@metaobjectsdev/codegen-ts 1.0.2 → 1.0.4-rc.1

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 (94) hide show
  1. package/dist/catalog-gates.d.ts +52 -0
  2. package/dist/catalog-gates.d.ts.map +1 -0
  3. package/dist/catalog-gates.js +183 -0
  4. package/dist/catalog-gates.js.map +1 -0
  5. package/dist/constants.d.ts +24 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +26 -0
  8. package/dist/constants.js.map +1 -1
  9. package/dist/enum-shared.d.ts +9 -2
  10. package/dist/enum-shared.d.ts.map +1 -1
  11. package/dist/enum-shared.js +12 -3
  12. package/dist/enum-shared.js.map +1 -1
  13. package/dist/generator-registry.d.ts +73 -0
  14. package/dist/generator-registry.d.ts.map +1 -1
  15. package/dist/generator-registry.js +182 -38
  16. package/dist/generator-registry.js.map +1 -1
  17. package/dist/generator.d.ts +48 -1
  18. package/dist/generator.d.ts.map +1 -1
  19. package/dist/generator.js.map +1 -1
  20. package/dist/generators/entity-file.d.ts.map +1 -1
  21. package/dist/generators/entity-file.js +4 -1
  22. package/dist/generators/entity-file.js.map +1 -1
  23. package/dist/generators/index.d.ts +1 -0
  24. package/dist/generators/index.d.ts.map +1 -1
  25. package/dist/generators/index.js +5 -0
  26. package/dist/generators/index.js.map +1 -1
  27. package/dist/generators/shared-model-file.d.ts +23 -0
  28. package/dist/generators/shared-model-file.d.ts.map +1 -0
  29. package/dist/generators/shared-model-file.js +235 -0
  30. package/dist/generators/shared-model-file.js.map +1 -0
  31. package/dist/generators/trace-helper-file.d.ts.map +1 -1
  32. package/dist/generators/trace-helper-file.js +54 -11
  33. package/dist/generators/trace-helper-file.js.map +1 -1
  34. package/dist/index.d.ts +5 -4
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +6 -3
  37. package/dist/index.js.map +1 -1
  38. package/dist/metaobjects-config.d.ts +0 -15
  39. package/dist/metaobjects-config.d.ts.map +1 -1
  40. package/dist/metaobjects-config.js.map +1 -1
  41. package/dist/projection/extract-view-spec.d.ts.map +1 -1
  42. package/dist/projection/extract-view-spec.js +111 -4
  43. package/dist/projection/extract-view-spec.js.map +1 -1
  44. package/dist/relation-resolver.d.ts.map +1 -1
  45. package/dist/relation-resolver.js +11 -9
  46. package/dist/relation-resolver.js.map +1 -1
  47. package/dist/routes-expose.d.ts +30 -0
  48. package/dist/routes-expose.d.ts.map +1 -1
  49. package/dist/routes-expose.js +46 -0
  50. package/dist/routes-expose.js.map +1 -1
  51. package/dist/runner.d.ts +29 -0
  52. package/dist/runner.d.ts.map +1 -1
  53. package/dist/runner.js +38 -1
  54. package/dist/runner.js.map +1 -1
  55. package/dist/templates/entity-file.js +2 -2
  56. package/dist/templates/entity-file.js.map +1 -1
  57. package/dist/templates/enums-file.d.ts +11 -1
  58. package/dist/templates/enums-file.d.ts.map +1 -1
  59. package/dist/templates/enums-file.js +10 -2
  60. package/dist/templates/enums-file.js.map +1 -1
  61. package/dist/templates/queries-file.js +5 -5
  62. package/dist/templates/queries-file.js.map +1 -1
  63. package/dist/templates/routes-file-hono.d.ts.map +1 -1
  64. package/dist/templates/routes-file-hono.js +10 -3
  65. package/dist/templates/routes-file-hono.js.map +1 -1
  66. package/dist/templates/routes-file.d.ts.map +1 -1
  67. package/dist/templates/routes-file.js +21 -4
  68. package/dist/templates/routes-file.js.map +1 -1
  69. package/dist/templates/value-object-file.js +2 -2
  70. package/dist/templates/value-object-file.js.map +1 -1
  71. package/package.json +6 -6
  72. package/src/catalog-gates.ts +222 -0
  73. package/src/constants.ts +27 -0
  74. package/src/enum-shared.ts +17 -3
  75. package/src/generator-registry.ts +253 -41
  76. package/src/generator.ts +48 -1
  77. package/src/generators/entity-file.ts +7 -1
  78. package/src/generators/index.ts +11 -0
  79. package/src/generators/shared-model-file.ts +292 -0
  80. package/src/generators/trace-helper-file.ts +55 -12
  81. package/src/index.ts +17 -3
  82. package/src/metaobjects-config.ts +0 -15
  83. package/src/projection/extract-view-spec.ts +126 -5
  84. package/src/reference/entity.ts +12 -3
  85. package/src/reference/queries.ts +2 -2
  86. package/src/relation-resolver.ts +14 -8
  87. package/src/routes-expose.ts +57 -0
  88. package/src/runner.ts +77 -1
  89. package/src/templates/entity-file.ts +2 -2
  90. package/src/templates/enums-file.ts +13 -2
  91. package/src/templates/queries-file.ts +5 -5
  92. package/src/templates/routes-file-hono.ts +10 -3
  93. package/src/templates/routes-file.ts +21 -4
  94. package/src/templates/value-object-file.ts +2 -2
