@specverse/engines 6.41.1 → 6.53.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.
- package/dist/ai/analyse-runner.d.ts.map +1 -1
- package/dist/ai/analyse-runner.js +53 -1
- package/dist/ai/analyse-runner.js.map +1 -1
- package/dist/ai/prompt-runner.d.ts +39 -1
- package/dist/ai/prompt-runner.d.ts.map +1 -1
- package/dist/ai/prompt-runner.js +44 -3
- package/dist/ai/prompt-runner.js.map +1 -1
- package/dist/ai/providers/claude-cli.d.ts.map +1 -1
- package/dist/ai/providers/claude-cli.js +8 -1
- package/dist/ai/providers/claude-cli.js.map +1 -1
- package/dist/ai/skill-loader.d.ts +50 -0
- package/dist/ai/skill-loader.d.ts.map +1 -0
- package/dist/ai/skill-loader.js +96 -0
- package/dist/ai/skill-loader.js.map +1 -0
- package/dist/analyse-prepass/adapters/index.d.ts +2 -0
- package/dist/analyse-prepass/adapters/index.d.ts.map +1 -1
- package/dist/analyse-prepass/adapters/index.js +2 -0
- package/dist/analyse-prepass/adapters/index.js.map +1 -1
- package/dist/analyse-prepass/adapters/module-functions.d.ts +95 -0
- package/dist/analyse-prepass/adapters/module-functions.d.ts.map +1 -0
- package/dist/analyse-prepass/adapters/module-functions.js +358 -0
- package/dist/analyse-prepass/adapters/module-functions.js.map +1 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts +90 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts.map +1 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.js +181 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.js.map +1 -0
- package/dist/analyse-prepass/index.d.ts +8 -0
- package/dist/analyse-prepass/index.d.ts.map +1 -1
- package/dist/analyse-prepass/index.js +130 -0
- package/dist/analyse-prepass/index.js.map +1 -1
- package/dist/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +11 -12
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +2 -2
- package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +24 -2
- package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +28 -20
- package/dist/normalise/index.d.ts +14 -0
- package/dist/normalise/index.d.ts.map +1 -0
- package/dist/normalise/index.js +14 -0
- package/dist/normalise/index.js.map +1 -0
- package/dist/normalise/load-overrides.d.ts +43 -0
- package/dist/normalise/load-overrides.d.ts.map +1 -0
- package/dist/normalise/load-overrides.js +121 -0
- package/dist/normalise/load-overrides.js.map +1 -0
- package/dist/normalise/normalise-rules.d.ts +181 -0
- package/dist/normalise/normalise-rules.d.ts.map +1 -0
- package/dist/normalise/normalise-rules.js +79 -0
- package/dist/normalise/normalise-rules.js.map +1 -0
- package/dist/normalise/rules/cluster-module-functions.d.ts +31 -0
- package/dist/normalise/rules/cluster-module-functions.d.ts.map +1 -0
- package/dist/normalise/rules/cluster-module-functions.js +238 -0
- package/dist/normalise/rules/cluster-module-functions.js.map +1 -0
- package/dist/normalise/rules/crud-into-curved.d.ts +117 -0
- package/dist/normalise/rules/crud-into-curved.d.ts.map +1 -0
- package/dist/normalise/rules/crud-into-curved.js +303 -0
- package/dist/normalise/rules/crud-into-curved.js.map +1 -0
- package/dist/normalise/rules/drop-trivial-passthrough.d.ts +92 -0
- package/dist/normalise/rules/drop-trivial-passthrough.d.ts.map +1 -0
- package/dist/normalise/rules/drop-trivial-passthrough.js +217 -0
- package/dist/normalise/rules/drop-trivial-passthrough.js.map +1 -0
- package/dist/normalise/runner.d.ts +58 -0
- package/dist/normalise/runner.d.ts.map +1 -0
- package/dist/normalise/runner.js +114 -0
- package/dist/normalise/runner.js.map +1 -0
- package/dist/parser/import-resolver/resolver.js +1 -1
- package/dist/parser/import-resolver/resolver.js.map +1 -1
- package/dist/realize/engines/typescript-engine.js +1 -1
- package/dist/realize/engines/typescript-engine.js.map +1 -1
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +142 -90
- package/dist/realize/index.js.map +1 -1
- package/dist/realize/library/library.js +1 -1
- package/dist/realize/library/library.js.map +1 -1
- package/dist/realize/library/resolver.d.ts.map +1 -1
- package/dist/realize/library/resolver.js +14 -1
- package/dist/realize/library/resolver.js.map +1 -1
- package/dist/realize/owner-emit-shared.d.ts +114 -0
- package/dist/realize/owner-emit-shared.d.ts.map +1 -0
- package/dist/realize/owner-emit-shared.js +227 -0
- package/dist/realize/owner-emit-shared.js.map +1 -0
- package/dist/realize/per-owner-emit.d.ts +13 -1
- package/dist/realize/per-owner-emit.d.ts.map +1 -1
- package/dist/realize/per-owner-emit.js +64 -1
- package/dist/realize/per-owner-emit.js.map +1 -1
- package/dist/realize/per-owner-runner.d.ts +36 -2
- package/dist/realize/per-owner-runner.d.ts.map +1 -1
- package/dist/realize/per-owner-runner.js +137 -3
- package/dist/realize/per-owner-runner.js.map +1 -1
- package/dist/realize/post-emit-verify/feedback-runner.d.ts +84 -0
- package/dist/realize/post-emit-verify/feedback-runner.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/feedback-runner.js +177 -0
- package/dist/realize/post-emit-verify/feedback-runner.js.map +1 -0
- package/dist/realize/post-emit-verify/index.d.ts +17 -0
- package/dist/realize/post-emit-verify/index.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/index.js +16 -0
- package/dist/realize/post-emit-verify/index.js.map +1 -0
- package/dist/realize/post-emit-verify/reemit.d.ts +61 -0
- package/dist/realize/post-emit-verify/reemit.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/reemit.js +122 -0
- package/dist/realize/post-emit-verify/reemit.js.map +1 -0
- package/dist/realize/post-emit-verify/types.d.ts +138 -0
- package/dist/realize/post-emit-verify/types.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/types.js +28 -0
- package/dist/realize/post-emit-verify/types.js.map +1 -0
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts +29 -0
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js +55 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.d.ts +24 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.js +148 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.js.map +1 -0
- package/dist/realize/realize-rules.d.ts +113 -0
- package/dist/realize/realize-rules.d.ts.map +1 -0
- package/dist/realize/realize-rules.js +271 -0
- package/dist/realize/realize-rules.js.map +1 -0
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +11 -12
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +2 -2
- package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +62 -2
- package/libs/instance-factories/services/templates/prisma/controller-generator.ts +42 -20
- package/package.json +9 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsc.js","sourceRoot":"","sources":["../../../../src/realize/post-emit-verify/verifiers/tsc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realize LLM-emit rule manifest.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for every post-emit constraint enforced on
|
|
5
|
+
* per-owner LLM output. Replaces the prior model where each rule was
|
|
6
|
+
* authored in THREE places (a regex+correction in `per-owner-emit.ts`,
|
|
7
|
+
* a prose-statement in `realize-owner.prompt.yaml`, and an ad-hoc unit
|
|
8
|
+
* test fixture). That model produced drift — prompt and validator
|
|
9
|
+
* statements got out of sync, fixture coverage was uneven, and adding
|
|
10
|
+
* a rule meant editing three locations consistently.
|
|
11
|
+
*
|
|
12
|
+
* The manifest below declares each rule once. Three consumers read it:
|
|
13
|
+
*
|
|
14
|
+
* 1. Validator pipeline (per-owner-emit.ts) — calls `detect(...)` to
|
|
15
|
+
* find violations, calls `correction(...)` to build the surgical-
|
|
16
|
+
* retry prefix, sorts rules by `ordering` to control which fires
|
|
17
|
+
* first when multiple violations co-occur.
|
|
18
|
+
*
|
|
19
|
+
* 2. Prompt builder — reads `promptStatement` to render the
|
|
20
|
+
* CONSTRAINTS section of `realize-owner.prompt.yaml` (Phase 2 of
|
|
21
|
+
* the 2026-05-12-VALIDATOR-MANIFEST-AND-TEST-CORPUS proposal).
|
|
22
|
+
*
|
|
23
|
+
* 3. Test corpus (`engines/src/realize/__tests__/llm-output-fixtures/`)
|
|
24
|
+
* — each fixture is annotated with the rule IDs it should trigger;
|
|
25
|
+
* the pipeline harness asserts the manifest's ordering produces
|
|
26
|
+
* exactly those fires.
|
|
27
|
+
*
|
|
28
|
+
* Adding a new rule is one place: append a new entry to RULES.
|
|
29
|
+
*
|
|
30
|
+
* Why in engines/src/realize/ rather than entities/src/core/realize/:
|
|
31
|
+
* For the moment, rules are realize-internal — they're regex scans
|
|
32
|
+
* over LLM-emitted TypeScript, not the kind of bundle-able content
|
|
33
|
+
* that R12 entity modules manage. If realize rules ever need to be
|
|
34
|
+
* extended by user specs (e.g. project-specific forbidden imports),
|
|
35
|
+
* migration to the entity-module pattern would be the next step.
|
|
36
|
+
*/
|
|
37
|
+
/** Context the rule pipeline carries through the per-owner emit. */
|
|
38
|
+
export interface RuleContext {
|
|
39
|
+
/** Owner identifier — e.g. 'AuthController', 'GameStateService'. */
|
|
40
|
+
ownerName: string;
|
|
41
|
+
/** Target runtime declaration — e.g. 'Node.js (backend)'. Some rules
|
|
42
|
+
* apply only on specific runtimes (see `appliesWhen`). */
|
|
43
|
+
targetRuntime?: string;
|
|
44
|
+
}
|
|
45
|
+
/** One violation found by a rule. Free-form string for the symbol /
|
|
46
|
+
* path / shape that triggered the rule (e.g. 'localStorage',
|
|
47
|
+
* '../services/AuthService'). Multiple violations can be returned
|
|
48
|
+
* from one detect() call. */
|
|
49
|
+
export type RuleViolation = string;
|
|
50
|
+
/**
|
|
51
|
+
* A single realize-emit rule. Each field has one purpose:
|
|
52
|
+
*
|
|
53
|
+
* - `id`: stable identifier for tests and logs. Kebab-case.
|
|
54
|
+
* - `summary`: one-line human description shown in stderr when
|
|
55
|
+
* `SPECVERSE_VERBOSE=1`.
|
|
56
|
+
* - `promptStatement`: human-language form of the rule for the
|
|
57
|
+
* prompt's CONSTRAINTS section. Phrased as an instruction to the
|
|
58
|
+
* LLM, NOT as a developer-facing comment.
|
|
59
|
+
* - `detect`: scan the LLM-emitted file for violations. Returns the
|
|
60
|
+
* list of distinct violations (cap to 8 for readability). Empty
|
|
61
|
+
* array = no violations.
|
|
62
|
+
* - `correction`: build the surgical-retry user-prefix string when
|
|
63
|
+
* violations are found. The LLM will see this prepended to the
|
|
64
|
+
* prompt on its second attempt.
|
|
65
|
+
* - `ordering`: pipeline position. Lower numbers fire first. Used to
|
|
66
|
+
* resolve which violation gets reported when multiple co-occur.
|
|
67
|
+
* Rough conventions:
|
|
68
|
+
* 0-9: structural pre-checks (parse, fence extraction)
|
|
69
|
+
* 10-19: runtime-API and environment-level constraints
|
|
70
|
+
* 20-29: import-shape constraints (extensions, scoping)
|
|
71
|
+
* 30-39: symbol-resolution constraints (sibling .ai, etc.)
|
|
72
|
+
* 40+: typing / shape constraints (Phase 3+)
|
|
73
|
+
* - `appliesWhen` (optional): predicate for runtime-conditional
|
|
74
|
+
* rules. e.g. 'no-browser-apis' applies only on Node target;
|
|
75
|
+
* 'no-node-builtins' applies only on Browser target.
|
|
76
|
+
*/
|
|
77
|
+
export interface RealizeRule {
|
|
78
|
+
id: string;
|
|
79
|
+
summary: string;
|
|
80
|
+
promptStatement: string;
|
|
81
|
+
detect: (fileContents: string, ctx: RuleContext) => RuleViolation[];
|
|
82
|
+
correction: (violations: RuleViolation[], ctx: RuleContext) => string;
|
|
83
|
+
ordering: number;
|
|
84
|
+
appliesWhen?: (ctx: RuleContext) => boolean;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Map a target-runtime label to its forbidden-API symbol set. Exported
|
|
88
|
+
* so the prompt builder can render the TARGET RUNTIME section using
|
|
89
|
+
* the same source-of-truth the validator enforces.
|
|
90
|
+
*
|
|
91
|
+
* Targets supported:
|
|
92
|
+
* - "Node.js (backend)" (default) — browser globals are forbidden
|
|
93
|
+
* - "Browser (DOM)" — Node builtins are forbidden
|
|
94
|
+
* - Unknown / unset — treat as Node.js backend
|
|
95
|
+
*/
|
|
96
|
+
export declare function forbiddenApisForRuntime(targetRuntime?: string): string[];
|
|
97
|
+
/**
|
|
98
|
+
* The full rule set, in pipeline order. Sorted by `ordering` field.
|
|
99
|
+
* The exported list is read by:
|
|
100
|
+
* - per-owner-emit.ts (validator loop)
|
|
101
|
+
* - prompt-builder (CONSTRAINTS section of realize-owner.prompt.yaml)
|
|
102
|
+
* - test corpus (fixture-to-rule expected mapping)
|
|
103
|
+
*/
|
|
104
|
+
export declare const RULES: ReadonlyArray<RealizeRule>;
|
|
105
|
+
/** Helper: get a single rule by id. Throws if the id doesn't exist
|
|
106
|
+
* (catches typos in test fixtures + downstream consumers). */
|
|
107
|
+
export declare function getRule(id: string): RealizeRule;
|
|
108
|
+
/** Helper: filter RULES to the ones that apply for a given context. */
|
|
109
|
+
export declare function rulesApplicableTo(ctx: RuleContext): RealizeRule[];
|
|
110
|
+
/** Helper: render the CONSTRAINTS section of the prompt by joining
|
|
111
|
+
* each rule's promptStatement. */
|
|
112
|
+
export declare function renderConstraintsForPrompt(ctx: RuleContext): string;
|
|
113
|
+
//# sourceMappingURL=realize-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realize-rules.d.ts","sourceRoot":"","sources":["../../src/realize/realize-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB;+DAC2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;8BAG8B;AAC9B,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,KAAK,aAAa,EAAE,CAAC;IACpE,UAAU,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,WAAW,KAAK,MAAM,CAAC;IACtE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC;CAC7C;AAqBD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAIxE;AA2KD;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,EAAE,aAAa,CAAC,WAAW,CAKJ,CAAC;AAE1C;+DAC+D;AAC/D,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,CAO/C;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,EAAE,CAEjE;AAED;mCACmC;AACnC,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAMnE"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realize LLM-emit rule manifest.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for every post-emit constraint enforced on
|
|
5
|
+
* per-owner LLM output. Replaces the prior model where each rule was
|
|
6
|
+
* authored in THREE places (a regex+correction in `per-owner-emit.ts`,
|
|
7
|
+
* a prose-statement in `realize-owner.prompt.yaml`, and an ad-hoc unit
|
|
8
|
+
* test fixture). That model produced drift — prompt and validator
|
|
9
|
+
* statements got out of sync, fixture coverage was uneven, and adding
|
|
10
|
+
* a rule meant editing three locations consistently.
|
|
11
|
+
*
|
|
12
|
+
* The manifest below declares each rule once. Three consumers read it:
|
|
13
|
+
*
|
|
14
|
+
* 1. Validator pipeline (per-owner-emit.ts) — calls `detect(...)` to
|
|
15
|
+
* find violations, calls `correction(...)` to build the surgical-
|
|
16
|
+
* retry prefix, sorts rules by `ordering` to control which fires
|
|
17
|
+
* first when multiple violations co-occur.
|
|
18
|
+
*
|
|
19
|
+
* 2. Prompt builder — reads `promptStatement` to render the
|
|
20
|
+
* CONSTRAINTS section of `realize-owner.prompt.yaml` (Phase 2 of
|
|
21
|
+
* the 2026-05-12-VALIDATOR-MANIFEST-AND-TEST-CORPUS proposal).
|
|
22
|
+
*
|
|
23
|
+
* 3. Test corpus (`engines/src/realize/__tests__/llm-output-fixtures/`)
|
|
24
|
+
* — each fixture is annotated with the rule IDs it should trigger;
|
|
25
|
+
* the pipeline harness asserts the manifest's ordering produces
|
|
26
|
+
* exactly those fires.
|
|
27
|
+
*
|
|
28
|
+
* Adding a new rule is one place: append a new entry to RULES.
|
|
29
|
+
*
|
|
30
|
+
* Why in engines/src/realize/ rather than entities/src/core/realize/:
|
|
31
|
+
* For the moment, rules are realize-internal — they're regex scans
|
|
32
|
+
* over LLM-emitted TypeScript, not the kind of bundle-able content
|
|
33
|
+
* that R12 entity modules manage. If realize rules ever need to be
|
|
34
|
+
* extended by user specs (e.g. project-specific forbidden imports),
|
|
35
|
+
* migration to the entity-module pattern would be the next step.
|
|
36
|
+
*/
|
|
37
|
+
// ─── Forbidden runtime APIs ─────────────────────────────────────────
|
|
38
|
+
/** Forbidden-API symbol set for Node.js target. */
|
|
39
|
+
const NODE_FORBIDDEN = [
|
|
40
|
+
'localStorage',
|
|
41
|
+
'sessionStorage',
|
|
42
|
+
'window.',
|
|
43
|
+
'document.',
|
|
44
|
+
'navigator.',
|
|
45
|
+
'location.',
|
|
46
|
+
'history.',
|
|
47
|
+
'alert(',
|
|
48
|
+
'prompt(',
|
|
49
|
+
'confirm(',
|
|
50
|
+
];
|
|
51
|
+
/** Forbidden-API symbol set for Browser target. */
|
|
52
|
+
const BROWSER_FORBIDDEN = ['process.env', 'require(', 'Buffer', '__dirname', '__filename', 'node:'];
|
|
53
|
+
/**
|
|
54
|
+
* Map a target-runtime label to its forbidden-API symbol set. Exported
|
|
55
|
+
* so the prompt builder can render the TARGET RUNTIME section using
|
|
56
|
+
* the same source-of-truth the validator enforces.
|
|
57
|
+
*
|
|
58
|
+
* Targets supported:
|
|
59
|
+
* - "Node.js (backend)" (default) — browser globals are forbidden
|
|
60
|
+
* - "Browser (DOM)" — Node builtins are forbidden
|
|
61
|
+
* - Unknown / unset — treat as Node.js backend
|
|
62
|
+
*/
|
|
63
|
+
export function forbiddenApisForRuntime(targetRuntime) {
|
|
64
|
+
const t = (targetRuntime ?? 'Node.js (backend)').toLowerCase();
|
|
65
|
+
if (t.includes('browser') && !t.includes('backend'))
|
|
66
|
+
return BROWSER_FORBIDDEN;
|
|
67
|
+
return NODE_FORBIDDEN;
|
|
68
|
+
}
|
|
69
|
+
// ─── Rules ───────────────────────────────────────────────────────────
|
|
70
|
+
const RULE_NO_FORBIDDEN_RUNTIME_APIS = {
|
|
71
|
+
id: 'no-forbidden-runtime-apis',
|
|
72
|
+
summary: 'No APIs from foreign runtimes',
|
|
73
|
+
promptStatement: 'Do NOT use APIs that don\'t exist in the target runtime. The ' +
|
|
74
|
+
'forbidden symbols for this run are listed in the TARGET RUNTIME ' +
|
|
75
|
+
'section above. If a spec step references a forbidden API ' +
|
|
76
|
+
'(e.g. "save to localStorage" with a Node.js target), emit the ' +
|
|
77
|
+
'γ-stub form for THAT action explaining the spec/runtime ' +
|
|
78
|
+
'mismatch — do NOT implement the forbidden API.',
|
|
79
|
+
detect(fileContents, ctx) {
|
|
80
|
+
const forbidden = forbiddenApisForRuntime(ctx.targetRuntime);
|
|
81
|
+
const violations = new Set();
|
|
82
|
+
for (const symbol of forbidden) {
|
|
83
|
+
if (fileContents.includes(symbol))
|
|
84
|
+
violations.add(symbol);
|
|
85
|
+
}
|
|
86
|
+
return Array.from(violations).slice(0, 8);
|
|
87
|
+
},
|
|
88
|
+
correction(violations, ctx) {
|
|
89
|
+
const runtime = ctx.targetRuntime ?? 'Node.js (backend)';
|
|
90
|
+
return [
|
|
91
|
+
`Your previous emission used runtime APIs that are NOT available in ${runtime}:`,
|
|
92
|
+
'',
|
|
93
|
+
...violations.map((v) => ` - ${v}`),
|
|
94
|
+
'',
|
|
95
|
+
`Re-emit the entire file WITHOUT those symbols. If a specific action's`,
|
|
96
|
+
`step text references runtime-incompatible behaviour, use the γ-stub`,
|
|
97
|
+
`form for THAT action explaining the spec/runtime mismatch. Other`,
|
|
98
|
+
`actions in the file should still be implemented fully. Preserve`,
|
|
99
|
+
`all [PRE-BAKED] snippets verbatim.`,
|
|
100
|
+
'',
|
|
101
|
+
].join('\n');
|
|
102
|
+
},
|
|
103
|
+
ordering: 10,
|
|
104
|
+
};
|
|
105
|
+
const RULE_JS_EXTENSIONS_ON_RELATIVE_IMPORTS = {
|
|
106
|
+
id: 'js-ext-on-relative-imports',
|
|
107
|
+
summary: 'Relative imports require explicit `.js` (or .ts/.json/...) extension',
|
|
108
|
+
promptStatement: 'Relative imports MUST end with `.js` (or `.ts`/`.json`/`.mjs`/`.mts`). ' +
|
|
109
|
+
'The project uses `moduleResolution: NodeNext` which requires explicit ' +
|
|
110
|
+
'extensions on relative paths. WRONG: `from \'../services/AuthService\'` ' +
|
|
111
|
+
'→ CORRECT: `from \'../services/AuthService.js\'`. Bare-package imports ' +
|
|
112
|
+
'(`@prisma/client`, `jsonwebtoken`) do NOT need an extension.',
|
|
113
|
+
detect(fileContents) {
|
|
114
|
+
const violations = new Set();
|
|
115
|
+
const re = /from\s+['"](\.\.?\/[^'"]*?)['"]/g;
|
|
116
|
+
let m;
|
|
117
|
+
while ((m = re.exec(fileContents)) !== null) {
|
|
118
|
+
const specifier = m[1];
|
|
119
|
+
if (!/\.(m?[jt]sx?|json)$/.test(specifier)) {
|
|
120
|
+
violations.add(specifier);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return Array.from(violations).slice(0, 8);
|
|
124
|
+
},
|
|
125
|
+
correction(violations) {
|
|
126
|
+
return [
|
|
127
|
+
`Your previous emission used relative imports WITHOUT the required`,
|
|
128
|
+
`\`.js\` extension. NodeNext module resolution requires explicit`,
|
|
129
|
+
`extensions on relative paths:`,
|
|
130
|
+
'',
|
|
131
|
+
...violations.map((v) => ` - '${v}' → '${v}.js'`),
|
|
132
|
+
'',
|
|
133
|
+
`Re-emit the entire file with \`.js\` appended to every relative-path`,
|
|
134
|
+
`import. Bare-package imports do NOT need an extension. Preserve all`,
|
|
135
|
+
`[PRE-BAKED] snippets verbatim.`,
|
|
136
|
+
'',
|
|
137
|
+
].join('\n');
|
|
138
|
+
},
|
|
139
|
+
ordering: 20,
|
|
140
|
+
};
|
|
141
|
+
const RULE_NO_SIBLING_CLASS_PATH_IMPORTS = {
|
|
142
|
+
id: 'no-sibling-class-path-imports',
|
|
143
|
+
summary: 'Sibling-class imports (`./<Capital>.js`) must use the parent-directory ' +
|
|
144
|
+
'path (`../<dir>/<Capital>.js`) because realize emits behaviors/ and ' +
|
|
145
|
+
'services/ as separate directories',
|
|
146
|
+
promptStatement: 'Sibling-class imports MUST use `../<dir>/<Name>.js`, NOT `./<Name>.js`. ' +
|
|
147
|
+
'The realize pipeline emits this file into `backend/src/behaviors/`; ' +
|
|
148
|
+
'service classes live at `backend/src/services/<Name>.ts` and ' +
|
|
149
|
+
'controller classes at `backend/src/controllers/<Name>.ts`. WRONG: ' +
|
|
150
|
+
'`from \'./GameStateService.js\'` → CORRECT: ' +
|
|
151
|
+
'`from \'../services/GameStateService.js\'`. (Sibling .ai imports are ' +
|
|
152
|
+
'separately forbidden — see the next rule. Subdirectory imports like ' +
|
|
153
|
+
'`./types/Foo.js` are fine; only TOP-LEVEL `./<Capital>.js` is wrong.)',
|
|
154
|
+
detect(fileContents) {
|
|
155
|
+
const violations = new Set();
|
|
156
|
+
// Match `from './<Capital><rest>.js'` with no subdirectory slash inside
|
|
157
|
+
// and where the bare name (rest) does NOT end in `.ai` (the sibling-ai
|
|
158
|
+
// rule handles those).
|
|
159
|
+
const re = /from\s+['"](\.\/[A-Z][^'"\/]*)\.js['"]/g;
|
|
160
|
+
let m;
|
|
161
|
+
while ((m = re.exec(fileContents)) !== null) {
|
|
162
|
+
const specifier = m[1];
|
|
163
|
+
// Skip `.ai` siblings — caught by `no-sibling-ai-imports` instead.
|
|
164
|
+
if (specifier.endsWith('.ai'))
|
|
165
|
+
continue;
|
|
166
|
+
violations.add(specifier);
|
|
167
|
+
}
|
|
168
|
+
return Array.from(violations).slice(0, 8);
|
|
169
|
+
},
|
|
170
|
+
correction(violations) {
|
|
171
|
+
return [
|
|
172
|
+
`Your previous emission imported sibling-class modules with the wrong path:`,
|
|
173
|
+
'',
|
|
174
|
+
...violations.map((v) => ` - '${v}.js' → '../services/${v.slice(2)}.js' (or '../controllers/${v.slice(2)}.js' if it's a controller class)`),
|
|
175
|
+
'',
|
|
176
|
+
`The realize pipeline organises generated code by kind:`,
|
|
177
|
+
` backend/src/behaviors/<Name>.ai.ts ← this file`,
|
|
178
|
+
` backend/src/services/<Name>.ts ← service classes`,
|
|
179
|
+
` backend/src/controllers/<Name>.ts ← controller classes`,
|
|
180
|
+
``,
|
|
181
|
+
`So a sibling-class import from THIS file is one directory up + into`,
|
|
182
|
+
`the service-or-controller dir. NOT \`./<Name>.js\`.`,
|
|
183
|
+
'',
|
|
184
|
+
`Re-emit the entire file with the imports corrected. Preserve all`,
|
|
185
|
+
`[PRE-BAKED] snippets verbatim.`,
|
|
186
|
+
'',
|
|
187
|
+
].join('\n');
|
|
188
|
+
},
|
|
189
|
+
ordering: 25,
|
|
190
|
+
};
|
|
191
|
+
const RULE_NO_SIBLING_AI_IMPORTS = {
|
|
192
|
+
id: 'no-sibling-ai-imports',
|
|
193
|
+
summary: 'Do not import sibling `.ai.ts` files',
|
|
194
|
+
promptStatement: 'Do NOT import sibling `.ai.ts` files. Each `<Owner>.ai.ts` is ' +
|
|
195
|
+
'self-contained — those modules export per-action async functions, ' +
|
|
196
|
+
'not the entity types or service instances you might want to use. ' +
|
|
197
|
+
'For cross-service calls, import from the service / controller class ' +
|
|
198
|
+
'file instead (e.g. `import { AuthService } from \'../services/AuthService.js\'`). ' +
|
|
199
|
+
'If a step requires logic from a sibling .ai, emit a γ-stub for THAT ' +
|
|
200
|
+
'specific action explaining the cross-owner gap.',
|
|
201
|
+
detect(fileContents) {
|
|
202
|
+
const violations = new Set();
|
|
203
|
+
const re = /from\s+['"](\.\.?\/[^'"]+\.ai)(?:\.js)?['"]/g;
|
|
204
|
+
let m;
|
|
205
|
+
while ((m = re.exec(fileContents)) !== null) {
|
|
206
|
+
violations.add(m[1]);
|
|
207
|
+
}
|
|
208
|
+
return Array.from(violations).slice(0, 8);
|
|
209
|
+
},
|
|
210
|
+
correction(violations) {
|
|
211
|
+
return [
|
|
212
|
+
`Your previous emission imported sibling .ai.ts modules, which is forbidden:`,
|
|
213
|
+
'',
|
|
214
|
+
...violations.map((v) => ` - ${v}`),
|
|
215
|
+
'',
|
|
216
|
+
`Each <Owner>.ai.ts is self-contained — those modules export per-action`,
|
|
217
|
+
`functions, NOT the entity types or service instances you can use here.`,
|
|
218
|
+
'',
|
|
219
|
+
`Re-emit the entire file WITHOUT importing any sibling .ai modules.`,
|
|
220
|
+
`For cross-service calls, import from the service / controller class file`,
|
|
221
|
+
`instead (e.g. \`import { AuthService } from '../services/AuthService.js'\`).`,
|
|
222
|
+
`If a step requires logic that lives in a sibling .ai, emit the γ-stub for`,
|
|
223
|
+
`THAT specific action explaining the cross-owner gap. Preserve all`,
|
|
224
|
+
`[PRE-BAKED] snippets verbatim.`,
|
|
225
|
+
'',
|
|
226
|
+
].join('\n');
|
|
227
|
+
},
|
|
228
|
+
ordering: 30,
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* The full rule set, in pipeline order. Sorted by `ordering` field.
|
|
232
|
+
* The exported list is read by:
|
|
233
|
+
* - per-owner-emit.ts (validator loop)
|
|
234
|
+
* - prompt-builder (CONSTRAINTS section of realize-owner.prompt.yaml)
|
|
235
|
+
* - test corpus (fixture-to-rule expected mapping)
|
|
236
|
+
*/
|
|
237
|
+
export const RULES = [
|
|
238
|
+
RULE_NO_FORBIDDEN_RUNTIME_APIS,
|
|
239
|
+
RULE_JS_EXTENSIONS_ON_RELATIVE_IMPORTS,
|
|
240
|
+
RULE_NO_SIBLING_CLASS_PATH_IMPORTS,
|
|
241
|
+
RULE_NO_SIBLING_AI_IMPORTS,
|
|
242
|
+
].sort((a, b) => a.ordering - b.ordering);
|
|
243
|
+
/** Helper: get a single rule by id. Throws if the id doesn't exist
|
|
244
|
+
* (catches typos in test fixtures + downstream consumers). */
|
|
245
|
+
export function getRule(id) {
|
|
246
|
+
const rule = RULES.find((r) => r.id === id);
|
|
247
|
+
if (!rule) {
|
|
248
|
+
const known = RULES.map((r) => r.id).join(', ');
|
|
249
|
+
throw new Error(`Unknown realize rule id: '${id}'. Known: ${known}.`);
|
|
250
|
+
}
|
|
251
|
+
return rule;
|
|
252
|
+
}
|
|
253
|
+
/** Helper: filter RULES to the ones that apply for a given context. */
|
|
254
|
+
export function rulesApplicableTo(ctx) {
|
|
255
|
+
return RULES.filter((r) => !r.appliesWhen || r.appliesWhen(ctx));
|
|
256
|
+
}
|
|
257
|
+
/** Helper: render the CONSTRAINTS section of the prompt by joining
|
|
258
|
+
* each rule's promptStatement. */
|
|
259
|
+
export function renderConstraintsForPrompt(ctx) {
|
|
260
|
+
const applicable = rulesApplicableTo(ctx);
|
|
261
|
+
if (applicable.length === 0)
|
|
262
|
+
return '(no constraints declared)';
|
|
263
|
+
return applicable
|
|
264
|
+
.map((rule, i) => `${i + 1}. ${rule.promptStatement}`)
|
|
265
|
+
.join('\n\n');
|
|
266
|
+
}
|
|
267
|
+
// Note: the LanguageModelV3 import is currently unused but kept for
|
|
268
|
+
// future rules that may need to consult the model object (e.g. for
|
|
269
|
+
// model-specific constraints). Remove if no such rules emerge.
|
|
270
|
+
void null;
|
|
271
|
+
//# sourceMappingURL=realize-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realize-rules.js","sourceRoot":"","sources":["../../src/realize/realize-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,20 +67,19 @@ import { fileURLToPath } from 'url';
|
|
|
67
67
|
import { dirname, join } from 'path';
|
|
68
68
|
${imports}
|
|
69
69
|
|
|
70
|
-
// Read version:
|
|
70
|
+
// Read version: walk up to find the @specverse/self package.json,
|
|
71
|
+
// fall back to the build-time interpolation when not found.
|
|
71
72
|
const __filename = fileURLToPath(import.meta.url);
|
|
72
73
|
const __dirname = dirname(__filename);
|
|
73
|
-
let _version =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
} catch { /* use fallback */ }
|
|
83
|
-
}
|
|
74
|
+
let _version = '${version}';
|
|
75
|
+
try {
|
|
76
|
+
for (const rel of ['../../package.json', '../../../package.json', '../../../../package.json', '../../../../../package.json']) {
|
|
77
|
+
try {
|
|
78
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, rel), 'utf8'));
|
|
79
|
+
if (pkg.name === '@specverse/self' && pkg.version) { _version = pkg.version; break; }
|
|
80
|
+
} catch { /* try next */ }
|
|
81
|
+
}
|
|
82
|
+
} catch { /* use fallback */ }
|
|
84
83
|
|
|
85
84
|
const program = new Command();
|
|
86
85
|
|
|
@@ -208,7 +208,7 @@ import type { ParserEngine } from '@specverse/types';`,
|
|
|
208
208
|
} catch (qe: any) {
|
|
209
209
|
// Don't let quint-gen module-loading issues block normal
|
|
210
210
|
// validate (e.g. running against a much older engines version).
|
|
211
|
-
if (process.env.
|
|
211
|
+
if (process.env.SPECVERSE_VERBOSE === '2') {
|
|
212
212
|
console.warn('quint-gen check skipped:', qe?.message ?? String(qe));
|
|
213
213
|
}
|
|
214
214
|
}
|
|
@@ -377,7 +377,7 @@ import type { ParserEngine, InferenceEngine, RealizeEngine } from '@specverse/ty
|
|
|
377
377
|
process.exit(1);
|
|
378
378
|
}
|
|
379
379
|
} catch (qe: any) {
|
|
380
|
-
if (process.env.
|
|
380
|
+
if (process.env.SPECVERSE_VERBOSE === '2') {
|
|
381
381
|
console.warn('quint-gen check skipped:', qe?.message ?? String(qe));
|
|
382
382
|
}
|
|
383
383
|
}
|
|
@@ -128,6 +128,14 @@ export function generateBehaviorWithHelpers(
|
|
|
128
128
|
|
|
129
129
|
let body = parts.join('\n\n');
|
|
130
130
|
|
|
131
|
+
// Rename precondition-fetched `const X = await prisma.X.findUniqueOrThrow(...)`
|
|
132
|
+
// bindings to `_X` when the body has no other reference to `X`. The
|
|
133
|
+
// existence-check pattern emits a const for "{Model} exists" preconditions;
|
|
134
|
+
// if no subsequent precondition / step / postcondition references it, tsc
|
|
135
|
+
// raises TS6133 unused-decl. Renaming to _-prefix suppresses tsc's check
|
|
136
|
+
// while preserving the throw-on-missing semantics.
|
|
137
|
+
body = renameUnusedFindUniqueBindings(body);
|
|
138
|
+
|
|
131
139
|
// Wrap in transaction if flagged
|
|
132
140
|
if (behavior.transactional) {
|
|
133
141
|
body = generateTransactionWrapper(body, context);
|
|
@@ -136,6 +144,50 @@ export function generateBehaviorWithHelpers(
|
|
|
136
144
|
return { body, helperMethods, unmatchedSteps };
|
|
137
145
|
}
|
|
138
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Post-process a method body string: find each `const X = await prisma.X.findUniqueOrThrow(...)`
|
|
149
|
+
* binding, count downstream references to `X`, and DROP the `const X =`
|
|
150
|
+
* binding entirely when the var is otherwise unused (keeping just the
|
|
151
|
+
* `await prisma.X.findUniqueOrThrow(...)` expression statement). The
|
|
152
|
+
* throw-on-missing semantic is preserved; tsc's noUnusedLocals stops
|
|
153
|
+
* complaining because there's no local to be unused.
|
|
154
|
+
*
|
|
155
|
+
* Why drop instead of rename to `_X`: TypeScript's `_`-prefix
|
|
156
|
+
* exemption only applies to `noUnusedParameters` (function arg names),
|
|
157
|
+
* NOT to `noUnusedLocals` (var decls). A `_invoice` const still trips
|
|
158
|
+
* TS6133 — dropping the binding is the actual fix.
|
|
159
|
+
*
|
|
160
|
+
* The `prisma.X` namespace reference inside the call is a model
|
|
161
|
+
* lookup — DO NOT touch it.
|
|
162
|
+
*/
|
|
163
|
+
function renameUnusedFindUniqueBindings(body: string): string {
|
|
164
|
+
const declRe = /\bconst\s+([a-zA-Z_][\w$]*)\s*=\s*await\s+prisma\.[\w.$]+\.findUniqueOrThrow\b/g;
|
|
165
|
+
const declared: string[] = [];
|
|
166
|
+
let m: RegExpExecArray | null;
|
|
167
|
+
while ((m = declRe.exec(body)) !== null) declared.push(m[1]!);
|
|
168
|
+
if (declared.length === 0) return body;
|
|
169
|
+
|
|
170
|
+
let out = body;
|
|
171
|
+
for (const name of declared) {
|
|
172
|
+
// Count occurrences of the bare identifier as a USAGE reference.
|
|
173
|
+
// The declaration line contributes 2: the `const NAME` binding
|
|
174
|
+
// and the `prisma.NAME` model reference. So 2 total = unused; 3+
|
|
175
|
+
// means at least one downstream reference.
|
|
176
|
+
const refRe = new RegExp(`\\b${name}\\b`, 'g');
|
|
177
|
+
const count = (out.match(refRe) ?? []).length;
|
|
178
|
+
if (count <= 2) {
|
|
179
|
+
// Drop the `const NAME =` prefix from the declaration line,
|
|
180
|
+
// leaving the `await prisma.NAME.findUniqueOrThrow(...);` as a
|
|
181
|
+
// pure side-effect statement.
|
|
182
|
+
out = out.replace(
|
|
183
|
+
new RegExp(`\\bconst\\s+${name}\\s*=\\s*(await\\s+prisma\\.)`),
|
|
184
|
+
`$1`,
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
|
|
139
191
|
/**
|
|
140
192
|
* Generate precondition checks from natural-language strings.
|
|
141
193
|
* Tracks declared variables to avoid duplicates and reuses fetched entities.
|
|
@@ -304,14 +356,22 @@ function inferLogicFromOperationName(context: BehaviorContext): string {
|
|
|
304
356
|
|
|
305
357
|
if (op.startsWith('handle')) {
|
|
306
358
|
const event = op.replace('handle', '');
|
|
359
|
+
// Use the first declared parameter name (typically `event`) instead
|
|
360
|
+
// of the hard-coded `params`. The method signature uses the spec-
|
|
361
|
+
// derived param name, so referencing `params` produces TS2304
|
|
362
|
+
// "Cannot find name" errors at compile time.
|
|
363
|
+
const eventParam = context.parameterNames?.[0] ?? '_event';
|
|
307
364
|
return ` // Event handler: ${op}
|
|
308
|
-
console.log('[${context.serviceName}] Processing ${event}',
|
|
365
|
+
console.log('[${context.serviceName}] Processing ${event}', ${eventParam});
|
|
309
366
|
return { handled: true, event: '${event}' };`;
|
|
310
367
|
}
|
|
311
368
|
|
|
312
369
|
if (op.startsWith('validate')) {
|
|
370
|
+
// Same fix as handle*: use the actual first parameter name. For
|
|
371
|
+
// validateX patterns the first param is conventionally `id`.
|
|
372
|
+
const idParam = context.parameterNames?.[0] ?? 'id';
|
|
313
373
|
return ` // Validation: ${op}
|
|
314
|
-
const records = await prisma.${modelVar}.findMany({ where: { id:
|
|
374
|
+
const records = await prisma.${modelVar}.findMany({ where: { id: ${idParam} } });
|
|
315
375
|
return { valid: records.length > 0, checked: records.length };`;
|
|
316
376
|
}
|
|
317
377
|
|
|
@@ -46,34 +46,56 @@ export default function generatePrismaController(context: TemplateContext): stri
|
|
|
46
46
|
// Generate custom actions and collect AI behavior stubs
|
|
47
47
|
const customActions = generateCustomActions(controller, modelName, modelVar);
|
|
48
48
|
|
|
49
|
+
// Build the class body first, then introspect to decide which
|
|
50
|
+
// top-of-file declarations are actually needed. Controllers with no
|
|
51
|
+
// CURVED ops and no prisma-using custom actions (e.g. a controller
|
|
52
|
+
// that only delegates to .ai.ts behaviour) end up with empty
|
|
53
|
+
// bodies — emitting `prisma` / `parseId` / `PrismaClient` import
|
|
54
|
+
// unconditionally produced TS6133 unused-decl errors at every
|
|
55
|
+
// realize run. Gating on actual body content drops those.
|
|
56
|
+
const classBody = [
|
|
57
|
+
generateValidateMethod(model, modelName),
|
|
58
|
+
curedOps.create ? generateCreateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : '',
|
|
59
|
+
curedOps.retrieve ? generateRetrieveMethod(model, modelName, modelVar, prismaDelegate) : '',
|
|
60
|
+
curedOps.update ? generateUpdateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : '',
|
|
61
|
+
curedOps.evolve ? generateEvolveMethod(model, modelName, modelVar, prismaDelegate, controller) : '',
|
|
62
|
+
curedOps.delete ? generateDeleteMethod(model, modelName, modelVar, prismaDelegate, controller) : '',
|
|
63
|
+
customActions.code,
|
|
64
|
+
].filter(Boolean).join('\n ');
|
|
65
|
+
|
|
66
|
+
const usesPrisma = /\bprisma\b/.test(classBody);
|
|
67
|
+
const usesParseId = /\bparseId\(/.test(classBody);
|
|
68
|
+
const usesEventBus = hasEventPublishing(curedOps, controller);
|
|
69
|
+
const usesAiBehaviors = customActions.needsAiBehaviors;
|
|
70
|
+
|
|
71
|
+
// Build top-of-file declarations conditionally.
|
|
72
|
+
const imports = [
|
|
73
|
+
usesPrisma ? `import { PrismaClient } from '@prisma/client';` : '',
|
|
74
|
+
usesEventBus ? `import { eventBus } from '../events/eventBus.js';` : '',
|
|
75
|
+
usesAiBehaviors ? `import * as aiBehaviors from '../behaviors/${modelName}Controller.ai.js';` : '',
|
|
76
|
+
].filter(Boolean).join('\n');
|
|
77
|
+
|
|
78
|
+
const declarations = [
|
|
79
|
+
usesPrisma ? `const prisma = new PrismaClient();` : '',
|
|
80
|
+
usesParseId
|
|
81
|
+
? `/** Parse ID from string to the correct type for this model */
|
|
82
|
+
function parseId(id: string): ${needsIntParse ? 'number' : 'string'} {
|
|
83
|
+
${needsIntParse ? 'return parseInt(id, 10);' : 'return id;'}
|
|
84
|
+
}`
|
|
85
|
+
: '',
|
|
86
|
+
].filter(Boolean).join('\n\n');
|
|
87
|
+
|
|
49
88
|
return `/**
|
|
50
89
|
* ${controllerName}
|
|
51
90
|
* Model-specific business logic for ${modelName}
|
|
52
91
|
* ${controller.description || ''}
|
|
53
92
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
${hasEventPublishing(curedOps, controller) ? `import { eventBus } from '../events/eventBus.js';` : ''}
|
|
57
|
-
${customActions.needsAiBehaviors ? `import * as aiBehaviors from '../behaviors/${modelName}Controller.ai.js';` : ''}
|
|
58
|
-
|
|
59
|
-
const prisma = new PrismaClient();
|
|
60
|
-
|
|
61
|
-
/** Parse ID from string to the correct type for this model */
|
|
62
|
-
function parseId(id: string): ${needsIntParse ? 'number' : 'string'} {
|
|
63
|
-
${needsIntParse ? 'return parseInt(id, 10);' : 'return id;'}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
93
|
+
${imports ? '\n' + imports + '\n' : ''}
|
|
94
|
+
${declarations ? declarations + '\n\n' : ''}/**
|
|
67
95
|
* ${controllerName} class
|
|
68
96
|
*/
|
|
69
97
|
export class ${controllerName} {
|
|
70
|
-
${
|
|
71
|
-
${curedOps.create ? generateCreateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : ''}
|
|
72
|
-
${curedOps.retrieve ? generateRetrieveMethod(model, modelName, modelVar, prismaDelegate) : ''}
|
|
73
|
-
${curedOps.update ? generateUpdateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : ''}
|
|
74
|
-
${curedOps.evolve ? generateEvolveMethod(model, modelName, modelVar, prismaDelegate, controller) : ''}
|
|
75
|
-
${curedOps.delete ? generateDeleteMethod(model, modelName, modelVar, prismaDelegate, controller) : ''}
|
|
76
|
-
${customActions.code}
|
|
98
|
+
${classBody}
|
|
77
99
|
}
|
|
78
100
|
|
|
79
101
|
// Export singleton instance
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specverse/engines",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.53.1",
|
|
4
4
|
"description": "SpecVerse toolchain — parser, inference, realize, generators, AI, registry, bundles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -35,6 +35,14 @@
|
|
|
35
35
|
"types": "./dist/realize/index.d.ts",
|
|
36
36
|
"import": "./dist/realize/index.js"
|
|
37
37
|
},
|
|
38
|
+
"./realize/post-emit-verify": {
|
|
39
|
+
"types": "./dist/realize/post-emit-verify/index.d.ts",
|
|
40
|
+
"import": "./dist/realize/post-emit-verify/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./normalise": {
|
|
43
|
+
"types": "./dist/normalise/index.d.ts",
|
|
44
|
+
"import": "./dist/normalise/index.js"
|
|
45
|
+
},
|
|
38
46
|
"./generators": {
|
|
39
47
|
"types": "./dist/generators/index.d.ts",
|
|
40
48
|
"import": "./dist/generators/index.js"
|