@strictly/define 0.0.1 → 0.0.2

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 (199) hide show
  1. package/.out/index.d.ts +17 -11
  2. package/.out/index.js +17 -11
  3. package/.out/transformers/copies/copy.d.ts +3 -3
  4. package/.out/transformers/copies/copy_to.d.ts +3 -3
  5. package/.out/transformers/copies/copy_to.js +4 -0
  6. package/.out/transformers/copies/mobx_copy.d.ts +4 -4
  7. package/.out/transformers/copies/mobx_copy.js +1 -1
  8. package/.out/transformers/copies/specs/copy_to.tests.js +8 -8
  9. package/.out/transformers/copies/specs/mobx_copy.tests.js +1 -1
  10. package/.out/transformers/flatteners/flatten_accessors_of_type.d.ts +5 -0
  11. package/.out/transformers/flatteners/flatten_accessors_of_type.js +11 -0
  12. package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.d.ts +2 -2
  13. package/.out/transformers/flatteners/flatten_json_value_to_type_paths_of.js +2 -2
  14. package/.out/transformers/flatteners/{flatten_type_def_to.d.ts → flatten_type_to.d.ts} +1 -1
  15. package/.out/transformers/flatteners/{flatten_type_def_to.js → flatten_type_to.js} +1 -1
  16. package/.out/transformers/flatteners/{flatten_type_defs_of.d.ts → flatten_types_of_type.d.ts} +1 -1
  17. package/.out/transformers/flatteners/flatten_types_of_type.js +7 -0
  18. package/.out/transformers/flatteners/flatten_validation_errors_of_type.d.ts +22 -0
  19. package/.out/transformers/flatteners/flatten_validation_errors_of_type.js +10 -0
  20. package/.out/transformers/flatteners/flatten_validators_of_validating_type.d.ts +4 -0
  21. package/.out/transformers/flatteners/flatten_validators_of_validating_type.js +17 -0
  22. package/.out/transformers/flatteners/{flatten_value_type_to.d.ts → flatten_value_to.d.ts} +4 -4
  23. package/.out/transformers/flatteners/{flatten_value_type_to.js → flatten_value_to.js} +7 -2
  24. package/.out/transformers/flatteners/flatten_values_of_type.d.ts +3 -0
  25. package/.out/transformers/flatteners/flatten_values_of_type.js +7 -0
  26. package/.out/transformers/flatteners/specs/{flatten_accessors_of.tests.js → flatten_accessors_of_type.tests.js} +5 -6
  27. package/.out/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.js +6 -6
  28. package/.out/transformers/flatteners/specs/{flatten_type_def_to.tests.js → flatten_type_to.tests.js} +15 -13
  29. package/.out/transformers/flatteners/specs/flatten_types_of_type.tests.js +18 -0
  30. package/.out/transformers/flatteners/specs/flatten_validation_errors_of_type.tests.js +25 -0
  31. package/.out/transformers/flatteners/specs/{flatten_value_type_to.tests.js → flatten_value_to.tests.js} +81 -58
  32. package/.out/transformers/flatteners/specs/{flatten_value_types_of.tests.js → flatten_values_of_type.tests.js} +4 -4
  33. package/.out/transformers/flatteners/specs/value_path_to_type_path.tests.js +5 -3
  34. package/.out/transformers/flatteners/value_path_to_type_path.d.ts +1 -1
  35. package/.out/tsconfig.tsbuildinfo +1 -1
  36. package/.out/types/builders.d.ts +55 -29
  37. package/.out/types/builders.js +116 -32
  38. package/.out/types/definitions.d.ts +1 -1
  39. package/.out/types/flattened_accessors_of_type.d.ts +9 -0
  40. package/.out/types/{flattened_type_defs_of.d.ts → flattened_types_of_type.d.ts} +9 -6
  41. package/.out/types/flattened_types_of_validating_type.d.ts +25 -0
  42. package/.out/types/flattened_validators_of_validating_type.d.ts +10 -0
  43. package/.out/types/flattened_values_of_type.d.ts +6 -0
  44. package/.out/types/{mobx_value_type_of.d.ts → mobx_value_of_type.d.ts} +2 -2
  45. package/.out/types/{partial_type_def_of.d.ts → partial_type_of_type.d.ts} +1 -1
  46. package/.out/types/path_of.d.ts +1 -0
  47. package/.out/types/{json_paths_of.d.ts → paths_of_type.d.ts} +5 -5
  48. package/.out/types/readonly_type_of_type.d.ts +29 -0
  49. package/.out/types/specs/builder.tests.js +73 -23
  50. package/.out/types/specs/{flattened_accessors_of.tests.js → flattened_accessors_of_type.tests.js} +1 -1
  51. package/.out/types/specs/{flattened_type_defs_of.tests.js → flattened_types_of_type.tests.js} +22 -15
  52. package/.out/types/specs/flattened_validators_of_validating_type.tests.js +24 -0
  53. package/.out/types/specs/flattened_values_of_type.tests.js +18 -0
  54. package/.out/types/specs/{partial_type_def_of.tests.js → partial_type_of_type.tests.js} +4 -4
  55. package/.out/types/specs/{json_paths_of.tests.js → paths_of_type.tests.js} +19 -19
  56. package/.out/types/specs/{readonly_type_def_of.tests.js → readonly_type_of_type.tests.js} +6 -6
  57. package/.out/types/specs/type_of_type.tests.d.ts +1 -0
  58. package/.out/types/specs/type_of_type.tests.js +27 -0
  59. package/.out/types/specs/value_of_type.tests.d.ts +1 -0
  60. package/.out/types/specs/{value_type_of.tests.js → value_of_type.tests.js} +1 -1
  61. package/.out/types/specs/value_to_type_paths_of_type.tests.d.ts +1 -0
  62. package/.out/types/specs/{value_to_type_paths_of.tests.js → value_to_type_paths_of_type.tests.js} +9 -9
  63. package/.out/types/specs/value_types_of_discriminated_union.tests.js +2 -2
  64. package/.out/types/strict_definitions.d.ts +2 -2
  65. package/.out/types/type_of_type.d.ts +49 -0
  66. package/.out/types/type_of_type.js +70 -0
  67. package/.out/types/validating_definitions.d.ts +49 -0
  68. package/.out/types/validating_definitions.js +1 -0
  69. package/.out/types/validating_type_def_with_error.d.ts +55 -0
  70. package/.out/types/validating_type_def_with_error.js +1 -0
  71. package/.out/types/value_of_type.d.ts +24 -0
  72. package/.out/types/value_of_type.js +1 -0
  73. package/.out/types/{value_to_type_paths_of.d.ts → value_to_type_paths_of_type.d.ts} +13 -13
  74. package/.out/types/value_to_type_paths_of_type.js +1 -0
  75. package/.out/types/value_types_of_discriminated_union.d.ts +5 -4
  76. package/.out/validation/errors_of_validators.d.ts +4 -0
  77. package/.out/validation/errors_of_validators.js +1 -0
  78. package/.out/validation/specs/errors_of_validators.tests.d.ts +1 -0
  79. package/.out/validation/specs/errors_of_validators.tests.js +9 -0
  80. package/.out/validation/specs/validators_of_values.tests.d.ts +1 -0
  81. package/.out/validation/specs/validators_of_values.tests.js +21 -0
  82. package/.out/validation/validator.d.ts +21 -0
  83. package/.out/validation/validator.js +26 -0
  84. package/.out/validation/validators/defined_validator.d.ts +10 -0
  85. package/.out/validation/validators/defined_validator.js +18 -0
  86. package/.out/validation/validators/minimum_string_length_validator.d.ts +16 -0
  87. package/.out/validation/validators/minimum_string_length_validator.js +23 -0
  88. package/.out/validation/validators_of_values.d.ts +4 -0
  89. package/.out/validation/validators_of_values.js +1 -0
  90. package/.turbo/turbo-build.log +9 -9
  91. package/.turbo/turbo-check-types.log +1 -1
  92. package/.turbo/turbo-release$colon$exports.log +1 -1
  93. package/README.md +16 -2
  94. package/dist/index.cjs +364 -76
  95. package/dist/index.d.cts +365 -114
  96. package/dist/index.d.ts +365 -114
  97. package/dist/index.js +355 -73
  98. package/index.ts +17 -11
  99. package/package.json +11 -3
  100. package/transformers/copies/copy.ts +4 -4
  101. package/transformers/copies/copy_to.ts +11 -7
  102. package/transformers/copies/mobx_copy.ts +6 -6
  103. package/transformers/copies/specs/copy_to.tests.ts +8 -8
  104. package/transformers/copies/specs/mobx_copy.tests.ts +3 -3
  105. package/transformers/flatteners/{flatten_accessors_of.ts → flatten_accessors_of_type.ts} +10 -10
  106. package/transformers/flatteners/flatten_json_value_to_type_paths_of.ts +5 -5
  107. package/transformers/flatteners/{flatten_type_def_to.ts → flatten_type_to.ts} +1 -1
  108. package/transformers/flatteners/{flatten_type_defs_of.ts → flatten_types_of_type.ts} +3 -3
  109. package/transformers/flatteners/flatten_validation_errors_of_type.ts +93 -0
  110. package/transformers/flatteners/flatten_validators_of_validating_type.ts +32 -0
  111. package/transformers/flatteners/{flatten_value_type_to.ts → flatten_value_to.ts} +12 -7
  112. package/transformers/flatteners/{flatten_value_types_of.ts → flatten_values_of_type.ts} +6 -6
  113. package/transformers/flatteners/specs/{flatten_accessors_of.tests.ts → flatten_accessors_of_type.tests.ts} +10 -11
  114. package/transformers/flatteners/specs/flatten_json_value_to_type_paths_of.tests.ts +6 -6
  115. package/transformers/flatteners/specs/{flatten_type_def_to.tests.ts → flatten_type_to.tests.ts} +15 -13
  116. package/transformers/flatteners/specs/flatten_types_of_type.tests.ts +27 -0
  117. package/transformers/flatteners/specs/flatten_validation_errors_of_type.tests.ts +48 -0
  118. package/transformers/flatteners/specs/{flatten_value_type_to.tests.ts → flatten_value_to.tests.ts} +124 -91
  119. package/transformers/flatteners/specs/{flatten_value_types_of.tests.ts → flatten_values_of_type.tests.ts} +4 -4
  120. package/transformers/flatteners/specs/value_path_to_type_path.tests.ts +20 -18
  121. package/transformers/flatteners/value_path_to_type_path.ts +4 -4
  122. package/types/builders.ts +239 -71
  123. package/types/definitions.ts +2 -2
  124. package/types/{flattened_accessors_of.ts → flattened_accessors_of_type.ts} +3 -3
  125. package/types/{flattened_type_defs_of.ts → flattened_types_of_type.ts} +22 -12
  126. package/types/flattened_types_of_validating_type.ts +152 -0
  127. package/types/flattened_validators_of_validating_type.ts +33 -0
  128. package/types/flattened_values_of_type.ts +11 -0
  129. package/types/{mobx_value_type_of.ts → mobx_value_of_type.ts} +2 -2
  130. package/types/{partial_type_def_of.ts → partial_type_of_type.ts} +3 -1
  131. package/types/{json_path_of.ts → path_of.ts} +1 -1
  132. package/types/{json_paths_of.ts → paths_of_type.ts} +5 -5
  133. package/types/readonly_type_of_type.ts +54 -0
  134. package/types/specs/builder.tests.ts +205 -54
  135. package/types/specs/{flattened_accessors_of.tests.ts → flattened_accessors_of_type.tests.ts} +3 -3
  136. package/types/specs/{flattened_type_defs_of.tests.ts → flattened_types_of_type.tests.ts} +82 -34
  137. package/types/specs/flattened_validators_of_validating_type.tests.ts +47 -0
  138. package/types/specs/flattened_values_of_type.tests.ts +39 -0
  139. package/types/specs/{partial_type_def_of.tests.ts → partial_type_of_type.tests.ts} +11 -11
  140. package/types/specs/{json_paths_of.tests.ts → paths_of_type.tests.ts} +47 -47
  141. package/types/specs/{readonly_type_def_of.tests.ts → readonly_type_of_type.tests.ts} +14 -14
  142. package/types/specs/type_of_type.tests.ts +60 -0
  143. package/types/specs/{value_type_of.tests.ts → value_of_type.tests.ts} +15 -15
  144. package/types/specs/{value_to_type_paths_of.tests.ts → value_to_type_paths_of_type.tests.ts} +26 -25
  145. package/types/specs/value_types_of_discriminated_union.tests.ts +6 -6
  146. package/types/strict_definitions.ts +3 -3
  147. package/types/type_of_type.ts +178 -0
  148. package/types/validating_definitions.ts +109 -0
  149. package/types/validating_type_def_with_error.ts +93 -0
  150. package/types/value_of_type.ts +84 -0
  151. package/types/{value_to_type_paths_of.ts → value_to_type_paths_of_type.ts} +30 -29
  152. package/types/value_types_of_discriminated_union.ts +4 -3
  153. package/validation/errors_of_validators.ts +10 -0
  154. package/validation/specs/errors_of_validators.tests.ts +20 -0
  155. package/validation/specs/validators_of_values.tests.ts +68 -0
  156. package/validation/validator.ts +103 -0
  157. package/validation/validators/defined_validator.ts +22 -0
  158. package/validation/validators/minimum_string_length_validator.ts +36 -0
  159. package/validation/validators_of_values.ts +17 -0
  160. package/.out/transformers/flatteners/flatten_accessors_of.d.ts +0 -5
  161. package/.out/transformers/flatteners/flatten_accessors_of.js +0 -11
  162. package/.out/transformers/flatteners/flatten_type_defs_of.js +0 -7
  163. package/.out/transformers/flatteners/flatten_value_types_of.d.ts +0 -3
  164. package/.out/transformers/flatteners/flatten_value_types_of.js +0 -7
  165. package/.out/transformers/flatteners/specs/flatten_type_defs_of.tests.js +0 -17
  166. package/.out/types/flattened_accessors_of.d.ts +0 -9
  167. package/.out/types/flattened_value_types_of.d.ts +0 -6
  168. package/.out/types/json_path_of.d.ts +0 -1
  169. package/.out/types/readonly_type_def_of.d.ts +0 -29
  170. package/.out/types/specs/flattened_value_types_of.tests.js +0 -11
  171. package/.out/types/value_type_of.d.ts +0 -24
  172. package/transformers/flatteners/specs/flatten_type_defs_of.tests.ts +0 -26
  173. package/types/flattened_value_types_of.ts +0 -11
  174. package/types/readonly_type_def_of.ts +0 -53
  175. package/types/specs/flattened_value_types_of.tests.ts +0 -21
  176. package/types/value_type_of.ts +0 -84
  177. /package/.out/transformers/flatteners/specs/{flatten_accessors_of.tests.d.ts → flatten_accessors_of_type.tests.d.ts} +0 -0
  178. /package/.out/transformers/flatteners/specs/{flatten_type_def_to.tests.d.ts → flatten_type_to.tests.d.ts} +0 -0
  179. /package/.out/transformers/flatteners/specs/{flatten_type_defs_of.tests.d.ts → flatten_types_of_type.tests.d.ts} +0 -0
  180. /package/.out/transformers/flatteners/specs/{flatten_value_type_to.tests.d.ts → flatten_validation_errors_of_type.tests.d.ts} +0 -0
  181. /package/.out/transformers/flatteners/specs/{flatten_value_types_of.tests.d.ts → flatten_value_to.tests.d.ts} +0 -0
  182. /package/.out/{types/flattened_accessors_of.js → transformers/flatteners/specs/flatten_values_of_type.tests.d.ts} +0 -0
  183. /package/.out/types/{flattened_type_defs_of.js → flattened_accessors_of_type.js} +0 -0
  184. /package/.out/types/{flattened_value_types_of.js → flattened_types_of_type.js} +0 -0
  185. /package/.out/types/{json_path_of.js → flattened_types_of_validating_type.js} +0 -0
  186. /package/.out/types/{json_paths_of.js → flattened_validators_of_validating_type.js} +0 -0
  187. /package/.out/types/{partial_type_def_of.js → flattened_values_of_type.js} +0 -0
  188. /package/.out/types/{mobx_value_type_of.js → mobx_value_of_type.js} +0 -0
  189. /package/.out/types/{readonly_type_def_of.js → partial_type_of_type.js} +0 -0
  190. /package/.out/types/{specs/flattened_accessors_of.tests.d.ts → path_of.js} +0 -0
  191. /package/.out/types/{specs/flattened_type_defs_of.tests.d.ts → paths_of_type.js} +0 -0
  192. /package/.out/types/{specs/flattened_value_types_of.tests.d.ts → readonly_type_of_type.js} +0 -0
  193. /package/.out/types/specs/{json_paths_of.tests.d.ts → flattened_accessors_of_type.tests.d.ts} +0 -0
  194. /package/.out/types/specs/{partial_type_def_of.tests.d.ts → flattened_types_of_type.tests.d.ts} +0 -0
  195. /package/.out/types/specs/{readonly_type_def_of.tests.d.ts → flattened_validators_of_validating_type.tests.d.ts} +0 -0
  196. /package/.out/types/specs/{value_to_type_paths_of.tests.d.ts → flattened_values_of_type.tests.d.ts} +0 -0
  197. /package/.out/types/specs/{value_type_of.tests.d.ts → partial_type_of_type.tests.d.ts} +0 -0
  198. /package/.out/types/{value_to_type_paths_of.js → specs/paths_of_type.tests.d.ts} +0 -0
  199. /package/.out/types/{value_type_of.js → specs/readonly_type_of_type.tests.d.ts} +0 -0