@@ -0,0 +1,52 @@
1
+ import type { Generator } from "./generator.js";
2
+ import type { GeneratorRegistryEntry } from "./generator-registry.js";
3
+ export declare function stableNameIndex(catalog: Record<string, GeneratorRegistryEntry>): ReadonlyMap<string, string>;
4
+ /**
5
+ * Warn for each wired generator whose `requires` are not also wired.
6
+ *
7
+ * A generator whose name resolves to no catalog entry is an owned or third-party one
8
+ * with nothing declared, and is skipped in silence — there is no declaration to check
9
+ * it against.
10
+ */
11
+ export declare function warnUnsatisfiedRequires(generators: readonly Generator[], catalog: Record<string, GeneratorRegistryEntry>, warn: (message: string) => void): void;
12
+ /**
13
+ * Warn when two wired `api`-layer generators declare DIFFERENT frameworks.
14
+ *
15
+ * Verified before it was written: `routes` emits `<Entity>.routes.ts` and `routes-hono`
16
+ * emits `<Entity>.routes.hono.ts`. Different paths — so wiring both does not trip the
17
+ * runner's conflicting-output-path error, does not fail `tsc`, and silently produces two
18
+ * complete HTTP surfaces over the same entities. Worth saying; not worth refusing.
19
+ *
20
+ * **`api` only, and there is deliberately no general per-layer rule.** The `client`
21
+ * layer disproves one: `@metaobjectsdev/tanstack` declares `react` as a peer, so
22
+ * `form` (react) + `hooks`/`grid` (tanstack) is the documented, normal composition. An
23
+ * earlier draft of the design carried "at most one framework per api and per client
24
+ * layer"; that rule would have forbidden the single most common client selection.
25
+ */
26
+ export declare function warnMixedApiFrameworks(generators: readonly Generator[], catalog: Record<string, GeneratorRegistryEntry>, warn: (message: string) => void): void;
27
+ /**
28
+ * Warn on the two halves of a library/generator selection that do not agree.
29
+ *
30
+ * A library ships metadata; a generator that keys on that metadata is a separate
31
+ * choice, and FR-043 §6 deliberately wires neither for you. What it does instead is
32
+ * refuse to let either half be silently half-done:
33
+ *
34
+ * - **opted in, not wired** — the design is in your model and the code it implies is
35
+ * not being generated.
36
+ * - **wired, not opted in** — the generator's anchor is a node only that library
37
+ * declares, so it will match nothing and emit zero files. Without this line that is
38
+ * indistinguishable from "my model has no trace entities yet".
39
+ *
40
+ * Both self-extinguish: wire it, or opt in, or remove one. Neither ever fails a build —
41
+ * an adopter who ejected the library and owns the metadata is in a legitimate state
42
+ * this cannot see, and a gate that cries wolf gets switched off.
43
+ *
44
+ * `optedIn` is the project's selection TOKENS (`["ai", "ai/db"]`); a layer token names
45
+ * the same library as its bare form.
46
+ */
47
+ export declare function warnLibrarySelectionMismatch(generators: readonly Generator[], catalog: Record<string, GeneratorRegistryEntry>, manifests: Readonly<Record<string, {
48
+ generators?: ReadonlyArray<{
49
+ name: string;
50
+ }>;
51
+ }>>, optedIn: readonly string[], warn: (message: string) => void): void;
52
+ //# sourceMappingURL=catalog-gates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-gates.d.ts","sourceRoot":"","sources":["../src/catalog-gates.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAqBtE,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GAC9C,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAuB7B;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC/C,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAC9B,IAAI,CAsBN;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC/C,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAC9B,IAAI,CAyBN;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC/C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;IAAE,UAAU,CAAC,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAAC,EACrF,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAC9B,IAAI,CAwCN"}
@@ -0,0 +1,183 @@
1
+ // The post-selection audits `meta gen` runs over the wired suite.
2
+ //
3
+ // Codegen is opt-in, so the selection is the adopter's (increasingly their agent's).
4
+ // That makes `meta gen` the place the selection is CHECKED — not by refusing it, but by
5
+ // naming the ways a legal selection still surprises you:
6
+ //
7
+ // 1. a generator whose output imports a module nothing in the run emits;
8
+ // 2. two `api`-layer generators bringing two different HTTP frameworks;
9
+ // 3. (FR-043) a library opted into whose implied generator is not wired, or a
10
+ // generator wired whose library is not opted into — the two halves of one choice.
11
+ //
12
+ // Both are WARNINGS, self-extinguishing, never a build failure. An adopter may
13
+ // legitimately have hand-written the other half, and serving Node and edge from one
14
+ // model is a real thing people do. Following the house rule: a gate that cries wolf
15
+ // gets deleted, and a gate nobody can satisfy is worse than no gate.
16
+ /**
17
+ * Map a CONSTRUCTED generator back to its catalog stable name.
18
+ *
19
+ * These are two different names and conflating them is the trap here: the catalog key
20
+ * is `routes` / `grid-hook`, while the object a factory returns calls itself
21
+ * `routes-file` / `tanstack-grid-hook`. A gate keyed on `g.name` therefore matches
22
+ * nothing at all — silently, since a name the catalog does not know is legitimately
23
+ * skipped as somebody's own generator.
24
+ *
25
+ * DERIVED by constructing every catalog factory and reading the name back, not kept as
26
+ * a table: a table would be a third spelling to maintain, and the failure mode of it
27
+ * going stale is exactly the silent no-op above. The factories are trivial (that is a
28
+ * registry invariant `--list` already depends on), and the result is memoized per
29
+ * catalog object.
30
+ *
31
+ * An implementation name produced by two entries is dropped rather than guessed at.
32
+ */
33
+ const STABLE_NAME_CACHE = new WeakMap();
34
+ export function stableNameIndex(catalog) {
35
+ const cached = STABLE_NAME_CACHE.get(catalog);
36
+ if (cached !== undefined)
37
+ return cached;
38
+ const index = new Map();
39
+ const ambiguous = new Set();
40
+ for (const [stable, entry] of Object.entries(catalog)) {
41
+ let implName;
42
+ try {
43
+ implName = entry.factory().name;
44
+ }
45
+ catch {
46
+ continue; // a factory that cannot construct contributes nothing
47
+ }
48
+ if (index.has(implName) && index.get(implName) !== stable)
49
+ ambiguous.add(implName);
50
+ index.set(implName, stable);
51
+ // The stable name maps to itself too, so a generator that already calls itself by
52
+ // its stable name (and an ejected copy that renamed itself to one) still resolves.
53
+ if (!index.has(stable))
54
+ index.set(stable, stable);
55
+ }
56
+ for (const name of ambiguous)
57
+ index.delete(name);
58
+ STABLE_NAME_CACHE.set(catalog, index);
59
+ return index;
60
+ }
61
+ /**
62
+ * Warn for each wired generator whose `requires` are not also wired.
63
+ *
64
+ * A generator whose name resolves to no catalog entry is an owned or third-party one
65
+ * with nothing declared, and is skipped in silence — there is no declaration to check
66
+ * it against.
67
+ */
68
+ export function warnUnsatisfiedRequires(generators, catalog, warn) {
69
+ const index = stableNameIndex(catalog);
70
+ const stableOf = (g) => index.get(g.name);
71
+ const wired = new Set(generators.map(stableOf).filter((n) => n !== undefined));
72
+ for (const g of generators) {
73
+ const stable = stableOf(g);
74
+ if (stable === undefined)
75
+ continue;
76
+ const entry = catalog[stable];
77
+ if (entry?.requires === undefined)
78
+ continue;
79
+ const missing = entry.requires.filter((dep) => !wired.has(dep));
80
+ if (missing.length === 0)
81
+ continue;
82
+ const list = missing.map((m) => `"${m}"`).join(", ");
83
+ warn(`"${stable}" is wired but ${list} ${missing.length === 1 ? "is" : "are"} not. ` +
84
+ `The code "${stable}" emits imports modules ${list} would have emitted, so ` +
85
+ `tsc will report an unresolved import. Wire ${missing.length === 1 ? "it" : "them"} ` +
86
+ `(\`meta eject ${missing.join(" ")}\` copies the reference generator${missing.length === 1 ? "" : "s"}), ` +
87
+ `or keep your own hand-written module${missing.length === 1 ? "" : "s"} at ${missing.length === 1 ? "that path" : "those paths"}.`);
88
+ }
89
+ }
90
+ /**
91
+ * Warn when two wired `api`-layer generators declare DIFFERENT frameworks.
92
+ *
93
+ * Verified before it was written: `routes` emits `<Entity>.routes.ts` and `routes-hono`
94
+ * emits `<Entity>.routes.hono.ts`. Different paths — so wiring both does not trip the
95
+ * runner's conflicting-output-path error, does not fail `tsc`, and silently produces two
96
+ * complete HTTP surfaces over the same entities. Worth saying; not worth refusing.
97
+ *
98
+ * **`api` only, and there is deliberately no general per-layer rule.** The `client`
99
+ * layer disproves one: `@metaobjectsdev/tanstack` declares `react` as a peer, so
100
+ * `form` (react) + `hooks`/`grid` (tanstack) is the documented, normal composition. An
101
+ * earlier draft of the design carried "at most one framework per api and per client
102
+ * layer"; that rule would have forbidden the single most common client selection.
103
+ */
104
+ export function warnMixedApiFrameworks(generators, catalog, warn) {
105
+ const index = stableNameIndex(catalog);
106
+ const byFramework = new Map();
107
+ for (const g of generators) {
108
+ const stable = index.get(g.name);
109
+ if (stable === undefined)
110
+ continue;
111
+ const entry = catalog[stable];
112
+ if (entry?.layer !== "api" || entry.framework === undefined)
113
+ continue;
114
+ const names = byFramework.get(entry.framework) ?? [];
115
+ names.push(stable);
116
+ byFramework.set(entry.framework, names);
117
+ }
118
+ if (byFramework.size < 2)
119
+ return;
120
+ const described = [...byFramework.entries()]
121
+ .sort(([a], [b]) => a.localeCompare(b))
122
+ .map(([fw, names]) => `${names.sort().map((n) => `"${n}"`).join(" + ")} (${fw})`)
123
+ .join(" and ");
124
+ warn(`two api-layer frameworks are wired — ${described}. They emit to DIFFERENT paths, ` +
125
+ "so nothing conflicts and nothing fails; this run produces two complete HTTP " +
126
+ "surfaces over the same entities. That is legitimate when you are migrating " +
127
+ "between them or serving Node and edge from one model — otherwise wire one.");
128
+ }
129
+ /**
130
+ * Warn on the two halves of a library/generator selection that do not agree.
131
+ *
132
+ * A library ships metadata; a generator that keys on that metadata is a separate
133
+ * choice, and FR-043 §6 deliberately wires neither for you. What it does instead is
134
+ * refuse to let either half be silently half-done:
135
+ *
136
+ * - **opted in, not wired** — the design is in your model and the code it implies is
137
+ * not being generated.
138
+ * - **wired, not opted in** — the generator's anchor is a node only that library
139
+ * declares, so it will match nothing and emit zero files. Without this line that is
140
+ * indistinguishable from "my model has no trace entities yet".
141
+ *
142
+ * Both self-extinguish: wire it, or opt in, or remove one. Neither ever fails a build —
143
+ * an adopter who ejected the library and owns the metadata is in a legitimate state
144
+ * this cannot see, and a gate that cries wolf gets switched off.
145
+ *
146
+ * `optedIn` is the project's selection TOKENS (`["ai", "ai/db"]`); a layer token names
147
+ * the same library as its bare form.
148
+ */
149
+ export function warnLibrarySelectionMismatch(generators, catalog, manifests, optedIn, warn) {
150
+ const index = stableNameIndex(catalog);
151
+ const wired = new Set(generators.map((g) => index.get(g.name)).filter((n) => n !== undefined));
152
+ const selected = new Set(optedIn.map((t) => t.split("/")[0]));
153
+ for (const [library, manifest] of Object.entries(manifests)) {
154
+ const implied = (manifest.generators ?? []).map((g) => g.name);
155
+ if (implied.length === 0)
156
+ continue;
157
+ if (selected.has(library)) {
158
+ const notWired = implied.filter((n) => !wired.has(n));
159
+ if (notWired.length > 0) {
160
+ warn(`library "${library}" is opted in and implies ${notWired.map((n) => `"${n}"`).join(", ")}, ` +
161
+ `which ${notWired.length === 1 ? "is" : "are"} not wired. The design is in your model; ` +
162
+ `the code it implies is not being generated. Wire it, or ignore this if you are ` +
163
+ `taking the metadata alone.`);
164
+ }
165
+ continue;
166
+ }
167
+ // Not opted in: name any of its generators that ARE wired. Checked per library
168
+ // rather than per generator so a name two libraries imply is not reported twice
169
+ // when one of them is selected.
170
+ const orphaned = implied.filter((n) => wired.has(n) && !impliedByAnySelected(n, manifests, selected));
171
+ if (orphaned.length > 0) {
172
+ warn(`${orphaned.map((n) => `"${n}"`).join(", ")} ${orphaned.length === 1 ? "is" : "are"} wired, ` +
173
+ `but library "${library}" — which declares the node ${orphaned.length === 1 ? "it keys" : "they key"} ` +
174
+ `on — is not opted in, so ${orphaned.length === 1 ? "it will" : "they will"} match nothing and emit ` +
175
+ `no files. Add "${library}" to \`libraries\` in .metaobjects/config.json, or unwire ` +
176
+ `${orphaned.length === 1 ? "it" : "them"}.`);
177
+ }
178
+ }
179
+ }
180
+ function impliedByAnySelected(generator, manifests, selected) {
181
+ return [...selected].some((lib) => (manifests[lib]?.generators ?? []).some((g) => g.name === generator));
182
+ }
183
+ //# sourceMappingURL=catalog-gates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-gates.js","sourceRoot":"","sources":["../src/catalog-gates.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,qFAAqF;AACrF,wFAAwF;AACxF,yDAAyD;AACzD,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,gFAAgF;AAChF,uFAAuF;AACvF,EAAE;AACF,+EAA+E;AAC/E,oFAAoF;AACpF,oFAAoF;AACpF,qEAAqE;AAKrE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAAuC,CAAC;AAE7E,MAAM,UAAU,eAAe,CAC7B,OAA+C;IAE/C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IAExC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,sDAAsD;QAClE,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM;YAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnF,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC5B,kFAAkF;QAClF,mFAAmF;QACnF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,SAAS;QAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEjD,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAgC,EAChC,OAA+C,EAC/C,IAA+B;IAE/B,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,CAAC,CAAY,EAAsB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IAE5F,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,KAAK,EAAE,QAAQ,KAAK,SAAS;YAAE,SAAS;QAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEnC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CACF,IAAI,MAAM,kBAAkB,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;YAC7E,aAAa,MAAM,2BAA2B,IAAI,0BAA0B;YAC5E,8CAA8C,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG;YACrF,iBAAiB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,oCAAoC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK;YAC1G,uCAAuC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,GAAG,CACrI,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAgC,EAChC,OAA+C,EAC/C,IAA+B;IAE/B,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAAE,SAAS;QACtE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC;QAAE,OAAO;IAEjC,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;SACzC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;SAChF,IAAI,CAAC,OAAO,CAAC,CAAC;IAEjB,IAAI,CACF,wCAAwC,SAAS,kCAAkC;QACjF,8EAA8E;QAC9E,6EAA6E;QAC7E,4EAA4E,CAC/E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,4BAA4B,CAC1C,UAAgC,EAChC,OAA+C,EAC/C,SAAqF,EACrF,OAA0B,EAC1B,IAA+B;IAE/B,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CACrF,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;IAE/D,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEnC,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CACF,YAAY,OAAO,6BAA6B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;oBAC1F,SAAS,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,2CAA2C;oBACxF,iFAAiF;oBACjF,4BAA4B,CAC/B,CAAC;YACJ,CAAC;YACD,SAAS;QACX,CAAC;QAED,+EAA+E;QAC/E,gFAAgF;QAChF,gCAAgC;QAChC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAC7B,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CACrE,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CACF,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,UAAU;gBAC3F,gBAAgB,OAAO,+BAA+B,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,GAAG;gBACvG,4BAA4B,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,0BAA0B;gBACrG,kBAAkB,OAAO,4DAA4D;gBACrF,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAC9C,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAAiB,EACjB,SAAqF,EACrF,QAA6B;IAE7B,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAChC,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CACrE,CAAC;AACJ,CAAC"}
@@ -24,6 +24,30 @@ export declare const GENERATED_HEADER = "@generated by @metaobjectsdev/codegen-t
24
24
  * finding the artifact it exists to protect, silently.
