@atproto/lex-schema 0.0.8 → 0.0.10

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 (279) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/core/$type.d.ts +11 -0
  4. package/dist/core/$type.d.ts.map +1 -1
  5. package/dist/core/$type.js +4 -0
  6. package/dist/core/$type.js.map +1 -1
  7. package/dist/core/schema.d.ts +31 -24
  8. package/dist/core/schema.d.ts.map +1 -1
  9. package/dist/core/schema.js +38 -8
  10. package/dist/core/schema.js.map +1 -1
  11. package/dist/core/string-format.d.ts +35 -35
  12. package/dist/core/string-format.d.ts.map +1 -1
  13. package/dist/core/string-format.js +49 -91
  14. package/dist/core/string-format.js.map +1 -1
  15. package/dist/core/validation-issue.js +1 -1
  16. package/dist/core/validation-issue.js.map +1 -1
  17. package/dist/core/validator.d.ts +53 -32
  18. package/dist/core/validator.d.ts.map +1 -1
  19. package/dist/core/validator.js +18 -22
  20. package/dist/core/validator.js.map +1 -1
  21. package/dist/external.d.ts +0 -85
  22. package/dist/external.d.ts.map +1 -1
  23. package/dist/external.js +0 -164
  24. package/dist/external.js.map +1 -1
  25. package/dist/helpers.d.ts +10 -5
  26. package/dist/helpers.d.ts.map +1 -1
  27. package/dist/helpers.js +3 -3
  28. package/dist/helpers.js.map +1 -1
  29. package/dist/schema/array.d.ts +9 -5
  30. package/dist/schema/array.d.ts.map +1 -1
  31. package/dist/schema/array.js +14 -5
  32. package/dist/schema/array.js.map +1 -1
  33. package/dist/schema/blob.d.ts +9 -7
  34. package/dist/schema/blob.d.ts.map +1 -1
  35. package/dist/schema/blob.js +9 -5
  36. package/dist/schema/blob.js.map +1 -1
  37. package/dist/schema/boolean.d.ts +3 -7
  38. package/dist/schema/boolean.d.ts.map +1 -1
  39. package/dist/schema/boolean.js +6 -7
  40. package/dist/schema/boolean.js.map +1 -1
  41. package/dist/schema/bytes.d.ts +3 -2
  42. package/dist/schema/bytes.d.ts.map +1 -1
  43. package/dist/schema/bytes.js +7 -3
  44. package/dist/schema/bytes.js.map +1 -1
  45. package/dist/schema/cid.d.ts +10 -8
  46. package/dist/schema/cid.d.ts.map +1 -1
  47. package/dist/schema/cid.js +5 -1
  48. package/dist/schema/cid.js.map +1 -1
  49. package/dist/schema/custom.d.ts +6 -5
  50. package/dist/schema/custom.d.ts.map +1 -1
  51. package/dist/schema/custom.js +10 -4
  52. package/dist/schema/custom.js.map +1 -1
  53. package/dist/schema/dict.d.ts +8 -8
  54. package/dist/schema/dict.d.ts.map +1 -1
  55. package/dist/schema/dict.js +11 -2
  56. package/dist/schema/dict.js.map +1 -1
  57. package/dist/schema/discriminated-union.d.ts +21 -14
  58. package/dist/schema/discriminated-union.d.ts.map +1 -1
  59. package/dist/schema/discriminated-union.js +7 -0
  60. package/dist/schema/discriminated-union.js.map +1 -1
  61. package/dist/schema/enum.d.ts +7 -9
  62. package/dist/schema/enum.d.ts.map +1 -1
  63. package/dist/schema/enum.js +8 -4
  64. package/dist/schema/enum.js.map +1 -1
  65. package/dist/schema/integer.d.ts +5 -5
  66. package/dist/schema/integer.d.ts.map +1 -1
  67. package/dist/schema/integer.js +9 -5
  68. package/dist/schema/integer.js.map +1 -1
  69. package/dist/schema/intersection.d.ts +4 -4
  70. package/dist/schema/intersection.d.ts.map +1 -1
  71. package/dist/schema/intersection.js +5 -0
  72. package/dist/schema/intersection.js.map +1 -1
  73. package/dist/schema/literal.d.ts +6 -9
  74. package/dist/schema/literal.d.ts.map +1 -1
  75. package/dist/schema/literal.js +7 -4
  76. package/dist/schema/literal.js.map +1 -1
  77. package/dist/schema/never.d.ts +3 -2
  78. package/dist/schema/never.d.ts.map +1 -1
  79. package/dist/schema/never.js +5 -1
  80. package/dist/schema/never.js.map +1 -1
  81. package/dist/schema/null.d.ts +4 -3
  82. package/dist/schema/null.d.ts.map +1 -1
  83. package/dist/schema/null.js +6 -4
  84. package/dist/schema/null.js.map +1 -1
  85. package/dist/schema/nullable.d.ts +6 -5
  86. package/dist/schema/nullable.d.ts.map +1 -1
  87. package/dist/schema/nullable.js +9 -5
  88. package/dist/schema/nullable.js.map +1 -1
  89. package/dist/schema/object.d.ts +10 -8
  90. package/dist/schema/object.d.ts.map +1 -1
  91. package/dist/schema/object.js +11 -3
  92. package/dist/schema/object.js.map +1 -1
  93. package/dist/schema/optional.d.ts +7 -5
  94. package/dist/schema/optional.d.ts.map +1 -1
  95. package/dist/schema/optional.js +14 -6
  96. package/dist/schema/optional.js.map +1 -1
  97. package/dist/schema/params.d.ts +24 -13
  98. package/dist/schema/params.d.ts.map +1 -1
  99. package/dist/schema/params.js +47 -25
  100. package/dist/schema/params.js.map +1 -1
  101. package/dist/schema/payload.d.ts +12 -9
  102. package/dist/schema/payload.d.ts.map +1 -1
  103. package/dist/schema/payload.js +11 -0
  104. package/dist/schema/payload.js.map +1 -1
  105. package/dist/schema/permission-set.d.ts +1 -0
  106. package/dist/schema/permission-set.d.ts.map +1 -1
  107. package/dist/schema/permission-set.js +5 -0
  108. package/dist/schema/permission-set.js.map +1 -1
  109. package/dist/schema/permission.d.ts +6 -5
  110. package/dist/schema/permission.d.ts.map +1 -1
  111. package/dist/schema/permission.js +5 -0
  112. package/dist/schema/permission.js.map +1 -1
  113. package/dist/schema/procedure.d.ts +2 -1
  114. package/dist/schema/procedure.d.ts.map +1 -1
  115. package/dist/schema/procedure.js +5 -0
  116. package/dist/schema/procedure.js.map +1 -1
  117. package/dist/schema/query.d.ts +2 -1
  118. package/dist/schema/query.d.ts.map +1 -1
  119. package/dist/schema/query.js +5 -0
  120. package/dist/schema/query.js.map +1 -1
  121. package/dist/schema/record.d.ts +48 -30
  122. package/dist/schema/record.d.ts.map +1 -1
  123. package/dist/schema/record.js +12 -9
  124. package/dist/schema/record.js.map +1 -1
  125. package/dist/schema/ref.d.ts +9 -6
  126. package/dist/schema/ref.d.ts.map +1 -1
  127. package/dist/schema/ref.js +9 -16
  128. package/dist/schema/ref.js.map +1 -1
  129. package/dist/schema/refine.d.ts +4 -4
  130. package/dist/schema/refine.d.ts.map +1 -1
  131. package/dist/schema/refine.js.map +1 -1
  132. package/dist/schema/regexp.d.ts +4 -3
  133. package/dist/schema/regexp.d.ts.map +1 -1
  134. package/dist/schema/regexp.js +5 -0
  135. package/dist/schema/regexp.js.map +1 -1
  136. package/dist/schema/string.d.ts +7 -8
  137. package/dist/schema/string.d.ts.map +1 -1
  138. package/dist/schema/string.js +13 -19
  139. package/dist/schema/string.js.map +1 -1
  140. package/dist/schema/subscription.d.ts +2 -1
  141. package/dist/schema/subscription.d.ts.map +1 -1
  142. package/dist/schema/subscription.js +5 -0
  143. package/dist/schema/subscription.js.map +1 -1
  144. package/dist/schema/token.d.ts +6 -5
  145. package/dist/schema/token.d.ts.map +1 -1
  146. package/dist/schema/token.js +5 -0
  147. package/dist/schema/token.js.map +1 -1
  148. package/dist/schema/typed-object.d.ts +43 -26
  149. package/dist/schema/typed-object.d.ts.map +1 -1
  150. package/dist/schema/typed-object.js +6 -3
  151. package/dist/schema/typed-object.js.map +1 -1
  152. package/dist/schema/typed-ref.d.ts +16 -25
  153. package/dist/schema/typed-ref.d.ts.map +1 -1
  154. package/dist/schema/typed-ref.js +7 -17
  155. package/dist/schema/typed-ref.js.map +1 -1
  156. package/dist/schema/typed-union.d.ts +9 -21
  157. package/dist/schema/typed-union.d.ts.map +1 -1
  158. package/dist/schema/typed-union.js +15 -11
  159. package/dist/schema/typed-union.js.map +1 -1
  160. package/dist/schema/union.d.ts +6 -6
  161. package/dist/schema/union.d.ts.map +1 -1
  162. package/dist/schema/union.js +7 -5
  163. package/dist/schema/union.js.map +1 -1
  164. package/dist/schema/unknown-object.d.ts +5 -4
  165. package/dist/schema/unknown-object.d.ts.map +1 -1
  166. package/dist/schema/unknown-object.js +5 -1
  167. package/dist/schema/unknown-object.js.map +1 -1
  168. package/dist/schema/unknown.d.ts +3 -2
  169. package/dist/schema/unknown.d.ts.map +1 -1
  170. package/dist/schema/unknown.js +5 -1
  171. package/dist/schema/unknown.js.map +1 -1
  172. package/dist/schema/with-default.d.ts +9 -0
  173. package/dist/schema/with-default.d.ts.map +1 -0
  174. package/dist/schema/with-default.js +27 -0
  175. package/dist/schema/with-default.js.map +1 -0
  176. package/dist/schema.d.ts +2 -2
  177. package/dist/schema.d.ts.map +1 -1
  178. package/dist/schema.js +2 -4
  179. package/dist/schema.js.map +1 -1
  180. package/dist/util/assertion-util.d.ts +0 -6
  181. package/dist/util/assertion-util.d.ts.map +1 -1
  182. package/dist/util/assertion-util.js +0 -28
  183. package/dist/util/assertion-util.js.map +1 -1
  184. package/dist/util/memoize.d.ts +2 -2
  185. package/dist/util/memoize.d.ts.map +1 -1
  186. package/dist/util/memoize.js +23 -39
  187. package/dist/util/memoize.js.map +1 -1
  188. package/package.json +3 -3
  189. package/src/core/$type.test.ts +20 -0
  190. package/src/core/$type.ts +30 -0
  191. package/src/core/schema.ts +86 -38
  192. package/src/core/string-format.ts +119 -158
  193. package/src/core/validation-issue.ts +1 -1
  194. package/src/core/validator.ts +93 -53
  195. package/src/external.ts +0 -404
  196. package/src/helpers.test.ts +22 -21
  197. package/src/helpers.ts +14 -14
  198. package/src/schema/array.test.ts +38 -40
  199. package/src/schema/array.ts +35 -13
  200. package/src/schema/blob.test.ts +21 -21
  201. package/src/schema/blob.ts +19 -17
  202. package/src/schema/boolean.test.ts +9 -8
  203. package/src/schema/boolean.ts +7 -13
  204. package/src/schema/bytes.test.ts +13 -13
  205. package/src/schema/bytes.ts +13 -8
  206. package/src/schema/cid.test.ts +3 -3
  207. package/src/schema/cid.ts +15 -13
  208. package/src/schema/custom.test.ts +26 -26
  209. package/src/schema/custom.ts +20 -13
  210. package/src/schema/dict.test.ts +21 -39
  211. package/src/schema/dict.ts +28 -19
  212. package/src/schema/discriminated-union.test.ts +128 -128
  213. package/src/schema/discriminated-union.ts +45 -26
  214. package/src/schema/enum.test.ts +17 -16
  215. package/src/schema/enum.ts +16 -16
  216. package/src/schema/integer.test.ts +22 -21
  217. package/src/schema/integer.ts +12 -9
  218. package/src/schema/intersection.test.ts +10 -10
  219. package/src/schema/intersection.ts +17 -14
  220. package/src/schema/literal.test.ts +35 -34
  221. package/src/schema/literal.ts +12 -15
  222. package/src/schema/never.test.ts +5 -5
  223. package/src/schema/never.ts +7 -2
  224. package/src/schema/null.test.ts +3 -3
  225. package/src/schema/null.ts +9 -9
  226. package/src/schema/nullable.test.ts +31 -42
  227. package/src/schema/nullable.ts +17 -9
  228. package/src/schema/object.test.ts +10 -12
  229. package/src/schema/object.ts +27 -18
  230. package/src/schema/optional.test.ts +21 -28
  231. package/src/schema/optional.ts +27 -10
  232. package/src/schema/params.test.ts +471 -47
  233. package/src/schema/params.ts +72 -38
  234. package/src/schema/payload.test.ts +150 -156
  235. package/src/schema/payload.ts +35 -19
  236. package/src/schema/permission-set.test.ts +206 -273
  237. package/src/schema/permission-set.ts +8 -0
  238. package/src/schema/permission.test.ts +177 -177
  239. package/src/schema/permission.ts +13 -5
  240. package/src/schema/procedure.test.ts +183 -242
  241. package/src/schema/procedure.ts +18 -5
  242. package/src/schema/query.test.ts +186 -200
  243. package/src/schema/query.ts +16 -4
  244. package/src/schema/record.test.ts +121 -101
  245. package/src/schema/record.ts +74 -40
  246. package/src/schema/ref.test.ts +101 -118
  247. package/src/schema/ref.ts +33 -28
  248. package/src/schema/refine.test.ts +28 -28
  249. package/src/schema/refine.ts +23 -20
  250. package/src/schema/regexp.test.ts +29 -33
  251. package/src/schema/regexp.ts +11 -7
  252. package/src/schema/string.test.ts +35 -35
  253. package/src/schema/string.ts +24 -33
  254. package/src/schema/subscription.test.ts +259 -387
  255. package/src/schema/subscription.ts +16 -4
  256. package/src/schema/token.test.ts +47 -324
  257. package/src/schema/token.ts +14 -7
  258. package/src/schema/typed-object.test.ts +98 -81
  259. package/src/schema/typed-object.ts +68 -33
  260. package/src/schema/typed-ref.test.ts +206 -234
  261. package/src/schema/typed-ref.ts +40 -42
  262. package/src/schema/typed-union.test.ts +40 -64
  263. package/src/schema/typed-union.ts +36 -58
  264. package/src/schema/union.test.ts +17 -27
  265. package/src/schema/union.ts +20 -16
  266. package/src/schema/unknown-object.test.ts +8 -8
  267. package/src/schema/unknown-object.ts +9 -7
  268. package/src/schema/unknown.test.ts +4 -4
  269. package/src/schema/unknown.ts +7 -5
  270. package/src/schema/with-default.ts +35 -0
  271. package/src/schema.ts +2 -6
  272. package/src/util/assertion-util.ts +0 -39
  273. package/src/util/memoize.ts +26 -46
  274. package/dist/schema/_parameters.d.ts +0 -17
  275. package/dist/schema/_parameters.d.ts.map +0 -1
  276. package/dist/schema/_parameters.js +0 -20
  277. package/dist/schema/_parameters.js.map +0 -1
  278. package/src/schema/_parameters.test.ts +0 -417
  279. package/src/schema/_parameters.ts +0 -26
