@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,39 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $buffer
5
+ *
6
+ * Converts a value to a Node.js Buffer. Accepts:
7
+ * - `Buffer` — passed through unchanged
8
+ * - `string` — decoded from Base64 via `Buffer.from(value, 'base64')`
9
+ * - `{size, fill?, encoding?}` — allocated via `Buffer.alloc(size, fill, encoding)`
10
+ * - `{encoding, buffer}` — constructed from an underlying ArrayBuffer via `Buffer.from(value.buffer)`
11
+ * - anything else (TypedArray, byte array, etc.) — via `Buffer.from(value)`
12
+ *
13
+ * See `$is-buffer` for strict Buffer validation without conversion.
14
+ *
15
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
16
+ */
17
+ export const BUFFER_OPERATOR = {
18
+ keyword: 'buffer',
19
+ process: (value) => {
20
+ if (Buffer.isBuffer(value)) {
21
+ return value;
22
+ }
23
+ try {
24
+ if (typeof value === 'string') {
25
+ return Buffer.from(value, 'base64');
26
+ }
27
+ if (typeof value === 'object' && Number.isInteger(value?.size)) {
28
+ return Buffer.alloc(value.size, value.fill ?? 0, value.encoding ?? 'utf8');
29
+ }
30
+ if (typeof value === 'object' && value?.encoding !== undefined) {
31
+ return Buffer.from(value.buffer, value.encoding);
32
+ }
33
+ return Buffer.from(value);
34
+ }
35
+ catch (error) {
36
+ throw new ConstraintError('Buffer array contains invalid data', {cause: error});
37
+ }
38
+ }
39
+ };
@@ -0,0 +1,35 @@
1
+ import * as fs from 'node:fs/promises';
2
+
3
+
4
+ import { ConstraintError } from '../../errors.js';
5
+
6
+ /**
7
+ * ## $directory
8
+ *
9
+ * Validates that a path exists on the filesystem and is a directory (not a file).
10
+ * This is an **async processor** that performs filesystem operations.
11
+ *
12
+ * The processor checks both existence and type, throwing distinct errors for:
13
+ * - Path does not exist (`ENOENT`)
14
+ * - Path exists but is a file, symlink, or other non-directory type
15
+ * - Path is inaccessible due to permissions or other filesystem errors
16
+ *
17
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
18
+ */
19
+ export const DIRECTORY_CONSTRAINT = {
20
+ keyword: 'directory',
21
+ process: async (value) => {
22
+ try {
23
+ const stat = await fs.stat(value);
24
+ if (!stat.isDirectory()) {
25
+ throw new ConstraintError('Path exists but is not a directory');
26
+ }
27
+ return value;
28
+ } catch (error) {
29
+ if (error.code === 'ENOENT') {
30
+ throw new ConstraintError('Directory does not exist');
31
+ }
32
+ throw new ConstraintError(`Cannot access directory: ${error.message}`);
33
+ }
34
+ }
35
+ };
@@ -0,0 +1,34 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import { constants } from 'node:fs';
3
+
4
+
5
+ import { ConstraintError } from '../../errors.js';
6
+
7
+ /**
8
+ * ## $executable
9
+ *
10
+ * Validates that a file path points to an executable file by checking execute
11
+ * permissions. This is an asynchronous processor that performs a file system
12
+ * access check.
13
+ *
14
+ * This processor is particularly useful for validating script paths, binary
15
+ * paths, and command executables in configuration files.
16
+ *
17
+ * **Note**: This processor performs async file system checks and should usually
18
+ * be used as a validator. Execution permissions are platform-dependent (Unix/Linux/macOS
19
+ * use chmod +x; Windows uses file extensions and ACLs).
20
+ *
21
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
22
+ */
23
+ export const EXECUTABLE_CONSTRAINT = {
24
+ keyword: 'executable',
25
+ process: async (value) => {
26
+ try {
27
+ await fs.access(value, constants.X_OK);
28
+ return value;
29
+ } catch {
30
+ throw new ConstraintError('File is not executable');
31
+ }
32
+ },
33
+ description: 'path'
34
+ };
@@ -0,0 +1,34 @@
1
+ import * as fs from 'node:fs/promises';
2
+
3
+
4
+ import { ConstraintError } from '../../errors.js';
5
+
6
+ /**
7
+ * ## $file
8
+ *
9
+ * Validates that a path exists in the filesystem and is a file (not a directory or other type).
10
+ * Performs an asynchronous filesystem check using `fs.stat()`.
11
+ *
12
+ * - Non-existent paths: `"/does/not/exist.txt"` → throws "File does not exist"
13
+ * - Directory paths: `"/var/log"` → throws "Path exists but is not a file"
14
+ * - Inaccessible paths: `"/root/secret.txt"` (permission denied) → throws "Cannot access file: ..."
15
+ *
16
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
17
+ */
18
+ export const FILE_CONSTRAINT = {
19
+ keyword: 'file',
20
+ process: async (value) => {
21
+ try {
22
+ const stat = await fs.stat(value);
23
+ if (!stat.isFile()) {
24
+ throw new ConstraintError('Path exists but is not a file');
25
+ }
26
+ return value;
27
+ } catch (error) {
28
+ if (error.code === 'ENOENT') {
29
+ throw new ConstraintError('File does not exist');
30
+ }
31
+ throw new ConstraintError(`Cannot access file: ${error.message}`);
32
+ }
33
+ }
34
+ };
@@ -0,0 +1,94 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import { ConstraintError, ResolverError } from '../../errors.js';
3
+
4
+ /**
5
+ * ## $file-size
6
+ *
7
+ * Validates that a file's size falls within the specified range. Accepts size constraints
8
+ * in bytes and checks the file's metadata without loading the entire file into memory.
9
+ * Can specify minimum, maximum, or both bounds.
10
+ *
11
+ * **This is an async processor** that performs filesystem I/O, and probably best suited
12
+ * for use during transformation or validation phases.
13
+ *
14
+ * ### Parameters
15
+ * - `min` (number, optional): Minimum file size in bytes (inclusive). If omitted, no lower bound.
16
+ * - `max` (number, optional): Maximum file size in bytes (inclusive). If omitted, no upper bound.
17
+ *
18
+ * **Unit Conversions**: Size must be specified in bytes. Use standard conversions:
19
+ * - 1 KB = 1024 bytes
20
+ * - 1 MB = 1024 * 1024 bytes (1,048,576)
21
+ * - 1 GB = 1024 * 1024 * 1024 bytes (1,073,741,824)
22
+ *
23
+ * **Note**: Typically used with `$file` validator to ensure the file exists before checking size.
24
+ * The processor reads file metadata via `fs.stat()` and does not load file contents.
25
+ *
26
+ * ### Example
27
+ * ```js
28
+ * // Validate a config file exists and is under 1 MB
29
+ * new Schema('string')
30
+ * .validator('$file')
31
+ * .validator({'$file-size': {max: 1024 * 1024}})
32
+ *
33
+ * // Require an upload file to be between 1 KB and 10 MB
34
+ * new Schema('string')
35
+ * .validator('$file')
36
+ * .validator({'$file-size': {min: 1024, max: 10 * 1024 * 1024}})
37
+ *
38
+ * // Ensure a log file is not empty
39
+ * new Schema('string')
40
+ * .validator('$file')
41
+ * .validator({'$file-size': {min: 1}})
42
+ * ```
43
+ *
44
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
45
+ */
46
+ export const FILE_SIZE_CONSTRAINT = {
47
+ keyword: 'file-size',
48
+ parameters: [ { parameter: 'min', type: 'number', default: undefined }, { parameter: 'max', type: 'number', default: undefined } ],
49
+
50
+ process: async (value, _target, _location, options) => {
51
+
52
+ const min = options.args.min;
53
+ const max = options.args.max;
54
+
55
+ try {
56
+ const stat = await fs.stat(value);
57
+ const size = stat.size;
58
+
59
+ if (min !== undefined && size < min) {
60
+ throw new ConstraintError(`File size must be at least ${min} bytes`);
61
+ }
62
+ if (max !== undefined && size > max) {
63
+ throw new ConstraintError(`File size must be at most ${max} bytes`);
64
+ }
65
+ return value;
66
+ } catch (error) {
67
+ if (error instanceof ConstraintError) {
68
+ throw error;
69
+ }
70
+ throw new ConstraintError(`Cannot access file: ${error.message}`);
71
+ }
72
+ },
73
+ describe: (args) => {
74
+
75
+ if (!args) {
76
+ return undefined; // should never happen
77
+ }
78
+
79
+ const minProcessor = (Array.isArray(args)? args[0] : args.min);
80
+ const maxProcessor = (Array.isArray(args)? args[1] : args.max);
81
+
82
+ const min = minProcessor?.description;
83
+ const max = maxProcessor?.description;
84
+
85
+ return min !== undefined && max !== undefined
86
+ ? `${min}-${max}B`
87
+ : min !== undefined
88
+ ? `≥${min}B`
89
+ : max !== undefined
90
+ ? `≤${max}B`
91
+ : undefined
92
+ }
93
+
94
+ };
@@ -0,0 +1,21 @@
1
+ import { ConstraintError } from '../../errors.js';
2
+
3
+ /**
4
+ * ## $is-buffer
5
+ *
6
+ * Validates that the input is a Node.js Buffer.
7
+ *
8
+ * See `$buffer` for looser normalization that accepts values that can be converted to a Buffer.
9
+ *
10
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
11
+ */
12
+ export const IS_BUFFER_CONSTRAINT = {
13
+ keyword: 'is-buffer',
14
+ process: (value) => {
15
+ if (Buffer.isBuffer(value)) {
16
+ return value;
17
+ }
18
+ throw new ConstraintError('Must be a Buffer');
19
+ },
20
+ description: ''
21
+ };
@@ -0,0 +1,28 @@
1
+ import { lookup } from 'node:dns/promises';
2
+
3
+
4
+ import { ConstraintError } from '../../errors.js';
5
+
6
+ /**
7
+ * ## $reachable
8
+ *
9
+ * Validates that a hostname is reachable by performing a DNS lookup.
10
+ * This is an asynchronous processor that checks if the hostname resolves to an IP address.
11
+ *
12
+ * Note: This processor performs a network operation and may fail if DNS is unavailable
13
+ * or the hostname does not exist. It does not verify that the host is responding on any port,
14
+ * only that it has a DNS record.
15
+ *
16
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
17
+ */
18
+ export const REACHABLE_CONSTRAINT = {
19
+ keyword: 'reachable',
20
+ process: async (value) => {
21
+ try {
22
+ await lookup(value);
23
+ return value;
24
+ } catch {
25
+ throw new ConstraintError('Host is not reachable');
26
+ }
27
+ }
28
+ };
@@ -0,0 +1,34 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import { constants } from 'node:fs';
3
+
4
+
5
+ import { ConstraintError } from '../../errors.js';
6
+
7
+ /**
8
+ * ## $readable
9
+ *
10
+ * Validates that a file or directory path exists and has read permissions for the
11
+ * current process. Performs an asynchronous file system access check.
12
+ *
13
+ * This processor uses Node.js `fs.access()` with `R_OK` flag to verify read permissions
14
+ * without actually opening the file. Note that permission checks can be subject to race
15
+ * conditions where permissions change between validation and actual file access.
16
+ *
17
+ * (e.g., `"/etc/hosts"`, `"./config.json"`, `"~/Documents"`)
18
+ *
19
+ * or non-string values
20
+ *
21
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
22
+ */
23
+ export const READABLE_CONSTRAINT = {
24
+ keyword: 'readable',
25
+ process: async (value) => {
26
+ try {
27
+ await fs.access(value, constants.R_OK);
28
+ return value;
29
+ } catch {
30
+ throw new ConstraintError('File is not readable');
31
+ }
32
+ },
33
+ description: 'path'
34
+ };
@@ -0,0 +1,59 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import { constants } from 'node:fs';
3
+
4
+
5
+ import { ConstraintError } from '../../errors.js';
6
+
7
+ /**
8
+ * ## $writable
9
+ *
10
+ * Validates that a file system path is writable by checking write permissions.
11
+ * If the path does not exist, validates that the parent directory exists and is writable.
12
+ *
13
+ * This is an asynchronous processor that performs file system permission checks.
14
+ *
15
+ * - Existing files with write permissions: `/tmp/output.log`, `./config.json`
16
+ * - Non-existent paths in writable directories: `/tmp/new-file.txt`, `./data/output.csv`
17
+ *
18
+ * - Read-only files: `/etc/hosts`, system-protected paths
19
+ * - Paths in non-existent parent directories: `/nonexistent/dir/file.txt`
20
+ * - Paths in read-only directories: `/read-only-mount/file.txt`
21
+ *
22
+ * @type {import("../../value-processor/value-processor.js").ValueProcessorDefinition}
23
+ */
24
+ export const WRITABLE_CONSTRAINT = {
25
+ keyword: 'writable',
26
+ process: async (value) => {
27
+ try {
28
+ // Try to access the file
29
+ await fs.access(value, constants.W_OK);
30
+ return value;
31
+ } catch (error) {
32
+ // File doesn't exist or isn't writable
33
+ if (error.code === 'ENOENT') {
34
+ // File doesn't exist - check if parent directory is writable
35
+ const path = await import('node:path');
36
+ const parentDir = path.dirname(value);
37
+
38
+ try {
39
+ const stat = await fs.stat(parentDir);
40
+ if (!stat.isDirectory()) {
41
+ throw new ConstraintError('Parent path exists but is not a directory');
42
+ }
43
+ await fs.access(parentDir, constants.W_OK);
44
+ return value; // Parent is writable
45
+ } catch (parentError) {
46
+ if (parentError.code === 'ENOENT') {
47
+ throw new ConstraintError('Parent directory does not exist');
48
+ }
49
+ else if (parentError instanceof ConstraintError) {
50
+ throw parentError;
51
+ }
52
+ throw new ConstraintError('Parent directory is not writable');
53
+ }
54
+ }
55
+ throw new ConstraintError('File is not writable');
56
+ }
57
+ },
58
+ description: 'path'
59
+ };
@@ -0,0 +1,10 @@
1
+ import { Schema } from '../../schema.js';
2
+
3
+ export const BUFFER_SCHEMA = new Schema()
4
+ .option('type', 'buffer')
5
+ .meta('valueName', 'buffer')
6
+ .meta('parserTypeHint', 'string')
7
+ .normalizer('$buffer')
8
+ .transformer('$buffer')
9
+ .validator('$is-buffer')
10
+ .serializer('$base64-encode')
package/src/errors.js ADDED
@@ -0,0 +1,209 @@
1
+ import { SchemaLocation } from "./schema-location.js";
2
+ import { formatValue } from './helpers/format.js';
3
+
4
+
5
+ /**
6
+ * Format a location/path (possibly with property), typically for error messages.
7
+ *
8
+ * @param {string} message
9
+ * @param {string|undefined} where - path
10
+ * @param {string|number} [property]
11
+ * @param {string} [prep]
12
+ * @returns {string}
13
+ * @internal
14
+ */
15
+ function fpm(message, where, property, prep = 'at') {
16
+
17
+ if (where === '') {
18
+ where = '(root)'
19
+ }
20
+ else if (where){
21
+ where = `"${where}"`
22
+ }
23
+
24
+ if (property) {
25
+ where = where? `${where} property "${property}"` : `property "${property}"`;
26
+ }
27
+
28
+ let m = message;
29
+
30
+ if (where) {
31
+ m += ` ${prep} ${where}`;
32
+ }
33
+
34
+ return m;
35
+ }
36
+
37
+ /**
38
+ * @param {string} message
39
+ * @param {any} value
40
+ * @param {string|undefined} where
41
+ * @param {string|number} [property]
42
+ * @param {string} [prep]
43
+ * @returns {string}
44
+ * @internal
45
+ */
46
+ function fpvm(message, value, where, property, prep) {
47
+ /** @type {string|undefined} */
48
+ const valueString = formatValue(value);
49
+
50
+ if (valueString?.length) {
51
+ message = `${message} with value ${valueString}`;
52
+ }
53
+ return fpm(message, where, property, prep);
54
+ }
55
+
56
+ export class SchemaError extends Error {
57
+ /**
58
+ * @param {string} message
59
+ * @param {object} [data]
60
+ * @param {Error|any} [data.cause]
61
+ * @param {string} [data.path]
62
+ * @param {SchemaLocation} [data.location]
63
+ * @param {string|number} [data.property]
64
+ * @param {any} [data.value]
65
+ * @param {number} [data.code]
66
+ * @param {Array<Error>} [data.errors]
67
+ * @param {boolean} [preserveStack]
68
+ */
69
+ constructor(message, data, preserveStack = false) {
70
+ // noinspection JSCheckFunctionSignatures
71
+
72
+ /** @type {Error|undefined} */
73
+ const cause = data?.cause
74
+ ? data.cause instanceof Error
75
+ ? data.cause
76
+ : new SchemaError(data.cause, undefined, false)
77
+ : undefined;
78
+
79
+ const path = data?.path ?? data?.location?.path ?? data?.cause?.path ?? data?.cause?.location?.path;
80
+ const property = data?.property;
81
+
82
+ if (!message?.length && cause?.message) {
83
+ message = cause.message;
84
+ }
85
+
86
+ if (!path || message.indexOf(path) === -1) {
87
+ if (data?.hasOwnProperty('value')) {
88
+ message = fpvm(message, data?.value, path, property);
89
+ }
90
+ else {
91
+ message = fpm(message, path, property);
92
+ }
93
+ }
94
+
95
+ super(message, cause ? { cause } : undefined);
96
+
97
+ if (data) {
98
+ /** @type {any} */
99
+ this.data = { ...data, cause };
100
+ }
101
+ // restore prototype chain
102
+ const actualProto = new.target.prototype;
103
+
104
+ if (Object.setPrototypeOf) {
105
+ Object.setPrototypeOf(this, actualProto);
106
+ } else {
107
+ // @ts-ignore
108
+ this.__proto__ = actualProto;
109
+ }
110
+
111
+ if (!preserveStack) {
112
+ // @ts-ignore
113
+ delete this.stack;
114
+ }
115
+
116
+ if (data?.cause && !super.cause) {
117
+ // should be set on super, but just in case...
118
+ this.cause = data.cause;
119
+ }
120
+ }
121
+
122
+ get name() {
123
+ return this.constructor.name;
124
+ }
125
+ get stack() {
126
+ return "";
127
+ }
128
+
129
+ set stack(str) {}
130
+
131
+ // get cause() {
132
+ // return super.cause ?? this.data?.cause;
133
+ // }
134
+
135
+ toString() {
136
+ if (this.message) {
137
+ return `${this.name}: ${this.message}`;
138
+ } else {
139
+ // @ts-ignore
140
+ if (this.cause?.message) {
141
+ // @ts-ignore
142
+ return `${this.name}: ${this.cause.message}`;
143
+ } else {
144
+ return this.name;
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+ /**
151
+ * @param {Error} error
152
+ * @param {RegExp|string} match
153
+ * @param {string} [fullErrorMessage]
154
+ * @param {Error} [err]
155
+ * @returns {boolean}
156
+ * @internal
157
+ */
158
+ export function assertErrorMessageInCauseChain(error, match, fullErrorMessage, err) {
159
+
160
+ if (err === undefined) {
161
+ err = new Error('message not found in cause chain');
162
+ }
163
+
164
+ const errorMessage = (error?.message ?? '');
165
+
166
+ fullErrorMessage = fullErrorMessage? `${fullErrorMessage} «${errorMessage}»` : `«${errorMessage}»`;
167
+
168
+ if (match instanceof RegExp && match.test(errorMessage)) {
169
+ return true;
170
+ }
171
+ else if (errorMessage.toLowerCase() === `${match}`.toLowerCase()) {
172
+ return true;
173
+ }
174
+ else if (error.cause instanceof Error) {
175
+ return assertErrorMessageInCauseChain(error.cause, match, fullErrorMessage, err );
176
+ }
177
+ else {
178
+ err.message = `«${match}» not found in cause chain ${fullErrorMessage}`;
179
+ throw err;
180
+ }
181
+ }
182
+
183
+
184
+ export class ConstraintError
185
+ extends SchemaError {}
186
+
187
+ export class ValidationError
188
+ extends SchemaError {}
189
+
190
+ export class NormalizeError
191
+ extends SchemaError {}
192
+
193
+ export class TransformError
194
+ extends SchemaError {}
195
+
196
+ export class FinalizeError
197
+ extends SchemaError {}
198
+
199
+ export class SerializeError
200
+ extends SchemaError {}
201
+
202
+ export class UnionResolutionError
203
+ extends SchemaError {}
204
+
205
+ export class ResolverError
206
+ extends SchemaError {}
207
+
208
+ export class SchemaCompilationError
209
+ extends SchemaError {}
@@ -0,0 +1,78 @@
1
+ import { Executor, toExecutor } from './executor.js';
2
+
3
+ /**
4
+ * @augments {Executor<any>}
5
+ */
6
+ export class ArrayExecutor extends Executor {
7
+
8
+ /** @type {Executor<any>[]} */
9
+ #executors = [];
10
+
11
+ /** @type {any} */
12
+ #constantValue;
13
+
14
+ /**
15
+ * @param {any[]|any} [array]
16
+ */
17
+ constructor(array = []) {
18
+ if (!Array.isArray(array)) {
19
+ array = [array];
20
+ }
21
+ super();
22
+
23
+ let isConstant = true;
24
+ for (const item of array) {
25
+ const itemExecutor = toExecutor(item);
26
+ isConstant &&= itemExecutor.isConstant;
27
+ this.#executors.push(itemExecutor);
28
+ }
29
+ this.#constantValue = isConstant ? this.#executors.map(executor => executor.execute(true)) : undefined;
30
+ }
31
+ /**
32
+ * @param {any} input
33
+ * @param {...any} extra
34
+ * @returns {any[]|Promise<any[]>}
35
+ */
36
+ execute(input, ...extra) {
37
+ if (this.#constantValue !== undefined) {
38
+ return this.#constantValue;
39
+ }
40
+ const output = [];
41
+ let current = 0;
42
+
43
+ const executors = this.#executors;
44
+
45
+ while (current < executors.length) {
46
+ const result = executors[current++].execute(input, ...extra);
47
+
48
+ if (result instanceof Promise) {
49
+ return result.then(resolved => {
50
+ output.push(resolved);
51
+ return this.#resume(input, extra, current, output)
52
+ })
53
+ }
54
+ else {
55
+ output.push(result);
56
+ }
57
+ }
58
+ return output;
59
+ }
60
+
61
+ /**
62
+ * @param {any} input
63
+ * @param {any[]} extra
64
+ * @param {number} resumeIndex
65
+ * @param {Array<any>} output
66
+ * @returns {Promise<any[]>}
67
+ */
68
+ async #resume(input, extra, resumeIndex, output) {
69
+ while (resumeIndex < this.#executors.length) {
70
+ output.push(await this.#executors[resumeIndex++].execute(input, ...extra));
71
+ }
72
+ return output;
73
+ }
74
+
75
+ get isConstant() {
76
+ return this.#constantValue !== undefined;
77
+ }
78
+ }