@atproto/lex-schema 0.0.12 → 0.0.14

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 (210) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/core/schema.d.ts +27 -36
  3. package/dist/core/schema.d.ts.map +1 -1
  4. package/dist/core/schema.js +68 -54
  5. package/dist/core/schema.js.map +1 -1
  6. package/dist/core/string-format.d.ts +1 -14
  7. package/dist/core/string-format.d.ts.map +1 -1
  8. package/dist/core/string-format.js +12 -9
  9. package/dist/core/string-format.js.map +1 -1
  10. package/dist/core/validation-error.d.ts +5 -5
  11. package/dist/core/validation-error.d.ts.map +1 -1
  12. package/dist/core/validation-error.js +8 -8
  13. package/dist/core/validation-error.js.map +1 -1
  14. package/dist/core/validation-issue.js +3 -1
  15. package/dist/core/validation-issue.js.map +1 -1
  16. package/dist/core/validator.d.ts +16 -8
  17. package/dist/core/validator.d.ts.map +1 -1
  18. package/dist/core/validator.js +24 -6
  19. package/dist/core/validator.js.map +1 -1
  20. package/dist/helpers.d.ts +10 -11
  21. package/dist/helpers.d.ts.map +1 -1
  22. package/dist/helpers.js.map +1 -1
  23. package/dist/schema/array.d.ts +1 -0
  24. package/dist/schema/array.d.ts.map +1 -1
  25. package/dist/schema/array.js +2 -1
  26. package/dist/schema/array.js.map +1 -1
  27. package/dist/schema/blob.d.ts +4 -2
  28. package/dist/schema/blob.d.ts.map +1 -1
  29. package/dist/schema/blob.js +5 -2
  30. package/dist/schema/blob.js.map +1 -1
  31. package/dist/schema/boolean.d.ts +1 -0
  32. package/dist/schema/boolean.d.ts.map +1 -1
  33. package/dist/schema/boolean.js +2 -1
  34. package/dist/schema/boolean.js.map +1 -1
  35. package/dist/schema/bytes.d.ts +1 -0
  36. package/dist/schema/bytes.d.ts.map +1 -1
  37. package/dist/schema/bytes.js +2 -1
  38. package/dist/schema/bytes.js.map +1 -1
  39. package/dist/schema/cid.d.ts +1 -0
  40. package/dist/schema/cid.d.ts.map +1 -1
  41. package/dist/schema/cid.js +2 -1
  42. package/dist/schema/cid.js.map +1 -1
  43. package/dist/schema/custom.d.ts +1 -0
  44. package/dist/schema/custom.d.ts.map +1 -1
  45. package/dist/schema/custom.js +1 -0
  46. package/dist/schema/custom.js.map +1 -1
  47. package/dist/schema/dict.d.ts +1 -0
  48. package/dist/schema/dict.d.ts.map +1 -1
  49. package/dist/schema/dict.js +2 -1
  50. package/dist/schema/dict.js.map +1 -1
  51. package/dist/schema/discriminated-union.d.ts +1 -0
  52. package/dist/schema/discriminated-union.d.ts.map +1 -1
  53. package/dist/schema/discriminated-union.js +2 -1
  54. package/dist/schema/discriminated-union.js.map +1 -1
  55. package/dist/schema/enum.d.ts +1 -0
  56. package/dist/schema/enum.d.ts.map +1 -1
  57. package/dist/schema/enum.js +1 -0
  58. package/dist/schema/enum.js.map +1 -1
  59. package/dist/schema/integer.d.ts +1 -0
  60. package/dist/schema/integer.d.ts.map +1 -1
  61. package/dist/schema/integer.js +2 -1
  62. package/dist/schema/integer.js.map +1 -1
  63. package/dist/schema/intersection.d.ts +1 -0
  64. package/dist/schema/intersection.d.ts.map +1 -1
  65. package/dist/schema/intersection.js +1 -0
  66. package/dist/schema/intersection.js.map +1 -1
  67. package/dist/schema/lex-map.d.ts +37 -0
  68. package/dist/schema/lex-map.d.ts.map +1 -0
  69. package/dist/schema/lex-map.js +60 -0
  70. package/dist/schema/lex-map.js.map +1 -0
  71. package/dist/schema/lex-value.d.ts +35 -0
  72. package/dist/schema/lex-value.d.ts.map +1 -0
  73. package/dist/schema/lex-value.js +87 -0
  74. package/dist/schema/lex-value.js.map +1 -0
  75. package/dist/schema/literal.d.ts +1 -0
  76. package/dist/schema/literal.d.ts.map +1 -1
  77. package/dist/schema/literal.js +1 -0
  78. package/dist/schema/literal.js.map +1 -1
  79. package/dist/schema/never.d.ts +1 -0
  80. package/dist/schema/never.d.ts.map +1 -1
  81. package/dist/schema/never.js +2 -1
  82. package/dist/schema/never.js.map +1 -1
  83. package/dist/schema/null.d.ts +1 -0
  84. package/dist/schema/null.d.ts.map +1 -1
  85. package/dist/schema/null.js +2 -1
  86. package/dist/schema/null.js.map +1 -1
  87. package/dist/schema/nullable.d.ts +1 -0
  88. package/dist/schema/nullable.d.ts.map +1 -1
  89. package/dist/schema/nullable.js +1 -0
  90. package/dist/schema/nullable.js.map +1 -1
  91. package/dist/schema/object.d.ts +1 -0
  92. package/dist/schema/object.d.ts.map +1 -1
  93. package/dist/schema/object.js +2 -1
  94. package/dist/schema/object.js.map +1 -1
  95. package/dist/schema/optional.d.ts +1 -0
  96. package/dist/schema/optional.d.ts.map +1 -1
  97. package/dist/schema/optional.js +1 -0
  98. package/dist/schema/optional.js.map +1 -1
  99. package/dist/schema/params.d.ts +14 -10
  100. package/dist/schema/params.d.ts.map +1 -1
  101. package/dist/schema/params.js +87 -24
  102. package/dist/schema/params.js.map +1 -1
  103. package/dist/schema/payload.d.ts.map +1 -1
  104. package/dist/schema/payload.js +3 -3
  105. package/dist/schema/payload.js.map +1 -1
  106. package/dist/schema/record.d.ts +21 -19
  107. package/dist/schema/record.d.ts.map +1 -1
  108. package/dist/schema/record.js +22 -12
  109. package/dist/schema/record.js.map +1 -1
  110. package/dist/schema/ref.d.ts +1 -0
  111. package/dist/schema/ref.d.ts.map +1 -1
  112. package/dist/schema/ref.js +1 -0
  113. package/dist/schema/ref.js.map +1 -1
  114. package/dist/schema/regexp.d.ts +1 -0
  115. package/dist/schema/regexp.d.ts.map +1 -1
  116. package/dist/schema/regexp.js +2 -1
  117. package/dist/schema/regexp.js.map +1 -1
  118. package/dist/schema/string.d.ts +22 -6
  119. package/dist/schema/string.d.ts.map +1 -1
  120. package/dist/schema/string.js +16 -9
  121. package/dist/schema/string.js.map +1 -1
  122. package/dist/schema/token.d.ts +1 -0
  123. package/dist/schema/token.d.ts.map +1 -1
  124. package/dist/schema/token.js +2 -1
  125. package/dist/schema/token.js.map +1 -1
  126. package/dist/schema/typed-object.d.ts +20 -16
  127. package/dist/schema/typed-object.d.ts.map +1 -1
  128. package/dist/schema/typed-object.js +23 -13
  129. package/dist/schema/typed-object.js.map +1 -1
  130. package/dist/schema/typed-ref.d.ts +1 -0
  131. package/dist/schema/typed-ref.d.ts.map +1 -1
  132. package/dist/schema/typed-ref.js +1 -0
  133. package/dist/schema/typed-ref.js.map +1 -1
  134. package/dist/schema/typed-union.d.ts +1 -0
  135. package/dist/schema/typed-union.d.ts.map +1 -1
  136. package/dist/schema/typed-union.js +2 -1
  137. package/dist/schema/typed-union.js.map +1 -1
  138. package/dist/schema/union.d.ts +1 -0
  139. package/dist/schema/union.d.ts.map +1 -1
  140. package/dist/schema/union.js +2 -1
  141. package/dist/schema/union.js.map +1 -1
  142. package/dist/schema/unknown.d.ts +1 -0
  143. package/dist/schema/unknown.d.ts.map +1 -1
  144. package/dist/schema/unknown.js +1 -0
  145. package/dist/schema/unknown.js.map +1 -1
  146. package/dist/schema/with-default.d.ts +1 -0
  147. package/dist/schema/with-default.d.ts.map +1 -1
  148. package/dist/schema/with-default.js +1 -0
  149. package/dist/schema/with-default.js.map +1 -1
  150. package/dist/schema.d.ts +2 -1
  151. package/dist/schema.d.ts.map +1 -1
  152. package/dist/schema.js +2 -1
  153. package/dist/schema.js.map +1 -1
  154. package/dist/util/if-any.d.ts +2 -0
  155. package/dist/util/if-any.d.ts.map +1 -0
  156. package/dist/util/if-any.js +3 -0
  157. package/dist/util/if-any.js.map +1 -0
  158. package/package.json +3 -3
  159. package/src/core/schema.ts +76 -62
  160. package/src/core/string-format.ts +14 -17
  161. package/src/core/validation-error.ts +10 -10
  162. package/src/core/validation-issue.ts +3 -2
  163. package/src/core/validator.ts +32 -12
  164. package/src/helpers.test.ts +1 -1
  165. package/src/helpers.ts +53 -19
  166. package/src/schema/array.ts +3 -1
  167. package/src/schema/blob.ts +4 -1
  168. package/src/schema/boolean.ts +3 -1
  169. package/src/schema/bytes.ts +3 -1
  170. package/src/schema/cid.ts +3 -1
  171. package/src/schema/custom.ts +2 -0
  172. package/src/schema/dict.ts +3 -1
  173. package/src/schema/discriminated-union.ts +3 -1
  174. package/src/schema/enum.ts +2 -0
  175. package/src/schema/integer.ts +3 -1
  176. package/src/schema/intersection.ts +2 -0
  177. package/src/schema/{unknown-object.test.ts → lex-map.test.ts} +9 -9
  178. package/src/schema/lex-map.ts +63 -0
  179. package/src/schema/lex-value.test.ts +81 -0
  180. package/src/schema/lex-value.ts +86 -0
  181. package/src/schema/literal.ts +2 -0
  182. package/src/schema/never.ts +3 -1
  183. package/src/schema/null.ts +3 -1
  184. package/src/schema/nullable.ts +2 -0
  185. package/src/schema/object.ts +3 -1
  186. package/src/schema/optional.ts +2 -0
  187. package/src/schema/params.test.ts +98 -43
  188. package/src/schema/params.ts +136 -39
  189. package/src/schema/payload.test.ts +2 -2
  190. package/src/schema/payload.ts +3 -4
  191. package/src/schema/record.ts +38 -22
  192. package/src/schema/ref.ts +2 -0
  193. package/src/schema/regexp.ts +3 -1
  194. package/src/schema/string.test.ts +99 -2
  195. package/src/schema/string.ts +58 -15
  196. package/src/schema/token.ts +3 -1
  197. package/src/schema/typed-object.test.ts +38 -0
  198. package/src/schema/typed-object.ts +40 -24
  199. package/src/schema/typed-ref.ts +2 -0
  200. package/src/schema/typed-union.ts +3 -1
  201. package/src/schema/union.ts +4 -2
  202. package/src/schema/unknown.ts +2 -0
  203. package/src/schema/with-default.ts +2 -0
  204. package/src/schema.ts +2 -1
  205. package/src/util/if-any.ts +3 -0
  206. package/dist/schema/unknown-object.d.ts +0 -42
  207. package/dist/schema/unknown-object.d.ts.map +0 -1
  208. package/dist/schema/unknown-object.js +0 -50
  209. package/dist/schema/unknown-object.js.map +0 -1
  210. package/src/schema/unknown-object.ts +0 -53
