@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
@@ -7,11 +7,31 @@ import {
7
7
  } from '../core.js'
8
8
  import { memoizedTransformer } from '../util/memoize.js'
9
9
 
10
+ /**
11
+ * Configuration options for array schema validation.
12
+ *
13
+ * @property minLength - Minimum number of items in the array
14
+ * @property maxLength - Maximum number of items in the array
15
+ */
10
16
  export type ArraySchemaOptions = {
11
17
  minLength?: number
12
18
  maxLength?: number
13
19
  }
14
20
 
21
+ /**
22
+ * Schema for validating arrays where all items match a given schema.
23
+ *
24
+ * Validates that the input is an array, checks length constraints, and
25
+ * validates each item against the provided item schema.
26
+ *
27
+ * @template TItem - The validator type for array items
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const schema = new ArraySchema(l.string(), { maxLength: 10 })
32
+ * const result = schema.validate(['a', 'b', 'c'])
33
+ * ```
34
+ */
15
35
  export class ArraySchema<const TItem extends Validator> extends Schema<
16
36
  Array<InferInput<TItem>>,
17
37
  Array<InferOutput<TItem>>
@@ -60,6 +80,31 @@ export class ArraySchema<const TItem extends Validator> extends Schema<
60
80
  }
61
81
  }
62
82
 
83
+ /**
84
+ * Creates an array schema that validates each item against the provided schema.
85
+ *
86
+ * @param items - Schema to validate each array item against
87
+ * @param options - Optional length constraints
88
+ * @returns A new {@link ArraySchema} instance
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * // Array of strings
93
+ * const tagsSchema = l.array(l.string())
94
+ *
95
+ * // Array with length constraints
96
+ * const limitedSchema = l.array(l.integer(), { maxLength: 100 })
97
+ *
98
+ * // Array of objects
99
+ * const usersSchema = l.array(l.object({
100
+ * name: l.string(),
101
+ * age: l.integer(),
102
+ * }))
103
+ *
104
+ * // Non-empty array
105
+ * const nonEmptySchema = l.array(l.string(), { minLength: 1 })
106
+ * ```
107
+ */
63
108
  /*@__NO_SIDE_EFFECTS__*/
