@optique/temporal 1.0.0-dev.921 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +196 -13
- package/dist/index.d.cts +21 -7
- package/dist/index.d.ts +21 -7
- package/dist/index.js +196 -13
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -46,8 +46,15 @@ function instant(options = {}) {
|
|
|
46
46
|
const metavar = options.metavar ?? "TIMESTAMP";
|
|
47
47
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
48
48
|
return {
|
|
49
|
-
|
|
49
|
+
mode: "sync",
|
|
50
50
|
metavar,
|
|
51
|
+
get placeholder() {
|
|
52
|
+
try {
|
|
53
|
+
return Temporal.Instant.from("1970-01-01T00:00:00Z");
|
|
54
|
+
} catch {
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
},
|
|
51
58
|
parse(input) {
|
|
52
59
|
ensureTemporal();
|
|
53
60
|
try {
|
|
@@ -86,8 +93,15 @@ function duration(options = {}) {
|
|
|
86
93
|
const metavar = options.metavar ?? "DURATION";
|
|
87
94
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
88
95
|
return {
|
|
89
|
-
|
|
96
|
+
mode: "sync",
|
|
90
97
|
metavar,
|
|
98
|
+
get placeholder() {
|
|
99
|
+
try {
|
|
100
|
+
return Temporal.Duration.from("PT0S");
|
|
101
|
+
} catch {
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
},
|
|
91
105
|
parse(input) {
|
|
92
106
|
ensureTemporal();
|
|
93
107
|
try {
|
|
@@ -125,8 +139,15 @@ function zonedDateTime(options = {}) {
|
|
|
125
139
|
const metavar = options.metavar ?? "ZONED_DATETIME";
|
|
126
140
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
127
141
|
return {
|
|
128
|
-
|
|
142
|
+
mode: "sync",
|
|
129
143
|
metavar,
|
|
144
|
+
get placeholder() {
|
|
145
|
+
try {
|
|
146
|
+
return Temporal.ZonedDateTime.from("1970-01-01T00:00:00+00:00[UTC]");
|
|
147
|
+
} catch {
|
|
148
|
+
return void 0;
|
|
149
|
+
}
|
|
150
|
+
},
|
|
130
151
|
parse(input) {
|
|
131
152
|
ensureTemporal();
|
|
132
153
|
try {
|
|
@@ -148,6 +169,64 @@ function zonedDateTime(options = {}) {
|
|
|
148
169
|
};
|
|
149
170
|
}
|
|
150
171
|
/**
|
|
172
|
+
* Optional RFC 9557 calendar annotation suffix, e.g. `[u-ca=gregory]`.
|
|
173
|
+
* Accepts case-insensitive values and the optional critical flag (`!`).
|
|
174
|
+
* Used by all plain Temporal regexes to accept `toString()` output for
|
|
175
|
+
* non-ISO calendars.
|
|
176
|
+
*/
|
|
177
|
+
const CALENDAR_ANNOTATION = String.raw`(\[!?u-ca=[a-zA-Z0-9\-]+\])?`;
|
|
178
|
+
/**
|
|
179
|
+
* Required RFC 9557 calendar annotation (non-optional variant used when the
|
|
180
|
+
* annotation must be present, e.g. for reference-day/year forms).
|
|
181
|
+
*/
|
|
182
|
+
const CALENDAR_ANNOTATION_REQUIRED = String.raw`\[!?u-ca=[a-zA-Z0-9\-]+\]`;
|
|
183
|
+
/**
|
|
184
|
+
* Year portion: either 4 digits (`YYYY`) or a sign-prefixed 6-digit expanded
|
|
185
|
+
* year (`+YYYYYY` / `-YYYYYY`).
|
|
186
|
+
*/
|
|
187
|
+
const YEAR = String.raw`([+-]\d{6}|\d{4})`;
|
|
188
|
+
/** ISO 8601 fractional seconds with `.` or `,` separator. */
|
|
189
|
+
const FRACTIONAL = String.raw`[.,]\d+`;
|
|
190
|
+
/** Extended date: `YYYY-MM-DD` or `±YYYYYY-MM-DD`. */
|
|
191
|
+
const DATE_EXTENDED = `${YEAR}-\\d{2}-\\d{2}`;
|
|
192
|
+
/** Basic date: `YYYYMMDD` or `±YYYYYYMMDD`. */
|
|
193
|
+
const DATE_BASIC = `${YEAR}\\d{4}`;
|
|
194
|
+
/** Extended time: `HH:MM[:SS[.frac]]`. */
|
|
195
|
+
const TIME_EXTENDED = `\\d{2}:\\d{2}(:\\d{2}(${FRACTIONAL})?)?`;
|
|
196
|
+
/** Basic time: `HH`, `HHMM`, or `HHMMSS[.frac]`. */
|
|
197
|
+
const TIME_BASIC = `\\d{2}(\\d{2}(\\d{2}(${FRACTIONAL})?)?)?`;
|
|
198
|
+
/**
|
|
199
|
+
* Matches YYYY-MM-DD (extended) or YYYYMMDD (basic) date forms only (no time
|
|
200
|
+
* component). Both forms accept expanded years and calendar annotations.
|
|
201
|
+
*/
|
|
202
|
+
const PLAIN_DATE_RE = /* @__PURE__ */ new RegExp(`^(${DATE_EXTENDED}|${DATE_BASIC})${CALENDAR_ANNOTATION}$`);
|
|
203
|
+
/**
|
|
204
|
+
* Matches time forms only (no date prefix). Accepts extended
|
|
205
|
+
* (`HH:MM[:SS[.frac]]`), basic (`HH`, `HHMM`, `HHMMSS[.frac]`), and
|
|
206
|
+
* `T`-prefixed variants. Calendar annotations are accepted for consistency
|
|
207
|
+
* with `Temporal.PlainTime.from()` on polyfill runtimes.
|
|
208
|
+
*/
|
|
209
|
+
const PLAIN_TIME_RE = /* @__PURE__ */ new RegExp(`^[Tt]?(${TIME_EXTENDED}|${TIME_BASIC})${CALENDAR_ANNOTATION}$`);
|
|
210
|
+
/**
|
|
211
|
+
* Matches date-time strings with both date and time parts. Accepts extended,
|
|
212
|
+
* basic, and mixed forms (e.g. `2020-01-23T170436`). The separator may be
|
|
213
|
+
* `T`, `t`, or a space. The time portion may be reduced-precision (hour
|
|
214
|
+
* only).
|
|
215
|
+
*/
|
|
216
|
+
const PLAIN_DATETIME_RE = /* @__PURE__ */ new RegExp(`^(${DATE_EXTENDED}|${DATE_BASIC})[Tt ](${TIME_EXTENDED}|${TIME_BASIC})${CALENDAR_ANNOTATION}$`);
|
|
217
|
+
/**
|
|
218
|
+
* Matches YYYY-MM (extended) or YYYYMM (basic), or a full date
|
|
219
|
+
* (extended or basic) with a required calendar annotation (the reference day
|
|
220
|
+
* is emitted by `toString()` for non-ISO calendars).
|
|
221
|
+
*/
|
|
222
|
+
const PLAIN_YEAR_MONTH_RE = /* @__PURE__ */ new RegExp(`^(${YEAR}-\\d{2}(${CALENDAR_ANNOTATION}|-\\d{2}${CALENDAR_ANNOTATION_REQUIRED})|${YEAR}\\d{2}(${CALENDAR_ANNOTATION}|\\d{2}${CALENDAR_ANNOTATION_REQUIRED}))$`);
|
|
223
|
+
/**
|
|
224
|
+
* Matches MM-DD, --MM-DD, MMDD, or --MMDD month-day forms, or a full date
|
|
225
|
+
* (extended or basic) with a required calendar annotation (the reference year
|
|
226
|
+
* is emitted by `toString()` for non-ISO calendars).
|
|
227
|
+
*/
|
|
228
|
+
const PLAIN_MONTH_DAY_RE = /* @__PURE__ */ new RegExp(`^((--)?(\\d{2}-\\d{2}|\\d{4})${CALENDAR_ANNOTATION}|(${DATE_EXTENDED}|${DATE_BASIC})${CALENDAR_ANNOTATION_REQUIRED})$`);
|
|
229
|
+
/**
|
|
151
230
|
* Creates a ValueParser for parsing Temporal.PlainDate from ISO 8601 date strings.
|
|
152
231
|
*
|
|
153
232
|
* Accepts strings like:
|
|
@@ -164,11 +243,19 @@ function plainDate(options = {}) {
|
|
|
164
243
|
const metavar = options.metavar ?? "DATE";
|
|
165
244
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
166
245
|
return {
|
|
167
|
-
|
|
246
|
+
mode: "sync",
|
|
168
247
|
metavar,
|
|
248
|
+
get placeholder() {
|
|
249
|
+
try {
|
|
250
|
+
return Temporal.PlainDate.from("1970-01-01");
|
|
251
|
+
} catch {
|
|
252
|
+
return void 0;
|
|
253
|
+
}
|
|
254
|
+
},
|
|
169
255
|
parse(input) {
|
|
170
256
|
ensureTemporal();
|
|
171
257
|
try {
|
|
258
|
+
if (!PLAIN_DATE_RE.test(input)) throw new RangeError();
|
|
172
259
|
const value = Temporal.PlainDate.from(input);
|
|
173
260
|
return {
|
|
174
261
|
success: true,
|
|
@@ -203,11 +290,19 @@ function plainTime(options = {}) {
|
|
|
203
290
|
const metavar = options.metavar ?? "TIME";
|
|
204
291
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
205
292
|
return {
|
|
206
|
-
|
|
293
|
+
mode: "sync",
|
|
207
294
|
metavar,
|
|
295
|
+
get placeholder() {
|
|
296
|
+
try {
|
|
297
|
+
return Temporal.PlainTime.from("00:00:00");
|
|
298
|
+
} catch {
|
|
299
|
+
return void 0;
|
|
300
|
+
}
|
|
301
|
+
},
|
|
208
302
|
parse(input) {
|
|
209
303
|
ensureTemporal();
|
|
210
304
|
try {
|
|
305
|
+
if (!PLAIN_TIME_RE.test(input)) throw new RangeError();
|
|
211
306
|
const value = Temporal.PlainTime.from(input);
|
|
212
307
|
return {
|
|
213
308
|
success: true,
|
|
@@ -242,11 +337,19 @@ function plainDateTime(options = {}) {
|
|
|
242
337
|
const metavar = options.metavar ?? "DATETIME";
|
|
243
338
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
244
339
|
return {
|
|
245
|
-
|
|
340
|
+
mode: "sync",
|
|
246
341
|
metavar,
|
|
342
|
+
get placeholder() {
|
|
343
|
+
try {
|
|
344
|
+
return Temporal.PlainDateTime.from("1970-01-01T00:00:00");
|
|
345
|
+
} catch {
|
|
346
|
+
return void 0;
|
|
347
|
+
}
|
|
348
|
+
},
|
|
247
349
|
parse(input) {
|
|
248
350
|
ensureTemporal();
|
|
249
351
|
try {
|
|
352
|
+
if (!PLAIN_DATETIME_RE.test(input)) throw new RangeError();
|
|
250
353
|
const value = Temporal.PlainDateTime.from(input);
|
|
251
354
|
return {
|
|
252
355
|
success: true,
|
|
@@ -281,11 +384,19 @@ function plainYearMonth(options = {}) {
|
|
|
281
384
|
const metavar = options.metavar ?? "YEAR-MONTH";
|
|
282
385
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
283
386
|
return {
|
|
284
|
-
|
|
387
|
+
mode: "sync",
|
|
285
388
|
metavar,
|
|
389
|
+
get placeholder() {
|
|
390
|
+
try {
|
|
391
|
+
return Temporal.PlainYearMonth.from("1970-01");
|
|
392
|
+
} catch {
|
|
393
|
+
return void 0;
|
|
394
|
+
}
|
|
395
|
+
},
|
|
286
396
|
parse(input) {
|
|
287
397
|
ensureTemporal();
|
|
288
398
|
try {
|
|
399
|
+
if (!PLAIN_YEAR_MONTH_RE.test(input)) throw new RangeError();
|
|
289
400
|
const value = Temporal.PlainYearMonth.from(input);
|
|
290
401
|
return {
|
|
291
402
|
success: true,
|
|
@@ -308,8 +419,8 @@ function plainYearMonth(options = {}) {
|
|
|
308
419
|
*
|
|
309
420
|
* Accepts strings like:
|
|
310
421
|
*
|
|
311
|
-
* - `"
|
|
312
|
-
* - `"
|
|
422
|
+
* - `"01-23"`
|
|
423
|
+
* - `"12-31"`
|
|
313
424
|
*
|
|
314
425
|
* @param options Configuration options for the plain month-day parser.
|
|
315
426
|
* @returns A ValueParser that parses strings into Temporal.PlainMonthDay values.
|
|
@@ -317,14 +428,22 @@ function plainYearMonth(options = {}) {
|
|
|
317
428
|
* at runtime.
|
|
318
429
|
*/
|
|
319
430
|
function plainMonthDay(options = {}) {
|
|
320
|
-
const metavar = options.metavar ?? "
|
|
431
|
+
const metavar = options.metavar ?? "MONTH-DAY";
|
|
321
432
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
322
433
|
return {
|
|
323
|
-
|
|
434
|
+
mode: "sync",
|
|
324
435
|
metavar,
|
|
436
|
+
get placeholder() {
|
|
437
|
+
try {
|
|
438
|
+
return Temporal.PlainMonthDay.from("01-01");
|
|
439
|
+
} catch {
|
|
440
|
+
return void 0;
|
|
441
|
+
}
|
|
442
|
+
},
|
|
325
443
|
parse(input) {
|
|
326
444
|
ensureTemporal();
|
|
327
445
|
try {
|
|
446
|
+
if (!PLAIN_MONTH_DAY_RE.test(input)) throw new RangeError();
|
|
328
447
|
const value = Temporal.PlainMonthDay.from(input);
|
|
329
448
|
return {
|
|
330
449
|
success: true,
|
|
@@ -333,7 +452,7 @@ function plainMonthDay(options = {}) {
|
|
|
333
452
|
} catch {
|
|
334
453
|
return {
|
|
335
454
|
success: false,
|
|
336
|
-
error: options.errors?.invalidFormat ? typeof options.errors.invalidFormat === "function" ? options.errors.invalidFormat(input) : options.errors.invalidFormat : __optique_core_message.message`Invalid month-day: ${input}. Expected ISO 8601 format like ${"
|
|
455
|
+
error: options.errors?.invalidFormat ? typeof options.errors.invalidFormat === "function" ? options.errors.invalidFormat(input) : options.errors.invalidFormat : __optique_core_message.message`Invalid month-day: ${input}. Expected ISO 8601 format like ${"01-23"}.`
|
|
337
456
|
};
|
|
338
457
|
}
|
|
339
458
|
},
|
|
@@ -343,6 +462,59 @@ function plainMonthDay(options = {}) {
|
|
|
343
462
|
};
|
|
344
463
|
}
|
|
345
464
|
/**
|
|
465
|
+
* Single-segment IANA timezone identifiers accepted across all supported
|
|
466
|
+
* runtimes (Deno, Node.js, Bun). This tuple is the single source of truth:
|
|
467
|
+
* {@link SingleSegmentTimeZone} is derived from it, and the runtime lookup
|
|
468
|
+
* {@link singleSegmentTimeZoneLookup} is built from it.
|
|
469
|
+
*/
|
|
470
|
+
const singleSegmentTimeZoneList = [
|
|
471
|
+
"UTC",
|
|
472
|
+
"GMT",
|
|
473
|
+
"GMT0",
|
|
474
|
+
"GMT+0",
|
|
475
|
+
"GMT-0",
|
|
476
|
+
"UCT",
|
|
477
|
+
"Universal",
|
|
478
|
+
"Greenwich",
|
|
479
|
+
"Zulu",
|
|
480
|
+
"EST",
|
|
481
|
+
"MST",
|
|
482
|
+
"HST",
|
|
483
|
+
"CET",
|
|
484
|
+
"MET",
|
|
485
|
+
"WET",
|
|
486
|
+
"EET",
|
|
487
|
+
"EST5EDT",
|
|
488
|
+
"CST6CDT",
|
|
489
|
+
"MST7MDT",
|
|
490
|
+
"PST8PDT",
|
|
491
|
+
"Cuba",
|
|
492
|
+
"Egypt",
|
|
493
|
+
"Eire",
|
|
494
|
+
"GB",
|
|
495
|
+
"GB-Eire",
|
|
496
|
+
"Hongkong",
|
|
497
|
+
"Iceland",
|
|
498
|
+
"Iran",
|
|
499
|
+
"Israel",
|
|
500
|
+
"Jamaica",
|
|
501
|
+
"Japan",
|
|
502
|
+
"Kwajalein",
|
|
503
|
+
"Libya",
|
|
504
|
+
"Navajo",
|
|
505
|
+
"NZ",
|
|
506
|
+
"NZ-CHAT",
|
|
507
|
+
"Poland",
|
|
508
|
+
"Portugal",
|
|
509
|
+
"PRC",
|
|
510
|
+
"ROC",
|
|
511
|
+
"ROK",
|
|
512
|
+
"Singapore",
|
|
513
|
+
"Turkey",
|
|
514
|
+
"W-SU"
|
|
515
|
+
];
|
|
516
|
+
const singleSegmentTimeZoneLookup = new Map(singleSegmentTimeZoneList.map((timeZone$1) => [timeZone$1.toLowerCase(), timeZone$1]));
|
|
517
|
+
/**
|
|
346
518
|
* Creates a ValueParser for parsing IANA Time Zone Database identifiers.
|
|
347
519
|
*
|
|
348
520
|
* Accepts strings like:
|
|
@@ -351,6 +523,8 @@ function plainMonthDay(options = {}) {
|
|
|
351
523
|
* - `"America/New_York"`
|
|
352
524
|
* - `"Europe/London"`
|
|
353
525
|
* - `"UTC"`
|
|
526
|
+
* - `"GMT"`
|
|
527
|
+
* - `"EST"`
|
|
354
528
|
*
|
|
355
529
|
* @param options Configuration options for the timezone parser.
|
|
356
530
|
* @returns A ValueParser that parses and validates timezone identifiers.
|
|
@@ -361,8 +535,9 @@ function timeZone(options = {}) {
|
|
|
361
535
|
const metavar = options.metavar ?? "TIMEZONE";
|
|
362
536
|
(0, __optique_core_nonempty.ensureNonEmptyString)(metavar);
|
|
363
537
|
return {
|
|
364
|
-
|
|
538
|
+
mode: "sync",
|
|
365
539
|
metavar,
|
|
540
|
+
placeholder: "UTC",
|
|
366
541
|
parse(input) {
|
|
367
542
|
ensureTemporal();
|
|
368
543
|
try {
|
|
@@ -372,6 +547,14 @@ function timeZone(options = {}) {
|
|
|
372
547
|
day: 1,
|
|
373
548
|
timeZone: input
|
|
374
549
|
});
|
|
550
|
+
if (!input.includes("/")) {
|
|
551
|
+
const canonical = singleSegmentTimeZoneLookup.get(input.toLowerCase());
|
|
552
|
+
if (canonical == null) throw new RangeError();
|
|
553
|
+
return {
|
|
554
|
+
success: true,
|
|
555
|
+
value: canonical
|
|
556
|
+
};
|
|
557
|
+
}
|
|
375
558
|
return {
|
|
376
559
|
success: true,
|
|
377
560
|
value: input
|
package/dist/index.d.cts
CHANGED
|
@@ -11,17 +11,21 @@ import { NonEmptyString } from "@optique/core/nonempty";
|
|
|
11
11
|
* convention:
|
|
12
12
|
*
|
|
13
13
|
* - Two-level: `"Asia/Seoul"`, `"America/New_York"`, `"Europe/London"`
|
|
14
|
-
* - Three-level: `"America/Argentina/Buenos_Aires"`,
|
|
15
|
-
*
|
|
14
|
+
* - Three-level: `"America/Argentina/Buenos_Aires"`,
|
|
15
|
+
* `"America/Kentucky/Louisville"`
|
|
16
|
+
* - Standard single-segment: `"UTC"`, `"GMT"`, `"Universal"`
|
|
17
|
+
* - POSIX abbreviations: `"EST"`, `"CET"`, `"EST5EDT"`
|
|
18
|
+
* - Deprecated aliases: `"Japan"`, `"Singapore"`, `"Cuba"`
|
|
16
19
|
*
|
|
17
20
|
* @example
|
|
18
21
|
* ```typescript
|
|
19
22
|
* const seoul: TimeZone = "Asia/Seoul";
|
|
20
23
|
* const utc: TimeZone = "UTC";
|
|
24
|
+
* const gmt: TimeZone = "GMT";
|
|
21
25
|
* const buenosAires: TimeZone = "America/Argentina/Buenos_Aires";
|
|
22
26
|
* ```
|
|
23
27
|
*/
|
|
24
|
-
type TimeZone = `${string}/${string}/${string}` | `${string}/${string}` |
|
|
28
|
+
type TimeZone = `${string}/${string}/${string}` | `${string}/${string}` | SingleSegmentTimeZone;
|
|
25
29
|
/**
|
|
26
30
|
* Options for creating an instant parser.
|
|
27
31
|
*/
|
|
@@ -197,8 +201,8 @@ interface PlainMonthDayOptions {
|
|
|
197
201
|
/**
|
|
198
202
|
* The metavariable name for this parser. This is used in help messages to
|
|
199
203
|
* indicate what kind of value this parser expects. Usually a single
|
|
200
|
-
* word in uppercase, like
|
|
201
|
-
* @default `"
|
|
204
|
+
* word in uppercase, like `MONTH-DAY`.
|
|
205
|
+
* @default `"MONTH-DAY"`
|
|
202
206
|
*/
|
|
203
207
|
readonly metavar?: NonEmptyString;
|
|
204
208
|
/**
|
|
@@ -342,8 +346,8 @@ declare function plainYearMonth(options?: PlainYearMonthOptions): ValueParser<"s
|
|
|
342
346
|
*
|
|
343
347
|
* Accepts strings like:
|
|
344
348
|
*
|
|
345
|
-
* - `"
|
|
346
|
-
* - `"
|
|
349
|
+
* - `"01-23"`
|
|
350
|
+
* - `"12-31"`
|
|
347
351
|
*
|
|
348
352
|
* @param options Configuration options for the plain month-day parser.
|
|
349
353
|
* @returns A ValueParser that parses strings into Temporal.PlainMonthDay values.
|
|
@@ -351,6 +355,14 @@ declare function plainYearMonth(options?: PlainYearMonthOptions): ValueParser<"s
|
|
|
351
355
|
* at runtime.
|
|
352
356
|
*/
|
|
353
357
|
declare function plainMonthDay(options?: PlainMonthDayOptions): ValueParser<"sync", Temporal.PlainMonthDay>;
|
|
358
|
+
/**
|
|
359
|
+
* Single-segment IANA timezone identifiers accepted across all supported
|
|
360
|
+
* runtimes (Deno, Node.js, Bun). This tuple is the single source of truth:
|
|
361
|
+
* {@link SingleSegmentTimeZone} is derived from it, and the runtime lookup
|
|
362
|
+
* {@link singleSegmentTimeZoneLookup} is built from it.
|
|
363
|
+
*/
|
|
364
|
+
declare const singleSegmentTimeZoneList: readonly ["UTC", "GMT", "GMT0", "GMT+0", "GMT-0", "UCT", "Universal", "Greenwich", "Zulu", "EST", "MST", "HST", "CET", "MET", "WET", "EET", "EST5EDT", "CST6CDT", "MST7MDT", "PST8PDT", "Cuba", "Egypt", "Eire", "GB", "GB-Eire", "Hongkong", "Iceland", "Iran", "Israel", "Jamaica", "Japan", "Kwajalein", "Libya", "Navajo", "NZ", "NZ-CHAT", "Poland", "Portugal", "PRC", "ROC", "ROK", "Singapore", "Turkey", "W-SU"];
|
|
365
|
+
type SingleSegmentTimeZone = typeof singleSegmentTimeZoneList[number];
|
|
354
366
|
/**
|
|
355
367
|
* Creates a ValueParser for parsing IANA Time Zone Database identifiers.
|
|
356
368
|
*
|
|
@@ -360,6 +372,8 @@ declare function plainMonthDay(options?: PlainMonthDayOptions): ValueParser<"syn
|
|
|
360
372
|
* - `"America/New_York"`
|
|
361
373
|
* - `"Europe/London"`
|
|
362
374
|
* - `"UTC"`
|
|
375
|
+
* - `"GMT"`
|
|
376
|
+
* - `"EST"`
|
|
363
377
|
*
|
|
364
378
|
* @param options Configuration options for the timezone parser.
|
|
365
379
|
* @returns A ValueParser that parses and validates timezone identifiers.
|
package/dist/index.d.ts
CHANGED
|
@@ -12,17 +12,21 @@ import { ValueParser } from "@optique/core/valueparser";
|
|
|
12
12
|
* convention:
|
|
13
13
|
*
|
|
14
14
|
* - Two-level: `"Asia/Seoul"`, `"America/New_York"`, `"Europe/London"`
|
|
15
|
-
* - Three-level: `"America/Argentina/Buenos_Aires"`,
|
|
16
|
-
*
|
|
15
|
+
* - Three-level: `"America/Argentina/Buenos_Aires"`,
|
|
16
|
+
* `"America/Kentucky/Louisville"`
|
|
17
|
+
* - Standard single-segment: `"UTC"`, `"GMT"`, `"Universal"`
|
|
18
|
+
* - POSIX abbreviations: `"EST"`, `"CET"`, `"EST5EDT"`
|
|
19
|
+
* - Deprecated aliases: `"Japan"`, `"Singapore"`, `"Cuba"`
|
|
17
20
|
*
|
|
18
21
|
* @example
|
|
19
22
|
* ```typescript
|
|
20
23
|
* const seoul: TimeZone = "Asia/Seoul";
|
|
21
24
|
* const utc: TimeZone = "UTC";
|
|
25
|
+
* const gmt: TimeZone = "GMT";
|
|
22
26
|
* const buenosAires: TimeZone = "America/Argentina/Buenos_Aires";
|
|
23
27
|
* ```
|
|
24
28
|
*/
|
|
25
|
-
type TimeZone = `${string}/${string}/${string}` | `${string}/${string}` |
|
|
29
|
+
type TimeZone = `${string}/${string}/${string}` | `${string}/${string}` | SingleSegmentTimeZone;
|
|
26
30
|
/**
|
|
27
31
|
* Options for creating an instant parser.
|
|
28
32
|
*/
|
|
@@ -198,8 +202,8 @@ interface PlainMonthDayOptions {
|
|
|
198
202
|
/**
|
|
199
203
|
* The metavariable name for this parser. This is used in help messages to
|
|
200
204
|
* indicate what kind of value this parser expects. Usually a single
|
|
201
|
-
* word in uppercase, like
|
|
202
|
-
* @default `"
|
|
205
|
+
* word in uppercase, like `MONTH-DAY`.
|
|
206
|
+
* @default `"MONTH-DAY"`
|
|
203
207
|
*/
|
|
204
208
|
readonly metavar?: NonEmptyString;
|
|
205
209
|
/**
|
|
@@ -343,8 +347,8 @@ declare function plainYearMonth(options?: PlainYearMonthOptions): ValueParser<"s
|
|
|
343
347
|
*
|
|
344
348
|
* Accepts strings like:
|
|
345
349
|
*
|
|
346
|
-
* - `"
|
|
347
|
-
* - `"
|
|
350
|
+
* - `"01-23"`
|
|
351
|
+
* - `"12-31"`
|
|
348
352
|
*
|
|
349
353
|
* @param options Configuration options for the plain month-day parser.
|
|
350
354
|
* @returns A ValueParser that parses strings into Temporal.PlainMonthDay values.
|
|
@@ -352,6 +356,14 @@ declare function plainYearMonth(options?: PlainYearMonthOptions): ValueParser<"s
|
|
|
352
356
|
* at runtime.
|
|
353
357
|
*/
|
|
354
358
|
declare function plainMonthDay(options?: PlainMonthDayOptions): ValueParser<"sync", Temporal.PlainMonthDay>;
|
|
359
|
+
/**
|
|
360
|
+
* Single-segment IANA timezone identifiers accepted across all supported
|
|
361
|
+
* runtimes (Deno, Node.js, Bun). This tuple is the single source of truth:
|
|
362
|
+
* {@link SingleSegmentTimeZone} is derived from it, and the runtime lookup
|
|
363
|
+
* {@link singleSegmentTimeZoneLookup} is built from it.
|
|
364
|
+
*/
|
|
365
|
+
declare const singleSegmentTimeZoneList: readonly ["UTC", "GMT", "GMT0", "GMT+0", "GMT-0", "UCT", "Universal", "Greenwich", "Zulu", "EST", "MST", "HST", "CET", "MET", "WET", "EET", "EST5EDT", "CST6CDT", "MST7MDT", "PST8PDT", "Cuba", "Egypt", "Eire", "GB", "GB-Eire", "Hongkong", "Iceland", "Iran", "Israel", "Jamaica", "Japan", "Kwajalein", "Libya", "Navajo", "NZ", "NZ-CHAT", "Poland", "Portugal", "PRC", "ROC", "ROK", "Singapore", "Turkey", "W-SU"];
|
|
366
|
+
type SingleSegmentTimeZone = typeof singleSegmentTimeZoneList[number];
|
|
355
367
|
/**
|
|
356
368
|
* Creates a ValueParser for parsing IANA Time Zone Database identifiers.
|
|
357
369
|
*
|
|
@@ -361,6 +373,8 @@ declare function plainMonthDay(options?: PlainMonthDayOptions): ValueParser<"syn
|
|
|
361
373
|
* - `"America/New_York"`
|
|
362
374
|
* - `"Europe/London"`
|
|
363
375
|
* - `"UTC"`
|
|
376
|
+
* - `"GMT"`
|
|
377
|
+
* - `"EST"`
|
|
364
378
|
*
|
|
365
379
|
* @param options Configuration options for the timezone parser.
|
|
366
380
|
* @returns A ValueParser that parses and validates timezone identifiers.
|
package/dist/index.js
CHANGED
|
@@ -23,8 +23,15 @@ function instant(options = {}) {
|
|
|
23
23
|
const metavar = options.metavar ?? "TIMESTAMP";
|
|
24
24
|
ensureNonEmptyString(metavar);
|
|
25
25
|
return {
|
|
26
|
-
|
|
26
|
+
mode: "sync",
|
|
27
27
|
metavar,
|
|
28
|
+
get placeholder() {
|
|
29
|
+
try {
|
|
30
|
+
return Temporal.Instant.from("1970-01-01T00:00:00Z");
|
|
31
|
+
} catch {
|
|
32
|
+
return void 0;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
28
35
|
parse(input) {
|
|
29
36
|
ensureTemporal();
|
|
30
37
|
try {
|
|
@@ -63,8 +70,15 @@ function duration(options = {}) {
|
|
|
63
70
|
const metavar = options.metavar ?? "DURATION";
|
|
64
71
|
ensureNonEmptyString(metavar);
|
|
65
72
|
return {
|
|
66
|
-
|
|
73
|
+
mode: "sync",
|
|
67
74
|
metavar,
|
|
75
|
+
get placeholder() {
|
|
76
|
+
try {
|
|
77
|
+
return Temporal.Duration.from("PT0S");
|
|
78
|
+
} catch {
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
68
82
|
parse(input) {
|
|
69
83
|
ensureTemporal();
|
|
70
84
|
try {
|
|
@@ -102,8 +116,15 @@ function zonedDateTime(options = {}) {
|
|
|
102
116
|
const metavar = options.metavar ?? "ZONED_DATETIME";
|
|
103
117
|
ensureNonEmptyString(metavar);
|
|
104
118
|
return {
|
|
105
|
-
|
|
119
|
+
mode: "sync",
|
|
106
120
|
metavar,
|
|
121
|
+
get placeholder() {
|
|
122
|
+
try {
|
|
123
|
+
return Temporal.ZonedDateTime.from("1970-01-01T00:00:00+00:00[UTC]");
|
|
124
|
+
} catch {
|
|
125
|
+
return void 0;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
107
128
|
parse(input) {
|
|
108
129
|
ensureTemporal();
|
|
109
130
|
try {
|
|
@@ -125,6 +146,64 @@ function zonedDateTime(options = {}) {
|
|
|
125
146
|
};
|
|
126
147
|
}
|
|
127
148
|
/**
|
|
149
|
+
* Optional RFC 9557 calendar annotation suffix, e.g. `[u-ca=gregory]`.
|
|
150
|
+
* Accepts case-insensitive values and the optional critical flag (`!`).
|
|
151
|
+
* Used by all plain Temporal regexes to accept `toString()` output for
|
|
152
|
+
* non-ISO calendars.
|
|
153
|
+
*/
|
|
154
|
+
const CALENDAR_ANNOTATION = String.raw`(\[!?u-ca=[a-zA-Z0-9\-]+\])?`;
|
|
155
|
+
/**
|
|
156
|
+
* Required RFC 9557 calendar annotation (non-optional variant used when the
|
|
157
|
+
* annotation must be present, e.g. for reference-day/year forms).
|
|
158
|
+
*/
|
|
159
|
+
const CALENDAR_ANNOTATION_REQUIRED = String.raw`\[!?u-ca=[a-zA-Z0-9\-]+\]`;
|
|
160
|
+
/**
|
|
161
|
+
* Year portion: either 4 digits (`YYYY`) or a sign-prefixed 6-digit expanded
|
|
162
|
+
* year (`+YYYYYY` / `-YYYYYY`).
|
|
163
|
+
*/
|
|
164
|
+
const YEAR = String.raw`([+-]\d{6}|\d{4})`;
|
|
165
|
+
/** ISO 8601 fractional seconds with `.` or `,` separator. */
|
|
166
|
+
const FRACTIONAL = String.raw`[.,]\d+`;
|
|
167
|
+
/** Extended date: `YYYY-MM-DD` or `±YYYYYY-MM-DD`. */
|
|
168
|
+
const DATE_EXTENDED = `${YEAR}-\\d{2}-\\d{2}`;
|
|
169
|
+
/** Basic date: `YYYYMMDD` or `±YYYYYYMMDD`. */
|
|
170
|
+
const DATE_BASIC = `${YEAR}\\d{4}`;
|
|
171
|
+
/** Extended time: `HH:MM[:SS[.frac]]`. */
|
|
172
|
+
const TIME_EXTENDED = `\\d{2}:\\d{2}(:\\d{2}(${FRACTIONAL})?)?`;
|
|
173
|
+
/** Basic time: `HH`, `HHMM`, or `HHMMSS[.frac]`. */
|
|
174
|
+
const TIME_BASIC = `\\d{2}(\\d{2}(\\d{2}(${FRACTIONAL})?)?)?`;
|
|
175
|
+
/**
|
|
176
|
+
* Matches YYYY-MM-DD (extended) or YYYYMMDD (basic) date forms only (no time
|
|
177
|
+
* component). Both forms accept expanded years and calendar annotations.
|
|
178
|
+
*/
|
|
179
|
+
const PLAIN_DATE_RE = /* @__PURE__ */ new RegExp(`^(${DATE_EXTENDED}|${DATE_BASIC})${CALENDAR_ANNOTATION}$`);
|
|
180
|
+
/**
|
|
181
|
+
* Matches time forms only (no date prefix). Accepts extended
|
|
182
|
+
* (`HH:MM[:SS[.frac]]`), basic (`HH`, `HHMM`, `HHMMSS[.frac]`), and
|
|
183
|
+
* `T`-prefixed variants. Calendar annotations are accepted for consistency
|
|
184
|
+
* with `Temporal.PlainTime.from()` on polyfill runtimes.
|
|
185
|
+
*/
|
|
186
|
+
const PLAIN_TIME_RE = /* @__PURE__ */ new RegExp(`^[Tt]?(${TIME_EXTENDED}|${TIME_BASIC})${CALENDAR_ANNOTATION}$`);
|
|
187
|
+
/**
|
|
188
|
+
* Matches date-time strings with both date and time parts. Accepts extended,
|
|
189
|
+
* basic, and mixed forms (e.g. `2020-01-23T170436`). The separator may be
|
|
190
|
+
* `T`, `t`, or a space. The time portion may be reduced-precision (hour
|
|
191
|
+
* only).
|
|
192
|
+
*/
|
|
193
|
+
const PLAIN_DATETIME_RE = /* @__PURE__ */ new RegExp(`^(${DATE_EXTENDED}|${DATE_BASIC})[Tt ](${TIME_EXTENDED}|${TIME_BASIC})${CALENDAR_ANNOTATION}$`);
|
|
194
|
+
/**
|
|
195
|
+
* Matches YYYY-MM (extended) or YYYYMM (basic), or a full date
|
|
196
|
+
* (extended or basic) with a required calendar annotation (the reference day
|
|
197
|
+
* is emitted by `toString()` for non-ISO calendars).
|
|
198
|
+
*/
|
|
199
|
+
const PLAIN_YEAR_MONTH_RE = /* @__PURE__ */ new RegExp(`^(${YEAR}-\\d{2}(${CALENDAR_ANNOTATION}|-\\d{2}${CALENDAR_ANNOTATION_REQUIRED})|${YEAR}\\d{2}(${CALENDAR_ANNOTATION}|\\d{2}${CALENDAR_ANNOTATION_REQUIRED}))$`);
|
|
200
|
+
/**
|
|
201
|
+
* Matches MM-DD, --MM-DD, MMDD, or --MMDD month-day forms, or a full date
|
|
202
|
+
* (extended or basic) with a required calendar annotation (the reference year
|
|
203
|
+
* is emitted by `toString()` for non-ISO calendars).
|
|
204
|
+
*/
|
|
205
|
+
const PLAIN_MONTH_DAY_RE = /* @__PURE__ */ new RegExp(`^((--)?(\\d{2}-\\d{2}|\\d{4})${CALENDAR_ANNOTATION}|(${DATE_EXTENDED}|${DATE_BASIC})${CALENDAR_ANNOTATION_REQUIRED})$`);
|
|
206
|
+
/**
|
|
128
207
|
* Creates a ValueParser for parsing Temporal.PlainDate from ISO 8601 date strings.
|
|
129
208
|
*
|
|
130
209
|
* Accepts strings like:
|
|
@@ -141,11 +220,19 @@ function plainDate(options = {}) {
|
|
|
141
220
|
const metavar = options.metavar ?? "DATE";
|
|
142
221
|
ensureNonEmptyString(metavar);
|
|
143
222
|
return {
|
|
144
|
-
|
|
223
|
+
mode: "sync",
|
|
145
224
|
metavar,
|
|
225
|
+
get placeholder() {
|
|
226
|
+
try {
|
|
227
|
+
return Temporal.PlainDate.from("1970-01-01");
|
|
228
|
+
} catch {
|
|
229
|
+
return void 0;
|
|
230
|
+
}
|
|
231
|
+
},
|
|
146
232
|
parse(input) {
|
|
147
233
|
ensureTemporal();
|
|
148
234
|
try {
|
|
235
|
+
if (!PLAIN_DATE_RE.test(input)) throw new RangeError();
|
|
149
236
|
const value = Temporal.PlainDate.from(input);
|
|
150
237
|
return {
|
|
151
238
|
success: true,
|
|
@@ -180,11 +267,19 @@ function plainTime(options = {}) {
|
|
|
180
267
|
const metavar = options.metavar ?? "TIME";
|
|
181
268
|
ensureNonEmptyString(metavar);
|
|
182
269
|
return {
|
|
183
|
-
|
|
270
|
+
mode: "sync",
|
|
184
271
|
metavar,
|
|
272
|
+
get placeholder() {
|
|
273
|
+
try {
|
|
274
|
+
return Temporal.PlainTime.from("00:00:00");
|
|
275
|
+
} catch {
|
|
276
|
+
return void 0;
|
|
277
|
+
}
|
|
278
|
+
},
|
|
185
279
|
parse(input) {
|
|
186
280
|
ensureTemporal();
|
|
187
281
|
try {
|
|
282
|
+
if (!PLAIN_TIME_RE.test(input)) throw new RangeError();
|
|
188
283
|
const value = Temporal.PlainTime.from(input);
|
|
189
284
|
return {
|
|
190
285
|
success: true,
|
|
@@ -219,11 +314,19 @@ function plainDateTime(options = {}) {
|
|
|
219
314
|
const metavar = options.metavar ?? "DATETIME";
|
|
220
315
|
ensureNonEmptyString(metavar);
|
|
221
316
|
return {
|
|
222
|
-
|
|
317
|
+
mode: "sync",
|
|
223
318
|
metavar,
|
|
319
|
+
get placeholder() {
|
|
320
|
+
try {
|
|
321
|
+
return Temporal.PlainDateTime.from("1970-01-01T00:00:00");
|
|
322
|
+
} catch {
|
|
323
|
+
return void 0;
|
|
324
|
+
}
|
|
325
|
+
},
|
|
224
326
|
parse(input) {
|
|
225
327
|
ensureTemporal();
|
|
226
328
|
try {
|
|
329
|
+
if (!PLAIN_DATETIME_RE.test(input)) throw new RangeError();
|
|
227
330
|
const value = Temporal.PlainDateTime.from(input);
|
|
228
331
|
return {
|
|
229
332
|
success: true,
|
|
@@ -258,11 +361,19 @@ function plainYearMonth(options = {}) {
|
|
|
258
361
|
const metavar = options.metavar ?? "YEAR-MONTH";
|
|
259
362
|
ensureNonEmptyString(metavar);
|
|
260
363
|
return {
|
|
261
|
-
|
|
364
|
+
mode: "sync",
|
|
262
365
|
metavar,
|
|
366
|
+
get placeholder() {
|
|
367
|
+
try {
|
|
368
|
+
return Temporal.PlainYearMonth.from("1970-01");
|
|
369
|
+
} catch {
|
|
370
|
+
return void 0;
|
|
371
|
+
}
|
|
372
|
+
},
|
|
263
373
|
parse(input) {
|
|
264
374
|
ensureTemporal();
|
|
265
375
|
try {
|
|
376
|
+
if (!PLAIN_YEAR_MONTH_RE.test(input)) throw new RangeError();
|
|
266
377
|
const value = Temporal.PlainYearMonth.from(input);
|
|
267
378
|
return {
|
|
268
379
|
success: true,
|
|
@@ -285,8 +396,8 @@ function plainYearMonth(options = {}) {
|
|
|
285
396
|
*
|
|
286
397
|
* Accepts strings like:
|
|
287
398
|
*
|
|
288
|
-
* - `"
|
|
289
|
-
* - `"
|
|
399
|
+
* - `"01-23"`
|
|
400
|
+
* - `"12-31"`
|
|
290
401
|
*
|
|
291
402
|
* @param options Configuration options for the plain month-day parser.
|
|
292
403
|
* @returns A ValueParser that parses strings into Temporal.PlainMonthDay values.
|
|
@@ -294,14 +405,22 @@ function plainYearMonth(options = {}) {
|
|
|
294
405
|
* at runtime.
|
|
295
406
|
*/
|
|
296
407
|
function plainMonthDay(options = {}) {
|
|
297
|
-
const metavar = options.metavar ?? "
|
|
408
|
+
const metavar = options.metavar ?? "MONTH-DAY";
|
|
298
409
|
ensureNonEmptyString(metavar);
|
|
299
410
|
return {
|
|
300
|
-
|
|
411
|
+
mode: "sync",
|
|
301
412
|
metavar,
|
|
413
|
+
get placeholder() {
|
|
414
|
+
try {
|
|
415
|
+
return Temporal.PlainMonthDay.from("01-01");
|
|
416
|
+
} catch {
|
|
417
|
+
return void 0;
|
|
418
|
+
}
|
|
419
|
+
},
|
|
302
420
|
parse(input) {
|
|
303
421
|
ensureTemporal();
|
|
304
422
|
try {
|
|
423
|
+
if (!PLAIN_MONTH_DAY_RE.test(input)) throw new RangeError();
|
|
305
424
|
const value = Temporal.PlainMonthDay.from(input);
|
|
306
425
|
return {
|
|
307
426
|
success: true,
|
|
@@ -310,7 +429,7 @@ function plainMonthDay(options = {}) {
|
|
|
310
429
|
} catch {
|
|
311
430
|
return {
|
|
312
431
|
success: false,
|
|
313
|
-
error: options.errors?.invalidFormat ? typeof options.errors.invalidFormat === "function" ? options.errors.invalidFormat(input) : options.errors.invalidFormat : message`Invalid month-day: ${input}. Expected ISO 8601 format like ${"
|
|
432
|
+
error: options.errors?.invalidFormat ? typeof options.errors.invalidFormat === "function" ? options.errors.invalidFormat(input) : options.errors.invalidFormat : message`Invalid month-day: ${input}. Expected ISO 8601 format like ${"01-23"}.`
|
|
314
433
|
};
|
|
315
434
|
}
|
|
316
435
|
},
|
|
@@ -320,6 +439,59 @@ function plainMonthDay(options = {}) {
|
|
|
320
439
|
};
|
|
321
440
|
}
|
|
322
441
|
/**
|
|
442
|
+
* Single-segment IANA timezone identifiers accepted across all supported
|
|
443
|
+
* runtimes (Deno, Node.js, Bun). This tuple is the single source of truth:
|
|
444
|
+
* {@link SingleSegmentTimeZone} is derived from it, and the runtime lookup
|
|
445
|
+
* {@link singleSegmentTimeZoneLookup} is built from it.
|
|
446
|
+
*/
|
|
447
|
+
const singleSegmentTimeZoneList = [
|
|
448
|
+
"UTC",
|
|
449
|
+
"GMT",
|
|
450
|
+
"GMT0",
|
|
451
|
+
"GMT+0",
|
|
452
|
+
"GMT-0",
|
|
453
|
+
"UCT",
|
|
454
|
+
"Universal",
|
|
455
|
+
"Greenwich",
|
|
456
|
+
"Zulu",
|
|
457
|
+
"EST",
|
|
458
|
+
"MST",
|
|
459
|
+
"HST",
|
|
460
|
+
"CET",
|
|
461
|
+
"MET",
|
|
462
|
+
"WET",
|
|
463
|
+
"EET",
|
|
464
|
+
"EST5EDT",
|
|
465
|
+
"CST6CDT",
|
|
466
|
+
"MST7MDT",
|
|
467
|
+
"PST8PDT",
|
|
468
|
+
"Cuba",
|
|
469
|
+
"Egypt",
|
|
470
|
+
"Eire",
|
|
471
|
+
"GB",
|
|
472
|
+
"GB-Eire",
|
|
473
|
+
"Hongkong",
|
|
474
|
+
"Iceland",
|
|
475
|
+
"Iran",
|
|
476
|
+
"Israel",
|
|
477
|
+
"Jamaica",
|
|
478
|
+
"Japan",
|
|
479
|
+
"Kwajalein",
|
|
480
|
+
"Libya",
|
|
481
|
+
"Navajo",
|
|
482
|
+
"NZ",
|
|
483
|
+
"NZ-CHAT",
|
|
484
|
+
"Poland",
|
|
485
|
+
"Portugal",
|
|
486
|
+
"PRC",
|
|
487
|
+
"ROC",
|
|
488
|
+
"ROK",
|
|
489
|
+
"Singapore",
|
|
490
|
+
"Turkey",
|
|
491
|
+
"W-SU"
|
|
492
|
+
];
|
|
493
|
+
const singleSegmentTimeZoneLookup = new Map(singleSegmentTimeZoneList.map((timeZone$1) => [timeZone$1.toLowerCase(), timeZone$1]));
|
|
494
|
+
/**
|
|
323
495
|
* Creates a ValueParser for parsing IANA Time Zone Database identifiers.
|
|
324
496
|
*
|
|
325
497
|
* Accepts strings like:
|
|
@@ -328,6 +500,8 @@ function plainMonthDay(options = {}) {
|
|
|
328
500
|
* - `"America/New_York"`
|
|
329
501
|
* - `"Europe/London"`
|
|
330
502
|
* - `"UTC"`
|
|
503
|
+
* - `"GMT"`
|
|
504
|
+
* - `"EST"`
|
|
331
505
|
*
|
|
332
506
|
* @param options Configuration options for the timezone parser.
|
|
333
507
|
* @returns A ValueParser that parses and validates timezone identifiers.
|
|
@@ -338,8 +512,9 @@ function timeZone(options = {}) {
|
|
|
338
512
|
const metavar = options.metavar ?? "TIMEZONE";
|
|
339
513
|
ensureNonEmptyString(metavar);
|
|
340
514
|
return {
|
|
341
|
-
|
|
515
|
+
mode: "sync",
|
|
342
516
|
metavar,
|
|
517
|
+
placeholder: "UTC",
|
|
343
518
|
parse(input) {
|
|
344
519
|
ensureTemporal();
|
|
345
520
|
try {
|
|
@@ -349,6 +524,14 @@ function timeZone(options = {}) {
|
|
|
349
524
|
day: 1,
|
|
350
525
|
timeZone: input
|
|
351
526
|
});
|
|
527
|
+
if (!input.includes("/")) {
|
|
528
|
+
const canonical = singleSegmentTimeZoneLookup.get(input.toLowerCase());
|
|
529
|
+
if (canonical == null) throw new RangeError();
|
|
530
|
+
return {
|
|
531
|
+
success: true,
|
|
532
|
+
value: canonical
|
|
533
|
+
};
|
|
534
|
+
}
|
|
352
535
|
return {
|
|
353
536
|
success: true,
|
|
354
537
|
value: input
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/temporal",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Temporal value parsers for Optique",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"sideEffects": false,
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@js-temporal/polyfill": "^0.5.1",
|
|
59
|
-
"@optique/core": "1.0.0
|
|
59
|
+
"@optique/core": "1.0.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/node": "^20.19.9",
|