@atproto/lex-schema 0.0.12 → 0.0.13

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 (199) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/core/schema.d.ts +4 -4
  3. package/dist/core/schema.d.ts.map +1 -1
  4. package/dist/core/schema.js +1 -1
  5. package/dist/core/schema.js.map +1 -1
  6. package/dist/core/validation-issue.js +3 -1
  7. package/dist/core/validation-issue.js.map +1 -1
  8. package/dist/core/validator.d.ts +10 -2
  9. package/dist/core/validator.d.ts.map +1 -1
  10. package/dist/core/validator.js +21 -3
  11. package/dist/core/validator.js.map +1 -1
  12. package/dist/helpers.d.ts +10 -11
  13. package/dist/helpers.d.ts.map +1 -1
  14. package/dist/helpers.js.map +1 -1
  15. package/dist/schema/array.d.ts +1 -0
  16. package/dist/schema/array.d.ts.map +1 -1
  17. package/dist/schema/array.js +2 -1
  18. package/dist/schema/array.js.map +1 -1
  19. package/dist/schema/blob.d.ts +4 -2
  20. package/dist/schema/blob.d.ts.map +1 -1
  21. package/dist/schema/blob.js +5 -2
  22. package/dist/schema/blob.js.map +1 -1
  23. package/dist/schema/boolean.d.ts +1 -0
  24. package/dist/schema/boolean.d.ts.map +1 -1
  25. package/dist/schema/boolean.js +2 -1
  26. package/dist/schema/boolean.js.map +1 -1
  27. package/dist/schema/bytes.d.ts +1 -0
  28. package/dist/schema/bytes.d.ts.map +1 -1
  29. package/dist/schema/bytes.js +2 -1
  30. package/dist/schema/bytes.js.map +1 -1
  31. package/dist/schema/cid.d.ts +1 -0
  32. package/dist/schema/cid.d.ts.map +1 -1
  33. package/dist/schema/cid.js +2 -1
  34. package/dist/schema/cid.js.map +1 -1
  35. package/dist/schema/custom.d.ts +1 -0
  36. package/dist/schema/custom.d.ts.map +1 -1
  37. package/dist/schema/custom.js +1 -0
  38. package/dist/schema/custom.js.map +1 -1
  39. package/dist/schema/dict.d.ts +1 -0
  40. package/dist/schema/dict.d.ts.map +1 -1
  41. package/dist/schema/dict.js +2 -1
  42. package/dist/schema/dict.js.map +1 -1
  43. package/dist/schema/discriminated-union.d.ts +1 -0
  44. package/dist/schema/discriminated-union.d.ts.map +1 -1
  45. package/dist/schema/discriminated-union.js +2 -1
  46. package/dist/schema/discriminated-union.js.map +1 -1
  47. package/dist/schema/enum.d.ts +1 -0
  48. package/dist/schema/enum.d.ts.map +1 -1
  49. package/dist/schema/enum.js +1 -0
  50. package/dist/schema/enum.js.map +1 -1
  51. package/dist/schema/integer.d.ts +1 -0
  52. package/dist/schema/integer.d.ts.map +1 -1
  53. package/dist/schema/integer.js +2 -1
  54. package/dist/schema/integer.js.map +1 -1
  55. package/dist/schema/intersection.d.ts +1 -0
  56. package/dist/schema/intersection.d.ts.map +1 -1
  57. package/dist/schema/intersection.js +1 -0
  58. package/dist/schema/intersection.js.map +1 -1
  59. package/dist/schema/lex-map.d.ts +37 -0
  60. package/dist/schema/lex-map.d.ts.map +1 -0
  61. package/dist/schema/lex-map.js +60 -0
  62. package/dist/schema/lex-map.js.map +1 -0
  63. package/dist/schema/lex-value.d.ts +35 -0
  64. package/dist/schema/lex-value.d.ts.map +1 -0
  65. package/dist/schema/lex-value.js +87 -0
  66. package/dist/schema/lex-value.js.map +1 -0
  67. package/dist/schema/literal.d.ts +1 -0
  68. package/dist/schema/literal.d.ts.map +1 -1
  69. package/dist/schema/literal.js +1 -0
  70. package/dist/schema/literal.js.map +1 -1
  71. package/dist/schema/never.d.ts +1 -0
  72. package/dist/schema/never.d.ts.map +1 -1
  73. package/dist/schema/never.js +2 -1
  74. package/dist/schema/never.js.map +1 -1
  75. package/dist/schema/null.d.ts +1 -0
  76. package/dist/schema/null.d.ts.map +1 -1
  77. package/dist/schema/null.js +2 -1
  78. package/dist/schema/null.js.map +1 -1
  79. package/dist/schema/nullable.d.ts +1 -0
  80. package/dist/schema/nullable.d.ts.map +1 -1
  81. package/dist/schema/nullable.js +1 -0
  82. package/dist/schema/nullable.js.map +1 -1
  83. package/dist/schema/object.d.ts +1 -0
  84. package/dist/schema/object.d.ts.map +1 -1
  85. package/dist/schema/object.js +2 -1
  86. package/dist/schema/object.js.map +1 -1
  87. package/dist/schema/optional.d.ts +1 -0
  88. package/dist/schema/optional.d.ts.map +1 -1
  89. package/dist/schema/optional.js +1 -0
  90. package/dist/schema/optional.js.map +1 -1
  91. package/dist/schema/params.d.ts +14 -10
  92. package/dist/schema/params.d.ts.map +1 -1
  93. package/dist/schema/params.js +84 -24
  94. package/dist/schema/params.js.map +1 -1
  95. package/dist/schema/payload.d.ts.map +1 -1
  96. package/dist/schema/payload.js +3 -3
  97. package/dist/schema/payload.js.map +1 -1
  98. package/dist/schema/record.d.ts +13 -17
  99. package/dist/schema/record.d.ts.map +1 -1
  100. package/dist/schema/record.js +1 -0
  101. package/dist/schema/record.js.map +1 -1
  102. package/dist/schema/ref.d.ts +1 -0
  103. package/dist/schema/ref.d.ts.map +1 -1
  104. package/dist/schema/ref.js +1 -0
  105. package/dist/schema/ref.js.map +1 -1
  106. package/dist/schema/regexp.d.ts +1 -0
  107. package/dist/schema/regexp.d.ts.map +1 -1
  108. package/dist/schema/regexp.js +2 -1
  109. package/dist/schema/regexp.js.map +1 -1
  110. package/dist/schema/string.d.ts +22 -6
  111. package/dist/schema/string.d.ts.map +1 -1
  112. package/dist/schema/string.js +16 -9
  113. package/dist/schema/string.js.map +1 -1
  114. package/dist/schema/token.d.ts +1 -0
  115. package/dist/schema/token.d.ts.map +1 -1
  116. package/dist/schema/token.js +2 -1
  117. package/dist/schema/token.js.map +1 -1
  118. package/dist/schema/typed-object.d.ts +11 -15
  119. package/dist/schema/typed-object.d.ts.map +1 -1
  120. package/dist/schema/typed-object.js +2 -1
  121. package/dist/schema/typed-object.js.map +1 -1
  122. package/dist/schema/typed-ref.d.ts +1 -0
  123. package/dist/schema/typed-ref.d.ts.map +1 -1
  124. package/dist/schema/typed-ref.js +1 -0
  125. package/dist/schema/typed-ref.js.map +1 -1
  126. package/dist/schema/typed-union.d.ts +1 -0
  127. package/dist/schema/typed-union.d.ts.map +1 -1
  128. package/dist/schema/typed-union.js +2 -1
  129. package/dist/schema/typed-union.js.map +1 -1
  130. package/dist/schema/union.d.ts +1 -0
  131. package/dist/schema/union.d.ts.map +1 -1
  132. package/dist/schema/union.js +1 -0
  133. package/dist/schema/union.js.map +1 -1
  134. package/dist/schema/unknown.d.ts +1 -0
  135. package/dist/schema/unknown.d.ts.map +1 -1
  136. package/dist/schema/unknown.js +1 -0
  137. package/dist/schema/unknown.js.map +1 -1
  138. package/dist/schema/with-default.d.ts +1 -0
  139. package/dist/schema/with-default.d.ts.map +1 -1
  140. package/dist/schema/with-default.js +1 -0
  141. package/dist/schema/with-default.js.map +1 -1
  142. package/dist/schema.d.ts +2 -1
  143. package/dist/schema.d.ts.map +1 -1
  144. package/dist/schema.js +2 -1
  145. package/dist/schema.js.map +1 -1
  146. package/dist/util/if-any.d.ts +2 -0
  147. package/dist/util/if-any.d.ts.map +1 -0
  148. package/dist/util/if-any.js +3 -0
  149. package/dist/util/if-any.js.map +1 -0
  150. package/package.json +2 -2
  151. package/src/core/schema.ts +9 -3
  152. package/src/core/validation-issue.ts +3 -2
  153. package/src/core/validator.ts +23 -3
  154. package/src/helpers.test.ts +1 -1
  155. package/src/helpers.ts +53 -19
  156. package/src/schema/array.ts +3 -1
  157. package/src/schema/blob.ts +4 -1
  158. package/src/schema/boolean.ts +3 -1
  159. package/src/schema/bytes.ts +3 -1
  160. package/src/schema/cid.ts +3 -1
  161. package/src/schema/custom.ts +2 -0
  162. package/src/schema/dict.ts +3 -1
  163. package/src/schema/discriminated-union.ts +3 -1
  164. package/src/schema/enum.ts +2 -0
  165. package/src/schema/integer.ts +3 -1
  166. package/src/schema/intersection.ts +2 -0
  167. package/src/schema/{unknown-object.test.ts → lex-map.test.ts} +9 -9
  168. package/src/schema/lex-map.ts +63 -0
  169. package/src/schema/lex-value.test.ts +81 -0
  170. package/src/schema/lex-value.ts +86 -0
  171. package/src/schema/literal.ts +2 -0
  172. package/src/schema/never.ts +3 -1
  173. package/src/schema/null.ts +3 -1
  174. package/src/schema/nullable.ts +2 -0
  175. package/src/schema/object.ts +3 -1
  176. package/src/schema/optional.ts +2 -0
  177. package/src/schema/params.test.ts +82 -43
  178. package/src/schema/params.ts +133 -39
  179. package/src/schema/payload.test.ts +2 -2
  180. package/src/schema/payload.ts +3 -4
  181. package/src/schema/record.ts +19 -8
  182. package/src/schema/ref.ts +2 -0
  183. package/src/schema/regexp.ts +3 -1
  184. package/src/schema/string.test.ts +99 -2
  185. package/src/schema/string.ts +58 -15
  186. package/src/schema/token.ts +3 -1
  187. package/src/schema/typed-object.ts +19 -8
  188. package/src/schema/typed-ref.ts +2 -0
  189. package/src/schema/typed-union.ts +3 -1
  190. package/src/schema/union.ts +2 -0
  191. package/src/schema/unknown.ts +2 -0
  192. package/src/schema/with-default.ts +2 -0
  193. package/src/schema.ts +2 -1
  194. package/src/util/if-any.ts +3 -0
  195. package/dist/schema/unknown-object.d.ts +0 -42
  196. package/dist/schema/unknown-object.d.ts.map +0 -1
  197. package/dist/schema/unknown-object.js +0 -50
  198. package/dist/schema/unknown-object.js.map +0 -1
  199. package/src/schema/unknown-object.ts +0 -53
