@nmtjs/type 0.4.7 → 0.5.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.
Files changed (69) hide show
  1. package/dist/compiler.js +84 -38
  2. package/dist/compiler.js.map +1 -1
  3. package/dist/formats.js +1 -1
  4. package/dist/formats.js.map +1 -1
  5. package/dist/index.js +53 -22
  6. package/dist/index.js.map +1 -1
  7. package/dist/schemas/discriminated-union.js +9 -0
  8. package/dist/schemas/discriminated-union.js.map +1 -0
  9. package/dist/schemas/nullable.js +1 -6
  10. package/dist/schemas/nullable.js.map +1 -1
  11. package/dist/temporal.js +7 -7
  12. package/dist/temporal.js.map +1 -1
  13. package/dist/types/any.js +3 -43
  14. package/dist/types/any.js.map +1 -1
  15. package/dist/types/array.js +17 -63
  16. package/dist/types/array.js.map +1 -1
  17. package/dist/types/base.js +78 -41
  18. package/dist/types/base.js.map +1 -1
  19. package/dist/types/boolean.js +3 -43
  20. package/dist/types/boolean.js.map +1 -1
  21. package/dist/types/custom.js +8 -48
  22. package/dist/types/custom.js.map +1 -1
  23. package/dist/types/date.js +8 -0
  24. package/dist/types/date.js.map +1 -0
  25. package/dist/types/enum.js +10 -94
  26. package/dist/types/enum.js.map +1 -1
  27. package/dist/types/literal.js +3 -43
  28. package/dist/types/literal.js.map +1 -1
  29. package/dist/types/never.js +3 -26
  30. package/dist/types/never.js.map +1 -1
  31. package/dist/types/number.js +52 -186
  32. package/dist/types/number.js.map +1 -1
  33. package/dist/types/object.js +10 -131
  34. package/dist/types/object.js.map +1 -1
  35. package/dist/types/string.js +25 -65
  36. package/dist/types/string.js.map +1 -1
  37. package/dist/types/temporal.js +23 -328
  38. package/dist/types/temporal.js.map +1 -1
  39. package/dist/types/union.js +16 -90
  40. package/dist/types/union.js.map +1 -1
  41. package/dist/utils.js.map +1 -1
  42. package/package.json +3 -3
  43. package/src/compiler.ts +124 -41
  44. package/src/formats.ts +1 -1
  45. package/src/index.ts +145 -63
  46. package/src/schemas/discriminated-union.ts +49 -0
  47. package/src/schemas/nullable.ts +7 -13
  48. package/src/temporal.ts +8 -7
  49. package/src/types/any.ts +6 -46
  50. package/src/types/array.ts +38 -86
  51. package/src/types/base.ts +205 -81
  52. package/src/types/boolean.ts +13 -47
  53. package/src/types/custom.ts +21 -79
  54. package/src/types/date.ts +10 -0
  55. package/src/types/enum.ts +18 -107
  56. package/src/types/literal.ts +7 -63
  57. package/src/types/never.ts +6 -36
  58. package/src/types/number.ts +52 -188
  59. package/src/types/object.ts +61 -202
  60. package/src/types/string.ts +25 -61
  61. package/src/types/temporal.ts +53 -410
  62. package/src/types/union.ts +98 -138
  63. package/src/utils.ts +8 -0
  64. package/dist/constants.js +0 -2
  65. package/dist/constants.js.map +0 -1
  66. package/dist/types/datetime.js +0 -53
  67. package/dist/types/datetime.js.map +0 -1
  68. package/src/constants.ts +0 -5
  69. package/src/types/datetime.ts +0 -65
