@nmtjs/type 0.2.1 → 0.3.1

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.
Files changed (55) hide show
  1. package/dist/compiler.js +2 -2
  2. package/dist/compiler.js.map +1 -1
  3. package/dist/constants.js +2 -0
  4. package/dist/constants.js.map +1 -0
  5. package/dist/index.js +2 -3
  6. package/dist/index.js.map +1 -1
  7. package/dist/temporal.js +3 -1
  8. package/dist/temporal.js.map +1 -1
  9. package/dist/types/any.js +37 -5
  10. package/dist/types/any.js.map +1 -1
  11. package/dist/types/array.js +55 -24
  12. package/dist/types/array.js.map +1 -1
  13. package/dist/types/base.js +31 -62
  14. package/dist/types/base.js.map +1 -1
  15. package/dist/types/boolean.js +37 -5
  16. package/dist/types/boolean.js.map +1 -1
  17. package/dist/types/custom.js +37 -8
  18. package/dist/types/custom.js.map +1 -1
  19. package/dist/types/datetime.js +41 -22
  20. package/dist/types/datetime.js.map +1 -1
  21. package/dist/types/enum.js +74 -16
  22. package/dist/types/enum.js.map +1 -1
  23. package/dist/types/literal.js +35 -8
  24. package/dist/types/literal.js.map +1 -1
  25. package/dist/types/never.js +17 -2
  26. package/dist/types/never.js.map +1 -1
  27. package/dist/types/number.js +116 -62
  28. package/dist/types/number.js.map +1 -1
  29. package/dist/types/object.js +58 -17
  30. package/dist/types/object.js.map +1 -1
  31. package/dist/types/string.js +57 -21
  32. package/dist/types/string.js.map +1 -1
  33. package/dist/types/temporal.js +292 -74
  34. package/dist/types/temporal.js.map +1 -1
  35. package/dist/types/union.js +75 -17
  36. package/dist/types/union.js.map +1 -1
  37. package/package.json +3 -3
  38. package/src/compiler.ts +2 -2
  39. package/src/constants.ts +5 -0
  40. package/src/index.ts +5 -6
  41. package/src/temporal.ts +4 -2
  42. package/src/types/any.ts +32 -9
  43. package/src/types/array.ts +59 -28
  44. package/src/types/base.ts +59 -112
  45. package/src/types/boolean.ts +31 -9
  46. package/src/types/custom.ts +61 -24
  47. package/src/types/datetime.ts +40 -35
  48. package/src/types/enum.ts +78 -21
  49. package/src/types/literal.ts +42 -12
  50. package/src/types/never.ts +24 -11
  51. package/src/types/number.ts +103 -67
  52. package/src/types/object.ts +87 -32
  53. package/src/types/string.ts +38 -30
  54. package/src/types/temporal.ts +378 -118
  55. package/src/types/union.ts +103 -31
@@ -1,227 +1,487 @@
1
- import { type TString, type TTransform, Type } from '@sinclair/typebox'
1
+ import {
2
+ type SchemaOptions,
3
+ type StringOptions,
4
+ type TString,
5
+ type TTransform,
6
+ Type,
7
+ } from '@sinclair/typebox'
2
8
  import { Temporal } from 'temporal-polyfill'
3
9
  import { BaseType } from './base.ts'
4
10
 
11
+ type Types = Exclude<
12
+ keyof typeof Temporal,
13
+ 'Now' | 'Instant' | 'Calendar' | 'TimeZone'
14
+ >
15
+
16
+ type TemporalTransformer<T extends Types> = {
17
+ decode: (value: string) => ReturnType<(typeof Temporal)[T]['from']>
18
+ encode: (value: ReturnType<(typeof Temporal)[T]['from']>) => string
19
+ }
20
+
21
+ const createTemporalTransformer = <T extends Types>(
22
+ type: T,
23
+ decode = (value: string) => Temporal[type].from(value),
24
+ ) => {
25
+ const encode = (value: ReturnType<(typeof Temporal)[T]['from']>) =>
26
+ value.toString({
27
+ calendarName: 'never',
28
+ smallestUnit: 'microsecond',
29
+ timeZoneName: 'never',
30
+ })
31
+
32
+ return {
33
+ decode,
34
+ encode,
35
+ } as TemporalTransformer<T>
36
+ }
37
+
5
38
  export class PlainDateType<