25
25
  */
26
26
  export declare const NAMES_FILE_SUFFIX = ".names.ts";
27
+ /**
28
+ * Line 3 of every generated file's header — where an adopter's own code goes.
29
+ *
30
+ * It used to read `Customize via <Name>.extra.ts in this directory`, and on the routes
31
+ * emitters `(e.g., auth, additional handlers)`. Both asserted a plugin point this engine
32
+ * does not have — the same claim `EXTRA_SUFFIX` was deleted above for implying. The
33
+ * convention is real and documented (`docs/features/own-your-codegen.md`): a sibling file
34
+ * is safe because `meta gen` writes only the paths it records, and the barrel is built
35
+ * from the model so it never re-exports one. What is NOT real is anything importing it
36
+ * for you, and "Customize via" is exactly the verb that promises otherwise.
37
+ *
38
+ * #367 is the measured cost: an agent building a real API read `(e.g., auth)` on a routes
39
+ * file, went looking for the seam, found none, and deleted `routesFile()` from its config
40
+ * rather than mount five unauthenticated endpoints over a password-hash table. The auth
41
+ * seam it needed exists — a parent plugin scope's `preHandler` (Fastify) or `app.use`
42
+ * (Hono) — and the routes emitters now say so in the handler's own JSDoc, gated by
43
+ * `runtime-ts/test/route-auth-seam.test.ts`.
44
+ *
45
+ * Spelled once because the literal had been copy-pasted to ten TypeScript emitters plus
46
+ * Python's `generated_header`, which is how one wrong sentence reached every generated
47
+ * file in the estate. `sidecarName` is the emitted module name, extension included
48
+ * (`Order.extra.ts`, `OrderForm.extra.tsx`).
49
+ */
50
+ export declare function sidecarLine(sidecarName: string): string;
27
51
  /** Default outDir used by tests + as a sane default for generate(). */
