@atproto/lex-schema 0.0.10 → 0.0.12

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 (239) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/core/$type.d.ts +149 -0
  3. package/dist/core/$type.d.ts.map +1 -1
  4. package/dist/core/$type.js +44 -0
  5. package/dist/core/$type.js.map +1 -1
  6. package/dist/core/record-key.d.ts +44 -0
  7. package/dist/core/record-key.d.ts.map +1 -1
  8. package/dist/core/record-key.js +30 -0
  9. package/dist/core/record-key.js.map +1 -1
  10. package/dist/core/result.d.ts +85 -4
  11. package/dist/core/result.d.ts.map +1 -1
  12. package/dist/core/result.js +60 -4
  13. package/dist/core/result.js.map +1 -1
  14. package/dist/core/schema.d.ts +229 -2
  15. package/dist/core/schema.d.ts.map +1 -1
  16. package/dist/core/schema.js +197 -4
  17. package/dist/core/schema.js.map +1 -1
  18. package/dist/core/string-format.d.ts +244 -11
  19. package/dist/core/string-format.d.ts.map +1 -1
  20. package/dist/core/string-format.js +150 -0
  21. package/dist/core/string-format.js.map +1 -1
  22. package/dist/core/types.d.ts +90 -3
  23. package/dist/core/types.d.ts.map +1 -1
  24. package/dist/core/types.js.map +1 -1
  25. package/dist/core/validation-error.d.ts +61 -1
  26. package/dist/core/validation-error.d.ts.map +1 -1
  27. package/dist/core/validation-error.js +60 -0
  28. package/dist/core/validation-error.js.map +1 -1
  29. package/dist/core/validation-issue.d.ts +61 -0
  30. package/dist/core/validation-issue.d.ts.map +1 -1
  31. package/dist/core/validation-issue.js +51 -0
  32. package/dist/core/validation-issue.js.map +1 -1
  33. package/dist/core/validator.d.ts +347 -10
  34. package/dist/core/validator.d.ts.map +1 -1
  35. package/dist/core/validator.js +184 -3
  36. package/dist/core/validator.js.map +1 -1
  37. package/dist/helpers.d.ts +13 -25
  38. package/dist/helpers.d.ts.map +1 -1
  39. package/dist/helpers.js +2 -2
  40. package/dist/helpers.js.map +1 -1
  41. package/dist/schema/array.d.ts +45 -0
  42. package/dist/schema/array.d.ts.map +1 -1
  43. package/dist/schema/array.js +14 -0
  44. package/dist/schema/array.js.map +1 -1
  45. package/dist/schema/blob.d.ts +46 -0
  46. package/dist/schema/blob.d.ts.map +1 -1
  47. package/dist/schema/blob.js +39 -0
  48. package/dist/schema/blob.js.map +1 -1
  49. package/dist/schema/boolean.d.ts +28 -0
  50. package/dist/schema/boolean.d.ts.map +1 -1
  51. package/dist/schema/boolean.js +28 -0
  52. package/dist/schema/boolean.js.map +1 -1
  53. package/dist/schema/bytes.d.ts +38 -0
  54. package/dist/schema/bytes.d.ts.map +1 -1
  55. package/dist/schema/bytes.js +32 -0
  56. package/dist/schema/bytes.js.map +1 -1
  57. package/dist/schema/cid.d.ts +38 -0
  58. package/dist/schema/cid.d.ts.map +1 -1
  59. package/dist/schema/cid.js +33 -0
  60. package/dist/schema/cid.js.map +1 -1
  61. package/dist/schema/custom.d.ts +66 -1
  62. package/dist/schema/custom.d.ts.map +1 -1
  63. package/dist/schema/custom.js +54 -0
  64. package/dist/schema/custom.js.map +1 -1
  65. package/dist/schema/dict.d.ts +44 -0
  66. package/dist/schema/dict.d.ts.map +1 -1
  67. package/dist/schema/dict.js +44 -0
  68. package/dist/schema/dict.js.map +1 -1
  69. package/dist/schema/discriminated-union.d.ts +58 -0
  70. package/dist/schema/discriminated-union.d.ts.map +1 -1
  71. package/dist/schema/discriminated-union.js +45 -0
  72. package/dist/schema/discriminated-union.js.map +1 -1
  73. package/dist/schema/enum.d.ts +48 -0
  74. package/dist/schema/enum.d.ts.map +1 -1
  75. package/dist/schema/enum.js +48 -0
  76. package/dist/schema/enum.js.map +1 -1
  77. package/dist/schema/integer.d.ts +42 -0
  78. package/dist/schema/integer.d.ts.map +1 -1
  79. package/dist/schema/integer.js +36 -0
  80. package/dist/schema/integer.js.map +1 -1
  81. package/dist/schema/intersection.d.ts +54 -0
  82. package/dist/schema/intersection.d.ts.map +1 -1
  83. package/dist/schema/intersection.js +49 -0
  84. package/dist/schema/intersection.js.map +1 -1
  85. package/dist/schema/literal.d.ts +44 -0
  86. package/dist/schema/literal.d.ts.map +1 -1
  87. package/dist/schema/literal.js +44 -0
  88. package/dist/schema/literal.js.map +1 -1
  89. package/dist/schema/never.d.ts +42 -0
  90. package/dist/schema/never.d.ts.map +1 -1
  91. package/dist/schema/never.js +42 -0
  92. package/dist/schema/never.js.map +1 -1
  93. package/dist/schema/null.d.ts +29 -0
  94. package/dist/schema/null.d.ts.map +1 -1
  95. package/dist/schema/null.js +29 -0
  96. package/dist/schema/null.js.map +1 -1
  97. package/dist/schema/nullable.d.ts +41 -0
  98. package/dist/schema/nullable.d.ts.map +1 -1
  99. package/dist/schema/nullable.js +41 -0
  100. package/dist/schema/nullable.js.map +1 -1
  101. package/dist/schema/object.d.ts +56 -0
  102. package/dist/schema/object.d.ts.map +1 -1
  103. package/dist/schema/object.js +51 -0
  104. package/dist/schema/object.js.map +1 -1
  105. package/dist/schema/optional.d.ts +42 -0
  106. package/dist/schema/optional.d.ts.map +1 -1
  107. package/dist/schema/optional.js +42 -0
  108. package/dist/schema/optional.js.map +1 -1
  109. package/dist/schema/params.d.ts +89 -7
  110. package/dist/schema/params.d.ts.map +1 -1
  111. package/dist/schema/params.js +84 -10
  112. package/dist/schema/params.js.map +1 -1
  113. package/dist/schema/payload.d.ts +111 -15
  114. package/dist/schema/payload.d.ts.map +1 -1
  115. package/dist/schema/payload.js +70 -0
  116. package/dist/schema/payload.js.map +1 -1
  117. package/dist/schema/permission-set.d.ts +58 -0
  118. package/dist/schema/permission-set.d.ts.map +1 -1
  119. package/dist/schema/permission-set.js +50 -0
  120. package/dist/schema/permission-set.js.map +1 -1
  121. package/dist/schema/permission.d.ts +42 -0
  122. package/dist/schema/permission.d.ts.map +1 -1
  123. package/dist/schema/permission.js +39 -0
  124. package/dist/schema/permission.js.map +1 -1
  125. package/dist/schema/procedure.d.ts +64 -0
  126. package/dist/schema/procedure.d.ts.map +1 -1
  127. package/dist/schema/procedure.js +64 -0
  128. package/dist/schema/procedure.js.map +1 -1
  129. package/dist/schema/query.d.ts +55 -0
  130. package/dist/schema/query.d.ts.map +1 -1
  131. package/dist/schema/query.js +55 -0
  132. package/dist/schema/query.js.map +1 -1
  133. package/dist/schema/record.d.ts +63 -8
  134. package/dist/schema/record.d.ts.map +1 -1
  135. package/dist/schema/record.js +20 -0
  136. package/dist/schema/record.js.map +1 -1
  137. package/dist/schema/ref.d.ts +50 -0
  138. package/dist/schema/ref.d.ts.map +1 -1
  139. package/dist/schema/ref.js +17 -0
  140. package/dist/schema/ref.js.map +1 -1
  141. package/dist/schema/refine.d.ts +58 -9
  142. package/dist/schema/refine.d.ts.map +1 -1
  143. package/dist/schema/refine.js.map +1 -1
  144. package/dist/schema/regexp.d.ts +44 -0
  145. package/dist/schema/regexp.d.ts.map +1 -1
  146. package/dist/schema/regexp.js +44 -0
  147. package/dist/schema/regexp.js.map +1 -1
  148. package/dist/schema/string.d.ts +50 -0
  149. package/dist/schema/string.d.ts.map +1 -1
  150. package/dist/schema/string.js +41 -0
  151. package/dist/schema/string.js.map +1 -1
  152. package/dist/schema/subscription.d.ts +72 -2
  153. package/dist/schema/subscription.d.ts.map +1 -1
  154. package/dist/schema/subscription.js +59 -0
  155. package/dist/schema/subscription.js.map +1 -1
  156. package/dist/schema/token.d.ts +47 -0
  157. package/dist/schema/token.d.ts.map +1 -1
  158. package/dist/schema/token.js +47 -0
  159. package/dist/schema/token.js.map +1 -1
  160. package/dist/schema/typed-object.d.ts +62 -8
  161. package/dist/schema/typed-object.d.ts.map +1 -1
  162. package/dist/schema/typed-object.js +18 -0
  163. package/dist/schema/typed-object.js.map +1 -1
  164. package/dist/schema/typed-ref.d.ts +53 -0
  165. package/dist/schema/typed-ref.d.ts.map +1 -1
  166. package/dist/schema/typed-ref.js +15 -0
  167. package/dist/schema/typed-ref.js.map +1 -1
  168. package/dist/schema/typed-union.d.ts +50 -1
  169. package/dist/schema/typed-union.d.ts.map +1 -1
  170. package/dist/schema/typed-union.js +50 -1
  171. package/dist/schema/typed-union.js.map +1 -1
  172. package/dist/schema/union.d.ts +45 -0
  173. package/dist/schema/union.d.ts.map +1 -1
  174. package/dist/schema/union.js +40 -0
  175. package/dist/schema/union.js.map +1 -1
  176. package/dist/schema/unknown-object.d.ts +34 -0
  177. package/dist/schema/unknown-object.d.ts.map +1 -1
  178. package/dist/schema/unknown-object.js +31 -0
  179. package/dist/schema/unknown-object.js.map +1 -1
  180. package/dist/schema/unknown.d.ts +33 -0
  181. package/dist/schema/unknown.d.ts.map +1 -1
  182. package/dist/schema/unknown.js +33 -0
  183. package/dist/schema/unknown.js.map +1 -1
  184. package/dist/schema/with-default.d.ts +44 -0
  185. package/dist/schema/with-default.d.ts.map +1 -1
  186. package/dist/schema/with-default.js +44 -0
  187. package/dist/schema/with-default.js.map +1 -1
  188. package/package.json +4 -4
  189. package/src/core/$type.ts +150 -18
  190. package/src/core/record-key.ts +44 -0
  191. package/src/core/result.ts +86 -4
  192. package/src/core/schema.ts +236 -7
  193. package/src/core/string-format.ts +259 -13
  194. package/src/core/types.ts +91 -3
  195. package/src/core/validation-error.ts +60 -0
  196. package/src/core/validation-issue.ts +65 -0
  197. package/src/core/validator.ts +351 -10
  198. package/src/helpers.test.ts +110 -29
  199. package/src/helpers.ts +14 -14
  200. package/src/schema/array.test.ts +94 -79
  201. package/src/schema/array.ts +45 -0
  202. package/src/schema/blob.ts +46 -0
  203. package/src/schema/boolean.ts +28 -0
  204. package/src/schema/bytes.ts +38 -0
  205. package/src/schema/cid.ts +38 -0
  206. package/src/schema/custom.ts +66 -1
  207. package/src/schema/dict.ts +44 -0
  208. package/src/schema/discriminated-union.ts +58 -0
  209. package/src/schema/enum.ts +48 -0
  210. package/src/schema/integer.ts +42 -0
  211. package/src/schema/intersection.ts +54 -0
  212. package/src/schema/literal.ts +44 -0
  213. package/src/schema/never.ts +42 -0
  214. package/src/schema/null.ts +29 -0
  215. package/src/schema/nullable.ts +41 -0
  216. package/src/schema/object.ts +56 -0
  217. package/src/schema/optional.ts +42 -0
  218. package/src/schema/params.test.ts +58 -2
  219. package/src/schema/params.ts +124 -16
  220. package/src/schema/payload.test.ts +3 -3
  221. package/src/schema/payload.ts +142 -38
  222. package/src/schema/permission-set.ts +58 -0
  223. package/src/schema/permission.ts +42 -0
  224. package/src/schema/procedure.ts +64 -0
  225. package/src/schema/query.ts +55 -0
  226. package/src/schema/record.ts +63 -8
  227. package/src/schema/ref.ts +50 -0
  228. package/src/schema/refine.ts +58 -9
  229. package/src/schema/regexp.ts +44 -0
  230. package/src/schema/string.ts +50 -0
  231. package/src/schema/subscription.ts +72 -2
  232. package/src/schema/token.ts +47 -0
  233. package/src/schema/typed-object.ts +62 -8
  234. package/src/schema/typed-ref.ts +53 -0
  235. package/src/schema/typed-union.ts +55 -2
  236. package/src/schema/union.ts +45 -0
  237. package/src/schema/unknown-object.ts +34 -0
  238. package/src/schema/unknown.ts +33 -0
  239. package/src/schema/with-default.ts +44 -0