@@ -1 +1 @@
1
- {"version":3,"file":"discriminated-union.js","sourceRoot":"","sources":["../../src/schema/discriminated-union.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPlainObject } from '@atproto/lex-data'\nimport {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n ValidationResult,\n Validator,\n} from '../core.js'\nimport { EnumSchema } from './enum.js'\nimport { LiteralSchema } from './literal.js'\nimport { ObjectSchema } from './object.js'\n\n/**\n * Type representing a single variant in a discriminated union.\n *\n * Must be an ObjectSchema with the discriminator property using either\n * a LiteralSchema or EnumSchema.\n *\n * @template Discriminator - The discriminator property name\n */\nexport type DiscriminatedUnionVariant<Discriminator extends string = string> =\n ObjectSchema<Record<Discriminator, EnumSchema<any> | LiteralSchema<any>>>\n\n/**\n * Type representing a non-empty tuple of discriminated union variants.\n *\n * @template TDiscriminator - The discriminator property name\n */\nexport type DiscriminatedUnionVariants<TDiscriminator extends string> =\n readonly [\n DiscriminatedUnionVariant<TDiscriminator>,\n ...DiscriminatedUnionVariant<TDiscriminator>[],\n ]\n\ntype DiscriminatedUnionSchemaInput<TVariants extends readonly Validator[]> =\n TVariants extends readonly [\n infer TValidator extends Validator,\n ...infer TRest extends readonly Validator[],\n ]\n ? InferInput<TValidator> | DiscriminatedUnionSchemaInput<TRest>\n : never\n\ntype DiscriminatedUnionSchemaOutput<TVariants extends readonly Validator[]> =\n TVariants extends readonly [\n infer TValidator extends Validator,\n ...infer TRest extends readonly Validator[],\n ]\n ? InferOutput<TValidator> | DiscriminatedUnionSchemaOutput<TRest>\n : never\n\n/**\n * Schema for validating discriminated unions of objects.\n *\n * More efficient than regular union schemas when discriminating on a known\n * property. Looks up the correct variant schema directly based on the\n * discriminator value instead of trying each variant in sequence.\n *\n * @note There is no discriminated union in Lexicon schemas. This is a custom\n * extension to allow optimized validation of union of objects when using the\n * lex library programmatically (i.e. not code generated from a lexicon schema).\n *\n * @template TDiscriminator - The discriminator property name\n * @template TVariants - Tuple type of the variant schemas\n *\n * @example\n * ```ts\n * const schema = new DiscriminatedUnionSchema('type', [\n * l.object({ type: l.literal('text'), content: l.string() }),\n * l.object({ type: l.literal('image'), url: l.string() }),\n * ])\n * ```\n */\nexport class DiscriminatedUnionSchema<\n const TDiscriminator extends string,\n const TVariants extends DiscriminatedUnionVariants<TDiscriminator>,\n> extends Schema<\n DiscriminatedUnionSchemaInput<TVariants>,\n DiscriminatedUnionSchemaOutput<TVariants>\n> {\n readonly variantsMap: Map<unknown, DiscriminatedUnionVariant<TDiscriminator>>\n\n constructor(\n readonly discriminator: TDiscriminator,\n readonly variants: TVariants,\n ) {\n super()\n\n // Although we usually try to avoid initialization work in constructors,\n // here it is necessary to ensure that invalid discriminated throw from the\n // place of construction, rather than later during validation.\n this.variantsMap = buildVariantsMap(discriminator, variants)\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!isPlainObject(input)) {\n return ctx.issueInvalidType(input, 'object')\n }\n\n const { discriminator } = this\n\n if (!Object.hasOwn(input, discriminator)) {\n return ctx.issueRequiredKey(input, discriminator)\n }\n\n const discriminatorValue = input[discriminator]\n\n const variant = this.variantsMap.get(discriminatorValue)\n if (variant) {\n return ctx.validate(input, variant) as ValidationResult<\n DiscriminatedUnionSchemaInput<TVariants>\n >\n }\n\n return ctx.issueInvalidPropertyValue(input, discriminator, [\n ...this.variantsMap.keys(),\n ])\n }\n}\n\nfunction buildVariantsMap<Discriminator extends string>(\n discriminator: Discriminator,\n variants: DiscriminatedUnionVariants<Discriminator>,\n) {\n const variantsMap = new Map<\n unknown,\n DiscriminatedUnionVariant<Discriminator>\n >()\n\n for (const variant of variants) {\n const schema = variant.shape[discriminator]\n if (schema instanceof LiteralSchema) {\n if (variantsMap.has(schema.value)) {\n throw new TypeError(`Overlapping discriminator value: ${schema.value}`)\n }\n variantsMap.set(schema.value, variant)\n } else if (schema instanceof EnumSchema) {\n for (const val of schema.values) {\n if (variantsMap.has(val)) {\n throw new TypeError(`Overlapping discriminator value: ${val}`)\n }\n variantsMap.set(val, variant)\n }\n } else {\n // Only enumerable discriminator schemas are supported\n\n // Should never happen if types are used correctly\n throw new TypeError(\n `Discriminator schema must be a LiteralSchema or EnumSchema`,\n )\n }\n }\n\n return variantsMap\n}\n\n/**\n * Creates a discriminated union schema for efficient object type switching.\n *\n * Unlike regular `union()`, this schema uses a discriminator property to\n * directly look up the correct variant, providing O(1) validation instead\n * of trying each variant sequentially.\n *\n * @param discriminator - Property name to discriminate on\n * @param variants - Non-empty array of object schemas with the discriminator property\n * @returns A new {@link DiscriminatedUnionSchema} instance\n *\n * @example\n * ```ts\n * // Message types discriminated by 'kind'\n * const messageSchema = l.discriminatedUnion('kind', [\n * l.object({ kind: l.literal('text'), text: l.string() }),\n * l.object({ kind: l.literal('image'), url: l.string(), alt: l.optional(l.string()) }),\n * l.object({ kind: l.literal('video'), url: l.string(), duration: l.integer() }),\n * ])\n *\n * // Using enums for multiple values mapping to same variant\n * const statusSchema = l.discriminatedUnion('status', [\n * l.object({ status: l.enum(['pending', 'processing']), startedAt: l.string() }),\n * l.object({ status: l.literal('completed'), completedAt: l.string() }),\n * l.object({ status: l.literal('failed'), error: l.string() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function discriminatedUnion<\n const Discriminator extends string,\n const Options extends DiscriminatedUnionVariants<Discriminator>,\n>(discriminator: Discriminator, variants: Options) {\n return new DiscriminatedUnionSchema<Discriminator, Options>(\n discriminator,\n variants,\n )\n}\n"]}
1
+ {"version":3,"file":"discriminated-union.js","sourceRoot":"","sources":["../../src/schema/discriminated-union.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPlainObject } from '@atproto/lex-data'\nimport {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n ValidationResult,\n Validator,\n} from '../core.js'\nimport { EnumSchema } from './enum.js'\nimport { LiteralSchema } from './literal.js'\nimport { ObjectSchema } from './object.js'\n\n/**\n * Type representing a single variant in a discriminated union.\n *\n * Must be an ObjectSchema with the discriminator property using either\n * a LiteralSchema or EnumSchema.\n *\n * @template Discriminator - The discriminator property name\n */\nexport type DiscriminatedUnionVariant<Discriminator extends string = string> =\n ObjectSchema<Record<Discriminator, EnumSchema<any> | LiteralSchema<any>>>\n\n/**\n * Type representing a non-empty tuple of discriminated union variants.\n *\n * @template TDiscriminator - The discriminator property name\n */\nexport type DiscriminatedUnionVariants<TDiscriminator extends string> =\n readonly [\n DiscriminatedUnionVariant<TDiscriminator>,\n ...DiscriminatedUnionVariant<TDiscriminator>[],\n ]\n\ntype DiscriminatedUnionSchemaInput<TVariants extends readonly Validator[]> =\n TVariants extends readonly [\n infer TValidator extends Validator,\n ...infer TRest extends readonly Validator[],\n ]\n ? InferInput<TValidator> | DiscriminatedUnionSchemaInput<TRest>\n : never\n\ntype DiscriminatedUnionSchemaOutput<TVariants extends readonly Validator[]> =\n TVariants extends readonly [\n infer TValidator extends Validator,\n ...infer TRest extends readonly Validator[],\n ]\n ? InferOutput<TValidator> | DiscriminatedUnionSchemaOutput<TRest>\n : never\n\n/**\n * Schema for validating discriminated unions of objects.\n *\n * More efficient than regular union schemas when discriminating on a known\n * property. Looks up the correct variant schema directly based on the\n * discriminator value instead of trying each variant in sequence.\n *\n * @note There is no discriminated union in Lexicon schemas. This is a custom\n * extension to allow optimized validation of union of objects when using the\n * lex library programmatically (i.e. not code generated from a lexicon schema).\n *\n * @template TDiscriminator - The discriminator property name\n * @template TVariants - Tuple type of the variant schemas\n *\n * @example\n * ```ts\n * const schema = new DiscriminatedUnionSchema('type', [\n * l.object({ type: l.literal('text'), content: l.string() }),\n * l.object({ type: l.literal('image'), url: l.string() }),\n * ])\n * ```\n */\nexport class DiscriminatedUnionSchema<\n const TDiscriminator extends string,\n const TVariants extends DiscriminatedUnionVariants<TDiscriminator>,\n> extends Schema<\n DiscriminatedUnionSchemaInput<TVariants>,\n DiscriminatedUnionSchemaOutput<TVariants>\n> {\n readonly type = 'discriminatedUnion' as const\n\n readonly variantsMap: Map<unknown, DiscriminatedUnionVariant<TDiscriminator>>\n\n constructor(\n readonly discriminator: TDiscriminator,\n readonly variants: TVariants,\n ) {\n super()\n\n // Although we usually try to avoid initialization work in constructors,\n // here it is necessary to ensure that invalid discriminated throw from the\n // place of construction, rather than later during validation.\n this.variantsMap = buildVariantsMap(discriminator, variants)\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!isPlainObject(input)) {\n return ctx.issueUnexpectedType(input, 'object')\n }\n\n const { discriminator } = this\n\n if (!Object.hasOwn(input, discriminator)) {\n return ctx.issueRequiredKey(input, discriminator)\n }\n\n const discriminatorValue = input[discriminator]\n\n const variant = this.variantsMap.get(discriminatorValue)\n if (variant) {\n return ctx.validate(input, variant) as ValidationResult<\n DiscriminatedUnionSchemaInput<TVariants>\n >\n }\n\n return ctx.issueInvalidPropertyValue(input, discriminator, [\n ...this.variantsMap.keys(),\n ])\n }\n}\n\nfunction buildVariantsMap<Discriminator extends string>(\n discriminator: Discriminator,\n variants: DiscriminatedUnionVariants<Discriminator>,\n) {\n const variantsMap = new Map<\n unknown,\n DiscriminatedUnionVariant<Discriminator>\n >()\n\n for (const variant of variants) {\n const schema = variant.shape[discriminator]\n if (schema instanceof LiteralSchema) {\n if (variantsMap.has(schema.value)) {\n throw new TypeError(`Overlapping discriminator value: ${schema.value}`)\n }\n variantsMap.set(schema.value, variant)\n } else if (schema instanceof EnumSchema) {\n for (const val of schema.values) {\n if (variantsMap.has(val)) {\n throw new TypeError(`Overlapping discriminator value: ${val}`)\n }\n variantsMap.set(val, variant)\n }\n } else {\n // Only enumerable discriminator schemas are supported\n\n // Should never happen if types are used correctly\n throw new TypeError(\n `Discriminator schema must be a LiteralSchema or EnumSchema`,\n )\n }\n }\n\n return variantsMap\n}\n\n/**\n * Creates a discriminated union schema for efficient object type switching.\n *\n * Unlike regular `union()`, this schema uses a discriminator property to\n * directly look up the correct variant, providing O(1) validation instead\n * of trying each variant sequentially.\n *\n * @param discriminator - Property name to discriminate on\n * @param variants - Non-empty array of object schemas with the discriminator property\n * @returns A new {@link DiscriminatedUnionSchema} instance\n *\n * @example\n * ```ts\n * // Message types discriminated by 'kind'\n * const messageSchema = l.discriminatedUnion('kind', [\n * l.object({ kind: l.literal('text'), text: l.string() }),\n * l.object({ kind: l.literal('image'), url: l.string(), alt: l.optional(l.string()) }),\n * l.object({ kind: l.literal('video'), url: l.string(), duration: l.integer() }),\n * ])\n *\n * // Using enums for multiple values mapping to same variant\n * const statusSchema = l.discriminatedUnion('status', [\n * l.object({ status: l.enum(['pending', 'processing']), startedAt: l.string() }),\n * l.object({ status: l.literal('completed'), completedAt: l.string() }),\n * l.object({ status: l.literal('failed'), error: l.string() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function discriminatedUnion<\n const Discriminator extends string,\n const Options extends DiscriminatedUnionVariants<Discriminator>,\n>(discriminator: Discriminator, variants: Options) {\n return new DiscriminatedUnionSchema<Discriminator, Options>(\n discriminator,\n variants,\n )\n}\n"]}
@@ -16,6 +16,7 @@ import { Schema, ValidationContext } from '../core.js';
16
16
  */
