@fougere/schema 0.2.0-alpha.1 → 0.3.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 (319) hide show
  1. package/dist/EntityDeclarations.d.ts +22 -0
  2. package/dist/EntityDeclarations.d.ts.map +1 -0
  3. package/dist/EntityDeclarations.js +19 -0
  4. package/dist/EntityDeclarations.js.map +1 -0
  5. package/dist/Field.d.ts +21 -0
  6. package/dist/Field.d.ts.map +1 -0
  7. package/dist/Field.js +50 -0
  8. package/dist/Field.js.map +1 -0
  9. package/dist/Schema.d.ts +67 -0
  10. package/dist/Schema.d.ts.map +1 -0
  11. package/dist/Schema.js +152 -0
  12. package/dist/Schema.js.map +1 -0
  13. package/dist/SchemaView.d.ts +18 -0
  14. package/dist/SchemaView.d.ts.map +1 -0
  15. package/dist/SchemaView.js +2 -0
  16. package/dist/SchemaView.js.map +1 -0
  17. package/dist/axis/Axis.d.ts +10 -0
  18. package/dist/axis/Axis.d.ts.map +1 -0
  19. package/dist/axis/Axis.js +9 -0
  20. package/dist/axis/Axis.js.map +1 -0
  21. package/dist/axis/Meta.d.ts +4 -0
  22. package/dist/axis/Meta.d.ts.map +1 -0
  23. package/dist/axis/Meta.js +2 -0
  24. package/dist/axis/Meta.js.map +1 -0
  25. package/dist/axis/boundary/Boundaries.d.ts +20 -0
  26. package/dist/axis/boundary/Boundaries.d.ts.map +1 -0
  27. package/dist/axis/boundary/Boundaries.js +31 -0
  28. package/dist/axis/boundary/Boundaries.js.map +1 -0
  29. package/dist/axis/boundary/Boundary.d.ts +26 -0
  30. package/dist/axis/boundary/Boundary.d.ts.map +1 -0
  31. package/dist/axis/boundary/Boundary.js +53 -0
  32. package/dist/axis/boundary/Boundary.js.map +1 -0
  33. package/dist/axis/boundary/axis.d.ts +4 -0
  34. package/dist/axis/boundary/axis.d.ts.map +1 -0
  35. package/dist/axis/boundary/axis.js +29 -0
  36. package/dist/axis/boundary/axis.js.map +1 -0
  37. package/dist/axis/lifecycle/Generators.d.ts +4 -0
  38. package/dist/axis/lifecycle/Generators.d.ts.map +1 -0
  39. package/dist/axis/lifecycle/Generators.js +8 -0
  40. package/dist/axis/lifecycle/Generators.js.map +1 -0
  41. package/dist/axis/lifecycle/Lifecycle.d.ts +28 -0
  42. package/dist/axis/lifecycle/Lifecycle.d.ts.map +1 -0
  43. package/dist/axis/lifecycle/Lifecycle.js +38 -0
  44. package/dist/axis/lifecycle/Lifecycle.js.map +1 -0
  45. package/dist/axis/lifecycle/apply.d.ts +8 -0
  46. package/dist/axis/lifecycle/apply.d.ts.map +1 -0
  47. package/dist/axis/lifecycle/apply.js +72 -0
  48. package/dist/axis/lifecycle/apply.js.map +1 -0
  49. package/dist/axis/lifecycle/axis.d.ts +4 -0
  50. package/dist/axis/lifecycle/axis.d.ts.map +1 -0
  51. package/dist/axis/lifecycle/axis.js +46 -0
  52. package/dist/axis/lifecycle/axis.js.map +1 -0
  53. package/dist/axis/role/Relation.d.ts +10 -0
  54. package/dist/axis/role/Relation.d.ts.map +1 -0
  55. package/dist/axis/role/Relation.js +6 -0
  56. package/dist/axis/role/Relation.js.map +1 -0
  57. package/dist/axis/role/Role.d.ts +38 -0
  58. package/dist/axis/role/Role.d.ts.map +1 -0
  59. package/dist/axis/role/Role.js +50 -0
  60. package/dist/axis/role/Role.js.map +1 -0
  61. package/dist/axis/role/axis.d.ts +5 -0
  62. package/dist/axis/role/axis.d.ts.map +1 -0
  63. package/dist/axis/role/axis.js +101 -0
  64. package/dist/axis/role/axis.js.map +1 -0
  65. package/dist/axis/shape/Formats.d.ts +8 -0
  66. package/dist/axis/shape/Formats.d.ts.map +1 -0
  67. package/dist/axis/shape/Formats.js +10 -0
  68. package/dist/axis/shape/Formats.js.map +1 -0
  69. package/dist/axis/shape/Shape.d.ts +58 -0
  70. package/dist/axis/shape/Shape.d.ts.map +1 -0
  71. package/dist/axis/shape/Shape.js +52 -0
  72. package/dist/axis/shape/Shape.js.map +1 -0
  73. package/dist/card/Descriptor.d.ts +55 -0
  74. package/dist/card/Descriptor.d.ts.map +1 -0
  75. package/dist/card/Descriptor.js +2 -0
  76. package/dist/card/Descriptor.js.map +1 -0
  77. package/dist/card/describe.d.ts +12 -0
  78. package/dist/card/describe.d.ts.map +1 -0
  79. package/dist/card/describe.js +83 -0
  80. package/dist/card/describe.js.map +1 -0
  81. package/dist/card/diff.d.ts +140 -0
  82. package/dist/card/diff.d.ts.map +1 -0
  83. package/dist/card/diff.js +123 -0
  84. package/dist/card/diff.js.map +1 -0
  85. package/dist/card/reconstruct.d.ts +11 -0
  86. package/dist/card/reconstruct.d.ts.map +1 -0
  87. package/dist/card/reconstruct.js +83 -0
  88. package/dist/card/reconstruct.js.map +1 -0
  89. package/dist/card/typescript.d.ts +17 -0
  90. package/dist/card/typescript.d.ts.map +1 -0
  91. package/dist/card/typescript.js +93 -0
  92. package/dist/card/typescript.js.map +1 -0
  93. package/dist/clean.d.ts +2 -0
  94. package/dist/clean.d.ts.map +1 -0
  95. package/dist/{projections/card.js → clean.js} +1 -2
  96. package/dist/clean.js.map +1 -0
  97. package/dist/constraint/FieldGroup.d.ts +21 -0
  98. package/dist/constraint/FieldGroup.d.ts.map +1 -0
  99. package/dist/constraint/FieldGroup.js +65 -0
  100. package/dist/constraint/FieldGroup.js.map +1 -0
  101. package/dist/constraint/Unique.d.ts +4 -0
  102. package/dist/constraint/Unique.d.ts.map +1 -0
  103. package/dist/constraint/Unique.js +4 -0
  104. package/dist/constraint/Unique.js.map +1 -0
  105. package/dist/entity.d.ts +4 -116
  106. package/dist/entity.d.ts.map +1 -1
  107. package/dist/entity.js +13 -289
  108. package/dist/entity.js.map +1 -1
  109. package/dist/index.d.ts +35 -17
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +25 -26
  112. package/dist/index.js.map +1 -1
  113. package/dist/judge/Judge.d.ts +14 -0
  114. package/dist/judge/Judge.d.ts.map +1 -0
  115. package/dist/judge/Judge.js +161 -0
  116. package/dist/judge/Judge.js.map +1 -0
  117. package/dist/judge/cases.d.ts +50 -0
  118. package/dist/judge/cases.d.ts.map +1 -0
  119. package/dist/judge/cases.js +100 -0
  120. package/dist/judge/cases.js.map +1 -0
  121. package/dist/judge/form.d.ts +11 -0
  122. package/dist/judge/form.d.ts.map +1 -0
  123. package/dist/judge/form.js +18 -0
  124. package/dist/judge/form.js.map +1 -0
  125. package/dist/judge/options.d.ts +4 -0
  126. package/dist/judge/options.d.ts.map +1 -0
  127. package/dist/judge/options.js +2 -0
  128. package/dist/judge/options.js.map +1 -0
  129. package/dist/judge/result.d.ts +17 -0
  130. package/dist/judge/result.d.ts.map +1 -0
  131. package/dist/judge/result.js +2 -0
  132. package/dist/judge/result.js.map +1 -0
  133. package/dist/name.d.ts +1 -14
  134. package/dist/name.d.ts.map +1 -1
  135. package/dist/name.js +3 -14
  136. package/dist/name.js.map +1 -1
  137. package/dist/projection/encode.d.ts +3 -0
  138. package/dist/projection/encode.d.ts.map +1 -0
  139. package/dist/projection/encode.js +19 -0
  140. package/dist/projection/encode.js.map +1 -0
  141. package/dist/projection/io.d.ts +4 -0
  142. package/dist/projection/io.d.ts.map +1 -0
  143. package/dist/projection/io.js +29 -0
  144. package/dist/projection/io.js.map +1 -0
  145. package/dist/projection/source.d.ts +7 -0
  146. package/dist/projection/source.d.ts.map +1 -0
  147. package/dist/projection/source.js +11 -0
  148. package/dist/projection/source.js.map +1 -0
  149. package/dist/{projections → projection}/standard.d.ts +0 -8
  150. package/dist/projection/standard.d.ts.map +1 -0
  151. package/dist/projection/standard.js +2 -0
  152. package/dist/projection/standard.js.map +1 -0
  153. package/dist/same.d.ts +6 -0
  154. package/dist/same.d.ts.map +1 -0
  155. package/dist/same.js +35 -0
  156. package/dist/same.js.map +1 -0
  157. package/dist/vocabulary/bool.d.ts +1 -1
  158. package/dist/vocabulary/bool.d.ts.map +1 -1
  159. package/dist/vocabulary/bool.js +2 -2
  160. package/dist/vocabulary/bool.js.map +1 -1
  161. package/dist/vocabulary/created.d.ts +2 -12
  162. package/dist/vocabulary/created.d.ts.map +1 -1
  163. package/dist/vocabulary/created.js +3 -14
  164. package/dist/vocabulary/created.js.map +1 -1
  165. package/dist/vocabulary/date.d.ts +1 -1
  166. package/dist/vocabulary/date.d.ts.map +1 -1
  167. package/dist/vocabulary/date.js +2 -2
  168. package/dist/vocabulary/date.js.map +1 -1
  169. package/dist/vocabulary/email.d.ts +1 -2
  170. package/dist/vocabulary/email.d.ts.map +1 -1
  171. package/dist/vocabulary/email.js +0 -1
  172. package/dist/vocabulary/email.js.map +1 -1
  173. package/dist/vocabulary/immutable.d.ts +2 -8
  174. package/dist/vocabulary/immutable.d.ts.map +1 -1
  175. package/dist/vocabulary/immutable.js +4 -10
  176. package/dist/vocabulary/immutable.js.map +1 -1
  177. package/dist/vocabulary/indexed.d.ts +2 -18
  178. package/dist/vocabulary/indexed.d.ts.map +1 -1
  179. package/dist/vocabulary/indexed.js +2 -20
  180. package/dist/vocabulary/indexed.js.map +1 -1
  181. package/dist/vocabulary/json.d.ts +3 -16
  182. package/dist/vocabulary/json.d.ts.map +1 -1
  183. package/dist/vocabulary/json.js +12 -9
  184. package/dist/vocabulary/json.js.map +1 -1
  185. package/dist/vocabulary/list.d.ts +2 -16
  186. package/dist/vocabulary/list.d.ts.map +1 -1
  187. package/dist/vocabulary/list.js +3 -15
  188. package/dist/vocabulary/list.js.map +1 -1
  189. package/dist/vocabulary/many.d.ts +2 -6
  190. package/dist/vocabulary/many.d.ts.map +1 -1
  191. package/dist/vocabulary/many.js +4 -7
  192. package/dist/vocabulary/many.js.map +1 -1
  193. package/dist/vocabulary/nullable.d.ts +2 -8
  194. package/dist/vocabulary/nullable.d.ts.map +1 -1
  195. package/dist/vocabulary/nullable.js +5 -12
  196. package/dist/vocabulary/nullable.js.map +1 -1
  197. package/dist/vocabulary/number.d.ts +1 -1
  198. package/dist/vocabulary/number.d.ts.map +1 -1
  199. package/dist/vocabulary/number.js +2 -2
  200. package/dist/vocabulary/number.js.map +1 -1
  201. package/dist/vocabulary/oneOf.d.ts +1 -8
  202. package/dist/vocabulary/oneOf.d.ts.map +1 -1
  203. package/dist/vocabulary/oneOf.js +2 -2
  204. package/dist/vocabulary/oneOf.js.map +1 -1
  205. package/dist/vocabulary/optional.d.ts +2 -9
  206. package/dist/vocabulary/optional.d.ts.map +1 -1
  207. package/dist/vocabulary/optional.js +6 -14
  208. package/dist/vocabulary/optional.js.map +1 -1
  209. package/dist/vocabulary/primary.d.ts +4 -17
  210. package/dist/vocabulary/primary.d.ts.map +1 -1
  211. package/dist/vocabulary/primary.js +10 -13
  212. package/dist/vocabulary/primary.js.map +1 -1
  213. package/dist/vocabulary/readOnly.d.ts +2 -9
  214. package/dist/vocabulary/readOnly.d.ts.map +1 -1
  215. package/dist/vocabulary/readOnly.js +5 -11
  216. package/dist/vocabulary/readOnly.js.map +1 -1
  217. package/dist/vocabulary/ref.d.ts +2 -7
  218. package/dist/vocabulary/ref.d.ts.map +1 -1
  219. package/dist/vocabulary/ref.js +3 -8
  220. package/dist/vocabulary/ref.js.map +1 -1
  221. package/dist/vocabulary/text.d.ts +2 -2
  222. package/dist/vocabulary/text.d.ts.map +1 -1
  223. package/dist/vocabulary/text.js +2 -2
  224. package/dist/vocabulary/text.js.map +1 -1
  225. package/dist/vocabulary/unique.d.ts +2 -22
  226. package/dist/vocabulary/unique.d.ts.map +1 -1
  227. package/dist/vocabulary/unique.js +5 -24
  228. package/dist/vocabulary/unique.js.map +1 -1
  229. package/dist/vocabulary/updated.d.ts +2 -7
  230. package/dist/vocabulary/updated.d.ts.map +1 -1
  231. package/dist/vocabulary/updated.js +1 -7
  232. package/dist/vocabulary/updated.js.map +1 -1
  233. package/dist/vocabulary/url.d.ts +1 -2
  234. package/dist/vocabulary/url.d.ts.map +1 -1
  235. package/dist/vocabulary/url.js +0 -1
  236. package/dist/vocabulary/url.js.map +1 -1
  237. package/dist/vocabulary/vocabulary.d.ts +5 -0
  238. package/dist/vocabulary/vocabulary.d.ts.map +1 -0
  239. package/dist/vocabulary/vocabulary.js +31 -0
  240. package/dist/vocabulary/vocabulary.js.map +1 -0
  241. package/dist/vocabulary/writeOnly.d.ts +2 -8
  242. package/dist/vocabulary/writeOnly.d.ts.map +1 -1
  243. package/dist/vocabulary/writeOnly.js +5 -10
  244. package/dist/vocabulary/writeOnly.js.map +1 -1
  245. package/package.json +2 -2
  246. package/dist/field/boundary.d.ts +0 -86
  247. package/dist/field/boundary.d.ts.map +0 -1
  248. package/dist/field/boundary.js +0 -94
  249. package/dist/field/boundary.js.map +0 -1
  250. package/dist/field/field.d.ts +0 -64
  251. package/dist/field/field.d.ts.map +0 -1
  252. package/dist/field/field.js +0 -28
  253. package/dist/field/field.js.map +0 -1
  254. package/dist/field/index.d.ts +0 -7
  255. package/dist/field/index.d.ts.map +0 -1
  256. package/dist/field/index.js +0 -9
  257. package/dist/field/index.js.map +0 -1
  258. package/dist/field/lifecycle.d.ts +0 -40
  259. package/dist/field/lifecycle.d.ts.map +0 -1
  260. package/dist/field/lifecycle.js +0 -27
  261. package/dist/field/lifecycle.js.map +0 -1
  262. package/dist/field/meta.d.ts +0 -9
  263. package/dist/field/meta.d.ts.map +0 -1
  264. package/dist/field/meta.js +0 -7
  265. package/dist/field/meta.js.map +0 -1
  266. package/dist/field/role.d.ts +0 -54
  267. package/dist/field/role.d.ts.map +0 -1
  268. package/dist/field/role.js +0 -55
  269. package/dist/field/role.js.map +0 -1
  270. package/dist/field/shape.d.ts +0 -77
  271. package/dist/field/shape.d.ts.map +0 -1
  272. package/dist/field/shape.js +0 -49
  273. package/dist/field/shape.js.map +0 -1
  274. package/dist/hints.d.ts +0 -33
  275. package/dist/hints.d.ts.map +0 -1
  276. package/dist/hints.js +0 -2
  277. package/dist/hints.js.map +0 -1
  278. package/dist/projections/card.d.ts +0 -117
  279. package/dist/projections/card.d.ts.map +0 -1
  280. package/dist/projections/card.js.map +0 -1
  281. package/dist/projections/describe.d.ts +0 -25
  282. package/dist/projections/describe.d.ts.map +0 -1
  283. package/dist/projections/describe.js +0 -136
  284. package/dist/projections/describe.js.map +0 -1
  285. package/dist/projections/encode.d.ts +0 -11
  286. package/dist/projections/encode.d.ts.map +0 -1
  287. package/dist/projections/encode.js +0 -26
  288. package/dist/projections/encode.js.map +0 -1
  289. package/dist/projections/io.d.ts +0 -30
  290. package/dist/projections/io.d.ts.map +0 -1
  291. package/dist/projections/io.js +0 -52
  292. package/dist/projections/io.js.map +0 -1
  293. package/dist/projections/lifecycle.d.ts +0 -43
  294. package/dist/projections/lifecycle.d.ts.map +0 -1
  295. package/dist/projections/lifecycle.js +0 -115
  296. package/dist/projections/lifecycle.js.map +0 -1
  297. package/dist/projections/reconstruct.d.ts +0 -36
  298. package/dist/projections/reconstruct.d.ts.map +0 -1
  299. package/dist/projections/reconstruct.js +0 -149
  300. package/dist/projections/reconstruct.js.map +0 -1
  301. package/dist/projections/source.d.ts +0 -41
  302. package/dist/projections/source.d.ts.map +0 -1
  303. package/dist/projections/source.js +0 -37
  304. package/dist/projections/source.js.map +0 -1
  305. package/dist/projections/standard.d.ts.map +0 -1
  306. package/dist/projections/standard.js +0 -10
  307. package/dist/projections/standard.js.map +0 -1
  308. package/dist/projections/typescript.d.ts +0 -53
  309. package/dist/projections/typescript.d.ts.map +0 -1
  310. package/dist/projections/typescript.js +0 -184
  311. package/dist/projections/typescript.js.map +0 -1
  312. package/dist/projections/validation.d.ts +0 -57
  313. package/dist/projections/validation.d.ts.map +0 -1
  314. package/dist/projections/validation.js +0 -148
  315. package/dist/projections/validation.js.map +0 -1
  316. package/dist/unique.d.ts +0 -65
  317. package/dist/unique.d.ts.map +0 -1
  318. package/dist/unique.js +0 -80
  319. package/dist/unique.js.map +0 -1
