typesea 0.1.0 → 0.3.0

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 (301) hide show
  1. package/CHANGELOG.md +85 -6
  2. package/README.md +143 -28
  3. package/dist/adapters/index.d.ts +50 -8
  4. package/dist/adapters/index.d.ts.map +1 -1
  5. package/dist/adapters/index.js +169 -48
  6. package/dist/aot/index.d.ts +19 -3
  7. package/dist/aot/index.d.ts.map +1 -1
  8. package/dist/aot/index.js +115 -17
  9. package/dist/async/index.d.ts +28 -56
  10. package/dist/async/index.d.ts.map +1 -1
  11. package/dist/async/index.js +94 -37
  12. package/dist/builders/composite.d.ts +43 -9
  13. package/dist/builders/composite.d.ts.map +1 -1
  14. package/dist/builders/composite.js +100 -17
  15. package/dist/builders/index.d.ts +8 -5
  16. package/dist/builders/index.d.ts.map +1 -1
  17. package/dist/builders/index.js +7 -4
  18. package/dist/builders/modifier.d.ts +36 -5
  19. package/dist/builders/modifier.d.ts.map +1 -1
  20. package/dist/builders/modifier.js +52 -5
  21. package/dist/builders/object/guard.d.ts +72 -24
  22. package/dist/builders/object/guard.d.ts.map +1 -1
  23. package/dist/builders/object/guard.js +139 -29
  24. package/dist/builders/object/index.d.ts +4 -2
  25. package/dist/builders/object/index.d.ts.map +1 -1
  26. package/dist/builders/object/index.js +3 -1
  27. package/dist/builders/object/schema.d.ts +88 -11
  28. package/dist/builders/object/schema.d.ts.map +1 -1
  29. package/dist/builders/object/schema.js +290 -23
  30. package/dist/builders/object/types.d.ts +20 -31
  31. package/dist/builders/object/types.d.ts.map +1 -1
  32. package/dist/builders/object/types.js +2 -0
  33. package/dist/builders/runtime.d.ts +40 -0
  34. package/dist/builders/runtime.d.ts.map +1 -0
  35. package/dist/builders/runtime.js +150 -0
  36. package/dist/builders/scalar.d.ts +49 -9
  37. package/dist/builders/scalar.d.ts.map +1 -1
  38. package/dist/builders/scalar.js +87 -9
  39. package/dist/builders/table.d.ts +35 -5
  40. package/dist/builders/table.d.ts.map +1 -1
  41. package/dist/builders/table.js +35 -5
  42. package/dist/builders/types.d.ts +20 -4
  43. package/dist/builders/types.d.ts.map +1 -1
  44. package/dist/builders/types.js +2 -0
  45. package/dist/compile/check-composite.d.ts +25 -2
  46. package/dist/compile/check-composite.d.ts.map +1 -1
  47. package/dist/compile/check-composite.js +699 -27
  48. package/dist/compile/check-scalar.d.ts +88 -0
  49. package/dist/compile/check-scalar.d.ts.map +1 -1
  50. package/dist/compile/check-scalar.js +570 -3
  51. package/dist/compile/check.d.ts +12 -0
  52. package/dist/compile/check.d.ts.map +1 -1
  53. package/dist/compile/check.js +62 -3
  54. package/dist/compile/context.d.ts +47 -9
  55. package/dist/compile/context.d.ts.map +1 -1
  56. package/dist/compile/context.js +53 -8
  57. package/dist/compile/first.d.ts +26 -0
  58. package/dist/compile/first.d.ts.map +1 -0
  59. package/dist/compile/first.js +850 -0
  60. package/dist/compile/graph-predicate.d.ts +4 -2
  61. package/dist/compile/graph-predicate.d.ts.map +1 -1
  62. package/dist/compile/graph-predicate.js +2272 -165
  63. package/dist/compile/guard.d.ts +16 -24
  64. package/dist/compile/guard.d.ts.map +1 -1
  65. package/dist/compile/guard.js +202 -72
  66. package/dist/compile/index.d.ts +3 -1
  67. package/dist/compile/index.d.ts.map +1 -1
  68. package/dist/compile/index.js +2 -0
  69. package/dist/compile/issue.d.ts +110 -0
  70. package/dist/compile/issue.d.ts.map +1 -1
  71. package/dist/compile/issue.js +184 -1
  72. package/dist/compile/names.d.ts +12 -2
  73. package/dist/compile/names.d.ts.map +1 -1
  74. package/dist/compile/names.js +19 -3
  75. package/dist/compile/predicate.d.ts +24 -0
  76. package/dist/compile/predicate.d.ts.map +1 -1
  77. package/dist/compile/predicate.js +287 -10
  78. package/dist/compile/runtime.d.ts +100 -13
  79. package/dist/compile/runtime.d.ts.map +1 -1
  80. package/dist/compile/runtime.js +56 -6
  81. package/dist/compile/source.d.ts +10 -2
  82. package/dist/compile/source.d.ts.map +1 -1
  83. package/dist/compile/source.js +385 -26
  84. package/dist/compile/types.d.ts +22 -0
  85. package/dist/compile/types.d.ts.map +1 -1
  86. package/dist/compile/types.js +2 -0
  87. package/dist/decoder/index.d.ts +92 -46
  88. package/dist/decoder/index.d.ts.map +1 -1
  89. package/dist/decoder/index.js +266 -39
  90. package/dist/evaluate/check-composite.d.ts +111 -2
  91. package/dist/evaluate/check-composite.d.ts.map +1 -1
  92. package/dist/evaluate/check-composite.js +343 -8
  93. package/dist/evaluate/check-scalar.d.ts +25 -0
  94. package/dist/evaluate/check-scalar.d.ts.map +1 -1
  95. package/dist/evaluate/check-scalar.js +124 -3
  96. package/dist/evaluate/check.d.ts +7 -0
  97. package/dist/evaluate/check.d.ts.map +1 -1
  98. package/dist/evaluate/check.js +62 -4
  99. package/dist/evaluate/index.d.ts +2 -0
  100. package/dist/evaluate/index.d.ts.map +1 -1
  101. package/dist/evaluate/index.js +2 -0
  102. package/dist/evaluate/issue.d.ts +11 -1
  103. package/dist/evaluate/issue.d.ts.map +1 -1
  104. package/dist/evaluate/issue.js +15 -1
  105. package/dist/evaluate/predicate.d.ts +16 -5
  106. package/dist/evaluate/predicate.d.ts.map +1 -1
  107. package/dist/evaluate/predicate.js +20 -5
  108. package/dist/evaluate/shared.d.ts +78 -13
  109. package/dist/evaluate/shared.d.ts.map +1 -1
  110. package/dist/evaluate/shared.js +101 -8
  111. package/dist/evaluate/state.d.ts +35 -13
  112. package/dist/evaluate/state.d.ts.map +1 -1
  113. package/dist/evaluate/state.js +35 -2
  114. package/dist/guard/array.d.ts +48 -0
  115. package/dist/guard/array.d.ts.map +1 -0
  116. package/dist/guard/array.js +84 -0
  117. package/dist/guard/base.d.ts +111 -31
  118. package/dist/guard/base.d.ts.map +1 -1
  119. package/dist/guard/base.js +165 -32
  120. package/dist/guard/date.d.ts +34 -0
  121. package/dist/guard/date.d.ts.map +1 -0
  122. package/dist/guard/date.js +60 -0
  123. package/dist/guard/error.d.ts +10 -5
  124. package/dist/guard/error.d.ts.map +1 -1
  125. package/dist/guard/error.js +10 -5
  126. package/dist/guard/index.d.ts +4 -0
  127. package/dist/guard/index.d.ts.map +1 -1
  128. package/dist/guard/index.js +4 -0
  129. package/dist/guard/number.d.ts +86 -11
  130. package/dist/guard/number.d.ts.map +1 -1
  131. package/dist/guard/number.js +159 -11
  132. package/dist/guard/props.d.ts +27 -3
  133. package/dist/guard/props.d.ts.map +1 -1
  134. package/dist/guard/props.js +27 -3
  135. package/dist/guard/read.d.ts +115 -10
  136. package/dist/guard/read.d.ts.map +1 -1
  137. package/dist/guard/read.js +185 -10
  138. package/dist/guard/registry.d.ts +12 -2
  139. package/dist/guard/registry.d.ts.map +1 -1
  140. package/dist/guard/registry.js +15 -3
  141. package/dist/guard/string.d.ts +115 -13
  142. package/dist/guard/string.d.ts.map +1 -1
  143. package/dist/guard/string.js +250 -13
  144. package/dist/guard/types.d.ts +110 -40
  145. package/dist/guard/types.d.ts.map +1 -1
  146. package/dist/guard/types.js +2 -0
  147. package/dist/index.d.ts +5 -5
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +4 -4
  150. package/dist/internal/index.d.ts +42 -6
  151. package/dist/internal/index.d.ts.map +1 -1
  152. package/dist/internal/index.js +51 -8
  153. package/dist/ir/builder.d.ts +17 -127
  154. package/dist/ir/builder.d.ts.map +1 -1
  155. package/dist/ir/builder.js +80 -137
  156. package/dist/ir/freeze.d.ts +4 -0
  157. package/dist/ir/freeze.d.ts.map +1 -1
  158. package/dist/ir/freeze.js +66 -0
  159. package/dist/ir/index.d.ts +3 -1
  160. package/dist/ir/index.d.ts.map +1 -1
  161. package/dist/ir/index.js +2 -0
  162. package/dist/ir/regexp.d.ts +2 -0
  163. package/dist/ir/regexp.d.ts.map +1 -1
  164. package/dist/ir/regexp.js +2 -0
  165. package/dist/ir/types.d.ts +94 -56
  166. package/dist/ir/types.d.ts.map +1 -1
  167. package/dist/ir/types.js +2 -0
  168. package/dist/ir/validate.d.ts +8 -1
  169. package/dist/ir/validate.d.ts.map +1 -1
  170. package/dist/ir/validate.js +511 -61
  171. package/dist/issue/index.d.ts +42 -10
  172. package/dist/issue/index.d.ts.map +1 -1
  173. package/dist/issue/index.js +65 -11
  174. package/dist/json-schema/emit-combinator.d.ts +44 -4
  175. package/dist/json-schema/emit-combinator.d.ts.map +1 -1
  176. package/dist/json-schema/emit-combinator.js +44 -4
  177. package/dist/json-schema/emit-composite.d.ts +16 -2
  178. package/dist/json-schema/emit-composite.d.ts.map +1 -1
  179. package/dist/json-schema/emit-composite.js +81 -13
  180. package/dist/json-schema/emit-scalar.d.ts +26 -3
  181. package/dist/json-schema/emit-scalar.d.ts.map +1 -1
  182. package/dist/json-schema/emit-scalar.js +124 -10
  183. package/dist/json-schema/emit-types.d.ts +11 -1
  184. package/dist/json-schema/emit-types.d.ts.map +1 -1
  185. package/dist/json-schema/emit-types.js +2 -0
  186. package/dist/json-schema/emit.d.ts +12 -1
  187. package/dist/json-schema/emit.d.ts.map +1 -1
  188. package/dist/json-schema/emit.js +23 -3
  189. package/dist/json-schema/freeze.d.ts +13 -2
  190. package/dist/json-schema/freeze.d.ts.map +1 -1
  191. package/dist/json-schema/freeze.js +41 -8
  192. package/dist/json-schema/index.d.ts +16 -2
  193. package/dist/json-schema/index.d.ts.map +1 -1
  194. package/dist/json-schema/index.js +23 -3
  195. package/dist/json-schema/issue.d.ts +4 -1
  196. package/dist/json-schema/issue.d.ts.map +1 -1
  197. package/dist/json-schema/issue.js +4 -1
  198. package/dist/json-schema/read.d.ts +24 -3
  199. package/dist/json-schema/read.d.ts.map +1 -1
  200. package/dist/json-schema/read.js +59 -12
  201. package/dist/json-schema/types.d.ts +45 -16
  202. package/dist/json-schema/types.d.ts.map +1 -1
  203. package/dist/json-schema/types.js +2 -0
  204. package/dist/kind/index.d.ts +40 -28
  205. package/dist/kind/index.d.ts.map +1 -1
  206. package/dist/kind/index.js +41 -13
  207. package/dist/lower/index.d.ts +6 -1
  208. package/dist/lower/index.d.ts.map +1 -1
  209. package/dist/lower/index.js +462 -46
  210. package/dist/message/index.d.ts +64 -10
  211. package/dist/message/index.d.ts.map +1 -1
  212. package/dist/message/index.js +155 -17
  213. package/dist/optimize/algebraic.d.ts +54 -0
  214. package/dist/optimize/algebraic.d.ts.map +1 -0
  215. package/dist/optimize/algebraic.js +314 -0
  216. package/dist/optimize/compact.d.ts +8 -1
  217. package/dist/optimize/compact.d.ts.map +1 -1
  218. package/dist/optimize/compact.js +13 -2
  219. package/dist/optimize/domain.d.ts +16 -0
  220. package/dist/optimize/domain.d.ts.map +1 -0
  221. package/dist/optimize/domain.js +619 -0
  222. package/dist/optimize/fold-boolean.d.ts +17 -2
  223. package/dist/optimize/fold-boolean.d.ts.map +1 -1
  224. package/dist/optimize/fold-boolean.js +59 -14
  225. package/dist/optimize/fold-common.d.ts +43 -8
  226. package/dist/optimize/fold-common.d.ts.map +1 -1
  227. package/dist/optimize/fold-common.js +37 -6
  228. package/dist/optimize/fold-constraints.d.ts +33 -0
  229. package/dist/optimize/fold-constraints.d.ts.map +1 -0
  230. package/dist/optimize/fold-constraints.js +484 -0
  231. package/dist/optimize/fold-scalar.d.ts +98 -13
  232. package/dist/optimize/fold-scalar.d.ts.map +1 -1
  233. package/dist/optimize/fold-scalar.js +98 -13
  234. package/dist/optimize/fold.d.ts +8 -1
  235. package/dist/optimize/fold.d.ts.map +1 -1
  236. package/dist/optimize/fold.js +22 -2
  237. package/dist/optimize/index.d.ts +9 -1
  238. package/dist/optimize/index.d.ts.map +1 -1
  239. package/dist/optimize/index.js +18 -3
  240. package/dist/optimize/map-node.d.ts +3 -1
  241. package/dist/optimize/map-node.d.ts.map +1 -1
  242. package/dist/optimize/map-node.js +48 -3
  243. package/dist/optimize/peephole.d.ts +16 -0
  244. package/dist/optimize/peephole.d.ts.map +1 -0
  245. package/dist/optimize/peephole.js +254 -0
  246. package/dist/optimize/remap.d.ts +2 -0
  247. package/dist/optimize/remap.d.ts.map +1 -1
  248. package/dist/optimize/remap.js +2 -0
  249. package/dist/optimize/rewrite.d.ts +13 -8
  250. package/dist/optimize/rewrite.d.ts.map +1 -1
  251. package/dist/optimize/rewrite.js +13 -8
  252. package/dist/plan/cache.d.ts +9 -3
  253. package/dist/plan/cache.d.ts.map +1 -1
  254. package/dist/plan/cache.js +34 -6
  255. package/dist/plan/index.d.ts +2 -0
  256. package/dist/plan/index.d.ts.map +1 -1
  257. package/dist/plan/index.js +2 -0
  258. package/dist/plan/predicate.d.ts +2 -0
  259. package/dist/plan/predicate.d.ts.map +1 -1
  260. package/dist/plan/predicate.js +298 -29
  261. package/dist/plan/schema-predicate.d.ts +6 -0
  262. package/dist/plan/schema-predicate.d.ts.map +1 -1
  263. package/dist/plan/schema-predicate.js +382 -19
  264. package/dist/plan/types.d.ts +2 -0
  265. package/dist/plan/types.d.ts.map +1 -1
  266. package/dist/plan/types.js +2 -0
  267. package/dist/result/index.d.ts +19 -5
  268. package/dist/result/index.d.ts.map +1 -1
  269. package/dist/result/index.js +10 -2
  270. package/dist/schema/common.d.ts +69 -6
  271. package/dist/schema/common.d.ts.map +1 -1
  272. package/dist/schema/common.js +104 -10
  273. package/dist/schema/freeze.d.ts +4 -0
  274. package/dist/schema/freeze.d.ts.map +1 -1
  275. package/dist/schema/freeze.js +40 -0
  276. package/dist/schema/index.d.ts +5 -2
  277. package/dist/schema/index.d.ts.map +1 -1
  278. package/dist/schema/index.js +4 -1
  279. package/dist/schema/lazy.d.ts +4 -0
  280. package/dist/schema/lazy.d.ts.map +1 -1
  281. package/dist/schema/lazy.js +4 -0
  282. package/dist/schema/literal.d.ts +7 -1
  283. package/dist/schema/literal.d.ts.map +1 -1
  284. package/dist/schema/literal.js +7 -1
  285. package/dist/schema/types.d.ts +109 -100
  286. package/dist/schema/types.d.ts.map +1 -1
  287. package/dist/schema/types.js +13 -2
  288. package/dist/schema/undefined.d.ts +17 -0
  289. package/dist/schema/undefined.d.ts.map +1 -0
  290. package/dist/schema/undefined.js +77 -0
  291. package/dist/schema/validate.d.ts +8 -1
  292. package/dist/schema/validate.d.ts.map +1 -1
  293. package/dist/schema/validate.js +255 -57
  294. package/docs/api.md +128 -8
  295. package/docs/assets/benchmark-headline.svg +163 -0
  296. package/docs/engine-notes.md +62 -15
  297. package/docs/index.html +1340 -702
  298. package/docs/ko/api.md +375 -0
  299. package/docs/ko/engine-notes.md +156 -0
  300. package/docs/ko/readme.md +378 -0
  301. package/package.json +66 -65