17
17
  export declare class EnumSchema<const TValue extends null | string | number | boolean> extends Schema<TValue> {
18
18
  readonly values: readonly TValue[];
19
+ readonly type: "enum";
19
20
  constructor(values: readonly TValue[]);
20
21
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<TValue>;
21
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"enum.d.ts","sourceRoot":"","sources":["../../src/schema/enum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEtD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAU,CACrB,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CACrD,SAAQ,MAAM,CAAC,MAAM,CAAC;IACV,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;gBAAzB,MAAM,EAAE,SAAS,MAAM,EAAE;IAI9C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EACzE,KAAK,EAAE,SAAS,CAAC,EAAE,iBAGpB;AAGD,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"enum.d.ts","sourceRoot":"","sources":["../../src/schema/enum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEtD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAU,CACrB,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CACrD,SAAQ,MAAM,CAAC,MAAM,CAAC;IAGV,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;IAF9C,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAS;gBAEV,MAAM,EAAE,SAAS,MAAM,EAAE;IAI9C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,wBAAgB,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EACzE,KAAK,EAAE,SAAS,CAAC,EAAE,iBAGpB;AAGD,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,CAAA"}
@@ -21,6 +21,7 @@ const core_js_1 = require("../core.js");
21
21
  */
22
22
  class EnumSchema extends core_js_1.Schema {
23
23
  values;
24
+ type = 'enum';
24
25
  constructor(values) {
25
26
  super();
26
27
  this.values = values;
@@ -1 +1 @@
1
- {"version":3,"file":"enum.js","sourceRoot":"","sources":["../../src/schema/enum.ts"],"names":[],"mappings":";;;AAmEA,gCAIC;AAGsB,0BAAI;AA1E3B,wCAAsD;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAa,UAEX,SAAQ,gBAAc;IACD;IAArB,YAAqB,MAAyB;QAC5C,KAAK,EAAE,CAAA;QADY,WAAM,GAAN,MAAM,CAAmB;IAE9C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAE,IAAI,CAAC,MAA6B,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,GAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,KAAe,CAAC,CAAA;IACrC,CAAC;CACF;AAdD,gCAcC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAwB;AACxB,SAAgB,UAAU,CACxB,KAAmB;IAEnB,OAAO,IAAI,UAAU,CAAI,KAAK,CAAC,CAAA;AACjC,CAAC","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\n\n/**\n * Schema that accepts one of several specific literal values.\n *\n * Validates that the input matches one of the allowed values using strict\n * equality. Similar to TypeScript union of literals.\n *\n * @template TValue - The union of literal types\n *\n * @example\n * ```ts\n * const schema = new EnumSchema(['pending', 'active', 'completed'])\n * schema.validate('active') // success\n * schema.validate('invalid') // fails\n * ```\n */\nexport class EnumSchema<\n const TValue extends null | string | number | boolean,\n> extends Schema<TValue> {\n constructor(readonly values: readonly TValue[]) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!(this.values as readonly unknown[]).includes(input)) {\n return ctx.issueInvalidValue(input, this.values)\n }\n\n return ctx.success(input as TValue)\n }\n}\n\n/**\n * Creates an enum schema that accepts one of the specified values.\n *\n * Similar to TypeScript's union of string literals. Use `l.enum()` for\n * the namespace-friendly alias.\n *\n * @param value - Array of allowed values\n * @returns A new {@link EnumSchema} instance\n *\n * @example\n * ```ts\n * // String enum\n * const statusSchema = l.enum(['pending', 'active', 'completed', 'failed'])\n *\n * // Number enum\n * const prioritySchema = l.enum([1, 2, 3, 4, 5])\n *\n * // Mixed types\n * const mixedSchema = l.enum(['auto', 0, 1, true])\n *\n * // Use in objects\n * const taskSchema = l.object({\n * title: l.string(),\n * status: l.enum(['todo', 'in-progress', 'done']),\n * })\n *\n * // In discriminated unions\n * const resultSchema = l.discriminatedUnion('status', [\n * l.object({ status: l.enum(['pending', 'processing']), progress: l.integer() }),\n * l.object({ status: l.literal('completed'), result: l.unknown() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function enumSchema<const V extends null | string | number | boolean>(\n value: readonly V[],\n) {\n return new EnumSchema<V>(value)\n}\n\n// @NOTE \"enum\" is a reserved keyword in JS/TS\nexport { enumSchema as enum }\n"]}
1
+ {"version":3,"file":"enum.js","sourceRoot":"","sources":["../../src/schema/enum.ts"],"names":[],"mappings":";;;AAqEA,gCAIC;AAGsB,0BAAI;AA5E3B,wCAAsD;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAa,UAEX,SAAQ,gBAAc;IAGD;IAFZ,IAAI,GAAG,MAAe,CAAA;IAE/B,YAAqB,MAAyB;QAC5C,KAAK,EAAE,CAAA;QADY,WAAM,GAAN,MAAM,CAAmB;IAE9C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAE,IAAI,CAAC,MAA6B,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,GAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,KAAe,CAAC,CAAA;IACrC,CAAC;CACF;AAhBD,gCAgBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAwB;AACxB,SAAgB,UAAU,CACxB,KAAmB;IAEnB,OAAO,IAAI,UAAU,CAAI,KAAK,CAAC,CAAA;AACjC,CAAC","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\n\n/**\n * Schema that accepts one of several specific literal values.\n *\n * Validates that the input matches one of the allowed values using strict\n * equality. Similar to TypeScript union of literals.\n *\n * @template TValue - The union of literal types\n *\n * @example\n * ```ts\n * const schema = new EnumSchema(['pending', 'active', 'completed'])\n * schema.validate('active') // success\n * schema.validate('invalid') // fails\n * ```\n */\nexport class EnumSchema<\n const TValue extends null | string | number | boolean,\n> extends Schema<TValue> {\n readonly type = 'enum' as const\n\n constructor(readonly values: readonly TValue[]) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!(this.values as readonly unknown[]).includes(input)) {\n return ctx.issueInvalidValue(input, this.values)\n }\n\n return ctx.success(input as TValue)\n }\n}\n\n/**\n * Creates an enum schema that accepts one of the specified values.\n *\n * Similar to TypeScript's union of string literals. Use `l.enum()` for\n * the namespace-friendly alias.\n *\n * @param value - Array of allowed values\n * @returns A new {@link EnumSchema} instance\n *\n * @example\n * ```ts\n * // String enum\n * const statusSchema = l.enum(['pending', 'active', 'completed', 'failed'])\n *\n * // Number enum\n * const prioritySchema = l.enum([1, 2, 3, 4, 5])\n *\n * // Mixed types\n * const mixedSchema = l.enum(['auto', 0, 1, true])\n *\n * // Use in objects\n * const taskSchema = l.object({\n * title: l.string(),\n * status: l.enum(['todo', 'in-progress', 'done']),\n * })\n *\n * // In discriminated unions\n * const resultSchema = l.discriminatedUnion('status', [\n * l.object({ status: l.enum(['pending', 'processing']), progress: l.integer() }),\n * l.object({ status: l.literal('completed'), result: l.unknown() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function enumSchema<const V extends null | string | number | boolean>(\n value: readonly V[],\n) {\n return new EnumSchema<V>(value)\n}\n\n// @NOTE \"enum\" is a reserved keyword in JS/TS\nexport { enumSchema as enum }\n"]}
@@ -23,6 +23,7 @@ export type IntegerSchemaOptions = {
23
23
  */
24
24
  export declare class IntegerSchema extends Schema<number> {
25
25
  readonly options?: IntegerSchemaOptions | undefined;
26
+ readonly type: "integer";
26
27
  constructor(options?: IntegerSchemaOptions | undefined);
27
28
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<number>;
28
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"integer.d.ts","sourceRoot":"","sources":["../../src/schema/integer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,aAAc,SAAQ,MAAM,CAAC,MAAM,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB;gBAA9B,OAAO,CAAC,EAAE,oBAAoB,YAAA;IAInD,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAezD;AASD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,OAAO,aACR,oBAAoB,kBAG9B,CAAA"}
1
+ {"version":3,"file":"integer.d.ts","sourceRoot":"","sources":["../../src/schema/integer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,aAAc,SAAQ,MAAM,CAAC,MAAM,CAAC;IAGnC,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB;IAFnD,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAS;gBAEb,OAAO,CAAC,EAAE,oBAAoB,YAAA;IAInD,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAezD;AASD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,OAAO,aACR,oBAAoB,kBAG9B,CAAA"}
@@ -17,13 +17,14 @@ const memoize_js_1 = require("../util/memoize.js");
17
17
  */
18
18
  class IntegerSchema extends core_js_1.Schema {
19
19
  options;
20
+ type = 'integer';
20
21
  constructor(options) {
21
22
  super();
22
23
  this.options = options;
23
24
  }
24
25
  validateInContext(input, ctx) {
25
26
  if (!isInteger(input)) {
26
- return ctx.issueInvalidType(input, 'integer');
27
+ return ctx.issueUnexpectedType(input, 'integer');
27
28
  }
28
29
  if (this.options?.minimum != null && input < this.options.minimum) {
29
30
  return ctx.issueTooSmall(input, 'integer', this.options.minimum, input);
@@ -1 +1 @@
1
- {"version":3,"file":"integer.js","sourceRoot":"","sources":["../../src/schema/integer.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAapD;;;;;;;;;;;GAWG;AACH,MAAa,aAAc,SAAQ,gBAAc;IAC1B;IAArB,YAAqB,OAA8B;QACjD,KAAK,EAAE,CAAA;QADY,YAAO,GAAP,OAAO,CAAuB;IAEnD,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC/C,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACzE,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACvE,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AApBD,sCAoBC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACU,QAAA,OAAO,GAAiB,IAAA,4BAAe,EAAC,UACnD,OAA8B;IAE9B,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;AACnC,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Configuration options for integer schema validation.\n *\n * @property minimum - Minimum allowed value (inclusive)\n * @property maximum - Maximum allowed value (inclusive)\n */\nexport type IntegerSchemaOptions = {\n minimum?: number\n maximum?: number\n}\n\n/**\n * Schema for validating integer values with optional range constraints.\n *\n * Only accepts safe integers (values that can be exactly represented in JavaScript).\n * Use {@link IntegerSchemaOptions} to constrain the allowed range.\n *\n * @example\n * ```ts\n * const schema = new IntegerSchema({ minimum: 0, maximum: 100 })\n * const result = schema.validate(42)\n * ```\n */\nexport class IntegerSchema extends Schema<number> {\n constructor(readonly options?: IntegerSchemaOptions) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!isInteger(input)) {\n return ctx.issueInvalidType(input, 'integer')\n }\n\n if (this.options?.minimum != null && input < this.options.minimum) {\n return ctx.issueTooSmall(input, 'integer', this.options.minimum, input)\n }\n\n if (this.options?.maximum != null && input > this.options.maximum) {\n return ctx.issueTooBig(input, 'integer', this.options.maximum, input)\n }\n\n return ctx.success(input)\n }\n}\n\n/**\n * Simple wrapper around {@link Number.isSafeInteger} that acts as a type guard.\n */\nfunction isInteger(input: unknown): input is number {\n return Number.isSafeInteger(input)\n}\n\n/**\n * Creates an integer schema with optional minimum and maximum constraints.\n *\n * Validates that the input is a safe integer (can be exactly represented in JavaScript)\n * and optionally falls within a specified range.\n *\n * @param options - Optional configuration for minimum and maximum values\n * @returns A new {@link IntegerSchema} instance\n *\n * @example\n * ```ts\n * // Basic integer\n * const countSchema = l.integer()\n *\n * // With minimum value\n * const positiveSchema = l.integer({ minimum: 1 })\n *\n * // With range constraints\n * const percentSchema = l.integer({ minimum: 0, maximum: 100 })\n *\n * // Age validation\n * const ageSchema = l.integer({ minimum: 0, maximum: 150 })\n * ```\n */\nexport const integer = /*#__PURE__*/ memoizedOptions(function (\n options?: IntegerSchemaOptions,\n) {\n return new IntegerSchema(options)\n})\n"]}
1
+ {"version":3,"file":"integer.js","sourceRoot":"","sources":["../../src/schema/integer.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAapD;;;;;;;;;;;GAWG;AACH,MAAa,aAAc,SAAQ,gBAAc;IAG1B;IAFZ,IAAI,GAAG,SAAkB,CAAA;IAElC,YAAqB,OAA8B;QACjD,KAAK,EAAE,CAAA;QADY,YAAO,GAAP,OAAO,CAAuB;IAEnD,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,GAAG,CAAC,mBAAmB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAClD,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACzE,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAClE,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACvE,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AAtBD,sCAsBC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;AACpC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACU,QAAA,OAAO,GAAiB,IAAA,4BAAe,EAAC,UACnD,OAA8B;IAE9B,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,CAAA;AACnC,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Configuration options for integer schema validation.\n *\n * @property minimum - Minimum allowed value (inclusive)\n * @property maximum - Maximum allowed value (inclusive)\n */\nexport type IntegerSchemaOptions = {\n minimum?: number\n maximum?: number\n}\n\n/**\n * Schema for validating integer values with optional range constraints.\n *\n * Only accepts safe integers (values that can be exactly represented in JavaScript).\n * Use {@link IntegerSchemaOptions} to constrain the allowed range.\n *\n * @example\n * ```ts\n * const schema = new IntegerSchema({ minimum: 0, maximum: 100 })\n * const result = schema.validate(42)\n * ```\n */\nexport class IntegerSchema extends Schema<number> {\n readonly type = 'integer' as const\n\n constructor(readonly options?: IntegerSchemaOptions) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!isInteger(input)) {\n return ctx.issueUnexpectedType(input, 'integer')\n }\n\n if (this.options?.minimum != null && input < this.options.minimum) {\n return ctx.issueTooSmall(input, 'integer', this.options.minimum, input)\n }\n\n if (this.options?.maximum != null && input > this.options.maximum) {\n return ctx.issueTooBig(input, 'integer', this.options.maximum, input)\n }\n\n return ctx.success(input)\n }\n}\n\n/**\n * Simple wrapper around {@link Number.isSafeInteger} that acts as a type guard.\n */\nfunction isInteger(input: unknown): input is number {\n return Number.isSafeInteger(input)\n}\n\n/**\n * Creates an integer schema with optional minimum and maximum constraints.\n *\n * Validates that the input is a safe integer (can be exactly represented in JavaScript)\n * and optionally falls within a specified range.\n *\n * @param options - Optional configuration for minimum and maximum values\n * @returns A new {@link IntegerSchema} instance\n *\n * @example\n * ```ts\n * // Basic integer\n * const countSchema = l.integer()\n *\n * // With minimum value\n * const positiveSchema = l.integer({ minimum: 1 })\n *\n * // With range constraints\n * const percentSchema = l.integer({ minimum: 0, maximum: 100 })\n *\n * // Age validation\n * const ageSchema = l.integer({ minimum: 0, maximum: 150 })\n * ```\n */\nexport const integer = /*#__PURE__*/ memoizedOptions(function (\n options?: IntegerSchemaOptions,\n) {\n return new IntegerSchema(options)\n})\n"]}
@@ -41,6 +41,7 @@ A & {
41
41
  export declare class IntersectionSchema<const Left extends ObjectSchema = any, const Right extends DictSchema = any> extends Schema<Simplify<Intersect<InferInput<Left>, InferInput<Right>>>, Simplify<Intersect<InferOutput<Left>, InferOutput<Right>>>> {
42
42
  protected readonly left: Left;
43
43
  protected readonly right: Right;
44
+ readonly type: "intersection";
44
45
  constructor(left: Left, right: Right);
45
46
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<Record<string, unknown>>;
46
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"intersection.d.ts","sourceRoot":"","sources":["../../src/schema/intersection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,QAAQ,EACR,iBAAiB,EAClB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GAClD,CAAC,GACD,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,KAAK,GAE7B,AADA,8CAA8C;AAC9C,CAAC,GAAG,CAAC,GAGL,AAFA,iEAAiE;AAEjE,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;CAAE,CAAA;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAkB,CAC7B,KAAK,CAAC,IAAI,SAAS,YAAY,GAAG,GAAG,EACrC,KAAK,CAAC,KAAK,SAAS,UAAU,GAAG,GAAG,CACpC,SAAQ,MAAM,CACd,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EACxD,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAC3D;IAEG,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI;IAC7B,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK;gBADZ,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK;IAKjC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAQzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,YAAY,EAC/B,KAAK,CAAC,KAAK,SAAS,UAAU,EAC9B,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,mCAEzB"}
1
+ {"version":3,"file":"intersection.d.ts","sourceRoot":"","sources":["../../src/schema/intersection.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,QAAQ,EACR,iBAAiB,EAClB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GAClD,CAAC,GACD,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,KAAK,GAE7B,AADA,8CAA8C;AAC9C,CAAC,GAAG,CAAC,GAGL,AAFA,iEAAiE;AAEjE,CAAC,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;CAAE,CAAA;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAkB,CAC7B,KAAK,CAAC,IAAI,SAAS,YAAY,GAAG,GAAG,EACrC,KAAK,CAAC,KAAK,SAAS,UAAU,GAAG,GAAG,CACpC,SAAQ,MAAM,CACd,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EACxD,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAC3D;IAIG,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI;IAC7B,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK;IAJjC,QAAQ,CAAC,IAAI,EAAG,cAAc,CAAS;gBAGlB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK;IAKjC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAQzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,YAAY,EAC/B,KAAK,CAAC,KAAK,SAAS,UAAU,EAC9B,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,mCAEzB"}
@@ -26,6 +26,7 @@ const core_js_1 = require("../core.js");
26
26
  class IntersectionSchema extends core_js_1.Schema {
27
27
  left;
28
28
  right;
29
+ type = 'intersection';
29
30
  constructor(left, right) {
30
31
  super();
31
32
  this.left = left;
@@ -1 +1 @@
1
- {"version":3,"file":"intersection.js","sourceRoot":"","sources":["../../src/schema/intersection.ts"],"names":[],"mappings":";;;AAyGA,oCAKC;AA9GD,wCAMmB;AAyBnB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAa,kBAGX,SAAQ,gBAGT;IAEsB;IACA;IAFrB,YACqB,IAAU,EACV,KAAY;QAE/B,KAAK,EAAE,CAAA;QAHY,SAAI,GAAJ,IAAI,CAAM;QACV,UAAK,GAAL,KAAK,CAAO;IAGjC,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QACjD,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAO,UAAU,CAAA;QAE1C,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE;YACzD,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa;SACrC,CAAC,CAAA;IACJ,CAAC;CACF;AAtBD,gDAsBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAwB;AACxB,SAAgB,YAAY,CAG1B,IAAU,EAAE,KAAY;IACxB,OAAO,IAAI,kBAAkB,CAAc,IAAI,EAAE,KAAK,CAAC,CAAA;AACzD,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n Simplify,\n ValidationContext,\n} from '../core.js'\nimport { DictSchema } from './dict.js'\nimport { ObjectSchema } from './object.js'\n\n/**\n * Type utility for computing the intersection of two object types.\n *\n * Allows to more accurately represent the intersection of two object types\n * where both types may share some keys, and one of them uses an index\n * signature.\n *\n * @template A - First object type (typically from ObjectSchema)\n * @template B - Second object type (typically from DictSchema)\n *\n * @see {@link https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8UDeUBmB7dAuKByARgIYBOuUAvlAGTJQDaA+lAJYB2UAzsMWwOYC6OVgFcAtvgjEKAKGkATCAGMANiWiL0rLlEI4YsjVuBQA1hBA4uPVrwRQARBnT2Dm7QDdCy4dESE6ZiD8UAD0IVAi4pJQABQcABbowspyUBIORMT2AJSyEAAeYOjExqCQUACSrMCSHErAzJoAPNJQsFAFNaxyHFAASkrFck1WfAA0UMKsJqzoAO6sAHxjrVAAQh35XT39g8TDozYTUzPzSyuLdqtwVKttMYHoqO00j88bnRDdvawQ7pJ3NpQAD860BbRwSHBQLadAA0ix2G91oJ1vDggAfWABcxPF5QOH8aFtci5aRlaAwVDMfIQVKIKo1Yh1RQNZq0Jw4AgkMjkCYoRiIzjcPioyISKTkRayBQqNRQQzaQgAMRpdL01NpclcRignm8EFVWrsKrVchxQVC4XF0SxmSAA Playground link}\n */\nexport type Intersect<A, B> = B[keyof B] extends never\n ? A\n : keyof A & keyof B extends never\n ? // If A and B don't overlap, just return A & B\n A & B\n : // Otherwise, properly represent the fact that accessing using an\n // index signature could return a value from either A or B\n A & { [K in keyof B]: B[K] | A[keyof A & K] }\n\n/**\n * Schema for combining an object schema with a dictionary schema.\n *\n * Validates that the input matches both the fixed object shape and allows\n * additional properties that match the dictionary schema. Properties defined\n * in the object schema are validated by the object, and remaining properties\n * are validated by the dictionary.\n *\n * @template Left - The ObjectSchema type for fixed properties\n * @template Right - The DictSchema type for additional properties\n *\n * @example\n * ```ts\n * const schema = new IntersectionSchema(\n * l.object({ name: l.string() }),\n * l.dict(l.string(), l.integer())\n * )\n * // Validates: { name: 'test', score: 100, count: 5 }\n * ```\n */\nexport class IntersectionSchema<\n const Left extends ObjectSchema = any,\n const Right extends DictSchema = any,\n> extends Schema<\n Simplify<Intersect<InferInput<Left>, InferInput<Right>>>,\n Simplify<Intersect<InferOutput<Left>, InferOutput<Right>>>\n> {\n constructor(\n protected readonly left: Left,\n protected readonly right: Right,\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n const leftResult = ctx.validate(input, this.left)\n if (!leftResult.success) return leftResult\n\n return this.right.validateInContext(leftResult.value, ctx, {\n ignoredKeys: this.left.validatorsMap,\n })\n }\n}\n\n/**\n * Creates an intersection schema combining fixed object properties with dynamic dictionary properties.\n *\n * Useful for objects that have a known set of properties plus additional\n * arbitrary properties that follow a pattern.\n *\n * @param left - Object schema defining the fixed, known properties\n * @param right - Dictionary schema for validating additional properties\n * @returns A new {@link IntersectionSchema} instance\n *\n * @example\n * ```ts\n * // Object with fixed and dynamic properties\n * const configSchema = l.intersection(\n * l.object({\n * version: l.integer(),\n * name: l.string(),\n * }),\n * l.dict(l.string(), l.string()) // Additional string properties\n * )\n *\n * configSchema.parse({\n * version: 1,\n * name: 'my-config',\n * customField: 'value',\n * anotherField: 'another',\n * })\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function intersection<\n const Left extends ObjectSchema,\n const Right extends DictSchema,\n>(left: Left, right: Right) {\n return new IntersectionSchema<Left, Right>(left, right)\n}\n"]}
1
+ {"version":3,"file":"intersection.js","sourceRoot":"","sources":["../../src/schema/intersection.ts"],"names":[],"mappings":";;;AA2GA,oCAKC;AAhHD,wCAMmB;AAyBnB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAa,kBAGX,SAAQ,gBAGT;IAIsB;IACA;IAJZ,IAAI,GAAG,cAAuB,CAAA;IAEvC,YACqB,IAAU,EACV,KAAY;QAE/B,KAAK,EAAE,CAAA;QAHY,SAAI,GAAJ,IAAI,CAAM;QACV,UAAK,GAAL,KAAK,CAAO;IAGjC,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;QACjD,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAO,UAAU,CAAA;QAE1C,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE;YACzD,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa;SACrC,CAAC,CAAA;IACJ,CAAC;CACF;AAxBD,gDAwBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAwB;AACxB,SAAgB,YAAY,CAG1B,IAAU,EAAE,KAAY;IACxB,OAAO,IAAI,kBAAkB,CAAc,IAAI,EAAE,KAAK,CAAC,CAAA;AACzD,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n Simplify,\n ValidationContext,\n} from '../core.js'\nimport { DictSchema } from './dict.js'\nimport { ObjectSchema } from './object.js'\n\n/**\n * Type utility for computing the intersection of two object types.\n *\n * Allows to more accurately represent the intersection of two object types\n * where both types may share some keys, and one of them uses an index\n * signature.\n *\n * @template A - First object type (typically from ObjectSchema)\n * @template B - Second object type (typically from DictSchema)\n *\n * @see {@link https://www.typescriptlang.org/play/?#code/C4TwDgpgBAglC8UDeUBmB7dAuKByARgIYBOuUAvlAGTJQDaA+lAJYB2UAzsMWwOYC6OVgFcAtvgjEKAKGkATCAGMANiWiL0rLlEI4YsjVuBQA1hBA4uPVrwRQARBnT2Dm7QDdCy4dESE6ZiD8UAD0IVAi4pJQABQcABbowspyUBIORMT2AJSyEAAeYOjExqCQUACSrMCSHErAzJoAPNJQsFAFNaxyHFAASkrFck1WfAA0UMKsJqzoAO6sAHxjrVAAQh35XT39g8TDozYTUzPzSyuLdqtwVKttMYHoqO00j88bnRDdvawQ7pJ3NpQAD860BbRwSHBQLadAA0ix2G91oJ1vDggAfWABcxPF5QOH8aFtci5aRlaAwVDMfIQVKIKo1Yh1RQNZq0Jw4AgkMjkCYoRiIzjcPioyISKTkRayBQqNRQQzaQgAMRpdL01NpclcRignm8EFVWrsKrVchxQVC4XF0SxmSAA Playground link}\n */\nexport type Intersect<A, B> = B[keyof B] extends never\n ? A\n : keyof A & keyof B extends never\n ? // If A and B don't overlap, just return A & B\n A & B\n : // Otherwise, properly represent the fact that accessing using an\n // index signature could return a value from either A or B\n A & { [K in keyof B]: B[K] | A[keyof A & K] }\n\n/**\n * Schema for combining an object schema with a dictionary schema.\n *\n * Validates that the input matches both the fixed object shape and allows\n * additional properties that match the dictionary schema. Properties defined\n * in the object schema are validated by the object, and remaining properties\n * are validated by the dictionary.\n *\n * @template Left - The ObjectSchema type for fixed properties\n * @template Right - The DictSchema type for additional properties\n *\n * @example\n * ```ts\n * const schema = new IntersectionSchema(\n * l.object({ name: l.string() }),\n * l.dict(l.string(), l.integer())\n * )\n * // Validates: { name: 'test', score: 100, count: 5 }\n * ```\n */\nexport class IntersectionSchema<\n const Left extends ObjectSchema = any,\n const Right extends DictSchema = any,\n> extends Schema<\n Simplify<Intersect<InferInput<Left>, InferInput<Right>>>,\n Simplify<Intersect<InferOutput<Left>, InferOutput<Right>>>\n> {\n readonly type = 'intersection' as const\n\n constructor(\n protected readonly left: Left,\n protected readonly right: Right,\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n const leftResult = ctx.validate(input, this.left)\n if (!leftResult.success) return leftResult\n\n return this.right.validateInContext(leftResult.value, ctx, {\n ignoredKeys: this.left.validatorsMap,\n })\n }\n}\n\n/**\n * Creates an intersection schema combining fixed object properties with dynamic dictionary properties.\n *\n * Useful for objects that have a known set of properties plus additional\n * arbitrary properties that follow a pattern.\n *\n * @param left - Object schema defining the fixed, known properties\n * @param right - Dictionary schema for validating additional properties\n * @returns A new {@link IntersectionSchema} instance\n *\n * @example\n * ```ts\n * // Object with fixed and dynamic properties\n * const configSchema = l.intersection(\n * l.object({\n * version: l.integer(),\n * name: l.string(),\n * }),\n * l.dict(l.string(), l.string()) // Additional string properties\n * )\n *\n * configSchema.parse({\n * version: 1,\n * name: 'my-config',\n * customField: 'value',\n * anotherField: 'another',\n * })\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function intersection<\n const Left extends ObjectSchema,\n const Right extends DictSchema,\n>(left: Left, right: Right) {\n return new IntersectionSchema<Left, Right>(left, right)\n}\n"]}
@@ -0,0 +1,37 @@
1
+ import { LexMap } from '@atproto/lex-data';
2
+ import { Schema, ValidationContext } from '../core.js';
3
+ export type { LexMap };
4
+ /**
5
+ * AT Protocol lexicon schema definitions with "type": "unknown" are represented
6
+ * as plain objects with string keys and values that are valid AT Protocol data
7
+ * types (string, integer, boolean, null, bytes, cid, array, or object). This
8
+ * type alias corresponds to the expected structure of such "unknown" schema
9
+ * values.
10
+ */
11
+ export declare class LexMapSchema extends Schema<LexMap> {
12
+ readonly type: "lexMap";
13
+ validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<Record<string, unknown>>;
14
+ }
15
+ /**
16
+ * Creates a schema that accepts any plain object with string keys and values
17
+ * that are valid AT Protocol data types (string, integer, boolean, null, bytes,
18
+ * cid, array, or object).
19
+ *
20
+ * @see {@link LexMap} from `@atproto/lex-data` for the type definition of valid AT Protocol data types
21
+ * @returns A new {@link LexMapSchema} instance
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // Accept any object shape
26
+ * const schema = l.lexMap()
27
+ *
28
+ * schema.validate({ any: 'props' }) // success
29
+ * schema.validate([1, 2, 3]) // fails - only plain objects are accepted
30
+ * schema.validate({ foo: new Date() }) // fails - Date is not a valid LexValue
31
+ * schema.validate({ foo: 1.2 }) // fails - 1.2 is not a valid LexValue (not an integer)
32
+ * ```
33
+ */
34
+ export declare const lexMap: () => LexMapSchema;
35
+ /** @deprecated Use {@link lexMap} instead */
36
+ export declare const unknownObject: () => LexMapSchema;
37
+ //# sourceMappingURL=lex-map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lex-map.d.ts","sourceRoot":"","sources":["../../src/schema/lex-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAMtD,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB;;;;;;GAMG;AACH,qBAAa,YAAa,SAAQ,MAAM,CAAC,MAAM,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAS;IAEjC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAiBzD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,MAAM,oBAEjB,CAAA;AAEF,6CAA6C;AAC7C,eAAO,MAAM,aAAa,oBAAS,CAAA"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unknownObject = exports.lexMap = exports.LexMapSchema = void 0;
4
+ const lex_data_1 = require("@atproto/lex-data");
5
+ const core_js_1 = require("../core.js");
6
+ const memoize_js_1 = require("../util/memoize.js");
7
+ const lex_value_js_1 = require("./lex-value.js");
8
+ const propertyValueSchema = /*#__PURE__*/ (0, lex_value_js_1.lexValue)();
9
+ /**
10
+ * AT Protocol lexicon schema definitions with "type": "unknown" are represented
11
+ * as plain objects with string keys and values that are valid AT Protocol data
12
+ * types (string, integer, boolean, null, bytes, cid, array, or object). This
13
+ * type alias corresponds to the expected structure of such "unknown" schema
14
+ * values.
15
+ */
16
+ class LexMapSchema extends core_js_1.Schema {
17
+ type = 'lexMap';
18
+ validateInContext(input, ctx) {
19
+ if (!(0, lex_data_1.isPlainObject)(input)) {
20
+ return ctx.issueUnexpectedType(input, 'object');
21
+ }
22
+ for (const key of Object.keys(input)) {
23
+ // @NOTE We use a lexValue() schema here to recursively validate all
24
+ // nested values, which ensures that the error reporting includes the
25
+ // correct path and type information for any invalid nested values. This
26
+ // allows for more informative error descriptions than a simple "isLexMap"
27
+ // check.
28
+ const r = ctx.validateChild(input, key, propertyValueSchema); // recursively validate all properties
29
+ if (!r.success)
30
+ return r;
31
+ }
32
+ return ctx.success(input);
33
+ }
34
+ }
35
+ exports.LexMapSchema = LexMapSchema;
36
+ /**
37
+ * Creates a schema that accepts any plain object with string keys and values
38
+ * that are valid AT Protocol data types (string, integer, boolean, null, bytes,
39
+ * cid, array, or object).
40
+ *
41
+ * @see {@link LexMap} from `@atproto/lex-data` for the type definition of valid AT Protocol data types
42
+ * @returns A new {@link LexMapSchema} instance
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * // Accept any object shape
47
+ * const schema = l.lexMap()
48
+ *
49
+ * schema.validate({ any: 'props' }) // success
50
+ * schema.validate([1, 2, 3]) // fails - only plain objects are accepted
51
+ * schema.validate({ foo: new Date() }) // fails - Date is not a valid LexValue
52
+ * schema.validate({ foo: 1.2 }) // fails - 1.2 is not a valid LexValue (not an integer)
53
+ * ```
54
+ */
55
+ exports.lexMap = (0, memoize_js_1.memoizedOptions)(function () {
56
+ return new LexMapSchema();
57
+ });
58
+ /** @deprecated Use {@link lexMap} instead */
59
+ exports.unknownObject = exports.lexMap;
60
+ //# sourceMappingURL=lex-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lex-map.js","sourceRoot":"","sources":["../../src/schema/lex-map.ts"],"names":[],"mappings":";;;AAAA,gDAAyD;AACzD,wCAAsD;AACtD,mDAAoD;AACpD,iDAAyC;AAEzC,MAAM,mBAAmB,GAAG,aAAa,CAAC,IAAA,uBAAQ,GAAE,CAAA;AAIpD;;;;;;GAMG;AACH,MAAa,YAAa,SAAQ,gBAAc;IACrC,IAAI,GAAG,QAAiB,CAAA;IAEjC,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,CAAC,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,GAAG,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;QACjD,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,oEAAoE;YACpE,qEAAqE;YACrE,wEAAwE;YACxE,0EAA0E;YAC1E,SAAS;YACT,MAAM,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,mBAAmB,CAAC,CAAA,CAAC,sCAAsC;YACnG,IAAI,CAAC,CAAC,CAAC,OAAO;gBAAE,OAAO,CAAC,CAAA;QAC1B,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AApBD,oCAoBC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACU,QAAA,MAAM,GAAiB,IAAA,4BAAe,EAAC;IAClD,OAAO,IAAI,YAAY,EAAE,CAAA;AAC3B,CAAC,CAAC,CAAA;AAEF,6CAA6C;AAChC,QAAA,aAAa,GAAG,cAAM,CAAA","sourcesContent":["import { LexMap, isPlainObject } from '@atproto/lex-data'\nimport { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\nimport { lexValue } from './lex-value.js'\n\nconst propertyValueSchema = /*#__PURE__*/ lexValue()\n\nexport type { LexMap }\n\n/**\n * AT Protocol lexicon schema definitions with \"type\": \"unknown\" are represented\n * as plain objects with string keys and values that are valid AT Protocol data\n * types (string, integer, boolean, null, bytes, cid, array, or object). This\n * type alias corresponds to the expected structure of such \"unknown\" schema\n * values.\n */\nexport class LexMapSchema extends Schema<LexMap> {\n readonly type = 'lexMap' as const\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (!isPlainObject(input)) {\n return ctx.issueUnexpectedType(input, 'object')\n }\n\n for (const key of Object.keys(input)) {\n // @NOTE We use a lexValue() schema here to recursively validate all\n // nested values, which ensures that the error reporting includes the\n // correct path and type information for any invalid nested values. This\n // allows for more informative error descriptions than a simple \"isLexMap\"\n // check.\n const r = ctx.validateChild(input, key, propertyValueSchema) // recursively validate all properties\n if (!r.success) return r\n }\n\n return ctx.success(input)\n }\n}\n\n/**\n * Creates a schema that accepts any plain object with string keys and values\n * that are valid AT Protocol data types (string, integer, boolean, null, bytes,\n * cid, array, or object).\n *\n * @see {@link LexMap} from `@atproto/lex-data` for the type definition of valid AT Protocol data types\n * @returns A new {@link LexMapSchema} instance\n *\n * @example\n * ```ts\n * // Accept any object shape\n * const schema = l.lexMap()\n *\n * schema.validate({ any: 'props' }) // success\n * schema.validate([1, 2, 3]) // fails - only plain objects are accepted\n * schema.validate({ foo: new Date() }) // fails - Date is not a valid LexValue\n * schema.validate({ foo: 1.2 }) // fails - 1.2 is not a valid LexValue (not an integer)\n * ```\n */\nexport const lexMap = /*#__PURE__*/ memoizedOptions(function () {\n return new LexMapSchema()\n})\n\n/** @deprecated Use {@link lexMap} instead */\nexport const unknownObject = lexMap\n"]}
@@ -0,0 +1,35 @@
1
+ import { LexValue } from '@atproto/lex-data';
2
+ import { Schema, ValidationContext } from '../core.js';
3
+ export type { LexValue };
4
+ /**
5
+ * AT Protocol lexicon values are any valid AT Protocol data types: string,
6
+ * integer, boolean, null, bytes, cid, array, or object.
7
+ */
8
+ export declare class LexValueSchema extends Schema<LexValue> {
9
+ readonly type: "lexValue";
10
+ validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<any[] | Record<string, unknown> | import("@atproto/lex-data").LexScalar>;
11
+ }
12
+ /**
13
+ * Creates a schema that accepts any valid AT Protocol data type: string,
14
+ * integer, boolean, null, bytes, cid, array, or plain object. Arrays and
15
+ * objects are recursively validated to ensure all nested values are also valid
16
+ * AT Protocol data types.
17
+ *
18
+ * @see {@link LexValue} from `@atproto/lex-data` for the type definition of valid AT Protocol data types
19
+ * @returns A new {@link LexValueSchema} instance
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const schema = l.lexValue()
24
+ *
25
+ * schema.validate('hello') // success
26
+ * schema.validate(42) // success
27
+ * schema.validate(null) // success
28
+ * schema.validate([1, 'two', null]) // success
29
+ * schema.validate({ any: 'props' }) // success
30
+ * schema.validate(new Date()) // fails - Date is not a valid LexValue
31
+ * schema.validate({ foo: 1.2 }) // fails - 1.2 is not a valid LexValue (not an integer)
32
+ * ```
33
+ */
34
+ export declare const lexValue: () => LexValueSchema;
35
+ //# sourceMappingURL=lex-value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lex-value.d.ts","sourceRoot":"","sources":["../../src/schema/lex-value.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAA8B,MAAM,mBAAmB,CAAA;AACxE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD,YAAY,EAAE,QAAQ,EAAE,CAAA;AAexB;;;GAGG;AACH,qBAAa,cAAe,SAAQ,MAAM,CAAC,QAAQ,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAS;IAEnC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAiCzD;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,QAAQ,sBAEnB,CAAA"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lexValue = exports.LexValueSchema = void 0;
4
+ const lex_data_1 = require("@atproto/lex-data");
5
+ const core_js_1 = require("../core.js");
6
+ const memoize_js_1 = require("../util/memoize.js");
7
+ const EXPECTED_TYPES = Object.freeze([
8
+ // Scalar types
9
+ 'null',
10
+ 'boolean',
11
+ 'integer',
12
+ 'string',
13
+ 'cid',
14
+ 'bytes',
15
+ // Recursive types
16
+ 'array',
17
+ 'object',
18
+ ]);
19
+ /**
20
+ * AT Protocol lexicon values are any valid AT Protocol data types: string,
21
+ * integer, boolean, null, bytes, cid, array, or object.
22
+ */
23
+ class LexValueSchema extends core_js_1.Schema {
24
+ type = 'lexValue';
25
+ validateInContext(input, ctx) {
26
+ // @NOTE We are *not* using "isLexValue" here to allow for more specific
27
+ // error messages about the path and type of the invalid value. The
28
+ // "isLexValue" check is effectively performed by the recursive validation
29
+ // of child properties below.
30
+ // @NOTE There are two limitations to the fact that we are not using
31
+ // "isLexValue" here:
32
+ // 1. We cannot detect circular references in objects or arrays, which would
33
+ // cause infinite recursion. However, circular references are not valid
34
+ // AT Protocol data types, so this is not a concern for valid input. This
35
+ // could easily be addressed in the "validateChild" method by keeping
36
+ // track of "parent" objects.
37
+ // 2. We are limited in the recursion depth we can validate due to potential
38
+ // recursion depth limits in JavaScript. However, this is also not a
39
+ // concern for most valid input, as extremely deep nesting is unlikely in
40
+ // typical use cases.
41
+ if ((0, lex_data_1.isPlainObject)(input)) {
42
+ for (const key of Object.keys(input)) {
43
+ const r = ctx.validateChild(input, key, this); // recursively validate all properties
44
+ if (!r.success)
45
+ return r;
46
+ }
47
+ }
48
+ else if (Array.isArray(input)) {
49
+ for (let i = 0; i < input.length; i++) {
50
+ const r = ctx.validateChild(input, i, this); // recursively validate all array items
51
+ if (!r.success)
52
+ return r;
53
+ }
54
+ }
55
+ else if (!(0, lex_data_1.isLexScalar)(input)) {
56
+ return ctx.issueInvalidType(input, EXPECTED_TYPES);
57
+ }
58
+ return ctx.success(input);
59
+ }
60
+ }
61
+ exports.LexValueSchema = LexValueSchema;
62
+ /**
63
+ * Creates a schema that accepts any valid AT Protocol data type: string,
64
+ * integer, boolean, null, bytes, cid, array, or plain object. Arrays and
65
+ * objects are recursively validated to ensure all nested values are also valid
66
+ * AT Protocol data types.
67
+ *
68
+ * @see {@link LexValue} from `@atproto/lex-data` for the type definition of valid AT Protocol data types
69
+ * @returns A new {@link LexValueSchema} instance
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * const schema = l.lexValue()
74
+ *
75
+ * schema.validate('hello') // success
76
+ * schema.validate(42) // success
77
+ * schema.validate(null) // success
78
+ * schema.validate([1, 'two', null]) // success
79
+ * schema.validate({ any: 'props' }) // success
80
+ * schema.validate(new Date()) // fails - Date is not a valid LexValue
81
+ * schema.validate({ foo: 1.2 }) // fails - 1.2 is not a valid LexValue (not an integer)
82
+ * ```
83
+ */
84
+ exports.lexValue = (0, memoize_js_1.memoizedOptions)(function () {
85
+ return new LexValueSchema();
86
+ });
87
+ //# sourceMappingURL=lex-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lex-value.js","sourceRoot":"","sources":["../../src/schema/lex-value.ts"],"names":[],"mappings":";;;AAAA,gDAAwE;AACxE,wCAAsD;AACtD,mDAAoD;AAIpD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,eAAe;IACf,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,KAAK;IACL,OAAO;IACP,kBAAkB;IAClB,OAAO;IACP,QAAQ;CACA,CAAC,CAAA;AAEX;;;GAGG;AACH,MAAa,cAAe,SAAQ,gBAAgB;IACzC,IAAI,GAAG,UAAmB,CAAA;IAEnC,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,wEAAwE;QACxE,mEAAmE;QACnE,0EAA0E;QAC1E,6BAA6B;QAE7B,oEAAoE;QACpE,qBAAqB;QACrB,4EAA4E;QAC5E,0EAA0E;QAC1E,4EAA4E;QAC5E,wEAAwE;QACxE,gCAAgC;QAChC,4EAA4E;QAC5E,uEAAuE;QACvE,4EAA4E;QAC5E,wBAAwB;QACxB,IAAI,IAAA,wBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrC,MAAM,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA,CAAC,sCAAsC;gBACpF,IAAI,CAAC,CAAC,CAAC,OAAO;oBAAE,OAAO,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA,CAAC,uCAAuC;gBACnF,IAAI,CAAC,CAAC,CAAC,OAAO;oBAAE,OAAO,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,IAAA,sBAAW,EAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;QACpD,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AApCD,wCAoCC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACU,QAAA,QAAQ,GAAiB,IAAA,4BAAe,EAAC;IACpD,OAAO,IAAI,cAAc,EAAE,CAAA;AAC7B,CAAC,CAAC,CAAA","sourcesContent":["import { LexValue, isLexScalar, isPlainObject } from '@atproto/lex-data'\nimport { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\nexport type { LexValue }\n\nconst EXPECTED_TYPES = Object.freeze([\n // Scalar types\n 'null',\n 'boolean',\n 'integer',\n 'string',\n 'cid',\n 'bytes',\n // Recursive types\n 'array',\n 'object',\n] as const)\n\n/**\n * AT Protocol lexicon values are any valid AT Protocol data types: string,\n * integer, boolean, null, bytes, cid, array, or object.\n */\nexport class LexValueSchema extends Schema<LexValue> {\n readonly type = 'lexValue' as const\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n // @NOTE We are *not* using \"isLexValue\" here to allow for more specific\n // error messages about the path and type of the invalid value. The\n // \"isLexValue\" check is effectively performed by the recursive validation\n // of child properties below.\n\n // @NOTE There are two limitations to the fact that we are not using\n // \"isLexValue\" here:\n // 1. We cannot detect circular references in objects or arrays, which would\n // cause infinite recursion. However, circular references are not valid\n // AT Protocol data types, so this is not a concern for valid input. This\n // could easily be addressed in the \"validateChild\" method by keeping\n // track of \"parent\" objects.\n // 2. We are limited in the recursion depth we can validate due to potential\n // recursion depth limits in JavaScript. However, this is also not a\n // concern for most valid input, as extremely deep nesting is unlikely in\n // typical use cases.\n if (isPlainObject(input)) {\n for (const key of Object.keys(input)) {\n const r = ctx.validateChild(input, key, this) // recursively validate all properties\n if (!r.success) return r\n }\n } else if (Array.isArray(input)) {\n for (let i = 0; i < input.length; i++) {\n const r = ctx.validateChild(input, i, this) // recursively validate all array items\n if (!r.success) return r\n }\n } else if (!isLexScalar(input)) {\n return ctx.issueInvalidType(input, EXPECTED_TYPES)\n }\n\n return ctx.success(input)\n }\n}\n\n/**\n * Creates a schema that accepts any valid AT Protocol data type: string,\n * integer, boolean, null, bytes, cid, array, or plain object. Arrays and\n * objects are recursively validated to ensure all nested values are also valid\n * AT Protocol data types.\n *\n * @see {@link LexValue} from `@atproto/lex-data` for the type definition of valid AT Protocol data types\n * @returns A new {@link LexValueSchema} instance\n *\n * @example\n * ```ts\n * const schema = l.lexValue()\n *\n * schema.validate('hello') // success\n * schema.validate(42) // success\n * schema.validate(null) // success\n * schema.validate([1, 'two', null]) // success\n * schema.validate({ any: 'props' }) // success\n * schema.validate(new Date()) // fails - Date is not a valid LexValue\n * schema.validate({ foo: 1.2 }) // fails - 1.2 is not a valid LexValue (not an integer)\n * ```\n */\nexport const lexValue = /*#__PURE__*/ memoizedOptions(function () {\n return new LexValueSchema()\n})\n"]}
@@ -16,6 +16,7 @@ import { Schema, ValidationContext } from '../core.js';
16
16
  */
17
17
  export declare class LiteralSchema<const TValue extends null | string | number | boolean> extends Schema<TValue> {
18
18
  readonly value: TValue;
19
+ readonly type: "literal";
19
20
  constructor(value: TValue);
20
21
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<TValue>;
21
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"literal.d.ts","sourceRoot":"","sources":["../../src/schema/literal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEtD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa,CACxB,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CACrD,SAAQ,MAAM,CAAC,MAAM,CAAC;IACV,QAAQ,CAAC,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;IAIlC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,wBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EACtE,KAAK,EAAE,CAAC,oBAGT"}
1
+ {"version":3,"file":"literal.d.ts","sourceRoot":"","sources":["../../src/schema/literal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEtD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAa,CACxB,KAAK,CAAC,MAAM,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CACrD,SAAQ,MAAM,CAAC,MAAM,CAAC;IAGV,QAAQ,CAAC,KAAK,EAAE,MAAM;IAFlC,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAS;gBAEb,KAAK,EAAE,MAAM;IAIlC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,wBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EACtE,KAAK,EAAE,CAAC,oBAGT"}
@@ -20,6 +20,7 @@ const core_js_1 = require("../core.js");
20
20
  */
21
21
  class LiteralSchema extends core_js_1.Schema {
22
22
  value;
23
+ type = 'literal';
23
24
  constructor(value) {
24
25
  super();
25
26
  this.value = value;
@@ -1 +1 @@
1
- {"version":3,"file":"literal.js","sourceRoot":"","sources":["../../src/schema/literal.ts"],"names":[],"mappings":";;;AA+DA,0BAIC;AAnED,wCAAsD;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAa,aAEX,SAAQ,gBAAc;IACD;IAArB,YAAqB,KAAa;QAChC,KAAK,EAAE,CAAA;QADY,UAAK,GAAL,KAAK,CAAQ;IAElC,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QACnD,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;CACF;AAdD,sCAcC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAwB;AACxB,SAAgB,OAAO,CACrB,KAAQ;IAER,OAAO,IAAI,aAAa,CAAI,KAAK,CAAC,CAAA;AACpC,CAAC","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\n\n/**\n * Schema that only accepts a specific literal value.\n *\n * Validates that the input is exactly equal to the specified value using\n * strict equality (===).\n *\n * @template TValue - The literal type (null, string, number, or boolean)\n *\n * @example\n * ```ts\n * const schema = new LiteralSchema('admin')\n * schema.validate('admin') // success\n * schema.validate('user') // fails\n * ```\n */\nexport class LiteralSchema<\n const TValue extends null | string | number | boolean,\n> extends Schema<TValue> {\n constructor(readonly value: TValue) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (input !== this.value) {\n return ctx.issueInvalidValue(input, [this.value])\n }\n\n return ctx.success(this.value)\n }\n}\n\n/**\n * Creates a literal schema that only accepts the exact specified value.\n *\n * Useful for discriminator fields in unions, constant values, or type narrowing.\n *\n * @param value - The exact value that must be matched\n * @returns A new {@link LiteralSchema} instance\n *\n * @example\n * ```ts\n * // String literal\n * const roleSchema = l.literal('admin')\n *\n * // Number literal\n * const versionSchema = l.literal(1)\n *\n * // Boolean literal\n * const enabledSchema = l.literal(true)\n *\n * // Null literal\n * const nullSchema = l.literal(null)\n *\n * // In discriminated unions\n * const actionSchema = l.discriminatedUnion('type', [\n * l.object({ type: l.literal('create'), data: l.unknown() }),\n * l.object({ type: l.literal('delete'), id: l.string() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function literal<const V extends null | string | number | boolean>(\n value: V,\n) {\n return new LiteralSchema<V>(value)\n}\n"]}
1
+ {"version":3,"file":"literal.js","sourceRoot":"","sources":["../../src/schema/literal.ts"],"names":[],"mappings":";;;AAiEA,0BAIC;AArED,wCAAsD;AAEtD;;;;;;;;;;;;;;GAcG;AACH,MAAa,aAEX,SAAQ,gBAAc;IAGD;IAFZ,IAAI,GAAG,SAAkB,CAAA;IAElC,YAAqB,KAAa;QAChC,KAAK,EAAE,CAAA;QADY,UAAK,GAAL,KAAK,CAAQ;IAElC,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QACnD,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;CACF;AAhBD,sCAgBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAwB;AACxB,SAAgB,OAAO,CACrB,KAAQ;IAER,OAAO,IAAI,aAAa,CAAI,KAAK,CAAC,CAAA;AACpC,CAAC","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\n\n/**\n * Schema that only accepts a specific literal value.\n *\n * Validates that the input is exactly equal to the specified value using\n * strict equality (===).\n *\n * @template TValue - The literal type (null, string, number, or boolean)\n *\n * @example\n * ```ts\n * const schema = new LiteralSchema('admin')\n * schema.validate('admin') // success\n * schema.validate('user') // fails\n * ```\n */\nexport class LiteralSchema<\n const TValue extends null | string | number | boolean,\n> extends Schema<TValue> {\n readonly type = 'literal' as const\n\n constructor(readonly value: TValue) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (input !== this.value) {\n return ctx.issueInvalidValue(input, [this.value])\n }\n\n return ctx.success(this.value)\n }\n}\n\n/**\n * Creates a literal schema that only accepts the exact specified value.\n *\n * Useful for discriminator fields in unions, constant values, or type narrowing.\n *\n * @param value - The exact value that must be matched\n * @returns A new {@link LiteralSchema} instance\n *\n * @example\n * ```ts\n * // String literal\n * const roleSchema = l.literal('admin')\n *\n * // Number literal\n * const versionSchema = l.literal(1)\n *\n * // Boolean literal\n * const enabledSchema = l.literal(true)\n *\n * // Null literal\n * const nullSchema = l.literal(null)\n *\n * // In discriminated unions\n * const actionSchema = l.discriminatedUnion('type', [\n * l.object({ type: l.literal('create'), data: l.unknown() }),\n * l.object({ type: l.literal('delete'), id: l.string() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function literal<const V extends null | string | number | boolean>(\n value: V,\n) {\n return new LiteralSchema<V>(value)\n}\n"]}
@@ -12,6 +12,7 @@ import { Schema, ValidationContext } from '../core.js';
12
12
  * ```
13
13
  */
14
14
  export declare class NeverSchema extends Schema<never> {
15
+ readonly type: "never";
15
16
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationFailure;
16
17
  }
17
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"never.d.ts","sourceRoot":"","sources":["../../src/schema/never.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAC;IAC5C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAGzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,KAAK,mBAEhB,CAAA"}
1
+ {"version":3,"file":"never.d.ts","sourceRoot":"","sources":["../../src/schema/never.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,SAAQ,MAAM,CAAC,KAAK,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAS;IAEhC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAGzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,KAAK,mBAEhB,CAAA"}
@@ -16,8 +16,9 @@ const memoize_js_1 = require("../util/memoize.js");
16
16
  * ```
17
17
  */
18
18
  class NeverSchema extends core_js_1.Schema {
19
+ type = 'never';
19
20
  validateInContext(input, ctx) {
20
- return ctx.issueInvalidType(input, 'never');
21
+ return ctx.issueUnexpectedType(input, 'never');
21
22
  }
22
23
  }
23
24
  exports.NeverSchema = NeverSchema;
@@ -1 +1 @@
1
- {"version":3,"file":"never.js","sourceRoot":"","sources":["../../src/schema/never.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;GAWG;AACH,MAAa,WAAY,SAAQ,gBAAa;IAC5C,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;CACF;AAJD,kCAIC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACU,QAAA,KAAK,GAAiB,IAAA,4BAAe,EAAC;IACjD,OAAO,IAAI,WAAW,EAAE,CAAA;AAC1B,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema that always fails validation.\n *\n * Represents an impossible type - no value can satisfy this schema.\n * Useful for exhaustiveness checking or marking impossible branches.\n *\n * @example\n * ```ts\n * const schema = new NeverSchema()\n * schema.validate(anything) // always fails\n * ```\n */\nexport class NeverSchema extends Schema<never> {\n validateInContext(input: unknown, ctx: ValidationContext) {\n return ctx.issueInvalidType(input, 'never')\n }\n}\n\n/**\n * Creates a never schema that always fails validation.\n *\n * Useful for exhaustiveness checking in TypeScript or marking impossible\n * code paths.\n *\n * @returns A new {@link NeverSchema} instance\n *\n * @example\n * ```ts\n * // Exhaustiveness checking\n * type Status = 'active' | 'inactive'\n *\n * function handleStatus(status: Status) {\n * switch (status) {\n * case 'active': return 'Active'\n * case 'inactive': return 'Inactive'\n * default:\n * // TypeScript will error if we miss a case\n * l.never().parse(status)\n * }\n * }\n *\n * // In impossible union branches\n * const schema = l.object({\n * type: l.literal('fixed'),\n * dynamic: l.never(), // This property can never exist\n * })\n * ```\n */\nexport const never = /*#__PURE__*/ memoizedOptions(function () {\n return new NeverSchema()\n})\n"]}
1
+ {"version":3,"file":"never.js","sourceRoot":"","sources":["../../src/schema/never.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;GAWG;AACH,MAAa,WAAY,SAAQ,gBAAa;IACnC,IAAI,GAAG,OAAgB,CAAA;IAEhC,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,OAAO,GAAG,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAChD,CAAC;CACF;AAND,kCAMC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACU,QAAA,KAAK,GAAiB,IAAA,4BAAe,EAAC;IACjD,OAAO,IAAI,WAAW,EAAE,CAAA;AAC1B,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema that always fails validation.\n *\n * Represents an impossible type - no value can satisfy this schema.\n * Useful for exhaustiveness checking or marking impossible branches.\n *\n * @example\n * ```ts\n * const schema = new NeverSchema()\n * schema.validate(anything) // always fails\n * ```\n */\nexport class NeverSchema extends Schema<never> {\n readonly type = 'never' as const\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n return ctx.issueUnexpectedType(input, 'never')\n }\n}\n\n/**\n * Creates a never schema that always fails validation.\n *\n * Useful for exhaustiveness checking in TypeScript or marking impossible\n * code paths.\n *\n * @returns A new {@link NeverSchema} instance\n *\n * @example\n * ```ts\n * // Exhaustiveness checking\n * type Status = 'active' | 'inactive'\n *\n * function handleStatus(status: Status) {\n * switch (status) {\n * case 'active': return 'Active'\n * case 'inactive': return 'Inactive'\n * default:\n * // TypeScript will error if we miss a case\n * l.never().parse(status)\n * }\n * }\n *\n * // In impossible union branches\n * const schema = l.object({\n * type: l.literal('fixed'),\n * dynamic: l.never(), // This property can never exist\n * })\n * ```\n */\nexport const never = /*#__PURE__*/ memoizedOptions(function () {\n return new NeverSchema()\n})\n"]}
@@ -13,6 +13,7 @@ import { Schema, ValidationContext } from '../core.js';
13
13
  * ```
14
14
  */
15
15
  export declare class NullSchema extends Schema<null> {
16
+ readonly type: "null";
16
17
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<null>;
17
18
  }
18
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"null.d.ts","sourceRoot":"","sources":["../../src/schema/null.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAW,SAAQ,MAAM,CAAC,IAAI,CAAC;IAC1C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,kBAErB,CAAA;AAEF,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"null.d.ts","sourceRoot":"","sources":["../../src/schema/null.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAW,SAAQ,MAAM,CAAC,IAAI,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAS;IAE/B,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU,kBAErB,CAAA;AAEF,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,CAAA"}
@@ -17,9 +17,10 @@ const memoize_js_1 = require("../util/memoize.js");
17
17
  * ```
18
18
  */
19
19
  class NullSchema extends core_js_1.Schema {
20
+ type = 'null';
20
21
  validateInContext(input, ctx) {
21
22
  if (input !== null) {
22
- return ctx.issueInvalidType(input, 'null');
23
+ return ctx.issueUnexpectedType(input, 'null');
23
24
  }
24
25
  return ctx.success(null);
25
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"null.js","sourceRoot":"","sources":["../../src/schema/null.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAa,UAAW,SAAQ,gBAAY;IAC1C,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,GAAG,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC5C,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;CACF;AARD,gCAQC;AAED;;;;;;;;;;;;;;;GAeG;AACU,QAAA,UAAU,GAAiB,IAAA,4BAAe,EAAC;IACtD,OAAO,IAAI,UAAU,EAAE,CAAA;AACzB,CAAC,CAAC,CAAA;AAEqB,eAJV,kBAAU,CAII","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema for validating null values.\n *\n * Only accepts the JavaScript `null` value. Rejects `undefined` and all\n * other values.\n *\n * @example\n * ```ts\n * const schema = new NullSchema()\n * schema.validate(null) // success\n * schema.validate(undefined) // fails\n * ```\n */\nexport class NullSchema extends Schema<null> {\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (input !== null) {\n return ctx.issueInvalidType(input, 'null')\n }\n\n return ctx.success(null)\n }\n}\n\n/**\n * Creates a null schema that only accepts the null value.\n *\n * Useful for explicitly representing null in union types or optional fields.\n *\n * @returns A new {@link NullSchema} instance\n *\n * @example\n * ```ts\n * // Explicit null\n * const nullOnlySchema = l.null()\n *\n * // Nullable string (string or null)\n * const nullableStringSchema = l.union([l.string(), l.null()])\n * ```\n */\nexport const nullSchema = /*#__PURE__*/ memoizedOptions(function () {\n return new NullSchema()\n})\n\nexport { nullSchema as null }\n"]}
1
+ {"version":3,"file":"null.js","sourceRoot":"","sources":["../../src/schema/null.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAa,UAAW,SAAQ,gBAAY;IACjC,IAAI,GAAG,MAAe,CAAA;IAE/B,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,GAAG,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC/C,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;CACF;AAVD,gCAUC;AAED;;;;;;;;;;;;;;;GAeG;AACU,QAAA,UAAU,GAAiB,IAAA,4BAAe,EAAC;IACtD,OAAO,IAAI,UAAU,EAAE,CAAA;AACzB,CAAC,CAAC,CAAA;AAEqB,eAJV,kBAAU,CAII","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema for validating null values.\n *\n * Only accepts the JavaScript `null` value. Rejects `undefined` and all\n * other values.\n *\n * @example\n * ```ts\n * const schema = new NullSchema()\n * schema.validate(null) // success\n * schema.validate(undefined) // fails\n * ```\n */\nexport class NullSchema extends Schema<null> {\n readonly type = 'null' as const\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n if (input !== null) {\n return ctx.issueUnexpectedType(input, 'null')\n }\n\n return ctx.success(null)\n }\n}\n\n/**\n * Creates a null schema that only accepts the null value.\n *\n * Useful for explicitly representing null in union types or optional fields.\n *\n * @returns A new {@link NullSchema} instance\n *\n * @example\n * ```ts\n * // Explicit null\n * const nullOnlySchema = l.null()\n *\n * // Nullable string (string or null)\n * const nullableStringSchema = l.union([l.string(), l.null()])\n * ```\n */\nexport const nullSchema = /*#__PURE__*/ memoizedOptions(function () {\n return new NullSchema()\n})\n\nexport { nullSchema as null }\n"]}
@@ -16,6 +16,7 @@ import { InferInput, InferOutput, Schema, ValidationContext, Validator } from '.
16
16
  */
17
17
  export declare class NullableSchema<const TValidator extends Validator> extends Schema<InferInput<TValidator> | null, InferOutput<TValidator> | null> {
18
18
  readonly validator: TValidator;
19
+ readonly type: "nullable";
19
20
  constructor(validator: TValidator);
20
21
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationFailure | import("../core.js").ValidationSuccess<null> | import("../core.js").ValidationSuccess<InferInput<TValidator>>;
21
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nullable.d.ts","sourceRoot":"","sources":["../../src/schema/nullable.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAGnB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAc,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,CAAE,SAAQ,MAAM,CAC5E,UAAU,CAAC,UAAU,CAAC,GAAG,IAAI,EAC7B,WAAW,CAAC,UAAU,CAAC,GAAG,IAAI,CAC/B;IACa,QAAQ,CAAC,SAAS,EAAE,UAAU;gBAArB,SAAS,EAAE,UAAU;IAI1C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,QAAQ,SACb,UAAU,SAAS,SAAS,aACvB,UAAU,+BAErB,CAAA"}
1
+ {"version":3,"file":"nullable.d.ts","sourceRoot":"","sources":["../../src/schema/nullable.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAGnB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAc,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,CAAE,SAAQ,MAAM,CAC5E,UAAU,CAAC,UAAU,CAAC,GAAG,IAAI,EAC7B,WAAW,CAAC,UAAU,CAAC,GAAG,IAAI,CAC/B;IAGa,QAAQ,CAAC,SAAS,EAAE,UAAU;IAF1C,QAAQ,CAAC,IAAI,EAAG,UAAU,CAAS;gBAEd,SAAS,EAAE,UAAU;IAI1C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAOzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,QAAQ,SACb,UAAU,SAAS,SAAS,aACvB,UAAU,+BAErB,CAAA"}
@@ -20,6 +20,7 @@ const memoize_js_1 = require("../util/memoize.js");
20
20
  */
21
21
  class NullableSchema extends core_js_1.Schema {
22
22
  validator;
23
+ type = 'nullable';
23
24
  constructor(validator) {
24
25
  super();
25
26
  this.validator = validator;