@fougere/schema 0.6.0-alpha.0 → 0.7.0-alpha.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 (421) hide show
  1. package/README.md +5 -4
  2. package/dist/{schema/Schema.d.ts → Schema.d.ts} +17 -27
  3. package/dist/Schema.d.ts.map +1 -0
  4. package/dist/{schema/Schema.js → Schema.js} +21 -61
  5. package/dist/Schema.js.map +1 -0
  6. package/dist/SchemaDefinition.d.ts +73 -0
  7. package/dist/SchemaDefinition.d.ts.map +1 -0
  8. package/dist/SchemaDefinition.js +184 -0
  9. package/dist/SchemaDefinition.js.map +1 -0
  10. package/dist/SchemaDerivation.d.ts +16 -0
  11. package/dist/SchemaDerivation.d.ts.map +1 -0
  12. package/dist/SchemaDerivation.js +31 -0
  13. package/dist/SchemaDerivation.js.map +1 -0
  14. package/dist/{schema/SchemaView.d.ts → SchemaView.d.ts} +9 -9
  15. package/dist/SchemaView.d.ts.map +1 -0
  16. package/dist/{schema/SchemaView.js.map → SchemaView.js.map} +1 -1
  17. package/dist/{schema/axis → axis}/Axis.d.ts +2 -2
  18. package/dist/axis/Axis.d.ts.map +1 -0
  19. package/dist/axis/Axis.js.map +1 -0
  20. package/dist/axis/Meta.d.ts.map +1 -0
  21. package/dist/{schema/axis → axis}/Meta.js.map +1 -1
  22. package/dist/axis/boundary/Boundaries.d.ts +21 -0
  23. package/dist/axis/boundary/Boundaries.d.ts.map +1 -0
  24. package/dist/axis/boundary/Boundaries.js +25 -0
  25. package/dist/axis/boundary/Boundaries.js.map +1 -0
  26. package/dist/{schema/axis → axis}/boundary/Boundary.d.ts +3 -1
  27. package/dist/axis/boundary/Boundary.d.ts.map +1 -0
  28. package/dist/{schema/axis → axis}/boundary/Boundary.js +8 -6
  29. package/dist/axis/boundary/Boundary.js.map +1 -0
  30. package/dist/axis/boundary/BoundaryAxis.d.ts.map +1 -0
  31. package/dist/{schema/axis → axis}/boundary/BoundaryAxis.js +4 -4
  32. package/dist/axis/boundary/BoundaryAxis.js.map +1 -0
  33. package/dist/{schema/axis → axis}/lifecycle/Clock.d.ts +1 -1
  34. package/dist/axis/lifecycle/Clock.d.ts.map +1 -0
  35. package/dist/{schema/axis → axis}/lifecycle/Clock.js +1 -1
  36. package/dist/axis/lifecycle/Clock.js.map +1 -0
  37. package/dist/axis/lifecycle/Generators.d.ts +10 -0
  38. package/dist/axis/lifecycle/Generators.d.ts.map +1 -0
  39. package/dist/axis/lifecycle/Generators.js +20 -0
  40. package/dist/axis/lifecycle/Generators.js.map +1 -0
  41. package/dist/axis/lifecycle/Lifecycle.d.ts.map +1 -0
  42. package/dist/axis/lifecycle/Lifecycle.js.map +1 -0
  43. package/dist/axis/lifecycle/LifecycleAxis.d.ts.map +1 -0
  44. package/dist/{schema/axis → axis}/lifecycle/LifecycleAxis.js +11 -6
  45. package/dist/axis/lifecycle/LifecycleAxis.js.map +1 -0
  46. package/dist/axis/lifecycle/apply.d.ts +15 -0
  47. package/dist/axis/lifecycle/apply.d.ts.map +1 -0
  48. package/dist/axis/lifecycle/apply.js +50 -0
  49. package/dist/axis/lifecycle/apply.js.map +1 -0
  50. package/dist/{schema/axis → axis}/role/Relation.d.ts +3 -2
  51. package/dist/axis/role/Relation.d.ts.map +1 -0
  52. package/dist/{schema/axis → axis}/role/Relation.js +6 -5
  53. package/dist/axis/role/Relation.js.map +1 -0
  54. package/dist/{schema/axis → axis}/role/Role.d.ts +6 -6
  55. package/dist/axis/role/Role.d.ts.map +1 -0
  56. package/dist/axis/role/Role.js +36 -0
  57. package/dist/axis/role/Role.js.map +1 -0
  58. package/dist/{schema/axis → axis}/role/RoleAxis.d.ts +1 -1
  59. package/dist/axis/role/RoleAxis.d.ts.map +1 -0
  60. package/dist/{schema/axis → axis}/role/RoleAxis.js +28 -36
  61. package/dist/axis/role/RoleAxis.js.map +1 -0
  62. package/dist/axis/shape/Formats.d.ts +11 -0
  63. package/dist/axis/shape/Formats.d.ts.map +1 -0
  64. package/dist/axis/shape/Formats.js +9 -0
  65. package/dist/axis/shape/Formats.js.map +1 -0
  66. package/dist/{schema/axis → axis}/shape/Shape.d.ts +5 -3
  67. package/dist/axis/shape/Shape.d.ts.map +1 -0
  68. package/dist/{schema/axis → axis}/shape/Shape.js +13 -13
  69. package/dist/axis/shape/Shape.js.map +1 -0
  70. package/dist/entity/EntityAdapterSet.d.ts +22 -0
  71. package/dist/entity/EntityAdapterSet.d.ts.map +1 -0
  72. package/dist/entity/EntityAdapterSet.js +63 -0
  73. package/dist/entity/EntityAdapterSet.js.map +1 -0
  74. package/dist/entity/EntityAdapters.d.ts +1 -24
  75. package/dist/entity/EntityAdapters.d.ts.map +1 -1
  76. package/dist/entity/EntityAdapters.js +1 -74
  77. package/dist/entity/EntityAdapters.js.map +1 -1
  78. package/dist/entity/EntityDeclarations.d.ts +1 -1
  79. package/dist/entity/EntityDeclarations.d.ts.map +1 -1
  80. package/dist/entity.d.ts +7 -2
  81. package/dist/entity.d.ts.map +1 -1
  82. package/dist/entity.js +6 -1
  83. package/dist/entity.js.map +1 -1
  84. package/dist/{schema/fields → field}/Field.d.ts +2 -3
  85. package/dist/field/Field.d.ts.map +1 -0
  86. package/dist/field/Field.js +35 -0
  87. package/dist/field/Field.js.map +1 -0
  88. package/dist/field/FieldSet.d.ts +22 -0
  89. package/dist/field/FieldSet.d.ts.map +1 -0
  90. package/dist/field/FieldSet.js +58 -0
  91. package/dist/field/FieldSet.js.map +1 -0
  92. package/dist/index.d.ts +27 -30
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +20 -23
  95. package/dist/index.js.map +1 -1
  96. package/dist/lib/Registry.d.ts +12 -0
  97. package/dist/lib/Registry.d.ts.map +1 -0
  98. package/dist/lib/Registry.js +29 -0
  99. package/dist/lib/Registry.js.map +1 -0
  100. package/dist/lib/utils.d.ts.map +1 -0
  101. package/dist/lib/utils.js.map +1 -0
  102. package/dist/projection/Cases.d.ts +9 -20
  103. package/dist/projection/Cases.d.ts.map +1 -1
  104. package/dist/projection/Cases.js +44 -39
  105. package/dist/projection/Cases.js.map +1 -1
  106. package/dist/projection/Visibility.d.ts +2 -1
  107. package/dist/projection/Visibility.d.ts.map +1 -1
  108. package/dist/projection/Visibility.js +4 -3
  109. package/dist/projection/Visibility.js.map +1 -1
  110. package/dist/projection/card/Bundle.d.ts +1 -1
  111. package/dist/projection/card/Bundle.d.ts.map +1 -1
  112. package/dist/projection/card/Bundle.js +7 -7
  113. package/dist/projection/card/Bundle.js.map +1 -1
  114. package/dist/projection/card/Card.d.ts +7 -13
  115. package/dist/projection/card/Card.d.ts.map +1 -1
  116. package/dist/projection/card/Card.js +96 -69
  117. package/dist/projection/card/Card.js.map +1 -1
  118. package/dist/projection/card/Descriptor.d.ts +7 -7
  119. package/dist/projection/card/Descriptor.d.ts.map +1 -1
  120. package/dist/projection/card/admission.d.ts +15 -5
  121. package/dist/projection/card/admission.d.ts.map +1 -1
  122. package/dist/projection/card/admission.js +15 -5
  123. package/dist/projection/card/admission.js.map +1 -1
  124. package/dist/projection/card/diff.d.ts +2 -2
  125. package/dist/projection/card/diff.d.ts.map +1 -1
  126. package/dist/{judge/result.d.ts → validation.d.ts} +1 -1
  127. package/dist/validation.d.ts.map +1 -0
  128. package/dist/validation.js +2 -0
  129. package/dist/validation.js.map +1 -0
  130. package/dist/validator/AdapterFieldValidator.d.ts +14 -0
  131. package/dist/validator/AdapterFieldValidator.d.ts.map +1 -0
  132. package/dist/validator/AdapterFieldValidator.js +36 -0
  133. package/dist/validator/AdapterFieldValidator.js.map +1 -0
  134. package/dist/validator/FieldDeclarationValidator.d.ts +9 -0
  135. package/dist/validator/FieldDeclarationValidator.d.ts.map +1 -0
  136. package/dist/{judge/FieldJudge.js → validator/FieldDeclarationValidator.js} +8 -8
  137. package/dist/validator/FieldDeclarationValidator.js.map +1 -0
  138. package/dist/validator/FieldValueValidator.d.ts +13 -0
  139. package/dist/validator/FieldValueValidator.d.ts.map +1 -0
  140. package/dist/{judge/ValueJudge.js → validator/FieldValueValidator.js} +12 -11
  141. package/dist/validator/FieldValueValidator.js.map +1 -0
  142. package/dist/{judge/RowRefusal.d.ts → validator/InputRefusal.d.ts} +3 -4
  143. package/dist/validator/InputRefusal.d.ts.map +1 -0
  144. package/dist/{judge/RowRefusal.js → validator/InputRefusal.js} +3 -3
  145. package/dist/validator/InputRefusal.js.map +1 -0
  146. package/dist/validator/InputValidator.d.ts +15 -0
  147. package/dist/validator/InputValidator.d.ts.map +1 -0
  148. package/dist/{judge/RowJudge.js → validator/InputValidator.js} +24 -20
  149. package/dist/validator/InputValidator.js.map +1 -0
  150. package/dist/vocabulary/bool.d.ts +6 -1
  151. package/dist/vocabulary/bool.d.ts.map +1 -1
  152. package/dist/vocabulary/bool.js +6 -1
  153. package/dist/vocabulary/bool.js.map +1 -1
  154. package/dist/vocabulary/created.d.ts +6 -1
  155. package/dist/vocabulary/created.d.ts.map +1 -1
  156. package/dist/vocabulary/created.js +5 -0
  157. package/dist/vocabulary/created.js.map +1 -1
  158. package/dist/vocabulary/date.d.ts +6 -1
  159. package/dist/vocabulary/date.d.ts.map +1 -1
  160. package/dist/vocabulary/date.js +6 -1
  161. package/dist/vocabulary/date.js.map +1 -1
  162. package/dist/vocabulary/email.d.ts +6 -1
  163. package/dist/vocabulary/email.d.ts.map +1 -1
  164. package/dist/vocabulary/email.js +5 -0
  165. package/dist/vocabulary/email.js.map +1 -1
  166. package/dist/vocabulary/immutable.d.ts +6 -1
  167. package/dist/vocabulary/immutable.d.ts.map +1 -1
  168. package/dist/vocabulary/immutable.js +5 -0
  169. package/dist/vocabulary/immutable.js.map +1 -1
  170. package/dist/vocabulary/indexed.d.ts +6 -1
  171. package/dist/vocabulary/indexed.d.ts.map +1 -1
  172. package/dist/vocabulary/indexed.js +5 -0
  173. package/dist/vocabulary/indexed.js.map +1 -1
  174. package/dist/vocabulary/json.d.ts +2 -2
  175. package/dist/vocabulary/json.d.ts.map +1 -1
  176. package/dist/vocabulary/json.js +9 -4
  177. package/dist/vocabulary/json.js.map +1 -1
  178. package/dist/vocabulary/list.d.ts +6 -1
  179. package/dist/vocabulary/list.d.ts.map +1 -1
  180. package/dist/vocabulary/list.js +6 -1
  181. package/dist/vocabulary/list.js.map +1 -1
  182. package/dist/vocabulary/many.d.ts +7 -2
  183. package/dist/vocabulary/many.d.ts.map +1 -1
  184. package/dist/vocabulary/many.js +7 -2
  185. package/dist/vocabulary/many.js.map +1 -1
  186. package/dist/vocabulary/nullable.d.ts +6 -1
  187. package/dist/vocabulary/nullable.d.ts.map +1 -1
  188. package/dist/vocabulary/nullable.js +7 -2
  189. package/dist/vocabulary/nullable.js.map +1 -1
  190. package/dist/vocabulary/number.d.ts +6 -1
  191. package/dist/vocabulary/number.d.ts.map +1 -1
  192. package/dist/vocabulary/number.js +6 -1
  193. package/dist/vocabulary/number.js.map +1 -1
  194. package/dist/vocabulary/oneOf.d.ts +1 -1
  195. package/dist/vocabulary/oneOf.d.ts.map +1 -1
  196. package/dist/vocabulary/oneOf.js +6 -1
  197. package/dist/vocabulary/oneOf.js.map +1 -1
  198. package/dist/vocabulary/optional.d.ts +6 -1
  199. package/dist/vocabulary/optional.d.ts.map +1 -1
  200. package/dist/vocabulary/optional.js +7 -2
  201. package/dist/vocabulary/optional.js.map +1 -1
  202. package/dist/vocabulary/primary.d.ts +2 -2
  203. package/dist/vocabulary/primary.d.ts.map +1 -1
  204. package/dist/vocabulary/primary.js +7 -2
  205. package/dist/vocabulary/primary.js.map +1 -1
  206. package/dist/vocabulary/readOnly.d.ts +6 -1
  207. package/dist/vocabulary/readOnly.d.ts.map +1 -1
  208. package/dist/vocabulary/readOnly.js +6 -1
  209. package/dist/vocabulary/readOnly.js.map +1 -1
  210. package/dist/vocabulary/ref.d.ts +7 -2
  211. package/dist/vocabulary/ref.d.ts.map +1 -1
  212. package/dist/vocabulary/ref.js +7 -2
  213. package/dist/vocabulary/ref.js.map +1 -1
  214. package/dist/vocabulary/text.d.ts +7 -2
  215. package/dist/vocabulary/text.d.ts.map +1 -1
  216. package/dist/vocabulary/text.js +6 -1
  217. package/dist/vocabulary/text.js.map +1 -1
  218. package/dist/vocabulary/unique.d.ts +6 -1
  219. package/dist/vocabulary/unique.d.ts.map +1 -1
  220. package/dist/vocabulary/unique.js +7 -3
  221. package/dist/vocabulary/unique.js.map +1 -1
  222. package/dist/vocabulary/updated.d.ts +6 -1
  223. package/dist/vocabulary/updated.d.ts.map +1 -1
  224. package/dist/vocabulary/updated.js +5 -0
  225. package/dist/vocabulary/updated.js.map +1 -1
  226. package/dist/vocabulary/url.d.ts +6 -1
  227. package/dist/vocabulary/url.d.ts.map +1 -1
  228. package/dist/vocabulary/url.js +5 -0
  229. package/dist/vocabulary/url.js.map +1 -1
  230. package/dist/vocabulary/vocabulary.d.ts +6 -1
  231. package/dist/vocabulary/vocabulary.d.ts.map +1 -1
  232. package/dist/vocabulary/vocabulary.js +22 -12
  233. package/dist/vocabulary/vocabulary.js.map +1 -1
  234. package/dist/vocabulary/writeOnly.d.ts +6 -1
  235. package/dist/vocabulary/writeOnly.d.ts.map +1 -1
  236. package/dist/vocabulary/writeOnly.js +6 -1
  237. package/dist/vocabulary/writeOnly.js.map +1 -1
  238. package/package.json +1 -1
  239. package/src/{schema/Schema.ts → Schema.ts} +31 -74
  240. package/src/SchemaDefinition.ts +257 -0
  241. package/src/SchemaDerivation.ts +44 -0
  242. package/src/{schema/SchemaView.ts → SchemaView.ts} +9 -9
  243. package/src/{schema/axis → axis}/Axis.ts +2 -2
  244. package/src/axis/boundary/Boundaries.ts +37 -0
  245. package/src/{schema/axis → axis}/boundary/Boundary.ts +9 -7
  246. package/src/{schema/axis → axis}/boundary/BoundaryAxis.ts +4 -4
  247. package/src/{schema/axis → axis}/lifecycle/Clock.ts +1 -1
  248. package/src/axis/lifecycle/Generators.ts +29 -0
  249. package/src/{schema/axis → axis}/lifecycle/LifecycleAxis.ts +12 -7
  250. package/src/axis/lifecycle/apply.ts +53 -0
  251. package/src/{schema/axis → axis}/role/Relation.ts +6 -5
  252. package/src/axis/role/Role.ts +52 -0
  253. package/src/{schema/axis → axis}/role/RoleAxis.ts +28 -40
  254. package/src/axis/shape/Formats.ts +20 -0
  255. package/src/{schema/axis → axis}/shape/Shape.ts +18 -18
  256. package/src/entity/EntityAdapterSet.ts +81 -0
  257. package/src/entity/EntityAdapters.ts +4 -96
  258. package/src/entity/EntityDeclarations.ts +1 -1
  259. package/src/entity.ts +7 -2
  260. package/src/{schema/fields → field}/Field.ts +8 -26
  261. package/src/field/FieldSet.ts +75 -0
  262. package/src/index.ts +29 -44
  263. package/src/lib/Registry.ts +37 -0
  264. package/src/projection/Cases.ts +56 -55
  265. package/src/projection/Visibility.ts +5 -4
  266. package/src/projection/card/Bundle.ts +9 -9
  267. package/src/projection/card/Card.ts +101 -74
  268. package/src/projection/card/Descriptor.ts +7 -7
  269. package/src/projection/card/admission.ts +16 -6
  270. package/src/projection/card/diff.ts +2 -2
  271. package/src/validator/AdapterFieldValidator.ts +40 -0
  272. package/src/{judge/FieldJudge.ts → validator/FieldDeclarationValidator.ts} +10 -10
  273. package/src/{judge/ValueJudge.ts → validator/FieldValueValidator.ts} +14 -13
  274. package/src/{judge/RowRefusal.ts → validator/InputRefusal.ts} +2 -4
  275. package/src/{judge/RowJudge.ts → validator/InputValidator.ts} +30 -23
  276. package/src/vocabulary/bool.ts +6 -1
  277. package/src/vocabulary/created.ts +6 -1
  278. package/src/vocabulary/date.ts +6 -1
  279. package/src/vocabulary/email.ts +6 -1
  280. package/src/vocabulary/immutable.ts +6 -1
  281. package/src/vocabulary/indexed.ts +6 -1
  282. package/src/vocabulary/json.ts +10 -5
  283. package/src/vocabulary/list.ts +6 -1
  284. package/src/vocabulary/many.ts +7 -2
  285. package/src/vocabulary/nullable.ts +8 -3
  286. package/src/vocabulary/number.ts +6 -1
  287. package/src/vocabulary/oneOf.ts +6 -1
  288. package/src/vocabulary/optional.ts +8 -3
  289. package/src/vocabulary/primary.ts +7 -2
  290. package/src/vocabulary/readOnly.ts +7 -2
  291. package/src/vocabulary/ref.ts +7 -2
  292. package/src/vocabulary/text.ts +7 -2
  293. package/src/vocabulary/unique.ts +8 -4
  294. package/src/vocabulary/updated.ts +6 -1
  295. package/src/vocabulary/url.ts +6 -1
  296. package/src/vocabulary/vocabulary.ts +22 -12
  297. package/src/vocabulary/writeOnly.ts +7 -2
  298. package/dist/judge/FieldJudge.d.ts +0 -9
  299. package/dist/judge/FieldJudge.d.ts.map +0 -1
  300. package/dist/judge/FieldJudge.js.map +0 -1
  301. package/dist/judge/RowJudge.d.ts +0 -12
  302. package/dist/judge/RowJudge.d.ts.map +0 -1
  303. package/dist/judge/RowJudge.js.map +0 -1
  304. package/dist/judge/RowRefusal.d.ts.map +0 -1
  305. package/dist/judge/RowRefusal.js.map +0 -1
  306. package/dist/judge/ValueJudge.d.ts +0 -12
  307. package/dist/judge/ValueJudge.d.ts.map +0 -1
  308. package/dist/judge/ValueJudge.js.map +0 -1
  309. package/dist/judge/options.d.ts +0 -4
  310. package/dist/judge/options.d.ts.map +0 -1
  311. package/dist/judge/options.js +0 -2
  312. package/dist/judge/options.js.map +0 -1
  313. package/dist/judge/result.d.ts.map +0 -1
  314. package/dist/judge/result.js +0 -2
  315. package/dist/judge/result.js.map +0 -1
  316. package/dist/projection/SchemaOrCard.d.ts +0 -7
  317. package/dist/projection/SchemaOrCard.d.ts.map +0 -1
  318. package/dist/projection/SchemaOrCard.js +0 -11
  319. package/dist/projection/SchemaOrCard.js.map +0 -1
  320. package/dist/projection/card/EntityTypeSource.d.ts +0 -12
  321. package/dist/projection/card/EntityTypeSource.d.ts.map +0 -1
  322. package/dist/projection/card/EntityTypeSource.js +0 -78
  323. package/dist/projection/card/EntityTypeSource.js.map +0 -1
  324. package/dist/projection/card/FacadeTypeSource.d.ts +0 -19
  325. package/dist/projection/card/FacadeTypeSource.d.ts.map +0 -1
  326. package/dist/projection/card/FacadeTypeSource.js +0 -40
  327. package/dist/projection/card/FacadeTypeSource.js.map +0 -1
  328. package/dist/schema/Schema.d.ts.map +0 -1
  329. package/dist/schema/Schema.js.map +0 -1
  330. package/dist/schema/SchemaDefinition.d.ts +0 -60
  331. package/dist/schema/SchemaDefinition.d.ts.map +0 -1
  332. package/dist/schema/SchemaDefinition.js +0 -85
  333. package/dist/schema/SchemaDefinition.js.map +0 -1
  334. package/dist/schema/SchemaDerivation.d.ts +0 -34
  335. package/dist/schema/SchemaDerivation.d.ts.map +0 -1
  336. package/dist/schema/SchemaDerivation.js +0 -51
  337. package/dist/schema/SchemaDerivation.js.map +0 -1
  338. package/dist/schema/SchemaView.d.ts.map +0 -1
  339. package/dist/schema/axis/Axis.d.ts.map +0 -1
  340. package/dist/schema/axis/Axis.js.map +0 -1
  341. package/dist/schema/axis/Meta.d.ts.map +0 -1
  342. package/dist/schema/axis/boundary/Boundaries.d.ts +0 -20
  343. package/dist/schema/axis/boundary/Boundaries.d.ts.map +0 -1
  344. package/dist/schema/axis/boundary/Boundaries.js +0 -31
  345. package/dist/schema/axis/boundary/Boundaries.js.map +0 -1
  346. package/dist/schema/axis/boundary/Boundary.d.ts.map +0 -1
  347. package/dist/schema/axis/boundary/Boundary.js.map +0 -1
  348. package/dist/schema/axis/boundary/BoundaryAxis.d.ts.map +0 -1
  349. package/dist/schema/axis/boundary/BoundaryAxis.js.map +0 -1
  350. package/dist/schema/axis/lifecycle/Clock.d.ts.map +0 -1
  351. package/dist/schema/axis/lifecycle/Clock.js.map +0 -1
  352. package/dist/schema/axis/lifecycle/Generators.d.ts +0 -18
  353. package/dist/schema/axis/lifecycle/Generators.d.ts.map +0 -1
  354. package/dist/schema/axis/lifecycle/Generators.js +0 -38
  355. package/dist/schema/axis/lifecycle/Generators.js.map +0 -1
  356. package/dist/schema/axis/lifecycle/Lifecycle.d.ts.map +0 -1
  357. package/dist/schema/axis/lifecycle/Lifecycle.js.map +0 -1
  358. package/dist/schema/axis/lifecycle/LifecycleAxis.d.ts.map +0 -1
  359. package/dist/schema/axis/lifecycle/LifecycleAxis.js.map +0 -1
  360. package/dist/schema/axis/lifecycle/apply.d.ts +0 -6
  361. package/dist/schema/axis/lifecycle/apply.d.ts.map +0 -1
  362. package/dist/schema/axis/lifecycle/apply.js +0 -34
  363. package/dist/schema/axis/lifecycle/apply.js.map +0 -1
  364. package/dist/schema/axis/role/Relation.d.ts.map +0 -1
  365. package/dist/schema/axis/role/Relation.js.map +0 -1
  366. package/dist/schema/axis/role/Role.d.ts.map +0 -1
  367. package/dist/schema/axis/role/Role.js +0 -40
  368. package/dist/schema/axis/role/Role.js.map +0 -1
  369. package/dist/schema/axis/role/RoleAxis.d.ts.map +0 -1
  370. package/dist/schema/axis/role/RoleAxis.js.map +0 -1
  371. package/dist/schema/axis/shape/Formats.d.ts +0 -8
  372. package/dist/schema/axis/shape/Formats.d.ts.map +0 -1
  373. package/dist/schema/axis/shape/Formats.js +0 -10
  374. package/dist/schema/axis/shape/Formats.js.map +0 -1
  375. package/dist/schema/axis/shape/Shape.d.ts.map +0 -1
  376. package/dist/schema/axis/shape/Shape.js.map +0 -1
  377. package/dist/schema/fields/Field.d.ts.map +0 -1
  378. package/dist/schema/fields/Field.js +0 -52
  379. package/dist/schema/fields/Field.js.map +0 -1
  380. package/dist/schema/fields/FieldSet.d.ts +0 -28
  381. package/dist/schema/fields/FieldSet.d.ts.map +0 -1
  382. package/dist/schema/fields/FieldSet.js +0 -55
  383. package/dist/schema/fields/FieldSet.js.map +0 -1
  384. package/dist/schema/fields/constraint/FieldGroup.d.ts +0 -21
  385. package/dist/schema/fields/constraint/FieldGroup.d.ts.map +0 -1
  386. package/dist/schema/fields/constraint/FieldGroup.js +0 -65
  387. package/dist/schema/fields/constraint/FieldGroup.js.map +0 -1
  388. package/dist/schema/fields/constraint/Unique.d.ts +0 -4
  389. package/dist/schema/fields/constraint/Unique.d.ts.map +0 -1
  390. package/dist/schema/fields/constraint/Unique.js +0 -4
  391. package/dist/schema/fields/constraint/Unique.js.map +0 -1
  392. package/dist/utils.d.ts.map +0 -1
  393. package/dist/utils.js.map +0 -1
  394. package/src/judge/options.ts +0 -3
  395. package/src/projection/SchemaOrCard.ts +0 -18
  396. package/src/projection/card/EntityTypeSource.ts +0 -90
  397. package/src/projection/card/FacadeTypeSource.ts +0 -55
  398. package/src/schema/SchemaDefinition.ts +0 -150
  399. package/src/schema/SchemaDerivation.ts +0 -65
  400. package/src/schema/axis/boundary/Boundaries.ts +0 -44
  401. package/src/schema/axis/lifecycle/Generators.ts +0 -46
  402. package/src/schema/axis/lifecycle/apply.ts +0 -39
  403. package/src/schema/axis/role/Role.ts +0 -56
  404. package/src/schema/axis/shape/Formats.ts +0 -22
  405. package/src/schema/fields/FieldSet.ts +0 -63
  406. package/src/schema/fields/constraint/FieldGroup.ts +0 -84
  407. package/src/schema/fields/constraint/Unique.ts +0 -3
  408. /package/dist/{schema/SchemaView.js → SchemaView.js} +0 -0
  409. /package/dist/{schema/axis → axis}/Axis.js +0 -0
  410. /package/dist/{schema/axis → axis}/Meta.d.ts +0 -0
  411. /package/dist/{schema/axis → axis}/Meta.js +0 -0
  412. /package/dist/{schema/axis → axis}/boundary/BoundaryAxis.d.ts +0 -0
  413. /package/dist/{schema/axis → axis}/lifecycle/Lifecycle.d.ts +0 -0
  414. /package/dist/{schema/axis → axis}/lifecycle/Lifecycle.js +0 -0
  415. /package/dist/{schema/axis → axis}/lifecycle/LifecycleAxis.d.ts +0 -0
  416. /package/dist/{utils.d.ts → lib/utils.d.ts} +0 -0
  417. /package/dist/{utils.js → lib/utils.js} +0 -0
  418. /package/src/{schema/axis → axis}/Meta.ts +0 -0
  419. /package/src/{schema/axis → axis}/lifecycle/Lifecycle.ts +0 -0
  420. /package/src/{utils.ts → lib/utils.ts} +0 -0
  421. /package/src/{judge/result.ts → validation.ts} +0 -0