@@ -1 +1 @@
1
- {"version":3,"file":"union.js","sourceRoot":"","sources":["../../src/schema/union.ts"],"names":[],"mappings":";;;AAkFA,sBAIC;AAtFD,wCAQmB;AASnB;;;;;;;;;;;;;;;GAeG;AACH,MAAa,WAEX,SAAQ,gBAGT;IACgC;IAA/B,YAA+B,UAAuB;QACpD,KAAK,EAAE,CAAA;QADsB,eAAU,GAAV,UAAU,CAAa;IAEtD,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,MAAM,QAAQ,GAAwB,EAAE,CAAA;QAExC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;YAC7C,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,MAAM,CAAA;YAEjC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,yBAAe,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5D,CAAC;CACF;AAtBD,kCAsBC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAwB;AACxB,SAAgB,KAAK,CACnB,UAAuB;IAEvB,OAAO,IAAI,WAAW,CAAc,UAAU,CAAC,CAAA;AACjD,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n ValidationError,\n ValidationFailure,\n Validator,\n} from '../core.js'\n\n/**\n * Type representing a non-empty tuple of validators for union schemas.\n *\n * Requires at least one validator in the tuple.\n */\nexport type UnionSchemaValidators = readonly [Validator, ...Validator[]]\n\n/**\n * Schema for validating values that match one of several possible schemas.\n *\n * Tries each validator in order until one succeeds. If all validators fail,\n * returns a combined error from all attempts.\n *\n * @template TValidators - Tuple type of the validators in the union\n *\n * @example\n * ```ts\n * const schema = new UnionSchema([l.string(), l.integer()])\n * schema.validate('hello') // success\n * schema.validate(42) // success\n * schema.validate(true) // fails\n * ```\n */\nexport class UnionSchema<\n const TValidators extends UnionSchemaValidators = any,\n> extends Schema<\n InferInput<TValidators[number]>,\n InferOutput<TValidators[number]>\n> {\n constructor(protected readonly validators: TValidators) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n const failures: ValidationFailure[] = []\n\n for (const validator of this.validators) {\n const result = ctx.validate(input, validator)\n if (result.success) return result\n\n failures.push(result)\n }\n\n return ctx.failure(ValidationError.fromFailures(failures))\n }\n}\n\n/**\n * Creates a union schema that accepts values matching any of the provided schemas.\n *\n * Validators are tried in order. Use `discriminatedUnion()` for better\n * performance when discriminating on a known property.\n *\n * @param validators - Non-empty array of validators to try\n * @returns A new {@link UnionSchema} instance\n *\n * @example\n * ```ts\n * // String or number\n * const stringOrNumber = l.union([l.string(), l.integer()])\n *\n * // Nullable value\n * const nullableString = l.union([l.string(), l.null()])\n *\n * // Multiple object types\n * const mediaSchema = l.union([\n * l.object({ type: l.literal('image'), url: l.string() }),\n * l.object({ type: l.literal('video'), url: l.string(), duration: l.integer() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function union<const TValidators extends UnionSchemaValidators>(\n validators: TValidators,\n) {\n return new UnionSchema<TValidators>(validators)\n}\n"]}
1
+ {"version":3,"file":"union.js","sourceRoot":"","sources":["../../src/schema/union.ts"],"names":[],"mappings":";;;AAoFA,sBAIC;AAxFD,wCAQmB;AASnB;;;;;;;;;;;;;;;GAeG;AACH,MAAa,WAEX,SAAQ,gBAGT;IAGgC;IAFtB,IAAI,GAAG,OAAgB,CAAA;IAEhC,YAA+B,UAAuB;QACpD,KAAK,EAAE,CAAA;QADsB,eAAU,GAAV,UAAU,CAAa;IAEtD,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,MAAM,QAAQ,GAAwB,EAAE,CAAA;QAExC,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;YAC7C,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,MAAM,CAAA;YAEjC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC;QAED,OAAO,GAAG,CAAC,OAAO,CAAC,yBAAe,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5D,CAAC;CACF;AAxBD,kCAwBC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAwB;AACxB,SAAgB,KAAK,CACnB,UAAuB;IAEvB,OAAO,IAAI,WAAW,CAAc,UAAU,CAAC,CAAA;AACjD,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n ValidationError,\n ValidationFailure,\n Validator,\n} from '../core.js'\n\n/**\n * Type representing a non-empty tuple of validators for union schemas.\n *\n * Requires at least one validator in the tuple.\n */\nexport type UnionSchemaValidators = readonly [Validator, ...Validator[]]\n\n/**\n * Schema for validating values that match one of several possible schemas.\n *\n * Tries each validator in order until one succeeds. If all validators fail,\n * returns a combined error from all attempts.\n *\n * @template TValidators - Tuple type of the validators in the union\n *\n * @example\n * ```ts\n * const schema = new UnionSchema([l.string(), l.integer()])\n * schema.validate('hello') // success\n * schema.validate(42) // success\n * schema.validate(true) // fails\n * ```\n */\nexport class UnionSchema<\n const TValidators extends UnionSchemaValidators = any,\n> extends Schema<\n InferInput<TValidators[number]>,\n InferOutput<TValidators[number]>\n> {\n readonly type = 'union' as const\n\n constructor(protected readonly validators: TValidators) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n const failures: ValidationFailure[] = []\n\n for (const validator of this.validators) {\n const result = ctx.validate(input, validator)\n if (result.success) return result\n\n failures.push(result)\n }\n\n return ctx.failure(ValidationError.fromFailures(failures))\n }\n}\n\n/**\n * Creates a union schema that accepts values matching any of the provided schemas.\n *\n * Validators are tried in order. Use `discriminatedUnion()` for better\n * performance when discriminating on a known property.\n *\n * @param validators - Non-empty array of validators to try\n * @returns A new {@link UnionSchema} instance\n *\n * @example\n * ```ts\n * // String or number\n * const stringOrNumber = l.union([l.string(), l.integer()])\n *\n * // Nullable value\n * const nullableString = l.union([l.string(), l.null()])\n *\n * // Multiple object types\n * const mediaSchema = l.union([\n * l.object({ type: l.literal('image'), url: l.string() }),\n * l.object({ type: l.literal('video'), url: l.string(), duration: l.integer() }),\n * ])\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function union<const TValidators extends UnionSchemaValidators>(\n validators: TValidators,\n) {\n return new UnionSchema<TValidators>(validators)\n}\n"]}
@@ -13,6 +13,7 @@ import { Schema, ValidationContext } from '../core.js';
13
13
  * ```
14
14
  */
15
15
  export declare class UnknownSchema extends Schema<unknown> {
16
+ readonly type: "unknown";
16
17
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<unknown>;
17
18
  }
18
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"unknown.d.ts","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,MAAM,CAAC,OAAO,CAAC;IAChD,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAGzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,OAAO,qBAElB,CAAA"}
1
+ {"version":3,"file":"unknown.d.ts","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAGtD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,MAAM,CAAC,OAAO,CAAC;IAChD,QAAQ,CAAC,IAAI,EAAG,SAAS,CAAS;IAElC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CAGzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,OAAO,qBAElB,CAAA"}
@@ -17,6 +17,7 @@ const memoize_js_1 = require("../util/memoize.js");
17
17
  * ```