@@ -44,7 +44,7 @@ export class IssueInvalidFormat extends Issue {
44
44
  }
45
45
 
46
46
  toString() {
47
- return `Invalid ${this.formatDescription} format${this.message ? ` (${this.message})` : ''}${stringifyPath(this.path)} (got ${stringifyValue(this.input)})`
47
+ return `Invalid ${this.formatDescription}${this.message ? ` (${this.message})` : ''}${stringifyPath(this.path)} (got ${stringifyValue(this.input)})`
48
48
  }
49
49
 
50
50
  toJSON() {
@@ -12,47 +12,48 @@ import {
12
12
  MeasurableType,
13
13
  } from './validation-issue.js'
14
14
 
15
- export type ValidationSuccess<Value = any> = ResultSuccess<Value>
15
+ export type ValidationSuccess<Value = unknown> = ResultSuccess<Value>
16
16
  export type ValidationFailure = ResultFailure<ValidationError>
17
- export type ValidationResult<Value = any> =
17
+ export type ValidationResult<Value = unknown> =
18
18
  | ValidationSuccess<Value>
19
19
  | ValidationFailure
20
20
 
21
- export type ValidationOptions = {
22
- path?: PropertyKey[]
23
-
24
- /** @default true */
25
- allowTransform?: boolean
26
- }
21
+ export type InferInput<V extends Validator> = V['__lex']['input']
22
+ export type InferOutput<V extends Validator> = V['__lex']['output']
27
23
 
28
- export type Infer<T extends Validator> = T['__lex']['output']
24
+ export type { InferInput as Infer }
29
25
 
30
- export interface Validator<Output = any> {
26
+ export interface Validator<TInput = unknown, TOutput = TInput> {
31
27
  /**
32
28
  * This property is used for type inference purposes and does not actually
33
29
  * exist at runtime.
34
30
  *
35
31
  * @deprecated **INTERNAL API, DO NOT USE**.
36
32
  */
37
- readonly ['__lex']: { output: Output }
33
+ readonly ['__lex']: {
34
+ /** @internal The inferred validation type */
35
+ input: TInput
36
+ /** @internal The inferred parse type */
37
+ output: TOutput
38
+ }
38
39
 
39
40
  /**
40
- * @internal **INTERNAL API**: use {@link ValidatorContext.validate} instead
41
+ * @internal **INTERNAL API**: use {@link ValidationContext.validate} instead
41
42
  *
42
43
  * This method is implemented by subclasses to perform transformation and
43
44
  * validation of the input value. Do not call this method directly; as the
44
- * {@link ValidatorContext.options.allowTransform} option will **not** be
45
- * enforced. See {@link ValidatorContext.validate} for details. When
46
- * delegating validation from one validator sub-class implementation to
47
- * another schema, {@link ValidatorContext.validate} must be used instead of
48
- * calling {@link Validator.validateInContext}. This will allow to stop the
49
- * validation process if the value was transformed (by the other schema) but
45
+ * {@link ValidationContext.options.mode} option will **not** be enforced. See
46
+ * {@link ValidationContext.validate} for details. When delegating validation
47
+ * from one validator sub-class implementation to another schema,
48
+ * {@link ValidationContext.validate} must be used instead of calling
49
+ * {@link Validator.validateInContext}. This will allow to stop the validation
50
+ * process if the value was transformed (by the other schema) but
50
51
  * transformations are not allowed.
51
52
  *
52
53
  * By convention, the {@link ValidationResult} must return the original input
53
54
  * value if validation was successful and no transformation was applied (i.e.
54
55
  * the input already conformed to the schema). If a default value, or any
55
- * other transformation was applied, the returned value c&an be different from
56
+ * other transformation was applied, the returned value can be different from
56
57
  * the input.
57
58
  *
58
59
  * This convention allows the {@link Validator.check check} and
@@ -60,34 +61,64 @@ export interface Validator<Output = any> {
60
61
  * exactly matches the schema (without defaults or transformations), by
61
62
  * checking if the returned value is strictly equal to the input.
62
63
  *
63
- * @see {@link ValidatorContext.validate}
64
+ * @see {@link ValidationContext.validate}
64
65
  */
65
- validateInContext(
66
- input: unknown,
67
- ctx: ValidatorContext,
68
- ): ValidationResult<Output>
66
+ validateInContext(input: unknown, ctx: ValidationContext): ValidationResult
69
67
  }
70
68
 
71
- export class ValidatorContext {
69
+ export type ValidationOptions = {
70
+ /**
71
+ * When set to `"validate"` (default), the result of validation must be
72
+ * strictly equal to the input value (i.e. no transformation, such as applying
73
+ * default values, is allowed).
74
+ */
75
+ mode?: 'validate' | 'parse'
76
+
72
77
  /**
73
- * Creates a new validation context and validates the input using the
74
- * provided validator.
78
+ * The path to the value being validated. This is used to provide more
79
+ * context in validation issues.
75
80
  */
76
- static validate<V>(
81
+ path?: readonly PropertyKey[]
82
+ }
83
+
84
+ export class ValidationContext {
85
+ static validate<V extends Validator>(
86
+ input: unknown,
87
+ validator: V,
88
+ options: ValidationOptions & {
89
+ mode: 'parse'
90
+ },
91
+ ): ValidationResult<InferOutput<V>>
92
+ static validate<V extends Validator, I = unknown>(
93
+ input: I,
94
+ validator: V,
95
+ options?: ValidationOptions & {
96
+ mode?: 'validate'
97
+ },
98
+ ): ValidationResult<I & InferInput<V>>
99
+ static validate<V extends Validator>(
100
+ input: unknown,
101
+ validator: V,
102
+ options?: ValidationOptions,
103
+ ): ValidationResult<InferOutput<V> | InferInput<V>>
104
+ static validate<V extends Validator>(
77
105
  input: unknown,
78
- validator: Validator<V>,
79
- options: ValidationOptions = {},
80
- ): ValidationResult<V> {
81
- const context = new ValidatorContext(options)
106
+ validator: V,
107
+ options?: ValidationOptions,
108
+ ): ValidationResult<InferOutput<V> | InferInput<V>> {
109
+ const context = new ValidationContext({
110
+ path: options?.path ?? [],
111
+ mode: options?.mode ?? 'validate',
112
+ })
82
113
  return context.validate(input, validator)
83
114
  }
84
115
 
85
- private readonly currentPath: PropertyKey[]
86
- private readonly issues: Issue[] = []
116
+ protected readonly currentPath: PropertyKey[]
117
+ protected readonly issues: Issue[] = []
87
118
 
88
- protected constructor(readonly options: ValidationOptions) {
119
+ constructor(readonly options: Required<ValidationOptions>) {
89
120
  // Create a copy because we will be mutating the array during validation.
90
- this.currentPath = options?.path != null ? Array.from(options.path) : []
121
+ this.currentPath = Array.from(options.path)
91
122
  }
92
123
 
93
124
  get path() {
@@ -101,22 +132,27 @@ export class ValidatorContext {
101
132
 
102
133
  /**
103
134
  * This is basically the entry point for validation within a context. Use this
104
- * method instead of {@link Validator.validateInContext} directly, because
105
- * this method enforces the {@link ValidationOptions.allowTransform} option.
135
+ * method instead of using {@link Validator.validateInContext} directly,
136
+ * because this method ensures the proper use of {@link ValidationOptions}.
106
137
  */
107
- validate<V>(input: unknown, validator: Validator<V>): ValidationResult<V> {
138
+ validate<V extends Validator>(
139
+ input: unknown,
140
+ validator: V,
141
+ ): ValidationResult<InferInput<V>> {
108
142
  // This is the only place where validateInContext should be called.
109
143
  const result = validator.validateInContext(input, this)
110
144
 
111
145
  if (result.success) {
112
- if (
113
- // Defaults to true
114
- this.options?.allowTransform === false &&
115
- !Object.is(result.value, input)
116
- ) {
146
+ if (this.issues.length > 0) {
147
+ // Validator returned a success but issues were added via the context.
148
+ // This means the overall validation failed.
149
+ return failure(new ValidationError(Array.from(this.issues)))
150
+ }
151
+
152
+ if (this.options.mode !== 'parse' && !Object.is(result.value, input)) {
117
153
  // If the value changed, it means that a default (or some other
118
154
  // transformation) was applied, meaning that the original value did
119
- // *not* match the (output) schema. When "allowTransform" is false, we
155
+ // *not* match the (output) schema. When not in "parse" mode, we
120
156
  // consider this a failure.
121
157
 
122
158
  // This check is the reason why Validator.validateInContext should not
@@ -129,22 +165,16 @@ export class ValidatorContext {
129
165
  // "failure" method below), resulting in a more complete error report.
130
166
  return this.issueInvalidValue(input, [result.value])
131
167
  }
132
-
133
- if (this.issues.length > 0) {
134
- // Validator returned a success but issues were added via the context.
135
- // This means the overall validation failed.
136
- return failure(new ValidationError(Array.from(this.issues)))
137
- }
138
168
  }
139
169
 
140
- return result as ValidationResult<V>
170
+ return result as ValidationResult<InferInput<V>>
141
171
  }
142
172
 
143
173
  validateChild<
144
174
  I extends object,
145
175
  K extends PropertyKey & keyof I,
146
176
  V extends Validator,
147
- >(input: I, key: K, validator: V): ValidationResult<Infer<V>> {
177
+ >(input: I, key: K, validator: V): ValidationResult<InferInput<V>> {
148
178
  // Instead of creating a new context, we just push/pop the path segment.
149
179
  this.currentPath.push(key)
150
180
  try {
@@ -224,3 +254,13 @@ export class ValidatorContext {
224
254
  return this.issue(new IssueInvalidType(path, value, [expected]))
225
255
  }
226
256
  }
257
+
258
+ export type UnwrapValidator<T extends Validator> = T extends {
259
+ unwrap(): infer U extends Validator
260
+ }
261
+ ? UnwrapValidator<U>
262
+ : T
263
+
264
+ export interface WrappedValidator<out Validator> {
265
+ unwrap(): Validator
266
+ }
package/src/external.ts CHANGED
@@ -1,407 +1,3 @@
1
- import {
2
- $Type,
3
- $TypeOf,
4
- $type,
5
- Infer,
6
- LexiconRecordKey,
7
- NsidString,
8
- PropertyKey,
9
- Schema,
10
- Validator,
11
- } from './core.js'
12
- import {
13
- ArraySchema,
14
- ArraySchemaOptions,
15
- BlobSchema,
16
- BlobSchemaOptions,
17
- BooleanSchema,
18
- BooleanSchemaOptions,
19
- BytesSchema,
20
- BytesSchemaOptions,
21
- CidSchema,
22
- CidSchemaOptions,
23
- CustomAssertion,
24
- CustomSchema,
25
- DictSchema,
26
- DiscriminatedUnionSchema,
27
- DiscriminatedUnionVariants,
28
- EnumSchema,
29
- EnumSchemaOptions,
30
- IntegerSchema,
31
- IntegerSchemaOptions,
32
- IntersectionSchema,
33
- LiteralSchema,
34
- LiteralSchemaOptions,
35
- NeverSchema,
36
- NullSchema,
37
- NullableSchema,
38
- ObjectSchema,
39
- ObjectSchemaShape,
40
- OptionalSchema,
41
- ParamsSchema,
42
- ParamsSchemaShape,
43
- Payload,
44
- PayloadSchema,
45
- Permission,
46
- PermissionOptions,
47
- PermissionSet,
48
- PermissionSetOptions,
49
- Procedure,
50
- Query,
51
- RecordSchema,
52
- RefSchema,
53
- RefSchemaGetter,
54
- RegexpSchema,
55
- StringSchema,
56
- StringSchemaOptions,
57
- Subscription,
58
- TokenSchema,
59
- TypedObjectSchema,
60
- TypedRefGetter,
61
- TypedRefSchema,
62
- TypedUnionSchema,
63
- UnionSchema,
64
- UnionSchemaValidators,
65
- UnknownObjectOutput,
66
- UnknownObjectSchema,
67
- UnknownSchema,
68
- refine,
69
- } from './schema.js'
70
- import { memoizedOptions, memoizedTransformer } from './util/memoize.js'
71
-
72
1
  export * from './core.js'
73
2
  export * from './helpers.js'
74
3
  export * from './schema.js'
75
-
76
- export { _null as null }
77
-
78
- export const never = /*#__PURE__*/ memoizedOptions(function () {
79
- return new NeverSchema()
80
- })
81
-
82
- export const unknown = /*#__PURE__*/ memoizedOptions(function () {
83
- return new UnknownSchema()
84
- })
85
-
86
- const _null = /*#__PURE__*/ memoizedOptions(function () {
87
- return new NullSchema()
88
- })
89
-
90
- /*@__NO_SIDE_EFFECTS__*/
91
- export function literal<const V extends null | string | number | boolean>(
92
- value: V,
93
- options?: LiteralSchemaOptions<V>,
94
- ) {
95
- return new LiteralSchema<V>(value, options)
96
- }
97
-
98
- /*@__NO_SIDE_EFFECTS__*/
99
- export function _enum<const V extends null | string | number | boolean>(
100
- value: readonly V[],
101
- options?: EnumSchemaOptions<V>,
102
- ) {
103
- return new EnumSchema<V>(value, options)
104
- }
105
-
106
- // @NOTE "enum" is a reserved keyword in JS/TS
107
- export { _enum as enum }
108
-
109
- export const boolean = /*#__PURE__*/ memoizedOptions(
110
- function (options?: BooleanSchemaOptions) {
111
- return new BooleanSchema(options)
112
- },
113
- (options) => {
114
- const keys = Object.keys(options)
115
- if (keys.length === 1 && keys[0] === 'default') return options.default!
116
- },
117
- )
118
-
119
- export const integer = /*#__PURE__*/ memoizedOptions(function (
120
- options?: IntegerSchemaOptions,
121
- ) {
122
- return new IntegerSchema(options)
123
- })
124
-
125
- export const cidLink = /*#__PURE__*/ memoizedOptions(function <
126
- O extends CidSchemaOptions = NonNullable<unknown>,
127
- >(options: O = {} as O) {
128
- return new CidSchema(options)
129
- })
130
-
131
- export const bytes = /*#__PURE__*/ memoizedOptions(function (
132
- options?: BytesSchemaOptions,
133
- ) {
134
- return new BytesSchema(options)
135
- })
136
-
137
- export const blob = /*#__PURE__*/ memoizedOptions(function <
138
- O extends BlobSchemaOptions = NonNullable<unknown>,
139
- >(options: O = {} as O) {
140
- return new BlobSchema(options)
141
- })
142
-
143
- export const string = /*#__PURE__*/ memoizedOptions(function <
144
- const O extends StringSchemaOptions = NonNullable<unknown>,
145
- >(options: StringSchemaOptions & O = {} as O) {
146
- return new StringSchema<O>(options)
147
- })
148
-
149
- /*@__NO_SIDE_EFFECTS__*/
150
- export function regexp<T extends string = string>(pattern: RegExp) {
151
- return new RegexpSchema<T>(pattern)
152
- }
153
-
154
- /*@__NO_SIDE_EFFECTS__*/
155
- export function array<const S extends Validator>(
156
- items: S,
157
- options?: ArraySchemaOptions,
158
- ): ArraySchema<S>
159
- export function array<T, const S extends Validator<T> = Validator<T>>(
160
- items: S,
161
- options?: ArraySchemaOptions,
162
- ): ArraySchema<S>
163
- export function array<const S extends Validator>(
164
- items: S,
165
- options?: ArraySchemaOptions,
166
- ) {
167
- return new ArraySchema<S>(items, options)
168
- }
169
-
170
- /*@__NO_SIDE_EFFECTS__*/
171
- export function object<const P extends ObjectSchemaShape>(properties: P) {
172
- return new ObjectSchema<P>(properties)
173
- }
174
-
175
- /*@__NO_SIDE_EFFECTS__*/
176
- export function dict<
177
- const K extends Validator<string>,
178
- const V extends Validator,
179
- >(key: K, value: V) {
180
- return new DictSchema<K, V>(key, value)
181
- }
182
-
183
- // Utility
184
- export type { UnknownObjectOutput as UnknownObject }
185
-
186
- export const unknownObject = /*#__PURE__*/ memoizedOptions(function () {
187
- return new UnknownObjectSchema()
188
- })
189
-
190
- /*@__NO_SIDE_EFFECTS__*/
191
- export function ref<T>(get: RefSchemaGetter<T>) {
192
- return new RefSchema<T>(get)
193
- }
194
-
195
- /*@__NO_SIDE_EFFECTS__*/
196
- export function custom<T>(
197
- assertion: CustomAssertion<T>,
198
- message: string,
199
- path?: PropertyKey | readonly PropertyKey[],
200
- ) {
201
- return new CustomSchema<T>(assertion, message, path)
202
- }
203
-
204
- export const nullable = /*#__PURE__*/ memoizedTransformer(function <
205
- const S extends Validator,
206
- >(schema: S) {
207
- return new NullableSchema<Infer<S>>(schema)
208
- })
209
-
210
- export const optional = /*#__PURE__*/ memoizedTransformer(function <
211
- const S extends Validator,
212
- >(schema: S) {
213
- return new OptionalSchema<Infer<S>>(schema)
214
- })
215
-
216
- /*@__NO_SIDE_EFFECTS__*/
217
- export function union<const V extends UnionSchemaValidators>(validators: V) {
218
- return new UnionSchema<V>(validators)
219
- }
220
-
221
- /*@__NO_SIDE_EFFECTS__*/
222
- export function intersection<
223
- const Left extends ObjectSchema,
224
- const Right extends DictSchema,
225
- >(left: Left, right: Right) {
226
- return new IntersectionSchema<Left, Right>(left, right)
227
- }
228
-
229
- export { refine }
230
-
231
- /*@__NO_SIDE_EFFECTS__*/
232
- export function discriminatedUnion<
233
- const Discriminator extends string,
234
- const Options extends DiscriminatedUnionVariants<Discriminator>,
235
- >(discriminator: Discriminator, variants: Options) {
236
- return new DiscriminatedUnionSchema<Discriminator, Options>(
237
- discriminator,
238
- variants,
239
- )
240
- }
241
-
242
- /*@__NO_SIDE_EFFECTS__*/
243
- export function token<const N extends NsidString, const H extends string>(
244
- nsid: N,
245
- hash: H,
246
- ) {
247
- return new TokenSchema($type(nsid, hash))
248
- }
249
-
250
- /*@__NO_SIDE_EFFECTS__*/
251
- export function typedRef<const V extends { $type?: string }>(
252
- get: TypedRefGetter<V>,
253
- ) {
254
- return new TypedRefSchema<V>(get)
255
- }
256
-
257
- /*@__NO_SIDE_EFFECTS__*/
258
- export function typedUnion<
259
- const R extends readonly TypedRefSchema[],
260
- const C extends boolean,
261
- >(refs: R, closed: C) {
262
- return new TypedUnionSchema<R, C>(refs, closed)
263
- }
264
-
265
- /**
266
- * This function offers two overloads:
267
- * - One that allows creating a {@link TypedObjectSchema}, and infer the output
268
- * type from the provided arguments, without requiring to specify any of the
269
- * generics. This is useful when you want to define a record without
270
- * explicitly defining its interface. This version does not support circular
271
- * references, as TypeScript cannot infer types in such cases.
272
- * - One allows creating a {@link TypedObjectSchema} with an explicitly defined
273
- * interface. This will typically be used by codegen (`lex build`) to generate
274
- * schemas that work even if they contain circular references.
275
- */
276
- export function typedObject<
277
- const N extends NsidString,
278
- const H extends string,
279
- const S extends Validator<{ [k: string]: unknown }>,
280
- >(nsid: N, hash: H, schema: S): TypedObjectSchema<$Type<N, H>, S>
281
- export function typedObject<V extends { $type?: $Type }>(
282
- nsid: V extends { $type?: infer T extends string }
283
- ? T extends `${infer N}#${string}`
284
- ? N
285
- : T // (T is a "main" type, so already an NSID)
286
- : never,
287
- hash: V extends { $type?: infer T extends string }
288
- ? T extends `${string}#${infer H}`
289
- ? H
290
- : 'main'
291
- : never,
292
- schema: Validator<Omit<V, '$type'>>,
293
- ): TypedObjectSchema<$TypeOf<V>, Validator<Omit<V, '$type'>>>
294
- /*@__NO_SIDE_EFFECTS__*/
295
- export function typedObject<
296
- const N extends NsidString,
297
- const H extends string,
298
- const S extends Validator<{ [k: string]: unknown }>,
299
- >(nsid: N, hash: H, schema: S) {
300
- return new TypedObjectSchema<$Type<N, H>, S>($type(nsid, hash), schema)
301
- }
302
-
303
- /**
304
- * Ensures that a `$type` used in a record is a valid NSID (i.e. no fragment).
305
- */
306
- type AsNsid<T> = T extends `${string}#${string}` ? never : T
307
-
308
- /**
309
- * This function offers two overloads:
310
- * - One that allows creating a {@link RecordSchema}, and infer the output type
311
- * from the provided arguments, without requiring to specify any of the
312
- * generics. This is useful when you want to define a record without
313
- * explicitly defining its interface. This version does not support circular
314
- * references, as TypeScript cannot infer types in such cases.
315
- * - One allows creating a {@link RecordSchema} with an explicitly defined
316
- * interface. This will typically be used by codegen (`lex build`) to generate
317
- * schemas that work even if they contain circular references.
318
- */
319
- export function record<
320
- const K extends LexiconRecordKey,
321
- const T extends NsidString,
322
- const S extends Validator<{ [k: string]: unknown }>,
323
- >(key: K, type: AsNsid<T>, schema: S): RecordSchema<K, T, S>
324
- export function record<
325
- const K extends LexiconRecordKey,
326
- const V extends { $type: NsidString },
327
- >(
328
- key: K,
329
- type: AsNsid<V['$type']>,
330
- schema: Validator<Omit<V, '$type'>>,
331
- ): RecordSchema<K, V['$type'], Validator<Omit<V, '$type'>>>
332
- /*@__NO_SIDE_EFFECTS__*/
333
- export function record<
334
- const K extends LexiconRecordKey,
335
- const T extends NsidString,
336
- const S extends Validator<{ [k: string]: unknown }>,
337
- >(key: K, type: T, schema: S) {
338
- return new RecordSchema<K, T, S>(key, type, schema)
339
- }
340
-
341
- export const params = /*#__PURE__*/ memoizedOptions(function <
342
- const P extends ParamsSchemaShape = NonNullable<unknown>,
343
- >(properties: P = {} as P) {
344
- return new ParamsSchema<P>(properties)
345
- })
346
-
347
- /*@__NO_SIDE_EFFECTS__*/
348
- export function payload<
349
- const E extends string | undefined = undefined,
350
- const S extends PayloadSchema<E> = undefined,
351
- >(encoding: E = undefined as E, schema: S = undefined as S) {
352
- return new Payload<E, S>(encoding, schema)
353
- }
354
-
355
- /*@__NO_SIDE_EFFECTS__*/
356
- export function jsonPayload<const P extends ObjectSchemaShape>(
357
- properties: P,
358
- ): Payload<'application/json', ObjectSchema<P>> {
359
- return payload('application/json', object(properties))
360
- }
361
-
362
- /*@__NO_SIDE_EFFECTS__*/
363
- export function query<
364
- const N extends NsidString,
365
- const P extends ParamsSchema,
366
- const O extends Payload,
367
- const E extends undefined | readonly string[] = undefined,
368
- >(nsid: N, parameters: P, output: O, errors: E = undefined as E) {
369
- return new Query<N, P, O, E>(nsid, parameters, output, errors)
370
- }
371
-
372
- /*@__NO_SIDE_EFFECTS__*/
373
- export function procedure<
374
- const N extends NsidString,
375
- const P extends ParamsSchema,
376
- const I extends Payload,
377
- const O extends Payload,
378
- const E extends undefined | readonly string[] = undefined,
379
- >(nsid: N, parameters: P, input: I, output: O, errors: E = undefined as E) {
380
- return new Procedure<N, P, I, O, E>(nsid, parameters, input, output, errors)
381
- }
382
-
383
- /*@__NO_SIDE_EFFECTS__*/
384
- export function subscription<
385
- const N extends NsidString,
386
- const P extends ParamsSchema,
387
- const M extends Schema,
388
- const E extends undefined | readonly string[] = undefined,
389
- >(nsid: N, parameters: P, message: M, errors: E = undefined as E) {
390
- return new Subscription<N, P, M, E>(nsid, parameters, message, errors)
391
- }
392
-
393
- /*@__NO_SIDE_EFFECTS__*/
394
- export function permission<
395
- const R extends string,
396
- const O extends PermissionOptions,
397
- >(resource: R, options: PermissionOptions & O = {} as O) {
398
- return new Permission<R, O>(resource, options)
399
- }
400
-
401
- /*@__NO_SIDE_EFFECTS__*/
402
- export function permissionSet<
403
- const N extends NsidString,
404
- const P extends readonly Permission[],
405
- >(nsid: N, permissions: P, options?: PermissionSetOptions) {
406
- return new PermissionSet<N, P>(nsid, permissions, options)
407
- }