@@ -1,31 +1,41 @@
1
- import { EXTENSION_SLOTS } from '../schema/axis/Axis.js';
1
+ import { EXTENSION_SLOTS } from '../axis/Axis.js';
2
2
  import { dequal } from 'dequal';
3
3
  const MEMBER_SLOTS = [...EXTENSION_SLOTS, 'meta'];
4
+ /**
5
+ * So a word is one statement about a field, not a rebuilt field.
6
+ * FR : pour qu'un mot soit une affirmation sur un champ, pas un champ reconstruit.
7
+ * `vocabulary('indexed', () => ({ role: { index: true } }))`
8
+ */
4
9
  export function vocabulary(name, states) {
5
10
  return (field) => field.with(merge(name, field, states(field)));
6
11
  }
7
- function merge(name, field, stated) {
8
- const out = {};
9
- if ('shape' in stated)
10
- out.shape = stated.shape;
12
+ /**
13
+ * So two words that state the same member differently refuse instead of one winning.
14
+ * FR : pour que deux mots contredisant un même membre refusent, plutôt qu'un l'emporte.
15
+ * `readOnly(writeOnly(text()))` → both close a different side, so both apply
16
+ */
17
+ function merge(name, field, given) {
18
+ const merged = {};
19
+ if ('shape' in given)
20
+ merged.shape = given.shape;
11
21
  for (const slot of MEMBER_SLOTS) {
12
- const members = stated[slot];
22
+ const members = given[slot];
13
23
  if (members === undefined)
14
24
  continue;
15
- const held = field[slot];
16
- if (typeof members !== 'object' || members === null || typeof held !== 'object') {
17
- out[slot] = members;
25
+ const already = field[slot];
26
+ if (typeof members !== 'object' || members === null || typeof already !== 'object') {
27
+ merged[slot] = members;
18
28
  continue;
19
29
  }
20
30
  for (const [member, value] of Object.entries(members)) {
21
- const previous = held?.[member];
31
+ const previous = already?.[member];
22
32
  if (previous === undefined || dequal(previous, value))
23
33
  continue;
24
34
  throw new Error(`vocabulary: \`${name}\` states ${slot}.${member} = ${JSON.stringify(value)}, but the ` +
25
35
  `field already states ${JSON.stringify(previous)}. Apply one or the other, not both.`);
26
36
  }
27
- out[slot] = { ...held, ...members };
37
+ merged[slot] = { ...already, ...members };
28
38
  }
29
- return out;
39
+ return merged;
30
40
  }
31
41
  //# sourceMappingURL=vocabulary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,YAAY,GAAG,CAAC,GAAG,eAAe,EAAE,MAAM,CAAU,CAAC;AAE3D,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,MAAwC;IAExC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAID,SAAS,KAAK,CAAC,IAAY,EAAE,KAAY,EAAE,MAAsB;IAC/D,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,IAAI,OAAO,IAAI,MAAM;QAAE,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAEhD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAwC,CAAC;QAChE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAChF,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;YACpB,SAAS;QACX,CAAC;QACD,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,MAAM,QAAQ,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC;gBAAE,SAAS;YAChE,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,aAAa,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY;gBACrF,wBAAwB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,qCAAqC,CACxF,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,GAAqB,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,YAAY,GAAG,CAAC,GAAG,eAAe,EAAE,MAAM,CAAU,CAAC;AAE3D;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,MAAwC;IAExC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAID;;;;GAIG;AACH,SAAS,KAAK,CAAC,IAAY,EAAE,KAAY,EAAE,KAAqB;IAC9D,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,IAAI,OAAO,IAAI,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAEjD,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAwC,CAAC;QACnE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACnF,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC;YACvB,SAAS;QACX,CAAC;QACD,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,MAAM,QAAQ,GAAG,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC;gBAAE,SAAS;YAChE,MAAM,IAAI,KAAK,CACb,iBAAiB,IAAI,aAAa,IAAI,IAAI,MAAM,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY;gBACrF,wBAAwB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,qCAAqC,CACxF,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,MAAwB,CAAC;AAClC,CAAC"}
@@ -1,3 +1,8 @@
1
- import { Field } from '../schema/fields/Field.js';
1
+ import { Field } from '../field/Field.js';
2
+ /**
3
+ * So a secret leaves no response, the dual of `readOnly` on the same axis.
4
+ * FR : pour qu'un secret ne reparte dans aucune réponse, dual de `readOnly`.
5
+ * `writeOnly(text())` → `boundary.out` is `'closed'`
6
+ */
2
7
  export declare const writeOnly: <T>(field: Field<T>) => Field<T>;
3
8
  //# sourceMappingURL=writeOnly.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writeOnly.d.ts","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAElD,eAAO,MAAM,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAKtD,CAAC"}
1
+ {"version":3,"file":"writeOnly.d.ts","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAKtD,CAAC"}
@@ -1,5 +1,10 @@
1
1
  import { vocabulary } from './vocabulary.js';
2
- import { Boundary } from '../schema/axis/boundary/Boundary.js';
2
+ import { Boundary } from '../axis/boundary/Boundary.js';
3
+ /**
4
+ * So a secret leaves no response, the dual of `readOnly` on the same axis.
5
+ * FR : pour qu'un secret ne reparte dans aucune réponse, dual de `readOnly`.
6
+ * `writeOnly(text())` → `boundary.out` is `'closed'`
7
+ */
3
8
  export const writeOnly = vocabulary('writeOnly', (field) => ({
4
9
  boundary: Boundary.declared(field).with({ out: 'closed' }),
5
10
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"writeOnly.js","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAG/D,MAAM,CAAC,MAAM,SAAS,GAAqC,UAAU,CACnE,WAAW,EACX,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACV,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;CAC3D,CAAC,CACH,CAAC"}
1
+ {"version":3,"file":"writeOnly.js","sourceRoot":"","sources":["../../src/vocabulary/writeOnly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAGxD;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAqC,UAAU,CACnE,WAAW,EACX,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACV,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;CAC3D,CAAC,CACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fougere/schema",
3
- "version": "0.6.0-alpha.0",
3
+ "version": "0.7.0-alpha.0",
4
4
  "description": "The entity and its 4 axes — shape, role, lifecycle, boundary. Subject-owned judgments, edge-safe.",
5
5
  "keywords": [
6
6
  "fougere",
@@ -1,29 +1,27 @@
1
1
  import { Boundary } from './axis/boundary/Boundary.js';
2
- import { type Fields } from './fields/Field.js';
2
+ import { type Fields } from './field/Field.js';
3
3
  import {
4
4
  type CompositeUnique,
5
5
  type EntityDeclarations,
6
6
  type PreviousNames,
7
- } from '../entity/EntityDeclarations.js';
8
- import { EntityAdapterSet, type EntityAdapters } from '../entity/EntityAdapters.js';
9
- import { FieldGroup } from './fields/constraint/FieldGroup.js';
10
- import { Unique } from './fields/constraint/Unique.js';
11
- import { RowJudge } from '../judge/RowJudge.js';
7
+ } from './entity/EntityDeclarations.js';
8
+ import { type EntityAdapters } from './entity/EntityAdapters.js';
9
+ import { InputValidator } from './validator/InputValidator.js';
12
10
  import { SchemaDerivation } from './SchemaDerivation.js';
13
- import { SchemaDefinition } from './SchemaDefinition.js';
14
- import { type ValidateOptions } from '../judge/options.js';
15
- import type { StandardSchemaV1 } from '../projection/standard.js';
16
- import type { PartialRow, Row, SchemaView } from './SchemaView.js';
11
+ import { SchemaDefinition, type SchemaConstraints } from './SchemaDefinition.js';
12
+ import { type ValidateOptions } from './validator/InputValidator.js';
13
+ import type { StandardSchemaV1 } from './projection/standard.js';
14
+ import type { PartialValues, Values, SchemaView } from './SchemaView.js';
17
15
 
18
16
  export const ANONYMOUS_SCHEMA_NAME = 'Schema';
19
17
 
20
18
  export interface SchemaConstructor<TFields extends Fields> extends SchemaView<TFields> {
21
- new (data: PartialRow<TFields>): Row<TFields>;
22
- readonly '~standard': StandardSchemaV1.Props<Record<string, unknown>, Row<TFields>>;
19
+ new (data: PartialValues<TFields>): Values<TFields>;
20
+ readonly '~standard': StandardSchemaV1.Props<Record<string, unknown>, Values<TFields>>;
23
21
  readonly derivation?: SchemaDerivation;
24
22
  readonly previous?: PreviousNames<TFields>;
25
23
  readonly anchored?: boolean;
26
- from(data: Record<string, unknown>): Row<TFields>;
24
+ from(data: Record<string, unknown>): Values<TFields>;
27
25
  pick<K extends string & keyof TFields>(
28
26
  ...keys: K[]
29
27
  ): SchemaConstructor<Pick<TFields, K>>;
@@ -42,13 +40,14 @@ export interface SchemaConstructor<TFields extends Fields> extends SchemaView<TF
42
40
 
43
41
  export class Schema {
44
42
  /** The one place a schema holds what it is. The readings below are its projections. */
45
- static definition: SchemaDefinition = SchemaDefinition.stated({ fields: {} });
43
+ static definition: SchemaDefinition = SchemaDefinition.of({ fields: {} });
46
44
 
47
45
  static get fields(): Fields {
48
46
  return this.definition.fields;
49
47
  }
50
- static get adapters(): EntityAdapters<Fields> | undefined {
51
- return this.definition.adapters;
48
+ /** An entry survives every derivation that kept its field: `Post.pick('body').adapters`. */
49
+ static get adapters(): EntityAdapters<Fields> {
50
+ return this.definition.adapterSet.adapters;
52
51
  }
53
52
  static get opts(): ValidateOptions {
54
53
  return this.definition.opts;
@@ -59,6 +58,7 @@ export class Schema {
59
58
  static get previous(): PreviousNames<Fields> | undefined {
60
59
  return this.definition.previous;
61
60
  }
61
+ /** An anchor holds rows of its own; a derivation borrows them. */
62
62
  static get anchored(): boolean {
63
63
  return this.definition.anchored;
64
64
  }
@@ -82,30 +82,29 @@ export class Schema {
82
82
  return this.adapters;
83
83
  }
84
84
  static getUnique(): CompositeUnique<Fields> | undefined {
85
- const groups = FieldGroup.groupsOf(this.fields, Unique);
86
- return groups.length ? groups.map((group) => [...group.members]) : undefined;
85
+ return this.definition.constraints.unique;
87
86
  }
88
87
  static getOpts() {
89
88
  return this.opts;
90
89
  }
91
90
 
92
91
  static validate(input: unknown) {
93
- return RowJudge.of(this.fields, this.opts).check(input);
92
+ return InputValidator.of(this.fields, this.opts).validate(input);
94
93
  }
95
94
 
96
95
  static from(data: Record<string, unknown>) {
97
- const out: Record<string, unknown> = {};
96
+ const row: Record<string, unknown> = {};
98
97
  for (const [key, field] of Object.entries(this.fields)) {
99
98
  if (!(key in data)) continue;
100
99
  const value = data[key];
101
100
  if (value === null || value === undefined) {
102
- out[key] = value;
101
+ row[key] = value;
103
102
  continue;
104
103
  }
105
104
  const decoded = Boundary.of(field).decode(value);
106
- out[key] = 'error' in decoded ? value : decoded.value;
105
+ row[key] = 'error' in decoded ? value : decoded.value;
107
106
  }
108
- return out;
107
+ return row;
109
108
  }
110
109
 
111
110
  static get ['~standard'](): StandardSchemaV1.Props<Record<string, unknown>> {
@@ -114,10 +113,10 @@ export class Schema {
114
113
  version: 1,
115
114
  vendor: 'fougere',
116
115
  validate(value: unknown) {
117
- const result = RowJudge.of(fields, opts).check(value);
118
- if (result.success) return { value: result.data };
116
+ const verdict = InputValidator.of(fields, opts).validate(value);
117
+ if (verdict.success) return { value: verdict.data };
119
118
  return {
120
- issues: result.errors.map((e) => ({
119
+ issues: verdict.errors.map((e) => ({
121
120
  message: e.message,
122
121
  path: e.path && e.path !== '.' ? [{ key: e.path }] : undefined,
123
122
  })),
@@ -127,50 +126,21 @@ export class Schema {
127
126
  }
128
127
 
129
128
  static pick(...keys: string[]) {
130
- assertKnownKeys('pick', keys, this.fields);
131
- const picked: Fields = {};
132
- for (const key of keys) if (this.fields[key]) picked[key] = this.fields[key];
133
- return this.derive(picked, (k) => (keys.includes(k) ? k : undefined));
129
+ return Schema.subclass(this.definition.pick(keys, this));
134
130
  }
135
131
 
136
132
  static omit(...keys: string[]) {
137
- assertKnownKeys('omit', keys, this.fields);
138
- const kept: Fields = {};
139
- for (const [key, field] of Object.entries(this.fields))
140
- if (!keys.includes(key)) kept[key] = field;
141
- return this.derive(kept, (k) => (keys.includes(k) ? undefined : k));
133
+ return Schema.subclass(this.definition.omit(keys, this));
142
134
  }
143
135
 
144
136
  static rename(mapping: Record<string, string>) {
145
- assertKnownKeys('rename', Object.keys(mapping), this.fields);
146
- const renamed: Fields = {};
147
- for (const [key, field] of Object.entries(this.fields))
148
- renamed[mapping[key] ?? key] = field;
149
- return this.derive(renamed, (k) => mapping[k] ?? k);
137
+ return Schema.subclass(this.definition.rename(mapping, this));
150
138
  }
151
139
 
152
- /**
153
- * Everything a schema states about ITSELF, available wherever a schema is. `entity(fields, …)`
154
- * is this same gesture at the declaration site; the fields do not move, so neither does the type.
155
- */
156
140
  static declares(declarations: EntityDeclarations<Fields>) {
157
- const addressed = EntityAdapterSet.of(declarations.adapters)?.fieldNames ?? [];
158
- assertKnownKeys(
159
- 'declares',
160
- [...addressed, ...Object.keys(declarations.previous ?? {})],
161
- this.fields,
162
- );
163
-
164
141
  return Schema.subclass(this.definition.declaring(declarations));
165
142
  }
166
143
 
167
- /**
168
- * This schema holds rows of its own — every entity is one, and a derivation says so.
169
- *
170
- * An anchor is where a walk STOPS: `derivation.anchor` climbs to the nearest one, and what
171
- * is cut from an anchor roots on it. Two anchors are two entities that happen to share a
172
- * shape, never a hierarchy — nothing here subtypes, so a relation between them is `ref()`.
173
- */
174
144
  static anchor() {
175
145
  return Schema.subclass(this.definition.anchoring());
176
146
  }
@@ -202,20 +172,20 @@ export class Schema {
202
172
  ) as unknown as SchemaConstructor<Merged<T>>;
203
173
  }
204
174
 
205
- static of<TFields extends Fields>(stated: {
175
+ static of<TFields extends Fields>(declaration: {
206
176
  fields: TFields;
207
177
  derivation?: SchemaDerivation;
208
178
  adapters?: EntityAdapters<TFields>;
209
179
  opts?: ValidateOptions;
210
180
  previous?: PreviousNames<TFields>;
211
181
  anchored?: boolean;
182
+ constraints?: SchemaConstraints;
212
183
  }): SchemaConstructor<TFields> {
213
184
  return Schema.subclass(
214
- SchemaDefinition.stated(stated),
185
+ SchemaDefinition.of(declaration),
215
186
  ) as unknown as SchemaConstructor<TFields>;
216
187
  }
217
188
 
218
- /** The class a definition becomes. The one place a Schema subclass is born. */
219
189
  private static subclass(definition: SchemaDefinition): SchemaConstructor<Fields> {
220
190
  class Derived extends Schema {}
221
191
  Derived.definition = definition;
@@ -225,19 +195,6 @@ export class Schema {
225
195
  });
226
196
  return Derived as unknown as SchemaConstructor<Fields>;
227
197
  }
228
-
229
- private static derive(fields: Fields, survives: (key: string) => string | undefined) {
230
- return Schema.subclass(this.definition.cut(fields, survives, this));
231
- }
232
- }
233
-
234
- function assertKnownKeys(operation: string, keys: string[], fields: Fields): void {
235
- const strangers = keys.filter((key) => !(key in fields));
236
- if (strangers.length === 0) return;
237
- throw new Error(
238
- `${operation}(): unknown field ${strangers.map((s) => `\`${s}\``).join(', ')}. ` +
239
- `This schema carries ${Object.keys(fields).join(', ')}.`,
240
- );
241
198
  }
242
199
 
243
200
  type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (
@@ -0,0 +1,257 @@
1
+ import { type Fields } from './field/Field.js';
2
+ import { FieldSet, deduplicated } from './field/FieldSet.js';
3
+ import {
4
+ type CompositeUnique,
5
+ type EntityDeclarations,
6
+ type PreviousNames,
7
+ } from './entity/EntityDeclarations.js';
8
+ import { type EntityAdapters } from './entity/EntityAdapters.js';
9
+ import { EntityAdapterSet } from './entity/EntityAdapterSet.js';
10
+ import { SchemaDerivation } from './SchemaDerivation.js';
11
+ import { type ValidateOptions } from './validator/InputValidator.js';
12
+ import type { SchemaView } from './SchemaView.js';
13
+
14
+ /**
15
+ * What a schema constrains beyond any single field.
16
+ *
17
+ * `unique` is the one member today. It sits under an owner rather than beside `fields`
18
+ * and `opts` because the next rule spanning two fields — a check, an exclusion — is a
19
+ * member here, not an eighth positional argument in a list that has already lost one.
20
+ */
21
+ export interface SchemaConstraints<TFields extends Fields = Fields> {
22
+ readonly unique?: CompositeUnique<TFields>;
23
+ }
24
+
25
+ /**
26
+ * Everything a definition is made of, every member required.
27
+ *
28
+ * A transformation states what it keeps AND what it clears — `previous: undefined` and
29
+ * `anchored: false` are the two a derivation decides, and positionally they were an
30
+ * `undefined` and a `false` a reader had to count arguments to name.
31
+ */
32
+ interface SchemaState {
33
+ fields: Fields;
34
+ adapterSet: EntityAdapterSet;
35
+ opts: ValidateOptions;
36
+ previous: PreviousNames<Fields> | undefined;
37
+ derivation: SchemaDerivation | undefined;
38
+ anchored: boolean;
39
+ constraints: SchemaConstraints;
40
+ }
41
+
42
+ /** The keys a derivation keeps, in the order it keeps them, under the names they take. */
43
+ type Renaming = ReadonlyMap<string, string>;
44
+
45
+ /**
46
+ * Everything a schema IS, apart from being a class whose instances are rows.
47
+ *
48
+ * The members used to be that many statics assigned side by side, and every derivation
49
+ * re-threaded them by hand — which is how one of them came to be dropped from a list
50
+ * without anyone noticing. A transformation here returns a COMPLETE definition or it does
51
+ * not compile, so no gesture can mix the fields of one with the options of another.
52
+ *
53
+ * Internal: it is not exported from the package and never appears on `SchemaConstructor`.
54
+ * A user derives with `Order.pick(…)`, never `Order.definition.pick(…)`.
55
+ */
56
+ export class SchemaDefinition {
57
+ readonly fields: Fields;
58
+ readonly adapterSet: EntityAdapterSet;
59
+ readonly opts: ValidateOptions;
60
+ readonly previous: PreviousNames<Fields> | undefined;
61
+ readonly derivation: SchemaDerivation | undefined;
62
+ readonly anchored: boolean;
63
+ readonly constraints: SchemaConstraints;
64
+
65
+ private constructor(state: SchemaState) {
66
+ this.fields = state.fields;
67
+ this.adapterSet = state.adapterSet;
68
+ this.opts = state.opts;
69
+ this.previous = state.previous;
70
+ this.derivation = state.derivation;
71
+ this.anchored = state.anchored;
72
+ this.constraints = state.constraints;
73
+ }
74
+
75
+ /** Built complete or not at all — no static assigned on the side. */
76
+ static of(declaration: {
77
+ fields: Fields;
78
+ adapters?: EntityAdapters<Fields>;
79
+ opts?: ValidateOptions;
80
+ previous?: PreviousNames<Fields>;
81
+ derivation?: SchemaDerivation;
82
+ anchored?: boolean;
83
+ constraints?: SchemaConstraints;
84
+ }): SchemaDefinition {
85
+ return new SchemaDefinition({
86
+ fields: declaration.fields,
87
+ adapterSet: EntityAdapterSet.of(declaration.adapters),
88
+ opts: declaration.opts ?? {},
89
+ previous: declaration.previous,
90
+ derivation: declaration.derivation,
91
+ anchored: declaration.anchored ?? false,
92
+ constraints: declaration.constraints ?? {},
93
+ });
94
+ }
95
+
96
+ declaring(declarations: EntityDeclarations<Fields>): SchemaDefinition {
97
+ const addressed = EntityAdapterSet.of(declarations.adapters).fieldNames;
98
+ this.assertKnown('declares', [
99
+ ...addressed,
100
+ ...Object.keys(declarations.previous ?? {}),
101
+ ]);
102
+ const declared = FieldSet.declaring(this.fields, declarations.unique);
103
+
104
+ return new SchemaDefinition({
105
+ fields: declared.fields,
106
+ adapterSet: EntityAdapterSet.merged([
107
+ this.adapterSet,
108
+ EntityAdapterSet.of(declarations.adapters),
109
+ ]),
110
+ opts: this.opts,
111
+ previous: declarations.previous ?? this.previous,
112
+ derivation: this.derivation,
113
+ anchored: this.anchored,
114
+ constraints:
115
+ declarations.unique === undefined ? this.constraints : { unique: declared.unique },
116
+ });
117
+ }
118
+
119
+ anchoring(): SchemaDefinition {
120
+ return new SchemaDefinition({
121
+ fields: this.fields,
122
+ adapterSet: this.adapterSet,
123
+ opts: this.opts,
124
+ previous: this.previous,
125
+ derivation: this.derivation,
126
+ anchored: true,
127
+ constraints: this.constraints,
128
+ });
129
+ }
130
+
131
+ pick(keys: readonly string[], root: SchemaView): SchemaDefinition {
132
+ this.assertKnown('pick', keys);
133
+
134
+ return this.renaming(new Map(keys.map((key) => [key, key])), root);
135
+ }
136
+
137
+ omit(keys: readonly string[], root: SchemaView): SchemaDefinition {
138
+ this.assertKnown('omit', keys);
139
+ const kept = Object.keys(this.fields).filter((key) => !keys.includes(key));
140
+
141
+ return this.renaming(new Map(kept.map((key) => [key, key])), root);
142
+ }
143
+
144
+ rename(mapping: Record<string, string>, root: SchemaView): SchemaDefinition {
145
+ this.assertKnown('rename', Object.keys(mapping));
146
+ const here = Object.keys(this.fields).map((key) => [key, mapping[key] ?? key] as const);
147
+
148
+ return this.renaming(new Map(here), root);
149
+ }
150
+
151
+ /**
152
+ * `pick`, `omit` and `rename` are one gesture, and the renaming IS that gesture: the
153
+ * fields it keeps and everything else addressed by field name are both read from it.
154
+ */
155
+ private renaming(kept: Renaming, root: SchemaView): SchemaDefinition {
156
+ const fields: Fields = {};
157
+ for (const [from, to] of kept) {
158
+ const field = this.fields[from];
159
+ if (field) fields[to] = field;
160
+ }
161
+ const nameOf = (key: string) => kept.get(key);
162
+
163
+ return new SchemaDefinition({
164
+ fields,
165
+ adapterSet: this.adapterSet.rename(nameOf),
166
+ opts: this.opts,
167
+ previous: undefined,
168
+ derivation: this.origin(root).rename(nameOf),
169
+ anchored: false,
170
+ constraints: this.constraintsRenamed(nameOf),
171
+ });
172
+ }
173
+
174
+ /** One member gone and the group is gone: it constrained a pair that no longer exists. */
175
+ private constraintsRenamed(
176
+ transform: (key: string) => string | undefined,
177
+ ): SchemaConstraints {
178
+ if (!this.constraints.unique) return this.constraints;
179
+ const kept: string[][] = [];
180
+ for (const group of this.constraints.unique) {
181
+ const renamed = group.map(transform);
182
+ if (renamed.every((key): key is string => key !== undefined)) kept.push(renamed);
183
+ }
184
+
185
+ return { unique: deduplicated(kept) as CompositeUnique<Fields> | undefined };
186
+ }
187
+
188
+ patched(root: SchemaView): SchemaDefinition {
189
+ return new SchemaDefinition({
190
+ fields: { ...this.fields },
191
+ adapterSet: this.adapterSet,
192
+ opts: { ...this.opts, patch: true },
193
+ previous: undefined,
194
+ derivation: this.origin(root),
195
+ anchored: false,
196
+ constraints: this.constraints,
197
+ });
198
+ }
199
+
200
+ /** An added field does not pretend to come from the root, which never declared it. */
201
+ extended(extra: Fields, root: SchemaView): SchemaDefinition {
202
+ return new SchemaDefinition({
203
+ fields: { ...this.fields, ...extra },
204
+ adapterSet: this.adapterSet,
205
+ opts: this.opts,
206
+ previous: undefined,
207
+ derivation: this.origin(root),
208
+ anchored: false,
209
+ constraints: this.constraints,
210
+ });
211
+ }
212
+
213
+ /** Several schemas fold into one, which has no single origin to point at. */
214
+ static merged(views: readonly SchemaView[]): SchemaDefinition {
215
+ const fields: Fields = {};
216
+ let opts: ValidateOptions = {};
217
+ const groups: (readonly string[])[] = [];
218
+ for (const view of views) {
219
+ Object.assign(fields, view.getFields());
220
+ opts = { ...opts, ...view.getOpts() };
221
+ groups.push(...(view.getUnique() ?? []));
222
+ }
223
+
224
+ return new SchemaDefinition({
225
+ fields,
226
+ adapterSet: EntityAdapterSet.merged(
227
+ views.map((view) => EntityAdapterSet.of(view.getAdapters())),
228
+ ),
229
+ opts,
230
+ previous: undefined,
231
+ derivation: undefined,
232
+ anchored: false,
233
+ constraints: { unique: deduplicated(groups) as CompositeUnique<Fields> | undefined },
234
+ });
235
+ }
236
+
237
+ /**
238
+ * So a gesture naming a field that does not exist says so, and lists what there is.
239
+ * FR : pour qu'un geste nommant un champ inexistant le dise, et énumère ce qui existe.
240
+ * `pick('titel')` → `pick(): unknown field \`titel\`. This schema carries id, title, body.`
241
+ */
242
+ private assertKnown(operation: string, keys: readonly string[]): void {
243
+ const strangers = keys.filter((key) => !(key in this.fields));
244
+ if (strangers.length === 0) return;
245
+
246
+ throw new Error(
247
+ `${operation}(): unknown field ${strangers.map((s) => `\`${s}\``).join(', ')}. ` +
248
+ `This schema carries ${Object.keys(this.fields).join(', ')}.`,
249
+ );
250
+ }
251
+
252
+ private origin(root: SchemaView): SchemaDerivation {
253
+ if (!this.anchored && this.derivation) return this.derivation;
254
+
255
+ return SchemaDerivation.first(root, this.fields);
256
+ }
257
+ }
@@ -0,0 +1,44 @@
1
+ import { type Fields } from './field/Field.js';
2
+ import type { SchemaView } from './SchemaView.js';
3
+
4
+ /**
5
+ * The origin is the ROOT: `Post.pick(a, b).omit(b)` answers `Post`, never the intermediate.
6
+ */
7
+ export class SchemaDerivation {
8
+ private constructor(
9
+ readonly source: SchemaView,
10
+ readonly nameOf: Readonly<Record<string, string | undefined>>,
11
+ ) {}
12
+
13
+ static first(source: SchemaView, fields: Fields): SchemaDerivation {
14
+ return new SchemaDerivation(
15
+ source,
16
+ Object.fromEntries(Object.keys(fields).map((key) => [key, key])),
17
+ );
18
+ }
19
+
20
+ rename(transform: (key: string) => string | undefined): SchemaDerivation {
21
+ return new SchemaDerivation(
22
+ this.source,
23
+ Object.fromEntries(
24
+ Object.entries(this.nameOf).map(([origin, here]) => [
25
+ origin,
26
+ here === undefined ? undefined : transform(here),
27
+ ]),
28
+ ),
29
+ );
30
+ }
31
+
32
+ get sourceName(): string {
33
+ return this.source.name;
34
+ }
35
+
36
+ /** Whose rows this one borrows, however many cuts away: `Post.pick('t').omit('t')` → `Post`. */
37
+ get anchor(): SchemaView {
38
+ const source = this.source;
39
+
40
+ return source.anchored !== undefined || !source.derivation
41
+ ? source
42
+ : source.derivation.anchor;
43
+ }
44
+ }
@@ -1,15 +1,15 @@
1
- import type { Field, Fields } from './fields/Field.js';
2
- import type { CompositeUnique, PreviousNames } from '../entity/EntityDeclarations.js';
3
- import type { EntityAdapters } from '../entity/EntityAdapters.js';
4
- import type { ValidationResult } from '../judge/result.js';
5
- import type { ValidateOptions } from '../judge/options.js';
1
+ import type { Field, Fields } from './field/Field.js';
2
+ import type { CompositeUnique, PreviousNames } from './entity/EntityDeclarations.js';
3
+ import type { EntityAdapters } from './entity/EntityAdapters.js';
4
+ import type { ValidationResult } from './validation.js';
5
+ import type { ValidateOptions } from './validator/InputValidator.js';
6
6
  import type { SchemaDerivation } from './SchemaDerivation.js';
7
7
 
8
- export type Row<TFields extends Fields> = {
8
+ export type Values<TFields extends Fields> = {
9
9
  [K in keyof TFields]: TFields[K] extends Field<infer T> ? T : never;
10
10
  };
11
11
 
12
- export type PartialRow<TFields extends Fields> = Partial<Row<TFields>>;
12
+ export type PartialValues<TFields extends Fields> = Partial<Values<TFields>>;
13
13
 
14
14
  export interface SchemaView<TFields extends Fields = Fields> {
15
15
  readonly name: string;
@@ -20,8 +20,8 @@ export interface SchemaView<TFields extends Fields = Fields> {
20
20
  /** Does it hold rows of its own? False on a derivation means an answer. */
21
21
  readonly anchored?: boolean;
22
22
  getFields(): TFields;
23
- getAdapters(): EntityAdapters<TFields> | undefined;
23
+ getAdapters(): EntityAdapters<TFields>;
24
24
  getUnique(): CompositeUnique<TFields> | undefined;
25
25
  getOpts(): ValidateOptions;
26
- validate(input: unknown): ValidationResult<Row<TFields>>;
26
+ validate(input: unknown): ValidationResult<Values<TFields>>;
27
27
  }