@versionzero/schema 1.0.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 (401) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +246 -0
  3. package/package.json +84 -0
  4. package/src/compilation/handler-compilation.js +28 -0
  5. package/src/compilation/metadata-compilation.js +35 -0
  6. package/src/compilation/schema-compilation.js +142 -0
  7. package/src/compilation/selection-compilation.js +84 -0
  8. package/src/compilation/union-compilation.js +510 -0
  9. package/src/compilation/values-compilation.js +35 -0
  10. package/src/compiled-schema.js +1709 -0
  11. package/src/constants.js +1 -0
  12. package/src/core-library/index.js +32 -0
  13. package/src/core-library/processors/aggregation-operators.js +75 -0
  14. package/src/core-library/processors/alpha-constraint.js +20 -0
  15. package/src/core-library/processors/alphanum-constraint.js +20 -0
  16. package/src/core-library/processors/array-operator.js +51 -0
  17. package/src/core-library/processors/assert-constraint.js +75 -0
  18. package/src/core-library/processors/base64-constraint.js +26 -0
  19. package/src/core-library/processors/camel-case-operator.js +24 -0
  20. package/src/core-library/processors/capitalize-operator.js +16 -0
  21. package/src/core-library/processors/cardnum-constraint.js +193 -0
  22. package/src/core-library/processors/ceil-operator.js +44 -0
  23. package/src/core-library/processors/collapse-operator.js +29 -0
  24. package/src/core-library/processors/compact-operator.js +34 -0
  25. package/src/core-library/processors/compile-operator.js +65 -0
  26. package/src/core-library/processors/concat-operator.js +51 -0
  27. package/src/core-library/processors/conditional-operators.js +301 -0
  28. package/src/core-library/processors/constant-case-operator.js +16 -0
  29. package/src/core-library/processors/data-size-operator.js +86 -0
  30. package/src/core-library/processors/date-object-operator.js +54 -0
  31. package/src/core-library/processors/date-operator.js +67 -0
  32. package/src/core-library/processors/date-range-constraint.js +76 -0
  33. package/src/core-library/processors/defined-constraint.js +30 -0
  34. package/src/core-library/processors/each-operator.js +57 -0
  35. package/src/core-library/processors/email-constraint.js +112 -0
  36. package/src/core-library/processors/entries-operator.js +25 -0
  37. package/src/core-library/processors/eq-constraint.js +37 -0
  38. package/src/core-library/processors/filter-operator.js +74 -0
  39. package/src/core-library/processors/find-schema-operator.js +45 -0
  40. package/src/core-library/processors/flatten-operator.js +40 -0
  41. package/src/core-library/processors/floor-operator.js +47 -0
  42. package/src/core-library/processors/get-operator.js +44 -0
  43. package/src/core-library/processors/group-by-operator.js +84 -0
  44. package/src/core-library/processors/has-prefix-constraint.js +37 -0
  45. package/src/core-library/processors/has-suffix-constraint.js +35 -0
  46. package/src/core-library/processors/hex-constraint.js +20 -0
  47. package/src/core-library/processors/hostname-constraint.js +22 -0
  48. package/src/core-library/processors/http-url-constraint.js +27 -0
  49. package/src/core-library/processors/in-constraint.js +66 -0
  50. package/src/core-library/processors/index-by-operator.js +98 -0
  51. package/src/core-library/processors/index.js +131 -0
  52. package/src/core-library/processors/input-operator.js +23 -0
  53. package/src/core-library/processors/instanceof-constraint.js +38 -0
  54. package/src/core-library/processors/integer-constraint.js +22 -0
  55. package/src/core-library/processors/invoke-operator.js +33 -0
  56. package/src/core-library/processors/ipv4-constraint.js +188 -0
  57. package/src/core-library/processors/ipv6-constraint.js +205 -0
  58. package/src/core-library/processors/is-array-constraint.js +21 -0
  59. package/src/core-library/processors/is-date-constraint.js +22 -0
  60. package/src/core-library/processors/is-number-constraint.js +21 -0
  61. package/src/core-library/processors/is-object-constraint.js +21 -0
  62. package/src/core-library/processors/is-string-constraint.js +21 -0
  63. package/src/core-library/processors/join-operator.js +41 -0
  64. package/src/core-library/processors/json-constraint.js +22 -0
  65. package/src/core-library/processors/json-decode-operator.js +25 -0
  66. package/src/core-library/processors/json-encode-operator.js +35 -0
  67. package/src/core-library/processors/kebab-case-operator.js +23 -0
  68. package/src/core-library/processors/keys-operator.js +20 -0
  69. package/src/core-library/processors/length-constraint.js +85 -0
  70. package/src/core-library/processors/lookup-operator.js +84 -0
  71. package/src/core-library/processors/lowercase-operator.js +14 -0
  72. package/src/core-library/processors/map-operator.js +84 -0
  73. package/src/core-library/processors/match-operator.js +64 -0
  74. package/src/core-library/processors/matches-constraint.js +54 -0
  75. package/src/core-library/processors/math-operators.js +151 -0
  76. package/src/core-library/processors/merge-deep-operator.js +61 -0
  77. package/src/core-library/processors/merge-operator.js +54 -0
  78. package/src/core-library/processors/metadata-operator.js +100 -0
  79. package/src/core-library/processors/negative-constraint.js +23 -0
  80. package/src/core-library/processors/never-constraint.js +69 -0
  81. package/src/core-library/processors/non-empty-constraint.js +59 -0
  82. package/src/core-library/processors/not-constraint.js +71 -0
  83. package/src/core-library/processors/number-operator.js +24 -0
  84. package/src/core-library/processors/numeric-constraint.js +22 -0
  85. package/src/core-library/processors/object-operator.js +38 -0
  86. package/src/core-library/processors/omit-operator.js +57 -0
  87. package/src/core-library/processors/parallel-operator.js +64 -0
  88. package/src/core-library/processors/pascal-case-operator.js +16 -0
  89. package/src/core-library/processors/phone-constraint.js +235 -0
  90. package/src/core-library/processors/pick-operator.js +62 -0
  91. package/src/core-library/processors/pipeline-operator.js +63 -0
  92. package/src/core-library/processors/port-constraint.js +22 -0
  93. package/src/core-library/processors/positive-constraint.js +23 -0
  94. package/src/core-library/processors/process-operator.js +55 -0
  95. package/src/core-library/processors/property-operator.js +49 -0
  96. package/src/core-library/processors/range-constraint.js +72 -0
  97. package/src/core-library/processors/reference-operator.js +79 -0
  98. package/src/core-library/processors/require-constraint.js +74 -0
  99. package/src/core-library/processors/reverse-operator.js +20 -0
  100. package/src/core-library/processors/round-operator.js +53 -0
  101. package/src/core-library/processors/schema-handler-operators.js +54 -0
  102. package/src/core-library/processors/semver-constraint.js +282 -0
  103. package/src/core-library/processors/sequence-processors.js +406 -0
  104. package/src/core-library/processors/sort-operator.js +52 -0
  105. package/src/core-library/processors/split-operator.js +43 -0
  106. package/src/core-library/processors/string-extra-operators.js +141 -0
  107. package/src/core-library/processors/string-operator.js +34 -0
  108. package/src/core-library/processors/target-operator.js +30 -0
  109. package/src/core-library/processors/template-operator.js +60 -0
  110. package/src/core-library/processors/title-case-operator.js +17 -0
  111. package/src/core-library/processors/trim-operator.js +14 -0
  112. package/src/core-library/processors/truthy-constraint.js +35 -0
  113. package/src/core-library/processors/type-operator.js +24 -0
  114. package/src/core-library/processors/unique-operator.js +21 -0
  115. package/src/core-library/processors/uppercase-operator.js +14 -0
  116. package/src/core-library/processors/url-constraint.js +31 -0
  117. package/src/core-library/processors/url-decode-operator.js +50 -0
  118. package/src/core-library/processors/url-encode-operator.js +44 -0
  119. package/src/core-library/processors/uuid-constraint.js +31 -0
  120. package/src/core-library/processors/values-operator.js +20 -0
  121. package/src/core-library/schemas/any-schema.js +23 -0
  122. package/src/core-library/schemas/array-schema.js +8 -0
  123. package/src/core-library/schemas/boolean-schema.js +10 -0
  124. package/src/core-library/schemas/date-schema.js +12 -0
  125. package/src/core-library/schemas/function-schema.js +40 -0
  126. package/src/core-library/schemas/number-schema.js +9 -0
  127. package/src/core-library/schemas/object-schema.js +10 -0
  128. package/src/core-library/schemas/root-schema.js +21 -0
  129. package/src/core-library/schemas/string-schema.js +9 -0
  130. package/src/core-library-node/index.js +47 -0
  131. package/src/core-library-node/processors/base64-decode-operator.js +20 -0
  132. package/src/core-library-node/processors/base64-encode-operator.js +20 -0
  133. package/src/core-library-node/processors/buffer-operator.js +39 -0
  134. package/src/core-library-node/processors/directory-constraint.js +35 -0
  135. package/src/core-library-node/processors/executable-constraint.js +34 -0
  136. package/src/core-library-node/processors/file-constraint.js +34 -0
  137. package/src/core-library-node/processors/file-size-constraint.js +94 -0
  138. package/src/core-library-node/processors/is-buffer-constraint.js +21 -0
  139. package/src/core-library-node/processors/reachable-constraint.js +28 -0
  140. package/src/core-library-node/processors/readable-constraint.js +34 -0
  141. package/src/core-library-node/processors/writable-constraint.js +59 -0
  142. package/src/core-library-node/schemas/buffer-schema.js +10 -0
  143. package/src/errors.js +209 -0
  144. package/src/executor/array-executor.js +78 -0
  145. package/src/executor/conditional-executor.js +134 -0
  146. package/src/executor/each-executor.js +68 -0
  147. package/src/executor/executor.js +123 -0
  148. package/src/executor/object-executor.js +98 -0
  149. package/src/executor/parallel-executor.js +43 -0
  150. package/src/executor/pipeline-executor.js +65 -0
  151. package/src/executor/sequence-executor.js +206 -0
  152. package/src/executor/serial-executor.js +24 -0
  153. package/src/executor/step-executor.js +68 -0
  154. package/src/helpers/case.js +124 -0
  155. package/src/helpers/data-size.js +144 -0
  156. package/src/helpers/debug-sink.js +15 -0
  157. package/src/helpers/deep.js +280 -0
  158. package/src/helpers/format.js +121 -0
  159. package/src/helpers/has-string-properties.js +30 -0
  160. package/src/helpers/index.js +16 -0
  161. package/src/helpers/object.js +115 -0
  162. package/src/helpers/parse-date.js +75 -0
  163. package/src/helpers/path.js +28 -0
  164. package/src/helpers/regex.js +18 -0
  165. package/src/helpers/stringify.js +309 -0
  166. package/src/helpers/to-data.js +64 -0
  167. package/src/helpers/truthy.js +55 -0
  168. package/src/index.js +29 -0
  169. package/src/schema-compiler.js +531 -0
  170. package/src/schema-location.js +200 -0
  171. package/src/schema-resolver.js +546 -0
  172. package/src/schema.js +1182 -0
  173. package/src/traversal/executors/check-condition.js +42 -0
  174. package/src/traversal/executors/check-input.js +27 -0
  175. package/src/traversal/executors/check-required.js +19 -0
  176. package/src/traversal/executors/check-schema.js +45 -0
  177. package/src/traversal/executors/defaults.js +21 -0
  178. package/src/traversal/executors/enter-existing.js +25 -0
  179. package/src/traversal/executors/enter-input.js +25 -0
  180. package/src/traversal/executors/enter.js +37 -0
  181. package/src/traversal/executors/exit.js +74 -0
  182. package/src/traversal/executors/finalize.js +64 -0
  183. package/src/traversal/executors/index.js +42 -0
  184. package/src/traversal/executors/normalize.js +38 -0
  185. package/src/traversal/executors/prepare-existing.js +27 -0
  186. package/src/traversal/executors/prepare-pending.js +54 -0
  187. package/src/traversal/executors/resolve-union.js +50 -0
  188. package/src/traversal/executors/serialize.js +48 -0
  189. package/src/traversal/executors/transform-early.js +51 -0
  190. package/src/traversal/executors/transform.js +68 -0
  191. package/src/traversal/executors/traversal-state-executor.js +46 -0
  192. package/src/traversal/executors/validate.js +63 -0
  193. package/src/traversal/traversal-context.js +231 -0
  194. package/src/traversal/traversal-state.js +809 -0
  195. package/src/types.js +102 -0
  196. package/src/value-processor/composed-value-processor.js +43 -0
  197. package/src/value-processor/defined-value-processor.js +72 -0
  198. package/src/value-processor/function-value-processor.js +68 -0
  199. package/src/value-processor/parameterized-value-processor.js +45 -0
  200. package/src/value-processor/parameters-value-processor.js +178 -0
  201. package/src/value-processor/spec.js +89 -0
  202. package/src/value-processor/value-processor.js +105 -0
  203. package/types/compilation/handler-compilation.d.ts +13 -0
  204. package/types/compilation/metadata-compilation.d.ts +6 -0
  205. package/types/compilation/schema-compilation.d.ts +32 -0
  206. package/types/compilation/selection-compilation.d.ts +9 -0
  207. package/types/compilation/union-compilation.d.ts +42 -0
  208. package/types/compilation/values-compilation.d.ts +12 -0
  209. package/types/compiled-schema.d.ts +883 -0
  210. package/types/constants.d.ts +1 -0
  211. package/types/core-library/index.d.ts +7 -0
  212. package/types/core-library/processors/aggregation-operators.d.ts +24 -0
  213. package/types/core-library/processors/alpha-constraint.d.ts +9 -0
  214. package/types/core-library/processors/alphanum-constraint.d.ts +9 -0
  215. package/types/core-library/processors/array-operator.d.ts +12 -0
  216. package/types/core-library/processors/assert-constraint.d.ts +30 -0
  217. package/types/core-library/processors/base64-constraint.d.ts +11 -0
  218. package/types/core-library/processors/camel-case-operator.d.ts +17 -0
  219. package/types/core-library/processors/capitalize-operator.d.ts +11 -0
  220. package/types/core-library/processors/cardnum-constraint.d.ts +51 -0
  221. package/types/core-library/processors/ceil-operator.d.ts +30 -0
  222. package/types/core-library/processors/collapse-operator.d.ts +24 -0
  223. package/types/core-library/processors/compact-operator.d.ts +29 -0
  224. package/types/core-library/processors/compile-operator.d.ts +34 -0
  225. package/types/core-library/processors/concat-operator.d.ts +23 -0
  226. package/types/core-library/processors/conditional-operators.d.ts +219 -0
  227. package/types/core-library/processors/constant-case-operator.d.ts +9 -0
  228. package/types/core-library/processors/data-size-operator.d.ts +31 -0
  229. package/types/core-library/processors/date-object-operator.d.ts +16 -0
  230. package/types/core-library/processors/date-operator.d.ts +21 -0
  231. package/types/core-library/processors/date-range-constraint.d.ts +26 -0
  232. package/types/core-library/processors/defined-constraint.d.ts +20 -0
  233. package/types/core-library/processors/each-operator.d.ts +34 -0
  234. package/types/core-library/processors/email-constraint.d.ts +54 -0
  235. package/types/core-library/processors/entries-operator.d.ts +13 -0
  236. package/types/core-library/processors/eq-constraint.d.ts +20 -0
  237. package/types/core-library/processors/filter-operator.d.ts +35 -0
  238. package/types/core-library/processors/find-schema-operator.d.ts +28 -0
  239. package/types/core-library/processors/flatten-operator.d.ts +26 -0
  240. package/types/core-library/processors/floor-operator.d.ts +33 -0
  241. package/types/core-library/processors/get-operator.d.ts +31 -0
  242. package/types/core-library/processors/group-by-operator.d.ts +36 -0
  243. package/types/core-library/processors/has-prefix-constraint.d.ts +22 -0
  244. package/types/core-library/processors/has-suffix-constraint.d.ts +20 -0
  245. package/types/core-library/processors/hex-constraint.d.ts +9 -0
  246. package/types/core-library/processors/hostname-constraint.d.ts +11 -0
  247. package/types/core-library/processors/http-url-constraint.d.ts +9 -0
  248. package/types/core-library/processors/in-constraint.d.ts +27 -0
  249. package/types/core-library/processors/index-by-operator.d.ts +26 -0
  250. package/types/core-library/processors/index.d.ts +8 -0
  251. package/types/core-library/processors/input-operator.d.ts +20 -0
  252. package/types/core-library/processors/instanceof-constraint.d.ts +23 -0
  253. package/types/core-library/processors/integer-constraint.d.ts +9 -0
  254. package/types/core-library/processors/invoke-operator.d.ts +12 -0
  255. package/types/core-library/processors/ipv4-constraint.d.ts +37 -0
  256. package/types/core-library/processors/ipv6-constraint.d.ts +34 -0
  257. package/types/core-library/processors/is-array-constraint.d.ts +10 -0
  258. package/types/core-library/processors/is-date-constraint.d.ts +10 -0
  259. package/types/core-library/processors/is-number-constraint.d.ts +10 -0
  260. package/types/core-library/processors/is-object-constraint.d.ts +10 -0
  261. package/types/core-library/processors/is-string-constraint.d.ts +10 -0
  262. package/types/core-library/processors/join-operator.d.ts +29 -0
  263. package/types/core-library/processors/json-constraint.d.ts +10 -0
  264. package/types/core-library/processors/json-decode-operator.d.ts +9 -0
  265. package/types/core-library/processors/json-encode-operator.d.ts +27 -0
  266. package/types/core-library/processors/kebab-case-operator.d.ts +16 -0
  267. package/types/core-library/processors/keys-operator.d.ts +9 -0
  268. package/types/core-library/processors/length-constraint.d.ts +34 -0
  269. package/types/core-library/processors/lookup-operator.d.ts +36 -0
  270. package/types/core-library/processors/lowercase-operator.d.ts +9 -0
  271. package/types/core-library/processors/map-operator.d.ts +38 -0
  272. package/types/core-library/processors/match-operator.d.ts +34 -0
  273. package/types/core-library/processors/matches-constraint.d.ts +29 -0
  274. package/types/core-library/processors/math-operators.d.ts +91 -0
  275. package/types/core-library/processors/merge-deep-operator.d.ts +32 -0
  276. package/types/core-library/processors/merge-operator.d.ts +26 -0
  277. package/types/core-library/processors/metadata-operator.d.ts +56 -0
  278. package/types/core-library/processors/negative-constraint.d.ts +13 -0
  279. package/types/core-library/processors/never-constraint.d.ts +26 -0
  280. package/types/core-library/processors/non-empty-constraint.d.ts +28 -0
  281. package/types/core-library/processors/not-constraint.d.ts +28 -0
  282. package/types/core-library/processors/number-operator.d.ts +9 -0
  283. package/types/core-library/processors/numeric-constraint.d.ts +10 -0
  284. package/types/core-library/processors/object-operator.d.ts +10 -0
  285. package/types/core-library/processors/omit-operator.d.ts +24 -0
  286. package/types/core-library/processors/parallel-operator.d.ts +41 -0
  287. package/types/core-library/processors/pascal-case-operator.d.ts +9 -0
  288. package/types/core-library/processors/phone-constraint.d.ts +65 -0
  289. package/types/core-library/processors/pick-operator.d.ts +27 -0
  290. package/types/core-library/processors/pipeline-operator.d.ts +40 -0
  291. package/types/core-library/processors/port-constraint.d.ts +11 -0
  292. package/types/core-library/processors/positive-constraint.d.ts +13 -0
  293. package/types/core-library/processors/process-operator.d.ts +37 -0
  294. package/types/core-library/processors/property-operator.d.ts +34 -0
  295. package/types/core-library/processors/range-constraint.d.ts +30 -0
  296. package/types/core-library/processors/reference-operator.d.ts +38 -0
  297. package/types/core-library/processors/require-constraint.d.ts +29 -0
  298. package/types/core-library/processors/reverse-operator.d.ts +9 -0
  299. package/types/core-library/processors/round-operator.d.ts +34 -0
  300. package/types/core-library/processors/schema-handler-operators.d.ts +28 -0
  301. package/types/core-library/processors/semver-constraint.d.ts +43 -0
  302. package/types/core-library/processors/sequence-processors.d.ts +213 -0
  303. package/types/core-library/processors/sort-operator.d.ts +31 -0
  304. package/types/core-library/processors/split-operator.d.ts +33 -0
  305. package/types/core-library/processors/string-extra-operators.d.ts +83 -0
  306. package/types/core-library/processors/string-operator.d.ts +10 -0
  307. package/types/core-library/processors/target-operator.d.ts +27 -0
  308. package/types/core-library/processors/template-operator.d.ts +31 -0
  309. package/types/core-library/processors/title-case-operator.d.ts +12 -0
  310. package/types/core-library/processors/trim-operator.d.ts +9 -0
  311. package/types/core-library/processors/truthy-constraint.d.ts +23 -0
  312. package/types/core-library/processors/type-operator.d.ts +11 -0
  313. package/types/core-library/processors/unique-operator.d.ts +10 -0
  314. package/types/core-library/processors/uppercase-operator.d.ts +9 -0
  315. package/types/core-library/processors/url-constraint.d.ts +20 -0
  316. package/types/core-library/processors/url-decode-operator.d.ts +31 -0
  317. package/types/core-library/processors/url-encode-operator.d.ts +36 -0
  318. package/types/core-library/processors/uuid-constraint.d.ts +20 -0
  319. package/types/core-library/processors/values-operator.d.ts +9 -0
  320. package/types/core-library/schemas/any-schema.d.ts +2 -0
  321. package/types/core-library/schemas/array-schema.d.ts +2 -0
  322. package/types/core-library/schemas/boolean-schema.d.ts +2 -0
  323. package/types/core-library/schemas/date-schema.d.ts +2 -0
  324. package/types/core-library/schemas/function-schema.d.ts +2 -0
  325. package/types/core-library/schemas/number-schema.d.ts +2 -0
  326. package/types/core-library/schemas/object-schema.d.ts +2 -0
  327. package/types/core-library/schemas/root-schema.d.ts +2 -0
  328. package/types/core-library/schemas/string-schema.d.ts +2 -0
  329. package/types/core-library-node/index.d.ts +12 -0
  330. package/types/core-library-node/processors/base64-decode-operator.d.ts +9 -0
  331. package/types/core-library-node/processors/base64-encode-operator.d.ts +9 -0
  332. package/types/core-library-node/processors/buffer-operator.d.ts +15 -0
  333. package/types/core-library-node/processors/directory-constraint.d.ts +14 -0
  334. package/types/core-library-node/processors/executable-constraint.d.ts +17 -0
  335. package/types/core-library-node/processors/file-constraint.d.ts +13 -0
  336. package/types/core-library-node/processors/file-size-constraint.d.ts +43 -0
  337. package/types/core-library-node/processors/is-buffer-constraint.d.ts +10 -0
  338. package/types/core-library-node/processors/reachable-constraint.d.ts +13 -0
  339. package/types/core-library-node/processors/readable-constraint.d.ts +17 -0
  340. package/types/core-library-node/processors/writable-constraint.d.ts +18 -0
  341. package/types/core-library-node/schemas/buffer-schema.d.ts +2 -0
  342. package/types/errors.d.ts +58 -0
  343. package/types/executor/array-executor.d.ts +17 -0
  344. package/types/executor/conditional-executor.d.ts +45 -0
  345. package/types/executor/each-executor.d.ts +15 -0
  346. package/types/executor/executor.d.ts +84 -0
  347. package/types/executor/object-executor.d.ts +14 -0
  348. package/types/executor/parallel-executor.d.ts +27 -0
  349. package/types/executor/pipeline-executor.d.ts +11 -0
  350. package/types/executor/sequence-executor.d.ts +32 -0
  351. package/types/executor/serial-executor.d.ts +16 -0
  352. package/types/executor/step-executor.d.ts +14 -0
  353. package/types/helpers/case.d.ts +30 -0
  354. package/types/helpers/data-size.d.ts +25 -0
  355. package/types/helpers/debug-sink.d.ts +9 -0
  356. package/types/helpers/deep.d.ts +33 -0
  357. package/types/helpers/format.d.ts +14 -0
  358. package/types/helpers/has-string-properties.d.ts +5 -0
  359. package/types/helpers/index.d.ts +13 -0
  360. package/types/helpers/object.d.ts +46 -0
  361. package/types/helpers/parse-date.d.ts +6 -0
  362. package/types/helpers/path.d.ts +13 -0
  363. package/types/helpers/regex.d.ts +7 -0
  364. package/types/helpers/stringify.d.ts +33 -0
  365. package/types/helpers/to-data.d.ts +13 -0
  366. package/types/helpers/truthy.d.ts +26 -0
  367. package/types/index.d.ts +6 -0
  368. package/types/schema-compiler.d.ts +49 -0
  369. package/types/schema-location.d.ts +64 -0
  370. package/types/schema-resolver.d.ts +145 -0
  371. package/types/schema.d.ts +586 -0
  372. package/types/traversal/executors/check-condition.d.ts +8 -0
  373. package/types/traversal/executors/check-input.d.ts +6 -0
  374. package/types/traversal/executors/check-required.d.ts +6 -0
  375. package/types/traversal/executors/check-schema.d.ts +7 -0
  376. package/types/traversal/executors/defaults.d.ts +8 -0
  377. package/types/traversal/executors/enter-existing.d.ts +6 -0
  378. package/types/traversal/executors/enter-input.d.ts +8 -0
  379. package/types/traversal/executors/enter.d.ts +7 -0
  380. package/types/traversal/executors/exit.d.ts +6 -0
  381. package/types/traversal/executors/finalize.d.ts +6 -0
  382. package/types/traversal/executors/index.d.ts +15 -0
  383. package/types/traversal/executors/normalize.d.ts +7 -0
  384. package/types/traversal/executors/prepare-existing.d.ts +6 -0
  385. package/types/traversal/executors/prepare-pending.d.ts +6 -0
  386. package/types/traversal/executors/resolve-union.d.ts +6 -0
  387. package/types/traversal/executors/serialize.d.ts +11 -0
  388. package/types/traversal/executors/transform-early.d.ts +6 -0
  389. package/types/traversal/executors/transform.d.ts +6 -0
  390. package/types/traversal/executors/traversal-state-executor.d.ts +19 -0
  391. package/types/traversal/executors/validate.d.ts +6 -0
  392. package/types/traversal/traversal-context.d.ts +67 -0
  393. package/types/traversal/traversal-state.d.ts +97 -0
  394. package/types/types.d.ts +218 -0
  395. package/types/value-processor/composed-value-processor.d.ts +17 -0
  396. package/types/value-processor/defined-value-processor.d.ts +16 -0
  397. package/types/value-processor/function-value-processor.d.ts +15 -0
  398. package/types/value-processor/parameterized-value-processor.d.ts +14 -0
  399. package/types/value-processor/parameters-value-processor.d.ts +28 -0
  400. package/types/value-processor/spec.d.ts +22 -0
  401. package/types/value-processor/value-processor.d.ts +92 -0
