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,6 +1,8 @@
1
1
  /**
2
2
  * @file check-composite.ts
3
3
  * @brief Composite diagnostic schema interpreters.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import type { Issue, PathSegment } from "../issue/index.js";
@@ -8,32 +10,139 @@ import type { DiscriminatedUnionCase, Schema } from "../schema/index.js";
8
10
  import type { ValidationState } from "./state.js";
9
11
  /**
10
12
  * @brief issue collector.
13
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
14
+ * aligned with compiled behavior.
11
15
  */
12
16
  export type IssueCollector = (schema: Schema, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState) => void;
13
17
  /**
14
18
  * @brief collect array issues.
19
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
20
+ * aligned with compiled behavior.
21
+ * @param item Schema applied to each logical array slot.
22
+ * @param value Candidate value supplied by the caller.
23
+ * @param path Mutable path stack reused by the diagnostic walker.
24
+ * @param issues Output issue buffer.
25
+ * @param state Shared recursion and cycle state.
26
+ * @param collectChild Dispatcher for nested schema diagnostics.
27
+ * @post Every pushed path segment is popped before return.
15
28
  */
16
- export declare function collectArrayIssues(item: Schema, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
29
+ export declare function collectArrayIssues(schema: Extract<Schema, {
30
+ readonly tag: typeof SchemaTag.Array;
31
+ }>, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
17
32
  /**
18
33
  * @brief collect tuple issues.
34
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
35
+ * aligned with compiled behavior.
36
+ * @param items Tuple item schemas.
37
+ * @param value Candidate runtime value.
38
+ * @param path Mutable path stack reused by the diagnostic walker.
39
+ * @param issues Output issue buffer.
40
+ * @param state Shared recursion and cycle state.
41
+ * @param collectChild Dispatcher for nested schema diagnostics.
42
+ * @post Every pushed tuple index is popped before return.
19
43
  */
20
- export declare function collectTupleIssues(items: readonly Schema[], value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
44
+ export declare function collectTupleIssues(schema: Extract<Schema, {
45
+ readonly tag: typeof SchemaTag.Tuple;
46
+ }>, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
21
47
  /**
22
48
  * @brief collect record issues.
49
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
50
+ * aligned with compiled behavior.
51
+ * @param item Schema applied to each own enumerable record value.
52
+ * @param value Candidate runtime value.
53
+ * @param path Mutable path stack reused by the diagnostic walker.
54
+ * @param issues Output issue buffer.
55
+ * @param state Shared recursion and cycle state.
56
+ * @param collectChild Dispatcher for nested schema diagnostics.
57
+ * @post Every pushed record key is popped before return.
23
58
  */
24
59
  export declare function collectRecordIssues(item: Schema, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
60
+ /**
61
+ * @brief collect Map issues.
62
+ * @param schema Map schema with key and value validators.
63
+ * @param value Candidate runtime value.
64
+ * @param path Mutable diagnostic path stack.
65
+ * @param issues Output issue buffer.
66
+ * @param state Shared recursion and cycle state.
67
+ * @param collectChild Dispatcher for nested schema diagnostics.
68
+ */
69
+ export declare function collectMapIssues(schema: Extract<Schema, {
70
+ readonly tag: typeof SchemaTag.Map;
71
+ }>, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
72
+ /**
73
+ * @brief collect Set issues.
74
+ * @param schema Set schema with item validator.
75
+ * @param value Candidate runtime value.
76
+ * @param path Mutable diagnostic path stack.
77
+ * @param issues Output issue buffer.
78
+ * @param state Shared recursion and cycle state.
79
+ * @param collectChild Dispatcher for nested schema diagnostics.
80
+ */
81
+ export declare function collectSetIssues(schema: Extract<Schema, {
82
+ readonly tag: typeof SchemaTag.Set;
83
+ }>, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
84
+ /**
85
+ * @brief collect instanceOf issues.
86
+ * @param schema InstanceOf schema with constructor metadata.
87
+ * @param value Candidate runtime value.
88
+ * @param path Current diagnostic path.
89
+ * @param issues Output issue buffer.
90
+ */
91
+ export declare function collectInstanceOfIssues(schema: Extract<Schema, {
92
+ readonly tag: typeof SchemaTag.InstanceOf;
93
+ }>, value: unknown, path: PathSegment[], issues: Issue[]): void;
94
+ /**
95
+ * @brief collect property issues.
96
+ * @param schema Property schema with base and own data property validator.
97
+ * @param value Candidate runtime value.
98
+ * @param path Mutable diagnostic path stack.
99
+ * @param issues Output issue buffer.
100
+ * @param state Shared recursion and cycle state.
101
+ * @param collectChild Dispatcher for nested schema diagnostics.
102
+ */
103
+ export declare function collectPropertyIssues(schema: Extract<Schema, {
104
+ readonly tag: typeof SchemaTag.Property;
105
+ }>, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
25
106
  /**
26
107
  * @brief collect object issues.
108
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
109
+ * aligned with compiled behavior.
110
+ * @param schema Object schema with entries and object mode.
111
+ * @param value Candidate runtime value.
112
+ * @param path Mutable path stack reused by the diagnostic walker.
113
+ * @param issues Output issue buffer.
114
+ * @param state Shared recursion and cycle state.
115
+ * @param collectChild Dispatcher for nested schema diagnostics.
116
+ * @post Every pushed object key is popped before return.
27
117
  */
28
118
  export declare function collectObjectIssues(schema: Extract<Schema, {
29
119
  readonly tag: typeof SchemaTag.Object;
30
120
  }>, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
31
121
  /**
32
122
  * @brief collect discriminated union issues.
123
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
124
+ * aligned with compiled behavior.
125
+ * @param key Discriminant property key.
126
+ * @param cases Closed discriminated union cases.
127
+ * @param value Candidate runtime value.
128
+ * @param path Mutable path stack reused by the diagnostic walker.
129
+ * @param issues Output issue buffer.
130
+ * @param state Shared recursion and cycle state.
131
+ * @param collectChild Dispatcher for nested schema diagnostics.
33
132
  */
34
133
  export declare function collectDiscriminatedUnionIssues(key: string, cases: readonly DiscriminatedUnionCase[], value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
35
134
  /**
36
135
  * @brief collect refine issues.
136
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
137
+ * aligned with compiled behavior.
138
+ * @param inner Schema validated before the predicate runs.
139
+ * @param predicate User predicate that must return true.
140
+ * @param name Refinement name used in diagnostics.
141
+ * @param value Candidate runtime value.
142
+ * @param path Mutable path stack reused by the diagnostic walker.
143
+ * @param issues Output issue buffer.
144
+ * @param state Shared recursion and cycle state.
145
+ * @param collectChild Dispatcher for nested schema diagnostics.
37
146
  */
38
147
  export declare function collectRefineIssues(inner: Schema, predicate: (value: unknown) => boolean, name: string, value: unknown, path: PathSegment[], issues: Issue[], state: ValidationState, collectChild: IssueCollector): void;
39
148
  //# sourceMappingURL=check-composite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-composite.d.ts","sourceRoot":"","sources":["../../src/evaluate/check-composite.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,SAAS,EACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EACV,sBAAsB,EACtB,MAAM,EACP,MAAM,oBAAoB,CAAC;AAa5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,KACnB,IAAI,CAAC;AAEV;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,cAAc,GAC3B,IAAI,CAqBN;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,cAAc,GAC3B,IAAI,CAmCN;AAwBD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,cAAc,GAC3B,IAAI,CAoBN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,cAAc,GAC3B,IAAI,CA6CN;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,sBAAsB,EAAE,EACxC,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,cAAc,GAC3B,IAAI,CAuCN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,EACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,cAAc,GAC3B,IAAI,CAMN"}
1
+ {"version":3,"file":"check-composite.d.ts","sourceRoot":"","sources":["../../src/evaluate/check-composite.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,45 @@
1
1
  /**
2
2
  * @file check-composite.ts
3
3
  * @brief Composite diagnostic schema interpreters.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
5
- import { ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
7
+ import { ArrayCheckTag, ObjectModeTag, PresenceTag, SchemaTag } from "../kind/index.js";
8
+ import { schemaCanAcceptUndefined } from "../schema/index.js";
6
9
  import { pushIssue } from "./issue.js";
7
- import { actualType, findDiscriminatedUnionCase, hasObjectKey, isDataPropertyDescriptor, isPlainRecord, isStrictTrue, literalToExpected, readOwnDataProperty } from "./shared.js";
10
+ import { actualType, findDiscriminatedUnionCase, hasObjectKey, isArrayIndexKey, isDataPropertyDescriptor, isPlainRecord, isStrictTrue, literalToExpected, ordinaryHasInstance, readOwnDataProperty } from "./shared.js";
8
11
  /**
9
12
  * @brief collect array issues.
13
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
14
+ * aligned with compiled behavior.
15
+ * @param item Schema applied to each logical array slot.
16
+ * @param value Candidate value supplied by the caller.
17
+ * @param path Mutable path stack reused by the diagnostic walker.
18
+ * @param issues Output issue buffer.
19
+ * @param state Shared recursion and cycle state.
20
+ * @param collectChild Dispatcher for nested schema diagnostics.
21
+ * @post Every pushed path segment is popped before return.
10
22
  */
11
- export function collectArrayIssues(item, value, path, issues, state, collectChild) {
23
+ export function collectArrayIssues(schema, value, path, issues, state, collectChild) {
12
24
  if (!Array.isArray(value)) {
13
25
  pushIssue(path, issues, "expected_array", "array", actualType(value));
14
26
  return;
15
27
  }
28
+ collectArrayLengthIssues(schema, value, path, issues);
29
+ const item = schema.item;
30
+ if (schemaCanAcceptUndefined(item)) {
31
+ /*
32
+ * A sparse hole is observationally undefined for this item schema. Walking
33
+ * present descriptors keeps huge sparse inputs proportional to stored
34
+ * slots while preserving accessor rejection.
35
+ */
36
+ collectPresentArrayIssues(item, value, path, issues, state, collectChild);
37
+ return;
38
+ }
39
+ /*
40
+ * When undefined is not valid, each missing descriptor is a real validation
41
+ * failure. The length loop keeps diagnostics tied to the failing index.
42
+ */
16
43
  for (let index = 0; index < value.length; index += 1) {
17
44
  const itemProperty = readArrayIndexDataProperty(value, index);
18
45
  path.push(index);
@@ -25,18 +52,104 @@ export function collectArrayIssues(item, value, path, issues, state, collectChil
25
52
  path.pop();
26
53
  }
27
54
  }
55
+ /**
56
+ * @brief Collect array length diagnostics.
57
+ * @param schema Array schema with normalized checks.
58
+ * @param value Array already proven by the caller.
59
+ * @param path Current diagnostic path.
60
+ * @param issues Output issue buffer.
61
+ * @details Length checks are reported at the array path, not at an item index,
62
+ * because the failure describes the container domain itself.
63
+ */
64
+ function collectArrayLengthIssues(schema, value, path, issues) {
65
+ const checks = schema.checks;
66
+ for (let index = 0; index < checks.length; index += 1) {
67
+ const check = checks[index];
68
+ if (check === undefined) {
69
+ continue;
70
+ }
71
+ switch (check.tag) {
72
+ case ArrayCheckTag.Min:
73
+ if (value.length < check.value) {
74
+ pushIssue(path, issues, "expected_min_length", `length >= ${String(check.value)}`, `length ${String(value.length)}`);
75
+ }
76
+ break;
77
+ case ArrayCheckTag.Max:
78
+ if (value.length > check.value) {
79
+ pushIssue(path, issues, "expected_max_length", `length <= ${String(check.value)}`, `length ${String(value.length)}`);
80
+ }
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * @brief collect present array issues.
87
+ * @details Holes are equivalent to `undefined` when the item schema accepts it,
88
+ * so only actual own index slots need descriptor checks and child validation.
89
+ * @param item Schema applied to each present own index.
90
+ * @param value Array already proven by the caller.
91
+ * @param path Mutable path stack reused by the diagnostic walker.
92
+ * @param issues Output issue buffer.
93
+ * @param state Shared recursion and cycle state.
94
+ * @param collectChild Dispatcher for nested schema diagnostics.
95
+ * @post Non-index own properties are ignored to match normal array iteration.
96
+ */
97
+ function collectPresentArrayIssues(item, value, path, issues, state, collectChild) {
98
+ const keys = Object.getOwnPropertyNames(value);
99
+ for (let keyIndex = 0; keyIndex < keys.length; keyIndex += 1) {
100
+ const key = keys[keyIndex];
101
+ if (key === undefined || !isArrayIndexKey(key, value.length)) {
102
+ continue;
103
+ }
104
+ /*
105
+ * Descriptor lookup is still mandatory on present indexes. It blocks
106
+ * getter-backed slots without invoking user code during validation.
107
+ */
108
+ const itemProperty = readArrayKeyDataProperty(value, key);
109
+ if (itemProperty === undefined) {
110
+ continue;
111
+ }
112
+ const index = Number(key);
113
+ path.push(index);
114
+ if (itemProperty === null) {
115
+ pushIssue(path, issues, "expected_array", "data property", "accessor");
116
+ }
117
+ else {
118
+ collectChild(item, itemProperty.value, path, issues, state);
119
+ }
120
+ path.pop();
121
+ }
122
+ }
28
123
  /**
29
124
  * @brief collect tuple issues.
125
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
126
+ * aligned with compiled behavior.
127
+ * @param items Tuple item schemas.
128
+ * @param value Candidate runtime value.
129
+ * @param path Mutable path stack reused by the diagnostic walker.
130
+ * @param issues Output issue buffer.
131
+ * @param state Shared recursion and cycle state.
132
+ * @param collectChild Dispatcher for nested schema diagnostics.
133
+ * @post Every pushed tuple index is popped before return.
30
134
  */
31
- export function collectTupleIssues(items, value, path, issues, state, collectChild) {
135
+ export function collectTupleIssues(schema, value, path, issues, state, collectChild) {
32
136
  if (!Array.isArray(value)) {
33
137
  pushIssue(path, issues, "expected_tuple", "tuple", actualType(value));
34
138
  return;
35
139
  }
36
- if (value.length !== items.length) {
140
+ const items = schema.items;
141
+ const rest = schema.rest;
142
+ if (rest === undefined && value.length !== items.length) {
37
143
  pushIssue(path, issues, "expected_tuple_length", `length ${String(items.length)}`, `length ${String(value.length)}`);
38
144
  }
145
+ else if (rest !== undefined && value.length < items.length) {
146
+ pushIssue(path, issues, "expected_tuple_length", `length >= ${String(items.length)}`, `length ${String(value.length)}`);
147
+ }
39
148
  const count = value.length < items.length ? value.length : items.length;
149
+ /*
150
+ * Length mismatch is reported once, then overlapping indexes are still
151
+ * diagnosed so callers get useful nested errors for present slots.
152
+ */
40
153
  for (let index = 0; index < count; index += 1) {
41
154
  const item = items[index];
42
155
  if (item === undefined) {
@@ -52,14 +165,40 @@ export function collectTupleIssues(items, value, path, issues, state, collectChi
52
165
  }
53
166
  path.pop();
54
167
  }
168
+ if (rest !== undefined && value.length > items.length) {
169
+ for (let index = items.length; index < value.length; index += 1) {
170
+ const itemValue = readArrayIndexDataProperty(value, index);
171
+ path.push(index);
172
+ if (itemValue === null) {
173
+ pushIssue(path, issues, "expected_tuple", "data property", "accessor");
174
+ }
175
+ else {
176
+ collectChild(rest, itemValue === undefined ? undefined : itemValue.value, path, issues, state);
177
+ }
178
+ path.pop();
179
+ }
180
+ }
55
181
  }
56
182
  /**
57
- * @brief read array index data property.
183
+ * @brief Read one array index for diagnostic collection.
58
184
  * @details Reads an array element through its descriptor so validation does not execute getters.
185
+ * @param value Array being inspected.
186
+ * @param index Numeric array index.
59
187
  * @returns Data descriptor for elements, undefined for holes, and null for accessors.
60
188
  */
61
189
  function readArrayIndexDataProperty(value, index) {
62
- const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
190
+ return readArrayKeyDataProperty(value, String(index));
191
+ }
192
+ /**
193
+ * @brief Read one canonical array index key for diagnostic collection.
194
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
195
+ * aligned with compiled behavior.
196
+ * @param value Array being inspected.
197
+ * @param key Canonical array index key.
198
+ * @returns Data descriptor for elements, undefined for holes, and null for accessors.
199
+ */
200
+ function readArrayKeyDataProperty(value, key) {
201
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
63
202
  if (descriptor === undefined) {
64
203
  return undefined;
65
204
  }
@@ -70,6 +209,15 @@ function readArrayIndexDataProperty(value, index) {
70
209
  }
71
210
  /**
72
211
  * @brief collect record issues.
212
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
213
+ * aligned with compiled behavior.
214
+ * @param item Schema applied to each own enumerable record value.
215
+ * @param value Candidate runtime value.
216
+ * @param path Mutable path stack reused by the diagnostic walker.
217
+ * @param issues Output issue buffer.
218
+ * @param state Shared recursion and cycle state.
219
+ * @param collectChild Dispatcher for nested schema diagnostics.
220
+ * @post Every pushed record key is popped before return.
73
221
  */
74
222
  export function collectRecordIssues(item, value, path, issues, state, collectChild) {
75
223
  if (!isPlainRecord(value)) {
@@ -77,6 +225,10 @@ export function collectRecordIssues(item, value, path, issues, state, collectChi
77
225
  return;
78
226
  }
79
227
  const keys = Object.keys(value);
228
+ /*
229
+ * Records intentionally validate enumerable own string keys. Symbols and
230
+ * non-enumerable slots are outside record value semantics.
231
+ */
80
232
  for (let index = 0; index < keys.length; index += 1) {
81
233
  const key = keys[index];
82
234
  if (key === undefined) {
@@ -93,8 +245,118 @@ export function collectRecordIssues(item, value, path, issues, state, collectChi
93
245
  path.pop();
94
246
  }
95
247
  }
248
+ /**
249
+ * @brief collect Map issues.
250
+ * @param schema Map schema with key and value validators.
251
+ * @param value Candidate runtime value.
252
+ * @param path Mutable diagnostic path stack.
253
+ * @param issues Output issue buffer.
254
+ * @param state Shared recursion and cycle state.
255
+ * @param collectChild Dispatcher for nested schema diagnostics.
256
+ */
257
+ export function collectMapIssues(schema, value, path, issues, state, collectChild) {
258
+ if (!(value instanceof Map)) {
259
+ pushIssue(path, issues, "expected_map", "Map", actualType(value));
260
+ return;
261
+ }
262
+ const iterator = Map.prototype.entries.call(value);
263
+ let index = 0;
264
+ for (;;) {
265
+ const step = iterator.next();
266
+ if (step.done === true) {
267
+ return;
268
+ }
269
+ const pair = step.value;
270
+ path.push(index);
271
+ path.push("key");
272
+ collectChild(schema.key, pair[0], path, issues, state);
273
+ path.pop();
274
+ path.push("value");
275
+ collectChild(schema.value, pair[1], path, issues, state);
276
+ path.pop();
277
+ path.pop();
278
+ index += 1;
279
+ }
280
+ }
281
+ /**
282
+ * @brief collect Set issues.
283
+ * @param schema Set schema with item validator.
284
+ * @param value Candidate runtime value.
285
+ * @param path Mutable diagnostic path stack.
286
+ * @param issues Output issue buffer.
287
+ * @param state Shared recursion and cycle state.
288
+ * @param collectChild Dispatcher for nested schema diagnostics.
289
+ */
290
+ export function collectSetIssues(schema, value, path, issues, state, collectChild) {
291
+ if (!(value instanceof Set)) {
292
+ pushIssue(path, issues, "expected_set", "Set", actualType(value));
293
+ return;
294
+ }
295
+ const iterator = Set.prototype.values.call(value);
296
+ let index = 0;
297
+ for (;;) {
298
+ const step = iterator.next();
299
+ if (step.done === true) {
300
+ return;
301
+ }
302
+ path.push(index);
303
+ collectChild(schema.item, step.value, path, issues, state);
304
+ path.pop();
305
+ index += 1;
306
+ }
307
+ }
308
+ /**
309
+ * @brief collect instanceOf issues.
310
+ * @param schema InstanceOf schema with constructor metadata.
311
+ * @param value Candidate runtime value.
312
+ * @param path Current diagnostic path.
313
+ * @param issues Output issue buffer.
314
+ */
315
+ export function collectInstanceOfIssues(schema, value, path, issues) {
316
+ if (!ordinaryHasInstance(value, schema.constructor)) {
317
+ pushIssue(path, issues, "expected_instance", schema.name, actualType(value));
318
+ }
319
+ }
320
+ /**
321
+ * @brief collect property issues.
322
+ * @param schema Property schema with base and own data property validator.
323
+ * @param value Candidate runtime value.
324
+ * @param path Mutable diagnostic path stack.
325
+ * @param issues Output issue buffer.
326
+ * @param state Shared recursion and cycle state.
327
+ * @param collectChild Dispatcher for nested schema diagnostics.
328
+ */
329
+ export function collectPropertyIssues(schema, value, path, issues, state, collectChild) {
330
+ const before = issues.length;
331
+ collectChild(schema.base, value, path, issues, state);
332
+ if (issues.length !== before) {
333
+ return;
334
+ }
335
+ if (((typeof value !== "object" && typeof value !== "function") || value === null)) {
336
+ pushIssue(path, issues, "expected_object", "object with property", actualType(value));
337
+ return;
338
+ }
339
+ const descriptor = Object.getOwnPropertyDescriptor(value, schema.key);
340
+ path.push(schema.key);
341
+ if (descriptor === undefined || !isDataPropertyDescriptor(descriptor)) {
342
+ pushIssue(path, issues, "expected_object", "data property", "missing or accessor");
343
+ }
344
+ else {
345
+ collectChild(schema.value, descriptor.value, path, issues, state);
346
+ }
347
+ path.pop();
348
+ }
96
349
  /**
97
350
  * @brief collect object issues.
351
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
352
+ * aligned with compiled behavior.
353
+ * @param schema Object schema with entries and object mode.
354
+ * @param value Candidate runtime value.
355
+ * @param path Mutable path stack reused by the diagnostic walker.
356
+ * @param issues Output issue buffer.
357
+ * @param state Shared recursion and cycle state.
358
+ * @param collectChild Dispatcher for nested schema diagnostics.
359
+ * @post Every pushed object key is popped before return.
98
360
  */
99
361
  export function collectObjectIssues(schema, value, path, issues, state, collectChild) {
100
362
  if (!isPlainRecord(value)) {
@@ -113,6 +375,11 @@ export function collectObjectIssues(schema, value, path, issues, state, collectC
113
375
  if (property === undefined) {
114
376
  if (entry.presence === PresenceTag.Optional &&
115
377
  !Object.prototype.hasOwnProperty.call(record, entry.key)) {
378
+ /*
379
+ * Missing optional key is valid. An own accessor at the same key
380
+ * is not valid because readOwnDataProperty would have returned
381
+ * undefined while hasOwnProperty remains true.
382
+ */
116
383
  path.pop();
117
384
  continue;
118
385
  }
@@ -128,7 +395,14 @@ export function collectObjectIssues(schema, value, path, issues, state, collectC
128
395
  collectChild(entry.schema, property.value, path, issues, state);
129
396
  path.pop();
130
397
  }
131
- if (schema.mode === ObjectModeTag.Strict) {
398
+ if (schema.catchall !== undefined) {
399
+ collectObjectCatchallIssues(schema, record, path, issues, state, collectChild);
400
+ }
401
+ else if (schema.mode === ObjectModeTag.Strict) {
402
+ /*
403
+ * Strict objects reject symbol and non-enumerable extras as well, so
404
+ * Reflect.ownKeys is required instead of Object.keys.
405
+ */
132
406
  const keys = Reflect.ownKeys(record);
133
407
  for (let index = 0; index < keys.length; index += 1) {
134
408
  const key = keys[index];
@@ -141,8 +415,50 @@ export function collectObjectIssues(schema, value, path, issues, state, collectC
141
415
  }
142
416
  }
143
417
  }
418
+ /**
419
+ * @brief Collect issues for undeclared own object keys.
420
+ * @param schema Object schema carrying a catchall schema.
421
+ * @param record Runtime object already proven to be a plain record.
422
+ * @param path Mutable diagnostic path stack.
423
+ * @param issues Output issue buffer.
424
+ * @param state Shared recursion and cycle state.
425
+ * @param collectChild Dispatcher used for the catchall value schema.
426
+ */
427
+ function collectObjectCatchallIssues(schema, record, path, issues, state, collectChild) {
428
+ const catchall = schema.catchall;
429
+ if (catchall === undefined) {
430
+ return;
431
+ }
432
+ const keys = Reflect.ownKeys(record);
433
+ for (let index = 0; index < keys.length; index += 1) {
434
+ const key = keys[index];
435
+ if (key === undefined ||
436
+ (typeof key === "string" && hasObjectKey(schema.keyLookup, key))) {
437
+ continue;
438
+ }
439
+ const pathKey = typeof key === "string" ? key : String(key);
440
+ const descriptor = Object.getOwnPropertyDescriptor(record, key);
441
+ path.push(pathKey);
442
+ if (descriptor === undefined || !isDataPropertyDescriptor(descriptor)) {
443
+ pushIssue(path, issues, "expected_object", "data property", "accessor");
444
+ }
445
+ else {
446
+ collectChild(catchall, descriptor.value, path, issues, state);
447
+ }
448
+ path.pop();
449
+ }
450
+ }
144
451
  /**
145
452
  * @brief collect discriminated union issues.
453
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
454
+ * aligned with compiled behavior.
455
+ * @param key Discriminant property key.
456
+ * @param cases Closed discriminated union cases.
457
+ * @param value Candidate runtime value.
458
+ * @param path Mutable path stack reused by the diagnostic walker.
459
+ * @param issues Output issue buffer.
460
+ * @param state Shared recursion and cycle state.
461
+ * @param collectChild Dispatcher for nested schema diagnostics.
146
462
  */
147
463
  export function collectDiscriminatedUnionIssues(key, cases, value, path, issues, state, collectChild) {
148
464
  if (!isPlainRecord(value)) {
@@ -151,6 +467,10 @@ export function collectDiscriminatedUnionIssues(key, cases, value, path, issues,
151
467
  }
152
468
  const discriminantProperty = readOwnDataProperty(value, key);
153
469
  if (discriminantProperty === undefined) {
470
+ /*
471
+ * The discriminant must be an own data property. Prototype values and
472
+ * accessors are rejected before branch selection.
473
+ */
154
474
  path.push(key);
155
475
  pushIssue(path, issues, "expected_discriminant", "data property", "missing or accessor");
156
476
  path.pop();
@@ -174,11 +494,26 @@ export function collectDiscriminatedUnionIssues(key, cases, value, path, issues,
174
494
  }
175
495
  /**
176
496
  * @brief collect refine issues.
497
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
498
+ * aligned with compiled behavior.
499
+ * @param inner Schema validated before the predicate runs.
500
+ * @param predicate User predicate that must return true.
501
+ * @param name Refinement name used in diagnostics.
502
+ * @param value Candidate runtime value.
503
+ * @param path Mutable path stack reused by the diagnostic walker.
504
+ * @param issues Output issue buffer.
505
+ * @param state Shared recursion and cycle state.
506
+ * @param collectChild Dispatcher for nested schema diagnostics.
177
507
  */
178
508
  export function collectRefineIssues(inner, predicate, name, value, path, issues, state, collectChild) {
179
509
  const before = issues.length;
180
510
  collectChild(inner, value, path, issues, state);
181
511
  if (issues.length === before && !isStrictTrue(predicate(value))) {
512
+ /*
513
+ * Refinement predicates run only after the inner schema produced no new
514
+ * issues. That keeps structural failures more specific than predicate
515
+ * failures.
516
+ */
182
517
  pushIssue(path, issues, "expected_refinement", name, actualType(value));
183
518
  }
184
519
  }
@@ -1,18 +1,43 @@
1
1
  /**
2
2
  * @file check-scalar.ts
3
3
  * @brief Scalar diagnostic schema interpreters.
4
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
5
+ * aligned with compiled behavior.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import type { Issue, PathSegment } from "../issue/index.js";
7
9
  import { type Schema } from "../schema/index.js";
8
10
  /**
9
11
  * @brief collect string issues.
12
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
13
+ * aligned with compiled behavior.
14
+ * @param schema String schema with scalar checks.
15
+ * @param value Candidate runtime value.
16
+ * @param path Current diagnostic path.
17
+ * @param issues Output issue buffer.
18
+ * @post Pattern checks reset lastIndex before testing.
10
19
  */
11
20
  export declare function collectStringIssues(schema: Extract<Schema, {
12
21
  readonly tag: typeof SchemaTag.String;
13
22
  }>, value: unknown, path: PathSegment[], issues: Issue[]): void;
23
+ /**
24
+ * @brief Collect Date issues.
25
+ * @param value Candidate runtime value.
26
+ * @param path Current diagnostic path.
27
+ * @param issues Output issue buffer.
28
+ */
29
+ export declare function collectDateIssues(schema: Extract<Schema, {
30
+ readonly tag: typeof SchemaTag.Date;
31
+ }>, value: unknown, path: PathSegment[], issues: Issue[]): void;
14
32
  /**
15
33
  * @brief collect number issues.
34
+ * @details Interpreter helpers keep safe descriptor-based reads and diagnostic collection
35
+ * aligned with compiled behavior.
36
+ * @param schema Number schema with scalar checks.
37
+ * @param value Candidate runtime value.
38
+ * @param path Current diagnostic path.
39
+ * @param issues Output issue buffer.
40
+ * @post Bound checks run only after the finite-number guard succeeds.
16
41
  */
17
42
  export declare function collectNumberIssues(schema: Extract<Schema, {
18
43
  readonly tag: typeof SchemaTag.Number;
@@ -1 +1 @@
1
- {"version":3,"file":"check-scalar.d.ts","sourceRoot":"","sources":["../../src/evaluate/check-scalar.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,SAAS,EAEV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAEL,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAI5B;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,GACd,IAAI,CAgDN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,GACd,IAAI,CAyCN"}
1
+ {"version":3,"file":"check-scalar.d.ts","sourceRoot":"","sources":["../../src/evaluate/check-scalar.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGH,SAAS,EAEZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EASH,KAAK,MAAM,EACd,MAAM,oBAAoB,CAAC;AAQ5B;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,GAChB,IAAI,CAsGN;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,IAAI,CAAA;CAAE,CAAC,EAChE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,GAChB,IAAI,CAqCN;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,SAAS,CAAC,MAAM,CAAA;CAAE,CAAC,EAClE,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,WAAW,EAAE,EACnB,MAAM,EAAE,KAAK,EAAE,GAChB,IAAI,CA8EN"}