28
52
  export declare const DEFAULT_OUT_DIR = "./src/db/entities";
29
53
  /** One retired codegen-control attribute, paired with what an adopter does instead. */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,6CAA6C,CAAC;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAU7C,uEAAuE;AACvE,eAAO,MAAM,eAAe,sBAAsB,CAAC;AA8BnD,uFAAuF;AACvF,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,EAAE,SAAS,kBAAkB,EAmCrD,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,6CAA6C,CAAC;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAU7C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,uEAAuE;AACvE,eAAO,MAAM,eAAe,sBAAsB,CAAC;AA8BnD,uFAAuF;AACvF,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,EAAE,SAAS,kBAAkB,EAmCrD,CAAC"}
package/dist/constants.js CHANGED
@@ -32,6 +32,32 @@ export const NAMES_FILE_SUFFIX = ".names.ts";
32
32
  // records in `.gen-state/.hashes.json` — not because of its name — and the generated
33
33
  // barrel is built from the model, so it does not re-export it. Say that in prose;
34
34
  // do not re-add a constant that suggests the engine knows the name.
35
+ /**
36
+ * Line 3 of every generated file's header — where an adopter's own code goes.
37
+ *
38
+ * It used to read `Customize via <Name>.extra.ts in this directory`, and on the routes
39
+ * emitters `(e.g., auth, additional handlers)`. Both asserted a plugin point this engine
40
+ * does not have — the same claim `EXTRA_SUFFIX` was deleted above for implying. The
41
+ * convention is real and documented (`docs/features/own-your-codegen.md`): a sibling file
42
+ * is safe because `meta gen` writes only the paths it records, and the barrel is built
43
+ * from the model so it never re-exports one. What is NOT real is anything importing it
44
+ * for you, and "Customize via" is exactly the verb that promises otherwise.
45
+ *
46
+ * #367 is the measured cost: an agent building a real API read `(e.g., auth)` on a routes
47
+ * file, went looking for the seam, found none, and deleted `routesFile()` from its config
48
+ * rather than mount five unauthenticated endpoints over a password-hash table. The auth
49
+ * seam it needed exists — a parent plugin scope's `preHandler` (Fastify) or `app.use`
50
+ * (Hono) — and the routes emitters now say so in the handler's own JSDoc, gated by
51
+ * `runtime-ts/test/route-auth-seam.test.ts`.
52
+ *
53
+ * Spelled once because the literal had been copy-pasted to ten TypeScript emitters plus
54
+ * Python's `generated_header`, which is how one wrong sentence reached every generated
55
+ * file in the estate. `sidecarName` is the emitted module name, extension included
56
+ * (`Order.extra.ts`, `OrderForm.extra.tsx`).
57
+ */
58
+ export function sidecarLine(sidecarName) {
59
+ return `// Extend in your own module (e.g. ${sidecarName}) — nothing imports it for you.\n`;
60
+ }
35
61
  /** Default outDir used by tests + as a sane default for generate(). */
