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,29 +1,48 @@
1
1
  /**
2
2
  * @file read.ts
3
3
  * @brief Guard receiver and constructor validation.
4
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
5
+ * existing guard instance.
4
6
  */
5
7
  import { SchemaTag } from "../kind/index.js";
6
8
  import { freezeSchema, isSchemaValue } from "../schema/index.js";
7
9
  import { isRecord } from "./props.js";
8
10
  import { isConstructedGuard } from "./registry.js";
9
11
  /**
10
- * @brief read guard schema.
12
+ * @brief Read schema from a verified guard receiver.
13
+ * @details Constructed guards take the WeakSet fast path; forged structural
14
+ * guards must expose a valid own data schema before use. The fallback exists
15
+ * because public methods can be detached from their instance in JavaScript.
16
+ * @param guard Candidate receiver or guard-like value.
17
+ * @param label Human-readable label used in TypeError messages.
18
+ * @returns Valid runtime schema carried by the guard.
19
+ * @throws TypeError when the receiver is not a valid TypeSea guard.
11
20
  */
12
21
  export function readGuardSchema(guard, label) {
13
22
  if (isConstructedGuard(guard)) {
23
+ /*
24
+ * Constructed guards have already frozen their schema, so the registry
25
+ * path avoids repeating structural schema validation for normal calls.
26
+ */
14
27
  return guard.schema;
15
28
  }
16
29
  if (!isRecord(guard)) {
17
30
  throw new TypeError(`${label} must be a TypeSea guard`);
18
31
  }
19
- const schema = guard["schema"];
32
+ const schema = readOwnDataProperty(guard, "schema");
20
33
  if (!isSchemaValue(schema)) {
21
34
  throw new TypeError(`${label} must contain a valid TypeSea schema`);
22
35
  }
23
36
  return schema;
24
37
  }
25
38
  /**
26
- * @brief read string method schema.
39
+ * @brief Read and require a string schema from a method receiver.
40
+ * @param guard Candidate receiver.
41
+ * @param label Human-readable label used in TypeError messages.
42
+ * @returns String schema carried by the receiver.
43
+ * @throws TypeError when the receiver is not a string guard.
44
+ * @details StringGuard methods share this gate so subtype-specific helpers do
45
+ * not duplicate receiver validation or accept forged schemas.
27
46
  */