18
18
  */
19
19
  class UnknownSchema extends core_js_1.Schema {
20
+ type = 'unknown';
20
21
  validateInContext(input, ctx) {
21
22
  return ctx.success(input);
22
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"unknown.js","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAa,aAAc,SAAQ,gBAAe;IAChD,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AAJD,sCAIC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,OAAO,GAAiB,IAAA,4BAAe,EAAC;IACnD,OAAO,IAAI,aAAa,EAAE,CAAA;AAC5B,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema that accepts any value without validation.\n *\n * Passes through any input unchanged. Use sparingly as it bypasses\n * type safety. Useful for dynamic data or when the schema is not\n * known at compile time.\n *\n * @example\n * ```ts\n * const schema = new UnknownSchema()\n * schema.validate(anything) // always succeeds\n * ```\n */\nexport class UnknownSchema extends Schema<unknown> {\n validateInContext(input: unknown, ctx: ValidationContext) {\n return ctx.success(input)\n }\n}\n\n/**\n * Creates an unknown schema that accepts any value.\n *\n * The value passes through without any validation or transformation.\n * Use this when you need to accept arbitrary data.\n *\n * @returns A new {@link UnknownSchema} instance\n *\n * @example\n * ```ts\n * // Accept any value\n * const anyDataSchema = l.unknown()\n *\n * // In an object with a dynamic field\n * const flexibleSchema = l.object({\n * type: l.string(),\n * data: l.unknown(),\n * })\n * ```\n */\nexport const unknown = /*#__PURE__*/ memoizedOptions(function () {\n return new UnknownSchema()\n})\n"]}
1
+ {"version":3,"file":"unknown.js","sourceRoot":"","sources":["../../src/schema/unknown.ts"],"names":[],"mappings":";;;AAAA,wCAAsD;AACtD,mDAAoD;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAa,aAAc,SAAQ,gBAAe;IACvC,IAAI,GAAG,SAAkB,CAAA;IAElC,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC3B,CAAC;CACF;AAND,sCAMC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,OAAO,GAAiB,IAAA,4BAAe,EAAC;IACnD,OAAO,IAAI,aAAa,EAAE,CAAA;AAC5B,CAAC,CAAC,CAAA","sourcesContent":["import { Schema, ValidationContext } from '../core.js'\nimport { memoizedOptions } from '../util/memoize.js'\n\n/**\n * Schema that accepts any value without validation.\n *\n * Passes through any input unchanged. Use sparingly as it bypasses\n * type safety. Useful for dynamic data or when the schema is not\n * known at compile time.\n *\n * @example\n * ```ts\n * const schema = new UnknownSchema()\n * schema.validate(anything) // always succeeds\n * ```\n */\nexport class UnknownSchema extends Schema<unknown> {\n readonly type = 'unknown' as const\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n return ctx.success(input)\n }\n}\n\n/**\n * Creates an unknown schema that accepts any value.\n *\n * The value passes through without any validation or transformation.\n * Use this when you need to accept arbitrary data.\n *\n * @returns A new {@link UnknownSchema} instance\n *\n * @example\n * ```ts\n * // Accept any value\n * const anyDataSchema = l.unknown()\n *\n * // In an object with a dynamic field\n * const flexibleSchema = l.object({\n * type: l.string(),\n * data: l.unknown(),\n * })\n * ```\n */\nexport const unknown = /*#__PURE__*/ memoizedOptions(function () {\n return new UnknownSchema()\n})\n"]}
@@ -18,6 +18,7 @@ import { InferInput, InferOutput, Schema, ValidationContext, Validator } from '.
18
18
  export declare class WithDefaultSchema<const TValidator extends Validator> extends Schema<InferInput<TValidator>, InferOutput<TValidator>> {
19
19
  readonly validator: TValidator;
20
20
  readonly defaultValue: InferInput<TValidator>;
21
+ readonly type: "withDefault";
21
22
  constructor(validator: TValidator, defaultValue: InferInput<TValidator>);
22
23
  validateInContext(input: unknown, ctx: ValidationContext): import("../core.js").ValidationResult<InferInput<TValidator>>;
23
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"with-default.d.ts","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAiB,CAC5B,KAAK,CAAC,UAAU,SAAS,SAAS,CAClC,SAAQ,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAE7D,QAAQ,CAAC,SAAS,EAAE,UAAU;IAC9B,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;gBADpC,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;IAK/C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CASzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,EAC5D,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC,iCAGrC"}
1
+ {"version":3,"file":"with-default.d.ts","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,SAAS,EACV,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAiB,CAC5B,KAAK,CAAC,UAAU,SAAS,SAAS,CAClC,SAAQ,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;IAI7D,QAAQ,CAAC,SAAS,EAAE,UAAU;IAC9B,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;IAJ/C,QAAQ,CAAC,IAAI,EAAG,aAAa,CAAS;gBAG3B,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC;IAK/C,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB;CASzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,UAAU,SAAS,SAAS,EAC5D,SAAS,EAAE,UAAU,EACrB,YAAY,EAAE,UAAU,CAAC,UAAU,CAAC,iCAGrC"}
@@ -22,6 +22,7 @@ const core_js_1 = require("../core.js");
22
22
  class WithDefaultSchema extends core_js_1.Schema {
23
23
  validator;
24
24
  defaultValue;
25
+ type = 'withDefault';
25
26
  constructor(validator, defaultValue) {
26
27
  super();
27
28
  this.validator = validator;
@@ -1 +1 @@
1
- {"version":3,"file":"with-default.js","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":";;;AAyEA,kCAKC;AA9ED,wCAMmB;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,MAAa,iBAEX,SAAQ,gBAAuD;IAEpD;IACA;IAFX,YACW,SAAqB,EACrB,YAAoC;QAE7C,KAAK,EAAE,CAAA;QAHE,cAAS,GAAT,SAAS,CAAY;QACrB,iBAAY,GAAZ,YAAY,CAAwB;IAG/C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,kEAAkE;QAClE,iCAAiC;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC3D,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACxD,CAAC;QAED,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;CACF;AAnBD,8CAmBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,WAAW,CACzB,SAAqB,EACrB,YAAoC;IAEpC,OAAO,IAAI,iBAAiB,CAAa,SAAS,EAAE,YAAY,CAAC,CAAA;AACnE,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n Validator,\n} from '../core.js'\n\n/**\n * Schema wrapper that provides a default value when the input is undefined.\n *\n * In parse mode, when the input is `undefined`, the default value is used\n * instead. In validate mode, undefined values pass through unchanged (the\n * default is not applied).\n *\n * @template TValidator - The wrapped validator type\n *\n * @example\n * ```ts\n * const schema = new WithDefaultSchema(l.integer(), 0)\n * schema.parse(undefined) // 0\n * schema.parse(42) // 42\n * ```\n */\nexport class WithDefaultSchema<\n const TValidator extends Validator,\n> extends Schema<InferInput<TValidator>, InferOutput<TValidator>> {\n constructor(\n readonly validator: TValidator,\n readonly defaultValue: InferInput<TValidator>,\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n // When in a validation context, the output should not be altered,\n // so we don't apply the default.\n if (input === undefined && ctx.options.mode !== 'validate') {\n return ctx.validate(this.defaultValue, this.validator)\n }\n\n return ctx.validate(input, this.validator)\n }\n}\n\n/**\n * Creates a schema that applies a default value when the input is undefined.\n *\n * Commonly used with `optional()` to provide fallback values for missing\n * properties. The default value is validated against the schema.\n *\n * @param validator - The validator for the value\n * @param defaultValue - The default value to use when input is undefined\n * @returns A new {@link WithDefaultSchema} instance\n *\n * @example\n * ```ts\n * // Integer with default\n * const countSchema = l.withDefault(l.integer(), 0)\n * countSchema.parse(undefined) // 0\n * countSchema.parse(5) // 5\n *\n * // Commonly combined with optional in objects\n * const settingsSchema = l.object({\n * theme: l.optional(l.withDefault(l.string(), 'light')),\n * pageSize: l.optional(l.withDefault(l.integer(), 25)),\n * })\n * settingsSchema.parse({}) // { theme: 'light', pageSize: 25 }\n *\n * // Boolean with default\n * const enabledSchema = l.withDefault(l.boolean(), false)\n * ```\n */\nexport function withDefault<const TValidator extends Validator>(\n validator: TValidator,\n defaultValue: InferInput<TValidator>,\n) {\n return new WithDefaultSchema<TValidator>(validator, defaultValue)\n}\n"]}
1
+ {"version":3,"file":"with-default.js","sourceRoot":"","sources":["../../src/schema/with-default.ts"],"names":[],"mappings":";;;AA2EA,kCAKC;AAhFD,wCAMmB;AAEnB;;;;;;;;;;;;;;;GAeG;AACH,MAAa,iBAEX,SAAQ,gBAAuD;IAIpD;IACA;IAJF,IAAI,GAAG,aAAsB,CAAA;IAEtC,YACW,SAAqB,EACrB,YAAoC;QAE7C,KAAK,EAAE,CAAA;QAHE,cAAS,GAAT,SAAS,CAAY;QACrB,iBAAY,GAAZ,YAAY,CAAwB;IAG/C,CAAC;IAED,iBAAiB,CAAC,KAAc,EAAE,GAAsB;QACtD,kEAAkE;QAClE,iCAAiC;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC3D,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACxD,CAAC;QAED,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5C,CAAC;CACF;AArBD,8CAqBC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,WAAW,CACzB,SAAqB,EACrB,YAAoC;IAEpC,OAAO,IAAI,iBAAiB,CAAa,SAAS,EAAE,YAAY,CAAC,CAAA;AACnE,CAAC","sourcesContent":["import {\n InferInput,\n InferOutput,\n Schema,\n ValidationContext,\n Validator,\n} from '../core.js'\n\n/**\n * Schema wrapper that provides a default value when the input is undefined.\n *\n * In parse mode, when the input is `undefined`, the default value is used\n * instead. In validate mode, undefined values pass through unchanged (the\n * default is not applied).\n *\n * @template TValidator - The wrapped validator type\n *\n * @example\n * ```ts\n * const schema = new WithDefaultSchema(l.integer(), 0)\n * schema.parse(undefined) // 0\n * schema.parse(42) // 42\n * ```\n */\nexport class WithDefaultSchema<\n const TValidator extends Validator,\n> extends Schema<InferInput<TValidator>, InferOutput<TValidator>> {\n readonly type = 'withDefault' as const\n\n constructor(\n readonly validator: TValidator,\n readonly defaultValue: InferInput<TValidator>,\n ) {\n super()\n }\n\n validateInContext(input: unknown, ctx: ValidationContext) {\n // When in a validation context, the output should not be altered,\n // so we don't apply the default.\n if (input === undefined && ctx.options.mode !== 'validate') {\n return ctx.validate(this.defaultValue, this.validator)\n }\n\n return ctx.validate(input, this.validator)\n }\n}\n\n/**\n * Creates a schema that applies a default value when the input is undefined.\n *\n * Commonly used with `optional()` to provide fallback values for missing\n * properties. The default value is validated against the schema.\n *\n * @param validator - The validator for the value\n * @param defaultValue - The default value to use when input is undefined\n * @returns A new {@link WithDefaultSchema} instance\n *\n * @example\n * ```ts\n * // Integer with default\n * const countSchema = l.withDefault(l.integer(), 0)\n * countSchema.parse(undefined) // 0\n * countSchema.parse(5) // 5\n *\n * // Commonly combined with optional in objects\n * const settingsSchema = l.object({\n * theme: l.optional(l.withDefault(l.string(), 'light')),\n * pageSize: l.optional(l.withDefault(l.integer(), 25)),\n * })\n * settingsSchema.parse({}) // { theme: 'light', pageSize: 25 }\n *\n * // Boolean with default\n * const enabledSchema = l.withDefault(l.boolean(), false)\n * ```\n */\nexport function withDefault<const TValidator extends Validator>(\n validator: TValidator,\n defaultValue: InferInput<TValidator>,\n) {\n return new WithDefaultSchema<TValidator>(validator, defaultValue)\n}\n"]}
package/dist/schema.d.ts CHANGED
@@ -6,13 +6,14 @@ export * from './schema/cid.js';
6
6
  export * from './schema/dict.js';
7
7
  export * from './schema/enum.js';
8
8
  export * from './schema/integer.js';
9
+ export * from './schema/lex-map.js';
10
+ export * from './schema/lex-value.js';
9
11
  export * from './schema/literal.js';
10
12
  export * from './schema/never.js';
11
13
  export * from './schema/null.js';
12
14
  export * from './schema/object.js';
13
15
  export * from './schema/regexp.js';
14
16
  export * from './schema/string.js';
15
- export * from './schema/unknown-object.js';
16
17
  export * from './schema/unknown.js';
17
18
  export * from './schema/custom.js';
18
19
  export * from './schema/discriminated-union.js';
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AAGnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AAGxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AAGnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AAGxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA"}
package/dist/schema.js CHANGED
@@ -10,13 +10,14 @@ tslib_1.__exportStar(require("./schema/cid.js"), exports);
10
10
  tslib_1.__exportStar(require("./schema/dict.js"), exports);
11
11
  tslib_1.__exportStar(require("./schema/enum.js"), exports);
12
12
  tslib_1.__exportStar(require("./schema/integer.js"), exports);
13
+ tslib_1.__exportStar(require("./schema/lex-map.js"), exports);
14
+ tslib_1.__exportStar(require("./schema/lex-value.js"), exports);
13
15
  tslib_1.__exportStar(require("./schema/literal.js"), exports);
14
16
  tslib_1.__exportStar(require("./schema/never.js"), exports);
15
17
  tslib_1.__exportStar(require("./schema/null.js"), exports);
16
18
  tslib_1.__exportStar(require("./schema/object.js"), exports);
17
19
  tslib_1.__exportStar(require("./schema/regexp.js"), exports);
18
20
  tslib_1.__exportStar(require("./schema/string.js"), exports);
19
- tslib_1.__exportStar(require("./schema/unknown-object.js"), exports);
20
21
  tslib_1.__exportStar(require("./schema/unknown.js"), exports);
21
22
  // Composite Types
22
23
  tslib_1.__exportStar(require("./schema/custom.js"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;AAAA,iBAAiB;AACjB,4DAAiC;AACjC,2DAAgC;AAChC,8DAAmC;AACnC,4DAAiC;AACjC,0DAA+B;AAC/B,2DAAgC;AAChC,2DAAgC;AAChC,8DAAmC;AACnC,8DAAmC;AACnC,4DAAiC;AACjC,2DAAgC;AAChC,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC;AAClC,qEAA0C;AAC1C,8DAAmC;AAEnC,kBAAkB;AAClB,6DAAkC;AAClC,0EAA+C;AAC/C,mEAAwC;AACxC,+DAAoC;AACpC,+DAAoC;AACpC,0DAA+B;AAC/B,6DAAkC;AAClC,4DAAiC;AACjC,mEAAwC;AAExC,yBAAyB;AACzB,6DAAkC;AAClC,8DAAmC;AACnC,qEAA0C;AAC1C,iEAAsC;AACtC,gEAAqC;AACrC,4DAAiC;AACjC,6DAAkC;AAClC,mEAAwC;AACxC,4DAAiC;AACjC,mEAAwC;AACxC,gEAAqC;AACrC,kEAAuC","sourcesContent":["// Concrete Types\nexport * from './schema/array.js'\nexport * from './schema/blob.js'\nexport * from './schema/boolean.js'\nexport * from './schema/bytes.js'\nexport * from './schema/cid.js'\nexport * from './schema/dict.js'\nexport * from './schema/enum.js'\nexport * from './schema/integer.js'\nexport * from './schema/literal.js'\nexport * from './schema/never.js'\nexport * from './schema/null.js'\nexport * from './schema/object.js'\nexport * from './schema/regexp.js'\nexport * from './schema/string.js'\nexport * from './schema/unknown-object.js'\nexport * from './schema/unknown.js'\n\n// Composite Types\nexport * from './schema/custom.js'\nexport * from './schema/discriminated-union.js'\nexport * from './schema/intersection.js'\nexport * from './schema/nullable.js'\nexport * from './schema/optional.js'\nexport * from './schema/ref.js'\nexport * from './schema/refine.js'\nexport * from './schema/union.js'\nexport * from './schema/with-default.js'\n\n// Lexicon specific Types\nexport * from './schema/params.js'\nexport * from './schema/payload.js'\nexport * from './schema/permission-set.js'\nexport * from './schema/permission.js'\nexport * from './schema/procedure.js'\nexport * from './schema/query.js'\nexport * from './schema/record.js'\nexport * from './schema/subscription.js'\nexport * from './schema/token.js'\nexport * from './schema/typed-object.js'\nexport * from './schema/typed-ref.js'\nexport * from './schema/typed-union.js'\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;AAAA,iBAAiB;AACjB,4DAAiC;AACjC,2DAAgC;AAChC,8DAAmC;AACnC,4DAAiC;AACjC,0DAA+B;AAC/B,2DAAgC;AAChC,2DAAgC;AAChC,8DAAmC;AACnC,8DAAmC;AACnC,gEAAqC;AACrC,8DAAmC;AACnC,4DAAiC;AACjC,2DAAgC;AAChC,6DAAkC;AAClC,6DAAkC;AAClC,6DAAkC;AAClC,8DAAmC;AAEnC,kBAAkB;AAClB,6DAAkC;AAClC,0EAA+C;AAC/C,mEAAwC;AACxC,+DAAoC;AACpC,+DAAoC;AACpC,0DAA+B;AAC/B,6DAAkC;AAClC,4DAAiC;AACjC,mEAAwC;AAExC,yBAAyB;AACzB,6DAAkC;AAClC,8DAAmC;AACnC,qEAA0C;AAC1C,iEAAsC;AACtC,gEAAqC;AACrC,4DAAiC;AACjC,6DAAkC;AAClC,mEAAwC;AACxC,4DAAiC;AACjC,mEAAwC;AACxC,gEAAqC;AACrC,kEAAuC","sourcesContent":["// Concrete Types\nexport * from './schema/array.js'\nexport * from './schema/blob.js'\nexport * from './schema/boolean.js'\nexport * from './schema/bytes.js'\nexport * from './schema/cid.js'\nexport * from './schema/dict.js'\nexport * from './schema/enum.js'\nexport * from './schema/integer.js'\nexport * from './schema/lex-map.js'\nexport * from './schema/lex-value.js'\nexport * from './schema/literal.js'\nexport * from './schema/never.js'\nexport * from './schema/null.js'\nexport * from './schema/object.js'\nexport * from './schema/regexp.js'\nexport * from './schema/string.js'\nexport * from './schema/unknown.js'\n\n// Composite Types\nexport * from './schema/custom.js'\nexport * from './schema/discriminated-union.js'\nexport * from './schema/intersection.js'\nexport * from './schema/nullable.js'\nexport * from './schema/optional.js'\nexport * from './schema/ref.js'\nexport * from './schema/refine.js'\nexport * from './schema/union.js'\nexport * from './schema/with-default.js'\n\n// Lexicon specific Types\nexport * from './schema/params.js'\nexport * from './schema/payload.js'\nexport * from './schema/permission-set.js'\nexport * from './schema/permission.js'\nexport * from './schema/procedure.js'\nexport * from './schema/query.js'\nexport * from './schema/record.js'\nexport * from './schema/subscription.js'\nexport * from './schema/token.js'\nexport * from './schema/typed-object.js'\nexport * from './schema/typed-ref.js'\nexport * from './schema/typed-union.js'\n"]}
@@ -0,0 +1,2 @@
1
+ export type IfAny<T, TrueValue, FalseValue> = 0 extends 1 & T ? TrueValue : FalseValue;
2
+ //# sourceMappingURL=if-any.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"if-any.d.ts","sourceRoot":"","sources":["../../src/util/if-any.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GACzD,SAAS,GACT,UAAU,CAAA"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=if-any.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"if-any.js","sourceRoot":"","sources":["../../src/util/if-any.ts"],"names":[],"mappings":"","sourcesContent":["export type IfAny<T, TrueValue, FalseValue> = 0 extends 1 & T\n ? TrueValue\n : FalseValue\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-schema",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "license": "MIT",
5
5
  "description": "Lexicon schema system for AT Lexicons",
6
6
  "keywords": [
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "tslib": "^2.8.1",
39
39
  "@atproto/syntax": "^0.4.3",
40
- "@atproto/lex-data": "^0.0.11"
40
+ "@atproto/lex-data": "^0.0.12"
41
41
  },
42
42
  "devDependencies": {
43
43
  "vitest": "^4.0.16"
@@ -11,13 +11,13 @@ import {
11
11
  * Options for parsing operations.
12
12
  * Excludes the `mode` option as it is implicitly set to `"parse"`.
13
13
  */
14
- type ParseOptions = Omit<ValidationOptions, 'mode'>
14
+ export type ParseOptions = Omit<ValidationOptions, 'mode'>
15
15
 
16
16
  /**
17
17
  * Options for validation operations.
18
18
  * Excludes the `mode` option as it is implicitly set to `"validate"`.
19
19
  */
20
- type ValidateOptions = Omit<ValidationOptions, 'mode'>
20
+ export type ValidateOptions = Omit<ValidationOptions, 'mode'>
21
21
 
22
22
  /**
23
23
  * Internal type structure for schema type inference.
@@ -58,7 +58,7 @@ export interface SchemaInternals<out TInput = unknown, out TOutput = TInput> {
58
58
  * class MySchema extends Schema<string> {
59
59
  * validateInContext(input: unknown, ctx: ValidationContext): ValidationResult {
60
60
  * if (typeof input !== 'string') {
61
- * return ctx.issueInvalidType(input, 'string')
61
+ * return ctx.issueUnexpectedType(input, 'string')
62
62
  * }
63
63
  * return ctx.success(input)
64
64
  * }
@@ -88,6 +88,12 @@ export abstract class Schema<
88
88
  */
89
89
  declare readonly ['__lex']: TInternals
90
90
 
91
+ // Needed to discriminate multiple schema types when used in unions. Without
92
+ // this, Typescript could allow an EnumSchema<"foo" | "bar"> to be used where
93
+ // a StringSchema is expected, since they would both be structurally
94
+ // compatible.
95
+ abstract readonly type: string
96
+
91
97
  /**
92
98
  * Performs validation of the input value within a validation context.
93
99
  *
@@ -1,4 +1,4 @@
1
- import { ifCid, isPlainObject } from '@atproto/lex-data'
1
+ import { ifCid, isLegacyBlobRef, isPlainObject } from '@atproto/lex-data'
2
2
  import { PropertyKey } from './property-key.js'
3
3
 
4
4
  /**
@@ -260,7 +260,7 @@ export class IssueTooSmall extends Issue {
260
260
 
261
261
  function stringifyExpectedType(expected: string): string {
262
262
  if (expected === '$typed') {
263
- return 'an object or record which includes a "$type" property'
263
+ return 'an object which includes the "$type" property'
264
264
  }
265
265
  return expected
266
266
  }
@@ -295,6 +295,7 @@ function stringifyType(value: unknown): string {
295
295
  if (value === null) return 'null'
296
296
  if (Array.isArray(value)) return 'array'
297
297
  if (ifCid(value)) return 'cid'
298
+ if (isLegacyBlobRef(value)) return 'legacy-blob'
298
299
  if (value instanceof Date) return 'date'
299
300
  if (value instanceof RegExp) return 'regexp'
300
301
  if (value instanceof Map) return 'map'
@@ -192,7 +192,7 @@ export type ValidationOptions = {
192
192
  * class MyValidator implements Validator {
193
193
  * validateInContext(input: unknown, ctx: ValidationContext): ValidationResult {
194
194
  * if (typeof input !== 'string') {
195
- * return ctx.issueInvalidType(input, 'string')
195
+ * return ctx.issueUnexpectedType(input, 'string')
196
196
  * }
197
197
  * return ctx.success(input)
198
198
  * }
@@ -377,6 +377,15 @@ export class ValidationContext {
377
377
  K extends PropertyKey & keyof I,
378
378
  V extends Validator,
379
379
  >(input: I, key: K, validator: V): ValidationResult<InferInput<V>> {
380
+ // @NOTE we could add support for recursive schemas by keeping track of
381
+ // "parent" objects in the context and checking for circular references
382
+ // here. This would allow us to validate recursive structures without
383
+ // hitting maximum call stack errors, and would also allow us to provide
384
+ // better error messages for circular reference issues. However, this is not
385
+ // a priority at the moment as recursive structures are not supported in
386
+ // the context of AT Protocol lexicons, and we can always add this in the
387
+ // future if needed.
388
+
380
389
  // Instead of creating a new context, we just push/pop the path segment.
381
390
  this.currentPath.push(key)
382
391
  try {
@@ -443,6 +452,17 @@ export class ValidationContext {
443
452
  return this.issue(new IssueInvalidValue(this.path, input, values))
444
453
  }
445
454
 
455
+ /**
456
+ * Creates a failure for an invalid type.
457
+ *
458
+ * @param input - The actual value that was received
459
+ * @param expected - An array of expected type names
460
+ * @returns A failed validation result with an invalid type issue
461
+ */
462
+ issueInvalidType(input: unknown, expected: readonly string[]) {
463
+ return this.issue(new IssueInvalidType(this.path, input, expected))
464
+ }
465
+
446
466
  /**
447
467
  * Creates a failure for an invalid type.
448
468
  *
@@ -450,8 +470,8 @@ export class ValidationContext {
450
470
  * @param expected - The expected type name
451
471
  * @returns A failed validation result with an invalid type issue
452
472
  */
453
- issueInvalidType(input: unknown, expected: string) {
454
- return this.issue(new IssueInvalidType(this.path, input, [expected]))
473
+ issueUnexpectedType(input: unknown, expected: string) {
474
+ return this.issueInvalidType(input, [expected])
455
475
  }
456
476
 
457
477
  /**
@@ -61,7 +61,7 @@ describe('InferMethodParams', () => {
61
61
  l.params({
62
62
  cursor: l.optional(l.integer()),
63
63
  }),
64
- l.unknownObject(),
64
+ l.lexMap(),
65
65
  )
66
66
 
67
67
  type Params = l.InferMethodParams<typeof subscription>
package/src/helpers.ts CHANGED
@@ -26,47 +26,81 @@ export function getMain<T extends object>(ns: Main<T>): T {
26
26
  * `ReadableStream`, etc.). This type is a placeholder to represent binary data
27
27
  * when not explicitly provided.
28
28
  */
29
- type BinaryData = Restricted<'Binary data'>
29
+ export type BinaryData = Restricted<'Binary data'>
30
30
 
31
- export type InferMethodParams<M extends Procedure | Query | Subscription> =
32
- InferOutput<M['parameters']>
31
+ export type InferMethodParams<
32
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
33
+ > =
34
+ M extends Procedure<any, infer TParams, any, any, any>
35
+ ? InferOutput<TParams>
36
+ : M extends Query<any, infer TParams, any, any>
37
+ ? InferOutput<TParams>
38
+ : M extends Subscription<any, infer TParams, any, any>
39
+ ? InferOutput<TParams>
40
+ : never
33
41
 
34
42
  export type InferMethodInput<
35
- M extends Procedure | Query | Subscription,
43
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
36
44
  B = BinaryData,
37
- > = M extends Procedure ? InferPayload<M['input'], B> : undefined
45
+ > =
46
+ M extends Procedure<any, any, infer TInput, any, any>
47
+ ? InferPayload<TInput, B>
48
+ : undefined
38
49
 
39
50
  export type InferMethodInputBody<
40
- M extends Procedure | Query | Subscription,
51
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
41
52
  B = BinaryData,
42
- > = M extends Procedure ? InferPayloadBody<M['input'], B> : undefined
53
+ > =
54
+ M extends Procedure<any, any, infer TInput, any, any>
55
+ ? InferPayloadBody<TInput, B>
56
+ : undefined
43
57
 
44
58
  export type InferMethodInputEncoding<
45
- M extends Procedure | Query | Subscription,
46
- > = M extends Procedure ? InferPayloadEncoding<M['input']> : undefined
59
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
60
+ > =
61
+ M extends Procedure<any, any, infer TInput, any, any>
62
+ ? InferPayloadEncoding<TInput>
63
+ : undefined
47
64
 
48
65
  export type InferMethodOutput<
49
- M extends Procedure | Query | Subscription,
66
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
50
67
  B = BinaryData,
51
- > = M extends Procedure | Query ? InferPayload<M['output'], B> : undefined
68
+ > =
69
+ M extends Procedure<any, any, any, infer TOutput, any>
70
+ ? InferPayload<TOutput, B>
71
+ : M extends Query<any, any, infer TOutput, any>
72
+ ? InferPayload<TOutput, B>
73
+ : undefined
52
74
 
53
75
  export type InferMethodOutputBody<
54
- M extends Procedure | Query | Subscription,
76
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
55
77
  B = BinaryData,
56
- > = M extends Procedure | Query ? InferPayloadBody<M['output'], B> : undefined
78
+ > =
79
+ M extends Procedure<any, any, any, infer TOutput, any>
80
+ ? InferPayloadBody<TOutput, B>
81
+ : M extends Query<any, any, infer TOutput, any>
82
+ ? InferPayloadBody<TOutput, B>
83
+ : undefined
57
84
 
58
85
  export type InferMethodOutputEncoding<
59
- M extends Procedure | Query | Subscription,
60
- > = M extends Procedure | Query ? InferPayloadEncoding<M['output']> : undefined
86
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
87
+ > =
88
+ M extends Procedure<any, any, any, infer TOutput, any>
89
+ ? InferPayloadEncoding<TOutput>
90
+ : M extends Query<any, any, infer TOutput, any>
91
+ ? InferPayloadEncoding<TOutput>
92
+ : undefined
61
93
 
62
94
  export type InferMethodMessage<
63
- //
64
- M extends Subscription,
65
- > = M extends Subscription ? InferOutput<M['message']> : undefined
95
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
96
+ > =
97
+ M extends Subscription<any, any, infer TMessage, any>
98
+ ? InferOutput<TMessage>
99
+ : undefined
66
100
 
67
101
  export type InferMethodError<
68
102
  //
69
- M extends Procedure | Query | Subscription,
103
+ M extends Procedure | Query | Subscription = Procedure | Query | Subscription,
70
104
  > = M extends { errors: readonly (infer E extends string)[] } ? E : never
71
105
 
72
106
  export const lexErrorDataSchema = object({
@@ -36,6 +36,8 @@ export class ArraySchema<const TItem extends Validator> extends Schema<
36
36
  Array<InferInput<TItem>>,
37
37
  Array<InferOutput<TItem>>
38
38
  > {
39
+ readonly type = 'array' as const
40
+
39
41
  constructor(
40
42
  readonly validator: TItem,
41
43
  readonly options: ArraySchemaOptions = {},
@@ -45,7 +47,7 @@ export class ArraySchema<const TItem extends Validator> extends Schema<
45
47
 
46
48
  validateInContext(input: unknown, ctx: ValidationContext) {
47
49
  if (!Array.isArray(input)) {
48
- return ctx.issueInvalidType(input, 'array')
50
+ return ctx.issueUnexpectedType(input, 'array')
49
51
  }
50
52
 
51
53
  const { minLength, maxLength } = this.options
@@ -32,6 +32,7 @@ export type BlobSchemaOptions = BlobRefCheckOptions & {
32
32
  }
33
33
 
34
34
  export type { BlobRef, LegacyBlobRef }
35
+ export { isBlobRef, isLegacyBlobRef }
35
36
 
36
37
  /**
37
38
  * Schema for validating blob references in AT Protocol.
@@ -53,6 +54,8 @@ export class BlobSchema<
53
54
  > extends Schema<
54
55
  TOptions extends { allowLegacy: true } ? BlobRef | LegacyBlobRef : BlobRef
55
56
  > {
57
+ readonly type = 'blob' as const
58
+
56
59
  constructor(readonly options?: TOptions) {
57
60
  super()
58
61
  }
@@ -68,7 +71,7 @@ export class BlobSchema<
68
71
  : null
69
72
 
70
73
  if (!blob) {
71
- return ctx.issueInvalidType(input, 'blob')
74
+ return ctx.issueUnexpectedType(input, 'blob')
72
75
  }
73
76
 
74
77
  const accept = this.options?.accept
@@ -16,12 +16,14 @@ import { memoizedOptions } from '../util/memoize.js'
16
16
  * ```
17
17
  */
18
18
  export class BooleanSchema extends Schema<boolean> {
19
+ readonly type = 'boolean' as const
20
+
19
21
  validateInContext(input: unknown, ctx: ValidationContext) {
20
22
  if (typeof input === 'boolean') {
21
23
  return ctx.success(input)
22
24
  }
23
25
 
24
- return ctx.issueInvalidType(input, 'boolean')
26
+ return ctx.issueUnexpectedType(input, 'boolean')
25
27
  }
26
28
  }
27
29
 
@@ -26,6 +26,8 @@ export type BytesSchemaOptions = {
26
26
  * ```
27
27
  */
28
28
  export class BytesSchema extends Schema<Uint8Array> {
29
+ readonly type = 'bytes' as const
30
+
29
31
  constructor(readonly options: BytesSchemaOptions = {}) {
30
32
  super()
31
33
  }
@@ -35,7 +37,7 @@ export class BytesSchema extends Schema<Uint8Array> {
35
37
  const bytes =
36
38
  ctx.options.mode === 'parse' ? asUint8Array(input) : ifUint8Array(input)
37
39
  if (!bytes) {
38
- return ctx.issueInvalidType(input, 'bytes')
40
+ return ctx.issueUnexpectedType(input, 'bytes')
39
41
  }
40
42
 
41
43
  const { minLength } = this.options
package/src/schema/cid.ts CHANGED
@@ -29,13 +29,15 @@ export type CidSchemaOptions = CheckCidOptions
29
29
  export class CidSchema<
30
30
  const TOptions extends CidSchemaOptions = { flavor: undefined },
31
31
  > extends Schema<InferCheckedCid<TOptions>> {
32
+ readonly type = 'cid' as const
33
+
32
34
  constructor(readonly options?: TOptions) {
33
35
  super()
34
36
  }
35
37
 
36
38
  validateInContext(input: unknown, ctx: ValidationContext) {
37
39
  if (!isCid(input, this.options)) {
38
- return ctx.issueInvalidType(input, 'cid')
40
+ return ctx.issueUnexpectedType(input, 'cid')
39
41
  }
40
42
 
41
43
  return ctx.success(input)
@@ -46,6 +46,8 @@ export type CustomAssertion<TValue> = (
46
46
  * ```
47
47
  */
48
48
  export class CustomSchema<out TValue = unknown> extends Schema<TValue> {
49
+ readonly type = 'custom' as const
50
+
49
51
  constructor(
50
52
  private readonly assertion: CustomAssertion<TValue>,
51
53
  private readonly message: string,
@@ -34,6 +34,8 @@ export class DictSchema<
34
34
  Record<InferInput<TKey>, InferInput<TValue>>,
35
35
  Record<InferInput<TKey>, InferOutput<TValue>>
36
36
  > {
37
+ readonly type = 'dict' as const
38
+
37
39
  constructor(
38
40
  readonly keySchema: TKey,
39
41
  readonly valueSchema: TValue,
@@ -47,7 +49,7 @@ export class DictSchema<
47
49
  options?: { ignoredKeys?: { has(k: string): boolean } },
48
50
  ) {
49
51
  if (!isPlainObject(input)) {
50
- return ctx.issueInvalidType(input, 'dict')
52
+ return ctx.issueUnexpectedType(input, 'dict')
51
53
  }
52
54
 
53
55
  let copy: undefined | Record<string, unknown>
@@ -78,6 +78,8 @@ export class DiscriminatedUnionSchema<
78
78
  DiscriminatedUnionSchemaInput<TVariants>,
79
79
  DiscriminatedUnionSchemaOutput<TVariants>
80
80
  > {
81
+ readonly type = 'discriminatedUnion' as const
82
+
81
83
  readonly variantsMap: Map<unknown, DiscriminatedUnionVariant<TDiscriminator>>
82
84
 
83
85
  constructor(
@@ -94,7 +96,7 @@ export class DiscriminatedUnionSchema<
94
96
 
95
97
  validateInContext(input: unknown, ctx: ValidationContext) {
96
98
  if (!isPlainObject(input)) {
97
- return ctx.issueInvalidType(input, 'object')
99
+ return ctx.issueUnexpectedType(input, 'object')
98
100
  }
99
101
 
100
102
  const { discriminator } = this
@@ -18,6 +18,8 @@ import { Schema, ValidationContext } from '../core.js'
18
18
  export class EnumSchema<
19
19
  const TValue extends null | string | number | boolean,
20
20
  > extends Schema<TValue> {
21
+ readonly type = 'enum' as const
22
+
21
23
  constructor(readonly values: readonly TValue[]) {
22
24
  super()
23
25
  }
@@ -25,13 +25,15 @@ export type IntegerSchemaOptions = {
25
25
  * ```
26
26
  */
27
27
  export class IntegerSchema extends Schema<number> {
28
+ readonly type = 'integer' as const
29
+
28
30
  constructor(readonly options?: IntegerSchemaOptions) {
29
31
  super()
30
32
  }
31
33
 
32
34
  validateInContext(input: unknown, ctx: ValidationContext) {
33
35
  if (!isInteger(input)) {
34
- return ctx.issueInvalidType(input, 'integer')
36
+ return ctx.issueUnexpectedType(input, 'integer')
35
37
  }
36
38
 
37
39
  if (this.options?.minimum != null && input < this.options.minimum) {
@@ -56,6 +56,8 @@ export class IntersectionSchema<
56
56
  Simplify<Intersect<InferInput<Left>, InferInput<Right>>>,
57
57
  Simplify<Intersect<InferOutput<Left>, InferOutput<Right>>>
58
58
  > {
59
+ readonly type = 'intersection' as const
60
+
59
61
  constructor(
60
62
  protected readonly left: Left,
61
63
  protected readonly right: Right,