@@ -1,14 +1,20 @@
1
1
  import type { Result } from "../result/index.js";
2
2
  /**
3
- * @brief path segment.
3
+ * @brief One segment in a validation issue path.
4
+ * @details Strings represent object keys and numbers represent array indexes.
5
+ * The path formatter decides how those segments become user-facing text.
4
6
  */
5
7
  export type PathSegment = string | number;
6
8
  /**
7
- * @brief issue code.
9
+ * @brief Closed set of validation issue codes emitted by TypeSea.
10
+ * @details Codes are stable machine-readable diagnostics shared by interpreters,
11
+ * compiled collectors, adapters, and message catalogs.
8
12
  */
9
- export type IssueCode = "expected_string" | "expected_number" | "expected_bigint" | "expected_symbol" | "expected_boolean" | "expected_never" | "expected_literal" | "expected_array" | "expected_tuple" | "expected_tuple_length" | "expected_object" | "expected_record" | "expected_integer" | "expected_min_length" | "expected_max_length" | "expected_pattern" | "expected_gte" | "expected_lte" | "expected_required_key" | "expected_union" | "expected_discriminant" | "expected_refinement" | "expected_depth_limit" | "unrecognized_key";
13
+ export type IssueCode = "expected_string" | "expected_number" | "expected_date" | "expected_bigint" | "expected_symbol" | "expected_boolean" | "expected_never" | "expected_literal" | "expected_array" | "expected_map" | "expected_set" | "expected_instance" | "expected_tuple" | "expected_tuple_length" | "expected_object" | "expected_record" | "expected_integer" | "expected_min_length" | "expected_max_length" | "expected_pattern" | "expected_gte" | "expected_lte" | "expected_gt" | "expected_lt" | "expected_multiple_of" | "expected_required_key" | "expected_union" | "expected_discriminant" | "expected_refinement" | "expected_depth_limit" | "unrecognized_key";
10
14
  /**
11
- * @brief issue.
15
+ * @brief Immutable validation diagnostic.
16
+ * @details The message field is optional so hot boolean validation and
17
+ * low-level collectors can defer human-readable formatting until requested.
12
18
  */
