@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,36 +0,0 @@
1
- import { type Field, type Fields } from '../field/index.js';
2
- import { type SchemaConstructor, type SchemaViewInfer } from '../entity.js';
3
- import { type SchemaBundle, type SchemaDescriptor } from './card.js';
4
- /**
5
- * The field map a stated row shape implies.
6
- *
7
- * Every member is marked auto-at-creation, so `CtorInput` asks for nothing: a card
8
- * describes rows as they are READ, and "what a caller must supply at creation" is a
9
- * different question — one `required` answers, and one a synced consumer never asks,
10
- * since it calls the host rather than constructing.
11
- */
12
- type FieldsOf<T> = {
13
- [K in keyof T]-?: Field<T[K], true>;
14
- };
15
- /**
16
- * Read a lone card back into a working schema — THE single reconstructor. The result
17
- * carries its `~standard` (live validation) rebuilt locally: the descriptor crosses
18
- * the wire as data, the behaviour is reconstituted here. Relations stay name stand-ins
19
- * (no set to resolve against — use {@link reconstructSet} for live targets).
20
- *
21
- * `T` states the shape of a row, and that is what makes a rebuilt schema a CLASS rather
22
- * than a type and a value declared side by side: `class Post extends reconstruct<{…}>(card) {}`
23
- * is one declaration carrying both, exactly like `class Post extends entity({…}) {}`.
24
- * Without it the instance type is an index signature, so a synced entity validated
25
- * perfectly and taught the compiler nothing — `post.titel` compiled.
26
- */
27
- export declare function reconstruct<T = SchemaViewInfer<Fields>>(descriptor: SchemaDescriptor): SchemaConstructor<FieldsOf<T>>;
28
- /**
29
- * Read a whole bundle back into live schemas, keyed by name — THE set reconstructor.
30
- * Every entity is rebuilt against a shared `$defs` resolver, so a relation's `to()`
31
- * hands back the real reconstructed target (feeds adapters), not a name stand-in.
32
- * Targets absent from the set (external/cross-frond `$ref`) keep the stand-in.
33
- */
34
- export declare function reconstructSet(bundle: SchemaBundle): Record<string, SchemaConstructor<Fields>>;
35
- export {};
36
- //# sourceMappingURL=reconstruct.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reconstruct.d.ts","sourceRoot":"","sources":["../../src/projections/reconstruct.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,KAAK,EACV,KAAK,MAAM,EAGZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAA2B,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACrG,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,WAAW,CAAC;AAsHnB;;;;;;;GAOG;AACH,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;CAAE,CAAC;AAE3D;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,EACrD,UAAU,EAAE,gBAAgB,GAC3B,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAEhC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAc9F"}
@@ -1,149 +0,0 @@
1
- import { createField, } from '../field/index.js';
2
- import { createSchemaConstructor } from '../entity.js';
3
- import { clean, } from './card.js';
4
- // ─── reconstruct — card → schema (the single reconstructor) ────────
5
- /**
6
- * Read a JSON Schema property back into a Fougère shape. The `type` travels
7
- * VERBATIM — nullability is the `[T,'null']` union on both sides, so there is
8
- * nothing to split; only the keyword subset of the base type is picked.
9
- */
10
- function reconstructShape(prop) {
11
- const types = Array.isArray(prop.type) ? prop.type : prop.type ? [prop.type] : [];
12
- const base = types.find((t) => t !== 'null');
13
- if (base === undefined)
14
- return undefined;
15
- const type = prop.type;
16
- // `array` is two distinct things: with `items` it is a value list (a real shape);
17
- // without, it is a bare `many` relation marker — no shape, the role carries it.
18
- if (base === 'array') {
19
- if (!prop.items)
20
- return undefined;
21
- const items = reconstructShape(prop.items);
22
- return clean({ type, items, minItems: prop.minItems, maxItems: prop.maxItems });
23
- }
24
- switch (base) {
25
- case 'string':
26
- return clean({ type, minLength: prop.minLength, maxLength: prop.maxLength, pattern: prop.pattern, enum: prop.enum, format: prop.format });
27
- case 'number':
28
- case 'integer':
29
- return clean({ type, minimum: prop.minimum, maximum: prop.maximum });
30
- case 'boolean':
31
- return { type };
32
- default: // 'object' or anything unrecognised → opaque value (nesting travels verbatim)
33
- return clean({ type, properties: prop.properties, required: prop.required });
34
- }
35
- }
36
- function reconstructRole(role, resolve) {
37
- const out = {};
38
- if (role.primary)
39
- out.primary = true;
40
- // Members arrive spelled out and stay that way — a single-member group read back as the
41
- // empty self-reference would re-describe identically but lose the distinction for no
42
- // gain. `uniqueMembers` treats a named group as already resolved.
43
- if (role.unique?.length)
44
- out.unique = role.unique.map((group) => [...group]);
45
- if (role.index)
46
- out.index = true;
47
- if (role.relation) {
48
- const name = role.relation.to;
49
- out.relation = {
50
- // `to` is the `$ref` (a name). With a resolver (a bundle), it hands back the real
51
- // reconstructed target — adapters can read its fields. Lazy, so circular relations
52
- // resolve fine. Without one (a lone card), a name-only stand-in: enough to validate
53
- // (`kind`) and re-describe identically, but not to feed an adapter.
54
- to: () => resolve?.(name) ?? { name },
55
- kind: role.relation.kind,
56
- ...(role.relation.onDelete ? { onDelete: role.relation.onDelete } : {}),
57
- };
58
- }
59
- return out;
60
- }
61
- function reconstructField(prop, resolve) {
62
- const ext = prop['x-fougere'];
63
- return createField({
64
- shape: reconstructShape(prop),
65
- role: ext?.role ? reconstructRole(ext.role, resolve) : undefined,
66
- // The normal forms are pure JSON — they travelled verbatim, they read back verbatim.
67
- lifecycle: ext?.lifecycle,
68
- boundary: ext?.boundary,
69
- meta: prop.description !== undefined ? { description: prop.description } : undefined,
70
- });
71
- }
72
- /**
73
- * The entity-level groups implied by the fields — the inverse of
74
- * `projectUniqueOntoFields`. Only groups of more than one member: a lone `unique(slug)`
75
- * is fully stated by the field's own role, and listing it here would make `getUnique()`
76
- * answer a composite the author never declared.
77
- */
78
- function compositeFromFields(fields) {
79
- const seen = new Map();
80
- for (const field of Object.values(fields)) {
81
- for (const group of field.role?.unique ?? []) {
82
- if (group.length < 2)
83
- continue;
84
- // A key that cannot collide with a field name — `JSON.stringify` rather than a
85
- // separator byte: a NUL in the source made every `grep` read this whole file as
86
- // binary and skip it silently, a poor price for a de-duplication key.
87
- seen.set(JSON.stringify(group), [...group]);
88
- }
89
- }
90
- return seen.size ? [...seen.values()] : undefined;
91
- }
92
- /** Build a live schema from a card; `resolve` wires relation targets when in a bundle. */
93
- function buildSchema(descriptor, resolve) {
94
- const fields = {};
95
- for (const [key, prop] of Object.entries(descriptor.properties)) {
96
- fields[key] = reconstructField(prop, resolve);
97
- }
98
- // Recover the entity-level declaration from what the members carry. The card holds the
99
- // fact once per member; a group of two arrives twice, so the set is de-duplicated —
100
- // `getUnique()` then answers what the original author wrote, and the DDL on this side
101
- // emits the same constraint as the DDL on the other.
102
- const schema = createSchemaConstructor(fields, undefined, undefined, {}, compositeFromFields(fields));
103
- // The name is the identity everything downstream keys on — the registration key, the
104
- // table, the GraphQL type, what a relation's `to` points at. `describe` writes it as
105
- // `title`; dropping it here left a rebuilt schema called `Schema`, so a card could not
106
- // round-trip and an adapter standing on one had no entity name to work from.
107
- // `reconstructSet` still overrides with the bundle key, which is the more specific truth.
108
- if (descriptor.title) {
109
- Object.defineProperty(schema, 'name', { value: descriptor.title, configurable: true });
110
- }
111
- return schema;
112
- }
113
- /**
114
- * Read a lone card back into a working schema — THE single reconstructor. The result
115
- * carries its `~standard` (live validation) rebuilt locally: the descriptor crosses
116
- * the wire as data, the behaviour is reconstituted here. Relations stay name stand-ins
117
- * (no set to resolve against — use {@link reconstructSet} for live targets).
118
- *
119
- * `T` states the shape of a row, and that is what makes a rebuilt schema a CLASS rather
120
- * than a type and a value declared side by side: `class Post extends reconstruct<{…}>(card) {}`
121
- * is one declaration carrying both, exactly like `class Post extends entity({…}) {}`.
122
- * Without it the instance type is an index signature, so a synced entity validated
123
- * perfectly and taught the compiler nothing — `post.titel` compiled.
124
- */
125
- export function reconstruct(descriptor) {
126
- return buildSchema(descriptor);
127
- }
128
- /**
129
- * Read a whole bundle back into live schemas, keyed by name — THE set reconstructor.
130
- * Every entity is rebuilt against a shared `$defs` resolver, so a relation's `to()`
131
- * hands back the real reconstructed target (feeds adapters), not a name stand-in.
132
- * Targets absent from the set (external/cross-frond `$ref`) keep the stand-in.
133
- */
134
- export function reconstructSet(bundle) {
135
- const map = {};
136
- const resolve = (name) => map[name.toLowerCase()];
137
- const out = {};
138
- for (const [name, descriptor] of Object.entries(bundle.$defs)) {
139
- const schema = buildSchema(descriptor, resolve);
140
- // Name the rebuilt class after its key so re-describing it yields the same `to` name
141
- // (describe reads `relation.to().name`). Lazy `to` means the map need only be full
142
- // before any `.to()` call — true once this loop ends.
143
- Object.defineProperty(schema, 'name', { value: name, configurable: true });
144
- map[name.toLowerCase()] = schema;
145
- out[name] = schema;
146
- }
147
- return out;
148
- }
149
- //# sourceMappingURL=reconstruct.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reconstruct.js","sourceRoot":"","sources":["../../src/projections/reconstruct.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,GAOZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,uBAAuB,EAAgD,MAAM,cAAc,CAAC;AACrG,OAAO,EACL,KAAK,GAKN,MAAM,WAAW,CAAC;AAEnB,sEAAsE;AAEtE;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,IAAqB;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAClF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IAC7C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAqB,CAAC;IACxC,kFAAkF;IAClF,gFAAgF;IAChF,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAClC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAqB,CAAC;IACtG,CAAC;IACD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAU,CAAC;QACrJ,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAU,CAAC;QAChF,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAW,CAAC;QAC3B,SAAS,8EAA8E;YACrF,OAAO,KAAK,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAqB,CAAC;IACrG,CAAC;AACH,CAAC;AAQD,SAAS,eAAe,CAAC,IAAoB,EAAE,OAAkB;IAC/D,MAAM,GAAG,GAAS,EAAE,CAAC;IACrB,IAAI,IAAI,CAAC,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;IACrC,wFAAwF;IACxF,qFAAqF;IACrF,kEAAkE;IAClE,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM;QAAE,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;IACjC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,GAAG,CAAC,QAAQ,GAAG;YACb,kFAAkF;YAClF,mFAAmF;YACnF,oFAAoF;YACpF,oEAAoE;YACpE,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,IAAK,EAAE,IAAI,EAAmC;YACvE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACxB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAqB,EAAE,OAAkB;IACjE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IAC9B,OAAO,WAAW,CAAC;QACjB,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC;QAC7B,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;QAChE,qFAAqF;QACrF,SAAS,EAAE,GAAG,EAAE,SAAS;QACzB,QAAQ,EAAE,GAAG,EAAE,QAAQ;QACvB,IAAI,EAAE,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS;KACrF,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,MAAc;IACzC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;YAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,+EAA+E;YAC/E,gFAAgF;YAChF,sEAAsE;YACtE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC;AAED,0FAA0F;AAC1F,SAAS,WAAW,CAAC,UAA4B,EAAE,OAAkB;IACnE,MAAM,MAAM,GAAW,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChE,MAAM,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IACD,uFAAuF;IACvF,oFAAoF;IACpF,sFAAsF;IACtF,qDAAqD;IACrD,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEtG,qFAAqF;IACrF,qFAAqF;IACrF,uFAAuF;IACvF,6EAA6E;IAC7E,0FAA0F;IAC1F,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAYD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CACzB,UAA4B;IAE5B,OAAO,WAAW,CAAC,UAAU,CAA8C,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,MAAM,GAAG,GAAsC,EAAE,CAAC;IAClD,MAAM,OAAO,GAAa,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5D,MAAM,GAAG,GAA8C,EAAE,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,qFAAqF;QACrF,mFAAmF;QACnF,sDAAsD;QACtD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,MAAsC,CAAC;QACjE,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACrB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1,41 +0,0 @@
1
- import type { Fields, SchemaLike } from '../field/index.js';
2
- import type { SchemaDescriptor } from './card.js';
3
- /**
4
- * The two forms a schema reaches an adapter in — and the single reader that takes both.
5
- *
6
- * An adapter has never needed the class, only its fields. In-process it gets the class
7
- * because the class is there; from a remote or foreign frond it gets the card, because a
8
- * class does not cross a wire. Naming that union here is what lets one projection serve
9
- * both, instead of each adapter growing its own branch.
10
- *
11
- * The card was built for exactly this and had no in-repo reader: every adapter called
12
- * `getFields()` on the live class, so writing a Fougere adapter meant being inside the
13
- * repo, in TypeScript, with the class in hand.
14
- */
15
- export type SchemaSource = SchemaLike | SchemaDescriptor;
16
- /**
17
- * Normalize a source to a live schema — reconstructing a card, passing a class through.
18
- *
19
- * This is what an adapter reaching for the schema MORE THAN ONCE should call, once, at its
20
- * boundary: `reconstruct` runs per call (6.5 µs for a 17-field entity), so a component that
21
- * reads fields in two places would otherwise rebuild the schema twice and hold two
22
- * unrelated field objects. Normalize at the edge, then nothing downstream knows the
23
- * difference — which is the point.
24
- */
25
- export declare function schemaOf(source: SchemaSource): SchemaLike;
26
- /**
27
- * The fields an adapter projects from, whichever form it was handed — {@link schemaOf}
28
- * for the single-read case.
29
- *
30
- * Cost: nothing for a class. For a card, one `reconstruct` — measured at 6.5 µs for a
31
- * 17-field entity, paid once per entity when the adapter builds, never per request. Read
32
- * twice and you pay twice: hold the result, or normalize with `schemaOf` instead.
33
- */
34
- export declare function fieldsOf(source: SchemaSource): Fields;
35
- /**
36
- * The composite unique groups, whichever form. A bare wrapper (a view mid-derivation)
37
- * carries no `getUnique` and answers `undefined`; a card's groups are recovered from what
38
- * its members carry, so `reconstruct` has already restored them by the time this reads.
39
- */
40
- export declare function uniqueOf(source: SchemaSource): ReadonlyArray<ReadonlyArray<string>> | undefined;
41
- //# sourceMappingURL=source.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/projections/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAGlD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAOzD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,UAAU,CAEzD;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAE/F"}
@@ -1,37 +0,0 @@
1
- import { reconstruct } from './reconstruct.js';
2
- /** A card is the plain document — no behaviour, so no `getFields`. */
3
- function isDescriptor(source) {
4
- return typeof source.getFields !== 'function';
5
- }
6
- /**
7
- * Normalize a source to a live schema — reconstructing a card, passing a class through.
8
- *
9
- * This is what an adapter reaching for the schema MORE THAN ONCE should call, once, at its
10
- * boundary: `reconstruct` runs per call (6.5 µs for a 17-field entity), so a component that
11
- * reads fields in two places would otherwise rebuild the schema twice and hold two
12
- * unrelated field objects. Normalize at the edge, then nothing downstream knows the
13
- * difference — which is the point.
14
- */
15
- export function schemaOf(source) {
16
- return isDescriptor(source) ? reconstruct(source) : source;
17
- }
18
- /**
19
- * The fields an adapter projects from, whichever form it was handed — {@link schemaOf}
20
- * for the single-read case.
21
- *
22
- * Cost: nothing for a class. For a card, one `reconstruct` — measured at 6.5 µs for a
23
- * 17-field entity, paid once per entity when the adapter builds, never per request. Read
24
- * twice and you pay twice: hold the result, or normalize with `schemaOf` instead.
25
- */
26
- export function fieldsOf(source) {
27
- return schemaOf(source).getFields();
28
- }
29
- /**
30
- * The composite unique groups, whichever form. A bare wrapper (a view mid-derivation)
31
- * carries no `getUnique` and answers `undefined`; a card's groups are recovered from what
32
- * its members carry, so `reconstruct` has already restored them by the time this reads.
33
- */
34
- export function uniqueOf(source) {
35
- return schemaOf(source).getUnique?.();
36
- }
37
- //# sourceMappingURL=source.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/projections/source.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAgB/C,sEAAsE;AACtE,SAAS,YAAY,CAAC,MAAoB;IACxC,OAAO,OAAQ,MAAqB,CAAC,SAAS,KAAK,UAAU,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAoB;IAC3C,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAoB;IAC3C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAoB;IAC3C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;AACxC,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"standard.d.ts","sourceRoot":"","sources":["../../src/projections/standard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC/D,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CAC7D;AAED,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,UAAU,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,OAAO,KACX,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;KACnD;IAED,KAAK,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC;IAE5D,UAAU,aAAa,CAAC,MAAM;QAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;KAC7B;IAED,UAAU,aAAa;QACrB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;KACvC;IAED,UAAU,KAAK;QACb,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,SAAS,CAAC;KACtE;IAED,UAAU,WAAW;QACnB,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;KAC3B;IAED,UAAU,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QAC7C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB;IAED,KAAK,UAAU,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CAC5D,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,OAAO,CAAC,CAAC;IAEX,KAAK,WAAW,CAAC,MAAM,SAAS,gBAAgB,IAAI,WAAW,CAC7D,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,QAAQ,CAAC,CAAC;CACb"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Standard Schema v1 — types inlined from @standard-schema/spec.
3
- *
4
- * We inline instead of depending on the package to keep @fougere/schema zero-dep.
5
- * The spec is stable (v1) and unlikely to change.
6
- *
7
- * @see https://standardschema.dev/
8
- */
9
- export {};
10
- //# sourceMappingURL=standard.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"standard.js","sourceRoot":"","sources":["../../src/projections/standard.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -1,53 +0,0 @@
1
- import type { SchemaDescriptor } from './card.js';
2
- export interface TypeSourceOptions {
3
- /** Name of the emitted interface. Defaults to the card's `title`, capitalized. */
4
- name?: string;
5
- /** Emit `export` before the declaration. Default: true. */
6
- exported?: boolean;
7
- }
8
- /**
9
- * The anonymous object type one card describes — the members, nothing around them.
10
- *
11
- * Every property is present: `required` on a Fougère card answers "what must a CALLER
12
- * supply at creation", not "what is always there when read" — an `id` the system
13
- * generates is absent from `required` and always present on a row. Typing the read
14
- * shape from the create rule would make `post.id` possibly-undefined for everyone.
15
- */
16
- export declare function shapeTypeOf(descriptor: SchemaDescriptor, indent?: string): string;
17
- /**
18
- * Emit the entity a card describes — ONE class, judge and shape together.
19
- *
20
- * An entity is a class here (`class Post extends entity({…}) {}`), and a class is the
21
- * language's own answer to "a name that is both a value and a type". Emitting an
22
- * interface next to a const said the same thing twice and relied on declaration
23
- * merging to look like a class; this IS one.
24
- *
25
- * The card travels inline, so the rebuilt judge is exact — the shape written above it
26
- * is read off that same card, never a second source to keep in step.
27
- *
28
- * Requires `reconstruct` in scope: the caller writes the import, since only it knows
29
- * whether the consumer says `@fougere/schema` or a path.
30
- */
31
- export declare function entitySourceOf(descriptor: SchemaDescriptor, options?: TypeSourceOptions): string;
32
- /** One operation, as much of it as a card can say. */
33
- export interface OpDescriptor {
34
- name: string;
35
- description?: string;
36
- output?: SchemaDescriptor;
37
- /** How much `output` describes. Absent means the card did not say. */
38
- cardinality?: 'one' | 'maybe' | 'many' | 'page' | 'none';
39
- }
40
- /**
41
- * Emit the type of a façade — every operation an entity serves, as a caller meets it.
42
- *
43
- * This is what `Facade<T>` needs and what no consumer in another repository could have:
44
- * writing `Facade<ArticleHandler>` used to require importing the handler's class, which
45
- * `sync` does not carry and should not. The card carries the operations; this reads them.
46
- *
47
- * Each op takes an optional invocation and returns a promise — the door's signature, not
48
- * the handler's. A handler's method takes positional arguments; its door takes the call.
49
- */
50
- export declare function facadeTypeSourceOf(ops: readonly OpDescriptor[], options?: TypeSourceOptions & {
51
- rowType?: string;
52
- }): string;
53
- //# sourceMappingURL=typescript.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"typescript.d.ts","sourceRoot":"","sources":["../../src/projections/typescript.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,WAAW,CAAC;AA0FnE,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAK,GAAG,MAAM,CAS7E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CASpG;AAmBD,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,sEAAsE;IACtE,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAC1D;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,SAAS,YAAY,EAAE,EAC5B,OAAO,GAAE,iBAAiB,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,MAAM,CAYR"}
@@ -1,184 +0,0 @@
1
- /**
2
- * card → TypeScript source — the projection that was missing.
3
- *
4
- * `describe` turns a schema into a card and `reconstruct` turns it back into a
5
- * living judge, so a consumer in another repository validates by the host's rules
6
- * without holding its code. What it did NOT get is a type: left to infer, a rebuilt
7
- * schema has an index signature for an instance type, so `post.title` was `any` and
8
- * `post.titel` compiled. The declaration travelled and the compiler learned nothing.
9
- *
10
- * So the card gets a third reader, and it writes the shape where `reconstruct` now
11
- * accepts it — as the type argument of the class's own base expression, one
12
- * declaration for the judge and the rows it judges. Same input as the other two
13
- * readers, same rule: the shape IS JSON Schema, and JSON Schema has a type form.
14
- *
15
- * Deliberately NOT a JSON Schema→TS library: the input is not arbitrary JSON Schema,
16
- * it is a Fougère card, whose vocabulary is closed (`describe` writes it). A general
17
- * library would carry `$ref`, `allOf`, tuple `items`, `additionalProperties` and the
18
- * rest of a spec we never emit, and would still need this file to know that
19
- * `format: date-time` means `Date` here — a fact about our boundary, not about JSON.
20
- */
21
- /** What a field's value looks like once `reconstruct` has decoded it. */
22
- function typeOf(field) {
23
- const types = Array.isArray(field.type) ? field.type : field.type ? [field.type] : [];
24
- const nullable = types.includes('null');
25
- const base = types.find((t) => t !== 'null');
26
- const inner = baseTypeOf(base, field);
27
- return nullable ? `${inner} | null` : inner;
28
- }
29
- function baseTypeOf(base, field) {
30
- // A bounded value set IS a type — the enum travels, so the union does too.
31
- if (field.enum?.length) {
32
- return field.enum.map((v) => (v === null ? 'null' : JSON.stringify(v))).join(' | ');
33
- }
34
- switch (base) {
35
- case 'string':
36
- // `date-time` is the wire form of a value the boundary decodes to a Date, and
37
- // the façade now hands the decoded value on. The type says what you receive.
38
- return field.format === 'date-time' ? 'Date' : 'string';
39
- case 'number':
40
- case 'integer':
41
- return 'number';
42
- case 'boolean':
43
- return 'boolean';
44
- case 'array':
45
- // Two distinct things share `array`: a value list carries `items`, a bare `many`
46
- // relation carries none — the ids of the other side, which the card names as a
47
- // relation rather than a shape.
48
- return field.items ? `${typeOf(field.items)}[]` : 'string[]';
49
- case 'object':
50
- return field.properties ? objectTypeOf(field.properties, field.required ?? []) : 'Record<string, unknown>';
51
- default:
52
- return 'unknown';
53
- }
54
- }
55
- function objectTypeOf(properties, required) {
56
- const members = Object.entries(properties).map(([name, field]) => {
57
- const optional = required.includes(name) ? '' : '?';
58
- return `${propertyKey(name)}${optional}: ${typeOf(field)}`;
59
- });
60
- return `{ ${members.join('; ')} }`;
61
- }
62
- /** Quote a key only when it is not a plain identifier — generated source stays readable. */
63
- function propertyKey(name) {
64
- return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);
65
- }
66
- /**
67
- * A description lands INSIDE a comment, and a card can come from a stranger.
68
- *
69
- * `identifierOf` already refuses a name for this reason — a name stops being data when it
70
- * lands in a declaration. So does a description: `*\/` ends the comment, and everything
71
- * after it is source. A card carrying `*\/ } console.log(…); interface X {` produced a file
72
- * that compiled with zero diagnostics and emitted a top-level statement, which `fougere
73
- * sync` then wrote into the consumer's repository for its next import to run.
74
- *
75
- * Escaped rather than refused, unlike a name: a description is prose, and prose contains
76
- * `*\/` legitimately (a sentence about a comment, a regex). `*\/` renders the same to a
77
- * reader and terminates nothing, so the text survives and the exit does not.
78
- */
79
- function docCommentOf(text, indent) {
80
- if (!text)
81
- return '';
82
- return `${indent}/** ${text.replace(/\*\//g, '*\\/')} */\n`;
83
- }
84
- /**
85
- * The anonymous object type one card describes — the members, nothing around them.
86
- *
87
- * Every property is present: `required` on a Fougère card answers "what must a CALLER
88
- * supply at creation", not "what is always there when read" — an `id` the system
89
- * generates is absent from `required` and always present on a row. Typing the read
90
- * shape from the create rule would make `post.id` possibly-undefined for everyone.
91
- */
92
- export function shapeTypeOf(descriptor, indent = '') {
93
- const entries = Object.entries(descriptor.properties ?? {});
94
- if (entries.length === 0)
95
- return '{}';
96
- const lines = entries.map(([key, field]) => {
97
- const doc = docCommentOf(field.description, `${indent} `);
98
- return `${doc}${indent} ${propertyKey(key)}: ${typeOf(field)};`;
99
- });
100
- return `{\n${lines.join('\n')}\n${indent}}`;
101
- }
102
- /**
103
- * Emit the entity a card describes — ONE class, judge and shape together.
104
- *
105
- * An entity is a class here (`class Post extends entity({…}) {}`), and a class is the
106
- * language's own answer to "a name that is both a value and a type". Emitting an
107
- * interface next to a const said the same thing twice and relied on declaration
108
- * merging to look like a class; this IS one.
109
- *
110
- * The card travels inline, so the rebuilt judge is exact — the shape written above it
111
- * is read off that same card, never a second source to keep in step.
112
- *
113
- * Requires `reconstruct` in scope: the caller writes the import, since only it knows
114
- * whether the consumer says `@fougere/schema` or a path.
115
- */
116
- export function entitySourceOf(descriptor, options = {}) {
117
- const name = identifierOf(options.name ?? capitalize(descriptor.title ?? 'Schema'));
118
- const exported = options.exported === false ? '' : 'export ';
119
- const card = JSON.stringify(descriptor, null, 2)
120
- .split('\n')
121
- .map((line, i) => (i === 0 ? line : ` ${line}`))
122
- .join('\n');
123
- return `${exported}class ${name} extends reconstruct<${shapeTypeOf(descriptor)}>(${card}) {}`;
124
- }
125
- /**
126
- * A card names itself, and a card can come from a stranger. Everything else here emits
127
- * data — a string lands inside `JSON.stringify` — but a name lands in a DECLARATION,
128
- * so it is the one value that could stop being data. Refuse it here as well as at the
129
- * caller: the projection should not depend on who calls it to be safe.
130
- */
131
- function identifierOf(name) {
132
- if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) {
133
- throw new Error(`'${name}' is not a TypeScript identifier — it cannot name a generated declaration`);
134
- }
135
- return name;
136
- }
137
- function capitalize(s) {
138
- return s ? s[0].toUpperCase() + s.slice(1) : s;
139
- }
140
- /**
141
- * What one operation hands back, in TypeScript.
142
- *
143
- * `output` is the shape of a ROW; `cardinality` is how many rows. Separating them is
144
- * what makes this honest — `list` returns a page, not an array, and a generator that
145
- * assumed otherwise would have written a signature that compiles and lies.
146
- *
147
- * A page is spelled as what it IS: `ListResult<T> extends Array<T>`, an array carrying
148
- * its own totals. So the type is the array intersected with them, not a wrapper.
149
- */
150
- function returnTypeOf(op, rowType) {
151
- switch (op.cardinality) {
152
- case 'many': return `${rowType}[]`;
153
- case 'page': return `${rowType}[] & { total?: number; endCursor?: string; hasMore?: boolean }`;
154
- case 'maybe': return `${rowType} | undefined`;
155
- case 'one': return rowType;
156
- // `none` says there is no shaped output — a boolean, a void. Saying `unknown` is
157
- // the truth; guessing `void` would forbid reading a value that does come back.
158
- case 'none': return 'unknown';
159
- default: return 'unknown';
160
- }
161
- }
162
- /**
163
- * Emit the type of a façade — every operation an entity serves, as a caller meets it.
164
- *
165
- * This is what `Facade<T>` needs and what no consumer in another repository could have:
166
- * writing `Facade<ArticleHandler>` used to require importing the handler's class, which
167
- * `sync` does not carry and should not. The card carries the operations; this reads them.
168
- *
169
- * Each op takes an optional invocation and returns a promise — the door's signature, not
170
- * the handler's. A handler's method takes positional arguments; its door takes the call.
171
- */
172
- export function facadeTypeSourceOf(ops, options = {}) {
173
- const name = options.name ?? 'Facade';
174
- const exported = options.exported === false ? '' : 'export ';
175
- const rowType = options.rowType ?? 'unknown';
176
- const members = ops.map((op) => {
177
- const doc = docCommentOf(op.description, ' ');
178
- return `${doc} ${propertyKey(op.name)}(invocation?: Invocation): Promise<${returnTypeOf(op, rowType)}>;`;
179
- });
180
- if (members.length === 0)
181
- return `${exported}interface ${name} {}`;
182
- return `${exported}interface ${name} {\n${members.join('\n')}\n}`;
183
- }
184
- //# sourceMappingURL=typescript.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"typescript.js","sourceRoot":"","sources":["../../src/projections/typescript.ts"],"names":[],"mappings":"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"}
@@ -1,57 +0,0 @@
1
- import type { AnyField, Fields } from '../field/index.js';
2
- /**
3
- * Validation — the Field metadata IS the source of truth.
4
- *
5
- * Validation is a projection of one axis: `shape` (the value), a PURE predicate —
6
- * it answers "is this value valid?" and never mutates the value. Null included:
7
- * the shape's `[T,'null']` union is judged by the engine, there is no hand-rolled
8
- * null branch. It never looks at `role` (persistence/domain) — a foreign key is
9
- * just a string here. Converting a valid value (e.g. an ISO string → a `Date`)
10
- * is a separate step, the `boundary` axis, applied after the predicate passes.
11
- * Absence is judged by `lifecycle.create` — any create rule makes it legal and
12
- * the field is OMITTED from the result, never filled: realising the rule
13
- * (stamp 'now', apply { value }, generate) belongs to the storage adapter at
14
- * the point of persistence, whose insert returns the complete row.
15
- */
16
- export interface ValidationError {
17
- path: string;
18
- message: string;
19
- }
20
- export type ValidationResult<T> = {
21
- success: true;
22
- data: T;
23
- } | {
24
- success: false;
25
- errors: ValidationError[];
26
- };
27
- export type Checked = {
28
- value: unknown;
29
- } | {
30
- error: string;
31
- };
32
- /**
33
- * Validate a present value (null included) against its field — pure, never mutates.
34
- *
35
- * Reads `shape` and nothing else, so it answers "is this a legal value?" without ever
36
- * asking who is speaking. That is what makes it usable on the way OUT of the domain,
37
- * where the client-only axes (`boundary`, `lifecycle`) do not apply.
38
- */
39
- export declare function checkValue(field: AnyField, value: unknown): Checked;
40
- export interface ValidateOptions {
41
- /**
42
- * Patch mode (update). An absent field is OMITTED from the result — not filled,
43
- * not required — so `validate({ name })` touches only `name`. Set by `partial()`.
44
- * Distinguishes "absent → don't touch" (patch) from "absent → null" (create).
45
- */
46
- patch?: boolean;
47
- }
48
- /**
49
- * A path is a field NAME here, never a dotted trail: `json(Entity)` is judged as one
50
- * opaque shape by the engine, so a nested failure answers `{ path: 'addr' }` with the
51
- * inner field in the prose. This used to take a `pathPrefix` that every call site passed
52
- * as `''` — a parameter for a recursion nobody wrote, which made the code read as if
53
- * nesting were handled. Writing that recursion changes what `FougereError.details`
54
- * carries across processes and languages, so it is a contract decision, not a patch.
55
- */
56
- export declare function validateFields(fields: Fields, input: unknown, opts?: ValidateOptions): ValidationResult<Record<string, unknown>>;
57
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/projections/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAS,MAAM,mBAAmB,CAAC;AAIjE;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAC1B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAmB7D;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAgCnE;AAED,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,eAAoB,GACzB,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA8E3C"}