36
62
  export const DEFAULT_OUT_DIR = "./src/db/entities";
37
63
  /** Every retired codegen-control attribute. Read ONLY by the `meta gen` warning. */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,0CAA0C,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAC;AAE7C,qFAAqF;AACrF,kFAAkF;AAClF,uFAAuF;AACvF,iFAAiF;AACjF,qFAAqF;AACrF,kFAAkF;AAClF,oEAAoE;AAEpE,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAsCnD,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAkC;IAClE;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,qFAAqF;YACrF,mGAAmG;KACtG;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,kFAAkF;YAClF,4EAA4E;YAC5E,8DAA8D;KACjE;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,mFAAmF;YACnF,yFAAyF;KAC5F;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,wFAAwF;YACxF,qFAAqF;YACrF,yFAAyF;YACzF,kFAAkF;KACrF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,yFAAyF;YACzF,8EAA8E;YAC9E,mEAAmE;KACtE;CACO,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,0CAA0C,CAAC;AAE3E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,WAAW,CAAC;AAE7C,qFAAqF;AACrF,kFAAkF;AAClF,uFAAuF;AACvF,iFAAiF;AACjF,qFAAqF;AACrF,kFAAkF;AAClF,oEAAoE;AAEpE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,sCAAsC,WAAW,mCAAmC,CAAC;AAC9F,CAAC;AAED,uEAAuE;AACvE,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAsCnD,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAkC;IAClE;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,qFAAqF;YACrF,mGAAmG;KACtG;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,kFAAkF;YAClF,4EAA4E;YAC5E,8DAA8D;KACjE;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,mFAAmF;YACnF,yFAAyF;KAC5F;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EACT,wFAAwF;YACxF,qFAAqF;YACrF,yFAAyF;YACzF,kFAAkF;KACrF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EACT,yFAAyF;YACzF,8EAA8E;YAC9E,mEAAmE;KACtE;CACO,CAAC"}