64
109
  function arraySchema<const TValidator extends Validator>(
65
110
  items: TValidator,
@@ -8,6 +8,13 @@ import {
8
8
  import { Schema, ValidationContext } from '../core.js'
9
9
  import { memoizedOptions } from '../util/memoize.js'
10
10
 
11
+ /**
12
+ * Configuration options for blob schema validation.
13
+ *
14
+ * @property allowLegacy - Whether to allow legacy blob references format
15
+ * @property accept - List of accepted MIME types (supports wildcards like 'image/*' or '*\/*')
16
+ * @property maxSize - Maximum blob size in bytes
17
+ */
11
18
  export type BlobSchemaOptions = BlobRefCheckOptions & {
12
19
  /**
13
20
  * Whether to allow legacy blob references format
@@ -26,6 +33,21 @@ export type BlobSchemaOptions = BlobRefCheckOptions & {
26
33
 
27
34
  export type { BlobRef, LegacyBlobRef }
28
35
 
36
+ /**
37
+ * Schema for validating blob references in AT Protocol.
38
+ *
39
+ * Validates BlobRef objects which contain a CID reference to binary data,
40
+ * along with metadata like MIME type and size. Can optionally accept
41
+ * legacy blob reference format.
42
+ *
43
+ * @template TOptions - The configuration options type
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * const schema = new BlobSchema({ accept: ['image/*'], maxSize: 1000000 })
48
+ * const result = schema.validate(blobRef)
49
+ * ```
50
+ */
29
51
  export class BlobSchema<
30
52
  const TOptions extends BlobSchemaOptions = NonNullable<unknown>,
31
53
  > extends Schema<
@@ -80,6 +102,30 @@ function matchesMime(mime: string, accepted: string[]): boolean {
80
102
  return false
81
103
  }
82
104
 
105
+ /**
106
+ * Creates a blob schema for validating blob references with optional constraints.
107
+ *
108
+ * Blob references are used in AT Protocol to reference binary data stored
109
+ * separately from records. They contain a CID, MIME type, and size information.
110
+ *
111
+ * @param options - Optional configuration for MIME type filtering and size limits
112
+ * @returns A new {@link BlobSchema} instance
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * // Basic blob reference
117
+ * const fileSchema = l.blob()
118
+ *
119
+ * // Image files only
120
+ * const imageSchema = l.blob({ accept: ['image/png', 'image/jpeg', 'image/gif'] })
121
+ *
122
+ * // Any image type with size limit
123
+ * const avatarSchema = l.blob({ accept: ['image/*'], maxSize: 1000000 })
124
+ *
125
+ * // Allow legacy format
126
+ * const legacySchema = l.blob({ allowLegacy: true })
127
+ * ```
128
+ */
83
129
  export const blob = /*#__PURE__*/ memoizedOptions(function <
84
130
  O extends BlobSchemaOptions = { allowLegacy?: false },
85
131
  >(options?: O) {
@@ -1,6 +1,20 @@
1
1
  import { Schema, ValidationContext } from '../core.js'
2
2
  import { memoizedOptions } from '../util/memoize.js'
3
3
 
4
+ /**
5
+ * Schema for validating boolean values.
6
+ *
7
+ * Only accepts JavaScript `true` or `false` values. Does not perform
8
+ * any coercion from strings or numbers.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const schema = new BooleanSchema()
13
+ * schema.validate(true) // success
14
+ * schema.validate(false) // success
15
+ * schema.validate('true') // fails - no string coercion
16
+ * ```
17
+ */
4
18
  export class BooleanSchema extends Schema<boolean> {
5
19
  validateInContext(input: unknown, ctx: ValidationContext) {
6
20
  if (typeof input === 'boolean') {
@@ -11,6 +25,20 @@ export class BooleanSchema extends Schema<boolean> {
11
25
  }
12
26
  }
13
27
 
28
+ /**
29
+ * Creates a boolean schema that validates true/false values.
30
+ *
31
+ * @returns A new {@link BooleanSchema} instance
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const enabledSchema = l.boolean()
36
+ *
37
+ * enabledSchema.parse(true) // true
38
+ * enabledSchema.parse(false) // false
39
+ * enabledSchema.parse('true') // throws - strings not accepted
40
+ * ```
41
+ */
14
42
  export const boolean = /*#__PURE__*/ memoizedOptions(function () {
15
43
  return new BooleanSchema()
16
44
  })
@@ -2,11 +2,29 @@ import { asUint8Array, ifUint8Array } from '@atproto/lex-data'
2
2
  import { Schema, ValidationContext } from '../core.js'
3
3
  import { memoizedOptions } from '../util/memoize.js'
4
4
 
5
+ /**
6
+ * Configuration options for bytes schema validation.
7
+ *
8
+ * @property minLength - Minimum length in bytes
9
+ * @property maxLength - Maximum length in bytes
10
+ */
5
11
  export type BytesSchemaOptions = {
6
12
  minLength?: number
7
13
  maxLength?: number
8
14
  }
9
15
 
16
+ /**
17
+ * Schema for validating binary data as Uint8Array with optional length constraints.
18
+ *
19
+ * In "parse" mode, coerces various binary formats (Buffer, ArrayBuffer, etc.)
20
+ * into Uint8Array. In "validate" mode, only accepts Uint8Array directly.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const schema = new BytesSchema({ maxLength: 1024 })
25
+ * const result = schema.validate(new Uint8Array([1, 2, 3]))
26
+ * ```
27
+ */
10
28
  export class BytesSchema extends Schema<Uint8Array> {
11
29
  constructor(readonly options: BytesSchemaOptions = {}) {
12
30
  super()
@@ -34,6 +52,26 @@ export class BytesSchema extends Schema<Uint8Array> {
34
52
  }
35
53
  }
36
54
 
55
+ /**
56
+ * Creates a bytes schema for validating binary data with optional length constraints.
57
+ *
58
+ * Validates Uint8Array values and can coerce other binary formats in parse mode.
59
+ *
60
+ * @param options - Optional configuration for minimum and maximum byte length
61
+ * @returns A new {@link BytesSchema} instance
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * // Basic bytes schema
66
+ * const dataSchema = l.bytes()
67
+ *
68
+ * // With size constraints
69
+ * const avatarSchema = l.bytes({ maxLength: 1000000 }) // 1MB max
70
+ *
71
+ * // With minimum size
72
+ * const hashSchema = l.bytes({ minLength: 32, maxLength: 32 }) // Exactly 32 bytes
73
+ * ```
74
+ */
37
75
  export const bytes = /*#__PURE__*/ memoizedOptions(function (
38
76
  options?: BytesSchemaOptions,
39
77
  ) {
package/src/schema/cid.ts CHANGED
@@ -4,8 +4,28 @@ import { memoizedOptions } from '../util/memoize.js'
4
4
 
5
5
  export type { Cid }
6
6
 
7
+ /**
8
+ * Configuration options for CID schema validation.
9
+ *
10
+ * @see CheckCidOptions from @atproto/lex-data for available options
11
+ */
7
12
  export type CidSchemaOptions = CheckCidOptions
8
13
 
14
+ /**
15
+ * Schema for validating Content Identifiers (CIDs).
16
+ *
17
+ * CIDs are self-describing content-addressed identifiers used in AT Protocol
18
+ * to reference data by its cryptographic hash. This schema validates that
19
+ * the input is a valid CID object.
20
+ *
21
+ * @template TOptions - The configuration options type
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * const schema = new CidSchema()
26
+ * const result = schema.validate(someCid)
27
+ * ```
28
+ */
9
29
  export class CidSchema<
10
30
  const TOptions extends CidSchemaOptions = { flavor: undefined },
11
31
  > extends Schema<InferCheckedCid<TOptions>> {
@@ -22,6 +42,24 @@ export class CidSchema<
22
42
  }
23
43
  }
24
44
 
45
+ /**
46
+ * Creates a CID schema for validating Content Identifiers.
47
+ *
48
+ * CIDs are used throughout AT Protocol to reference content by its hash.
49
+ * This is commonly used for referencing blobs, commits, and other data.
50
+ *
51
+ * @param options - Optional configuration for CID validation
52
+ * @returns A new {@link CidSchema} instance
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * // Basic CID validation
57
+ * const cidSchema = l.cid()
58
+ *
59
+ * // Validate a CID from a blob reference
60
+ * const result = cidSchema.validate(blobRef.ref)
61
+ * ```
62
+ */
25
63
  export const cid = /*#__PURE__*/ memoizedOptions(function <
26
64
  O extends CidSchemaOptions = NonNullable<unknown>,
27
65
  >(options?: O) {
@@ -6,18 +6,46 @@ import {
6
6
  ValidationContext,
7
7
  } from '../core.js'
8
8
 
9
+ /**
10
+ * Context object provided to custom assertion functions.
11
+ *
12
+ * @property path - Current validation path as an array of property keys
13
+ * @property addIssue - Function to add additional validation issues
14
+ */
9
15
  export type CustomAssertionContext = {
10
16
  path: PropertyKey[]
11
17
  addIssue(issue: Issue): void
12
18
  }
13
19
 
20
+ /**
21
+ * Type guard function for custom schema validation.
22
+ *
23
+ * @template TValue - The type to validate/narrow to
24
+ */
14
25
  export type CustomAssertion<TValue> = (
15
26
  this: null,
16
27
  input: unknown,
17
28
  ctx: CustomAssertionContext,
18
29
  ) => input is TValue
19
30
 
20
- export class CustomSchema<const TValue = unknown> extends Schema<TValue> {
31
+ /**
32
+ * Schema with a custom validation function.
33
+ *
34
+ * Allows defining completely custom validation logic using a type guard
35
+ * assertion function. The function receives the input and validation context,
36
+ * and must return whether the input is valid.
37
+ *
38
+ * @template TValue - The validated output type
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * const schema = new CustomSchema(
43
+ * (input): input is Date => input instanceof Date,
44
+ * 'Expected a Date instance'
45
+ * )
46
+ * ```
47
+ */
48
+ export class CustomSchema<out TValue = unknown> extends Schema<TValue> {
21
49
  constructor(
22
50
  private readonly assertion: CustomAssertion<TValue>,
23
51
  private readonly message: string,
@@ -35,6 +63,43 @@ export class CustomSchema<const TValue = unknown> extends Schema<TValue> {
35
63
  }
36
64
  }
37
65
 
66
+ /**
67
+ * Creates a custom schema with a user-defined validation function.
68
+ *
69
+ * Use this when the built-in schemas don't cover your validation needs.
70
+ * The assertion function must be a type guard that narrows the input type.
71
+ *
72
+ * @param assertion - Type guard function that validates the input
73
+ * @param message - Error message when validation fails
74
+ * @param path - Optional path to associate with validation errors
75
+ * @returns A new {@link CustomSchema} instance
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * // Validate Date instances
80
+ * const dateSchema = l.custom(
81
+ * (input): input is Date => input instanceof Date && !isNaN(input.getTime()),
82
+ * 'Expected a valid Date'
83
+ * )
84
+ *
85
+ * // Validate specific object shape
86
+ * const pointSchema = l.custom(
87
+ * (input): input is { x: number; y: number } =>
88
+ * typeof input === 'object' &&
89
+ * input !== null &&
90
+ * typeof (input as any).x === 'number' &&
91
+ * typeof (input as any).y === 'number',
92
+ * 'Expected a point with x and y coordinates'
93
+ * )
94
+ *
95
+ * // With custom path
96
+ * const validConfig = l.custom(
97
+ * (input): input is Config => validateConfig(input),
98
+ * 'Invalid configuration',
99
+ * ['config']
100
+ * )
101
+ * ```
102
+ */
38
103
  /*@__NO_SIDE_EFFECTS__*/
39
104
  export function custom<TValue>(
40
105
  assertion: CustomAssertion<TValue>,
@@ -8,9 +8,24 @@ import {
8
8
  } from '../core.js'
9
9
 
10
10
  /**
11
+ * Schema for validating dictionary/map-like objects with dynamic keys.
12
+ *
13
+ * Unlike `ObjectSchema` which validates a fixed set of properties, `DictSchema`
14
+ * validates objects where any string key is allowed, with both keys and values
15
+ * validated against their respective schemas.
16
+ *
11
17
  * @note There is no dictionary in Lexicon schemas. This is a custom extension
12
18
  * to allow map-like objects when using the lex library programmatically (i.e.
13
19
  * not code generated from a lexicon schema).
20
+ *
21
+ * @template TKey - The validator type for dictionary keys (must validate strings)
22
+ * @template TValue - The validator type for dictionary values
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const schema = new DictSchema(l.string(), l.integer())
27
+ * const result = schema.validate({ a: 1, b: 2, c: 3 })
28
+ * ```
14
29
  */
15
30
  export class DictSchema<
16
31
  const TKey extends Validator<string> = any,
@@ -67,6 +82,35 @@ export class DictSchema<
67
82
  }
68
83
  }
69
84
 
85
+ /**
86
+ * Creates a dictionary schema for validating map-like objects.
87
+ *
88
+ * Validates objects where all keys match the key schema and all values
89
+ * match the value schema. Useful for dynamic key-value mappings.
90
+ *
91
+ * @param key - Schema to validate each key (must be a string validator)
92
+ * @param value - Schema to validate each value
93
+ * @returns A new {@link DictSchema} instance
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * // String to number mapping
98
+ * const scoresSchema = l.dict(l.string(), l.integer())
99
+ * scoresSchema.parse({ alice: 100, bob: 85 })
100
+ *
101
+ * // Constrained keys
102
+ * const langSchema = l.dict(
103
+ * l.string({ minLength: 2, maxLength: 5 }), // Language codes
104
+ * l.string() // Translations
105
+ * )
106
+ *
107
+ * // Complex values
108
+ * const usersById = l.dict(
109
+ * l.string({ format: 'did' }),
110
+ * l.object({ name: l.string(), age: l.integer() })
111
+ * )
112
+ * ```
113
+ */
70
114
  /*@__NO_SIDE_EFFECTS__*/
71
115
  export function dict<
72
116
  const TKey extends Validator<string>,
@@ -11,9 +11,22 @@ import { EnumSchema } from './enum.js'
11
11
  import { LiteralSchema } from './literal.js'
12
12
  import { ObjectSchema } from './object.js'
13
13
 
14
+ /**
15
+ * Type representing a single variant in a discriminated union.
16
+ *
17
+ * Must be an ObjectSchema with the discriminator property using either
18
+ * a LiteralSchema or EnumSchema.
19
+ *
20
+ * @template Discriminator - The discriminator property name
21
+ */
14
22
  export type DiscriminatedUnionVariant<Discriminator extends string = string> =
15
23
  ObjectSchema<Record<Discriminator, EnumSchema<any> | LiteralSchema<any>>>
16
24
 
25
+ /**
26
+ * Type representing a non-empty tuple of discriminated union variants.
27
+ *
28
+ * @template TDiscriminator - The discriminator property name
29
+ */
17
30
  export type DiscriminatedUnionVariants<TDiscriminator extends string> =
18
31
  readonly [
19
32
  DiscriminatedUnionVariant<TDiscriminator>,
@@ -37,9 +50,26 @@ type DiscriminatedUnionSchemaOutput<TVariants extends readonly Validator[]> =
37
50
  : never
38
51
 
39
52
  /**
53
+ * Schema for validating discriminated unions of objects.
54
+ *
55
+ * More efficient than regular union schemas when discriminating on a known
56
+ * property. Looks up the correct variant schema directly based on the
57
+ * discriminator value instead of trying each variant in sequence.
58
+ *
40
59
  * @note There is no discriminated union in Lexicon schemas. This is a custom
41
60
  * extension to allow optimized validation of union of objects when using the
42
61
  * lex library programmatically (i.e. not code generated from a lexicon schema).
62
+ *
63
+ * @template TDiscriminator - The discriminator property name
64
+ * @template TVariants - Tuple type of the variant schemas
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const schema = new DiscriminatedUnionSchema('type', [
69
+ * l.object({ type: l.literal('text'), content: l.string() }),
70
+ * l.object({ type: l.literal('image'), url: l.string() }),
71
+ * ])
72
+ * ```
43
73
  */
44
74
  export class DiscriminatedUnionSchema<
45
75
  const TDiscriminator extends string,
@@ -124,6 +154,34 @@ function buildVariantsMap<Discriminator extends string>(
124
154
  return variantsMap
125
155
  }
126
156
 
157
+ /**
158
+ * Creates a discriminated union schema for efficient object type switching.
159
+ *
160
+ * Unlike regular `union()`, this schema uses a discriminator property to
161
+ * directly look up the correct variant, providing O(1) validation instead
162
+ * of trying each variant sequentially.
163
+ *
164
+ * @param discriminator - Property name to discriminate on
165
+ * @param variants - Non-empty array of object schemas with the discriminator property
166
+ * @returns A new {@link DiscriminatedUnionSchema} instance
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * // Message types discriminated by 'kind'
171
+ * const messageSchema = l.discriminatedUnion('kind', [
172
+ * l.object({ kind: l.literal('text'), text: l.string() }),
173
+ * l.object({ kind: l.literal('image'), url: l.string(), alt: l.optional(l.string()) }),
174
+ * l.object({ kind: l.literal('video'), url: l.string(), duration: l.integer() }),
175
+ * ])
176
+ *
177
+ * // Using enums for multiple values mapping to same variant
178
+ * const statusSchema = l.discriminatedUnion('status', [
179
+ * l.object({ status: l.enum(['pending', 'processing']), startedAt: l.string() }),
180
+ * l.object({ status: l.literal('completed'), completedAt: l.string() }),
181
+ * l.object({ status: l.literal('failed'), error: l.string() }),
182
+ * ])
183
+ * ```
184
+ */
127
185
  /*@__NO_SIDE_EFFECTS__*/
128
186
  export function discriminatedUnion<
129
187
  const Discriminator extends string,
@@ -1,5 +1,20 @@
1
1
  import { Schema, ValidationContext } from '../core.js'
2
2
 
3
+ /**
4
+ * Schema that accepts one of several specific literal values.
5
+ *
6
+ * Validates that the input matches one of the allowed values using strict
7
+ * equality. Similar to TypeScript union of literals.
8
+ *
9
+ * @template TValue - The union of literal types
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const schema = new EnumSchema(['pending', 'active', 'completed'])
14
+ * schema.validate('active') // success
15
+ * schema.validate('invalid') // fails
16
+ * ```
17
+ */
3
18
  export class EnumSchema<
4
19
  const TValue extends null | string | number | boolean,
5
20
  > extends Schema<TValue> {
@@ -16,6 +31,39 @@ export class EnumSchema<
16
31
  }
17
32
  }
18
33
 
34
+ /**
35
+ * Creates an enum schema that accepts one of the specified values.
36
+ *
37
+ * Similar to TypeScript's union of string literals. Use `l.enum()` for
38
+ * the namespace-friendly alias.
39
+ *
40
+ * @param value - Array of allowed values
41
+ * @returns A new {@link EnumSchema} instance
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * // String enum
46
+ * const statusSchema = l.enum(['pending', 'active', 'completed', 'failed'])
47
+ *
48
+ * // Number enum
49
+ * const prioritySchema = l.enum([1, 2, 3, 4, 5])
50
+ *
51
+ * // Mixed types
52
+ * const mixedSchema = l.enum(['auto', 0, 1, true])
53
+ *
54
+ * // Use in objects
55
+ * const taskSchema = l.object({
56
+ * title: l.string(),
57
+ * status: l.enum(['todo', 'in-progress', 'done']),
58
+ * })
59
+ *
60
+ * // In discriminated unions
61
+ * const resultSchema = l.discriminatedUnion('status', [
62
+ * l.object({ status: l.enum(['pending', 'processing']), progress: l.integer() }),
63
+ * l.object({ status: l.literal('completed'), result: l.unknown() }),
64
+ * ])
65
+ * ```
66
+ */
19
67
  /*@__NO_SIDE_EFFECTS__*/
20
68
  export function enumSchema<const V extends null | string | number | boolean>(
21
69
  value: readonly V[],
@@ -1,11 +1,29 @@
1
1
  import { Schema, ValidationContext } from '../core.js'
2
2
  import { memoizedOptions } from '../util/memoize.js'
3
3
 
4
+ /**
5
+ * Configuration options for integer schema validation.
6
+ *
7
+ * @property minimum - Minimum allowed value (inclusive)
8
+ * @property maximum - Maximum allowed value (inclusive)
9
+ */
4
10
  export type IntegerSchemaOptions = {
5
11
  minimum?: number
6
12
  maximum?: number
7
13
  }
8
14
 
15
+ /**
16
+ * Schema for validating integer values with optional range constraints.
17
+ *
18
+ * Only accepts safe integers (values that can be exactly represented in JavaScript).
19
+ * Use {@link IntegerSchemaOptions} to constrain the allowed range.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const schema = new IntegerSchema({ minimum: 0, maximum: 100 })
24
+ * const result = schema.validate(42)
25
+ * ```
26
+ */
9
27
  export class IntegerSchema extends Schema<number> {
10
28
  constructor(readonly options?: IntegerSchemaOptions) {
11
29
  super()
@@ -35,6 +53,30 @@ function isInteger(input: unknown): input is number {
35
53
  return Number.isSafeInteger(input)
36
54
  }
37
55
 
56
+ /**
57
+ * Creates an integer schema with optional minimum and maximum constraints.
58
+ *
59
+ * Validates that the input is a safe integer (can be exactly represented in JavaScript)
60
+ * and optionally falls within a specified range.
61
+ *
62
+ * @param options - Optional configuration for minimum and maximum values
63
+ * @returns A new {@link IntegerSchema} instance
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * // Basic integer
68
+ * const countSchema = l.integer()
69
+ *
70
+ * // With minimum value
71
+ * const positiveSchema = l.integer({ minimum: 1 })
72
+ *
73
+ * // With range constraints
74
+ * const percentSchema = l.integer({ minimum: 0, maximum: 100 })
75
+ *
76
+ * // Age validation
77
+ * const ageSchema = l.integer({ minimum: 0, maximum: 150 })
78
+ * ```
79
+ */
38
80
  export const integer = /*#__PURE__*/ memoizedOptions(function (
39
81
  options?: IntegerSchemaOptions,
40
82
  ) {