6
39
  N extends boolean = false,
7
40
  O extends boolean = false,
8
- > extends BaseType<TTransform<TString, Temporal.PlainDate>, N, O> {
9
- constructor(nullable: N = false as N, optional: O = false as O) {
10
- super(
11
- Type.Transform(Type.String({ format: 'iso-date' }))
12
- .Decode((value) => Temporal.PlainDate.from(value))
13
- .Encode((value) => value.toString({ calendarName: 'never' })),
14
- nullable,
15
- optional,
16
- )
41
+ D extends boolean = false,
42
+ > extends BaseType<
43
+ TTransform<TString, Temporal.PlainDate>,
44
+ N,
45
+ O,
46
+ D,
47
+ StringOptions
48
+ > {
49
+ static readonly transformer = createTemporalTransformer('PlainDate')
50
+
51
+ constructor(
52
+ options: StringOptions = {},
53
+ isNullable: N = false as N,
54
+ isOptional: O = false as O,
55
+ hasDefault: D = false as D,
56
+ ) {
57
+ super(options, isNullable, isOptional, hasDefault)
58
+ }
59
+
60
+ protected _constructSchema(
61
+ options: SchemaOptions,
62
+ ): TTransform<TString, Temporal.PlainDate> {
63
+ return Type.Transform(Type.String({ ...options, format: 'iso-date' }))
64
+ .Decode(PlainDateType.transformer.decode)
65
+ .Encode(PlainDateType.transformer.encode)
17
66
  }
18
67
 
19
68
  nullable() {
20
- const [_, ...args] = this._nullable()
21
- return new PlainDateType(...args)
69
+ return new PlainDateType(...this._with({ isNullable: true }))
22
70
  }
23
71
 
24
72
  optional() {
25
- const [_, ...args] = this._optional()
26
- return new PlainDateType(...args)
73
+ return new PlainDateType(...this._with({ isOptional: true }))
27
74
  }
28
75
 
29
76
  nullish() {
30
- const [_, ...args] = this._nullish()
31
- return new PlainDateType(...args)
77
+ return new PlainDateType(
78
+ ...this._with({ isNullable: true, isOptional: true }),
79
+ )
80
+ }
81
+
82
+ default(value: Temporal.PlainDate) {
83
+ return new PlainDateType(
84
+ ...this._with({
85
+ options: { default: PlainDateType.transformer.encode(value) },
86
+ hasDefault: true,
87
+ }),
88
+ )
89
+ }
90
+
91
+ description(description: string) {
92
+ return new PlainDateType(...this._with({ options: { description } }))
93
+ }
94
+
95
+ examples(...examples: [Temporal.PlainDate, ...Temporal.PlainDate[]]) {
96
+ return new PlainDateType(
97
+ ...this._with({
98
+ options: { examples: examples.map(PlainDateType.transformer.encode) },
99
+ }),
100
+ )
32
101
  }
33
102
  }
34
103
 
35
104
  export class PlainDateTimeType<
36
105
  N extends boolean = false,
37
106
  O extends boolean = false,
38
- > extends BaseType<TTransform<TString, Temporal.PlainDateTime>, N, O> {
39
- constructor(nullable: N = false as N, optional: O = false as O) {
40
- super(
41
- Type.Transform(Type.String({ format: 'iso-date-time' }))
42
- .Decode((value) => Temporal.PlainDateTime.from(value))
43
- .Encode((value) => value.toString({ calendarName: 'never' })),
44
- nullable,
45
- optional,
46
- )
107
+ D extends boolean = false,
108
+ > extends BaseType<
109
+ TTransform<TString, Temporal.PlainDateTime>,
110
+ N,
111
+ O,
112
+ D,
113
+ StringOptions
114
+ > {
115
+ static readonly transformer = createTemporalTransformer('PlainDateTime')
116
+
117
+ constructor(
118
+ options: StringOptions = {},
119
+ isNullable: N = false as N,
120
+ isOptional: O = false as O,
121
+ hasDefault: D = false as D,
122
+ ) {
123
+ super(options, isNullable, isOptional, hasDefault)
124
+ }
125
+
126
+ protected _constructSchema(
127
+ options: SchemaOptions,
128
+ ): TTransform<TString, Temporal.PlainDateTime> {
129
+ return Type.Transform(Type.String({ ...options, format: 'iso-date-time' }))
130
+ .Decode(PlainDateTimeType.transformer.decode)
131
+ .Encode(PlainDateTimeType.transformer.encode)
47
132
  }
48
133
 
49
134
  nullable() {
50
- const [_, ...args] = this._nullable()
51
- return new PlainDateTimeType(...args)
135
+ return new PlainDateTimeType(...this._with({ isNullable: true }))
52
136
  }
53
137
 
54
138
  optional() {
55
- const [_, ...args] = this._optional()
56
- return new PlainDateTimeType(...args)
139
+ return new PlainDateTimeType(...this._with({ isOptional: true }))
57
140
  }
58
141
 
59
142
  nullish() {
60
- const [_, ...args] = this._nullish()
61
- return new PlainDateTimeType(...args)
143
+ return new PlainDateTimeType(
144
+ ...this._with({ isNullable: true, isOptional: true }),
145
+ )
146
+ }
147
+
148
+ default(value: Temporal.PlainDateTime) {
149
+ return new PlainDateTimeType(
150
+ ...this._with({
151
+ options: { default: PlainDateTimeType.transformer.encode(value) },
152
+ hasDefault: true,
153
+ }),
154
+ )
155
+ }
156
+
157
+ description(description: string) {
158
+ return new PlainDateTimeType(...this._with({ options: { description } }))
159
+ }
160
+
161
+ examples(...examples: string[]) {
162
+ return new PlainDateTimeType(...this._with({ options: { examples } }))
62
163
  }
63
164
  }
64
165
 
65
166
  export class ZonedDateTimeType<
66
167
  N extends boolean = false,
67
168
  O extends boolean = false,
68
- > extends BaseType<TTransform<TString, Temporal.ZonedDateTime>, N, O> {
69
- constructor(nullable: N = false as N, optional: O = false as O) {
70
- super(
71
- Type.Transform(Type.String({ format: 'date-time' }))
72
- .Decode((value) =>
73
- Temporal.Instant.from(value).toZonedDateTimeISO('UTC'),
74
- )
75
- .Encode((value) => value.toString({ calendarName: 'never' })),
76
- nullable,
77
- optional,
78
- )
169
+ D extends boolean = false,
170
+ > extends BaseType<
171
+ TTransform<TString, Temporal.ZonedDateTime>,
172
+ N,
173
+ O,
174
+ D,
175
+ StringOptions
176
+ > {
177
+ static readonly transformer = createTemporalTransformer(
178
+ 'ZonedDateTime',
179
+ (value) => Temporal.Instant.from(value).toZonedDateTimeISO('UTC'),
180
+ )
181
+
182
+ constructor(
183
+ options: StringOptions = {},
184
+ isNullable: N = false as N,
185
+ isOptional: O = false as O,
186
+ hasDefault: D = false as D,
187
+ ) {
188
+ super(options, isNullable, isOptional, hasDefault)
189
+ }
190
+
191
+ protected _constructSchema(
192
+ options: SchemaOptions,
193
+ ): TTransform<TString, Temporal.ZonedDateTime> {
194
+ return Type.Transform(Type.String({ ...options, format: 'date-time' }))
195
+ .Decode(ZonedDateTimeType.transformer.decode)
196
+ .Encode(ZonedDateTimeType.transformer.encode)
79
197
  }
80
198
 
81
199
  nullable() {
82
- const [_, ...args] = this._nullable()
83
- return new ZonedDateTimeType(...args)
200
+ return new ZonedDateTimeType(...this._with({ isNullable: true }))
84
201
  }
85
202
 
86
203
  optional() {
87
- const [_, ...args] = this._optional()
88
- return new ZonedDateTimeType(...args)
204
+ return new ZonedDateTimeType(...this._with({ isOptional: true }))
89
205
  }
90
206
 
91
207
  nullish() {
92
- const [_, ...args] = this._nullish()
93
- return new ZonedDateTimeType(...args)
208
+ return new ZonedDateTimeType(
209
+ ...this._with({ isNullable: true, isOptional: true }),
210
+ )
211
+ }
212
+
213
+ default(value: Temporal.ZonedDateTime) {
214
+ return new ZonedDateTimeType(
215
+ ...this._with({
216
+ options: { default: ZonedDateTimeType.transformer.encode(value) },
217
+ hasDefault: true,
218
+ }),
219
+ )
220
+ }
221
+
222
+ description(description: string) {
223
+ return new ZonedDateTimeType(...this._with({ options: { description } }))
224
+ }
225
+
226
+ examples(...examples: string[]) {
227
+ return new ZonedDateTimeType(...this._with({ options: { examples } }))
94
228
  }
95
229
  }
96
230
 
97
231
  export class PlainTimeType<
98
232
  N extends boolean = false,
99
233
  O extends boolean = false,
100
- > extends BaseType<TTransform<TString, Temporal.PlainTime>, N, O> {
101
- constructor(nullable: N = false as N, optional: O = false as O) {
102
- super(
103
- Type.Transform(Type.String({ format: 'time' }))
104
- .Decode((value) => Temporal.PlainTime.from(value))
105
- .Encode((value) => value.toString({ smallestUnit: 'microsecond' })),
106
- nullable,
107
- optional,
108
- )
234
+ D extends boolean = false,
235
+ > extends BaseType<
236
+ TTransform<TString, Temporal.PlainTime>,
237
+ N,
238
+ O,
239
+ D,
240
+ StringOptions
241
+ > {
242
+ static readonly transformer = createTemporalTransformer('PlainTime')
243
+
244
+ constructor(
245
+ options: StringOptions = {},
246
+ isNullable: N = false as N,
247
+ isOptional: O = false as O,
248
+ hasDefault: D = false as D,
249
+ ) {
250
+ super(options, isNullable, isOptional, hasDefault)
251
+ }
252
+
253
+ protected _constructSchema(
254
+ options: SchemaOptions,
255
+ ): TTransform<TString, Temporal.PlainTime> {
256
+ return Type.Transform(Type.String({ ...options, format: 'time' }))
257
+ .Decode(PlainTimeType.transformer.decode)
258
+ .Encode(PlainTimeType.transformer.encode)
109
259
  }
110
260
 
111
261
  nullable() {
112
- const [_, ...args] = this._nullable()
113
- return new PlainTimeType(...args)
262
+ return new PlainTimeType(...this._with({ isNullable: true }))
114
263
  }
115
264
 
116
265
  optional() {
117
- const [_, ...args] = this._optional()
118
- return new PlainTimeType(...args)
266
+ return new PlainTimeType(...this._with({ isOptional: true }))
119
267
  }
120
268
 
121
269
  nullish() {
122
- const [_, ...args] = this._nullish()
123
- return new PlainTimeType(...args)
270
+ return new PlainTimeType(
271
+ ...this._with({ isNullable: true, isOptional: true }),
272
+ )
273
+ }
274
+
275
+ default(value: Temporal.PlainTime) {
276
+ return new PlainTimeType(
277
+ ...this._with({
278
+ options: { default: PlainTimeType.transformer.encode(value) },
279
+ hasDefault: true,
280
+ }),
281
+ )
282
+ }
283
+
284
+ description(description: string) {
285
+ return new PlainTimeType(...this._with({ options: { description } }))
286
+ }
287
+
288
+ examples(...examples: string[]) {
289
+ return new PlainTimeType(...this._with({ options: { examples } }))
124
290
  }
125
291
  }
126
292
 
127
293
  export class DurationType<
128
294
  N extends boolean = false,
129
295
  O extends boolean = false,
130
- > extends BaseType<TTransform<TString, Temporal.Duration>, N, O> {
131
- constructor(nullable: N = false as N, optional: O = false as O) {
132
- super(
133
- Type.Transform(
134
- Type.String({
135
- /* TODO: duration format, or regex? */
136
- }),
137
- )
138
- .Decode((value) => Temporal.Duration.from(value))
139
- .Encode((value) => value.toString({ smallestUnit: 'microsecond' })),
140
- nullable,
141
- optional,
142
- )
296
+ D extends boolean = false,
297
+ > extends BaseType<
298
+ TTransform<TString, Temporal.Duration>,
299
+ N,
300
+ O,
301
+ D,
302
+ StringOptions
303
+ > {
304
+ static readonly transformer = createTemporalTransformer('Duration')
305
+
306
+ constructor(
307
+ options: StringOptions = {},
308
+ isNullable: N = false as N,
309
+ isOptional: O = false as O,
310
+ hasDefault: D = false as D,
311
+ ) {
312
+ super(options, isNullable, isOptional, hasDefault)
313
+ }
314
+
315
+ protected _constructSchema(
316
+ options: SchemaOptions,
317
+ ): TTransform<TString, Temporal.Duration> {
318
+ return Type.Transform(Type.String({ ...options, format: 'duration' }))
319
+ .Decode(DurationType.transformer.decode)
320
+ .Encode(DurationType.transformer.encode)
143
321
  }
144
322
 
145
323
  nullable() {
146
- const [_, ...args] = this._nullable()
147
- return new DurationType(...args)
324
+ return new DurationType(...this._with({ isNullable: true }))
148
325
  }
149
326
 
150
327
  optional() {
151
- const [_, ...args] = this._optional()
152
- return new DurationType(...args)
328
+ return new DurationType(...this._with({ isOptional: true }))
153
329
  }
154
330
 
155
331
  nullish() {
156
- const [_, ...args] = this._nullish()
157
- return new DurationType(...args)
332
+ return new DurationType(
333
+ ...this._with({ isNullable: true, isOptional: true }),
334
+ )
335
+ }
336
+
337
+ default(value: Temporal.Duration) {
338
+ return new DurationType(
339
+ ...this._with({
340
+ options: { default: DurationType.transformer.encode(value) },
341
+ hasDefault: true,
342
+ }),
343
+ )
344
+ }
345
+
346
+ description(description: string) {
347
+ return new DurationType(...this._with({ options: { description } }))
348
+ }
349
+
350
+ examples(...examples: string[]) {
351
+ return new DurationType(...this._with({ options: { examples } }))
158
352
  }
159
353
  }
160
354
 
161
355
  export class PlainYearMonthType<
162
356
  N extends boolean = false,
163
357
  O extends boolean = false,
164
- > extends BaseType<TTransform<TString, Temporal.PlainYearMonth>, N, O> {
165
- constructor(nullable: N = false as N, optional: O = false as O) {
166
- super(
167
- Type.Transform(
168
- Type.String({
169
- /* TODO: duration format, or regex? */
170
- }),
171
- )
172
- .Decode((value) => Temporal.PlainYearMonth.from(value))
173
- .Encode((value) => value.toString({ calendarName: 'never' })),
174
- nullable,
175
- optional,
358
+ D extends boolean = false,
359
+ > extends BaseType<
360
+ TTransform<TString, Temporal.PlainYearMonth>,
361
+ N,
362
+ O,
363
+ D,
364
+ StringOptions
365
+ > {
366
+ static readonly transformer = createTemporalTransformer('PlainYearMonth')
367
+
368
+ constructor(
369
+ options: StringOptions = {},
370
+ isNullable: N = false as N,
371
+ isOptional: O = false as O,
372
+ hasDefault: D = false as D,
373
+ ) {
374
+ super(options, isNullable, isOptional, hasDefault)
375
+ }
376
+
377
+ protected _constructSchema(
378
+ options: SchemaOptions,
379
+ ): TTransform<TString, Temporal.PlainYearMonth> {
380
+ return Type.Transform(
381
+ Type.String({
382
+ ...options,
383
+ // TODO: duration format, or regex?
384
+ }),
176
385
  )
386
+ .Decode(PlainYearMonthType.transformer.decode)
387
+ .Encode(PlainYearMonthType.transformer.encode)
177
388
  }
178
389
 
179
390
  nullable() {
180
- const [_, ...args] = this._nullable()
181
- return new PlainYearMonthType(...args)
391
+ return new PlainYearMonthType(...this._with({ isNullable: true }))
182
392
  }
183
393
 
184
394
  optional() {
185
- const [_, ...args] = this._optional()
186
- return new PlainYearMonthType(...args)
395
+ return new PlainYearMonthType(...this._with({ isOptional: true }))
187
396
  }
188
397
 
189
398
  nullish() {
190
- const [_, ...args] = this._nullish()
191
- return new PlainYearMonthType(...args)
399
+ return new PlainYearMonthType(
400
+ ...this._with({ isNullable: true, isOptional: true }),
401
+ )
402
+ }
403
+
404
+ default(value: Temporal.PlainYearMonth) {
405
+ return new PlainYearMonthType(
406
+ ...this._with({
407
+ options: { default: PlainYearMonthType.transformer.encode(value) },
408
+ hasDefault: true,
409
+ }),
410
+ )
411
+ }
412
+
413
+ description(description: string) {
414
+ return new PlainYearMonthType(...this._with({ options: { description } }))
415
+ }
416
+
417
+ examples(...examples: string[]) {
418
+ return new PlainYearMonthType(...this._with({ options: { examples } }))
192
419
  }
193
420
  }
194
421
 
195
422
  export class PlainMonthDayType<
196
423
  N extends boolean = false,
197
424
  O extends boolean = false,
198
- > extends BaseType<TTransform<TString, Temporal.PlainMonthDay>, N, O> {
199
- constructor(nullable: N = false as N, optional: O = false as O) {
200
- super(
201
- Type.Transform(
202
- Type.String({
203
- /* TODO: duration format, or regex? */
204
- }),
205
- )
206
- .Decode((value) => Temporal.PlainMonthDay.from(value))
207
- .Encode((value) => value.toString({ calendarName: 'never' })),
208
- nullable,
209
- optional,
425
+ D extends boolean = false,
426
+ > extends BaseType<
427
+ TTransform<TString, Temporal.PlainMonthDay>,
428
+ N,
429
+ O,
430
+ D,
431
+ StringOptions
432
+ > {
433
+ static readonly transformer = createTemporalTransformer('PlainMonthDay')
434
+
435
+ constructor(
436
+ options: StringOptions = {},
437
+ isNullable: N = false as N,
438
+ isOptional: O = false as O,
439
+ hasDefault: D = false as D,
440
+ ) {
441
+ super(options, isNullable, isOptional, hasDefault)
442
+ }
443
+
444
+ protected _constructSchema(
445
+ options: SchemaOptions,
446
+ ): TTransform<TString, Temporal.PlainMonthDay> {
447
+ return Type.Transform(
448
+ Type.String({
449
+ ...options,
450
+ // TODO: duration format, or regex?
451
+ }),
210
452
  )
453
+ .Decode(PlainMonthDayType.transformer.decode)
454
+ .Encode(PlainMonthDayType.transformer.encode)
211
455
  }
212
456
 
213
457
  nullable() {
214
- const [_, ...args] = this._nullable()
215
- return new PlainMonthDayType(...args)
458
+ return new PlainMonthDayType(...this._with({ isNullable: true }))
216
459
  }
217
460
 
218
461
  optional() {
219
- const [_, ...args] = this._optional()
220
- return new PlainMonthDayType(...args)
462
+ return new PlainMonthDayType(...this._with({ isOptional: true }))
221
463
  }
222
464
 
223
465
  nullish() {
224
- const [_, ...args] = this._nullish()
225
- return new PlainMonthDayType(...args)
466
+ return new PlainMonthDayType(
467
+ ...this._with({ isNullable: true, isOptional: true }),
468
+ )
469
+ }
470
+
471
+ default(value: Temporal.PlainMonthDay) {
472
+ return new PlainMonthDayType(
473
+ ...this._with({
474
+ options: { default: PlainMonthDayType.transformer.encode(value) },
475
+ hasDefault: true,
476
+ }),
477
+ )
478
+ }
479
+
480
+ description(description: string) {
481
+ return new PlainMonthDayType(...this._with({ options: { description } }))
482
+ }
483
+
484
+ examples(...examples: string[]) {
485
+ return new PlainMonthDayType(...this._with({ options: { examples } }))
226
486
  }
227
487
  }