@@ -1,148 +0,0 @@
1
- import { anatomy, boundaryOf, resolveBoundary } from '../field/index.js';
2
- import { Validator } from '@cfworker/json-schema';
3
- /**
4
- * One validator per shape — the shape object IS the source JSON Schema (the closed
5
- * grammar the helpers emit), handed straight to the engine. Keyed by the shape
6
- * reference (stable: derivations copy field refs, `partial()` spreads the field but
7
- * keeps the same `shape`), built once and reused so the parse cost is amortised.
8
- */
9
- const validators = new WeakMap();
10
- function validatorFor(shape) {
11
- let v = validators.get(shape);
12
- if (!v) {
13
- v = new Validator(shape, '2020-12', true);
14
- validators.set(shape, v);
15
- }
16
- return v;
17
- }
18
- /**
19
- * Validate a present value (null included) against its field — pure, never mutates.
20
- *
21
- * Reads `shape` and nothing else, so it answers "is this a legal value?" without ever
22
- * asking who is speaking. That is what makes it usable on the way OUT of the domain,
23
- * where the client-only axes (`boundary`, `lifecycle`) do not apply.
24
- */
25
- export function checkValue(field, value) {
26
- const shape = field.shape;
27
- // Relation-only field (`many`): no value shape, just an array of related rows.
28
- if (!shape) {
29
- if (field.role?.relation?.kind === 'many') {
30
- return Array.isArray(value) ? { value } : { error: 'Expected an array' };
31
- }
32
- return { value };
33
- }
34
- // The pre-engine guards dispatch on the BASE type — `shape.type` itself may be
35
- // the nullable union. They only short-circuit NON-null values: null always goes
36
- // to the engine, whose union judges it (that is the whole nullability model).
37
- const base = anatomy(shape).base;
38
- if (value !== null) {
39
- // Opaque JSON (`json()`): no nested shape → passes through unchecked.
40
- // `json(Entity)` carries `properties` and falls through to the engine,
41
- // which validates the nesting natively (it's plain JSON Schema).
42
- if (base?.type === 'object' && !base.properties)
43
- return { value };
44
- // A date-time field also accepts a live Date — the domain value, not its JSON wire
45
- // string — which the boundary then passes through. The engine validates JSON, so a
46
- // Date (a non-JSON value) skips the schema check here; a date STRING is validated below.
47
- if (base?.type === 'string' && base.format === 'date-time' && value instanceof Date) {
48
- return Number.isNaN(value.getTime()) ? { error: 'Invalid date' } : { value };
49
- }
50
- // NaN is `typeof number` yet has no JSON form, so the JSON-centric engine accepts it —
51
- // guard it here (same nature as the Date case: a JS value JSON can't represent).
52
- if ((base?.type === 'number' || base?.type === 'integer') && typeof value === 'number' && Number.isNaN(value)) {
53
- return { error: 'Expected a number' };
54
- }
55
- }
56
- const result = validatorFor(shape).validate(value);
57
- return result.valid ? { value } : { error: result.errors[0]?.error ?? 'Invalid value' };
58
- }
59
- /**
60
- * A path is a field NAME here, never a dotted trail: `json(Entity)` is judged as one
61
- * opaque shape by the engine, so a nested failure answers `{ path: 'addr' }` with the
62
- * inner field in the prose. This used to take a `pathPrefix` that every call site passed
63
- * as `''` — a parameter for a recursion nobody wrote, which made the code read as if
64
- * nesting were handled. Writing that recursion changes what `FougereError.details`
65
- * carries across processes and languages, so it is a contract decision, not a patch.
66
- */
67
- export function validateFields(fields, input, opts = {}) {
68
- if (typeof input !== 'object' || input === null) {
69
- return { success: false, errors: [{ path: '.', message: 'Expected an object' }] };
70
- }
71
- const data = input;
72
- const errors = [];
73
- const out = {};
74
- // Refuse, never strip: a key outside the contract is an error, not a silent
75
- // drop. The client derives from the same contract (a form cannot emit a
76
- // foreign key), so a stranger is a bug or an attack — both deserve the 400.
77
- // Stripping would also let the envelope diverge from GraphQL, which refuses
78
- // unknown input keys by construction.
79
- //
80
- // A FACT is judged by this same rule, deliberately — the one place it was tempting to
81
- // relax it. A subscriber's copy of a fact can be older than the sender's, so tolerating
82
- // a stranger key would let a rolling deployment through; it would also mean a reader
83
- // silently ignoring a field it was supposed to handle. If the judge refuses, that is
84
- // the end of it: the sender re-syncs its readers before it ships.
85
- for (const key of Object.keys(data)) {
86
- if (!(key in fields)) {
87
- errors.push({ path: key, message: 'Unknown field' });
88
- }
89
- }
90
- for (const [key, field] of Object.entries(fields)) {
91
- const path = key;
92
- const value = data[key];
93
- if (value === undefined) {
94
- if (opts.patch)
95
- continue; // patch: an unsent field is left untouched
96
- // A read-only field is server-owned: its absence from a client input is
97
- // never "Required" (same stance as OpenAPI readOnly+required).
98
- if (boundaryOf(field).in === 'closed')
99
- continue;
100
- // Absence is answered by `lifecycle.create` — a key access on the normal
101
- // form. The judge only asks "is there a rule?": any rule ('now',
102
- // 'optional', { value }, { generate }) makes absence legal, and the field
103
- // is omitted from the result. Realisation is the storage adapter's role.
104
- if (field.lifecycle?.create !== undefined)
105
- continue;
106
- // No create rule: a `many` relation defaults to the empty collection
107
- // (graph semantics, read on `role` — never a shared `{ value: [] }`).
108
- if (field.role?.relation?.kind === 'many') {
109
- out[key] = [];
110
- continue;
111
- }
112
- errors.push({ path, message: 'Required' });
113
- continue;
114
- }
115
- // A PRESENT value can be illegal by an axis other than shape:
116
- // boundary `in: 'closed'` — a read-only field never crosses inbound;
117
- // lifecycle `update: 'forbidden'` — re-supplying an immutable field in a patch.
118
- if (boundaryOf(field).in === 'closed') {
119
- errors.push({ path, message: 'Read-only' });
120
- continue;
121
- }
122
- if (opts.patch && field.lifecycle?.update === 'forbidden') {
123
- errors.push({ path, message: 'Immutable' });
124
- continue;
125
- }
126
- // The shape predicate judges the value — null included, via the `[T,'null']`
127
- // union. Then the boundary's decode converts wire→domain; null skips decode
128
- // (a legal null is already the domain value, there is nothing to convert).
129
- const checked = checkValue(field, value);
130
- if ('error' in checked) {
131
- errors.push({ path, message: checked.error });
132
- continue;
133
- }
134
- if (checked.value === null) {
135
- out[key] = null;
136
- continue;
137
- }
138
- const decoded = resolveBoundary(field).decode(checked.value);
139
- if ('error' in decoded)
140
- errors.push({ path, message: decoded.error });
141
- else
142
- out[key] = decoded.value;
143
- }
144
- if (errors.length > 0)
145
- return { success: false, errors };
146
- return { success: true, data: out };
147
- }
148
- //# sourceMappingURL=validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/projections/validation.ts"],"names":[],"mappings":"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"}
package/dist/unique.d.ts DELETED
@@ -1,65 +0,0 @@
1
- import type { Fields } from './field/index.js';
2
- import type { Hints } from './hints.js';
3
- /**
4
- * Field names that identify at most one row when taken together.
5
- *
6
- * `unique(field)` states a fact about one column; some facts are about a pair.
7
- * "A book appears once in a list" is true of `(listId, docId)` and of neither
8
- * alone, and there is no shape that can express it — judging one value never
9
- * sees the other rows. So it is declared on the entity and realized by storage.
10
- *
11
- * Held here rather than in a handler because a handler cannot hold it: a check
12
- * followed by a write is two round trips, and a concurrent request fits between
13
- * them. The database is the only place where the promise is keepable.
14
- */
15
- export type CompositeUnique<TFields extends Fields> = ReadonlyArray<ReadonlyArray<Extract<keyof TFields, string>>>;
16
- /**
17
- * What an entity declares about itself, beyond its fields — the 2nd argument of
18
- * `entity()`.
19
- *
20
- * One object rather than a growing parameter list: a second fact about an entity
21
- * adds a key here, never a positional argument.
22
- */
23
- export interface EntityDeclarations<TFields extends Fields> {
24
- /** Field groups that must be unique together. */
25
- unique?: CompositeUnique<TFields>;
26
- /** Per-consumer hints, keyed by registered adapter. See {@link Hints}. */
27
- hints?: Hints<TFields>;
28
- }
29
- /**
30
- * Carry composite groups across a field-key transform — the entity-level twin of
31
- * `deriveHints`.
32
- *
33
- * A group whose members did not all survive is dropped rather than narrowed: the
34
- * pair `(listId, docId)` says nothing about `listId` alone, and keeping the
35
- * remnant would silently state a stronger fact than the author ever wrote.
36
- */
37
- export declare function deriveUnique(groups: CompositeUnique<Fields> | undefined, mapKey: (key: string) => string | undefined): CompositeUnique<Fields> | undefined;
38
- /**
39
- * Carry the projected groups across the same key transform — the field-level twin of
40
- * {@link deriveUnique}, and it has to run with it: the group lives in TWO places once
41
- * projected (the declaration and each member's role), so remapping one alone left
42
- * `pick('id','listId')` with a role still claiming a pair whose other member was gone.
43
- *
44
- * Same rule as the declaration — a group that lost a member is dropped, not narrowed.
45
- * The empty self-reference needs no remapping: it names no key, which is exactly why it
46
- * survives a `rename()` for free.
47
- */
48
- export declare function deriveUniqueRoles<TFields extends Fields>(fields: TFields, mapKey: (key: string) => string | undefined): TFields;
49
- /**
50
- * Project the entity's composite groups onto the role of every member — the single
51
- * place the two ways of stating uniqueness meet.
52
- *
53
- * The author writes each fact where it lives: `unique(slug)` on the field it is about,
54
- * `entity(fields, { unique: [['listId','docId']] })` on the entity, because a fact about
55
- * a pair is held by neither field alone. Both then read as ONE normal form on the role
56
- * axis, so every consumer — the DDL, the card, a foreign adapter — has a single shape to
57
- * handle, and a field belonging to two constraints simply carries two member lists.
58
- *
59
- * The entity declaration stays the source (`getUnique()` keeps answering it); this is a
60
- * projection of it, never a second place to edit. A named member group is spelled out
61
- * here, while a lone `unique()` keeps its `[]` self-reference — resolved by whoever reads
62
- * it, which is what makes `rename()` free.
63
- */
64
- export declare function projectUniqueOntoFields<TFields extends Fields>(fields: TFields, groups: CompositeUnique<TFields> | undefined): TFields;
65
- //# sourceMappingURL=unique.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"unique.d.ts","sourceRoot":"","sources":["../src/unique.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,CAAC,OAAO,SAAS,MAAM,IAAI,aAAa,CACjE,aAAa,CAAC,OAAO,CAAC,MAAM,OAAO,EAAE,MAAM,CAAC,CAAC,CAC9C,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB,CAAC,OAAO,SAAS,MAAM;IACxD,iDAAiD;IACjD,MAAM,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAClC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,SAAS,EAC3C,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAC1C,eAAe,CAAC,MAAM,CAAC,GAAG,SAAS,CAQrC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,SAAS,MAAM,EACtD,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAC1C,OAAO,CAkBT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,SAAS,MAAM,EAC5D,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,GAC3C,OAAO,CAiBT"}
package/dist/unique.js DELETED
@@ -1,80 +0,0 @@
1
- /**
2
- * Carry composite groups across a field-key transform — the entity-level twin of
3
- * `deriveHints`.
4
- *
5
- * A group whose members did not all survive is dropped rather than narrowed: the
6
- * pair `(listId, docId)` says nothing about `listId` alone, and keeping the
7
- * remnant would silently state a stronger fact than the author ever wrote.
8
- */
9
- export function deriveUnique(groups, mapKey) {
10
- if (!groups)
11
- return undefined;
12
- const carried = groups
13
- .map((group) => group.map(mapKey))
14
- .filter((group) => group.every((key) => key !== undefined));
15
- return carried.length > 0 ? carried : undefined;
16
- }
17
- /**
18
- * Carry the projected groups across the same key transform — the field-level twin of
19
- * {@link deriveUnique}, and it has to run with it: the group lives in TWO places once
20
- * projected (the declaration and each member's role), so remapping one alone left
21
- * `pick('id','listId')` with a role still claiming a pair whose other member was gone.
22
- *
23
- * Same rule as the declaration — a group that lost a member is dropped, not narrowed.
24
- * The empty self-reference needs no remapping: it names no key, which is exactly why it
25
- * survives a `rename()` for free.
26
- */
27
- export function deriveUniqueRoles(fields, mapKey) {
28
- const out = { ...fields };
29
- for (const [key, field] of Object.entries(out)) {
30
- const groups = field.role?.unique;
31
- if (!groups?.length)
32
- continue;
33
- const carried = groups
34
- .map((group) => (group.length === 0 ? [] : group.map(mapKey)))
35
- .filter((group) => group.every((member) => member !== undefined));
36
- if (carried.length === groups.length)
37
- continue; // nothing lost, keep the field as is
38
- const { unique: _dropped, ...rest } = field.role;
39
- out[key] = {
40
- ...field,
41
- role: carried.length ? { ...rest, unique: carried } : rest,
42
- };
43
- }
44
- return out;
45
- }
46
- /**
47
- * Project the entity's composite groups onto the role of every member — the single
48
- * place the two ways of stating uniqueness meet.
49
- *
50
- * The author writes each fact where it lives: `unique(slug)` on the field it is about,
51
- * `entity(fields, { unique: [['listId','docId']] })` on the entity, because a fact about
52
- * a pair is held by neither field alone. Both then read as ONE normal form on the role
53
- * axis, so every consumer — the DDL, the card, a foreign adapter — has a single shape to
54
- * handle, and a field belonging to two constraints simply carries two member lists.
55
- *
56
- * The entity declaration stays the source (`getUnique()` keeps answering it); this is a
57
- * projection of it, never a second place to edit. A named member group is spelled out
58
- * here, while a lone `unique()` keeps its `[]` self-reference — resolved by whoever reads
59
- * it, which is what makes `rename()` free.
60
- */
61
- export function projectUniqueOntoFields(fields, groups) {
62
- if (!groups || groups.length === 0)
63
- return fields;
64
- const projected = { ...fields };
65
- for (const group of groups) {
66
- const members = [...group];
67
- for (const key of members) {
68
- const field = projected[key];
69
- if (!field)
70
- continue; // a group naming an absent field states nothing here
71
- const already = field.role?.unique ?? [];
72
- projected[key] = {
73
- ...field,
74
- role: { ...field.role, unique: [...already, members] },
75
- };
76
- }
77
- }
78
- return projected;
79
- }
80
- //# sourceMappingURL=unique.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"unique.js","sourceRoot":"","sources":["../src/unique.ts"],"names":[],"mappings":"AAiCA;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,MAA2C,EAC3C,MAA2C;IAE3C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAE9B,MAAM,OAAO,GAAG,MAAM;SACnB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SACjC,MAAM,CAAC,CAAC,KAAK,EAAqB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC;IAEjF,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAe,EACf,MAA2C;IAE3C,MAAM,GAAG,GAAG,EAAE,GAAG,MAAM,EAAY,CAAC;IACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,MAAM;YAAE,SAAS;QAE9B,MAAM,OAAO,GAAG,MAAM;aACnB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;aAC7D,MAAM,CAAC,CAAC,KAAK,EAAqB,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC;QAEvF,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;YAAE,SAAS,CAAG,qCAAqC;QACvF,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,IAAK,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,GAAG;YACT,GAAG,KAAK;YACR,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;SAC3D,CAAC;IACJ,CAAC;IACD,OAAO,GAAc,CAAC;AACxB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAe,EACf,MAA4C;IAE5C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAElD,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,EAAY,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QAC3B,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK;gBAAE,SAAS,CAAG,qDAAqD;YAC7E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC;YACzC,SAAS,CAAC,GAAG,CAAC,GAAG;gBACf,GAAG,KAAK;gBACR,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,EAAE;aACvD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAoB,CAAC;AAC9B,CAAC"}