@fougere/schema 0.11.0-alpha.0 → 0.12.1-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 (287) hide show
  1. package/dist/Schema.d.ts +1 -1
  2. package/dist/Schema.d.ts.map +1 -1
  3. package/dist/Schema.js +4 -3
  4. package/dist/Schema.js.map +1 -1
  5. package/dist/SchemaConstructor.d.ts +3 -4
  6. package/dist/SchemaConstructor.d.ts.map +1 -1
  7. package/dist/SchemaDefinition.d.ts.map +1 -1
  8. package/dist/SchemaDefinition.js +2 -1
  9. package/dist/SchemaDefinition.js.map +1 -1
  10. package/dist/SchemaError.d.ts +4 -0
  11. package/dist/SchemaError.d.ts.map +1 -0
  12. package/dist/SchemaError.js +7 -0
  13. package/dist/SchemaError.js.map +1 -0
  14. package/dist/SchemaView.d.ts +1 -1
  15. package/dist/SchemaView.d.ts.map +1 -1
  16. package/dist/axis/Axes.d.ts +16 -0
  17. package/dist/axis/Axes.d.ts.map +1 -0
  18. package/dist/axis/Axes.js +27 -0
  19. package/dist/axis/Axes.js.map +1 -0
  20. package/dist/axis/Axis.d.ts +5 -9
  21. package/dist/axis/Axis.d.ts.map +1 -1
  22. package/dist/axis/Axis.js +1 -10
  23. package/dist/axis/Axis.js.map +1 -1
  24. package/dist/axis/boundary/Boundary.d.ts +29 -3
  25. package/dist/axis/boundary/Boundary.d.ts.map +1 -1
  26. package/dist/axis/boundary/Boundary.js +15 -11
  27. package/dist/axis/boundary/Boundary.js.map +1 -1
  28. package/dist/axis/boundary/Decoder.d.ts +10 -7
  29. package/dist/axis/boundary/Decoder.d.ts.map +1 -1
  30. package/dist/axis/boundary/Decoder.js +2 -2
  31. package/dist/axis/boundary/Decoder.js.map +1 -1
  32. package/dist/axis/lifecycle/Generators.d.ts +5 -5
  33. package/dist/axis/lifecycle/Generators.d.ts.map +1 -1
  34. package/dist/axis/lifecycle/Generators.js +5 -15
  35. package/dist/axis/lifecycle/Generators.js.map +1 -1
  36. package/dist/axis/lifecycle/Lifecycle.d.ts +18 -6
  37. package/dist/axis/lifecycle/Lifecycle.d.ts.map +1 -1
  38. package/dist/axis/lifecycle/Lifecycle.js +29 -14
  39. package/dist/axis/lifecycle/Lifecycle.js.map +1 -1
  40. package/dist/axis/lifecycle/apply.d.ts.map +1 -1
  41. package/dist/axis/lifecycle/apply.js +5 -22
  42. package/dist/axis/lifecycle/apply.js.map +1 -1
  43. package/dist/axis/role/Role.d.ts +18 -6
  44. package/dist/axis/role/Role.d.ts.map +1 -1
  45. package/dist/axis/role/Role.js +30 -16
  46. package/dist/axis/role/Role.js.map +1 -1
  47. package/dist/axis/shape/Shape.d.ts +2 -2
  48. package/dist/axis/shape/Shape.d.ts.map +1 -1
  49. package/dist/axis/shape/Shape.js +2 -2
  50. package/dist/axis/shape/Shape.js.map +1 -1
  51. package/dist/axis/shape/{Formats.d.ts → StringFormats.d.ts} +3 -3
  52. package/dist/axis/shape/StringFormats.d.ts.map +1 -0
  53. package/dist/axis/shape/{Formats.js → StringFormats.js} +3 -3
  54. package/dist/axis/shape/StringFormats.js.map +1 -0
  55. package/dist/entity/EntityAdapterSet.d.ts.map +1 -1
  56. package/dist/entity/EntityAdapterSet.js +3 -2
  57. package/dist/entity/EntityAdapterSet.js.map +1 -1
  58. package/dist/entity.d.ts +0 -1
  59. package/dist/entity.d.ts.map +1 -1
  60. package/dist/entity.js +0 -1
  61. package/dist/entity.js.map +1 -1
  62. package/dist/field/Field.d.ts +11 -5
  63. package/dist/field/Field.d.ts.map +1 -1
  64. package/dist/field/Field.js +10 -7
  65. package/dist/field/Field.js.map +1 -1
  66. package/dist/field/FieldFormat.d.ts +9 -0
  67. package/dist/field/FieldFormat.d.ts.map +1 -0
  68. package/dist/field/FieldFormat.js +12 -0
  69. package/dist/field/FieldFormat.js.map +1 -0
  70. package/dist/field/FieldSet.d.ts.map +1 -1
  71. package/dist/field/FieldSet.js +5 -3
  72. package/dist/field/FieldSet.js.map +1 -1
  73. package/dist/field/FougereFieldAxes.d.ts +3 -0
  74. package/dist/field/FougereFieldAxes.d.ts.map +1 -0
  75. package/dist/field/FougereFieldAxes.js +2 -0
  76. package/dist/field/FougereFieldAxes.js.map +1 -0
  77. package/dist/field/Meta.d.ts +5 -3
  78. package/dist/field/Meta.d.ts.map +1 -1
  79. package/dist/field/Meta.js +2 -1
  80. package/dist/field/Meta.js.map +1 -1
  81. package/dist/field/Values.d.ts +6 -0
  82. package/dist/field/Values.d.ts.map +1 -0
  83. package/dist/field/Values.js.map +1 -0
  84. package/dist/index.d.ts +8 -3
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +5 -3
  87. package/dist/index.js.map +1 -1
  88. package/dist/lib/Format.d.ts +56 -0
  89. package/dist/lib/Format.d.ts.map +1 -0
  90. package/dist/lib/Format.js +95 -0
  91. package/dist/lib/Format.js.map +1 -0
  92. package/dist/lib/JsonSchema.d.ts +2 -0
  93. package/dist/lib/JsonSchema.d.ts.map +1 -0
  94. package/dist/lib/JsonSchema.js +2 -0
  95. package/dist/lib/JsonSchema.js.map +1 -0
  96. package/dist/lib/Registry.d.ts +5 -4
  97. package/dist/lib/Registry.d.ts.map +1 -1
  98. package/dist/lib/Registry.js +14 -8
  99. package/dist/lib/Registry.js.map +1 -1
  100. package/dist/lib/ValidationResult.d.ts +2 -0
  101. package/dist/lib/ValidationResult.d.ts.map +1 -1
  102. package/dist/lib/ValidationResult.js +6 -0
  103. package/dist/lib/ValidationResult.js.map +1 -1
  104. package/dist/lib/Verdict.d.ts +12 -0
  105. package/dist/lib/Verdict.d.ts.map +1 -0
  106. package/dist/lib/Verdict.js +2 -0
  107. package/dist/lib/Verdict.js.map +1 -0
  108. package/dist/projection/Cases.js +52 -54
  109. package/dist/projection/Cases.js.map +1 -1
  110. package/dist/projection/Visibility.d.ts +11 -0
  111. package/dist/projection/Visibility.d.ts.map +1 -1
  112. package/dist/projection/Visibility.js +22 -0
  113. package/dist/projection/Visibility.js.map +1 -1
  114. package/dist/projection/card/Bundle.d.ts.map +1 -1
  115. package/dist/projection/card/Bundle.js +2 -1
  116. package/dist/projection/card/Bundle.js.map +1 -1
  117. package/dist/projection/card/Card.d.ts +1 -1
  118. package/dist/projection/card/Card.d.ts.map +1 -1
  119. package/dist/projection/card/Card.js +19 -11
  120. package/dist/projection/card/Card.js.map +1 -1
  121. package/dist/projection/card/CardForm.d.ts +7 -0
  122. package/dist/projection/card/CardForm.d.ts.map +1 -0
  123. package/dist/projection/card/CardForm.js +2 -0
  124. package/dist/projection/card/CardForm.js.map +1 -0
  125. package/dist/projection/card/CardForms.d.ts +10 -0
  126. package/dist/projection/card/CardForms.d.ts.map +1 -0
  127. package/dist/projection/card/CardForms.js +12 -0
  128. package/dist/projection/card/CardForms.js.map +1 -0
  129. package/dist/projection/card/Change.d.ts +2 -2
  130. package/dist/projection/card/Change.d.ts.map +1 -1
  131. package/dist/projection/card/Diff.d.ts.map +1 -1
  132. package/dist/projection/card/Diff.js +36 -39
  133. package/dist/projection/card/Diff.js.map +1 -1
  134. package/dist/projection/card/FieldExtension.d.ts +4 -2
  135. package/dist/projection/card/FieldExtension.d.ts.map +1 -1
  136. package/dist/projection/card/RoleDescriptor.d.ts +9 -2
  137. package/dist/projection/card/RoleDescriptor.d.ts.map +1 -1
  138. package/dist/projection/card/RoleDescriptor.js +40 -1
  139. package/dist/projection/card/RoleDescriptor.js.map +1 -1
  140. package/dist/projection/card/admission.d.ts +0 -14
  141. package/dist/projection/card/admission.d.ts.map +1 -1
  142. package/dist/projection/card/admission.js +2 -21
  143. package/dist/projection/card/admission.js.map +1 -1
  144. package/dist/validator/FieldDeclarationValidator.d.ts.map +1 -1
  145. package/dist/validator/FieldDeclarationValidator.js +5 -17
  146. package/dist/validator/FieldDeclarationValidator.js.map +1 -1
  147. package/dist/validator/FieldValueValidator.d.ts +3 -3
  148. package/dist/validator/FieldValueValidator.d.ts.map +1 -1
  149. package/dist/validator/FieldValueValidator.js +18 -35
  150. package/dist/validator/FieldValueValidator.js.map +1 -1
  151. package/dist/validator/InputValidator.d.ts +3 -0
  152. package/dist/validator/InputValidator.d.ts.map +1 -1
  153. package/dist/validator/InputValidator.js +28 -31
  154. package/dist/validator/InputValidator.js.map +1 -1
  155. package/dist/validator/JsonSchemaValidator.d.ts +23 -0
  156. package/dist/validator/JsonSchemaValidator.d.ts.map +1 -0
  157. package/dist/validator/JsonSchemaValidator.js +113 -0
  158. package/dist/validator/JsonSchemaValidator.js.map +1 -0
  159. package/dist/vocabulary/primitive/list.d.ts.map +1 -1
  160. package/dist/vocabulary/primitive/list.js +2 -1
  161. package/dist/vocabulary/primitive/list.js.map +1 -1
  162. package/dist/vocabulary/vocabulary.d.ts.map +1 -1
  163. package/dist/vocabulary/vocabulary.js +9 -6
  164. package/dist/vocabulary/vocabulary.js.map +1 -1
  165. package/package.json +1 -1
  166. package/src/Schema.ts +6 -4
  167. package/src/SchemaConstructor.ts +4 -4
  168. package/src/SchemaDefinition.ts +2 -1
  169. package/src/SchemaError.ts +7 -0
  170. package/src/SchemaView.ts +1 -1
  171. package/src/axis/Axes.ts +34 -0
  172. package/src/axis/Axis.ts +5 -20
  173. package/src/axis/boundary/Boundary.ts +26 -13
  174. package/src/axis/boundary/Decoder.ts +5 -4
  175. package/src/axis/lifecycle/Generators.ts +6 -18
  176. package/src/axis/lifecycle/Lifecycle.ts +41 -19
  177. package/src/axis/lifecycle/apply.ts +13 -21
  178. package/src/axis/role/Role.ts +35 -19
  179. package/src/axis/shape/Shape.ts +3 -3
  180. package/src/axis/shape/{Formats.ts → StringFormats.ts} +2 -2
  181. package/src/entity/EntityAdapterSet.ts +3 -2
  182. package/src/entity.ts +0 -1
  183. package/src/field/Field.ts +23 -12
  184. package/src/field/FieldFormat.ts +18 -0
  185. package/src/field/FieldSet.ts +5 -3
  186. package/src/field/FougereFieldAxes.ts +2 -0
  187. package/src/field/Meta.ts +5 -3
  188. package/src/{Values.ts → field/Values.ts} +2 -2
  189. package/src/index.ts +8 -3
  190. package/src/lib/Format.ts +139 -0
  191. package/src/lib/JsonSchema.ts +1 -0
  192. package/src/lib/Registry.ts +18 -9
  193. package/src/lib/ValidationResult.ts +8 -0
  194. package/src/lib/Verdict.ts +10 -0
  195. package/src/projection/Cases.ts +61 -57
  196. package/src/projection/Visibility.ts +22 -0
  197. package/src/projection/card/Bundle.ts +2 -1
  198. package/src/projection/card/Card.ts +24 -13
  199. package/src/projection/card/CardForm.ts +8 -0
  200. package/src/projection/card/CardForms.ts +13 -0
  201. package/src/projection/card/Change.ts +2 -2
  202. package/src/projection/card/Diff.ts +44 -44
  203. package/src/projection/card/FieldExtension.ts +5 -2
  204. package/src/projection/card/RoleDescriptor.ts +48 -2
  205. package/src/projection/card/admission.ts +2 -34
  206. package/src/validator/FieldDeclarationValidator.ts +5 -17
  207. package/src/validator/FieldValueValidator.ts +22 -46
  208. package/src/validator/InputValidator.ts +30 -32
  209. package/src/validator/JsonSchemaValidator.ts +142 -0
  210. package/src/vocabulary/primitive/list.ts +2 -1
  211. package/src/vocabulary/vocabulary.ts +9 -6
  212. package/dist/PartialValues.d.ts +0 -4
  213. package/dist/PartialValues.d.ts.map +0 -1
  214. package/dist/PartialValues.js +0 -2
  215. package/dist/PartialValues.js.map +0 -1
  216. package/dist/Values.d.ts +0 -6
  217. package/dist/Values.d.ts.map +0 -1
  218. package/dist/Values.js.map +0 -1
  219. package/dist/axis/boundary/Boundaries.d.ts +0 -17
  220. package/dist/axis/boundary/Boundaries.d.ts.map +0 -1
  221. package/dist/axis/boundary/Boundaries.js +0 -25
  222. package/dist/axis/boundary/Boundaries.js.map +0 -1
  223. package/dist/axis/boundary/BoundaryAxis.d.ts +0 -4
  224. package/dist/axis/boundary/BoundaryAxis.d.ts.map +0 -1
  225. package/dist/axis/boundary/BoundaryAxis.js +0 -30
  226. package/dist/axis/boundary/BoundaryAxis.js.map +0 -1
  227. package/dist/axis/boundary/BoundaryRef.d.ts +0 -3
  228. package/dist/axis/boundary/BoundaryRef.d.ts.map +0 -1
  229. package/dist/axis/boundary/BoundaryRef.js +0 -2
  230. package/dist/axis/boundary/BoundaryRef.js.map +0 -1
  231. package/dist/axis/boundary/BoundaryRules.d.ts +0 -9
  232. package/dist/axis/boundary/BoundaryRules.d.ts.map +0 -1
  233. package/dist/axis/boundary/BoundaryRules.js +0 -2
  234. package/dist/axis/boundary/BoundaryRules.js.map +0 -1
  235. package/dist/axis/lifecycle/Clock.d.ts +0 -18
  236. package/dist/axis/lifecycle/Clock.d.ts.map +0 -1
  237. package/dist/axis/lifecycle/Clock.js +0 -25
  238. package/dist/axis/lifecycle/Clock.js.map +0 -1
  239. package/dist/axis/lifecycle/LifecycleAxis.d.ts +0 -4
  240. package/dist/axis/lifecycle/LifecycleAxis.d.ts.map +0 -1
  241. package/dist/axis/lifecycle/LifecycleAxis.js +0 -52
  242. package/dist/axis/lifecycle/LifecycleAxis.js.map +0 -1
  243. package/dist/axis/lifecycle/LifecycleRules.d.ts +0 -12
  244. package/dist/axis/lifecycle/LifecycleRules.d.ts.map +0 -1
  245. package/dist/axis/lifecycle/LifecycleRules.js +0 -3
  246. package/dist/axis/lifecycle/LifecycleRules.js.map +0 -1
  247. package/dist/axis/role/RoleAxis.d.ts +0 -5
  248. package/dist/axis/role/RoleAxis.d.ts.map +0 -1
  249. package/dist/axis/role/RoleAxis.js +0 -93
  250. package/dist/axis/role/RoleAxis.js.map +0 -1
  251. package/dist/axis/role/RoleRules.d.ts +0 -8
  252. package/dist/axis/role/RoleRules.d.ts.map +0 -1
  253. package/dist/axis/role/RoleRules.js +0 -2
  254. package/dist/axis/role/RoleRules.js.map +0 -1
  255. package/dist/axis/shape/Formats.d.ts.map +0 -1
  256. package/dist/axis/shape/Formats.js.map +0 -1
  257. package/dist/lib/Checked.d.ts +0 -11
  258. package/dist/lib/Checked.d.ts.map +0 -1
  259. package/dist/lib/Checked.js +0 -2
  260. package/dist/lib/Checked.js.map +0 -1
  261. package/dist/projection/card/RelationDescriptor.d.ts +0 -5
  262. package/dist/projection/card/RelationDescriptor.d.ts.map +0 -1
  263. package/dist/projection/card/RelationDescriptor.js +0 -2
  264. package/dist/projection/card/RelationDescriptor.js.map +0 -1
  265. package/dist/projection/standard.d.ts +0 -14
  266. package/dist/projection/standard.d.ts.map +0 -1
  267. package/dist/projection/standard.js +0 -2
  268. package/dist/projection/standard.js.map +0 -1
  269. package/dist/validator/AdapterFieldValidator.d.ts +0 -14
  270. package/dist/validator/AdapterFieldValidator.d.ts.map +0 -1
  271. package/dist/validator/AdapterFieldValidator.js +0 -36
  272. package/dist/validator/AdapterFieldValidator.js.map +0 -1
  273. package/src/PartialValues.ts +0 -4
  274. package/src/axis/boundary/Boundaries.ts +0 -36
  275. package/src/axis/boundary/BoundaryAxis.ts +0 -32
  276. package/src/axis/boundary/BoundaryRef.ts +0 -3
  277. package/src/axis/boundary/BoundaryRules.ts +0 -4
  278. package/src/axis/lifecycle/Clock.ts +0 -26
  279. package/src/axis/lifecycle/LifecycleAxis.ts +0 -55
  280. package/src/axis/lifecycle/LifecycleRules.ts +0 -9
  281. package/src/axis/role/RoleAxis.ts +0 -104
  282. package/src/axis/role/RoleRules.ts +0 -8
  283. package/src/lib/Checked.ts +0 -5
  284. package/src/projection/card/RelationDescriptor.ts +0 -3
  285. package/src/projection/standard.ts +0 -13
  286. package/src/validator/AdapterFieldValidator.ts +0 -40
  287. /package/dist/{Values.js → field/Values.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonSchemaValidator.js","sourceRoot":"","sources":["../../src/validator/JsonSchemaValidator.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/vocabulary/primitive/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAQtE"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/vocabulary/primitive/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAG7C,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,CAQtE"}