@@ -23,10 +23,17 @@ export declare function sharedEnumForField(field: MetaField): SharedEnum | undef
23
23
  * actually CONSUMED by at least one concrete entity field — keyed by the
24
24
  * materialized type name. A declaration nobody extends is not materialized (no
25
25
  * dangling type). Deterministic order: first-consumption order across entities.
26
+ *
27
+ * `select` (FR-023 §11.1 item 2), when given, narrows which CONSUMING entities
28
+ * count toward "is this enum used" — an entity for which `select(entity.
29
+ * resolutionKey())` is false contributes nothing, even if it extends the shared
30
+ * declaration. It does not touch which declarations EXIST, only which usages are
31
+ * counted. Absent `select` ⇒ every entity counts, byte-identical to before this
32
+ * parameter existed.
26
33
  */
27
- export declare function collectSharedEnums(root: MetaRoot): Map<string, SharedEnum>;
34
+ export declare function collectSharedEnums(root: MetaRoot, select?: (fqn: string) => boolean): Map<string, SharedEnum>;
28
35
  /** The shared enums that metaobjects MATERIALIZES (non-@provided, consumed). */
29
- export declare function materializedSharedEnums(root: MetaRoot): SharedEnum[];
36
+ export declare function materializedSharedEnums(root: MetaRoot, select?: (fqn: string) => boolean): SharedEnum[];
30
37
  /** Whether any shared enum (materialized or provided) is consumed in the model. */
31
38
  export declare function hasSharedEnums(root: MetaRoot): boolean;
32
39
  //# sourceMappingURL=enum-shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"enum-shared.d.ts","sourceRoot":"","sources":["../src/enum-shared.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AASpE,qFAAqF;AACrF,MAAM,WAAW,UAAU;IACzB,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAU7E;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAgB3E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAU1E;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,EAAE,CAEpE;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEtD"}