@@ -4,6 +4,34 @@ exports.ValidationContext = void 0;
4
4
  const result_js_1 = require("./result.js");
5
5
  const validation_error_js_1 = require("./validation-error.js");
6
6
  const validation_issue_js_1 = require("./validation-issue.js");
7
+ /**
8
+ * Manages the state and context for validation operations.
9
+ *
10
+ * The `ValidationContext` class is responsible for:
11
+ * - Tracking the current path in nested structures for error reporting
12
+ * - Collecting validation issues during traversal
13
+ * - Enforcing validation mode (validate vs parse)
14
+ * - Providing factory methods for creating validation results
15
+ *
16
+ * Use the static {@link ValidationContext.validate} method as the primary entry point
17
+ * for validation. This ensures proper mode enforcement and issue aggregation.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Primary usage via static method
22
+ * const result = ValidationContext.validate(data, schema, { mode: 'parse' })
23
+ *
24
+ * // Within a custom validator implementation
25
+ * class MyValidator implements Validator {
26
+ * validateInContext(input: unknown, ctx: ValidationContext): ValidationResult {
27
+ * if (typeof input !== 'string') {
28
+ * return ctx.issueInvalidType(input, 'string')
29
+ * }
30
+ * return ctx.success(input)
31
+ * }
32
+ * }
33
+ * ```
34
+ */
7
35
  class ValidationContext {
8
36
  options;
9
37
  static validate(input, validator, options) {
@@ -13,25 +41,55 @@ class ValidationContext {
13
41
  });
14
42
  return context.validate(input, validator);
15
43
  }
44
+ /**
45
+ * The current path being validated, used for error reporting.
46
+ */
16
47
  currentPath;
48
+ /**
49
+ * Accumulated validation issues collected during traversal.
50
+ */
17
51
  issues = [];
52
+ /**
53
+ * Creates a new validation context with the specified options.
54
+ *
55
+ * @param options - The validation options (path and mode are required)
56
+ */
18
57
  constructor(options) {
19
58
  this.options = options;
20
59
  // Create a copy because we will be mutating the array during validation.
21
60
  this.currentPath = Array.from(options.path);
22
61
  }
62
+ /**
63
+ * Returns a copy of the current validation path.
64
+ *
65
+ * The path represents the location in the data structure being validated,
66
+ * used for constructing meaningful error messages.
67
+ */
23
68
  get path() {
24
69
  return Array.from(this.currentPath);
25
70
  }
71
+ /**
72
+ * Creates a new path by appending segments to the current path.
73
+ *
74
+ * @param path - Optional path segment(s) to append
75
+ * @returns A new path array with the segment(s) appended
76
+ */
26
77
  concatPath(path) {
27
78
  if (path == null)
28
79
  return this.path;
29
80
  return this.currentPath.concat(path);
30
81
  }
31
82
  /**
32
- * This is basically the entry point for validation within a context. Use this
33
- * method instead of using {@link Validator.validateInContext} directly,
34
- * because this method ensures the proper use of {@link ValidationOptions}.
83
+ * Validates input against a validator within this context.
84
+ *
85
+ * This is the primary entry point for validation within a context. Always use
86
+ * this method instead of calling {@link Validator.validateInContext} directly,
87
+ * as this method enforces validation mode rules and handles transformation detection.
88
+ *
89
+ * @typeParam V - The validator type
90
+ * @param input - The value to validate
91
+ * @param validator - The validator to use
92
+ * @returns A validation result with the validated value or error
35
93
  */
36
94
  validate(input, validator) {
37
95
  // This is the only place where validateInContext should be called.
@@ -59,6 +117,28 @@ class ValidationContext {
59
117
  }
60
118
  return result;
61
119
  }
120
+ /**
121
+ * Validates a child property of an object within this context.
122
+ *
123
+ * This method automatically manages the path stack, pushing the property key
124
+ * before validation and popping it afterward. Use this for validating object
125
+ * properties to ensure proper path tracking in error messages.
126
+ *
127
+ * @typeParam I - The input object type
128
+ * @typeParam K - The property key type
129
+ * @typeParam V - The validator type
130
+ * @param input - The parent object containing the property
131
+ * @param key - The property key to validate
132
+ * @param validator - The validator to use for the property value
133
+ * @returns A validation result for the property value
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * // In a custom object validator
138
+ * const result = ctx.validateChild(input, 'name', stringSchema)
139
+ * // If validation fails, error path will include 'name'
140
+ * ```
141
+ */
62
142
  validateChild(input, key, validator) {
63
143
  // Instead of creating a new context, we just push/pop the path segment.
64
144
  this.currentPath.push(key);
@@ -69,41 +149,142 @@ class ValidationContext {
69
149
  this.currentPath.length--;
70
150
  }
71
151
  }
152
+ /**
153
+ * Adds a validation issue to the context without immediately failing.
154
+ *
155
+ * Use this method to collect multiple issues during validation before
156
+ * determining the final result. Issues added this way will be included
157
+ * in the final error if validation fails.
158
+ *
159
+ * @param issue - The validation issue to add
160
+ */
72
161
  addIssue(issue) {
73
162
  this.issues.push(issue);
74
163
  }
164
+ /**
165
+ * Creates a successful validation result with the given value.
166
+ *
167
+ * @typeParam V - The value type
168
+ * @param value - The validated value
169
+ * @returns A successful validation result
170
+ */
75
171
  success(value) {
76
172
  return (0, result_js_1.success)(value);
77
173
  }
174
+ /**
175
+ * Creates a failed validation result with the given error.
176
+ *
177
+ * @param reason - The validation error
178
+ * @returns A failed validation result
179
+ */
78
180
  failure(reason) {
79
181
  return (0, result_js_1.failure)(reason);
80
182
  }
183
+ /**
184
+ * Creates a failed validation result from a single issue.
185
+ *
186
+ * Any previously accumulated issues in the context are included in the error.
187
+ *
188
+ * @param issue - The validation issue that caused the failure
189
+ * @returns A failed validation result
190
+ */
81
191
  issue(issue) {
82
192
  return this.failure(new validation_error_js_1.ValidationError([...this.issues, issue]));
83
193
  }
