@@ -25,6 +25,17 @@ if (!year || !month) {
25
25
` ) ;
26
26
process . exit ( 1 ) ;
27
27
}
28
+ const today = new Date ( ) ;
29
+ if ( year < today . getFullYear ( ) - 3 || year > today . getFullYear ( ) + 9 ) {
30
+ console . error (
31
+ `Invalid year '${ year } ', please select a recent or close future year`
32
+ ) ;
33
+ process . exit ( 1 ) ;
34
+ }
35
+ if ( month < 1 || month > 12 ) {
36
+ console . error ( `Invalid month '${ month } ', must be between 1 and 12` ) ;
37
+ process . exit ( 1 ) ;
38
+ }
28
39
29
40
// For all three meetings in a month, fill and write the template
30
41
for ( num = 0 ; num < 3 ; num ++ ) {
@@ -67,7 +78,7 @@ agenda items, follow ups from the primary meeting, or agenda introduced by those
67
78
who could not make the primary meeting time.` ,
68
79
] [ meeting . num ] ;
69
80
70
- return `<!--
81
+ return t `<!--
71
82
72
83
# How to join (copied directly from /JoiningAMeeting.md)
73
84
@@ -78,15 +89,15 @@ ${howToJoin}
78
89
| This is an open meeting: To attend, read [JoiningAMeeting.md][] then edit and PR this file. (Edit: ✎ above, or press "e") |
79
90
| ---------------------------------------------------------------------------------------- |
80
91
81
- # GraphQL WG – ${ t ( meeting . monthName ) } ${ t ( meeting . year ) } (${ t ( meeting . name ) } )
92
+ # GraphQL WG – ${ meeting . monthName } ${ meeting . year } (${ meeting . name } )
82
93
83
94
The GraphQL Working Group meets regularly to discuss changes to the
84
95
[GraphQL Specification][] and other core GraphQL projects. This is an open
85
96
meeting in which anyone in the GraphQL community may attend.
86
97
87
98
${ meetingDescription }
88
99
89
- - **Date & Time**: [${ t ( meeting . dateTimeDuration ) } ](${ t ( meeting . timeLink ) } )
100
+ - **Date & Time**: [${ meeting . dateTimeRange } ](${ meeting . timeLink } )
90
101
- View the [calendar][], or subscribe ([Google Calendar][], [ical file][]).
91
102
- _Please Note:_ The date or time may change. Please check this agenda the
92
103
week of the meeting to confirm. While we try to keep all calendars accurate,
@@ -120,24 +131,21 @@ ${meetingDescription}
120
131
1. Determine volunteers for note taking (1m, Lee)
121
132
1. Review agenda (2m, Lee)
122
133
1. Review prior secondary meetings (5m, Lee)
123
- - [${ t ( prior2Meeting . monthName ) } WG ${ t ( prior2Meeting . name ) } ](${ t (
124
- prior2Meeting . url
125
- ) } )
126
- - [${ t ( prior1Meeting . monthName ) } WG ${ t ( prior1Meeting . name ) } ](${ t (
127
- prior1Meeting . url
128
- ) } )
134
+ - [${ prior2Meeting . monthName } WG ${ prior2Meeting . name } ](${ prior2Meeting . url } )
135
+ - [${ prior1Meeting . monthName } WG ${ prior1Meeting . name } ](${ prior1Meeting . url } )
129
136
1. Review previous meeting's action items (5m, Lee)
130
137
- [Ready for review](https://github.com/graphql/graphql-wg/issues?q=is%3Aissue+is%3Aopen+label%3A%22Ready+for+review+%F0%9F%99%8C%22+sort%3Aupdated-desc)
131
138
- [All open action items (by last update)](https://github.com/graphql/graphql-wg/issues?q=is%3Aissue+is%3Aopen+label%3A%22Action+item+%3Aclapper%3A%22+sort%3Aupdated-desc)
132
139
- [All open action items (by meeting)](https://github.com/graphql/graphql-wg/projects?query=is%3Aopen+sort%3Aname-asc)
133
140
` ;
134
141
}
135
142
136
- function t ( v ) {
137
- if ( ! v ) {
138
- throw new Error ( `Missing value` ) ;
139
- }
140
- return v ;
143
+ function t ( strings , ...values ) {
144
+ return strings . reduce ( ( out , string , i ) => {
145
+ const value = values [ i - 1 ] ;
146
+ if ( ! value ) throw new Error ( `Template value #${ i } : ${ value } ` ) ;
147
+ return out + value + string ;
148
+ } ) ;
141
149
}
142
150
143
151
function getMeeting ( year , month , num ) {
@@ -151,7 +159,7 @@ function getMeeting(year, month, num) {
151
159
// - The first meeting is first Thursday.
152
160
// - Second is the following Wednesday after the first.
153
161
// - Third is two weeks following the first, also on a Thursday.
154
- const monthStartWeekday = new Date ( year , month - 1 , 1 ) . getDay ( ) ;
162
+ const monthStartWeekday = new Date ( year , month - 1 , 1 , 12 ) . getDay ( ) ;
155
163
const firstThursday = new Date (
156
164
year ,
157
165
month - 1 ,
@@ -162,37 +170,41 @@ function getMeeting(year, month, num) {
162
170
// Get the actual Date instance representing the start time of this meeting
163
171
const dateTime = getDateTime ( year , month , day , time ) ;
164
172
165
- // Month names
166
- const monthName = dateTime . toLocaleString ( "en-US" , { month : "long" } ) ;
167
-
168
- // Get the full date and time duration string
169
- const end = new Date ( dateTime ) ;
170
- end . setMinutes ( dateTime . getMinutes ( ) + length ) ;
171
- const dateTimeDuration =
172
- dateTime . toLocaleDateString ( "en-US" , {
173
- timeZone : "America/Los_Angeles" ,
174
- year : "numeric" ,
175
- month : "long" ,
176
- day : "numeric" ,
177
- hour12 : true ,
178
- hour : "numeric" ,
179
- minute : "numeric" ,
180
- } ) +
181
- " - " +
182
- end . toLocaleTimeString ( "en-US" , {
183
- timeZone : "America/Los_Angeles" ,
184
- hour12 : true ,
185
- hour : "numeric" ,
186
- minute : "numeric" ,
187
- timeZoneName : "short" ,
188
- } ) ;
173
+ // Get the full date and time range string
174
+ const endTime = new Date ( dateTime ) ;
175
+ endTime . setMinutes ( dateTime . getMinutes ( ) + length ) ;
176
+ const dateTimeRange = new Intl . DateTimeFormat ( "en-US" , {
177
+ timeZone : "America/Los_Angeles" ,
178
+ year : "numeric" ,
179
+ month : "long" ,
180
+ day : "numeric" ,
181
+ hour12 : true ,
182
+ hour : "numeric" ,
183
+ minute : "numeric" ,
184
+ timeZoneName : "short" ,
185
+ } ) . formatRange ( dateTime , endTime ) ;
189
186
190
187
const isoTime = dateTime . toISOString ( ) . replace ( / [: -] / g, "" ) . slice ( 0 , 15 ) ;
191
188
const timeLink = `https://www.timeanddate.com/worldclock/converter.html?iso=${ isoTime } &p1=224&p2=179&p3=136&p4=268&p5=367&p6=438&p7=248&p8=240` ;
192
189
193
- const monthShort = dateTime . toLocaleString ( "en-US" , { month : "short" } ) ;
194
- const month2D = dateTime . toLocaleString ( "en-US" , { month : "2-digit" } ) ;
195
- const day2D = dateTime . toLocaleString ( "en-US" , { day : "2-digit" } ) ;
190
+ // Date parts for formatting below
191
+ const monthName = dateTime . toLocaleString ( "en-US" , {
192
+ timeZone : "America/Los_Angeles" ,
193
+ month : "long" ,
194
+ } ) ;
195
+ const monthShort = dateTime . toLocaleString ( "en-US" , {
196
+ timeZone : "America/Los_Angeles" ,
197
+ month : "short" ,
198
+ } ) ;
199
+ const month2D = dateTime . toLocaleString ( "en-US" , {
200
+ timeZone : "America/Los_Angeles" ,
201
+ month : "2-digit" ,
202
+ } ) ;
203
+ const day2D = dateTime . toLocaleString ( "en-US" , {
204
+ timeZone : "America/Los_Angeles" ,
205
+ day : "2-digit" ,
206
+ } ) ;
207
+
196
208
const fileName = [ "wg-primary" , "wg-secondary-apac" , "wg-secondary-eu" ] [ num ] ;
197
209
const repoPath = `agendas/${ year } /${ month2D } -${ monthShort } /${ day2D } -${ fileName } .md` ;
198
210
@@ -206,7 +218,7 @@ function getMeeting(year, month, num) {
206
218
day,
207
219
name,
208
220
monthName,
209
- dateTimeDuration ,
221
+ dateTimeRange ,
210
222
timeLink,
211
223
repoPath,
212
224
filePath,
@@ -230,13 +242,13 @@ function getPriorMeeting(meeting) {
230
242
231
243
// Times are in Pacific Time
232
244
function getDateTime ( year , month , date , time ) {
233
- const iso = new Date ( year , month - 1 , date ) . toISOString ( ) ;
245
+ const yyyy = String ( year ) ;
246
+ const mm = String ( month ) . padStart ( 2 , "0" ) ;
247
+ const dd = String ( date ) . padStart ( 2 , "0" ) ;
234
248
// Timezones are hard. This iterates through a few offsets until we find the
235
249
// one which has a time which matches the expected time.
236
250
for ( let offset = 7 ; offset <= 8 ; offset ++ ) {
237
- const d = new Date (
238
- iso . slice ( 0 , 11 ) + time + iso . slice ( 16 , - 1 ) + "-0" + offset + ":00"
239
- ) ;
251
+ const d = new Date ( `${ yyyy } -${ mm } -${ dd } T${ time } :00-0${ offset } :00` ) ;
240
252
if (
241
253
time ===
242
254
d . toLocaleTimeString ( "en-US" , {
0 commit comments