@atproto/lex-schema 0.1.5 → 0.1.6

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 (263) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/core/$type.d.ts +2 -2
  3. package/dist/core/$type.d.ts.map +1 -1
  4. package/dist/core/$type.js.map +1 -1
  5. package/dist/core/record-key.d.ts +1 -1
  6. package/dist/core/record-key.d.ts.map +1 -1
  7. package/dist/core/record-key.js.map +1 -1
  8. package/dist/core/schema.d.ts +3 -2
  9. package/dist/core/schema.d.ts.map +1 -1
  10. package/dist/core/schema.js +1 -1
  11. package/dist/core/schema.js.map +1 -1
  12. package/dist/core/standard-schema.d.ts +2 -2
  13. package/dist/core/standard-schema.d.ts.map +1 -1
  14. package/dist/core/standard-schema.js.map +1 -1
  15. package/dist/core/string-format.d.ts +2 -2
  16. package/dist/core/string-format.d.ts.map +1 -1
  17. package/dist/core/string-format.js.map +1 -1
  18. package/dist/core/validation-error.d.ts +1 -1
  19. package/dist/core/validation-error.d.ts.map +1 -1
  20. package/dist/core/validation-error.js +1 -1
  21. package/dist/core/validation-error.js.map +1 -1
  22. package/dist/core/validator.d.ts +1 -1
  23. package/dist/core/validator.d.ts.map +1 -1
  24. package/dist/core/validator.js +1 -1
  25. package/dist/core/validator.js.map +1 -1
  26. package/dist/helpers.d.ts +2 -2
  27. package/dist/helpers.d.ts.map +1 -1
  28. package/dist/helpers.js +2 -2
  29. package/dist/helpers.js.map +1 -1
  30. package/dist/schema/array.d.ts +1 -1
  31. package/dist/schema/array.d.ts.map +1 -1
  32. package/dist/schema/array.js +1 -1
  33. package/dist/schema/array.js.map +1 -1
  34. package/dist/schema/blob.d.ts +1 -1
  35. package/dist/schema/blob.d.ts.map +1 -1
  36. package/dist/schema/blob.js +2 -2
  37. package/dist/schema/blob.js.map +1 -1
  38. package/dist/schema/boolean.js +1 -1
  39. package/dist/schema/boolean.js.map +1 -1
  40. package/dist/schema/bytes.js +1 -1
  41. package/dist/schema/bytes.js.map +1 -1
  42. package/dist/schema/cid.d.ts +1 -1
  43. package/dist/schema/cid.d.ts.map +1 -1
  44. package/dist/schema/cid.js +3 -3
  45. package/dist/schema/cid.js.map +1 -1
  46. package/dist/schema/custom.js +1 -1
  47. package/dist/schema/custom.js.map +1 -1
  48. package/dist/schema/dict.d.ts +1 -1
  49. package/dist/schema/dict.d.ts.map +1 -1
  50. package/dist/schema/dict.js +1 -1
  51. package/dist/schema/dict.js.map +1 -1
  52. package/dist/schema/discriminated-union.d.ts +1 -1
  53. package/dist/schema/discriminated-union.d.ts.map +1 -1
  54. package/dist/schema/discriminated-union.js +2 -1
  55. package/dist/schema/discriminated-union.js.map +1 -1
  56. package/dist/schema/enum.js +1 -1
  57. package/dist/schema/enum.js.map +1 -1
  58. package/dist/schema/integer.js +1 -1
  59. package/dist/schema/integer.js.map +1 -1
  60. package/dist/schema/intersection.d.ts +1 -1
  61. package/dist/schema/intersection.d.ts.map +1 -1
  62. package/dist/schema/intersection.js +3 -1
  63. package/dist/schema/intersection.js.map +1 -1
  64. package/dist/schema/lex-map.d.ts +1 -1
  65. package/dist/schema/lex-map.d.ts.map +1 -1
  66. package/dist/schema/lex-map.js +1 -1
  67. package/dist/schema/lex-map.js.map +1 -1
  68. package/dist/schema/lex-value.d.ts +1 -1
  69. package/dist/schema/lex-value.d.ts.map +1 -1
  70. package/dist/schema/lex-value.js +1 -1
  71. package/dist/schema/lex-value.js.map +1 -1
  72. package/dist/schema/literal.js +1 -1
  73. package/dist/schema/literal.js.map +1 -1
  74. package/dist/schema/never.js +1 -1
  75. package/dist/schema/never.js.map +1 -1
  76. package/dist/schema/null.js +1 -1
  77. package/dist/schema/null.js.map +1 -1
  78. package/dist/schema/nullable.d.ts +1 -1
  79. package/dist/schema/nullable.d.ts.map +1 -1
  80. package/dist/schema/nullable.js +1 -1
  81. package/dist/schema/nullable.js.map +1 -1
  82. package/dist/schema/object.d.ts +2 -1
  83. package/dist/schema/object.d.ts.map +1 -1
  84. package/dist/schema/object.js +1 -1
  85. package/dist/schema/object.js.map +1 -1
  86. package/dist/schema/optional.d.ts +2 -1
  87. package/dist/schema/optional.d.ts.map +1 -1
  88. package/dist/schema/optional.js +2 -1
  89. package/dist/schema/optional.js.map +1 -1
  90. package/dist/schema/params.d.ts +1 -1
  91. package/dist/schema/params.d.ts.map +1 -1
  92. package/dist/schema/params.js +1 -1
  93. package/dist/schema/params.js.map +1 -1
  94. package/dist/schema/payload.d.ts +3 -2
  95. package/dist/schema/payload.d.ts.map +1 -1
  96. package/dist/schema/payload.js +2 -1
  97. package/dist/schema/payload.js.map +1 -1
  98. package/dist/schema/permission-set.d.ts +1 -1
  99. package/dist/schema/permission-set.d.ts.map +1 -1
  100. package/dist/schema/permission-set.js +1 -0
  101. package/dist/schema/permission-set.js.map +1 -1
  102. package/dist/schema/permission.d.ts +1 -1
  103. package/dist/schema/permission.d.ts.map +1 -1
  104. package/dist/schema/permission.js.map +1 -1
  105. package/dist/schema/procedure.d.ts +1 -1
  106. package/dist/schema/procedure.d.ts.map +1 -1
  107. package/dist/schema/procedure.js +2 -0
  108. package/dist/schema/procedure.js.map +1 -1
  109. package/dist/schema/query.d.ts +1 -1
  110. package/dist/schema/query.d.ts.map +1 -1
  111. package/dist/schema/query.js +2 -0
  112. package/dist/schema/query.js.map +1 -1
  113. package/dist/schema/record.d.ts +2 -2
  114. package/dist/schema/record.d.ts.map +1 -1
  115. package/dist/schema/record.js +1 -1
  116. package/dist/schema/record.js.map +1 -1
  117. package/dist/schema/ref.d.ts +1 -1
  118. package/dist/schema/ref.d.ts.map +1 -1
  119. package/dist/schema/ref.js +1 -1
  120. package/dist/schema/ref.js.map +1 -1
  121. package/dist/schema/refine.d.ts +2 -2
  122. package/dist/schema/refine.d.ts.map +1 -1
  123. package/dist/schema/refine.js +1 -1
  124. package/dist/schema/refine.js.map +1 -1
  125. package/dist/schema/regexp.js +1 -1
  126. package/dist/schema/regexp.js.map +1 -1
  127. package/dist/schema/string.d.ts +2 -2
  128. package/dist/schema/string.d.ts.map +1 -1
  129. package/dist/schema/string.js +1 -1
  130. package/dist/schema/string.js.map +1 -1
  131. package/dist/schema/subscription.d.ts +3 -2
  132. package/dist/schema/subscription.d.ts.map +1 -1
  133. package/dist/schema/subscription.js +2 -0
  134. package/dist/schema/subscription.js.map +1 -1
  135. package/dist/schema/token.d.ts +1 -1
  136. package/dist/schema/token.d.ts.map +1 -1
  137. package/dist/schema/token.js +1 -1
  138. package/dist/schema/token.js.map +1 -1
  139. package/dist/schema/typed-object.d.ts +2 -2
  140. package/dist/schema/typed-object.d.ts.map +1 -1
  141. package/dist/schema/typed-object.js +1 -1
  142. package/dist/schema/typed-object.js.map +1 -1
  143. package/dist/schema/typed-ref.d.ts +1 -1
  144. package/dist/schema/typed-ref.d.ts.map +1 -1
  145. package/dist/schema/typed-ref.js +1 -1
  146. package/dist/schema/typed-ref.js.map +1 -1
  147. package/dist/schema/typed-union.d.ts +1 -1
  148. package/dist/schema/typed-union.d.ts.map +1 -1
  149. package/dist/schema/typed-union.js +3 -1
  150. package/dist/schema/typed-union.js.map +1 -1
  151. package/dist/schema/union.d.ts +1 -1
  152. package/dist/schema/union.d.ts.map +1 -1
  153. package/dist/schema/union.js +1 -1
  154. package/dist/schema/union.js.map +1 -1
  155. package/dist/schema/unknown.js +1 -1
  156. package/dist/schema/unknown.js.map +1 -1
  157. package/dist/schema/with-default.d.ts +1 -1
  158. package/dist/schema/with-default.d.ts.map +1 -1
  159. package/dist/schema/with-default.js +1 -1
  160. package/dist/schema/with-default.js.map +1 -1
  161. package/package.json +6 -10
  162. package/src/core/$type.test.ts +0 -24
  163. package/src/core/$type.ts +0 -199
  164. package/src/core/record-key.ts +0 -85
  165. package/src/core/result.ts +0 -15
  166. package/src/core/schema.ts +0 -412
  167. package/src/core/standard-schema.test.ts +0 -124
  168. package/src/core/standard-schema.ts +0 -31
  169. package/src/core/string-format.ts +0 -411
  170. package/src/core/types.ts +0 -120
  171. package/src/core/validation-error.ts +0 -134
  172. package/src/core/validation-issue.ts +0 -340
  173. package/src/core/validator.ts +0 -636
  174. package/src/core.ts +0 -9
  175. package/src/external.ts +0 -3
  176. package/src/helpers.test.ts +0 -694
  177. package/src/helpers.ts +0 -222
  178. package/src/index.ts +0 -3
  179. package/src/schema/array.test.ts +0 -251
  180. package/src/schema/array.ts +0 -126
  181. package/src/schema/blob.test.ts +0 -733
  182. package/src/schema/blob.ts +0 -150
  183. package/src/schema/boolean.test.ts +0 -118
  184. package/src/schema/boolean.ts +0 -46
  185. package/src/schema/bytes.test.ts +0 -227
  186. package/src/schema/bytes.ts +0 -81
  187. package/src/schema/cid.test.ts +0 -125
  188. package/src/schema/cid.ts +0 -69
  189. package/src/schema/custom.test.ts +0 -414
  190. package/src/schema/custom.ts +0 -106
  191. package/src/schema/dict.test.ts +0 -181
  192. package/src/schema/dict.ts +0 -122
  193. package/src/schema/discriminated-union.test.ts +0 -676
  194. package/src/schema/discriminated-union.ts +0 -196
  195. package/src/schema/enum.test.ts +0 -398
  196. package/src/schema/enum.ts +0 -77
  197. package/src/schema/integer.test.ts +0 -314
  198. package/src/schema/integer.ts +0 -86
  199. package/src/schema/intersection.test.ts +0 -33
  200. package/src/schema/intersection.ts +0 -113
  201. package/src/schema/lex-map.test.ts +0 -593
  202. package/src/schema/lex-map.ts +0 -63
  203. package/src/schema/lex-value.test.ts +0 -81
  204. package/src/schema/lex-value.ts +0 -86
  205. package/src/schema/literal.test.ts +0 -533
  206. package/src/schema/literal.ts +0 -70
  207. package/src/schema/never.test.ts +0 -175
  208. package/src/schema/never.ts +0 -56
  209. package/src/schema/null.test.ts +0 -80
  210. package/src/schema/null.ts +0 -49
  211. package/src/schema/nullable.test.ts +0 -470
  212. package/src/schema/nullable.ts +0 -74
  213. package/src/schema/object.test.ts +0 -69
  214. package/src/schema/object.ts +0 -136
  215. package/src/schema/optional.test.ts +0 -479
  216. package/src/schema/optional.ts +0 -92
  217. package/src/schema/params.test.ts +0 -1118
  218. package/src/schema/params.ts +0 -371
  219. package/src/schema/payload.test.ts +0 -340
  220. package/src/schema/payload.ts +0 -204
  221. package/src/schema/permission-set.test.ts +0 -613
  222. package/src/schema/permission-set.ts +0 -86
  223. package/src/schema/permission.test.ts +0 -537
  224. package/src/schema/permission.ts +0 -63
  225. package/src/schema/procedure.test.ts +0 -324
  226. package/src/schema/procedure.ts +0 -98
  227. package/src/schema/query.test.ts +0 -348
  228. package/src/schema/query.ts +0 -86
  229. package/src/schema/record.test.ts +0 -812
  230. package/src/schema/record.ts +0 -217
  231. package/src/schema/ref.test.ts +0 -349
  232. package/src/schema/ref.ts +0 -103
  233. package/src/schema/refine.test.ts +0 -579
  234. package/src/schema/refine.ts +0 -153
  235. package/src/schema/regexp.test.ts +0 -577
  236. package/src/schema/regexp.ts +0 -82
  237. package/src/schema/string.test.ts +0 -773
  238. package/src/schema/string.ts +0 -229
  239. package/src/schema/subscription.test.ts +0 -499
  240. package/src/schema/subscription.ts +0 -108
  241. package/src/schema/token.test.ts +0 -152
  242. package/src/schema/token.ts +0 -103
  243. package/src/schema/typed-object.test.ts +0 -745
  244. package/src/schema/typed-object.ts +0 -181
  245. package/src/schema/typed-ref.test.ts +0 -796
  246. package/src/schema/typed-ref.ts +0 -126
  247. package/src/schema/typed-union.test.ts +0 -355
  248. package/src/schema/typed-union.ts +0 -130
  249. package/src/schema/union.test.ts +0 -191
  250. package/src/schema/union.ts +0 -89
  251. package/src/schema/unknown.test.ts +0 -313
  252. package/src/schema/unknown.ts +0 -47
  253. package/src/schema/with-default.ts +0 -81
  254. package/src/schema.ts +0 -43
  255. package/src/util/array-agg.test.ts +0 -42
  256. package/src/util/array-agg.ts +0 -44
  257. package/src/util/assertion-util.ts +0 -1
  258. package/src/util/if-any.ts +0 -3
  259. package/src/util/lazy-property.ts +0 -14
  260. package/src/util/memoize.ts +0 -37
  261. package/tsconfig.build.json +0 -12
  262. package/tsconfig.json +0 -7
  263. package/tsconfig.tests.json +0 -8