194
+ /**
195
+ * Creates a failure for an invalid value that doesn't match expected values.
196
+ *
197
+ * @param input - The actual value that was received
198
+ * @param values - The expected valid values
199
+ * @returns A failed validation result with an invalid value issue
200
+ */
84
201
  issueInvalidValue(input, values) {
85
202
  return this.issue(new validation_issue_js_1.IssueInvalidValue(this.path, input, values));
86
203
  }
204
+ /**
205
+ * Creates a failure for an invalid type.
206
+ *
207
+ * @param input - The actual value that was received
208
+ * @param expected - The expected type name
209
+ * @returns A failed validation result with an invalid type issue
210
+ */
87
211
  issueInvalidType(input, expected) {
88
212
  return this.issue(new validation_issue_js_1.IssueInvalidType(this.path, input, [expected]));
89
213
  }
214
+ /**
215
+ * Creates a failure for a missing required key in an object.
216
+ *
217
+ * @param input - The object missing the required key
218
+ * @param key - The name of the required key
219
+ * @returns A failed validation result with a required key issue
220
+ */
90
221
  issueRequiredKey(input, key) {
91
222
  return this.issue(new validation_issue_js_1.IssueRequiredKey(this.path, input, key));
92
223
  }
224
+ /**
225
+ * Creates a failure for an invalid string format.
226
+ *
227
+ * @param input - The actual value that was received
228
+ * @param format - The expected format name (e.g., 'did', 'handle', 'uri')
229
+ * @param msg - Optional additional message describing the format error
230
+ * @returns A failed validation result with an invalid format issue
231
+ */
93
232
  issueInvalidFormat(input, format, msg) {
94
233
  return this.issue(new validation_issue_js_1.IssueInvalidFormat(this.path, input, format, msg));
95
234
  }
235
+ /**
236
+ * Creates a failure for a value that exceeds a maximum constraint.
237
+ *
238
+ * @param input - The actual value that was received
239
+ * @param type - The type of measurement (e.g., 'string', 'array', 'bytes')
240
+ * @param max - The maximum allowed value
241
+ * @param actual - The actual measured value
242
+ * @returns A failed validation result with a too big issue
243
+ */
96
244
  issueTooBig(input, type, max, actual) {
97
245
  return this.issue(new validation_issue_js_1.IssueTooBig(this.path, input, max, type, actual));
98
246
  }
247
+ /**
248
+ * Creates a failure for a value that is below a minimum constraint.
249
+ *
250
+ * @param input - The actual value that was received
251
+ * @param type - The type of measurement (e.g., 'string', 'array', 'bytes')
252
+ * @param min - The minimum required value
253
+ * @param actual - The actual measured value
254
+ * @returns A failed validation result with a too small issue
255
+ */
99
256
  issueTooSmall(input, type, min, actual) {
100
257
  return this.issue(new validation_issue_js_1.IssueTooSmall(this.path, input, min, type, actual));
101
258
  }
259
+ /**
260
+ * Creates a failure for an invalid property value within an object.
261
+ *
262
+ * This is a convenience method that automatically extracts the property value
263
+ * and constructs the appropriate path.
264
+ *
265
+ * @typeParam I - The input object type
266
+ * @param input - The object containing the invalid property
267
+ * @param property - The property key with the invalid value
268
+ * @param values - The expected valid values
269
+ * @returns A failed validation result with an invalid value issue at the property path
270
+ */
102
271
  issueInvalidPropertyValue(input, property, values) {
103
272
  const value = input[property];
104
273
  const path = this.concatPath(property);
105
274
  return this.issue(new validation_issue_js_1.IssueInvalidValue(path, value, values));
106
275
  }