@@ -13,13 +13,13 @@ import {
13
13
  } from 'types/definitions'
14
14
 
15
15
  export function valuePathToTypePath<
16
- JsonPaths extends Record<string, string>,
17
- ValuePath extends keyof JsonPaths,
16
+ ValuePathsToTypePaths extends Record<string, string>,
17
+ ValuePath extends keyof ValuePathsToTypePaths,
18
18
  >(
19
19
  { definition: typeDef }: Type,
20
20
  valuePath: ValuePath,
21
21
  allowMissingPaths: boolean = false,
22
- ): JsonPaths[ValuePath] {
22
+ ): ValuePathsToTypePaths[ValuePath] {
23
23
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
24
24
  const valueSteps = (valuePath as string).split(/\.|\[/g)
25
25
  assertEqual(valueSteps[0], '$')
@@ -33,7 +33,7 @@ export function valuePathToTypePath<
33
33
  )
34
34
  typeSteps.unshift('$')
35
35
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
36
- return typeSteps.join('.') as JsonPaths[ValuePath]
36
+ return typeSteps.join('.') as ValuePathsToTypePaths[ValuePath]
37
37
  }
38
38
 
39
39
  function internalJsonValuePathToTypePath(
package/types/builders.ts CHANGED
@@ -2,116 +2,245 @@ import {
2
2
  type IsFieldReadonly,
3
3
  } from '@strictly/base'
4
4
  import {
5
- type ListTypeDef,
6
- type LiteralTypeDef,
7
5
  type ObjectFieldKey,
8
- type ObjectTypeDef,
9
6
  type RecordKeyType,
10
- type RecordTypeDef,
11
7
  type Type,
12
8
  type TypeDef,
13
9
  TypeDefType,
14
10
  type UnionKey,
15
- type UnionTypeDef,
16
11
  } from './definitions'
12
+ import {
13
+ type TypeOfType,
14
+ typeOfType,
15
+ } from './type_of_type'
16
+ import {
17
+ type Rule,
18
+ type ValidatingListTypeDef,
19
+ type ValidatingLiteralTypeDef,
20
+ type ValidatingObjectTypeDef,
21
+ type ValidatingRecordTypeDef,
22
+ type ValidatingType,
23
+ type ValidatingTypeDef,
24
+ type ValidatingUnionTypeDef,
25
+ } from './validating_definitions'
26
+ import { type ValidatingTypeDefWithError } from './validating_type_def_with_error'
27
+ import {
28
+ type ValueOfType,
29
+ type ValueOfTypeDef,
30
+ } from './value_of_type'
31
+
32
+ function emptyRule() {
33
+ return null
34
+ }
17
35
 
18
- class TypeDefBuilder<T extends TypeDef> implements Type<T> {
36
+ class TypeDefBuilder<T extends ValidatingTypeDef> implements ValidatingType<T> {
19
37
  constructor(readonly definition: T) {
20
38
  }
21
39
 
22
- // returns just the relevant types, which can help typescript
23
- // from complaining about infinitely deep data structures
24
- get narrow(): Type<T> {
40
+ enforce<E2>(rule: Rule<E2, ValueOfType<Type<T>>>) {
41
+ return new TypeDefBuilder<ValidatingTypeDefWithError<T, E2>>(
42
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
43
+ {
44
+ ...this.definition,
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ rule: (value: any) => {
47
+ return this.definition.rule(value) || rule(value)
48
+ },
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ } as any,
51
+ )
52
+ }
53
+
54
+ required(): TypeDefBuilder<ValidatingTypeDefWithError<T, never>>
55
+ required<
56
+ RequiredError,
57
+ >(rule: Rule<RequiredError, ValueOfType<typeof this.narrow>>): TypeDefBuilder<
58
+ ValidatingTypeDefWithError<T, RequiredError>
59
+ >
60
+ required<RequiredError = never>(rule?: Rule<RequiredError, ValueOfType<typeof this.narrow>>) {
61
+ return new TypeDefBuilder<ValidatingTypeDefWithError<T, RequiredError>>(
62
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63
+ {
64
+ ...this.definition,
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ rule: (v: any) => {
67
+ return this.definition.rule(v) || rule?.(v)
68
+ },
69
+ required: true,
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ } as any,
72
+ )
73
+ }
74
+
75
+ readonly(): TypeDefBuilder<T> {
76
+ return new TypeDefBuilder<T>(
77
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
78
+ {
79
+ ...this.definition,
80
+ readonly: true,
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ } as any,
83
+ )
84
+ }
85
+
86
+ // should only be used in tests requiring Types, client code should be happy with validating types
87
+ // eslint-disable-next-line @typescript-eslint/naming-convention
88
+ get _type(): TypeOfType<Type<T>> {
89
+ return typeOfType<Type<T>>(this)
90
+ }
91
+
92
+ get narrow(): ValidatingType<T> {
93
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
25
94
  return {
26
95
  definition: this.definition,
27
- }
96
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
97
+ } as any
28
98
  }
29
99
  }
30
100
 
31
- class LiteralTypeDefBuilder<T> extends TypeDefBuilder<LiteralTypeDef<T>> {
32
- }
33
-
34
101
  class ListTypeDefBuilder<
35
- T extends ListTypeDef,
102
+ T extends ValidatingListTypeDef,
36
103
  > extends TypeDefBuilder<T> {
37
- readonly(): ListTypeDefBuilder<{
104
+ readonlyElements(): ListTypeDefBuilder<{
38
105
  readonly type: TypeDefType.List,
39
106
  readonly elements: T['elements'],
107
+ readonly rule: T['rule'],
108
+ readonly required: boolean,
109
+ readonly readonly: boolean,
40
110
  }> {
41
- return this
111
+ return new ListTypeDefBuilder({
112
+ ...this.definition,
113
+ elements: {
114
+ ...this.definition.elements,
115
+ readonly: true,
116
+ },
117
+ })
42
118
  }
43
119
  }
44
120
 
45
- class RecordTypeDefBuilder<T extends RecordTypeDef> extends TypeDefBuilder<T> {
46
- partial(): IsFieldReadonly<T, 'valueTypeDef'> extends true ? RecordTypeDefBuilder<{
121
+ class RecordTypeDefBuilder<T extends ValidatingRecordTypeDef> extends TypeDefBuilder<T> {
122
+ partialKeys(): IsFieldReadonly<T, 'valueTypeDef'> extends true ? RecordTypeDefBuilder<{
47
123
  readonly type: TypeDefType.Record,
48
124
  readonly keyPrototype: T['keyPrototype'],
49
125
  readonly valueTypeDef: T['valueTypeDef'] | undefined,
126
+ readonly rule: T['rule'],
127
+ readonly required: boolean,
128
+ readonly readonly: boolean,
50
129
  }>
51
130
  : RecordTypeDefBuilder<{
52
131
  readonly type: TypeDefType.Record,
53
132
  readonly keyPrototype: T['keyPrototype'],
54
133
  valueTypeDef: T['valueTypeDef'] | undefined,
134
+ readonly rule: T['rule'],
135
+ readonly required: boolean,
136
+ readonly readonly: boolean,
55
137
  }>
56
138
  {
57
139
  return this
58
140
  }
59
141
 
60
- readonly(): RecordTypeDefBuilder<{
142
+ readonlyKeys(): RecordTypeDefBuilder<{
61
143
  readonly type: TypeDefType.Record,
62
144
  readonly keyPrototype: T['keyPrototype'],
63
145
  readonly valueTypeDef: T['valueTypeDef'],
146
+ readonly rule: T['rule'],
147
+ readonly required: boolean,
148
+ readonly readonly: boolean,
64
149
  }> {
65
- return this
150
+ return new RecordTypeDefBuilder({
151
+ ...this.definition,
152
+ valueTypeDef: {
153
+ ...this.definition.valueTypeDef,
154
+ readonly: true,
155
+ },
156
+ })
66
157
  }
67
158
  }
68
159
 
69
160
  class ObjectTypeDefBuilder<
70
- Fields extends Readonly<Record<ObjectFieldKey, TypeDef>> = {},
161
+ E,
162
+ Fields extends Readonly<Record<ObjectFieldKey, ValidatingTypeDef>> = {},
71
163
  > extends TypeDefBuilder<
72
- ObjectTypeDef<Fields>
164
+ ValidatingObjectTypeDef<E, Fields>
73
165
  > {
74
- set<
166
+ field<
75
167
  Name extends string,
76
- T extends TypeDef,
168
+ T extends ValidatingTypeDef,
77
169
  >(
78
170
  name: Name,
79
- { definition: typeDef }: Type<T>,
171
+ { definition }: Type<T>,
80
172
  ): ObjectTypeDefBuilder<
173
+ E,
81
174
  Fields & Record<Name, T>
175
+ >
176
+ field<
177
+ Name extends string,
178
+ T extends ValidatingTypeDef,
179
+ RequiredError,
180
+ >(
181
+ name: Name,
182
+ { definition }: Type<T>,
183
+ rule: Rule<RequiredError, ValueOfTypeDef<T>>,
184
+ ): ObjectTypeDefBuilder<
185
+ E,
186
+ Fields & Record<Name, ValidatingTypeDefWithError<T, RequiredError>>
187
+ >
188
+ field<
189
+ Name extends string,
190
+ T extends ValidatingTypeDef,
191
+ RequiredError = never,
192
+ >(
193
+ name: Name,
194
+ { definition }: Type<T>,
195
+ rule?: Rule<RequiredError, ValueOfTypeDef<T>>,
196
+ ): ObjectTypeDefBuilder<
197
+ E,
198
+ Fields & Record<Name, ValidatingTypeDefWithError<T, RequiredError>>
82
199
  > {
83
- const newFields = {
84
- [name]: typeDef,
85
- }
86
200
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
87
201
  return new ObjectTypeDefBuilder<
88
- Fields & Record<Name, T>
202
+ E,
203
+ Fields & Record<Name, ValidatingTypeDefWithError<T, RequiredError>>
89
204
  >({
90
- type: TypeDefType.Object,
205
+ ...this.definition,
206
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
91
207
  fields: {
92
208
  ...this.definition.fields,
93
- ...newFields,
94
- },
209
+ [name]: {
210
+ ...definition,
211
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
212
+ rule: function (v: any) {
213
+ return definition.rule(v) || rule?.(v)
214
+ },
215
+ required: true,
216
+ },
217
+ } as Fields & Record<Name, ValidatingTypeDefWithError<T, RequiredError>>,
95
218
  })
96
219
  }
97
220
 
98
- setReadonly<
221
+ readonlyField<
99
222
  Name extends string,
100
- T extends TypeDef,
223
+ T extends ValidatingTypeDef,
101
224
  >(
102
225
  name: Name,
103
- { definition: typeDef }: Type<T>,
226
+ { definition }: Type<T>,
104
227
  ): ObjectTypeDefBuilder<
228
+ E,
105
229
  Fields & Readonly<Record<Name, T>>
106
230
  > {
107
231
  const newFields = {
108
- [name]: typeDef,
232
+ [name]: {
233
+ ...definition,
234
+ required: true,
235
+ readonly: true,
236
+ },
109
237
  }
110
238
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
111
239
  return new ObjectTypeDefBuilder<
240
+ E,
112
241
  Fields & Readonly<Record<Name, T>>
113
242
  >({
114
- type: TypeDefType.Object,
243
+ ...this.definition,
115
244
  fields: {
116
245
  ...this.definition.fields,
117
246
  ...newFields,
@@ -119,23 +248,27 @@ class ObjectTypeDefBuilder<
119
248
  })
120
249
  }
121
250
 
122
- setOptional<
251
+ optionalField<
123
252
  Name extends string,
124
- T extends TypeDef,
253
+ T extends ValidatingTypeDef,
125
254
  >(
126
255
  name: Name,
127
- { definition: typeDef }: Type<T>,
256
+ { definition }: Type<T>,
128
257
  ): ObjectTypeDefBuilder<
258
+ E,
129
259
  Fields & Partial<Record<Name, T>>
130
260
  > {
131
261
  const newFields = {
132
- [name]: typeDef,
262
+ [name]: {
263
+ ...definition,
264
+ },
133
265
  }
134
266
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
135
267
  return new ObjectTypeDefBuilder<
268
+ E,
136
269
  Fields & Partial<Record<Name, T>>
137
270
  >({
138
- type: TypeDefType.Object,
271
+ ...this.definition,
139
272
  fields: {
140
273
  ...this.definition.fields,
141
274
  ...newFields,
@@ -143,23 +276,28 @@ class ObjectTypeDefBuilder<
143
276
  })
144
277
  }
145
278
 
146
- setReadonlyOptional<
279
+ readonlyOptionalField<
147
280
  Name extends string,
148
281
  T extends TypeDef,
149
282
  >(
150
283
  name: Name,
151
- { definition: typeDef }: Type<T>,
284
+ { definition }: Type<T>,
152
285
  ): ObjectTypeDefBuilder<
286
+ E,
153
287
  Fields & Partial<Readonly<Record<Name, T>>>
154
288
  > {
155
289
  const newFields = {
156
- [name]: typeDef,
290
+ [name]: {
291
+ ...definition,
292
+ readonly: true,
293
+ },
157
294
  }
158
295
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
159
296
  return new ObjectTypeDefBuilder<
297
+ E,
160
298
  Fields & Partial<Readonly<Record<Name, T>>>
161
299
  >({
162
- type: TypeDefType.Object,
300
+ ...this.definition,
163
301
  fields: {
164
302
  ...this.definition.fields,
165
303
  ...newFields,
@@ -169,15 +307,17 @@ class ObjectTypeDefBuilder<
169
307
  }
170
308
 
171
309
  class UnionTypeDefBuilder<
310
+ E,
172
311
  D extends string | null,
173
312
  U extends Record<UnionKey, TypeDef>,
174
313
  > extends TypeDefBuilder<
175
- UnionTypeDef<
314
+ ValidatingUnionTypeDef<
315
+ E,
176
316
  D,
177
317
  U
178
318
  >
179
319
  > {
180
- add<
320
+ or<
181
321
  K extends Exclude<UnionKey, keyof U>,
182
322
  T extends TypeDef,
183
323
  >(
@@ -185,15 +325,13 @@ class UnionTypeDefBuilder<
185
325
  {
186
326
  definition: typeDef,
187
327
  }: Type<T>,
188
- ): UnionTypeDefBuilder<D, Readonly<Record<K, T>> & U> {
328
+ ): UnionTypeDefBuilder<E, D, Readonly<Record<K, T>> & U> {
189
329
  const {
190
- discriminator,
191
330
  unions,
192
331
  } = this.definition
193
- return new UnionTypeDefBuilder<D, Readonly<Record<K, T>> & U>(
332
+ return new UnionTypeDefBuilder<E, D, Readonly<Record<K, T>> & U>(
194
333
  {
195
- type: TypeDefType.Union,
196
- discriminator: discriminator,
334
+ ...this.definition,
197
335
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
198
336
  unions: {
199
337
  ...unions,
@@ -204,10 +342,13 @@ class UnionTypeDefBuilder<
204
342
  }
205
343
  }
206
344
 
207
- export function literal<T>(value?: [T]): LiteralTypeDefBuilder<T> {
208
- return new LiteralTypeDefBuilder({
345
+ export function literal<T>(value?: [T]): TypeDefBuilder<ValidatingLiteralTypeDef<never, T>> {
346
+ return new TypeDefBuilder({
209
347
  type: TypeDefType.Literal,
210
348
  valuePrototype: value!,
349
+ rule: emptyRule,
350
+ readonly: false,
351
+ required: false,
211
352
  })
212
353
  }
213
354
 
@@ -216,10 +357,16 @@ export const numberType = literal<number>()
216
357
  export const booleanType = literal<boolean>()
217
358
  export const nullType = literal([null])
218
359
 
219
- export function nullable<T extends TypeDef>(nonNullable: Type<T>): UnionTypeDefBuilder<null, {
220
- readonly ['0']: T,
221
- readonly ['1']: LiteralTypeDef<null>,
222
- }> {
360
+ export function nullable<
361
+ T extends ValidatingTypeDef,
362
+ >(nonNullable: ValidatingType<T>): UnionTypeDefBuilder<
363
+ never,
364
+ null,
365
+ {
366
+ readonly ['0']: T,
367
+ readonly ['1']: ValidatingLiteralTypeDef<never, null>,
368
+ }
369
+ > {
223
370
  return new UnionTypeDefBuilder(
224
371
  {
225
372
  type: TypeDefType.Union,
@@ -228,57 +375,78 @@ export function nullable<T extends TypeDef>(nonNullable: Type<T>): UnionTypeDefB
228
375
  ['0']: nonNullable.definition,
229
376
  ['1']: nullType.definition,
230
377
  },
378
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
379
+ rule: emptyRule as Rule<never>,
380
+ readonly: false,
381
+ required: false,
231
382
  },
232
383
  )
233
384
  }
234
385
 
235
- export function list<T extends TypeDef>(elements: Type<T>): ListTypeDefBuilder<{
386
+ export function list<T extends ValidatingTypeDef>(elements: ValidatingType<T>): ListTypeDefBuilder<{
236
387
  readonly type: TypeDefType.List,
237
388
  elements: T,
389
+ readonly rule: Rule<never>,
390
+ readonly readonly: boolean,
391
+ readonly required: boolean,
238
392
  }> {
239
393
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
240
- return new ListTypeDefBuilder<ListTypeDef<T>>({
394
+ return new ListTypeDefBuilder<ValidatingListTypeDef<never, T>>({
241
395
  type: TypeDefType.List,
242
396
  elements: elements.definition,
397
+ rule: emptyRule,
398
+ readonly: false,
399
+ required: false,
243
400
  })
244
401
  }
245
402
 
246
403
  export function record<
247
- V extends Type,
404
+ V extends ValidatingType,
248
405
  // NOTE if we swap these generics and the caller forgets to supply the second one (so the Type)
249
406
  // TSC will freeze
250
407
  K extends RecordKeyType,
251
- >({ definition: typeDef }: V) {
408
+ >({ definition: valueTypeDef }: V) {
252
409
  return new RecordTypeDefBuilder<{
253
410
  readonly type: TypeDefType.Record,
254
411
  readonly keyPrototype: K,
255
412
  valueTypeDef: V['definition'],
413
+ readonly rule: Rule<never>,
414
+ readonly readonly: boolean,
415
+ readonly required: boolean,
256
416
  }>({
257
417
  type: TypeDefType.Record,
258
- // eslint-disable-next-line no-undefined
259
418
  keyPrototype: undefined!,
260
- valueTypeDef: typeDef,
419
+ valueTypeDef,
420
+ rule: emptyRule,
421
+ readonly: false,
422
+ required: false,
261
423
  })
262
424
  }
263
425
 
264
- export function object(): ObjectTypeDefBuilder<{}> {
426
+ export function object(): ObjectTypeDefBuilder<never, {}> {
265
427
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
266
- return new ObjectTypeDefBuilder<{}>({
428
+ return new ObjectTypeDefBuilder<never, {}>({
267
429
  type: TypeDefType.Object,
268
430
  fields: {},
431
+ rule: emptyRule,
432
+ readonly: false,
433
+ required: false,
269
434
  })
270
435
  }
271
436
 
272
- export function union<D extends null>(): UnionTypeDefBuilder<D, {}>
273
- export function union<D extends string>(discriminator: D): UnionTypeDefBuilder<D, {}>
274
- export function union<D extends string | null>(discriminator?: D): UnionTypeDefBuilder<D, {}> {
437
+ export function union<D extends null>(): UnionTypeDefBuilder<never, D, {}>
438
+ export function union<D extends string>(discriminator: D): UnionTypeDefBuilder<never, D, {}>
439
+ export function union<D extends string | null>(discriminator?: D): UnionTypeDefBuilder<never, D, {}> {
275
440
  // have to explicitly supply types as TS will infinitely recurse trying to infer them!
276
- return new UnionTypeDefBuilder<D, {}>(
441
+ return new UnionTypeDefBuilder<never, D, {}>(
277
442
  {
278
443
  type: TypeDefType.Union,
279
444
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
280
445
  discriminator: (discriminator ?? null) as D,
281
446
  unions: {},
447
+ rule: emptyRule,
448
+ readonly: false,
449
+ required: false,
282
450
  },
283
451
  )
284
452
  }
@@ -73,9 +73,9 @@ export type RecordTypeDef<
73
73
  readonly valueTypeDef: V,
74
74
  }
75
75
 
76
- // structured type
76
+ // object type
77
77
  // could be replaced with a map and an intersection
78
- export type ObjectFieldKey = string | number
78
+ export type ObjectFieldKey = string
79
79
 
80
80
  // NOTE we use the `readonly` and `?` (partial) status of these field definitions
81
81
  // to describe the same attributes of the fields
@@ -1,5 +1,5 @@
1
1
  import { type Type } from './definitions'
2
- import { type FlattenedValueTypesOf } from './flattened_value_types_of'
2
+ import { type FlattenedValuesOfType } from './flattened_values_of_type'
3
3
 
4
4
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
5
  export type Accessor<T = any> = {
@@ -7,9 +7,9 @@ export type Accessor<T = any> = {
7
7
  set(v: T): void,
8
8
  }
9
9
 
10
- export type FlattenedAccessorsOf<
10
+ export type FlattenedAccessorsOfType<
11
11
  T extends Type,
12
- Flattened extends Readonly<Record<string, Accessor>> = FlattenedValueTypesOf<T>,
12
+ Flattened extends Readonly<Record<string, Accessor>> = FlattenedValuesOfType<T>,
13
13
  > = {
14
14
  readonly [K in keyof Flattened]: Accessor<Flattened[K]>
15
15
  }
@@ -14,11 +14,11 @@ import {
14
14
  type Depths,
15
15
  type StartingDepth,
16
16
  } from './flattened'
17
- import { type JsonPathOf } from './json_path_of'
17
+ import { type PathOf } from './path_of'
18
18
 
19
19
  // NOTE removing any ternary from this file improves the performance and the depth of data structure we can go to
20
20
 
21
- export type FlattenedTypeDefsOf<
21
+ export type FlattenedTypesOfType<
22
22
  T extends Type,
23
23
  SegmentOverride extends string | null,
24
24
  Path extends string = '$',
@@ -66,7 +66,7 @@ type InternalFlattenedTypeDefsOfListChildren<
66
66
  > = InternalFlattenedTypeDefsOf<
67
67
  T['elements'],
68
68
  SegmentOverride,
69
- JsonPathOf<Path, number, SegmentOverride>,
69
+ PathOf<Path, number, SegmentOverride>,
70
70
  '',
71
71
  Depth
72
72
  >
@@ -79,7 +79,7 @@ type InternalFlattenedTypeDefsOfRecordChildren<
79
79
  > = InternalFlattenedTypeDefsOf<
80
80
  T['valueTypeDef'],
81
81
  SegmentOverride,
82
- JsonPathOf<Path, T['keyPrototype'], SegmentOverride>,
82
+ PathOf<Path, T['keyPrototype'], SegmentOverride>,
83
83
  '',
84
84
  Depth
85
85
  >
@@ -90,14 +90,24 @@ type InternalFlattenedTypeDefsOfObjectChildren<
90
90
  Path extends string,
91
91
  Qualifier extends string,
92
92
  Depth extends number,
93
- > = T extends ObjectTypeDef<infer Fields> ? {} extends Fields ? {} : keyof Fields extends string ? UnionToIntersection<{
94
- readonly [K in keyof Fields]-?: InternalFlattenedTypeDefsOf<
95
- Exclude<Fields[K], undefined>,
96
- SegmentOverride,
97
- JsonPathOf<Path, `${Qualifier}${K}`, null>,
98
- '',
99
- Depth
100
- >
93
+ > = T extends ObjectTypeDef<infer Fields> ? keyof Fields extends string ? UnionToIntersection<{
94
+ readonly [K in keyof Fields]-?: undefined extends Fields[K] ? InternalFlattenedTypeDefsOf<
95
+ UnionTypeDef<null, {
96
+ readonly '0': Exclude<Fields[K], undefined>,
97
+ readonly '1': LiteralTypeDef<undefined>,
98
+ }>,
99
+ SegmentOverride,
100
+ PathOf<Path, `${Qualifier}${K}`, null>,
101
+ '',
102
+ Depth
103
+ >
104
+ : InternalFlattenedTypeDefsOf<
105
+ Exclude<Fields[K], undefined>,
106
+ SegmentOverride,
107
+ PathOf<Path, `${Qualifier}${K}`, null>,
108
+ '',
109
+ Depth
110
+ >
101
111
  }[keyof Fields]>
102
112
  : never
103
113
  : never