28
47
  export function readStringMethodSchema(guard, label) {
29
48
  if (isConstructedGuard(guard)) {
@@ -40,7 +59,13 @@ export function readStringMethodSchema(guard, label) {
40
59
  return schema;
41
60
  }
42
61
  /**
43
- * @brief read number method schema.
62
+ * @brief Read and require a number schema from a method receiver.
63
+ * @param guard Candidate receiver.
64
+ * @param label Human-readable label used in TypeError messages.
65
+ * @returns Number schema carried by the receiver.
66
+ * @throws TypeError when the receiver is not a number guard.
67
+ * @details NumberGuard methods must fail before reading numeric check vectors
68
+ * when a receiver is detached or structurally forged.
44
69
  */
45
70
  export function readNumberMethodSchema(guard, label) {
46
71
  if (isConstructedGuard(guard)) {
@@ -57,7 +82,56 @@ export function readNumberMethodSchema(guard, label) {
57
82
  return schema;
58
83
  }
59
84
  /**
60
- * @brief read constructor schema.
85
+ * @brief Read and require a Date schema from a method receiver.
86
+ * @param guard Candidate receiver.
87
+ * @param label Human-readable label used in TypeError messages.
88
+ * @returns Date schema carried by the receiver.
89
+ * @throws TypeError when the receiver is not a Date guard.
90
+ */
91
+ export function readDateMethodSchema(guard, label) {
92
+ if (isConstructedGuard(guard)) {
93
+ const schema = guard.schema;
94
+ if (schema.tag !== SchemaTag.Date) {
95
+ throw new TypeError(`${label} must be a date TypeSea guard`);
96
+ }
97
+ return schema;
98
+ }
99
+ const schema = readGuardSchema(guard, label);
100
+ if (schema.tag !== SchemaTag.Date) {
101
+ throw new TypeError(`${label} must be a date TypeSea guard`);
102
+ }
103
+ return schema;
104
+ }
105
+ /**
106
+ * @brief Read and require an array schema from a method receiver.
107
+ * @param guard Candidate receiver.
108
+ * @param label Human-readable label used in TypeError messages.
109
+ * @returns Array schema carried by the receiver.
110
+ * @throws TypeError when the receiver is not an array guard.
111
+ * @details ArrayGuard methods share this gate so fluent length helpers cannot
112
+ * be detached and applied to unrelated guard instances.
113
+ */
114
+ export function readArrayMethodSchema(guard, label) {
115
+ if (isConstructedGuard(guard)) {
116
+ const schema = guard.schema;
117
+ if (schema.tag !== SchemaTag.Array) {
118
+ throw new TypeError(`${label} must be an array TypeSea guard`);
119
+ }
120
+ return schema;
121
+ }
122
+ const schema = readGuardSchema(guard, label);
123
+ if (schema.tag !== SchemaTag.Array) {
124
+ throw new TypeError(`${label} must be an array TypeSea guard`);
125
+ }
126
+ return schema;
127
+ }
128
+ /**
129
+ * @brief Validate and freeze a generic guard constructor schema.
130
+ * @param schema Candidate runtime schema.
131
+ * @returns Frozen schema accepted by BaseGuard.
132
+ * @throws TypeError when the schema is malformed.
133
+ * @details Constructors are the only place that accepts mutable schema records.
134
+ * Freezing here lets normal method calls use the registry fast path later.
61
135
  */
62
136
  export function readConstructorSchema(schema) {
63
137
  if (!isSchemaValue(schema)) {
@@ -66,7 +140,12 @@ export function readConstructorSchema(schema) {
66
140
  return freezeSchema(schema);
67
141
  }
68
142
  /**
69
- * @brief read string constructor schema.
143
+ * @brief Validate a StringGuard constructor schema.
144
+ * @param schema Candidate runtime schema.
145
+ * @returns String schema accepted by StringGuard.
146
+ * @throws TypeError when the schema is not a string schema.
147
+ * @details Specialized guards keep their schema tag invariant at construction,
148
+ * so hot method calls only need to verify receiver identity.
70
149
  */
71
150
  export function readStringConstructorSchema(schema) {
72
151
  if (!isSchemaValue(schema) || schema.tag !== SchemaTag.String) {
@@ -75,7 +154,12 @@ export function readStringConstructorSchema(schema) {
75
154
  return schema;
76
155
  }
77
156
  /**
78
- * @brief read number constructor schema.
157
+ * @brief Validate a NumberGuard constructor schema.
158
+ * @param schema Candidate runtime schema.
159
+ * @returns Number schema accepted by NumberGuard.
160
+ * @throws TypeError when the schema is not a number schema.
161
+ * @details Rejecting non-number schemas at construction prevents mixed scalar
162
+ * helper methods from observing incompatible check vectors.
79
163
  */
80
164
  export function readNumberConstructorSchema(schema) {
81
165
  if (!isSchemaValue(schema) || schema.tag !== SchemaTag.Number) {
@@ -84,7 +168,38 @@ export function readNumberConstructorSchema(schema) {
84
168
  return schema;
85
169
  }
86
170
  /**
87
- * @brief check refinement input.
171
+ * @brief Validate a DateGuard constructor schema.
172
+ * @param schema Candidate runtime schema.
173
+ * @returns Date schema accepted by DateGuard.
174
+ * @throws TypeError when the schema is not a Date schema.
175
+ */
176
+ export function readDateConstructorSchema(schema) {
177
+ if (!isSchemaValue(schema) || schema.tag !== SchemaTag.Date) {
178
+ throw new TypeError("DateGuard constructor requires a date schema");
179
+ }
180
+ return schema;
181
+ }
182
+ /**
183
+ * @brief Validate an ArrayGuard constructor schema.
184
+ * @param schema Candidate runtime schema.
185
+ * @returns Array schema accepted by ArrayGuard.
186
+ * @throws TypeError when the schema is not an array schema.
187
+ * @details The schema validator already checks the item tree and length-check
188
+ * vector, so the specialized constructor only enforces the root tag.
189
+ */
190
+ export function readArrayConstructorSchema(schema) {
191
+ if (!isSchemaValue(schema) || schema.tag !== SchemaTag.Array) {
192
+ throw new TypeError("ArrayGuard constructor requires an array schema");
193
+ }
194
+ return schema;
195
+ }
196
+ /**
197
+ * @brief Validate refinement API inputs.
198
+ * @param predicate Candidate refinement predicate.
199
+ * @param name Candidate diagnostic name.
200
+ * @throws TypeError when either input has the wrong runtime type.
201
+ * @details Refinements execute user code by design. This gate narrows the call
202
+ * target and diagnostic label before the schema stores them.
88
203
  */
89
204
  export function checkRefinementInput(predicate, name) {
90
205
  if (typeof predicate !== "function") {
@@ -95,7 +210,13 @@ export function checkRefinementInput(predicate, name) {
95
210
  }
96
211
  }
97
212
  /**
98
- * @brief check string length bound.
213
+ * @brief Validate a non-negative string length bound.
214
+ * @param value Candidate bound.
215
+ * @param label Bound label used in RangeError messages.
216
+ * @returns The validated bound.
217
+ * @throws RangeError when the bound is negative or non-integer.
218
+ * @details Bounds are checked once at builder time so generated validators can
219
+ * emit straight comparisons without defensive range checks.
99
220
  */
100
221
  export function checkStringLengthBound(value, label) {
101
222
  if (!Number.isInteger(value) || value < 0) {
@@ -104,7 +225,28 @@ export function checkStringLengthBound(value, label) {
104
225
  return value;
105
226
  }
106
227
  /**
107
- * @brief check finite number bound.
228
+ * @brief Validate a non-negative array length bound.
229
+ * @param value Candidate bound.
230
+ * @param label Bound label used in RangeError messages.
231
+ * @returns The validated bound.
232
+ * @throws RangeError when the bound is negative or non-integer.
233
+ * @details Array bounds share the same integer contract as string length
234
+ * bounds, but the separate helper keeps public error text precise.
235
+ */
236
+ export function checkArrayLengthBound(value, label) {
237
+ if (!Number.isInteger(value) || value < 0) {
238
+ throw new RangeError(`${label} array length bound must be a non-negative integer`);
239
+ }
240
+ return value;
241
+ }
242
+ /**
243
+ * @brief Validate a finite numeric bound.
244
+ * @param value Candidate bound.
245
+ * @param label Bound label used in RangeError messages.
246
+ * @returns The validated bound.
247
+ * @throws RangeError when the bound is not finite.
248
+ * @details Finite bounds keep interpreter, plan, and emitted code semantics
249
+ * aligned for comparisons such as gte and lte.
108
250
  */
109
251
  export function checkFiniteNumberBound(value, label) {
110
252
  if (typeof value !== "number" || !Number.isFinite(value)) {
@@ -112,3 +254,36 @@ export function checkFiniteNumberBound(value, label) {
112
254
  }
113
255
  return value;
114
256
  }
257
+ /**
258
+ * @brief Normalize a Date bound into a finite epoch millisecond value.
259
+ * @param value Candidate Date bound.
260
+ * @param label Bound label used in RangeError messages.
261
+ * @returns Finite epoch millisecond value.
262
+ * @throws RangeError when the bound is not a valid Date instance.
263
+ */
264
+ export function checkDateBound(value, label) {
265
+ if (!(value instanceof Date)) {
266
+ throw new RangeError(`${label} date bound must be a Date`);
267
+ }
268
+ const time = Date.prototype.getTime.call(value);
269
+ if (!Number.isFinite(time)) {
270
+ throw new RangeError(`${label} date bound must be valid`);
271
+ }
272
+ return time;
273
+ }
274
+ /**
275
+ * @brief Read one own data slot from a structural guard receiver.
276
+ * @param value Candidate receiver.
277
+ * @param key Field name or symbol.
278
+ * @returns Stored field value, or undefined when the slot is absent.
279
+ * @details Structural guard support is intentionally narrow: inherited schema
280
+ * getters must not execute while validating detached method receivers.
281
+ */
282
+ function readOwnDataProperty(value, key) {
283
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
284
+ if (descriptor === undefined ||
285
+ !Object.prototype.hasOwnProperty.call(descriptor, "value")) {
286
+ return undefined;
287
+ }
288
+ return descriptor.value;
289
+ }
@@ -1,15 +1,25 @@
1
1
  /**
2
2
  * @file registry.ts
3
3
  * @brief Constructed guard receiver registry.
4
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
5
+ * existing guard instance.
4
6
  */
5
7
  import type { BaseGuard } from "./base.js";
6
8
  import type { Presence } from "./types.js";
7
9
  /**
8
- * @brief register constructed guard.
10
+ * @brief Mark a guard instance as constructor-owned.
11
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
12
+ * existing guard instance.
13
+ * @param value Guard instance created by TypeSea constructors.
14
+ * @post The value can use the fast receiver validation path.
9
15
  */
10
16
  export declare function registerConstructedGuard(value: object): void;
11
17
  /**
12
- * @brief is constructed guard.
18
+ * @brief Test whether a receiver was built by a TypeSea guard constructor.
19
+ * @param value Candidate receiver.
20
+ * @returns True when the value was registered by a TypeSea guard constructor.
21
+ * @details Public methods use this check to skip structural schema validation
22
+ * only for receivers whose schema slot was already frozen during construction.
13
23
  */
14
24
  export declare function isConstructedGuard(value: unknown): value is BaseGuard<unknown, Presence>;
15
25
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/guard/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3C;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAEvC"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/guard/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAU3C;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,OAAO,GACf,KAAK,IAAI,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAEvC"}
@@ -1,20 +1,32 @@
1
1
  /**
2
2
  * @file registry.ts
3
3
  * @brief Constructed guard receiver registry.
4
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
5
+ * existing guard instance.
4
6
  */
5
7
  import { isRecord } from "./props.js";
6
8
  /**
7
- * @brief constructed guards.
9
+ * @brief Receiver identity table for guards constructed by TypeSea.
10
+ * @details Weak membership proves that a receiver passed a TypeSea constructor
11
+ * without adding public marker fields that user code could forge.
8
12
  */
9
13
  const constructedGuards = new WeakSet();
10
14
  /**
11
- * @brief register constructed guard.
15
+ * @brief Mark a guard instance as constructor-owned.
16
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
17
+ * existing guard instance.
18
+ * @param value Guard instance created by TypeSea constructors.
19
+ * @post The value can use the fast receiver validation path.
12
20
  */
13
21
  export function registerConstructedGuard(value) {
14
22
  constructedGuards.add(value);
15
23
  }
16
24
  /**
17
- * @brief is constructed guard.
25
+ * @brief Test whether a receiver was built by a TypeSea guard constructor.
26
+ * @param value Candidate receiver.
27
+ * @returns True when the value was registered by a TypeSea guard constructor.
28
+ * @details Public methods use this check to skip structural schema validation
29
+ * only for receivers whose schema slot was already frozen during construction.
18
30
  */
19
31
  export function isConstructedGuard(value) {
20
32
  return isRecord(value) && constructedGuards.has(value);
@@ -1,36 +1,138 @@
1
1
  /**
2
2
  * @file string.ts
3
3
  * @brief String guard implementation.
4
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
5
+ * existing guard instance.
4
6
  */
7
+ import { type BaseDecoder } from "../decoder/index.js";
5
8
  import type { StringSchema } from "../schema/index.js";
6
9
  import { BaseGuard } from "./base.js";
7
10
  import type { Presence } from "./types.js";
8
11
  /**
9
- * @brief string guard.
10
- * @details Owns its state directly; methods expose receiver checks and explicit result flow.
11
- * @invariant Construction leaves the instance in a fully usable state before it escapes.
12
+ * @brief Persistent builder for string predicates.
13
+ * @details Refinement methods append schema checks and return fresh frozen
14
+ * guards, so shared guard values cannot be mutated by later chains.
12
15
  */
13
16
  export declare class StringGuard<TPresence extends Presence = "required"> extends BaseGuard<string, TPresence> {
14
17
  /**
15
- * @brief constructor.
16
- * @post The receiver is initialized according to the class invariant before it can be observed.
18
+ * @brief Construct a frozen string guard.
19
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
20
+ * existing guard instance.
21
+ * @param schema String schema backing this guard.
17
22
  */
18
23
  constructor(schema: StringSchema);
19
24
  /**
20
- * @brief min.
21
- */
25
+ * @brief Add a minimum string length.
26
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
27
+ * existing guard instance.
28
+ * @param value Non-negative integer lower length bound.
29
+ * @returns Fresh StringGuard with an appended min check.
30
+ */
22
31
  min(value: number): StringGuard<TPresence>;
23
32
  /**
24
- * @brief max.
25
- */
33
+ * @brief Add a maximum string length.
34
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
35
+ * existing guard instance.
36
+ * @param value Non-negative integer upper length bound.
37
+ * @returns Fresh StringGuard with an appended max check.
38
+ */
26
39
  max(value: number): StringGuard<TPresence>;
27
40
  /**
28
- * @brief regex.
29
- */
41
+ * @brief Require an exact string length.
42
+ * @param value Non-negative integer length.
43
+ * @returns Fresh StringGuard with matching min and max bounds.
44
+ */
45
+ length(value: number): StringGuard<TPresence>;
46
+ /**
47
+ * @brief Require a non-empty string.
48
+ * @returns Fresh StringGuard with `min(1)`.
49
+ */
50
+ nonempty(): StringGuard<TPresence>;
51
+ /**
52
+ * @brief Add a regular expression check.
53
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
54
+ * existing guard instance.
55
+ * @param pattern Plain RegExp instance to clone into the schema.
56
+ * @param name Diagnostic name for pattern failures.
57
+ * @returns Fresh StringGuard with an appended regex check.
58
+ */
30
59
  regex(pattern: RegExp, name: string): StringGuard<TPresence>;
31
60
  /**
32
- * @brief uuid.
33
- */
61
+ * @brief Require a fixed prefix.
62
+ * @param value Prefix string matched at offset zero.
63
+ * @returns Fresh StringGuard with an escaped prefix regex.
64
+ */
65
+ startsWith(value: string): StringGuard<TPresence>;
66
+ /**
67
+ * @brief Require a fixed suffix.
68
+ * @param value Suffix string matched at the end of the input.
69
+ * @returns Fresh StringGuard with an escaped suffix regex.
70
+ */
71
+ endsWith(value: string): StringGuard<TPresence>;
72
+ /**
73
+ * @brief Require a fixed substring.
74
+ * @param value Substring that must appear in the input.
75
+ * @returns Fresh StringGuard with an escaped substring regex.
76
+ */
77
+ includes(value: string): StringGuard<TPresence>;
78
+ /**
79
+ * @brief Add the built-in UUID string check.
80
+ * @details Guard helpers build new immutable schema wrappers so fluent APIs never mutate an
81
+ * existing guard instance.
82
+ * @returns Fresh StringGuard with an appended uuid check.
83
+ */
34
84
  uuid(): StringGuard<TPresence>;
85
+ /**
86
+ * @brief Add the built-in email string check.
87
+ * @returns Fresh StringGuard with an appended email check.
88
+ */
89
+ email(): StringGuard<TPresence>;
90
+ /**
91
+ * @brief Add the built-in URL string check.
92
+ * @returns Fresh StringGuard with an appended URL check.
93
+ * @details The check is a deterministic grammar subset rather than a
94
+ * throwing URL constructor call, so AOT and runtime validators agree.
95
+ */
96
+ url(): StringGuard<TPresence>;
97
+ /**
98
+ * @brief Add the built-in ISO date check.
99
+ * @returns Fresh StringGuard with an appended ISO date check.
100
+ */
101
+ isoDate(): StringGuard<TPresence>;
102
+ /**
103
+ * @brief Add the built-in ISO date-time check.
104
+ * @returns Fresh StringGuard with an appended ISO date-time check.
105
+ */
106
+ isoDateTime(): StringGuard<TPresence>;
107
+ /**
108
+ * @brief Add the built-in ULID string check.
109
+ * @returns Fresh StringGuard with an appended ULID check.
110
+ */
111
+ ulid(): StringGuard<TPresence>;
112
+ /**
113
+ * @brief Add the built-in IPv4 string check.
114
+ * @returns Fresh StringGuard with an appended IPv4 check.
115
+ */
116
+ ipv4(): StringGuard<TPresence>;
117
+ /**
118
+ * @brief Add the built-in IPv6 string check.
119
+ * @returns Fresh StringGuard with an appended IPv6 check.
120
+ */
121
+ ipv6(): StringGuard<TPresence>;
122
+ /**
123
+ * @brief Decode a string and trim surrounding whitespace.
124
+ * @returns Decoder that validates this string guard before trimming.
125
+ */
126
+ trim(): BaseDecoder<string>;
127
+ /**
128
+ * @brief Decode a string and lowercase it.
129
+ * @returns Decoder that validates this string guard before lowercasing.
130
+ */
131
+ toLowerCase(): BaseDecoder<string>;
132
+ /**
133
+ * @brief Decode a string and uppercase it.
134
+ * @returns Decoder that validates this string guard before uppercasing.
135
+ */
136
+ toUpperCase(): BaseDecoder<string>;
35
137
  }
36
138
  //# sourceMappingURL=string.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/guard/string.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAOtC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,qBAAa,WAAW,CACtB,SAAS,SAAS,QAAQ,GAAG,UAAU,CACvC,SAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;IAEpC;;;OAGG;gBACgB,MAAM,EAAE,YAAY;IAKvC;;aAES;IACF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAejD;;aAES;IACF,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAejD;;eAEW;IACJ,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAqBnE;;WAEO;IACA,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC;CAYtC"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/guard/string.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAOtC,OAAO,KAAK,EAAS,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,WAAW,CACpB,SAAS,SAAS,QAAQ,GAAG,UAAU,CACzC,SAAQ,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;IAElC;;;;;OAKG;gBACgB,MAAM,EAAE,YAAY;IAKvC;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAejD;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAejD;;;;OAIG;IACI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAKpD;;;OAGG;IACI,QAAQ,IAAI,WAAW,CAAC,SAAS,CAAC;IAIzC;;;;;;;OAOG;IACI,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAyBnE;;;;OAIG;IACI,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAOxD;;;;OAIG;IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAOtD;;;;OAIG;IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC;IAOtD;;;;;OAKG;IACI,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC;IAarC;;;OAGG;IACI,KAAK,IAAI,WAAW,CAAC,SAAS,CAAC;IAatC;;;;;OAKG;IACI,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC;IAapC;;;OAGG;IACI,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC;IAaxC;;;OAGG;IACI,WAAW,IAAI,WAAW,CAAC,SAAS,CAAC;IAa5C;;;OAGG;IACI,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC;IAarC;;;OAGG;IACI,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC;IAarC;;;OAGG;IACI,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC;IAarC;;;OAGG;IACI,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC;IAKlC;;;OAGG;IACI,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC;IAKzC;;;OAGG;IACI,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC;CAI5C"}