276
+ /**
277
+ * Creates a failure for an invalid property type within an object.
278
+ *
279
+ * This is a convenience method that automatically extracts the property value
280
+ * and constructs the appropriate path.
281
+ *
282
+ * @typeParam I - The input object type
283
+ * @param input - The object containing the invalid property
284
+ * @param property - The property key with the invalid type
285
+ * @param expected - The expected type name
286
+ * @returns A failed validation result with an invalid type issue at the property path
287
+ */
107
288
  issueInvalidPropertyType(input, property, expected) {
108
289
  const value = input[property];
109
290
  const path = this.concatPath(property);
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"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","sourcesContent":["import { PropertyKey } from './property-key.js'\nimport { ResultFailure, ResultSuccess, failure, success } from './result.js'\nimport { ValidationError } from './validation-error.js'\nimport {\n Issue,\n IssueInvalidFormat,\n IssueInvalidType,\n IssueInvalidValue,\n IssueRequiredKey,\n IssueTooBig,\n IssueTooSmall,\n MeasurableType,\n} from './validation-issue.js'\n\nexport type ValidationSuccess<Value = unknown> = ResultSuccess<Value>\nexport type ValidationFailure = ResultFailure<ValidationError>\nexport type ValidationResult<Value = unknown> =\n | ValidationSuccess<Value>\n | ValidationFailure\n\nexport type InferInput<V extends Validator> = V['__lex']['input']\nexport type InferOutput<V extends Validator> = V['__lex']['output']\n\nexport type { InferInput as Infer }\n\nexport interface Validator<TInput = unknown, TOutput = TInput> {\n /**\n * This property is used for type inference purposes and does not actually\n * exist at runtime.\n *\n * @deprecated **INTERNAL API, DO NOT USE**.\n */\n readonly ['__lex']: {\n /** @internal The inferred validation type */\n input: TInput\n /** @internal The inferred parse type */\n output: TOutput\n }\n\n /**\n * @internal **INTERNAL API**: use {@link ValidationContext.validate} instead\n *\n * This method is implemented by subclasses to perform transformation and\n * validation of the input value. Do not call this method directly; as the\n * {@link ValidationContext.options.mode} option will **not** be enforced. See\n * {@link ValidationContext.validate} for details. When delegating validation\n * from one validator sub-class implementation to another schema,\n * {@link ValidationContext.validate} must be used instead of calling\n * {@link Validator.validateInContext}. This will allow to stop the validation\n * process if the value was transformed (by the other schema) but\n * transformations are not allowed.\n *\n * By convention, the {@link ValidationResult} must return the original input\n * value if validation was successful and no transformation was applied (i.e.\n * the input already conformed to the schema). If a default value, or any\n * other transformation was applied, the returned value can be different from\n * the input.\n *\n * This convention allows the {@link Validator.check check} and\n * {@link Validator.assert assert} methods to check whether the input value\n * exactly matches the schema (without defaults or transformations), by\n * checking if the returned value is strictly equal to the input.\n *\n * @see {@link ValidationContext.validate}\n */\n validateInContext(input: unknown, ctx: ValidationContext): ValidationResult\n}\n\nexport type ValidationOptions = {\n /**\n * When set to `\"validate\"` (default), the result of validation must be\n * strictly equal to the input value (i.e. no transformation, such as applying\n * default values, is allowed).\n */\n mode?: 'validate' | 'parse'\n\n /**\n * The path to the value being validated. This is used to provide more\n * context in validation issues.\n */\n path?: readonly PropertyKey[]\n}\n\nexport class ValidationContext {\n static validate<V extends Validator>(\n input: unknown,\n validator: V,\n options: ValidationOptions & {\n mode: 'parse'\n },\n ): ValidationResult<InferOutput<V>>\n static validate<V extends Validator, I = unknown>(\n input: I,\n validator: V,\n options?: ValidationOptions & {\n mode?: 'validate'\n },\n ): ValidationResult<I & InferInput<V>>\n static validate<V extends Validator>(\n input: unknown,\n validator: V,\n options?: ValidationOptions,\n ): ValidationResult<InferOutput<V> | InferInput<V>>\n static validate<V extends Validator>(\n input: unknown,\n validator: V,\n options?: ValidationOptions,\n ): ValidationResult<InferOutput<V> | InferInput<V>> {\n const context = new ValidationContext({\n path: options?.path ?? [],\n mode: options?.mode ?? 'validate',\n })\n return context.validate(input, validator)\n }\n\n protected readonly currentPath: PropertyKey[]\n protected readonly issues: Issue[] = []\n\n constructor(readonly options: Required<ValidationOptions>) {\n // Create a copy because we will be mutating the array during validation.\n this.currentPath = Array.from(options.path)\n }\n\n get path() {\n return Array.from(this.currentPath)\n }\n\n concatPath(path?: PropertyKey | readonly PropertyKey[]) {\n if (path == null) return this.path\n return this.currentPath.concat(path)\n }\n\n /**\n * This is basically the entry point for validation within a context. Use this\n * method instead of using {@link Validator.validateInContext} directly,\n * because this method ensures the proper use of {@link ValidationOptions}.\n */\n validate<V extends Validator>(\n input: unknown,\n validator: V,\n ): ValidationResult<InferInput<V>> {\n // This is the only place where validateInContext should be called.\n const result = validator.validateInContext(input, this)\n\n if (result.success) {\n if (this.issues.length > 0) {\n // Validator returned a success but issues were added via the context.\n // This means the overall validation failed.\n return failure(new ValidationError(Array.from(this.issues)))\n }\n\n if (this.options.mode !== 'parse' && !Object.is(result.value, input)) {\n // If the value changed, it means that a default (or some other\n // transformation) was applied, meaning that the original value did\n // *not* match the (output) schema. When not in \"parse\" mode, we\n // consider this a failure.\n\n // This check is the reason why Validator.validateInContext should not\n // be used directly, and ValidatorContext.validate should be used\n // instead, even when delegating validation from one validator to\n // another.\n\n // This if block comes before the next one because 'this.issues' will\n // end-up being appended to the returned ValidationError (see the\n // \"failure\" method below), resulting in a more complete error report.\n return this.issueInvalidValue(input, [result.value])\n }\n }\n\n return result as ValidationResult<InferInput<V>>\n }\n\n validateChild<\n I extends object,\n K extends PropertyKey & keyof I,\n V extends Validator,\n >(input: I, key: K, validator: V): ValidationResult<InferInput<V>> {\n // Instead of creating a new context, we just push/pop the path segment.\n this.currentPath.push(key)\n try {\n return this.validate(input[key], validator)\n } finally {\n this.currentPath.length--\n }\n }\n\n addIssue(issue: Issue): void {\n this.issues.push(issue)\n }\n\n success<V>(value: V): ValidationResult<V> {\n return success(value)\n }\n\n failure(reason: ValidationError): ValidationFailure {\n return failure(reason)\n }\n\n issue(issue: Issue) {\n return this.failure(new ValidationError([...this.issues, issue]))\n }\n\n issueInvalidValue(input: unknown, values: readonly unknown[]) {\n return this.issue(new IssueInvalidValue(this.path, input, values))\n }\n\n issueInvalidType(input: unknown, expected: string) {\n return this.issue(new IssueInvalidType(this.path, input, [expected]))\n }\n\n issueRequiredKey(input: object, key: PropertyKey) {\n return this.issue(new IssueRequiredKey(this.path, input, key))\n }\n\n issueInvalidFormat(input: unknown, format: string, msg?: string) {\n return this.issue(new IssueInvalidFormat(this.path, input, format, msg))\n }\n\n issueTooBig(\n input: unknown,\n type: MeasurableType,\n max: number,\n actual: number,\n ) {\n return this.issue(new IssueTooBig(this.path, input, max, type, actual))\n }\n\n issueTooSmall(\n input: unknown,\n type: MeasurableType,\n min: number,\n actual: number,\n ) {\n return this.issue(new IssueTooSmall(this.path, input, min, type, actual))\n }\n\n issueInvalidPropertyValue<I>(\n input: I,\n property: keyof I & PropertyKey,\n values: readonly unknown[],\n ) {\n const value = input[property]\n const path = this.concatPath(property)\n return this.issue(new IssueInvalidValue(path, value, values))\n }\n\n issueInvalidPropertyType<I>(\n input: I,\n property: keyof I & PropertyKey,\n expected: string,\n ) {\n const value = input[property]\n const path = this.concatPath(property)\n return this.issue(new IssueInvalidType(path, value, [expected]))\n }\n}\n\nexport type UnwrapValidator<T extends Validator> = T extends {\n unwrap(): infer U extends Validator\n}\n ? UnwrapValidator<U>\n : T\n\nexport interface WrappedValidator<out Validator> {\n unwrap(): Validator\n}\n"]}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"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","sourcesContent":["import { PropertyKey } from './property-key.js'\nimport { ResultFailure, ResultSuccess, failure, success } from './result.js'\nimport { ValidationError } from './validation-error.js'\nimport {\n Issue,\n IssueInvalidFormat,\n IssueInvalidType,\n IssueInvalidValue,\n IssueRequiredKey,\n IssueTooBig,\n IssueTooSmall,\n MeasurableType,\n} from './validation-issue.js'\n\n/**\n * Represents a successful validation result.\n *\n * @typeParam Value - The type of the validated value\n */\nexport type ValidationSuccess<Value = unknown> = ResultSuccess<Value>\n\n/**\n * Represents a failed validation result containing a {@link ValidationError}.\n */\nexport type ValidationFailure = ResultFailure<ValidationError>\n\n/**\n * Discriminated union representing the outcome of a validation operation.\n *\n * Check the `success` property to determine if validation passed or failed:\n * - If `success` is `true`, the `value` property contains the validated data\n * - If `success` is `false`, the `reason` property contains the {@link ValidationError}\n *\n * @typeParam Value - The type of the validated value on success\n *\n * @example\n * ```typescript\n * const result: ValidationResult<string> = schema.safeParse(data)\n * if (result.success) {\n * // result.value is string\n * } else {\n * // result.reason is ValidationError\n * }\n * ```\n */\nexport type ValidationResult<Value = unknown> =\n | ValidationSuccess<Value>\n | ValidationFailure\n\n/**\n * Extracts the input type that a validator accepts.\n *\n * Use this utility type to infer what type a schema will accept during validation.\n *\n * @typeParam V - A validator type\n *\n * @example\n * ```typescript\n * const userSchema = new ObjectSchema({ name: stringSchema, age: numberSchema })\n * type UserInput = InferInput<typeof userSchema>\n * // { name: string; age: number }\n * ```\n */\nexport type InferInput<V extends Validator> = V['__lex']['input']\n\n/**\n * Extracts the output type that a validator produces after parsing.\n *\n * The output type may differ from the input type when the schema applies\n * transformations such as default values or type coercion during parsing.\n *\n * @typeParam V - A validator type\n *\n * @example\n * ```typescript\n * const schema = new StringSchema().default('hello')\n * type Input = InferInput<typeof schema> // string | undefined\n * type Output = InferOutput<typeof schema> // string\n * ```\n */\nexport type InferOutput<V extends Validator> = V['__lex']['output']\n\n/**\n * Alias for {@link InferInput} for convenient type inference.\n *\n * @typeParam V - A validator type\n */\nexport type { InferInput as Infer }\n\nexport interface Validator<TInput = unknown, TOutput = TInput> {\n /**\n * This property is used for type inference purposes and does not actually\n * exist at runtime.\n *\n * @internal\n * @deprecated **INTERNAL API, DO NOT USE**.\n */\n readonly ['__lex']: {\n input: TInput\n output: TOutput\n }\n\n /**\n * @internal **INTERNAL API**: use {@link ValidationContext.validate} instead\n *\n * This method is implemented by subclasses to perform transformation and\n * validation of the input value. Do not call this method directly; as the\n * {@link ValidationContext.options.mode} option will **not** be enforced. See\n * {@link ValidationContext.validate} for details. When delegating validation\n * from one validator sub-class implementation to another schema,\n * {@link ValidationContext.validate} must be used instead of calling\n * {@link Validator.validateInContext}. This will allow to stop the validation\n * process if the value was transformed (by the other schema) but\n * transformations are not allowed.\n *\n * By convention, the {@link ValidationResult} must return the original input\n * value if validation was successful and no transformation was applied (i.e.\n * the input already conformed to the schema). If a default value, or any\n * other transformation was applied, the returned value can be different from\n * the input.\n *\n * This convention allows the {@link Validator.check check} and\n * {@link Validator.assert assert} methods to check whether the input value\n * exactly matches the schema (without defaults or transformations), by\n * checking if the returned value is strictly equal to the input.\n *\n * @see {@link ValidationContext.validate}\n */\n validateInContext(input: unknown, ctx: ValidationContext): ValidationResult\n}\n\n/**\n * Configuration options for validation and parsing operations.\n *\n * @example\n * ```typescript\n * // Validate mode (strict, no transformations)\n * ValidationContext.validate(data, schema, { mode: 'validate' })\n *\n * // Parse mode (allows transformations like defaults)\n * ValidationContext.validate(data, schema, { mode: 'parse' })\n *\n * // With initial path for nested validation\n * ValidationContext.validate(data, schema, { path: ['user', 'profile'] })\n * ```\n */\nexport type ValidationOptions = {\n /**\n * The validation mode determining how transformations are handled.\n *\n * - `\"validate\"` (default): Strict validation where the result must be\n * strictly equal to the input value. No transformations such as applying\n * default values are allowed.\n * - `\"parse\"`: Allows the schema to transform the input value, such as\n * applying default values or performing type coercion.\n */\n mode?: 'validate' | 'parse'\n\n /**\n * The initial path to the value being validated.\n *\n * This is used to provide context in validation issues when validating\n * nested structures. The path is prepended to all issue paths.\n *\n * @example\n * ```typescript\n * // Issues will be reported at paths like \"user.name\" instead of just \"name\"\n * ValidationContext.validate(data, schema, { path: ['user'] })\n * ```\n */\n path?: readonly PropertyKey[]\n}\n\n/**\n * Manages the state and context for validation operations.\n *\n * The `ValidationContext` class is responsible for:\n * - Tracking the current path in nested structures for error reporting\n * - Collecting validation issues during traversal\n * - Enforcing validation mode (validate vs parse)\n * - Providing factory methods for creating validation results\n *\n * Use the static {@link ValidationContext.validate} method as the primary entry point\n * for validation. This ensures proper mode enforcement and issue aggregation.\n *\n * @example\n * ```typescript\n * // Primary usage via static method\n * const result = ValidationContext.validate(data, schema, { mode: 'parse' })\n *\n * // Within a custom validator implementation\n * class MyValidator implements Validator {\n * validateInContext(input: unknown, ctx: ValidationContext): ValidationResult {\n * if (typeof input !== 'string') {\n * return ctx.issueInvalidType(input, 'string')\n * }\n * return ctx.success(input)\n * }\n * }\n * ```\n */\nexport class ValidationContext {\n /**\n * Validates input against a validator in parse mode.\n *\n * In parse mode, the schema may transform the input (e.g., apply defaults).\n *\n * @param input - The value to validate\n * @param validator - The validator to use\n * @param options - Validation options with mode set to 'parse'\n * @returns A validation result with the parsed output type\n */\n static validate<V extends Validator>(\n input: unknown,\n validator: V,\n options: ValidationOptions & {\n mode: 'parse'\n },\n ): ValidationResult<InferOutput<V>>\n /**\n * Validates input against a validator in validate mode (default).\n *\n * In validate mode, the result must be strictly equal to the input.\n * No transformations are allowed.\n *\n * @typeParam V - The validator type\n * @typeParam I - The input type\n * @param input - The value to validate\n * @param validator - The validator to use\n * @param options - Optional validation options (defaults to validate mode)\n * @returns A validation result preserving the input type intersected with the schema type\n */\n static validate<V extends Validator, I = unknown>(\n input: I,\n validator: V,\n options?: ValidationOptions & {\n mode?: 'validate'\n },\n ): ValidationResult<I & InferInput<V>>\n /**\n * Validates input against a validator with configurable options.\n *\n * @param input - The value to validate\n * @param validator - The validator to use\n * @param options - Optional validation options\n * @returns A validation result with either the input or output type\n */\n static validate<V extends Validator>(\n input: unknown,\n validator: V,\n options?: ValidationOptions,\n ): ValidationResult<InferOutput<V> | InferInput<V>>\n static validate<V extends Validator>(\n input: unknown,\n validator: V,\n options?: ValidationOptions,\n ): ValidationResult<InferOutput<V> | InferInput<V>> {\n const context = new ValidationContext({\n path: options?.path ?? [],\n mode: options?.mode ?? 'validate',\n })\n return context.validate(input, validator)\n }\n\n /**\n * The current path being validated, used for error reporting.\n */\n protected readonly currentPath: PropertyKey[]\n\n /**\n * Accumulated validation issues collected during traversal.\n */\n protected readonly issues: Issue[] = []\n\n /**\n * Creates a new validation context with the specified options.\n *\n * @param options - The validation options (path and mode are required)\n */\n constructor(readonly options: Required<ValidationOptions>) {\n // Create a copy because we will be mutating the array during validation.\n this.currentPath = Array.from(options.path)\n }\n\n /**\n * Returns a copy of the current validation path.\n *\n * The path represents the location in the data structure being validated,\n * used for constructing meaningful error messages.\n */\n get path() {\n return Array.from(this.currentPath)\n }\n\n /**\n * Creates a new path by appending segments to the current path.\n *\n * @param path - Optional path segment(s) to append\n * @returns A new path array with the segment(s) appended\n */\n concatPath(path?: PropertyKey | readonly PropertyKey[]) {\n if (path == null) return this.path\n return this.currentPath.concat(path)\n }\n\n /**\n * Validates input against a validator within this context.\n *\n * This is the primary entry point for validation within a context. Always use\n * this method instead of calling {@link Validator.validateInContext} directly,\n * as this method enforces validation mode rules and handles transformation detection.\n *\n * @typeParam V - The validator type\n * @param input - The value to validate\n * @param validator - The validator to use\n * @returns A validation result with the validated value or error\n */\n validate<V extends Validator>(\n input: unknown,\n validator: V,\n ): ValidationResult<InferInput<V>> {\n // This is the only place where validateInContext should be called.\n const result = validator.validateInContext(input, this)\n\n if (result.success) {\n if (this.issues.length > 0) {\n // Validator returned a success but issues were added via the context.\n // This means the overall validation failed.\n return failure(new ValidationError(Array.from(this.issues)))\n }\n\n if (this.options.mode !== 'parse' && !Object.is(result.value, input)) {\n // If the value changed, it means that a default (or some other\n // transformation) was applied, meaning that the original value did\n // *not* match the (output) schema. When not in \"parse\" mode, we\n // consider this a failure.\n\n // This check is the reason why Validator.validateInContext should not\n // be used directly, and ValidatorContext.validate should be used\n // instead, even when delegating validation from one validator to\n // another.\n\n // This if block comes before the next one because 'this.issues' will\n // end-up being appended to the returned ValidationError (see the\n // \"failure\" method below), resulting in a more complete error report.\n return this.issueInvalidValue(input, [result.value])\n }\n }\n\n return result as ValidationResult<InferInput<V>>\n }\n\n /**\n * Validates a child property of an object within this context.\n *\n * This method automatically manages the path stack, pushing the property key\n * before validation and popping it afterward. Use this for validating object\n * properties to ensure proper path tracking in error messages.\n *\n * @typeParam I - The input object type\n * @typeParam K - The property key type\n * @typeParam V - The validator type\n * @param input - The parent object containing the property\n * @param key - The property key to validate\n * @param validator - The validator to use for the property value\n * @returns A validation result for the property value\n *\n * @example\n * ```typescript\n * // In a custom object validator\n * const result = ctx.validateChild(input, 'name', stringSchema)\n * // If validation fails, error path will include 'name'\n * ```\n */\n validateChild<\n I extends object,\n K extends PropertyKey & keyof I,\n V extends Validator,\n >(input: I, key: K, validator: V): ValidationResult<InferInput<V>> {\n // Instead of creating a new context, we just push/pop the path segment.\n this.currentPath.push(key)\n try {\n return this.validate(input[key], validator)\n } finally {\n this.currentPath.length--\n }\n }\n\n /**\n * Adds a validation issue to the context without immediately failing.\n *\n * Use this method to collect multiple issues during validation before\n * determining the final result. Issues added this way will be included\n * in the final error if validation fails.\n *\n * @param issue - The validation issue to add\n */\n addIssue(issue: Issue): void {\n this.issues.push(issue)\n }\n\n /**\n * Creates a successful validation result with the given value.\n *\n * @typeParam V - The value type\n * @param value - The validated value\n * @returns A successful validation result\n */\n success<V>(value: V): ValidationResult<V> {\n return success(value)\n }\n\n /**\n * Creates a failed validation result with the given error.\n *\n * @param reason - The validation error\n * @returns A failed validation result\n */\n failure(reason: ValidationError): ValidationFailure {\n return failure(reason)\n }\n\n /**\n * Creates a failed validation result from a single issue.\n *\n * Any previously accumulated issues in the context are included in the error.\n *\n * @param issue - The validation issue that caused the failure\n * @returns A failed validation result\n */\n issue(issue: Issue) {\n return this.failure(new ValidationError([...this.issues, issue]))\n }\n\n /**\n * Creates a failure for an invalid value that doesn't match expected values.\n *\n * @param input - The actual value that was received\n * @param values - The expected valid values\n * @returns A failed validation result with an invalid value issue\n */\n issueInvalidValue(input: unknown, values: readonly unknown[]) {\n return this.issue(new IssueInvalidValue(this.path, input, values))\n }\n\n /**\n * Creates a failure for an invalid type.\n *\n * @param input - The actual value that was received\n * @param expected - The expected type name\n * @returns A failed validation result with an invalid type issue\n */\n issueInvalidType(input: unknown, expected: string) {\n return this.issue(new IssueInvalidType(this.path, input, [expected]))\n }\n\n /**\n * Creates a failure for a missing required key in an object.\n *\n * @param input - The object missing the required key\n * @param key - The name of the required key\n * @returns A failed validation result with a required key issue\n */\n issueRequiredKey(input: object, key: PropertyKey) {\n return this.issue(new IssueRequiredKey(this.path, input, key))\n }\n\n /**\n * Creates a failure for an invalid string format.\n *\n * @param input - The actual value that was received\n * @param format - The expected format name (e.g., 'did', 'handle', 'uri')\n * @param msg - Optional additional message describing the format error\n * @returns A failed validation result with an invalid format issue\n */\n issueInvalidFormat(input: unknown, format: string, msg?: string) {\n return this.issue(new IssueInvalidFormat(this.path, input, format, msg))\n }\n\n /**\n * Creates a failure for a value that exceeds a maximum constraint.\n *\n * @param input - The actual value that was received\n * @param type - The type of measurement (e.g., 'string', 'array', 'bytes')\n * @param max - The maximum allowed value\n * @param actual - The actual measured value\n * @returns A failed validation result with a too big issue\n */\n issueTooBig(\n input: unknown,\n type: MeasurableType,\n max: number,\n actual: number,\n ) {\n return this.issue(new IssueTooBig(this.path, input, max, type, actual))\n }\n\n /**\n * Creates a failure for a value that is below a minimum constraint.\n *\n * @param input - The actual value that was received\n * @param type - The type of measurement (e.g., 'string', 'array', 'bytes')\n * @param min - The minimum required value\n * @param actual - The actual measured value\n * @returns A failed validation result with a too small issue\n */\n issueTooSmall(\n input: unknown,\n type: MeasurableType,\n min: number,\n actual: number,\n ) {\n return this.issue(new IssueTooSmall(this.path, input, min, type, actual))\n }\n\n /**\n * Creates a failure for an invalid property value within an object.\n *\n * This is a convenience method that automatically extracts the property value\n * and constructs the appropriate path.\n *\n * @typeParam I - The input object type\n * @param input - The object containing the invalid property\n * @param property - The property key with the invalid value\n * @param values - The expected valid values\n * @returns A failed validation result with an invalid value issue at the property path\n */\n issueInvalidPropertyValue<I>(\n input: I,\n property: keyof I & PropertyKey,\n values: readonly unknown[],\n ) {\n const value = input[property]\n const path = this.concatPath(property)\n return this.issue(new IssueInvalidValue(path, value, values))\n }\n\n /**\n * Creates a failure for an invalid property type within an object.\n *\n * This is a convenience method that automatically extracts the property value\n * and constructs the appropriate path.\n *\n * @typeParam I - The input object type\n * @param input - The object containing the invalid property\n * @param property - The property key with the invalid type\n * @param expected - The expected type name\n * @returns A failed validation result with an invalid type issue at the property path\n */\n issueInvalidPropertyType<I>(\n input: I,\n property: keyof I & PropertyKey,\n expected: string,\n ) {\n const value = input[property]\n const path = this.concatPath(property)\n return this.issue(new IssueInvalidType(path, value, [expected]))\n }\n}\n\n/**\n * Recursively unwraps a wrapped validator to its innermost validator type.\n *\n * Some validators wrap other validators (e.g., optional, nullable). This type\n * utility recursively unwraps such wrappers to reveal the core validator.\n *\n * @typeParam T - A validator type, possibly wrapped\n *\n * @example\n * ```typescript\n * type Inner = UnwrapValidator<OptionalValidator<NullableValidator<StringSchema>>>\n * // Result: StringSchema\n * ```\n */\nexport type UnwrapValidator<T extends Validator> = T extends {\n unwrap(): infer U extends Validator\n}\n ? UnwrapValidator<U>\n : T\n\n/**\n * Interface for validators that wrap another validator.\n *\n * Implement this interface when creating validators that wrap or modify\n * the behavior of another validator (e.g., optional, nullable, transform).\n *\n * @typeParam Validator - The type of the wrapped validator\n *\n * @example\n * ```typescript\n * class OptionalSchema<V extends Validator> implements WrappedValidator<V> {\n * constructor(private inner: V) {}\n *\n * unwrap(): V {\n * return this.inner\n * }\n * }\n * ```\n */\nexport interface WrappedValidator<out Validator> {\n /**\n * Returns the inner wrapped validator.\n *\n * @returns The wrapped validator\n */\n unwrap(): Validator\n}\n"]}
package/dist/helpers.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { LexValue } from '@atproto/lex-data';
2
- import { InferOutput, Restricted, Schema } from './core.js';
3
- import { InferPayload, InferPayloadBody, InferPayloadEncoding, Payload, Procedure, Query, Subscription } from './schema.js';
1
+ import { InferOutput, Restricted } from './core.js';
2
+ import { InferPayload, InferPayloadBody, InferPayloadEncoding, Procedure, Query, Subscription } from './schema.js';
4
3
  export type Main<T> = T | {
5
4
  main: T;
6
5
  };