@@ -1,636 +0,0 @@
1
- import type * as Result from './result.js'
2
- import { LexValidationError } from './validation-error.js'
3
- import {
4
- Issue,
5
- IssueInvalidFormat,
6
- IssueInvalidType,
7
- IssueInvalidValue,
8
- IssueRequiredKey,
9
- IssueTooBig,
10
- IssueTooSmall,
11
- MeasurableType,
12
- } from './validation-issue.js'
13
-
14
- /**
15
- * Represents a successful validation result.
16
- *
17
- * @typeParam TValue - The type of the validated value
18
- * @extends Result.ResultSuccess<TValue>
19
- */
20
- export type ValidationSuccess<TValue = unknown> = Result.ResultSuccess<TValue>
21
-
22
- /**
23
- * Represents a failed validation result containing a {@link LexValidationError}.
24
- *
25
- * @see {@link LexValidationError}
26
- * @extends Result.ResultFailure<LexValidationError>
27
- */
28
- export type ValidationFailure = LexValidationError
29
-
30
- /**
31
- * Discriminated union representing the outcome of a validation operation.
32
- *
33
- * Check the `success` property to determine if validation passed or failed:
34
- * - If `success` is `true`, the `value` property contains the validated data
35
- * - If `success` is `false`, the `reason` property contains the {@link LexValidationError}
36
- *
37
- * @typeParam Value - The type of the validated value on success
38
- *
39
- * @example
40
- * ```typescript
41
- * const result: ValidationResult<string> = schema.safeParse(data)
42
- * if (result.success) {
43
- * // result.value is string
44
- * } else {
45
- * // result.reason is LexValidationError
46
- * }
47
- * ```
48
- */
49
- export type ValidationResult<Value = unknown> =
50
- | ValidationSuccess<Value>
51
- | ValidationFailure
52
-
53
- /**
54
- * Extracts the input type that a validator accepts.
55
- *
56
- * Use this utility type to infer what type a schema will accept during validation.
57
- *
58
- * @typeParam V - A validator type
59
- *
60
- * @example
61
- * ```typescript
62
- * const userSchema = new ObjectSchema({ name: stringSchema, age: numberSchema })
63
- * type UserInput = InferInput<typeof userSchema>
64
- * // { name: string; age: number }
65
- * ```
66
- */
67
- export type InferInput<V extends Validator> = V['__lex']['input']
68
-
69
- /**
70
- * Extracts the output type that a validator produces after parsing.
71
- *
72
- * The output type may differ from the input type when the schema applies
73
- * transformations such as default values or type coercion during parsing.
74
- *
75
- * @typeParam V - A validator type
76
- *
77
- * @example
78
- * ```typescript
79
- * const schema = new StringSchema().default('hello')
80
- * type Input = InferInput<typeof schema> // string | undefined
81
- * type Output = InferOutput<typeof schema> // string
82
- * ```
83
- */
84
- export type InferOutput<V extends Validator> = V['__lex']['output']
85
-
86
- /**
87
- * Alias for {@link InferInput} for convenient type inference.
88
- *
89
- * @typeParam V - A validator type
90
- */
91
- export type { InferInput as Infer }
92
-
93
- export interface Validator<TInput = unknown, TOutput = TInput> {
94
- /**
95
- * This property is used for type inference purposes and does not actually
96
- * exist at runtime.
97
- *
98
- * @internal
99
- * @deprecated **INTERNAL API, DO NOT USE**.
100
- */
101
- readonly ['__lex']: {
102
- input: TInput
103
- output: TOutput
104
- }
105
-
106
- /**
107
- * @internal **INTERNAL API**: use {@link ValidationContext.validate} instead
108
- *
109
- * This method is implemented by subclasses to perform transformation and
110
- * validation of the input value. Do not call this method directly; as the
111
- * {@link ValidationContext.options.mode} option will **not** be enforced. See
112
- * {@link ValidationContext.validate} for details. When delegating validation
113
- * from one validator sub-class implementation to another schema,
114
- * {@link ValidationContext.validate} must be used instead of calling
115
- * {@link Validator.validateInContext}. This will allow to stop the validation
116
- * process if the value was transformed (by the other schema) but
117
- * transformations are not allowed.
118
- *
119
- * By convention, the {@link ValidationResult} must return the original input
120
- * value if validation was successful and no transformation was applied (i.e.
121
- * the input already conformed to the schema). If a default value, or any
122
- * other transformation was applied, the returned value can be different from
123
- * the input.
124
- *
125
- * This convention allows the {@link Validator.check check} and
126
- * {@link Validator.assert assert} methods to check whether the input value
127
- * exactly matches the schema (without defaults or transformations), by
128
- * checking if the returned value is strictly equal to the input.
129
- *
130
- * @see {@link ValidationContext.validate}
131
- */
132
- validateInContext(input: unknown, ctx: ValidationContext): ValidationResult
133
- }
134
-
135
- /**
136
- * Configuration options for validation and parsing operations.
137
- *
138
- * @example
139
- * ```typescript
140
- * // Validate mode (strict, no transformations)
141
- * ValidationContext.validate(data, schema, { mode: 'validate' })
142
- *
143
- * // Parse mode (allows transformations like defaults)
144
- * ValidationContext.validate(data, schema, { mode: 'parse' })
145
- *
146
- * // With initial path for nested validation
147
- * ValidationContext.validate(data, schema, { path: ['user', 'profile'] })
148
- * ```
149
- */
150
- export type ValidationOptions = {
151
- /**
152
- * The validation mode determining how transformations are handled.
153
- *
154
- * - `"validate"`: Strict validation where the result must be
155
- * strictly equal to the input value. No transformations such as applying
156
- * default values are allowed.
157
- * - `"parse"`: Allows the schema to transform the input value, such as
158
- * applying default values or performing type coercion.
159
- *
160
- * @default "validate"
161
- */
162
- mode?: 'validate' | 'parse'
163
-
164
- /**
165
- * The initial path to the value being validated.
166
- *
167
- * This is used to provide context in validation issues when validating
168
- * nested structures. The path is prepended to all issue paths.
169
- *
170
- * @example
171
- * ```typescript
172
- * // Issues will be reported at paths like "user.name" instead of just "name"
173
- * ValidationContext.validate(data, schema, { path: ['user'] })
174
- * ```
175
- */
176
- path?: readonly PropertyKey[]
177
-
178
- /**
179
- * Whether to enforce strict validation rules (e.g., MIME type matching, size
180
- * limits, datetime format).
181
- *
182
- * This is typically useful to allow more lax validation when parsing server
183
- * responses, while enforcing strict validation for user input.
184
- *
185
- * @default true
186
- */
187
- strict?: boolean
188
- }
189
-
190
- /**
191
- * Manages the state and context for validation operations.
192
- *
193
- * The `ValidationContext` class is responsible for:
194
- * - Tracking the current path in nested structures for error reporting
195
- * - Collecting validation issues during traversal
196
- * - Enforcing validation mode (validate vs parse)
197
- * - Providing factory methods for creating validation results
198
- *
199
- * Use the static {@link ValidationContext.validate} method as the primary entry point
200
- * for validation. This ensures proper mode enforcement and issue aggregation.
201
- *
202
- * @example
203
- * ```typescript
204
- * // Primary usage via static method
205
- * const result = ValidationContext.validate(data, schema, { mode: 'parse' })
206
- *
207
- * // Within a custom validator implementation
208
- * class MyValidator implements Validator {
209
- * validateInContext(input: unknown, ctx: ValidationContext): ValidationResult {
210
- * if (typeof input !== 'string') {
211
- * return ctx.issueUnexpectedType(input, 'string')
212
- * }
213
- * return ctx.success(input)
214
- * }
215
- * }
216
- * ```
217
- */
218
- export class ValidationContext {
219
- /**
220
- * Validates input against a validator in parse mode.
221
- *
222
- * In parse mode, the schema may transform the input (e.g., apply defaults).
223
- *
224
- * @param input - The value to validate
225
- * @param validator - The validator to use
226
- * @param options - Validation options with mode set to 'parse'
227
- * @returns A validation result with the parsed output type
228
- */
229
- static validate<V extends Validator>(
230
- input: unknown,
231
- validator: V,
232
- options: ValidationOptions & {
233
- mode: 'parse'
234
- },
235
- ): ValidationResult<InferOutput<V>>
236
-
237
- /**
238
- * Validates input against a validator in validate mode (default).
239
- *
240
- * In validate mode, the result must be strictly equal to the input.
241
- * No transformations are allowed.
242
- *
243
- * @typeParam V - The validator type
244
- * @typeParam I - The input type
245
- * @param input - The value to validate
246
- * @param validator - The validator to use
247
- * @param options - Optional validation options (defaults to validate mode)
248
- * @returns A validation result preserving the input type intersected with the schema type
249
- */
250
- static validate<V extends Validator, I = unknown>(
251
- input: I,
252
- validator: V,
253
- options?: ValidationOptions & {
254
- mode?: 'validate'
255
- },
256
- ): ValidationResult<I & InferInput<V>>
257
-
258
- /**
259
- * Validates input against a validator with configurable options.
260
- *
261
- * @param input - The value to validate
262
- * @param validator - The validator to use
263
- * @param options - Optional validation options
264
- * @returns A validation result with either the input or output type
265
- */
266
- static validate<V extends Validator>(
267
- input: unknown,
268
- validator: V,
269
- options?: ValidationOptions,
270
- ): ValidationResult<InferOutput<V> | InferInput<V>>
271
- static validate<V extends Validator>(
272
- input: unknown,
273
- validator: V,
274
- options?: ValidationOptions,
275
- ): ValidationResult<InferOutput<V> | InferInput<V>> {
276
- const context = new ValidationContext({
277
- path: options?.path ?? [],
278
- mode: options?.mode ?? 'validate',
279
- strict: options?.strict ?? true,
280
- })
281
- return context.validate(input, validator)
282
- }
283
-
284
- /**
285
- * The current path being validated, used for error reporting.
286
- */
287
- protected readonly currentPath: PropertyKey[]
288
-
289
- /**
290
- * Accumulated validation issues collected during traversal.
291
- */
292
- protected readonly issues: Issue[] = []
293
-
294
- /**
295
- * Creates a new validation context with the specified options.
296
- *
297
- * @param options - The validation options (path and mode are required)
298
- */
299
- constructor(readonly options: Required<ValidationOptions>) {
300
- // Create a copy because we will be mutating the array during validation.
301
- this.currentPath = Array.from(options.path)
302
- }
303
-
304
- /**
305
- * Returns a copy of the current validation path.
306
- *
307
- * The path represents the location in the data structure being validated,
308
- * used for constructing meaningful error messages.
309
- */
310
- get path() {
311
- return Array.from(this.currentPath)
312
- }
313
-
314
- /**
315
- * Creates a new path by appending segments to the current path.
316
- *
317
- * @param path - Optional path segment(s) to append
318
- * @returns A new path array with the segment(s) appended
319
- */
320
- concatPath(path?: PropertyKey | readonly PropertyKey[]) {
321
- if (path == null) return this.path
322
- return this.currentPath.concat(path)
323
- }
324
-
325
- /**
326
- * Validates input against a validator within this context.
327
- *
328
- * This is the primary entry point for validation within a context. Always use
329
- * this method instead of calling {@link Validator.validateInContext} directly,
330
- * as this method enforces validation mode rules and handles transformation detection.
331
- *
332
- * @typeParam V - The validator type
333
- * @param input - The value to validate
334
- * @param validator - The validator to use
335
- * @returns A validation result with the validated value or error
336
- */
337
- validate<V extends Validator>(
338
- input: unknown,
339
- validator: V,
340
- ): ValidationResult<InferInput<V>> {
341
- // This is the only place where validateInContext should be called.
342
- const result = validator.validateInContext(input, this)
343
-
344
- if (result.success) {
345
- if (this.issues.length > 0) {
346
- // Validator returned a success but issues were added via the context.
347
- // This means the overall validation failed.
348
- return new LexValidationError(Array.from(this.issues))
349
- }
350
-
351
- if (this.options.mode !== 'parse' && !Object.is(result.value, input)) {
352
- // If the value changed, it means that a default (or some other
353
- // transformation) was applied, meaning that the original value did
354
- // *not* match the (output) schema. When not in "parse" mode, we
355
- // consider this a failure.
356
-
357
- // This check is the reason why Validator.validateInContext should not
358
- // be used directly, and ValidatorContext.validate should be used
359
- // instead, even when delegating validation from one validator to
360
- // another.
361
-
362
- // This if block comes before the next one because 'this.issues' will
363
- // end-up being appended to the returned LexValidationError (see the
364
- // "failure" method below), resulting in a more complete error report.
365
- return this.issueInvalidValue(input, [result.value])
366
- }
367
- }
368
-
369
- return result as ValidationResult<InferInput<V>>
370
- }
371
-
372
- /**
373
- * Validates a child property of an object within this context.
374
- *
375
- * This method automatically manages the path stack, pushing the property key
376
- * before validation and popping it afterward. Use this for validating object
377
- * properties to ensure proper path tracking in error messages.
378
- *
379
- * @typeParam I - The input object type
380
- * @typeParam K - The property key type
381
- * @typeParam V - The validator type
382
- * @param input - The parent object containing the property
383
- * @param key - The property key to validate
384
- * @param validator - The validator to use for the property value
385
- * @returns A validation result for the property value
386
- *
387
- * @example
388
- * ```typescript
389
- * // In a custom object validator
390
- * const result = ctx.validateChild(input, 'name', stringSchema)
391
- * // If validation fails, error path will include 'name'
392
- * ```
393
- */
394
- validateChild<
395
- I extends object,
396
- K extends PropertyKey & keyof I,
397
- V extends Validator,
398
- >(input: I, key: K, validator: V): ValidationResult<InferInput<V>> {
399
- // @NOTE we could add support for recursive schemas by keeping track of
400
- // "parent" objects in the context and checking for circular references
401
- // here. This would allow us to validate recursive structures without
402
- // hitting maximum call stack errors, and would also allow us to provide
403
- // better error messages for circular reference issues. However, this is not
404
- // a priority at the moment as recursive structures are not supported in
405
- // the context of AT Protocol lexicons, and we can always add this in the
406
- // future if needed.
407
-
408
- // Instead of creating a new context, we just push/pop the path segment.
409
- this.currentPath.push(key)
410
- try {
411
- return this.validate(input[key], validator)
412
- } finally {
413
- this.currentPath.length--
414
- }
415
- }
416
-
417
- /**
418
- * Adds a validation issue to the context without immediately failing.
419
- *
420
- * Use this method to collect multiple issues during validation before
421
- * determining the final result. Issues added this way will be included
422
- * in the final error if validation fails.
423
- *
424
- * @param issue - The validation issue to add
425
- */
426
- addIssue(issue: Issue): void {
427
- this.issues.push(issue)
428
- }
429
-
430
- /**
431
- * Helper method to create a successful validation result.
432
- *
433
- * @typeParam V - The value type
434
- * @param value - The validated value
435
- * @returns A successful validation result
436
- */
437
- success<V>(value: V): ValidationSuccess<V> {
438
- return { success: true, value }
439
- }
440
-
441
- /**
442
- * Creates a failed validation result from a single issue.
443
- *
444
- * Any previously accumulated issues in the context are included in the error.
445
- *
446
- * @param issue - The validation issue that caused the failure
447
- * @returns A failed validation result
448
- */
449
- issue(issue: Issue): ValidationFailure {
450
- return new LexValidationError([...this.issues, issue])
451
- }
452
-
453
- /**
454
- * Creates a failure for an invalid value that doesn't match expected values.
455
- *
456
- * @param input - The actual value that was received
457
- * @param values - The expected valid values
458
- * @returns A failed validation result with an invalid value issue
459
- */
460
- issueInvalidValue(input: unknown, values: readonly unknown[]) {
461
- return this.issue(new IssueInvalidValue(this.path, input, values))
462
- }
463
-
464
- /**
465
- * Creates a failure for an invalid type.
466
- *
467
- * @param input - The actual value that was received
468
- * @param expected - An array of expected type names
469
- * @returns A failed validation result with an invalid type issue
470
- */
471
- issueInvalidType(input: unknown, expected: readonly string[]) {
472
- return this.issue(new IssueInvalidType(this.path, input, expected))
473
- }
474
-
475
- /**
476
- * Creates a failure for an invalid type.
477
- *
478
- * @param input - The actual value that was received
479
- * @param expected - The expected type name
480
- * @returns A failed validation result with an invalid type issue
481
- */
482
- issueUnexpectedType(input: unknown, expected: string) {
483
- return this.issueInvalidType(input, [expected])
484
- }
485
-
486
- /**
487
- * Creates a failure for a missing required key in an object.
488
- *
489
- * @param input - The object missing the required key
490
- * @param key - The name of the required key
491
- * @returns A failed validation result with a required key issue
492
- */
493
- issueRequiredKey(input: object, key: PropertyKey) {
494
- return this.issue(new IssueRequiredKey(this.path, input, key))
495
- }
496
-
497
- /**
498
- * Creates a failure for an invalid string format.
499
- *
500
- * @param input - The actual value that was received
501
- * @param format - The expected format name (e.g., 'did', 'handle', 'uri')
502
- * @param msg - Optional additional message describing the format error
503
- * @returns A failed validation result with an invalid format issue
504
- */
505
- issueInvalidFormat(input: unknown, format: string, msg?: string) {
506
- return this.issue(new IssueInvalidFormat(this.path, input, format, msg))
507
- }
508
-
509
- /**
510
- * Creates a failure for a value that exceeds a maximum constraint.
511
- *
512
- * @param input - The actual value that was received
513
- * @param type - The type of measurement (e.g., 'string', 'array', 'bytes')
514
- * @param max - The maximum allowed value
515
- * @param actual - The actual measured value
516
- * @returns A failed validation result with a too big issue
517
- */
518
- issueTooBig(
519
- input: unknown,
520
- type: MeasurableType,
521
- max: number,
522
- actual: number,
523
- ) {
524
- return this.issue(new IssueTooBig(this.path, input, max, type, actual))
525
- }
526
-
527
- /**
528
- * Creates a failure for a value that is below a minimum constraint.
529
- *
530
- * @param input - The actual value that was received
531
- * @param type - The type of measurement (e.g., 'string', 'array', 'bytes')
532
- * @param min - The minimum required value
533
- * @param actual - The actual measured value
534
- * @returns A failed validation result with a too small issue
535
- */
536
- issueTooSmall(
537
- input: unknown,
538
- type: MeasurableType,
539
- min: number,
540
- actual: number,
541
- ) {
542
- return this.issue(new IssueTooSmall(this.path, input, min, type, actual))
543
- }
544
-
545
- /**
546
- * Creates a failure for an invalid property value within an object.
547
- *
548
- * This is a convenience method that automatically extracts the property value
549
- * and constructs the appropriate path.
550
- *
551
- * @typeParam I - The input object type
552
- * @param input - The object containing the invalid property
553
- * @param property - The property key with the invalid value
554
- * @param values - The expected valid values
555
- * @returns A failed validation result with an invalid value issue at the property path
556
- */
557
- issueInvalidPropertyValue<I>(
558
- input: I,
559
- property: keyof I & PropertyKey,
560
- values: readonly unknown[],
561
- ) {
562
- const value = input[property]
563
- const path = this.concatPath(property)
564
- return this.issue(new IssueInvalidValue(path, value, values))
565
- }
566
-
567
- /**
568
- * Creates a failure for an invalid property type within an object.
569
- *
570
- * This is a convenience method that automatically extracts the property value
571
- * and constructs the appropriate path.
572
- *
573
- * @typeParam I - The input object type
574
- * @param input - The object containing the invalid property
575
- * @param property - The property key with the invalid type
576
- * @param expected - The expected type name
577
- * @returns A failed validation result with an invalid type issue at the property path
578
- */
579
- issueInvalidPropertyType<I>(
580
- input: I,
581
- property: keyof I & PropertyKey,
582
- expected: string,
583
- ) {
584
- const value = input[property]
585
- const path = this.concatPath(property)
586
- return this.issue(new IssueInvalidType(path, value, [expected]))
587
- }
588
- }
589
-
590
- /**
591
- * Recursively unwraps a wrapped validator to its innermost validator type.
592
- *
593
- * Some validators wrap other validators (e.g., optional, nullable). This type
594
- * utility recursively unwraps such wrappers to reveal the core validator.
595
- *
596
- * @typeParam T - A validator type, possibly wrapped
597
- *
598
- * @example
599
- * ```typescript
600
- * type Inner = UnwrapValidator<OptionalValidator<NullableValidator<StringSchema>>>
601
- * // Result: StringSchema
602
- * ```
603
- */
604
- export type UnwrapValidator<T extends Validator> = T extends {
605
- unwrap(): infer U extends Validator
606
- }
607
- ? UnwrapValidator<U>
608
- : T
609
-
610
- /**
611
- * Interface for validators that wrap another validator.
612
- *
613
- * Implement this interface when creating validators that wrap or modify
614
- * the behavior of another validator (e.g., optional, nullable, transform).
615
- *
616
- * @typeParam Validator - The type of the wrapped validator
617
- *
618
- * @example
619
- * ```typescript
620
- * class OptionalSchema<V extends Validator> implements WrappedValidator<V> {
621
- * constructor(private inner: V) {}
622
- *
623
- * unwrap(): V {
624
- * return this.inner
625
- * }
626
- * }
627
- * ```
628
- */
629
- export interface WrappedValidator<out Validator> {
630
- /**
631
- * Returns the inner wrapped validator.
632
- *
633
- * @returns The wrapped validator
634
- */
635
- unwrap(): Validator
636
- }
package/src/core.ts DELETED
@@ -1,9 +0,0 @@
1
- export * from './core/$type.js'
2
- export * from './core/record-key.js'
3
- export * from './core/result.js'
4
- export * from './core/schema.js'
5
- export * from './core/string-format.js'
6
- export * from './core/types.js'
7
- export * from './core/validation-error.js'
8
- export * from './core/validation-issue.js'
9
- export * from './core/validator.js'
package/src/external.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './core.js'
2
- export * from './helpers.js'
3
- export * from './schema.js'