1
+ {"version":3,"file":"enum-shared.d.ts","sourceRoot":"","sources":["../src/enum-shared.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AASpE,qFAAqF;AACrF,MAAM,WAAW,UAAU;IACzB,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAU7E;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAgB3E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,QAAQ,EACd,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAChC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAWzB;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,QAAQ,EACd,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAChC,UAAU,EAAE,CAEd;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEtD"}
@@ -64,10 +64,19 @@ export function sharedEnumForField(field) {
64
64
  * actually CONSUMED by at least one concrete entity field — keyed by the
65
65
  * materialized type name. A declaration nobody extends is not materialized (no
66
66
  * dangling type). Deterministic order: first-consumption order across entities.
67
+ *
68
+ * `select` (FR-023 §11.1 item 2), when given, narrows which CONSUMING entities
69
+ * count toward "is this enum used" — an entity for which `select(entity.
70
+ * resolutionKey())` is false contributes nothing, even if it extends the shared
71
+ * declaration. It does not touch which declarations EXIST, only which usages are
72
+ * counted. Absent `select` ⇒ every entity counts, byte-identical to before this
73
+ * parameter existed.
67
74
  */
68
- export function collectSharedEnums(root) {
75
+ export function collectSharedEnums(root, select) {
69
76
  const out = new Map();
70
77
  for (const entity of root.objects()) {
78
+ if (select !== undefined && !select(entity.resolutionKey()))
79
+ continue;
71
80
  for (const field of entity.fields()) {
72
81
  const shared = sharedEnumForField(field);
73
82
  if (shared === undefined)
@@ -79,8 +88,8 @@ export function collectSharedEnums(root) {
79
88
  return out;
80
89
  }
81
90
  /** The shared enums that metaobjects MATERIALIZES (non-@provided, consumed). */
82
- export function materializedSharedEnums(root) {
83
- return [...collectSharedEnums(root).values()].filter((e) => !e.provided);
91
+ export function materializedSharedEnums(root, select) {
92
+ return [...collectSharedEnums(root, select).values()].filter((e) => !e.provided);
84
93
  }
85
94
  /** Whether any shared enum (materialized or provided) is consumed in the model. */
86
95
  export function hasSharedEnums(root) {
@@ -1 +1 @@
1
- {"version":3,"file":"enum-shared.js","sourceRoot":"","sources":["../src/enum-shared.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,oDAAoD;AACpD,EAAE;AACF,yCAAyC;AACzC,gFAAgF;AAChF,yCAAyC;AACzC,iFAAiF;AACjF,iFAAiF;AACjF,gFAAgF;AAChF,EAAE;AACF,kFAAkF;AAClF,iFAAiF;AAGjF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAY5C;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAgB;IACpD,IAAI,KAAK,CAAC,OAAO,KAAK,kBAAkB;QAAE,OAAO,SAAS,CAAC;IAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;IACjC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IACtC,iFAAiF;IACjF,6CAA6C;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,SAAS,CAAC;IAC5E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IACjD,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,MAAM;QACN,8EAA8E;QAC9E,gFAAgF;QAChF,iFAAiF;QACjF,kFAAkF;QAClF,iFAAiF;QACjF,+DAA+D;QAC/D,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,IAAI;KAC5D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC/C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC1C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS;YACnC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,uBAAuB,CAAC,IAAc;IACpD,OAAO,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAC3E,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"enum-shared.js","sourceRoot":"","sources":["../src/enum-shared.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,oDAAoD;AACpD,EAAE;AACF,yCAAyC;AACzC,gFAAgF;AAChF,yCAAyC;AACzC,iFAAiF;AACjF,iFAAiF;AACjF,gFAAgF;AAChF,EAAE;AACF,kFAAkF;AAClF,iFAAiF;AAGjF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAY5C;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAgB;IACpD,IAAI,KAAK,CAAC,OAAO,KAAK,kBAAkB;QAAE,OAAO,SAAS,CAAC;IAC3D,MAAM,GAAG,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;IACjC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IACtC,iFAAiF;IACjF,6CAA6C;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IAC1B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,SAAS,CAAC;IAC5E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IACjD,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,MAAM;QACN,8EAA8E;QAC9E,gFAAgF;QAChF,iFAAiF;QACjF,kFAAkF;QAClF,iFAAiF;QACjF,+DAA+D;QAC/D,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,IAAI;KAC5D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAc,EACd,MAAiC;IAEjC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC1C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAAE,SAAS;QACtE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,SAAS;gBAAE,SAAS;YACnC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,uBAAuB,CACrC,IAAc,EACd,MAAiC;IAEjC,OAAO,CAAC,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACnF,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;AAC3C,CAAC"}
@@ -1,8 +1,41 @@
1
1
  import type { Generator } from "./generator.js";
2
+ import type { MetaobjectsGenConfig } from "./metaobjects-config.js";
2
3
  export type GeneratorTier = "native" | "neutral";
4
+ /**
5
+ * The six layers a generator can belong to — the axis an adopter SELECTS BY.
6
+ *
7
+ * Cross-port: `layer` is gated by every port's registry-conformance test against
8
+ * `fixtures/generator-registry-conformance/registry.json`, exactly as `tier` is, so a
9
+ * polyglot agent groups the catalog by the same words everywhere.
10
+ *
11
+ * Six, not ten. The first four are app-shape decisions a builder makes; `docs` is on by
12
+ * default (`meta docs`); `capability` holds the ones the MODEL has already made — nobody
13
+ * picks `prompt-render` by browsing a taxonomy, they pick it because they declared a
14
+ * `template.prompt`, which `meta gen --list --probe` reports with a real file count. A
15
+ * layer with one member does no grouping work, so do not split `capability` to tidy it.
16
+ */
17
+ export declare const GENERATOR_LAYERS: readonly ["model", "persistence", "api", "client", "docs", "capability"];
18
+ export type Layer = (typeof GENERATOR_LAYERS)[number];
19
+ /**
20
+ * The framework a generator's OUTPUT targets. Absent = framework-neutral.
21
+ *
22
+ * Exclusivity is an ADVISORY and only on the `api` layer (spec §8a): `routes` and
23
+ * `routes-hono` emit to different paths, so wiring both is legal and silently produces
24
+ * two HTTP surfaces — worth a warning, never an error, because migrating between them is
25
+ * legitimate. There is NO general per-layer rule: `@metaobjectsdev/tanstack` peers on
26
+ * `react`, so `form` (react) + `hooks`/`grid` (tanstack) is the intended composition.
27
+ */
28
+ export type GeneratorFramework = "fastify" | "hono" | "react" | "tanstack";
3
29
  export interface GeneratorRegistryEntry {
4
30
  /** Stable, cross-port-consistent id. Equals the registry map key. */
5
31
  name: string;
32
+ /**
33
+ * Catalog discriminator. Today every entry is a generator; FR-043 adds
34
+ * `kind: "library"` rows to the same table rather than building a parallel one.
35
+ */
36
+ kind: "generator";
37
+ /** The selection axis — see {@link GENERATOR_LAYERS}. Gated cross-port. */
38
+ layer: Layer;
6
39
  /** One-line (no newline) human description for `--list`. */
7
40
  description: string;
8
41
  /** "native" = recommended `meta gen` suite; "neutral" = `meta docs`-owned. */
@@ -11,6 +44,46 @@ export interface GeneratorRegistryEntry {
11
44
  factory: () => Generator;
12
45
  /** Optional one-line options summary for `--list`. */
13
46
  options?: string;
47
+ /** The framework this generator's OUTPUT targets. Absent = framework-neutral. */
48
+ framework?: GeneratorFramework;
49
+ /**
50
+ * Stable names whose emitted output THIS generator's output imports.
51
+ *
52
+ * Resolved, not trusted: a gate dry-runs every generator, resolves each emitted
53
+ * RELATIVE import back to whichever generator emits that path, and asserts the result
54
+ * is a subset of this list — so a generator that quietly starts depending on `entity`
55
+ * cannot ship claiming it depends on nothing.
56
+ */
57
+ requires?: readonly string[];
58
+ /**
59
+ * The `@metaobjectsdev` runtime packages the EMITTED code imports.
60
+ *
61
+ * PLURAL, against the design's first sketch, because the emitted code is: an
62
+ * `output-parser` module imports `@metaobjectsdev/metadata`, `/render` AND
63
+ * `/runtime-ts`, and a `hooks` module imports `/runtime-web` and `/tanstack`. A
64
+ * singular field would have forced two of the three to go undeclared, which is the
65
+ * exact under-declaration the gate exists to catch. Resolved, not trusted — the
66
+ * emitted files are read back and every `@metaobjectsdev` import must appear here.
67
+ */
68
+ runtimePackages?: readonly string[];
69
+ /**
70
+ * Third-party packages the EMITTED code imports.
71
+ *
72
+ * Per generator rather than derived from {@link runtimePackages}, because
73
+ * `@metaobjectsdev/runtime-ts`'s peers are a union (drizzle-orm, fastify, hono, kysely,
74
+ * zod) — deriving per package would tell someone ejecting `entity` to install both
75
+ * Fastify and Hono. Version RANGES are read from the runtime package's own
76
+ * `peerDependencies`, never written here. Gated the same way `requires` is.
77
+ */
78
+ runtimePeers?: readonly string[];
79
+ /**
80
+ * Config keys this generator reads. Typed against the real config so a renamed key
81
+ * breaks the build instead of going quietly stale — the same "resolved, not trusted"
82
+ * doctrine as `requires`, obtained here for free from the type system.
83
+ */
84
+ configKeys?: readonly (keyof MetaobjectsGenConfig)[];
85
+ /** True iff this package ships a `src/reference/<name>.ts` for `meta eject`. */
86
+ ejectable: boolean;
14
87
  /** Optional note — used to point neutral entries at their canonical door. */
15
88
  note?: string;
16
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator-registry.d.ts","sourceRoot":"","sources":["../src/generator-registry.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwBhD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,IAAI,EAAE,aAAa,CAAC;IACpB,kFAAkF;IAClF,OAAO,EAAE,MAAM,SAAS,CAAC;IACzB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAeD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CA6HpE,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,cAAc,IAAI,sBAAsB,EAAE,CAQzD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAE3E"}
1
+ {"version":3,"file":"generator-registry.d.ts","sourceRoot":"","sources":["../src/generator-registry.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AA2BpE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,0EAOnB,CAAC;AACX,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE3E,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,EAAE,WAAW,CAAC;IAClB,2EAA2E;IAC3E,KAAK,EAAE,KAAK,CAAC;IACb,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,IAAI,EAAE,aAAa,CAAC;IACpB,kFAAkF;IAClF,OAAO,EAAE,MAAM,SAAS,CAAC;IACzB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,oBAAoB,CAAC,EAAE,CAAC;IACrD,gFAAgF;IAChF,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAoBD,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAgPpE,CAAC;AAEF,iFAAiF;AACjF,wBAAgB,cAAc,IAAI,sBAAsB,EAAE,CAQzD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,sBAAsB,GAAG,SAAS,CAE3E"}