@@ -1,4 +1,5 @@
1
1
  import { Field } from '../../field/Field.js';
2
+ import { SchemaError } from '../../SchemaError.js';
2
3
  /**
3
4
  * A list of VALUES. The other side of a relation is `many()`, and passing one here throws.
4
5
  * FR : une liste de VALEURS. L'autre côté d'une relation est `many()`, et en passer une ici lève.
@@ -6,7 +7,7 @@ import { Field } from '../../field/Field.js';
6
7
  */
7
8
  export function list(item, opts) {
8
9
  if (item.role?.relation)
9
- throw new Error('list() takes a value field (text(), number()…) — a relation has no value shape');
10
+ throw new SchemaError('list() takes a value field (text(), number()…) — a relation has no value shape');
10
11
  return new Field({
11
12
  shape: { type: 'array', items: item.shape, minItems: opts?.min, maxItems: opts?.max },
12
13
  });
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/vocabulary/primitive/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAO7C;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAI,IAAc,EAAE,IAAkB;IACxD,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ;QACrB,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,OAAO,IAAI,KAAK,CAAM;QACpB,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE;KACtF,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/vocabulary/primitive/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAOnD;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAI,IAAc,EAAE,IAAkB;IACxD,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ;QACrB,MAAM,IAAI,WAAW,CACnB,gFAAgF,CACjF,CAAC;IACJ,OAAO,IAAI,KAAK,CAAM;QACpB,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE;KACtF,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAM1C;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,GACvC,SAAS,CAEX;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAO1C;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,GACvC,SAAS,CAEX;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC"}
@@ -1,6 +1,7 @@
1
- import { EXTENSION_SLOTS } from '../axis/Axis.js';
1
+ import { Axes } from '../axis/Axes.js';
2
2
  import { dequal } from 'dequal';
3
- const MEMBER_SLOTS = [...EXTENSION_SLOTS, 'meta'];
3
+ import { SchemaError } from '../SchemaError.js';
4
+ const memberSlots = () => [...Axes.names, 'meta'];
4
5
  /**
5
6
  * Builds a `rule/` word, which states members on the field it receives.
6
7
  * FR : fabrique un mot de `rule/`, qui énonce des membres sur le champ reçu.
@@ -16,13 +17,15 @@ export function vocabulary(name, states) {
16
17
  */
17
18
  function merge(name, field, given) {
18
19
  const merged = {};
20
+ const stated = given;
21
+ const held = field;
19
22
  if ('shape' in given)
20
23
  merged.shape = given.shape;
21
- for (const slot of MEMBER_SLOTS) {
22
- const members = given[slot];
24
+ for (const slot of memberSlots()) {
25
+ const members = stated[slot];
23
26
  if (members === undefined)
24
27
  continue;
25
- const already = field[slot];
28
+ const already = held[slot];
26
29
  if (typeof members !== 'object' || members === null || typeof already !== 'object') {
27
30
  merged[slot] = members;
28
31
  continue;
@@ -31,7 +34,7 @@ function merge(name, field, given) {
31
34
  const previous = already?.[member];
32
35
  if (previous === undefined || dequal(previous, value))
33
36
  continue;
34
- throw new Error(`vocabulary: \`${name}\` states ${slot}.${member} = ${JSON.stringify(value)}, but the ` +
37
+ throw new SchemaError(`vocabulary: \`${name}\` states ${slot}.${member} = ${JSON.stringify(value)}, but the ` +
35
38
  `field already states ${JSON.stringify(previous)}. Apply one or the other, not both.`);
36
39
  }
37
40
  merged[slot] = { ...already, ...members };
@@ -1 +1 @@
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
+ {"version":3,"file":"vocabulary.js","sourceRoot":"","sources":["../../src/vocabulary/vocabulary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,GAAG,GAAa,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAE5D;;;;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,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,MAAM,IAAI,GAAG,KAA2C,CAAC;IACzD,IAAI,OAAO,IAAI,KAAK;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAEjD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,OAAO,KAAK,SAAS;YAAE,SAAS;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAwC,CAAC;QAClE,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,WAAW,CACnB,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fougere/schema",
3
- "version": "0.11.0-alpha.0",
3
+ "version": "0.12.1-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",
package/src/Schema.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+
1
3
  import { Boundary } from './axis/boundary/Boundary.js';
2
4
  import { type Fields } from './field/Fields.js';
3
5
  import { type CompositeUnique } from './entity/CompositeUnique.js';
@@ -9,11 +11,11 @@ import { SchemaDerivation } from './SchemaDerivation.js';
9
11
  import { type SchemaConstraints } from './SchemaConstraints.js';
10
12
  import { SchemaDefinition } from './SchemaDefinition.js';
11
13
  import { type ValidateOptions } from './validator/ValidateOptions.js';
12
- import type { StandardSchemaV1 } from './projection/standard.js';
13
14
 
14
15
  import type { SchemaView } from './SchemaView.js';
15
16
 
16
17
  import type { SchemaConstructor } from './SchemaConstructor.js';
18
+ import { SchemaError } from './SchemaError.js';
17
19
 
18
20
  export const ANONYMOUS_SCHEMA_NAME = 'Schema';
19
21
 
@@ -74,7 +76,7 @@ export class Schema {
74
76
  continue;
75
77
  }
76
78
  const decoded = Boundary.of(field).decode(value);
77
- row[key] = 'error' in decoded ? value : decoded.value;
79
+ row[key] = 'message' in decoded ? value : decoded.value;
78
80
  }
79
81
  return row;
80
82
  }
@@ -128,10 +130,10 @@ export class Schema {
128
130
 
129
131
  static named(name: string) {
130
132
  if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) {
131
- throw new Error(`named(): \`${name}\` is not a valid class name.`);
133
+ throw new SchemaError(`named(): \`${name}\` is not a valid class name.`);
132
134
  }
133
135
  if (this.name !== ANONYMOUS_SCHEMA_NAME) {
134
- throw new Error(
136
+ throw new SchemaError(
135
137
  `named(): \`${this.name}\` is already named by its class declaration.`,
136
138
  );
137
139
  }
@@ -1,15 +1,15 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+
1
3
  import { type Fields } from './field/Fields.js';
2
4
 
3
5
  import { type EntityDeclarations } from './entity/EntityDeclarations.js';
4
6
  import { type PreviousNames } from './entity/PreviousNames.js';
5
7
  import { SchemaDerivation } from './SchemaDerivation.js';
6
- import type { StandardSchemaV1 } from './projection/standard.js';
7
- import type { PartialValues } from './PartialValues.js';
8
8
  import type { SchemaView } from './SchemaView.js';
9
- import type { Values } from './Values.js';
9
+ import type { Values } from './field/Values.js';
10
10
 
11
11
  export interface SchemaConstructor<TFields extends Fields> extends SchemaView<TFields> {
12
- new (data: PartialValues<TFields>): Values<TFields>;
12
+ new (data: Partial<Values<TFields>>): Values<TFields>;
13
13
  readonly '~standard': StandardSchemaV1.Props<Record<string, unknown>, Values<TFields>>;
14
14
  readonly derivation?: SchemaDerivation;
15
15
  readonly previous?: PreviousNames<TFields>;
@@ -9,6 +9,7 @@ import { SchemaDerivation } from './SchemaDerivation.js';
9
9
  import { type ValidateOptions } from './validator/ValidateOptions.js';
10
10
  import type { SchemaView } from './SchemaView.js';
11
11
  import { SchemaConstraints } from './SchemaConstraints.js';
12
+ import { SchemaError } from './SchemaError.js';
12
13
 
13
14
  /**
14
15
  * Everything a definition is made of, every member required.
@@ -225,7 +226,7 @@ export class SchemaDefinition {
225
226
  const strangers = keys.filter((key) => !Object.hasOwn(this.fields, key));
226
227
  if (strangers.length === 0) return;
227
228
 
228
- throw new Error(
229
+ throw new SchemaError(
229
230
  `${operation}(): unknown field ${strangers.map((s) => `\`${s}\``).join(', ')}. ` +
230
231
  `This schema carries ${Object.keys(this.fields).join(', ')}.`,
231
232
  );
@@ -0,0 +1,7 @@
1
+ export class SchemaError extends Error {
2
+ constructor(message: string) {
3
+ super(message);
4
+
5
+ this.name = 'SchemaError';
6
+ }
7
+ }
package/src/SchemaView.ts CHANGED
@@ -5,7 +5,7 @@ import type { EntityAdapters } from './entity/EntityAdapters.js';
5
5
  import type { ValidationResult } from './lib/ValidationResult.js';
6
6
  import type { ValidateOptions } from './validator/ValidateOptions.js';
7
7
  import type { SchemaDerivation } from './SchemaDerivation.js';
8
- import type { Values } from './Values.js';
8
+ import type { Values } from './field/Values.js';
9
9
 
10
10
  export interface SchemaView<TFields extends Fields = Fields> {
11
11
  readonly name: string;
@@ -0,0 +1,34 @@
1
+ import { Registry } from '../lib/Registry.js';
2
+ import type { JsonSchema } from '../lib/JsonSchema.js';
3
+ import { fieldFormat } from '../field/FieldFormat.js';
4
+ import type { Axis } from './Axis.js';
5
+ import { Boundary } from './boundary/Boundary.js';
6
+ import { Lifecycle } from './lifecycle/Lifecycle.js';
7
+ import { Role } from './role/Role.js';
8
+
9
+ class AxisRegistry extends Registry<Axis> {
10
+ private composed?: JsonSchema;
11
+
12
+ register(slot: string, axis: Axis): Axis {
13
+ this.composed = undefined;
14
+
15
+ return super.register(slot, axis);
16
+ }
17
+
18
+ /** The document a field declaration is judged against, rebuilt the next time one arrives. */
19
+ get fieldFormat(): JsonSchema {
20
+ this.composed ??= fieldFormat(this.entries);
21
+
22
+ return this.composed;
23
+ }
24
+ }
25
+
26
+ /**
27
+ * The axes this process reads, and the door an axis declared elsewhere comes through.
28
+ * `Axes.register('tenancy', Tenancy)` — from a `vocabulary/` file, read before `entities/`
29
+ */
30
+ export const Axes = new AxisRegistry('axis', 'call Axes.register(slot, axis)', [
31
+ ['role', Role],
32
+ ['lifecycle', Lifecycle],
33
+ ['boundary', Boundary],
34
+ ]);
package/src/axis/Axis.ts CHANGED
@@ -1,24 +1,9 @@
1
- import { roleAxis } from './role/RoleAxis.js';
2
- import { lifecycleAxis } from './lifecycle/LifecycleAxis.js';
3
- import { boundaryAxis } from './boundary/BoundaryAxis.js';
1
+ import type { Format } from '../lib/Format.js';
4
2
  import type { ValidationError } from '../lib/ValidationError.js';
5
- import type { Resolver } from './Resolver.js';
6
3
 
7
- export interface Axis<Declared = unknown, Wire = unknown> {
8
- readonly slot: 'role' | 'lifecycle' | 'boundary';
4
+ export interface Axis {
5
+ readonly format: Format;
9
6
 
10
- validator(value: unknown, errors: ValidationError[]): void;
11
-
12
- describe(value: Declared, key: string): Wire | undefined;
13
-
14
- reconstruct(wire: Wire, resolve?: Resolver): Declared;
7
+ /** What a format cannot state: `role.relation.to` is a function, and JSON holds none. */
8
+ refusals?(value: unknown): ValidationError[];
15
9
  }
16
-
17
- export const EXTENSION_AXES: readonly Axis[] = [
18
- roleAxis,
19
- lifecycleAxis,
20
- boundaryAxis,
21
- ];
22
-
23
- /** The slots they occupy: the keys of `x-fougere` on a field descriptor. */
24
- export const EXTENSION_SLOTS = EXTENSION_AXES.map((axis) => axis.slot);
@@ -4,24 +4,37 @@ import { Boundaries } from './Decoder.js';
4
4
  import type { Field } from '../../field/Field.js';
5
5
  import { type Shape } from '../shape/Shape.js';
6
6
  import { Shapes } from '../shape/Shape.js';
7
- import type { BoundaryRules } from './BoundaryRules.js';
7
+ import { SchemaError } from '../../SchemaError.js';
8
+ import { Format, type Accepted } from '../../lib/Format.js';
9
+
10
+ const closedOr = <Verb extends 'decode' | 'encode'>(verb: Verb) =>
11
+ Format.either(Format.tokens(['closed']), Format.of().key(verb, Format.text).needs(verb).closed());
12
+
13
+ const RULES = Format.of().key('in', closedOr('decode')).key('out', closedOr('encode')).closed();
14
+
15
+ const BOUNDARY = Format.named(
16
+ 'axis/boundary',
17
+ Format.either(Format.text.as<'isoDate' | (string & {})>(), RULES),
18
+ );
19
+
20
+ export type BoundaryRules = Accepted<typeof RULES>;
21
+
22
+ export type BoundaryRef = Accepted<typeof BOUNDARY>;
8
23
 
9
24
  const identityDecoder: Decoder = (value) => ({ value });
10
25
 
11
26
  const identityEncoder: Encoder = (value) => value;
12
27
 
13
28
  export class Boundary {
14
- private readonly in?: BoundaryRules['in'];
15
- private readonly out?: BoundaryRules['out'];
29
+ static readonly format = BOUNDARY;
30
+
16
31
  readonly decode: Decoder;
17
32
  readonly encode: Encoder;
18
33
 
19
34
  private constructor(
20
- rules: BoundaryRules = {},
35
+ private readonly rules: BoundaryRules = {},
21
36
  codecs?: { decode: Decoder; encode: Encoder },
22
37
  ) {
23
- this.in = rules.in;
24
- this.out = rules.out;
25
38
  this.decode = codecs?.decode ?? identityDecoder;
26
39
  this.encode = codecs?.encode ?? identityEncoder;
27
40
  }
@@ -33,7 +46,7 @@ export class Boundary {
33
46
  if (typeof ref !== 'string') return new Boundary(ref);
34
47
 
35
48
  const alias = Boundaries.aliases.find(ref);
36
- if (!alias) throw new Error(`Unknown boundary alias: '${ref}'`);
49
+ if (!alias) throw new SchemaError(`Unknown boundary alias: '${ref}'`);
37
50
  return new Boundary(alias);
38
51
  }
39
52
 
@@ -41,8 +54,8 @@ export class Boundary {
41
54
  const declared = Boundary.declared(field);
42
55
  const derived = Boundary.forShape(field.shape);
43
56
  const rules: BoundaryRules = {
44
- in: declared.in ?? derived.in,
45
- out: declared.out ?? derived.out,
57
+ in: declared.rules.in ?? derived.rules.in,
58
+ out: declared.rules.out ?? derived.rules.out,
46
59
  };
47
60
  return new Boundary(rules, {
48
61
  decode:
@@ -58,20 +71,20 @@ export class Boundary {
58
71
 
59
72
  /** `date-time` means a `Date` on both sides, without a word in the entity. */
60
73
  static forShape(shape: Shape | undefined): Boundary {
61
- if (Shapes.typeOf(shape) === 'date') return new Boundary(Boundaries.aliases.find('isoDate')!);
74
+ if (Shapes.typeOf(shape) === 'date') return new Boundary(Boundaries.aliases.resolve('isoDate'));
62
75
  return new Boundary();
63
76
  }
64
77
 
65
78
  /** The dual of `declared`: what `readOnly()` writes back on the field, not a judge. */
66
79
  declaring(overrides: BoundaryRules): BoundaryRules {
67
- return { in: overrides.in ?? this.in, out: overrides.out ?? this.out };
80
+ return { in: overrides.in ?? this.rules.in, out: overrides.out ?? this.rules.out };
68
81
  }
69
82
 
70
83
  get readOnly(): boolean {
71
- return this.in === 'closed';
84
+ return this.rules.in === 'closed';
72
85
  }
73
86
 
74
87
  get writeOnly(): boolean {
75
- return this.out === 'closed';
88
+ return this.rules.out === 'closed';
76
89
  }
77
90
  }
@@ -1,13 +1,14 @@
1
- import type { BoundaryRules } from './BoundaryRules.js';
1
+ import type { BoundaryRules } from './Boundary.js';
2
2
  import { Registry } from '../../lib/Registry.js';
3
3
  import type { Encoder } from './Encoder.js';
4
+ import type { Verdict } from '../../lib/Verdict.js';
4
5
 
5
6
  /**
6
7
  * Wire to domain, and it must ANSWER a value it already produced: two facades decode — the
7
8
  * client one on what arrives, `StorageGuard` on what a handler writes — so a decoder that
8
9
  * halves cents halves them twice and stores a hundredth.
9
10
  */
10
- export type Decoder = (value: unknown) => { value: unknown } | { error: string };
11
+ export type Decoder = (value: unknown) => Verdict;
11
12
 
12
13
  /**
13
14
  * `decoders` for a value coming in, `encoders` for one going out, `aliases` for the word
@@ -32,9 +33,9 @@ Boundaries.decoders.register('isoDate', (value) => {
32
33
  if (value instanceof Date) return { value };
33
34
  if (typeof value === 'string') {
34
35
  const date = new Date(value);
35
- return Number.isNaN(date.getTime()) ? { error: 'Invalid date' } : { value: date };
36
+ return Number.isNaN(date.getTime()) ? { message: 'Invalid date' } : { value: date };
36
37
  }
37
- return { error: 'Expected a date' };
38
+ return { message: 'Expected a date' };
38
39
  });
39
40
  Boundaries.encoders.register('isoDate', (value) =>
40
41
  value instanceof Date ? value.toISOString() : value,
@@ -2,28 +2,16 @@ import { createId } from '@paralleldrive/cuid2';
2
2
 
3
3
  import { Registry } from '../../lib/Registry.js';
4
4
 
5
- export type GeneratorRef = 'cuid2' | 'uuid' | 'nanoid' | (string & {});
6
-
7
- const NANOID_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
8
-
9
- function nanoid(): string {
10
- const bytes = new Uint8Array(21);
11
- globalThis.crypto.getRandomValues(bytes);
12
- return Array.from(bytes, (byte) => NANOID_ALPHABET[byte & 63]).join('');
13
- }
5
+ export type GeneratorRef = 'cuid2' | (string & {});
14
6
 
15
7
  /**
16
- * Who answers a `generate:` name. `cuid2`, `uuid` and `nanoid` are registered like any
17
- * other, so `Generators.resolve('ulid')` is refused here and lists the three.
18
- * FR : pour qu'un `generate:` soit répondu par un registre, builtins compris.
19
- * `Generators.register('ulid', ulid)` → `create: { generate: 'ulid' }` now resolves
8
+ * Who answers a `generate:` name. `cuid2` is registered like any other, so
9
+ * `Generators.resolve('uuid')` is refused here and names what the process holds.
10
+ * `Generators.register('uuid', () => globalThis.crypto.randomUUID())` →
11
+ * `create: { generate: 'uuid' }` now resolves
20
12
  */
21
13
  export const Generators = new Registry<() => string>(
22
14
  'generator',
23
15
  'call Generators.register(name, fn)',
24
- [
25
- ['cuid2', createId],
26
- ['uuid', () => globalThis.crypto.randomUUID()],
27
- ['nanoid', nanoid],
28
- ],
16
+ [['cuid2', createId]],
29
17
  );
@@ -1,32 +1,60 @@
1
+ import { Format, type Accepted } from '../../lib/Format.js';
2
+ import { Generators } from './Generators.js';
1
3
  import type { GeneratorRef } from './Generators.js';
2
- import type { LifecycleRules } from './LifecycleRules.js';
3
4
 
5
+ export type LifecycleRules = Accepted<typeof Lifecycle.format>;
4
6
  export class Lifecycle {
5
- private readonly create?: LifecycleRules['create'];
6
- private readonly update?: LifecycleRules['update'];
7
+ static readonly CREATE = ['now', 'optional'] as const;
8
+ static readonly UPDATE = ['now', 'forbidden'] as const;
7
9
 
8
- private constructor(rules: LifecycleRules = {}) {
9
- this.create = rules.create;
10
- this.update = rules.update;
11
- }
10
+ static readonly format = Format.of('axis/lifecycle')
11
+ .key(
12
+ 'create',
13
+ Format.either(
14
+ Format.tokens(Lifecycle.CREATE),
15
+ Format.exactlyOne({
16
+ value: Format.anything,
17
+ generate: Format.text.as<GeneratorRef>(),
18
+ }),
19
+ ),
20
+ )
21
+ .key('update', Format.tokens(Lifecycle.UPDATE))
22
+ .closed();
23
+
24
+ private constructor(private readonly rules: LifecycleRules = {}) {}
12
25
 
13
26
  static of(field: { lifecycle?: LifecycleRules }): Lifecycle {
14
27
  return new Lifecycle(field.lifecycle);
15
28
  }
16
29
 
30
+ private get create() {
31
+ return this.rules.create;
32
+ }
33
+
34
+ private get update() {
35
+ return this.rules.update;
36
+ }
37
+
38
+ bornWith(instant: number): { value: unknown } | undefined {
39
+ const rule = this.create;
40
+
41
+ if (rule === 'now') return { value: new Date(instant) };
42
+
43
+ if (typeof rule !== 'object') return undefined;
44
+
45
+ if ('value' in rule) return { value: structuredClone(rule.value) };
46
+
47
+ return { value: Generators.resolve(rule.generate)() };
48
+ }
49
+
17
50
  get requiredAtCreate(): boolean {
18
51
  return this.create === undefined;
19
52
  }
20
53
 
21
- /** The server fills it at create, so a client form never carries it. */
22
54
  get stampedAtCreate(): boolean {
23
55
  return this.create === 'now';
24
56
  }
25
57
 
26
- get stampedOnce(): boolean {
27
- return this.stampedAtCreate && !this.stampedOnUpdate;
28
- }
29
-
30
58
  get immutable(): boolean {
31
59
  return this.update === 'forbidden';
32
60
  }
@@ -37,15 +65,9 @@ export class Lifecycle {
37
65
 
38
66
  get literal(): { value: unknown } | undefined {
39
67
  const rule = this.create;
68
+
40
69
  return typeof rule === 'object' && rule !== null && 'value' in rule
41
70
  ? { value: (rule as { value: unknown }).value }
42
71
  : undefined;
43
72
  }
44
-
45
- get generator(): GeneratorRef | undefined {
46
- const rule = this.create;
47
- return typeof rule === 'object' && rule !== null && 'generate' in rule
48
- ? (rule as { generate: GeneratorRef }).generate
49
- : undefined;
50
- }
51
73
  }
@@ -1,6 +1,4 @@
1
1
  import { Lifecycle } from './Lifecycle.js';
2
- import { Generators } from './Generators.js';
3
- import { Clock } from './Clock.js';
4
2
  import { type Field } from '../../field/Field.js';
5
3
  import { type Fields } from '../../field/Fields.js';
6
4
 
@@ -9,42 +7,36 @@ import { type Fields } from '../../field/Fields.js';
9
7
  * FR : remplit ce que la déclaration laisse au storage : aucun handler n'estampe lui-même.
10
8
  * `applyCreate({ id: primary(), createdAt: created() }, { title: 'a' })` → `id`, `createdAt`
11
9
  */
12
- export function applyCreate(fields: Fields, input: Record<string, unknown>): Record<string, unknown> {
10
+ export function applyCreate(
11
+ fields: Fields,
12
+ input: Record<string, unknown>,
13
+ ): Record<string, unknown> {
13
14
  const values: Record<string, unknown> = { ...input };
14
- const instant = Clock.now();
15
+ const instant = Date.now();
15
16
 
16
17
  for (const [name, field] of Object.entries(fields) as [string, Field][]) {
17
18
  if (name in values) continue;
18
- const rule = Lifecycle.of(field);
19
19
 
20
- if (rule.stampedAtCreate) values[name] = new Date(instant);
21
- else if (rule.literal) values[name] = freshValue(rule.literal.value);
22
- else if (rule.generator) values[name] = Generators.resolve(rule.generator)();
20
+ const born = Lifecycle.of(field).bornWith(instant);
21
+
22
+ if (born) values[name] = born.value;
23
23
  }
24
24
 
25
25
  return values;
26
26
  }
27
27
 
28
- /**
29
- * Clones a declared default, so two rows born of `create: { value: [] }` hold two arrays.
30
- * FR : clone un défaut déclaré, pour que deux lignes nées de `create: { value: [] }`
31
- * tiennent deux tableaux.
32
- * `create: { value: [] }` → each instance gets its own array
33
- */
34
- function freshValue(value: unknown): unknown {
35
- if (value === null || typeof value !== 'object') return value;
36
- return structuredClone(value);
37
- }
38
-
39
28
  /**
40
29
  * The dual of `applyCreate` on a patch: only `update: 'now'` fields are touched.
41
30
  * FR : le dual d'`applyCreate` sur une modification : seuls les champs `update: 'now'`
42
31
  * sont touchés.
43
32
  * `applyUpdate(fields, { title: 'b' })` → `updatedAt` added, nothing else
44
33
  */
45
- export function applyUpdate(fields: Fields, patch: Record<string, unknown>): Record<string, unknown> {
34
+ export function applyUpdate(
35
+ fields: Fields,
36
+ patch: Record<string, unknown>,
37
+ ): Record<string, unknown> {
46
38
  const values: Record<string, unknown> = { ...patch };
47
- const instant = Clock.now();
39
+ const instant = Date.now();
48
40
 
49
41
  for (const [name, field] of Object.entries(fields) as [string, Field][]) {
50
42
  if (Lifecycle.of(field).stampedOnUpdate && !(name in values))