@@ -0,0 +1,188 @@
1
+ import { ConstraintError, ResolverError } from '../../errors.js';
2
+
3
+ const IPV4_REGEX = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
4
+
5
+ /**
6
+ * Parse a dotted-decimal IPv4 string into a 32-bit unsigned integer.
7
+ * @param {string} ip
8
+ * @returns {number}
9
+ */
10
+ function ipToUint32(ip) {
11
+ const [a, b, c, d] = ip.split('.').map(Number);
12
+ return ((a << 24) | (b << 16) | (c << 8) | d) >>> 0;
13
+ }
14
+
15
+ /**
16
+ * Parse a CIDR string (e.g. '192.168.1.0/24') into network and mask as uint32.
17
+ * @param {string} cidr
18
+ * @returns {{ network: number, mask: number }}
19
+ */
20
+ function parseCIDR(cidr) {
21
+ const [ip, bitsStr] = cidr.split('/');
22
+ const bits = Number(bitsStr);
23
+ if (!IPV4_REGEX.test(ip) || !Number.isInteger(bits) || bits < 0 || bits > 32) {
24
+ throw new ResolverError(`Invalid CIDR notation: ${cidr}`);
25
+ }
26
+ const mask = bits === 0 ? 0 : (~0 << (32 - bits)) >>> 0;
27
+ const network = ipToUint32(ip) & mask;
28
+ return { network, mask };
29
+ }
30
+
31
+ /**
32
+ * Check whether an IPv4 uint32 falls within a CIDR range.
33
+ * @param {number} ip
34
+ * @param {{ network: number, mask: number }} cidr
35
+ * @returns {boolean}
36
+ */
37
+ function isInCIDR(ip, cidr) {
38
+ return (ip & cidr.mask) === cidr.network;
39
+ }
40
+
41
+ /** @type {Record<string, { network: number, mask: number }[]>} */
42
+ const NAMED_RANGES = {
43
+ rfc1918: [
44
+ parseCIDR('10.0.0.0/8'),
45
+ parseCIDR('172.16.0.0/12'),
46
+ parseCIDR('192.168.0.0/16'),
47
+ ],
48
+ loopback: [
49
+ parseCIDR('127.0.0.0/8'),
50
+ ],
51
+ 'link-local': [
52
+ parseCIDR('169.254.0.0/16'),
53
+ ],
54
+ rfc6598: [
55
+ parseCIDR('100.64.0.0/10'),
56
+ ],
57
+ multicast: [
58
+ parseCIDR('224.0.0.0/4'),
59
+ ],
60
+ };
61
+
62
+ NAMED_RANGES['non-routable'] = [
63
+ ...NAMED_RANGES.rfc1918,
64
+ ...NAMED_RANGES.loopback,
65
+ ...NAMED_RANGES['link-local'],
66
+ ...NAMED_RANGES.rfc6598,
67
+ ];
68
+
69
+ /**
70
+ * Resolve an `in` parameter value to an array of CIDR ranges.
71
+ * Accepts a named range (e.g. 'rfc1918') or a CIDR string (e.g. '10.0.0.0/8').
72
+ * @param {string} spec
73
+ * @returns {{ network: number, mask: number }[]}
74
+ */
75
+ function resolveRange(spec) {
76
+ const named = NAMED_RANGES[spec.toLowerCase()];
77
+ if (named) return named;
78
+ if (spec.includes('/')) return [parseCIDR(spec)];
79
+ throw new ResolverError(`Unknown IPv4 range: "${spec}" (expected CIDR or one of: ${Object.keys(NAMED_RANGES).join(', ')})`);
80
+ }
81
+
82
+ /**
83
+ * ## $ipv4
84
+ *
85
+ * Validates that a string is a valid IPv4 address in dotted-decimal notation.
86
+ *
87
+ * ### Parameters
88
+ * - `in` (string, optional): Network range to validate against. Accepts CIDR
89
+ * notation (e.g. `'192.168.1.0/24'`) or a named range: `rfc1918`, `loopback`,
90
+ * `link-local`, `rfc6598`, `multicast`, `non-routable`.
91
+ * - `min` (string, optional): Minimum IPv4 address (inclusive).
92
+ * - `max` (string, optional): Maximum IPv4 address (inclusive).
93
+ * - `format` (string, optional): Output format — `'integer'` emits the address
94
+ * as a uint32. Default passes through the original dotted-decimal string.
95
+ *
96
+ * Use either `in` OR `min`/`max`, not both.
97
+ *
98
+ * ### Example
99
+ * ```js
100
+ * // Format-only validation
101
+ * new Schema('string').validator('$ipv4')
102
+ *
103
+ * // CIDR range (positional `in`)
104
+ * new Schema('string').validator({$ipv4: '192.168.1.0/24'})
105
+ *
106
+ * // Named range
107
+ * new Schema('string').validator({$ipv4: 'rfc1918'})
108
+ *
109
+ * // Explicit min/max
110
+ * new Schema('string').validator({$ipv4: {min: '192.168.1.1', max: '192.168.1.254'}})
111
+ *
112
+ * // Output as uint32
113
+ * new Schema('string').validator({$ipv4: {in: 'rfc1918', format: 'integer'}})
114
+ * ```
115
+ *
116
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
117
+ */
118
+ export const IPV4_CONSTRAINT = {
119
+ keyword: 'ipv4',
120
+
121
+ parameters: [
122
+ { parameter: 'in', default: undefined, type: 'string' },
123
+ { parameter: 'min', default: undefined, type: 'string' },
124
+ { parameter: 'max', default: undefined, type: 'string' },
125
+ { parameter: 'format', default: undefined, type: 'string' },
126
+ ],
127
+
128
+ process: (value, _target, _location, options) => {
129
+ if (!IPV4_REGEX.test(value)) {
130
+ throw new ConstraintError('Invalid IPv4 address');
131
+ }
132
+
133
+ const { in: inRange, min, max, format } = options?.args ?? {};
134
+
135
+ // mutual exclusivity check
136
+ if (inRange !== undefined && (min !== undefined || max !== undefined)) {
137
+ throw new ResolverError('$ipv4: "in" and "min"/"max" are mutually exclusive');
138
+ }
139
+
140
+ // validate min/max are valid IPv4 if provided
141
+ if (min !== undefined && !IPV4_REGEX.test(min)) {
142
+ throw new ResolverError(`$ipv4: invalid "min" address: ${min}`);
143
+ }
144
+ if (max !== undefined && !IPV4_REGEX.test(max)) {
145
+ throw new ResolverError(`$ipv4: invalid "max" address: ${max}`);
146
+ }
147
+
148
+ const ip = ipToUint32(value);
149
+
150
+ if (inRange !== undefined) {
151
+ const ranges = resolveRange(inRange);
152
+ if (!ranges.some(cidr => isInCIDR(ip, cidr))) {
153
+ throw new ConstraintError(`IPv4 address not in range "${inRange}"`);
154
+ }
155
+ }
156
+
157
+ if (min !== undefined && ip < ipToUint32(min)) {
158
+ throw new ConstraintError(`IPv4 address below minimum ${min}`);
159
+ }
160
+ if (max !== undefined && ip > ipToUint32(max)) {
161
+ throw new ConstraintError(`IPv4 address above maximum ${max}`);
162
+ }
163
+
164
+ if (format === 'integer') {
165
+ return ip;
166
+ }
167
+
168
+ return value;
169
+ },
170
+
171
+ describe: (args) => {
172
+ if (!args) return undefined;
173
+
174
+ const inProcessor = (Array.isArray(args) ? args[0] : args.in);
175
+ const minProcessor = (Array.isArray(args) ? args[1] : args.min);
176
+ const maxProcessor = (Array.isArray(args) ? args[2] : args.max);
177
+
178
+ const inVal = inProcessor?.description;
179
+ const min = minProcessor?.description;
180
+ const max = maxProcessor?.description;
181
+
182
+ if (inVal !== undefined) return `in ${inVal}`;
183
+ if (min !== undefined && max !== undefined) return `${min}–${max}`;
184
+ if (min !== undefined) return `≥${min}`;
185
+ if (max !== undefined) return `≤${max}`;
186
+ return undefined;
187
+ }
188
+ };
@@ -0,0 +1,205 @@
1
+ import { ConstraintError, ResolverError } from '../../errors.js';
2
+
3
+ const IPV6_REGEX = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
4
+
5
+ const IPV4_TAIL_REGEX = /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
6
+
7
+ /**
8
+ * Expand an IPv6 string (possibly compressed, possibly with zone id or IPv4 tail)
9
+ * into exactly 8 16-bit groups as a BigInt.
10
+ * @param {string} ip
11
+ * @returns {bigint}
12
+ */
13
+ function ipv6ToBigInt(ip) {
14
+ // strip zone identifier (e.g. %eth0)
15
+ let addr = ip.replace(/%.*$/, '');
16
+
17
+ // handle IPv4-mapped tail: convert dotted-decimal to two hex groups
18
+ const v4Match = IPV4_TAIL_REGEX.exec(addr);
19
+ if (v4Match) {
20
+ const [a, b, c, d] = [v4Match[1], v4Match[2], v4Match[3], v4Match[4]].map(Number);
21
+ const hi = ((a << 8) | b).toString(16);
22
+ const lo = ((c << 8) | d).toString(16);
23
+ addr = addr.slice(0, v4Match.index) + `${hi}:${lo}`;
24
+ }
25
+
26
+ // expand :: shorthand
27
+ if (addr.includes('::')) {
28
+ const [left, right] = addr.split('::');
29
+ const leftGroups = left ? left.split(':') : [];
30
+ const rightGroups = right ? right.split(':') : [];
31
+ const missing = 8 - leftGroups.length - rightGroups.length;
32
+ const fill = Array(missing).fill('0');
33
+ addr = [...leftGroups, ...fill, ...rightGroups].join(':');
34
+ }
35
+
36
+ const groups = addr.split(':');
37
+ let result = 0n;
38
+ for (const group of groups) {
39
+ result = (result << 16n) | BigInt(parseInt(group, 16));
40
+ }
41
+ return result;
42
+ }
43
+
44
+ /**
45
+ * Parse an IPv6 CIDR string into network and mask as BigInt.
46
+ * @param {string} cidr
47
+ * @returns {{ network: bigint, mask: bigint }}
48
+ */
49
+ function parseCIDR(cidr) {
50
+ const slashIdx = cidr.lastIndexOf('/');
51
+ if (slashIdx === -1) {
52
+ throw new ResolverError(`Invalid IPv6 CIDR notation: ${cidr}`);
53
+ }
54
+ const ip = cidr.slice(0, slashIdx);
55
+ const bits = Number(cidr.slice(slashIdx + 1));
56
+ if (!IPV6_REGEX.test(ip) || !Number.isInteger(bits) || bits < 0 || bits > 128) {
57
+ throw new ResolverError(`Invalid IPv6 CIDR notation: ${cidr}`);
58
+ }
59
+ const mask = bits === 0 ? 0n : ((1n << 128n) - 1n) << BigInt(128 - bits);
60
+ const network = ipv6ToBigInt(ip) & mask;
61
+ return { network, mask };
62
+ }
63
+
64
+ /**
65
+ * Check whether an IPv6 BigInt falls within a CIDR range.
66
+ * @param {bigint} ip
67
+ * @param {{ network: bigint, mask: bigint }} cidr
68
+ * @returns {boolean}
69
+ */
70
+ function isInCIDR(ip, cidr) {
71
+ return (ip & cidr.mask) === cidr.network;
72
+ }
73
+
74
+ /** @type {Record<string, { network: bigint, mask: bigint }[]>} */
75
+ const NAMED_RANGES = {
76
+ loopback: [
77
+ parseCIDR('::1/128'),
78
+ ],
79
+ 'link-local': [
80
+ parseCIDR('fe80::/10'),
81
+ ],
82
+ 'unique-local': [
83
+ parseCIDR('fc00::/7'),
84
+ ],
85
+ multicast: [
86
+ parseCIDR('ff00::/8'),
87
+ ],
88
+ };
89
+
90
+ NAMED_RANGES['non-routable'] = [
91
+ ...NAMED_RANGES.loopback,
92
+ ...NAMED_RANGES['link-local'],
93
+ ...NAMED_RANGES['unique-local'],
94
+ ];
95
+
96
+ /**
97
+ * Resolve an `in` parameter value to an array of CIDR ranges.
98
+ * Accepts a named range or a CIDR string.
99
+ * @param {string} spec
100
+ * @returns {{ network: bigint, mask: bigint }[]}
101
+ */
102
+ function resolveRange(spec) {
103
+ const named = NAMED_RANGES[spec.toLowerCase()];
104
+ if (named) return named;
105
+ if (spec.includes('/')) return [parseCIDR(spec)];
106
+ throw new ResolverError(`Unknown IPv6 range: "${spec}" (expected CIDR or one of: ${Object.keys(NAMED_RANGES).join(', ')})`);
107
+ }
108
+
109
+ /**
110
+ * ## $ipv6
111
+ *
112
+ * Validates that a string is a properly formatted IPv6 address. Supports all standard
113
+ * notation formats including full, compressed (::), link-local with zone identifiers,
114
+ * and IPv4-mapped addresses.
115
+ *
116
+ * ### Parameters
117
+ * - `in` (string, optional): Network range to validate against. Accepts CIDR
118
+ * notation (e.g. `'fe80::/10'`) or a named range: `loopback`, `link-local`,
119
+ * `unique-local`, `multicast`, `non-routable`.
120
+ * - `min` (string, optional): Minimum IPv6 address (inclusive).
121
+ * - `max` (string, optional): Maximum IPv6 address (inclusive).
122
+ *
123
+ * Use either `in` OR `min`/`max`, not both.
124
+ *
125
+ * ### Example
126
+ * ```js
127
+ * // Format-only validation
128
+ * new Schema('string').validator('$ipv6')
129
+ *
130
+ * // CIDR range (positional `in`)
131
+ * new Schema('string').validator({$ipv6: '2001:db8::/32'})
132
+ *
133
+ * // Named range
134
+ * new Schema('string').validator({$ipv6: 'unique-local'})
135
+ *
136
+ * // Explicit min/max
137
+ * new Schema('string').validator({$ipv6: {min: '2001:db8::1', max: '2001:db8::ffff'}})
138
+ * ```
139
+ *
140
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
141
+ */
142
+ export const IPV6_CONSTRAINT = {
143
+ keyword: 'ipv6',
144
+
145
+ parameters: [
146
+ { parameter: 'in', default: undefined, type: 'string' },
147
+ { parameter: 'min', default: undefined, type: 'string' },
148
+ { parameter: 'max', default: undefined, type: 'string' },
149
+ ],
150
+
151
+ process: (value, _target, _location, options) => {
152
+ if (!IPV6_REGEX.test(value)) {
153
+ throw new ConstraintError('Invalid IPv6 address');
154
+ }
155
+
156
+ const { in: inRange, min, max } = options?.args ?? {};
157
+
158
+ if (inRange !== undefined && (min !== undefined || max !== undefined)) {
159
+ throw new ResolverError('$ipv6: "in" and "min"/"max" are mutually exclusive');
160
+ }
161
+
162
+ if (min !== undefined && !IPV6_REGEX.test(min)) {
163
+ throw new ResolverError(`$ipv6: invalid "min" address: ${min}`);
164
+ }
165
+ if (max !== undefined && !IPV6_REGEX.test(max)) {
166
+ throw new ResolverError(`$ipv6: invalid "max" address: ${max}`);
167
+ }
168
+
169
+ const ip = ipv6ToBigInt(value);
170
+
171
+ if (inRange !== undefined) {
172
+ const ranges = resolveRange(inRange);
173
+ if (!ranges.some(cidr => isInCIDR(ip, cidr))) {
174
+ throw new ConstraintError(`IPv6 address not in range "${inRange}"`);
175
+ }
176
+ }
177
+
178
+ if (min !== undefined && ip < ipv6ToBigInt(min)) {
179
+ throw new ConstraintError(`IPv6 address below minimum ${min}`);
180
+ }
181
+ if (max !== undefined && ip > ipv6ToBigInt(max)) {
182
+ throw new ConstraintError(`IPv6 address above maximum ${max}`);
183
+ }
184
+
185
+ return value;
186
+ },
187
+
188
+ describe: (args) => {
189
+ if (!args) return undefined;
190
+
191
+ const inProcessor = (Array.isArray(args) ? args[0] : args.in);
192
+ const minProcessor = (Array.isArray(args) ? args[1] : args.min);
193
+ const maxProcessor = (Array.isArray(args) ? args[2] : args.max);
194
+
195
+ const inVal = inProcessor?.description;
196
+ const min = minProcessor?.description;
197
+ const max = maxProcessor?.description;
198
+
199
+ if (inVal !== undefined) return `in ${inVal}`;
200
+ if (min !== undefined && max !== undefined) return `${min}–${max}`;
201
+ if (min !== undefined) return `≥${min}`;
202
+ if (max !== undefined) return `≤${max}`;
203
+ return undefined;
204
+ }
205
+ };
@@ -0,0 +1,21 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $is-array
5
+ *
6
+ * Validates that the input is a valid array.
7
+ *
8
+ * See `$array` for looser array handling that accepts values that can be normalized as arrays.
9
+ *
10
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
11
+ */
12
+ export const IS_ARRAY_CONSTRAINT = {
13
+ keyword: 'is-array',
14
+ process: (value, _, location) => {
15
+ if (!Array.isArray(value)) {
16
+ throw new ConstraintError('Must be an array');
17
+ }
18
+ return value;
19
+ },
20
+ description: ''
21
+ };
@@ -0,0 +1,22 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+ import { formatValue } from '../../helpers/format.js';
3
+
4
+ /**
5
+ * ## $is-date
6
+ *
7
+ * Validates that the input is a valid date.
8
+ *
9
+ * See `$date` for looser date handling that accepts values that can be normalized as dates.
10
+ *
11
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
12
+ */
13
+ export const IS_DATE_CONSTRAINT = {
14
+ keyword: 'is-date',
15
+ process: (value) => {
16
+ if (value instanceof Date && !isNaN(value.getTime())) {
17
+ return value;
18
+ }
19
+ throw new ConstraintError(`Invalid date: ${formatValue(value)}`)
20
+ },
21
+ description: ''
22
+ };
@@ -0,0 +1,21 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $is-number
5
+ *
6
+ * Validates that the input is a valid number.
7
+ *
8
+ * See `$number` for looser number validation that accepts values that can be normalized as numbers.
9
+ *
10
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
11
+ */
12
+ export const IS_NUMBER_CONSTRAINT = {
13
+ keyword: 'is-number',
14
+ process: (value) => {
15
+ if (typeof value !== 'number' || Number.isNaN(value) || !Number.isFinite(value)) {
16
+ throw new ConstraintError('Must be a number');
17
+ }
18
+ return value;
19
+ },
20
+ description: ''
21
+ };
@@ -0,0 +1,21 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $is-object
5
+ *
6
+ * Validates that the input is a valid object (and not null!)
7
+ *
8
+ * See `$object` for looser object handling that accepts values that can be normalized as objects.
9
+ *
10
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
11
+ */
12
+ export const IS_OBJECT_CONSTRAINT = {
13
+ keyword: 'is-object',
14
+ process: (value, _, location) => {
15
+ if (typeof value === 'object' && value !== null) {
16
+ return value;
17
+ }
18
+ throw new ConstraintError('Must be an object');
19
+ },
20
+ description: ''
21
+ };
@@ -0,0 +1,21 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $is-string
5
+ *
6
+ * Validates that the input is a valid string.
7
+ *
8
+ * See `$string` for looser validation that accepts values that can be normalized as strings.
9
+ *
10
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
11
+ */
12
+ export const IS_STRING_CONSTRAINT = {
13
+ keyword: 'is-string',
14
+ process: (value) => {
15
+ if (typeof value === 'string') {
16
+ return value;
17
+ }
18
+ throw new ConstraintError('Must be a string');
19
+ },
20
+ description: ''
21
+ };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * ## $join
3
+ *
4
+ * Join the input array elements into a string using the provided separator.
5
+ *
6
+ * ### Parameters
7
+ * - `separator` (string, required): The value to use for joining
8
+ *
9
+ * If the input is not an array, it is treated as a single element.
10
+ * Follows the behavior of JavaScript's Array.prototype.join()
11
+ *
12
+ * ### Example
13
+ * ```js
14
+ * // Join array elements with a comma (default)
15
+ * new Schema('array').transformer('$join')
16
+ * // ['a', 'b', 'c'] → 'a,b,c'
17
+ *
18
+ * // Join with a custom separator
19
+ * new Schema('array').transformer({$join: {separator: ' | '}})
20
+ * // ['admin', 'read', 'write'] → 'admin | read | write'
21
+ *
22
+ * // Split then rejoin with normalized separators
23
+ * new Schema('string').normalizer([{$split: {separator: /[,;]/}}, {$each: '$trim'}])
24
+ * .transformer({$join: {separator: ', '}})
25
+ * ```
26
+ *
27
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}*
28
+ */
29
+ export const JOIN_OPERATOR = {
30
+ keyword: 'join',
31
+ parameters: [ { parameter: 'separator', default: ',' } ],
32
+
33
+ process: (value, _target, _location, options) => {
34
+ const separator = options.args?.['separator'];
35
+
36
+ if (!Array.isArray(value)) {
37
+ return `${value}`;
38
+ }
39
+ return value.join(separator);
40
+ }
41
+ }
@@ -0,0 +1,22 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $json
5
+ *
6
+ * Validates that a string contains valid JSON that can be parsed by `JSON.parse()`.
7
+ * The processor does not modify the input - it only validates that the string is
8
+ * syntactically correct JSON.
9
+ *
10
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
11
+ */
12
+ export const JSON_CONSTRAINT = {
13
+ keyword: 'json',
14
+ process: (value) => {
15
+ try {
16
+ JSON.parse(value);
17
+ return value;
18
+ } catch {
19
+ throw new ConstraintError('Invalid JSON format');
20
+ }
21
+ }
22
+ };
@@ -0,0 +1,25 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+ import { formatValue } from '../../helpers/format.js';
3
+
4
+ /**
5
+ * ## $json-decode
6
+ *
7
+ * Parses a JSON string into a value.
8
+ * Throws if the input is not a string or is not valid JSON.
9
+ *
10
+ * @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
11
+ */
12
+ export const JSON_DECODE_OPERATOR = {
13
+ keyword: 'json-decode',
14
+ process: (value, _target, location) => {
15
+ if (typeof value !== 'string') {
16
+ throw new ConstraintError(`$json-decode requires a string, got ${formatValue(value)}`, {location});
17
+ }
18
+ try {
19
+ return JSON.parse(value);
20
+ }
21
+ catch (error) {
22
+ throw new ConstraintError(`$json-decode: invalid JSON — ${error.message}`, {location, cause: error});
23
+ }
24
+ }
25
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ## $json-encode
3
+ *
4
+ * Serializes any value to a JSON string.
5
+ *
6
+ * ### Parameters
7
+ * - `indent` (number, optional, default `0`): Indentation spaces for pretty-printing. `0` produces compact output.
8
+ *
9
+ * ### Example
10
+ * ```js
11
+ * // Serialize an object to a compact JSON string
12
+ * new Schema('object').transformer('$json-encode')
13
+ * // {a: 1} → '{"a":1}'
14
+ *
15
+ * // Pretty-print with 2-space indentation
16
+ * new Schema('object').transformer({'$json-encode': {indent: 2}})
17
+ * // {a: 1} → '{\n "a": 1\n}'
18
+ *
19
+ * // Encode a nested payload field for storage
20
+ * new Schema('object', {
21
+ * payload: new Schema('object').transformer('$json-encode'),
22
+ * })
23
+ * ```
24
+ *
25
+ * @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
26
+ */
27
+ export const JSON_ENCODE_OPERATOR = {
28
+ keyword: 'json-encode',
29
+ parameters: [ { parameter: 'indent', default: 0 } ],
30
+
31
+ process: (value, _target, _location, options) => {
32
+ const indent = options.args?.['indent'] || 0;
33
+ return JSON.stringify(value, null, indent || undefined);
34
+ }
35
+ };
@@ -0,0 +1,23 @@
1
+ import { toKebabCase } from '../../helpers/case.js';
2
+
3
+ /**
4
+ * ## $kebab-case
5
+ *
6
+ * Converts a string to kebab-case format (lowercase words separated by hyphens).
7
+ * Safe to use in normalize phase (non-throwing).
8
+ *
9
+ * **Input/Output Examples**:
10
+ * - `"HelloWorld"` → `"hello-world"`
11
+ * - `"API_KEY_NAME"` → `"api-key-name"`
12
+ * - `"some text here"` → `"some-text-here"`
13
+ * - `"camelCase"` → `"camel-case"`
14
+ * - `"already-kebab"` → `"already-kebab"`
15
+ *
16
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
17
+ */
18
+ export const KEBAB_CASE_OPERATOR = {
19
+ keyword: 'kebab-case',
20
+ process: (value) => {
21
+ return toKebabCase(String(value));
22
+ }
23
+ };
@@ -0,0 +1,20 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+ import { formatValue } from '../../helpers/format.js';
3
+
4
+ /**
5
+ * ## $keys
6
+ *
7
+ * Returns the enumerable own property keys of an object as an array of strings.
8
+ * Throws if the input is not a plain object.
9
+ *
10
+ * @type {import('../../value-processor/value-processor.js').ValueProcessorDefinition}
11
+ */
12
+ export const KEYS_OPERATOR = {
13
+ keyword: 'keys',
14
+ process: (value, _target, location) => {
15
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
16
+ throw new ConstraintError(`$keys requires a plain object, got ${formatValue(value)}`, {location});
17
+ }
18
+ return Object.keys(value);
19
+ }
20
+ };