13
19
  export interface Issue {
14
20
  readonly path: readonly PathSegment[];
@@ -18,27 +24,53 @@ export interface Issue {
18
24
  readonly message: string | undefined;
19
25
  }
20
26
  /**
21
- * @brief check result.
27
+ * @brief Result shape returned by diagnostic validation APIs.
28
+ * @details Success carries the accepted value, failure carries a frozen issue
29
+ * array suitable for message formatting or adapter conversion.
22
30
  */
23
31
  export type CheckResult<TValue> = Result<TValue, readonly Issue[]>;
24
32
  /**
25
- * @brief make issue.
33
+ * @brief Construct one issue record without freezing it.
34
+ * @details Collectors use this helper while building mutable arrays, then
35
+ * freeze the final array at the API boundary.
36
+ * @param path Path to the failing value.
37
+ * @param code Stable issue code.
38
+ * @param expected Expected-value label, when available.
39
+ * @param actual Actual-value label, when available.
40
+ * @param message Pre-rendered human message, when available.
41
+ * @returns Mutable issue record ready for collection.
26
42
  */
27
43
  export declare function makeIssue(path: readonly PathSegment[], code: IssueCode, expected: string | undefined, actual: string | undefined, message: string | undefined): Issue;
28
44
  /**
29
- * @brief copy issue array.
45
+ * @brief Defensive-copy externally supplied issue arrays before publication.
46
+ * @details Adapter and user callback boundaries may hand back mutable objects.
47
+ * Copying revalidates shape and ensures TypeSea publishes frozen diagnostics.
48
+ * @param value Candidate issue array.
49
+ * @returns Frozen issue array with copied paths.
30
50
  */
31
51
  export declare function copyIssueArray(value: unknown): readonly Issue[];
32
52
  /**
33
- * @brief finalize issue array.
53
+ * @brief Normalize generated collector output into the public immutable shape.
54
+ * @details Generated collectors return arrays only on failure. Empty arrays use
55
+ * the shared sentinel so failed-but-empty states cannot allocate repeatedly.
56
+ * @param value Candidate issue array from a collector.
57
+ * @returns Frozen public issue array.
34
58
  */
35
59
  export declare function finalizeIssueArray(value: unknown): readonly Issue[];
36
60
  /**
37
- * @brief freeze issue array.
61
+ * @brief Freeze issues and their path arrays in-place.
62
+ * @details Paths are built mutably for speed during collection, then hardened
63
+ * before callers can retain or format the diagnostics.
64
+ * @param issues Issue array to harden.
65
+ * @returns The same issue array after freezing.
38
66
  */
39
67
  export declare function freezeIssueArray(issues: readonly Issue[]): readonly Issue[];
40
68
  /**
41
- * @brief is issue code value.
69
+ * @brief Check whether a value is one of TypeSea's stable issue codes.
70
+ * @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
71
+ * validation results later.
72
+ * @param value Candidate issue code.
73
+ * @returns True when the value belongs to the closed issue-code set.
42
74
  */
43
75
  export declare function isIssueCodeValue(value: unknown): value is IssueCode;
44
76
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/issue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,uBAAuB,GACvB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,qBAAqB,GACrB,qBAAqB,GACrB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,uBAAuB,GACvB,gBAAgB,GAChB,uBAAuB,GACvB,qBAAqB,GACrB,sBAAsB,GACtB,kBAAkB,CAAC;AAEvB;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;AAOnE;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,KAAK,CAQP;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,KAAK,EAAE,CAS/D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,KAAK,EAAE,CAQnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,SAAS,KAAK,EAAE,CAS3E;AAkDD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CA8BnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/issue/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1C;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACf,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,cAAc,GACd,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,uBAAuB,GACvB,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,qBAAqB,GACrB,qBAAqB,GACrB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,aAAa,GACb,aAAa,GACb,sBAAsB,GACtB,uBAAuB,GACvB,gBAAgB,GAChB,uBAAuB,GACvB,qBAAqB,GACrB,sBAAsB,GACtB,kBAAkB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;AAUnE;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACrB,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC5B,KAAK,CAQP;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,KAAK,EAAE,CAS/D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,KAAK,EAAE,CAQnE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,SAAS,KAAK,EAAE,CAS3E;AA6DD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAkCnE"}
@@ -1,9 +1,20 @@
1
1
  /**
2
- * @brief empty issues.
2
+ * @brief Shared success sentinel for compiled check() paths.
3
+ * @details Reusing a frozen empty array avoids allocating diagnostics for
4
+ * successful validation.
3
5
  */
4
6
  const EMPTY_ISSUES = Object.freeze([]);
7
+ const EMPTY_PATH = Object.freeze([]);
5
8
  /**
6
- * @brief make issue.
9
+ * @brief Construct one issue record without freezing it.
10
+ * @details Collectors use this helper while building mutable arrays, then
11
+ * freeze the final array at the API boundary.
12
+ * @param path Path to the failing value.
13
+ * @param code Stable issue code.
14
+ * @param expected Expected-value label, when available.
15
+ * @param actual Actual-value label, when available.
16
+ * @param message Pre-rendered human message, when available.
17
+ * @returns Mutable issue record ready for collection.
7
18
  */
8
19
  export function makeIssue(path, code, expected, actual, message) {
9
20
  return {
@@ -15,7 +26,11 @@ export function makeIssue(path, code, expected, actual, message) {
15
26
  };
16
27
  }
17
28
  /**
18
- * @brief copy issue array.
29
+ * @brief Defensive-copy externally supplied issue arrays before publication.
30
+ * @details Adapter and user callback boundaries may hand back mutable objects.
31
+ * Copying revalidates shape and ensures TypeSea publishes frozen diagnostics.
32
+ * @param value Candidate issue array.
33
+ * @returns Frozen issue array with copied paths.
19
34
  */
20
35
  export function copyIssueArray(value) {
21
36
  if (!isUnknownArray(value)) {
@@ -28,7 +43,11 @@ export function copyIssueArray(value) {
28
43
  return freezeIssueArray(copied);
29
44
  }
30
45
  /**
31
- * @brief finalize issue array.
46
+ * @brief Normalize generated collector output into the public immutable shape.
47
+ * @details Generated collectors return arrays only on failure. Empty arrays use
48
+ * the shared sentinel so failed-but-empty states cannot allocate repeatedly.
49
+ * @param value Candidate issue array from a collector.
50
+ * @returns Frozen public issue array.
32
51
  */
33
52
  export function finalizeIssueArray(value) {
34
53
  if (!isUnknownArray(value)) {
@@ -40,7 +59,11 @@ export function finalizeIssueArray(value) {
40
59
  return copyIssueArray(value);
41
60
  }
42
61
  /**
43
- * @brief freeze issue array.
62
+ * @brief Freeze issues and their path arrays in-place.
63
+ * @details Paths are built mutably for speed during collection, then hardened
64
+ * before callers can retain or format the diagnostics.
65
+ * @param issues Issue array to harden.
66
+ * @returns The same issue array after freezing.
44
67
  */
45
68
  export function freezeIssueArray(issues) {
46
69
  for (let index = 0; index < issues.length; index += 1) {
@@ -53,7 +76,11 @@ export function freezeIssueArray(issues) {
53
76
  return Object.freeze(issues);
54
77
  }
55
78
  /**
56
- * @brief copy issue.
79
+ * @brief Copy and validate one issue-like object.
80
+ * @details Only own data read syntax is used here because the candidate object
81
+ * has already been reduced to a plain record by `isRecord`.
82
+ * @param value Candidate issue object.
83
+ * @returns Normalized mutable issue record.
57
84
  */
58
85
  function copyIssue(value) {
59
86
  if (!isRecord(value)) {
@@ -75,12 +102,19 @@ function copyIssue(value) {
75
102
  return makeIssue(path, code, expected, actual, message);
76
103
  }
77
104
  /**
78
- * @brief copy path.
105
+ * @brief Copy and validate an issue path.
106
+ * @details Negative and fractional numeric segments are rejected because TypeSea
107
+ * only emits non-negative array indexes.
108
+ * @param value Candidate path array.
109
+ * @returns Copied path, or the shared empty-path sentinel.
79
110
  */
80
111
  function copyPath(value) {
81
112
  if (!isUnknownArray(value)) {
82
113
  throw new TypeError("issue path must be an array");
83
114
  }
115
+ if (value.length === 0) {
116
+ return EMPTY_PATH;
117
+ }
84
118
  const copied = new Array(value.length);
85
119
  for (let index = 0; index < value.length; index += 1) {
86
120
  const segment = value[index];
@@ -99,12 +133,17 @@ function copyPath(value) {
99
133
  return copied;
100
134
  }
101
135
  /**
102
- * @brief is issue code value.
136
+ * @brief Check whether a value is one of TypeSea's stable issue codes.
137
+ * @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
138
+ * validation results later.
139
+ * @param value Candidate issue code.
140
+ * @returns True when the value belongs to the closed issue-code set.
103
141
  */
104
142
  export function isIssueCodeValue(value) {
105
143
  switch (value) {
106
144
  case "expected_string":
107
145
  case "expected_number":
146
+ case "expected_date":
108
147
  case "expected_bigint":
109
148
  case "expected_symbol":
110
149
  case "expected_boolean":
@@ -121,6 +160,9 @@ export function isIssueCodeValue(value) {
121
160
  case "expected_pattern":
122
161
  case "expected_gte":
123
162
  case "expected_lte":
163
+ case "expected_gt":
164
+ case "expected_lt":
165
+ case "expected_multiple_of":
124
166
  case "expected_required_key":
125
167
  case "expected_union":
126
168
  case "expected_discriminant":
@@ -133,19 +175,31 @@ export function isIssueCodeValue(value) {
133
175
  }
134
176
  }
135
177
  /**
136
- * @brief is optional string.
178
+ * @brief Accept optional text fields used by issue diagnostics.
179
+ * @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
180
+ * validation results later.
181
+ * @param value Candidate issue text field.
182
+ * @returns True for string values and undefined.
137
183
  */
138
184
  function isOptionalString(value) {
139
185
  return value === undefined || typeof value === "string";
140
186
  }
141
187
  /**
142
- * @brief is record.
188
+ * @brief Check whether a value can be read as an issue-like record.
189
+ * @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
190
+ * validation results later.
191
+ * @param value Candidate runtime value.
192
+ * @returns True for non-array object values.
143
193
  */
144
194
  function isRecord(value) {
145
195
  return typeof value === "object" && value !== null && !Array.isArray(value);
146
196
  }
147
197
  /**
148
- * @brief is unknown array.
198
+ * @brief Check whether a value is an array before indexed reads.
199
+ * @details Issue helpers publish frozen diagnostics so adapters and callers cannot mutate
200
+ * validation results later.
201
+ * @param value Candidate runtime value.
202
+ * @returns True when the value is an array.
149
203
  */
150
204
  function isUnknownArray(value) {
151
205
  return Array.isArray(value);
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @file emit-combinator.ts
3
3
  * @brief Combinator TypeSea schema to JSON Schema emitters.
4
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
5
+ * report a structured export issue.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import type { PathSegment } from "../issue/index.js";
@@ -8,21 +10,59 @@ import type { Schema } from "../schema/index.js";
8
10
  import type { JsonSchemaEmitter } from "./emit-types.js";
9
11
  import type { JsonSchema, JsonSchemaDialect, JsonSchemaExportIssue } from "./types.js";
10
12
  /**
11
- * @brief emit union.
13
+ * @brief Emit a TypeSea union as a JSON Schema `anyOf` list.
14
+ * @details Each branch is emitted with its index appended to the issue path so
15
+ * unsupported children can be reported precisely. A single failed child aborts
16
+ * the whole union because dropping a branch would make the exported schema
17
+ * stricter than the TypeSea validator.
18
+ * @param options Union option schemas in declaration order.
19
+ * @param path Mutable issue path stack owned by the export walk.
20
+ * @param issues Mutable export issue buffer.
21
+ * @param emitChild Recursive schema emitter callback.
22
+ * @param dialect Target JSON Schema dialect.
23
+ * @returns JSON Schema union, or undefined when a child cannot be emitted.
12
24
  */
13
25
  export declare function emitUnion(options: readonly Schema[], path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
14
26
  /**
15
- * @brief emit intersection.
27
+ * @brief Emit a TypeSea intersection as a JSON Schema `allOf` pair.
28
+ * @details Both sides must be representable. If either side fails, the exported
29
+ * schema would no longer model the same acceptance set, so the emitter reports
30
+ * the failed side and returns undefined.
31
+ * @param left Left intersection operand.
32
+ * @param right Right intersection operand.
33
+ * @param path Mutable issue path stack owned by the export walk.
34
+ * @param issues Mutable export issue buffer.
35
+ * @param emitChild Recursive schema emitter callback.
36
+ * @param dialect Target JSON Schema dialect.
37
+ * @returns JSON Schema intersection, or undefined when a side cannot be emitted.
16
38
  */
17
39
  export declare function emitIntersection(left: Schema, right: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
18
40
  /**
19
- * @brief emit discriminated union.
41
+ * @brief Emit a discriminated union through the general union exporter.
42
+ * @details JSON Schema output does not need TypeSea's dispatch table; it only
43
+ * needs the branch schemas. The discriminant proof has already been enforced at
44
+ * builder time, so preserving branch order is enough for diagnostics.
45
+ * @param cases Discriminated-union cases from the TypeSea schema.
46
+ * @param path Mutable issue path stack owned by the export walk.
47
+ * @param issues Mutable export issue buffer.
48
+ * @param emitChild Recursive schema emitter callback.
49
+ * @param dialect Target JSON Schema dialect.
50
+ * @returns JSON Schema union, or undefined when a child cannot be emitted.
20
51
  */
21
52
  export declare function emitDiscriminatedUnion(cases: Extract<Schema, {
22
53
  readonly tag: typeof SchemaTag.DiscriminatedUnion;
23
54
  }>["cases"], path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
24
55
  /**
25
- * @brief emit nullable.
56
+ * @brief Emit a nullable wrapper as an `anyOf` with `null`.
57
+ * @details The wrapped schema is emitted first so unsupported inner constructs
58
+ * are reported at a stable `nullable` path segment instead of silently widening
59
+ * to just null.
60
+ * @param inner Inner TypeSea schema.
61
+ * @param path Mutable issue path stack owned by the export walk.
62
+ * @param issues Mutable export issue buffer.
63
+ * @param emitChild Recursive schema emitter callback.
64
+ * @param dialect Target JSON Schema dialect.
65
+ * @returns Nullable JSON Schema, or undefined when the inner schema fails.
26
66
  */
27
67
  export declare function emitNullable(inner: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
28
68
  //# sourceMappingURL=emit-combinator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"emit-combinator.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-combinator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAyBxB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAuBxB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE;IACrB,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAA;CAClD,CAAC,CAAC,OAAO,CAAC,EACX,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CASxB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAiBxB"}
1
+ {"version":3,"file":"emit-combinator.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-combinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EACR,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACxB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACrB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAyBxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAuBxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE;IACnB,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,kBAAkB,CAAA;CACpD,CAAC,CAAC,OAAO,CAAC,EACX,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CASxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAiBxB"}
@@ -1,11 +1,23 @@
1
1
  /**
2
2
  * @file emit-combinator.ts
3
3
  * @brief Combinator TypeSea schema to JSON Schema emitters.
4
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
5
+ * report a structured export issue.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import { pushJsonSchemaIssue } from "./issue.js";
7
9
  /**
8
- * @brief emit union.
10
+ * @brief Emit a TypeSea union as a JSON Schema `anyOf` list.
11
+ * @details Each branch is emitted with its index appended to the issue path so
12
+ * unsupported children can be reported precisely. A single failed child aborts
13
+ * the whole union because dropping a branch would make the exported schema
14
+ * stricter than the TypeSea validator.
15
+ * @param options Union option schemas in declaration order.
16
+ * @param path Mutable issue path stack owned by the export walk.
17
+ * @param issues Mutable export issue buffer.
18
+ * @param emitChild Recursive schema emitter callback.
19
+ * @param dialect Target JSON Schema dialect.
20
+ * @returns JSON Schema union, or undefined when a child cannot be emitted.
9
21
  */
10
22
  export function emitUnion(options, path, issues, emitChild, dialect) {
11
23
  const emitted = new Array(options.length);
@@ -34,7 +46,17 @@ export function emitUnion(options, path, issues, emitChild, dialect) {
34
46
  };
35
47
  }
36
48
  /**
37
- * @brief emit intersection.
49
+ * @brief Emit a TypeSea intersection as a JSON Schema `allOf` pair.
50
+ * @details Both sides must be representable. If either side fails, the exported
51
+ * schema would no longer model the same acceptance set, so the emitter reports
52
+ * the failed side and returns undefined.
53
+ * @param left Left intersection operand.
54
+ * @param right Right intersection operand.
55
+ * @param path Mutable issue path stack owned by the export walk.
56
+ * @param issues Mutable export issue buffer.
57
+ * @param emitChild Recursive schema emitter callback.
58
+ * @param dialect Target JSON Schema dialect.
59
+ * @returns JSON Schema intersection, or undefined when a side cannot be emitted.
38
60
  */
39
61
  export function emitIntersection(left, right, path, issues, emitChild, dialect) {
40
62
  path.push("left");
@@ -61,7 +83,16 @@ export function emitIntersection(left, right, path, issues, emitChild, dialect)
61
83
  };
62
84
  }
63
85
  /**
64
- * @brief emit discriminated union.
86
+ * @brief Emit a discriminated union through the general union exporter.
87
+ * @details JSON Schema output does not need TypeSea's dispatch table; it only
88
+ * needs the branch schemas. The discriminant proof has already been enforced at
89
+ * builder time, so preserving branch order is enough for diagnostics.
90
+ * @param cases Discriminated-union cases from the TypeSea schema.
91
+ * @param path Mutable issue path stack owned by the export walk.
92
+ * @param issues Mutable export issue buffer.
93
+ * @param emitChild Recursive schema emitter callback.
94
+ * @param dialect Target JSON Schema dialect.
95
+ * @returns JSON Schema union, or undefined when a child cannot be emitted.
65
96
  */
66
97
  export function emitDiscriminatedUnion(cases, path, issues, emitChild, dialect) {
67
98
  const options = new Array(cases.length);
@@ -74,7 +105,16 @@ export function emitDiscriminatedUnion(cases, path, issues, emitChild, dialect)
74
105
  return emitUnion(options, path, issues, emitChild, dialect);
75
106
  }
76
107
  /**
77
- * @brief emit nullable.
108
+ * @brief Emit a nullable wrapper as an `anyOf` with `null`.
109
+ * @details The wrapped schema is emitted first so unsupported inner constructs
110
+ * are reported at a stable `nullable` path segment instead of silently widening
111
+ * to just null.
112
+ * @param inner Inner TypeSea schema.
113
+ * @param path Mutable issue path stack owned by the export walk.
114
+ * @param issues Mutable export issue buffer.
115
+ * @param emitChild Recursive schema emitter callback.
116
+ * @param dialect Target JSON Schema dialect.
117
+ * @returns Nullable JSON Schema, or undefined when the inner schema fails.
78
118
  */
79
119
  export function emitNullable(inner, path, issues, emitChild, dialect) {
80
120
  path.push("nullable");
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @file emit-composite.ts
3
3
  * @brief Container TypeSea schema to JSON Schema emitters.
4
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
5
+ * report a structured export issue.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import type { PathSegment } from "../issue/index.js";
@@ -9,18 +11,30 @@ import type { JsonSchemaEmitter } from "./emit-types.js";
9
11
  import type { JsonSchema, JsonSchemaDialect, JsonSchemaExportIssue } from "./types.js";
10
12
  /**
11
13
  * @brief emit array.
14
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
15
+ * report a structured export issue.
12
16
  */
13
- export declare function emitArray(item: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
17
+ export declare function emitArray(schema: Extract<Schema, {
18
+ readonly tag: typeof SchemaTag.Array;
19
+ }>, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
14
20
  /**
15
21
  * @brief emit tuple.
22
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
23
+ * report a structured export issue.
16
24
  */
17
- export declare function emitTuple(items: readonly Schema[], path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
25
+ export declare function emitTuple(schema: Extract<Schema, {
26
+ readonly tag: typeof SchemaTag.Tuple;
27
+ }>, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
18
28
  /**
19
29
  * @brief emit record.
30
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
31
+ * report a structured export issue.
20
32
  */
21
33
  export declare function emitRecord(value: Schema, path: PathSegment[], issues: JsonSchemaExportIssue[], emitChild: JsonSchemaEmitter, dialect: JsonSchemaDialect): JsonSchema | undefined;
22
34
  /**
23
35
  * @brief emit object.
36
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
37
+ * report a structured export issue.
24
38
  */
25
39
  export declare function emitObject(schema: Extract<Schema, {
26
40
  readonly tag: typeof SchemaTag.Object;
@@ -1 +1 @@
1
- {"version":3,"file":"emit-composite.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-composite.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,SAAS,EACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EACV,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAaxB;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAqCxB;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAaxB;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GACzB,UAAU,GAAG,SAAS,CAoCxB"}
1
+ {"version":3,"file":"emit-composite.d.ts","sourceRoot":"","sources":["../../src/json-schema/emit-composite.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIH,SAAS,EACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EACR,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EAExB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,KAAK,CAAA;CAAE,CAAC,EACjE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAkCxB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACrB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,KAAK,CAAA;CAAE,CAAC,EACjE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAyDxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAaxB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,qBAAqB,EAAE,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,iBAAiB,GAC3B,UAAU,GAAG,SAAS,CAgDxB"}
@@ -1,13 +1,18 @@
1
1
  /**
2
2
  * @file emit-composite.ts
3
3
  * @brief Container TypeSea schema to JSON Schema emitters.
4
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
5
+ * report a structured export issue.
4
6
  */
5
- import { ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
7
+ import { ArrayCheckTag, ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
6
8
  import { pushJsonSchemaIssue } from "./issue.js";
7
9
  /**
8
10
  * @brief emit array.
11
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
12
+ * report a structured export issue.
9
13
  */
10
- export function emitArray(item, path, issues, emitChild, dialect) {
14
+ export function emitArray(schema, path, issues, emitChild, dialect) {
15
+ const item = schema.item;
11
16
  path.push("items");
12
17
  const emitted = emitChild(item, path, issues, dialect);
13
18
  if (emitted === undefined) {
@@ -16,15 +21,38 @@ export function emitArray(item, path, issues, emitChild, dialect) {
16
21
  return undefined;
17
22
  }
18
23
  path.pop();
19
- return {
24
+ const result = {
20
25
  type: "array",
21
26
  items: emitted
22
27
  };
28
+ const checks = schema.checks;
29
+ for (let index = 0; index < checks.length; index += 1) {
30
+ const check = checks[index];
31
+ if (check === undefined) {
32
+ continue;
33
+ }
34
+ switch (check.tag) {
35
+ case ArrayCheckTag.Min:
36
+ result.minItems = result.minItems === undefined
37
+ ? check.value
38
+ : Math.max(result.minItems, check.value);
39
+ break;
40
+ case ArrayCheckTag.Max:
41
+ result.maxItems = result.maxItems === undefined
42
+ ? check.value
43
+ : Math.min(result.maxItems, check.value);
44
+ break;
45
+ }
46
+ }
47
+ return result;
23
48
  }
24
49
  /**
25
50
  * @brief emit tuple.
51
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
52
+ * report a structured export issue.
26
53
  */
27
- export function emitTuple(items, path, issues, emitChild, dialect) {
54
+ export function emitTuple(schema, path, issues, emitChild, dialect) {
55
+ const items = schema.items;
28
56
  const emitted = new Array(items.length);
29
57
  let failed = false;
30
58
  for (let index = 0; index < items.length; index += 1) {
@@ -46,24 +74,46 @@ export function emitTuple(items, path, issues, emitChild, dialect) {
46
74
  if (failed) {
47
75
  return undefined;
48
76
  }
77
+ let restSchema;
78
+ if (schema.rest !== undefined) {
79
+ path.push("rest");
80
+ restSchema = emitChild(schema.rest, path, issues, dialect);
81
+ if (restSchema === undefined) {
82
+ pushJsonSchemaIssue(path, issues, "unsupported_child", "Tuple rest schema is unsupported");
83
+ path.pop();
84
+ return undefined;
85
+ }
86
+ path.pop();
87
+ }
49
88
  if (dialect === "2020-12") {
50
- return {
89
+ const result = {
51
90
  type: "array",
52
91
  prefixItems: emitted,
53
- minItems: items.length,
54
- maxItems: items.length
92
+ minItems: items.length
55
93
  };
94
+ if (restSchema === undefined) {
95
+ result.maxItems = items.length;
96
+ }
97
+ else {
98
+ result.items = restSchema;
99
+ }
100
+ return result;
56
101
  }
57
- return {
102
+ const result = {
58
103
  type: "array",
59
104
  items: emitted,
60
- additionalItems: false,
61
- minItems: items.length,
62
- maxItems: items.length
105
+ additionalItems: restSchema ?? false,
106
+ minItems: items.length
63
107
  };
108
+ if (restSchema === undefined) {
109
+ result.maxItems = items.length;
110
+ }
111
+ return result;
64
112
  }
65
113
  /**
66
114
  * @brief emit record.
115
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
116
+ * report a structured export issue.
67
117
  */
68
118
  export function emitRecord(value, path, issues, emitChild, dialect) {
69
119
  path.push("additionalProperties");
@@ -81,6 +131,8 @@ export function emitRecord(value, path, issues, emitChild, dialect) {
81
131
  }
82
132
  /**
83
133
  * @brief emit object.
134
+ * @details JSON Schema helpers emit only representations that preserve TypeSea semantics or
135
+ * report a structured export issue.
84
136
  */
85
137
  export function emitObject(schema, path, issues, emitChild, dialect) {
86
138
  const properties = makeJsonSchemaProperties();
@@ -109,10 +161,22 @@ export function emitObject(schema, path, issues, emitChild, dialect) {
109
161
  if (failed) {
110
162
  return undefined;
111
163
  }
164
+ let additionalProperties = schema.mode !== ObjectModeTag.Strict;
165
+ if (schema.catchall !== undefined) {
166
+ path.push("additionalProperties");
167
+ const emittedCatchall = emitChild(schema.catchall, path, issues, dialect);
168
+ if (emittedCatchall === undefined) {
169
+ pushJsonSchemaIssue(path, issues, "unsupported_child", "Object catchall schema is unsupported");
170
+ path.pop();
171
+ return undefined;
172
+ }
173
+ path.pop();
174
+ additionalProperties = emittedCatchall;
175
+ }
112
176
  const result = {
113
177
  type: "object",
114
178
  properties,
115
- additionalProperties: schema.mode !== ObjectModeTag.Strict
179
+ additionalProperties
116
180
  };
117
181
  if (required.length !== 0) {
118
182
  result.required = required;
@@ -120,7 +184,11 @@ export function emitObject(schema, path, issues, emitChild, dialect) {
120
184
  return result;
121
185
  }
122
186
  /**
123
- * @brief make json schema properties.
187
+ * @brief Allocate the JSON Schema property table with no prototype chain.
188
+ * @details Object schema keys originate from user models. A null-prototype map
189
+ * prevents names such as `constructor` from colliding with inherited object
190
+ * members while keeping writes monomorphic for the emitter loop.
191
+ * @returns Empty mutable property table for an object schema emission pass.
124
192
  */
125
193
  function makeJsonSchemaProperties() {
126
194
  return Object.create(null);