@@ -1,97 +1,49 @@
1
- import { type ArrayOptions, type TArray, Type } from '@sinclair/typebox'
2
- import type { typeStatic } from '../constants.ts'
3
- import { BaseType, getTypeSchema } from './base.ts'
4
-
5
- export class ArrayType<
6
- T extends BaseType = BaseType,
7
- N extends boolean = false,
8
- O extends boolean = false,
9
- D extends boolean = false,
10
- > extends BaseType<TArray<T[typeStatic]['schema']>, N, O, D, ArrayOptions> {
11
- constructor(
12
- readonly element: T,
13
- options: ArrayOptions = {},
14
- isNullable: N = false as N,
15
- isOptional: O = false as O,
16
- hasDefault: D = false as D,
17
- ) {
18
- super(options, isNullable, isOptional, hasDefault, element)
19
- }
20
-
21
- protected _constructSchema(
22
- options: ArrayOptions,
23
- element: T,
24
- ): TArray<T[typeStatic]['schema']> {
25
- return Type.Array(getTypeSchema(element), options)
26
- }
27
-
28
- nullable() {
29
- return new ArrayType(this.element, ...this._with({ isNullable: true }))
30
- }
31
-
32
- optional() {
33
- return new ArrayType(this.element, ...this._with({ isOptional: true }))
34
- }
35
-
36
- nullish() {
37
- return new ArrayType(
38
- this.element,
39
- ...this._with({ isNullable: true, isOptional: true }),
40
- )
41
- }
42
-
43
- default(value: this[typeStatic]['encoded']) {
44
- return new ArrayType(
45
- this.element,
46
- ...this._with({
47
- options: { default: value },
48
- hasDefault: true,
49
- }),
50
- )
51
- }
52
-
53
- description(description: string) {
54
- return new ArrayType(
55
- this.element,
56
- ...this._with({ options: { description } }),
57
- )
58
- }
59
-
60
- examples(
61
- ...examples: [this[typeStatic]['encoded'], ...this[typeStatic]['encoded'][]]
62
- ) {
63
- return new ArrayType(
64
- this.element,
65
- ...this._with({
66
- options: { example: examples[0], examples },
67
- }),
68
- )
1
+ import {
2
+ type ArrayOptions,
3
+ type StaticDecode,
4
+ type TArray,
5
+ Type,
6
+ } from '@sinclair/typebox'
7
+ import { BaseType } from './base.ts'
8
+
9
+ export class ArrayType<T extends BaseType = BaseType> extends BaseType<
10
+ TArray<T['schema']>,
11
+ { element: T; options: ArrayOptions }
12
+ > {
13
+ _!: {
14
+ encoded: {
15
+ input: TArray<T['_']['encoded']['input']>
16
+ output: TArray<T['_']['encoded']['output']>
17
+ }
18
+ decoded: {
19
+ input: TArray<T['_']['decoded']['input']>
20
+ output: TArray<T['_']['decoded']['output']>
21
+ }
22
+ }
23
+
24
+ static factory<T extends BaseType>(element: T, options: ArrayOptions = {}) {
25
+ return new ArrayType<T>(Type.Array(element.schema, options))
69
26
  }
70
27
 
71
28
  min(value: number) {
72
- return new ArrayType(
73
- this.element,
74
- ...this._with({
75
- options: { minItems: value },
76
- }),
77
- )
29
+ return ArrayType.factory(this.props.element, {
30
+ ...this.props.options,
31
+ minItems: value,
32
+ })
78
33
  }
79
34
 
80
35
  max(value: number) {
81
- return new ArrayType(
82
- this.element,
83
- ...this._with({
84
- options: { maxItems: value },
85
- }),
86
- )
36
+ return ArrayType.factory(this.props.element, {
37
+ ...this.props.options,
38
+ maxItems: value,
39
+ })
87
40
  }
88
41
 
89
42
  length(value: number) {
90
- return new ArrayType(
91
- this.element,
92
- ...this._with({
93
- options: { minItems: value, maxItems: value },
94
- }),
95
- )
43
+ return ArrayType.factory(this.props.element, {
44
+ ...this.props.options,
45
+ minItems: value,
46
+ maxItems: value,
47
+ })
96
48
  }
97
49
  }
package/src/types/base.ts CHANGED
@@ -1,109 +1,233 @@
1
1
  import {
2
+ Optional,
2
3
  type SchemaOptions,
3
4
  type StaticDecode,
4
5
  type StaticEncode,
5
- type TAny,
6
- type TOptional,
7
6
  type TSchema,
8
- Type,
9
7
  } from '@sinclair/typebox'
10
- import { typeSchema, typeStatic } from '../constants.ts'
11
- import { Nullable, type TNullable } from '../schemas/nullable.ts'
8
+ import {
9
+ Nullable,
10
+ type TNullable,
11
+ type TOptionalUndefined,
12
+ } from '../schemas/nullable.ts'
13
+ import type { Merge } from '../utils.ts'
14
+
15
+ export type TypeProps = Record<string, any>
16
+
17
+ export type TypeParams = {
18
+ optional?: boolean
19
+ nullable?: boolean
20
+ hasDefault?: boolean
21
+ encode?: (value: any) => any
22
+ }
23
+
24
+ export type DefaultTypeParams = {
25
+ optional: false
26
+ nullable: false
27
+ hasDefault: false
28
+ encode?: TypeParams['encode']
29
+ }
12
30
 
13
- type ResolveNullable<T extends TSchema, Is extends boolean> = Is extends true
14
- ? TNullable<T>
31
+ export type BaseTypeAny<T extends TSchema = TSchema> = BaseType<T, any, any>
32
+
33
+ type ResolveNullable<
34
+ T extends TSchema,
35
+ P extends TypeParams,
36
+ > = P['nullable'] extends true
37
+ ? T extends TNullable<infer S>
38
+ ? TNullable<S>
39
+ : TNullable<T>
15
40
  : T
16
41
 
17
- type ResolveOptional<T extends TSchema, Is extends boolean> = Is extends true
18
- ? TOptional<T>
42
+ type ResolveOptional<
43
+ T extends TSchema,
44
+ P extends TypeParams,
45
+ > = P['optional'] extends true
46
+ ? T extends TOptionalUndefined<infer S>
47
+ ? TOptionalUndefined<S>
48
+ : TOptionalUndefined<T>
19
49
  : T
20
50
 
21
- type Resolve<
22
- Schema extends TSchema,
23
- IsNullable extends boolean,
24
- IsOptional extends boolean,
25
- > = ResolveOptional<ResolveNullable<Schema, IsNullable>, IsOptional>
51
+ type ResolveDefault<
52
+ T extends TSchema,
53
+ P extends TypeParams,
54
+ > = P['hasDefault'] extends true
55
+ ? T extends TOptionalUndefined<infer U>
56
+ ? U
57
+ : T
58
+ : T
26
59
 
27
60
  export abstract class BaseType<
28
61
  Schema extends TSchema = TSchema,
29
- IsNullable extends boolean = boolean,
30
- IsOptional extends boolean = boolean,
31
- HasDefault extends boolean = boolean,
32
- Options extends SchemaOptions = SchemaOptions,
62
+ Props extends TypeProps = TypeProps,
63
+ Params extends TypeParams = DefaultTypeParams,
33
64
  > {
34
- protected abstract _constructSchema(
35
- options: Options,
36
- ...constructArgs: any[]
37
- ): Schema
38
-
39
- [typeStatic]!: {
40
- schema: Resolve<
41
- Schema,
42
- IsNullable,
43
- HasDefault extends true ? false : IsOptional
44
- >
45
- isOptional: IsOptional
46
- isNullable: IsNullable
47
- hasDefault: HasDefault
48
- encoded: StaticEncode<Resolve<Schema, IsNullable, IsOptional>>
49
- decoded: StaticDecode<
50
- Resolve<Schema, IsNullable, HasDefault extends true ? false : IsOptional>
51
- >
65
+ abstract _: {
66
+ encoded: {
67
+ input: TSchema
68
+ output: TSchema
69
+ }
70
+ decoded: {
71
+ input: TSchema
72
+ output: TSchema
73
+ }
52
74
  }
53
75
 
76
+ readonly schema: Schema
77
+ readonly final: TSchema
78
+ readonly props: Props
79
+ readonly params: Params
80
+
54
81
  constructor(
55
- protected options: Options = {} as Options,
56
- protected isNullable: IsNullable = false as IsNullable,
57
- protected isOptional: IsOptional = false as IsOptional,
58
- protected hasDefault: HasDefault = false as HasDefault,
59
- ...contstructArgs: any[]
82
+ schema: Schema,
83
+ props: Props = {} as Props,
84
+ params: Params = {} as Params,
60
85
  ) {
61
- let schema: TSchema = this._constructSchema(options, ...contstructArgs)
62
- if (this.isNullable) {
63
- schema = Nullable(schema)
64
- }
65
- if (this.isOptional) {
66
- schema = Type.Optional(schema)
67
- }
68
- this[typeSchema] = schema as Schema
86
+ const { hasDefault = false, nullable = false, optional = false } = params
87
+ this.schema = schema
88
+ this.final = schema
89
+ if (nullable) this.final = Nullable(this.final) as any
90
+ if (optional || hasDefault) this.final = Optional(this.final) as any
91
+
92
+ this.props = props
93
+ this.params = {
94
+ hasDefault,
95
+ nullable,
96
+ optional,
97
+ } as Params
98
+ }
99
+
100
+ optional(): OptionalType<this> {
101
+ return OptionalType.factory(this) as any
69
102
  }
70
- protected [typeSchema]: Schema
71
103
 
72
- protected get _args(): [IsNullable, IsOptional, HasDefault] {
73
- return [this.isNullable, this.isOptional, this.hasDefault]
104
+ nullable(): NullableType<this> {
105
+ return NullableType.factory(this) as any
74
106
  }
75
107
 
76
- protected _with<
77
- _IsNullable extends boolean = IsNullable,
78
- _IsOptional extends boolean = IsOptional,
79
- _HasDefault extends boolean = HasDefault,
80
- >({
81
- options = this.options as Options,
82
- isNullable = this.isNullable as unknown as _IsNullable,
83
- isOptional = this.isOptional as unknown as _IsOptional,
84
- hasDefault = this.hasDefault as unknown as _HasDefault,
85
- }: {
86
- options?: Options
87
- isNullable?: _IsNullable
88
- isOptional?: _IsOptional
89
- hasDefault?: _HasDefault
90
- } = {}): [Options, _IsNullable, _IsOptional, _HasDefault] {
91
- return [{ ...this.options, ...options }, isNullable, isOptional, hasDefault]
108
+ nullish() {
109
+ return this.nullable().optional()
92
110
  }
93
111
 
94
- abstract optional(): BaseType<Schema, IsNullable, true, HasDefault>
95
- abstract nullish(): BaseType<Schema, true, true, HasDefault>
96
- abstract default(value: any): BaseType<Schema, IsNullable, IsOptional, true>
97
- abstract description(
98
- value: string,
99
- ): BaseType<Schema, IsNullable, IsOptional, HasDefault>
100
- abstract examples(
101
- ...values: any[]
102
- ): BaseType<Schema, IsNullable, IsOptional, HasDefault>
112
+ default(
113
+ value: StaticDecode<this['_']['decoded']['output']>,
114
+ ): DefaultType<this> {
115
+ return DefaultType.factory(
116
+ this,
117
+ this.params.encode?.(value) ?? value,
118
+ ) as any
119
+ }
120
+
121
+ description(description: string): this {
122
+ const ThisConstructor = this.constructor as any
123
+ return new ThisConstructor(
124
+ {
125
+ ...this.schema,
126
+ description,
127
+ },
128
+ this.props,
129
+ this.params,
130
+ ) as any
131
+ }
132
+
133
+ examples(...examples: any[]): this {
134
+ const ThisConstructor = this.constructor as any
135
+ return new ThisConstructor(
136
+ {
137
+ ...this.schema,
138
+ examples,
139
+ },
140
+ this.props,
141
+ this.params,
142
+ ) as any
143
+ }
103
144
  }
104
145
 
105
- export function getTypeSchema<T extends BaseType>(
106
- type: T,
107
- ): T[typeStatic]['schema'] {
108
- return type[typeSchema]
146
+ export type ConstantType<T extends TSchema> = {
147
+ encoded: {
148
+ input: T
149
+ output: T
150
+ }
151
+ decoded: {
152
+ input: T
153
+ output: T
154
+ }
155
+ }
156
+
157
+ export type Static<
158
+ T extends BaseTypeAny,
159
+ P extends TypeProps,
160
+ Params extends Merge<T['params'], P> = Merge<T['params'], P>,
161
+ > = {
162
+ encoded: {
163
+ input: ResolveOptional<
164
+ ResolveNullable<T['_']['encoded']['input'], Params>,
165
+ Params
166
+ >
167
+ output: ResolveDefault<
168
+ ResolveOptional<
169
+ ResolveNullable<T['_']['encoded']['output'], Params>,
170
+ Params
171
+ >,
172
+ Params
173
+ >
174
+ }
175
+ decoded: {
176
+ input: ResolveOptional<
177
+ ResolveNullable<T['_']['decoded']['input'], Params>,
178
+ Params
179
+ >
180
+ output: ResolveDefault<
181
+ ResolveOptional<
182
+ ResolveNullable<T['_']['decoded']['output'], Params>,
183
+ Params
184
+ >,
185
+ Params
186
+ >
187
+ }
188
+ }
189
+
190
+ export class OptionalType<
191
+ Type extends BaseTypeAny<any>,
192
+ Params extends TypeParams = DefaultTypeParams,
193
+ > extends BaseType<Type['schema'], { inner: Type }, Params> {
194
+ _!: Static<Type, Params>
195
+
196
+ static factory<T extends BaseTypeAny<any>>(type: T) {
197
+ return new OptionalType<T, Merge<T['params'], { optional: true }>>(
198
+ type.schema,
199
+ { inner: type },
200
+ { ...type.params, optional: true } as any,
201
+ )
202
+ }
203
+ }
204
+
205
+ export class NullableType<
206
+ Type extends BaseTypeAny<any>,
207
+ Params extends TypeParams = DefaultTypeParams,
208
+ > extends BaseType<Type['schema'], { inner: Type }, Params> {
209
+ _!: Static<Type, Params>
210
+
211
+ static factory<T extends BaseTypeAny<any>>(type: T) {
212
+ return new NullableType<T, Merge<T['params'], { nullable: true }>>(
213
+ type.schema,
214
+ { inner: type },
215
+ { ...type.params, nullable: true } as any,
216
+ )
217
+ }
218
+ }
219
+
220
+ export class DefaultType<
221
+ Type extends BaseTypeAny<any>,
222
+ Params extends TypeParams = DefaultTypeParams,
223
+ > extends BaseType<Type['schema'], { inner: Type }, Params> {
224
+ _!: Static<Type, Params>
225
+
226
+ static factory<T extends BaseTypeAny<any>>(type: T, defaultValue: any) {
227
+ return new DefaultType<T, Merge<T['params'], { hasDefault: true }>>(
228
+ { ...type.schema, default: defaultValue },
229
+ { inner: type },
230
+ { ...type.params, hasDefault: true } as any,
231
+ )
232
+ }
109
233
  }
@@ -1,49 +1,15 @@
1
- import { type SchemaOptions, type TBoolean, Type } from '@sinclair/typebox'
2
- import { BaseType } from './base.ts'
3
-
4
- export class BooleanType<
5
- N extends boolean = false,
6
- O extends boolean = false,
7
- D extends boolean = false,
8
- > extends BaseType<TBoolean, N, O, D> {
9
- constructor(
10
- options: SchemaOptions = {},
11
- isNullable: N = false as N,
12
- isOptional: O = false as O,
13
- hasDefault: D = false as D,
14
- ) {
15
- super(options, isNullable, isOptional, hasDefault)
16
- }
17
-
18
- protected _constructSchema(options: SchemaOptions): TBoolean {
19
- return Type.Boolean(options)
20
- }
21
-
22
- nullable() {
23
- return new BooleanType(...this._with({ isNullable: true }))
24
- }
25
-
26
- optional() {
27
- return new BooleanType(...this._with({ isOptional: true }))
28
- }
29
-
30
- nullish() {
31
- return new BooleanType(
32
- ...this._with({ isNullable: true, isOptional: true }),
33
- )
34
- }
35
-
36
- default(value: boolean) {
37
- return new BooleanType(
38
- ...this._with({ options: { default: value }, hasDefault: true }),
39
- )
40
- }
41
-
42
- description(description: string) {
43
- return new BooleanType(...this._with({ options: { description } }))
44
- }
45
-
46
- examples(...examples: [boolean, ...boolean[]]) {
47
- return new BooleanType(...this._with({ options: { examples } }))
1
+ import {
2
+ type SchemaOptions,
3
+ type StaticDecode,
4
+ type TBoolean,
5
+ Type,
6
+ } from '@sinclair/typebox'
7
+ import { BaseType, type ConstantType } from './base.ts'
8
+
9
+ export class BooleanType extends BaseType<TBoolean> {
10
+ _!: ConstantType<this['schema']>
11
+
12
+ static factory() {
13
+ return new BooleanType(Type.Boolean())
48
14
  }
49
15
  }
@@ -1,90 +1,32 @@
1
1
  import {
2
- type SchemaOptions,
2
+ type TAny,
3
3
  type TTransform,
4
4
  type TUnsafe,
5
5
  Type,
6
6
  } from '@sinclair/typebox'
7
- import { BaseType } from './base.ts'
7
+ import { BaseType, type ConstantType } from './base.ts'
8
8
 
9
- type CustomDecode<T> = (value: any) => T
10
- type CustomEncode<T> = (value: T) => any
9
+ export type CustomTypeDecode<T> = (value: any) => T
10
+ export type CustomTypeEncode<T> = (value: T) => any
11
11
 
12
- export class CustomType<
13
- T,
14
- S = T,
15
- N extends boolean = false,
16
- O extends boolean = false,
17
- D extends boolean = false,
18
- > extends BaseType<TTransform<TUnsafe<S>, T>, N, O, D> {
19
- constructor(
20
- protected readonly decode: CustomDecode<T>,
21
- protected readonly encode: CustomEncode<T>,
22
- options: SchemaOptions = {},
23
- isNullable: N = false as N,
24
- isOptional: O = false as O,
25
- hasDefault: D = false as D,
26
- ) {
27
- super(options, isNullable, isOptional, hasDefault, decode, encode)
28
- }
29
-
30
- protected _constructSchema(
31
- options: SchemaOptions,
32
- decode: CustomDecode<T>,
33
- encode: CustomEncode<T>,
34
- ): TTransform<TUnsafe<S>, T> {
35
- return Type.Transform(Type.Any(options) as unknown as TUnsafe<S>)
36
- .Decode(decode)
37
- .Encode(encode)
38
- }
39
-
40
- nullable() {
41
- return new CustomType<T, S, true, O, D>(
42
- this.decode,
43
- this.encode,
44
- ...this._with({ isNullable: true }),
45
- )
46
- }
47
-
48
- optional() {
49
- return new CustomType<T, S, N, true, D>(
50
- this.decode,
51
- this.encode,
52
- ...this._with({ isOptional: true }),
53
- )
54
- }
55
-
56
- nullish() {
57
- return new CustomType<T, S, true, true, D>(
58
- this.decode,
59
- this.encode,
60
- ...this._with({ isNullable: true, isOptional: true }),
61
- )
62
- }
63
-
64
- default(value: T) {
65
- return new CustomType<T, S, N, O, true>(
66
- this.decode,
67
- this.encode,
68
- ...this._with({
69
- options: { default: this.encode(value) },
70
- hasDefault: true,
71
- }),
72
- )
73
- }
74
-
75
- description(description: string) {
76
- return new CustomType<T, S, N, O, D>(
77
- this.decode,
78
- this.encode,
79
- ...this._with({ options: { description } }),
80
- )
81
- }
12
+ export abstract class TransformType<T, S = TAny> extends BaseType<
13
+ TTransform<TUnsafe<S>, T>
14
+ > {
15
+ _!: ConstantType<this['schema']>
16
+ }
82
17
 
83
- examples(...examples: [T, ...T[]]) {
84
- return new CustomType<T, S, N, O, D>(
85
- this.decode,
86
- this.encode,
87
- ...this._with({ options: { examples: examples.map(this.encode) } }),
18
+ export class CustomType<T, S = TAny> extends TransformType<T, S> {
19
+ static factory<T, S = TAny>(
20
+ decode: CustomTypeDecode<T>,
21
+ encode: CustomTypeEncode<T>,
22
+ schema = Type.Any() as unknown as TUnsafe<S>,
23
+ ) {
24
+ return new CustomType<T, S>(
25
+ Type.Transform(schema as unknown as TUnsafe<S>)
26
+ .Decode(decode)
27
+ .Encode(encode),
28
+ {},
29
+ { encode } as any,
88
30
  )
89
31
  }
90
32
  }
@@ -0,0 +1,10 @@
1
+ import { CustomType, TransformType } from './custom.ts'
2
+
3
+ const decode = (value: any): Date => new Date(value)
4
+ const encode = (value: Date): any => value.toISOString()
5
+
6
+ export class DateType extends TransformType<Date> {
7
+ static factory() {
8
+ return CustomType.factory<Date>(decode, encode)
9
+ }
10
+ }