@@ -15,28 +14,17 @@ export declare function getMain<T extends object>(ns: Main<T>): T;
15
14
  */
16
15
  type BinaryData = Restricted<'Binary data'>;
17
16
  export type InferMethodParams<M extends Procedure | Query | Subscription> = InferOutput<M['parameters']>;
18
- export type InferMethodInput<M extends Procedure | Query | Subscription, B = BinaryData> = M extends {
19
- input: Payload;
20
- } ? InferPayload<M['input'], B> : undefined;
21
- export type InferMethodInputBody<M extends Procedure | Query | Subscription, B = BinaryData> = M extends {
22
- input: Payload;
23
- } ? InferPayloadBody<M['input'], B> : undefined;
24
- export type InferMethodInputEncoding<M extends Procedure | Query | Subscription> = M extends {
25
- input: Payload;
26
- } ? InferPayloadEncoding<M['input']> : undefined;
27
- export type InferMethodOutput<M extends Procedure | Query | Subscription, B = BinaryData> = M extends {
28
- output: Payload;
29
- } ? InferPayload<M['output'], B> : undefined;
30
- export type InferMethodOutputBody<M extends Procedure | Query | Subscription, B = BinaryData> = M extends {
31
- output: Payload;
32
- } ? InferPayloadBody<M['output'], B> : undefined;
33
- export type InferMethodOutputEncoding<M extends Procedure | Query | Subscription> = M extends {
34
- output: Payload;
35
- } ? InferPayloadEncoding<M['output']> : undefined;
36
- export type InferMethodMessage<M extends Procedure | Query | Subscription> = M extends {
37
- message: Schema;
38
- } ? LexValue & InferOutput<M['message']> : undefined;
39
- export declare const lexErrorData: import("./schema.js").ObjectSchema<{
17
+ export type InferMethodInput<M extends Procedure | Query | Subscription, B = BinaryData> = M extends Procedure ? InferPayload<M['input'], B> : undefined;
18
+ export type InferMethodInputBody<M extends Procedure | Query | Subscription, B = BinaryData> = M extends Procedure ? InferPayloadBody<M['input'], B> : undefined;
19
+ export type InferMethodInputEncoding<M extends Procedure | Query | Subscription> = M extends Procedure ? InferPayloadEncoding<M['input']> : undefined;
20
+ export type InferMethodOutput<M extends Procedure | Query | Subscription, B = BinaryData> = M extends Procedure | Query ? InferPayload<M['output'], B> : undefined;
21
+ export type InferMethodOutputBody<M extends Procedure | Query | Subscription, B = BinaryData> = M extends Procedure | Query ? InferPayloadBody<M['output'], B> : undefined;
22
+ export type InferMethodOutputEncoding<M extends Procedure | Query | Subscription> = M extends Procedure | Query ? InferPayloadEncoding<M['output']> : undefined;
23
+ export type InferMethodMessage<M extends Subscription> = M extends Subscription ? InferOutput<M['message']> : undefined;
24
+ export type InferMethodError<M extends Procedure | Query | Subscription> = M extends {
25
+ errors: readonly (infer E extends string)[];
26
+ } ? E : never;
27
+ export declare const lexErrorDataSchema: import("./schema.js").ObjectSchema<{
40
28
  readonly error: import("./schema.js").StringSchema<{
41
29
  readonly minLength: 1;
42
30
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,OAAO,EACP,SAAS,EACT,KAAK,EACL,YAAY,EAIb,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAA;AAErC,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAExD;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC,CAAA;AAE3C,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACtE,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;AAE9B,MAAM,MAAM,gBAAgB,CAC1B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAE1E,MAAM,MAAM,oBAAoB,CAC9B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAE9E,MAAM,MAAM,wBAAwB,CAClC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACxC,CAAC,SAAS;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;AAE/E,MAAM,MAAM,iBAAiB,CAC3B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAE5E,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAEhF,MAAM,MAAM,yBAAyB,CACnC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACxC,CAAC,SAAS;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAC7B,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GACjC,SAAS,CAAA;AAEb,MAAM,MAAM,kBAAkB,CAE5B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACxC,CAAC,SAAS;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7B,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GACpC,SAAS,CAAA;AAEb,eAAO,MAAM,YAAY;;;;;EAGQ,CAAA"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,WAAW,CAAA;AAC3D,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,SAAS,EACT,KAAK,EACL,YAAY,EAIb,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAA;AAErC,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAExD;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,GAAG,UAAU,CAAC,aAAa,CAAC,CAAA;AAE3C,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACtE,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;AAE9B,MAAM,MAAM,gBAAgB,CAC1B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS,SAAS,GAAG,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAEjE,MAAM,MAAM,oBAAoB,CAC9B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAErE,MAAM,MAAM,wBAAwB,CAClC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACxC,CAAC,SAAS,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAA;AAEtE,MAAM,MAAM,iBAAiB,CAC3B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAE1E,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,EAC1C,CAAC,GAAG,UAAU,IACZ,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAA;AAE9E,MAAM,MAAM,yBAAyB,CACnC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACxC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAAA;AAE/E,MAAM,MAAM,kBAAkB,CAE5B,CAAC,SAAS,YAAY,IACpB,CAAC,SAAS,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,CAAA;AAElE,MAAM,MAAM,gBAAgB,CAE1B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,YAAY,IACxC,CAAC,SAAS;IAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,MAAM,CAAC,EAAE,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAA;AAEzE,eAAO,MAAM,kBAAkB;;;;;EAGE,CAAA"}
package/dist/helpers.js CHANGED
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lexErrorData = void 0;
3
+ exports.lexErrorDataSchema = void 0;
4
4
  exports.getMain = getMain;
5
5
  const schema_js_1 = require("./schema.js");
6
6
  function getMain(ns) {
7
7
  return 'main' in ns ? ns.main : ns;
8
8
  }
9
- exports.lexErrorData = (0, schema_js_1.object)({
9
+ exports.lexErrorDataSchema = (0, schema_js_1.object)({
10
10
  error: (0, schema_js_1.string)({ minLength: 1 }),
11
11
  message: (0, schema_js_1.optional)((0, schema_js_1.string)()),
12
12
  });
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;AAiBA,0BAEC;AAjBD,2CAWoB;AAIpB,SAAgB,OAAO,CAAmB,EAAW;IACnD,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AACpC,CAAC;AAoDY,QAAA,YAAY,GAAG,IAAA,kBAAM,EAAC;IACjC,KAAK,EAAE,IAAA,kBAAM,EAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC/B,OAAO,EAAE,IAAA,oBAAQ,EAAC,IAAA,kBAAM,GAAE,CAAC;CAC5B,CAAgC,CAAA","sourcesContent":["import { LexErrorData, LexValue } from '@atproto/lex-data'\nimport { InferOutput, Restricted, Schema } from './core.js'\nimport {\n InferPayload,\n InferPayloadBody,\n InferPayloadEncoding,\n Payload,\n Procedure,\n Query,\n Subscription,\n object,\n optional,\n string,\n} from './schema.js'\n\nexport type Main<T> = T | { main: T }\n\nexport function getMain<T extends object>(ns: Main<T>): T {\n return 'main' in ns ? ns.main : ns\n}\n\n/**\n * Every XRPC implementation should translate `application/json` and `text/*`\n * payloads into their native equivalent ({@link LexValue} or string). Binary\n * data payloads, however, can be represented differently depending on the\n * environment and use case (e.g. `Uint8Array`, `Blob`, `Buffer`,\n * `ReadableStream`, etc.). This type is a placeholder to represent binary data\n * when not explicitly provided.\n */\ntype BinaryData = Restricted<'Binary data'>\n\nexport type InferMethodParams<M extends Procedure | Query | Subscription> =\n InferOutput<M['parameters']>\n\nexport type InferMethodInput<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends { input: Payload } ? InferPayload<M['input'], B> : undefined\n\nexport type InferMethodInputBody<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends { input: Payload } ? InferPayloadBody<M['input'], B> : undefined\n\nexport type InferMethodInputEncoding<\n M extends Procedure | Query | Subscription,\n> = M extends { input: Payload } ? InferPayloadEncoding<M['input']> : undefined\n\nexport type InferMethodOutput<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends { output: Payload } ? InferPayload<M['output'], B> : undefined\n\nexport type InferMethodOutputBody<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends { output: Payload } ? InferPayloadBody<M['output'], B> : undefined\n\nexport type InferMethodOutputEncoding<\n M extends Procedure | Query | Subscription,\n> = M extends { output: Payload }\n ? InferPayloadEncoding<M['output']>\n : undefined\n\nexport type InferMethodMessage<\n //\n M extends Procedure | Query | Subscription,\n> = M extends { message: Schema }\n ? LexValue & InferOutput<M['message']>\n : undefined\n\nexport const lexErrorData = object({\n error: string({ minLength: 1 }),\n message: optional(string()),\n}) satisfies Schema<LexErrorData>\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";;;AAgBA,0BAEC;AAhBD,2CAUoB;AAIpB,SAAgB,OAAO,CAAmB,EAAW;IACnD,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AACpC,CAAC;AAqDY,QAAA,kBAAkB,GAAG,IAAA,kBAAM,EAAC;IACvC,KAAK,EAAE,IAAA,kBAAM,EAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC/B,OAAO,EAAE,IAAA,oBAAQ,EAAC,IAAA,kBAAM,GAAE,CAAC;CAC5B,CAAgC,CAAA","sourcesContent":["import { LexErrorData } from '@atproto/lex-data'\nimport { InferOutput, Restricted, Schema } from './core.js'\nimport {\n InferPayload,\n InferPayloadBody,\n InferPayloadEncoding,\n Procedure,\n Query,\n Subscription,\n object,\n optional,\n string,\n} from './schema.js'\n\nexport type Main<T> = T | { main: T }\n\nexport function getMain<T extends object>(ns: Main<T>): T {\n return 'main' in ns ? ns.main : ns\n}\n\n/**\n * Every XRPC implementation should translate `application/json` and `text/*`\n * payloads into their native equivalent ({@link LexValue} or string). Binary\n * data payloads, however, can be represented differently depending on the\n * environment and use case (e.g. `Uint8Array`, `Blob`, `Buffer`,\n * `ReadableStream`, etc.). This type is a placeholder to represent binary data\n * when not explicitly provided.\n */\ntype BinaryData = Restricted<'Binary data'>\n\nexport type InferMethodParams<M extends Procedure | Query | Subscription> =\n InferOutput<M['parameters']>\n\nexport type InferMethodInput<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends Procedure ? InferPayload<M['input'], B> : undefined\n\nexport type InferMethodInputBody<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends Procedure ? InferPayloadBody<M['input'], B> : undefined\n\nexport type InferMethodInputEncoding<\n M extends Procedure | Query | Subscription,\n> = M extends Procedure ? InferPayloadEncoding<M['input']> : undefined\n\nexport type InferMethodOutput<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends Procedure | Query ? InferPayload<M['output'], B> : undefined\n\nexport type InferMethodOutputBody<\n M extends Procedure | Query | Subscription,\n B = BinaryData,\n> = M extends Procedure | Query ? InferPayloadBody<M['output'], B> : undefined\n\nexport type InferMethodOutputEncoding<\n M extends Procedure | Query | Subscription,\n> = M extends Procedure | Query ? InferPayloadEncoding<M['output']> : undefined\n\nexport type InferMethodMessage<\n //\n M extends Subscription,\n> = M extends Subscription ? InferOutput<M['message']> : undefined\n\nexport type InferMethodError<\n //\n M extends Procedure | Query | Subscription,\n> = M extends { errors: readonly (infer E extends string)[] } ? E : never\n\nexport const lexErrorDataSchema = object({\n error: string({ minLength: 1 }),\n message: optional(string()),\n}) satisfies Schema<LexErrorData>\n"]}
@@ -1,14 +1,59 @@
1
1
  import { InferInput, InferOutput, Schema, ValidationContext, Validator } from '../core.js';
2
+ /**
3
+ * Configuration options for array schema validation.
4
+ *
5
+ * @property minLength - Minimum number of items in the array
6
+ * @property maxLength - Maximum number of items in the array
7
+ */
2
8
  export type ArraySchemaOptions = {
3
9
  minLength?: number;
4
10
  maxLength?: number;
5
11
  };
12
+ /**
13
+ * Schema for validating arrays where all items match a given schema.
14
+ *
15
+ * Validates that the input is an array, checks length constraints, and
16
+ * validates each item against the provided item schema.
17
+ *
18
+ * @template TItem - The validator type for array items
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const schema = new ArraySchema(l.string(), { maxLength: 10 })
23
+ * const result = schema.validate(['a', 'b', 'c'])
24
+ * ```
25
+ */
6
26
  export declare class ArraySchema<const TItem extends Validator> extends Schema<Array<InferInput<TItem>>, Array<InferOutput<TItem>>> {
7
27
  readonly validator: TItem;
8
28
  readonly options: ArraySchemaOptions;
9
29
  constructor(validator: TItem, options?: ArraySchemaOptions);
10
30
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<any[]>;
11
31
  }
32
+ /**
33
+ * Creates an array schema that validates each item against the provided schema.
34
+ *
35
+ * @param items - Schema to validate each array item against
36
+ * @param options - Optional length constraints
37
+ * @returns A new {@link ArraySchema} instance
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * // Array of strings
42
+ * const tagsSchema = l.array(l.string())
43
+ *
44
+ * // Array with length constraints
45
+ * const limitedSchema = l.array(l.integer(), { maxLength: 100 })
46
+ *
47
+ * // Array of objects
48
+ * const usersSchema = l.array(l.object({
49
+ * name: l.string(),
50
+ * age: l.integer(),
51
+ * }))
52
+ *
53
+ * // Non-empty array
54
+ * const nonEmptySchema = l.array(l.string(), { minLength: 1 })
55
+ * ```
56
+ */
12
57
  declare function arraySchema<const TValidator extends Validator>(items: TValidator, options?: ArraySchemaOptions): ArraySchema<TValidator>;
13
58
  declare function arraySchema<const TValue, const TValidator extends Validator<TValue> = Validator<TValue>>(items: TValidator, options?: ArraySchemaOptions): ArraySchema<TValidator>;
14
59
  export declare const array: typeof arraySchema;
@@ -1 +1 @@
1
- {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/schema/array.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAGnB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,qBAAa,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,SAAS,CAAE,SAAQ,MAAM,CACpE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EACxB,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAC1B;IAEG,QAAQ,CAAC,SAAS,EAAE,KAAK;IACzB,QAAQ,CAAC,OAAO,EAAE,kBAAkB;gBAD3B,SAAS,EAAE,KAAK,EAChB,OAAO,GAAE,kBAAuB;IAK3C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAmCzD;AAGD,iBAAS,WAAW,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,EACrD,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,WAAW,CAAC,UAAU,CAAC,CAAA;AAC1B,iBAAS,WAAW,CAClB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,SAAS,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,EAC9D,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;AAQ3E,eAAO,MAAM,KAAK,oBAAiD,CAAA"}
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../src/schema/array.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAGnB;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,SAAS,CAAE,SAAQ,MAAM,CACpE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EACxB,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAC1B;IAEG,QAAQ,CAAC,SAAS,EAAE,KAAK;IACzB,QAAQ,CAAC,OAAO,EAAE,kBAAkB;gBAD3B,SAAS,EAAE,KAAK,EAChB,OAAO,GAAE,kBAAuB;IAK3C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAmCzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,iBAAS,WAAW,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,EACrD,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,WAAW,CAAC,UAAU,CAAC,CAAA;AAC1B,iBAAS,WAAW,CAClB,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,SAAS,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,EAC9D,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAAC,UAAU,CAAC,CAAA;AAQ3E,eAAO,MAAM,KAAK,oBAAiD,CAAA"}
@@ -3,6 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.array = exports.ArraySchema = void 0;
4
4
  const core_js_1 = require("../core.js");
5
5
  const memoize_js_1 = require("../util/memoize.js");
6
+ /**
7
+ * Schema for validating arrays where all items match a given schema.
8
+ *
9
+ * Validates that the input is an array, checks length constraints, and
10
+ * validates each item against the provided item schema.
11
+ *
12
+ * @template TItem - The validator type for array items
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const schema = new ArraySchema(l.string(), { maxLength: 10 })
17
+ * const result = schema.validate(['a', 'b', 'c'])
18
+ * ```
19
+ */
6
20
  class ArraySchema extends core_js_1.Schema {
7
21
  validator;
8
22
  options;
@@ -1 +1 @@
1
- {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/schema/array.ts"],"names":[],"mappings":";;;AAAA,wCAMmB;AACnB,mDAAwD;AAOxD,MAAa,WAA2C,SAAQ,gBAG/D;IAEY;IACA;IAFX,YACW,SAAgB,EAChB,UAA8B,EAAE;QAEzC,KAAK,EAAE,CAAA;QAHE,cAAS,GAAT,SAAS,CAAO;QAChB,YAAO,GAAP,OAAO,CAAyB;IAG3C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7C,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE7C,IAAI,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QACnE,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QACjE,CAAC;QAED,IAAI,IAA2B,CAAA;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;YAC1D,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO,MAAM,CAAA;YAElC,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9B,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACpC,sEAAsE;oBACtE,OAAO,GAAG,CAAC,yBAAyB,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;gBAChE,CAAC;gBAED,6DAA6D;gBAC7D,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAA;YACxB,CAAC;QACH,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,CAAA;IACnC,CAAC;CACF;AA9CD,kCA8CC;AAWD,SAAS,WAAW,CAClB,KAAiB,EACjB,OAA4B;IAE5B,OAAO,IAAI,WAAW,CAAa,KAAK,EAAE,OAAO,CAAC,CAAA;AACpD,CAAC;AAEY,QAAA,KAAK,GAAiB,IAAA,gCAAmB,EAAC,WAAW,CAAC,CAAA","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n Validator,\n} from '../core.js'\nimport { memoizedTransformer } from '../util/memoize.js'\n\nexport type ArraySchemaOptions = {\n minLength?: number\n maxLength?: number\n}\n\nexport class ArraySchema<const TItem extends Validator> extends Schema<\n Array<InferInput<TItem>>,\n Array<InferOutput<TItem>>\n> {\n constructor(\n readonly validator: TItem,\n readonly options: ArraySchemaOptions = {},\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!Array.isArray(input)) {\n return ctx.issueInvalidType(input, 'array')\n }\n\n const { minLength, maxLength } = this.options\n\n if (minLength != null && input.length < minLength) {\n return ctx.issueTooSmall(input, 'array', minLength, input.length)\n }\n\n if (maxLength != null && input.length > maxLength) {\n return ctx.issueTooBig(input, 'array', maxLength, input.length)\n }\n\n let copy: undefined | unknown[]\n\n for (let i = 0; i < input.length; i++) {\n const result = ctx.validateChild(input, i, this.validator)\n if (!result.success) return result\n\n if (result.value !== input[i]) {\n if (ctx.options.mode === 'validate') {\n // In \"validate\" mode, we can't modify the input, so we issue an error\n return ctx.issueInvalidPropertyValue(input, i, [result.value])\n }\n\n // Copy on write (but only if we did not already make a copy)\n copy ??= Array.from(input)\n copy[i] = result.value\n }\n }\n\n return ctx.success(copy ?? input)\n }\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nfunction arraySchema<const TValidator extends Validator>(\n items: TValidator,\n options?: ArraySchemaOptions,\n): ArraySchema<TValidator>\nfunction arraySchema<\n const TValue,\n const TValidator extends Validator<TValue> = Validator<TValue>,\n>(items: TValidator, options?: ArraySchemaOptions): ArraySchema<TValidator>\nfunction arraySchema<const TValidator extends Validator>(\n items: TValidator,\n options?: ArraySchemaOptions,\n) {\n return new ArraySchema<TValidator>(items, options)\n}\n\nexport const array = /*#__PURE__*/ memoizedTransformer(arraySchema)\n"]}
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../../src/schema/array.ts"],"names":[],"mappings":";;;AAAA,wCAMmB;AACnB,mDAAwD;AAaxD;;;;;;;;;;;;;GAaG;AACH,MAAa,WAA2C,SAAQ,gBAG/D;IAEY;IACA;IAFX,YACW,SAAgB,EAChB,UAA8B,EAAE;QAEzC,KAAK,EAAE,CAAA;QAHE,cAAS,GAAT,SAAS,CAAO;QAChB,YAAO,GAAP,OAAO,CAAyB;IAG3C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7C,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAA;QAE7C,IAAI,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QACnE,CAAC;QAED,IAAI,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QACjE,CAAC;QAED,IAAI,IAA2B,CAAA;QAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;YAC1D,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO,MAAM,CAAA;YAElC,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9B,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACpC,sEAAsE;oBACtE,OAAO,GAAG,CAAC,yBAAyB,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;gBAChE,CAAC;gBAED,6DAA6D;gBAC7D,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAA;YACxB,CAAC;QACH,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,CAAA;IACnC,CAAC;CACF;AA9CD,kCA8CC;AAoCD,SAAS,WAAW,CAClB,KAAiB,EACjB,OAA4B;IAE5B,OAAO,IAAI,WAAW,CAAa,KAAK,EAAE,OAAO,CAAC,CAAA;AACpD,CAAC;AAEY,QAAA,KAAK,GAAiB,IAAA,gCAAmB,EAAC,WAAW,CAAC,CAAA","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n Validator,\n} from '../core.js'\nimport { memoizedTransformer } from '../util/memoize.js'\n\n/**\n * Configuration options for array schema validation.\n *\n * @property minLength - Minimum number of items in the array\n * @property maxLength - Maximum number of items in the array\n */\nexport type ArraySchemaOptions = {\n minLength?: number\n maxLength?: number\n}\n\n/**\n * Schema for validating arrays where all items match a given schema.\n *\n * Validates that the input is an array, checks length constraints, and\n * validates each item against the provided item schema.\n *\n * @template TItem - The validator type for array items\n *\n * @example\n * ```ts\n * const schema = new ArraySchema(l.string(), { maxLength: 10 })\n * const result = schema.validate(['a', 'b', 'c'])\n * ```\n */\nexport class ArraySchema<const TItem extends Validator> extends Schema<\n Array<InferInput<TItem>>,\n Array<InferOutput<TItem>>\n> {\n constructor(\n readonly validator: TItem,\n readonly options: ArraySchemaOptions = {},\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!Array.isArray(input)) {\n return ctx.issueInvalidType(input, 'array')\n }\n\n const { minLength, maxLength } = this.options\n\n if (minLength != null && input.length < minLength) {\n return ctx.issueTooSmall(input, 'array', minLength, input.length)\n }\n\n if (maxLength != null && input.length > maxLength) {\n return ctx.issueTooBig(input, 'array', maxLength, input.length)\n }\n\n let copy: undefined | unknown[]\n\n for (let i = 0; i < input.length; i++) {\n const result = ctx.validateChild(input, i, this.validator)\n if (!result.success) return result\n\n if (result.value !== input[i]) {\n if (ctx.options.mode === 'validate') {\n // In \"validate\" mode, we can't modify the input, so we issue an error\n return ctx.issueInvalidPropertyValue(input, i, [result.value])\n }\n\n // Copy on write (but only if we did not already make a copy)\n copy ??= Array.from(input)\n copy[i] = result.value\n }\n }\n\n return ctx.success(copy ?? input)\n }\n}\n\n/**\n * Creates an array schema that validates each item against the provided schema.\n *\n * @param items - Schema to validate each array item against\n * @param options - Optional length constraints\n * @returns A new {@link ArraySchema} instance\n *\n * @example\n * ```ts\n * // Array of strings\n * const tagsSchema = l.array(l.string())\n *\n * // Array with length constraints\n * const limitedSchema = l.array(l.integer(), { maxLength: 100 })\n *\n * // Array of objects\n * const usersSchema = l.array(l.object({\n * name: l.string(),\n * age: l.integer(),\n * }))\n *\n * // Non-empty array\n * const nonEmptySchema = l.array(l.string(), { minLength: 1 })\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction arraySchema<const TValidator extends Validator>(\n items: TValidator,\n options?: ArraySchemaOptions,\n): ArraySchema<TValidator>\nfunction arraySchema<\n const TValue,\n const TValidator extends Validator<TValue> = Validator<TValue>,\n>(items: TValidator, options?: ArraySchemaOptions): ArraySchema<TValidator>\nfunction arraySchema<const TValidator extends Validator>(\n items: TValidator,\n options?: ArraySchemaOptions,\n) {\n return new ArraySchema<TValidator>(items, options)\n}\n\nexport const array = /*#__PURE__*/ memoizedTransformer(arraySchema)\n"]}
@@ -1,5 +1,12 @@
1
1
  import { BlobRef, BlobRefCheckOptions, LegacyBlobRef } from '@atproto/lex-data';
2
2
  import { Schema, ValidationContext } from '../core.js';
3
+ /**
4
+ * Configuration options for blob schema validation.
5
+ *
6
+ * @property allowLegacy - Whether to allow legacy blob references format
7
+ * @property accept - List of accepted MIME types (supports wildcards like 'image/*' or '*\/*')
8
+ * @property maxSize - Maximum blob size in bytes
9
+ */
3
10
  export type BlobSchemaOptions = BlobRefCheckOptions & {
4
11
  /**
5
12
  * Whether to allow legacy blob references format
@@ -16,6 +23,21 @@ export type BlobSchemaOptions = BlobRefCheckOptions & {
16
23
  maxSize?: number;
17
24
  };
18
25
  export type { BlobRef, LegacyBlobRef };
26
+ /**
27
+ * Schema for validating blob references in AT Protocol.
28
+ *
29
+ * Validates BlobRef objects which contain a CID reference to binary data,
30
+ * along with metadata like MIME type and size. Can optionally accept
31
+ * legacy blob reference format.
32
+ *
33
+ * @template TOptions - The configuration options type
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const schema = new BlobSchema({ accept: ['image/*'], maxSize: 1000000 })
38
+ * const result = schema.validate(blobRef)
39
+ * ```
40
+ */
19
41
  export declare class BlobSchema<const TOptions extends BlobSchemaOptions = NonNullable<unknown>> extends Schema<TOptions extends {
20
42
  allowLegacy: true;
21
43
  } ? BlobRef | LegacyBlobRef : BlobRef> {
@@ -24,6 +46,30 @@ export declare class BlobSchema<const TOptions extends BlobSchemaOptions = NonNu
24
46
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<BlobRef | LegacyBlobRef>;
25
47
  matchesMime(mime: string): boolean;
26
48
  }
49
+ /**
50
+ * Creates a blob schema for validating blob references with optional constraints.
51
+ *
52
+ * Blob references are used in AT Protocol to reference binary data stored
53
+ * separately from records. They contain a CID, MIME type, and size information.
54
+ *
55
+ * @param options - Optional configuration for MIME type filtering and size limits
56
+ * @returns A new {@link BlobSchema} instance
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * // Basic blob reference
61
+ * const fileSchema = l.blob()
62
+ *
63
+ * // Image files only
64
+ * const imageSchema = l.blob({ accept: ['image/png', 'image/jpeg', 'image/gif'] })
65
+ *
66
+ * // Any image type with size limit
67
+ * const avatarSchema = l.blob({ accept: ['image/*'], maxSize: 1000000 })
68
+ *
69
+ * // Allow legacy format
70
+ * const legacySchema = l.blob({ allowLegacy: true })
71
+ * ```
72
+ */
27
73
  export declare const blob: <O extends BlobSchemaOptions = {
28
74
  allowLegacy?: false;
29
75
  }>(options?: O) => BlobSchema<O>;