@specverse/engines 4.1.28 → 4.2.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.
- package/assets/examples/manifests/frontend-only.yaml +3 -6
- package/assets/examples/manifests/fullstack-app.yaml +5 -7
- package/assets/examples/manifests/fullstack-monorepo.yaml +3 -6
- package/dist/inference/comprehensive-engine.d.ts.map +1 -1
- package/dist/inference/comprehensive-engine.js +3 -19
- package/dist/inference/comprehensive-engine.js.map +1 -1
- package/dist/inference/core/rule-engine.d.ts +31 -0
- package/dist/inference/core/rule-engine.d.ts.map +1 -1
- package/dist/inference/core/rule-engine.js +117 -33
- package/dist/inference/core/rule-engine.js.map +1 -1
- package/dist/inference/core/rule-file-types.d.ts +0 -2
- package/dist/inference/core/rule-file-types.d.ts.map +1 -1
- package/dist/inference/core/rule-file-types.js +3 -6
- package/dist/inference/core/rule-file-types.js.map +1 -1
- package/dist/inference/core/rule-loader.d.ts +5 -15
- package/dist/inference/core/rule-loader.d.ts.map +1 -1
- package/dist/inference/core/rule-loader.js +43 -132
- package/dist/inference/core/rule-loader.js.map +1 -1
- package/dist/inference/core/types.d.ts +0 -6
- package/dist/inference/core/types.d.ts.map +1 -1
- package/dist/inference/core/types.js +0 -4
- package/dist/inference/core/types.js.map +1 -1
- package/dist/inference/logical/generators/component-type-resolver.d.ts +0 -26
- package/dist/inference/logical/generators/component-type-resolver.d.ts.map +1 -1
- package/dist/inference/logical/generators/component-type-resolver.js +0 -19
- package/dist/inference/logical/generators/component-type-resolver.js.map +1 -1
- package/dist/inference/logical/generators/specialist-view-expander.d.ts +1 -17
- package/dist/inference/logical/generators/specialist-view-expander.d.ts.map +1 -1
- package/dist/inference/logical/generators/specialist-view-expander.js +0 -15
- package/dist/inference/logical/generators/specialist-view-expander.js.map +1 -1
- package/dist/inference/logical/generators/view-generator.d.ts +4 -14
- package/dist/inference/logical/generators/view-generator.d.ts.map +1 -1
- package/dist/inference/logical/generators/view-generator.js +6 -26
- package/dist/inference/logical/generators/view-generator.js.map +1 -1
- package/dist/inference/logical/index.d.ts +2 -2
- package/dist/inference/logical/index.d.ts.map +1 -1
- package/dist/inference/logical/logical-engine.d.ts.map +1 -1
- package/dist/inference/logical/logical-engine.js +17 -80
- package/dist/inference/logical/logical-engine.js.map +1 -1
- package/dist/inference/quint-transpiler.d.ts +5 -3
- package/dist/inference/quint-transpiler.d.ts.map +1 -1
- package/dist/inference/quint-transpiler.js +11 -6
- package/dist/inference/quint-transpiler.js.map +1 -1
- package/dist/libs/instance-factories/applications/templates/generic/main-generator.js +3 -3
- package/dist/libs/instance-factories/applications/templates/react/api-client-generator.js +16 -6
- package/dist/libs/instance-factories/applications/templates/react-starter/app-tsx-generator.js +110 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/dashboard-body-composer.js +121 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/detail-body-composer.js +78 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/form-body-composer.js +190 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/helpers-emitter.js +45 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/html-to-jsx.js +192 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/list-body-composer.js +46 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/orchestrator.js +30 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/package-json-generator.js +38 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/regen-safety.js +89 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/view-emitter.js +56 -0
- package/dist/libs/instance-factories/applications/templates/react-starter/views-generator.js +66 -0
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +14 -11
- package/dist/libs/instance-factories/controllers/templates/fastify/server-generator.js +11 -3
- package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +27 -17
- package/dist/libs/instance-factories/shared/path-resolver.js +1 -1
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +15 -22
- package/dist/realize/index.js.map +1 -1
- package/dist/registry/utils/manifest-adapter.d.ts +8 -1
- package/dist/registry/utils/manifest-adapter.d.ts.map +1 -1
- package/dist/registry/utils/manifest-adapter.js +8 -1
- package/dist/registry/utils/manifest-adapter.js.map +1 -1
- package/libs/instance-factories/applications/react-app-starter.yaml +150 -0
- package/libs/instance-factories/applications/templates/generic/main-generator.ts +3 -3
- package/libs/instance-factories/applications/templates/react/api-client-generator.ts +16 -6
- package/libs/instance-factories/applications/templates/react-starter/README.md +211 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/dashboard-body-composer.test.ts +153 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/detail-body-composer.test.ts +145 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/form-body-composer.test.ts +175 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/helpers-emitter.test.ts +55 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/html-to-jsx.test.ts +140 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/list-body-composer.test.ts +146 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/orchestrator.test.ts +163 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/parity-p2-factory-imports.test.ts +116 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/parity-p3-rendered-output.test.ts +183 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/regen-safety.test.ts +144 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/starter-generators.test.ts +114 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/view-emitter.test.ts +107 -0
- package/libs/instance-factories/applications/templates/react-starter/__tests__/views-generator.test.ts +139 -0
- package/libs/instance-factories/applications/templates/react-starter/app-tsx-generator.ts +141 -0
- package/libs/instance-factories/applications/templates/react-starter/dashboard-body-composer.ts +174 -0
- package/libs/instance-factories/applications/templates/react-starter/detail-body-composer.ts +135 -0
- package/libs/instance-factories/applications/templates/react-starter/form-body-composer.ts +306 -0
- package/libs/instance-factories/applications/templates/react-starter/helpers-emitter.ts +60 -0
- package/libs/instance-factories/applications/templates/react-starter/html-to-jsx.ts +334 -0
- package/libs/instance-factories/applications/templates/react-starter/list-body-composer.ts +120 -0
- package/libs/instance-factories/applications/templates/react-starter/orchestrator.ts +80 -0
- package/libs/instance-factories/applications/templates/react-starter/package-json-generator.ts +57 -0
- package/libs/instance-factories/applications/templates/react-starter/regen-safety.ts +157 -0
- package/libs/instance-factories/applications/templates/react-starter/skeletons/dashboard.tsx.template +47 -0
- package/libs/instance-factories/applications/templates/react-starter/skeletons/detail.tsx.template +94 -0
- package/libs/instance-factories/applications/templates/react-starter/skeletons/form.tsx.template +114 -0
- package/libs/instance-factories/applications/templates/react-starter/skeletons/list.tsx.template +72 -0
- package/libs/instance-factories/applications/templates/react-starter/view-emitter.ts +151 -0
- package/libs/instance-factories/applications/templates/react-starter/views-generator.ts +137 -0
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +14 -11
- package/libs/instance-factories/controllers/templates/fastify/server-generator.ts +11 -3
- package/libs/instance-factories/services/templates/prisma/controller-generator.ts +27 -17
- package/libs/instance-factories/shared/path-resolver.ts +8 -2
- package/package.json +3 -3
- package/dist/libs/instance-factories/applications/templates/react/_view-components-source.js +0 -530
- package/dist/libs/instance-factories/applications/templates/react/app-tsx-generator.js +0 -73
- package/dist/libs/instance-factories/applications/templates/react/field-helpers-generator.js +0 -99
- package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +0 -49
- package/dist/libs/instance-factories/applications/templates/react/pattern-adapter-generator.js +0 -156
- package/dist/libs/instance-factories/applications/templates/react/react-pattern-adapter.js +0 -935
- package/dist/libs/instance-factories/applications/templates/react/relationship-field-generator.js +0 -143
- package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.js +0 -646
- package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.js +0 -65
- package/dist/libs/instance-factories/applications/templates/react/view-dashboard-generator.js +0 -143
- package/dist/libs/instance-factories/applications/templates/react/view-detail-generator.js +0 -143
- package/dist/libs/instance-factories/applications/templates/react/view-form-generator.js +0 -355
- package/dist/libs/instance-factories/applications/templates/react/view-list-generator.js +0 -91
- package/dist/libs/instance-factories/applications/templates/react/view-router-generator.js +0 -79
- package/dist/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.js.bak +0 -244
- package/dist/libs/instance-factories/views/index.js +0 -48
- package/dist/libs/instance-factories/views/templates/react/adapters/antd-adapter.js +0 -742
- package/dist/libs/instance-factories/views/templates/react/adapters/mui-adapter.js +0 -824
- package/dist/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.js +0 -719
- package/dist/libs/instance-factories/views/templates/react/app-generator.js +0 -45
- package/dist/libs/instance-factories/views/templates/react/components-generator.js +0 -820
- package/dist/libs/instance-factories/views/templates/react/forms-generator.js +0 -275
- package/dist/libs/instance-factories/views/templates/react/frontend-package-json-generator.js +0 -46
- package/dist/libs/instance-factories/views/templates/react/hooks-generator.js +0 -81
- package/dist/libs/instance-factories/views/templates/react/index-css-generator.js +0 -9
- package/dist/libs/instance-factories/views/templates/react/index-html-generator.js +0 -23
- package/dist/libs/instance-factories/views/templates/react/main-tsx-generator.js +0 -21
- package/dist/libs/instance-factories/views/templates/react/react-component-generator.js +0 -299
- package/dist/libs/instance-factories/views/templates/react/router-generator.js +0 -136
- package/dist/libs/instance-factories/views/templates/react/router-generic-generator.js +0 -107
- package/dist/libs/instance-factories/views/templates/react/shared-utils-generator.js +0 -187
- package/dist/libs/instance-factories/views/templates/react/spec-json-generator.js +0 -7
- package/dist/libs/instance-factories/views/templates/react/types-generator.js +0 -56
- package/dist/libs/instance-factories/views/templates/react/views-metadata-generator.js +0 -27
- package/dist/libs/instance-factories/views/templates/react/vite-config-generator.js +0 -29
- package/dist/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js +0 -261
- package/dist/libs/instance-factories/views/templates/shared/adapter-types.js +0 -34
- package/dist/libs/instance-factories/views/templates/shared/atomic-components-registry.js +0 -800
- package/dist/libs/instance-factories/views/templates/shared/base-generator.js +0 -305
- package/dist/libs/instance-factories/views/templates/shared/component-metadata.js +0 -517
- package/dist/libs/instance-factories/views/templates/shared/composite-pattern-types.js +0 -0
- package/dist/libs/instance-factories/views/templates/shared/composite-patterns.js +0 -445
- package/dist/libs/instance-factories/views/templates/shared/index.js +0 -80
- package/dist/libs/instance-factories/views/templates/shared/pattern-validator.js +0 -210
- package/dist/libs/instance-factories/views/templates/shared/property-mapper.js +0 -492
- package/dist/libs/instance-factories/views/templates/shared/syntax-mapper.js +0 -321
- package/dist/realize/index.js.bak +0 -758
- package/libs/instance-factories/applications/react-app.yaml +0 -186
- package/libs/instance-factories/applications/templates/react/_view-components-source.ts +0 -555
- package/libs/instance-factories/applications/templates/react/app-tsx-generator.ts +0 -94
- package/libs/instance-factories/applications/templates/react/field-helpers-generator.ts +0 -106
- package/libs/instance-factories/applications/templates/react/package-json-generator.ts +0 -57
- package/libs/instance-factories/applications/templates/react/pattern-adapter-generator.ts +0 -179
- package/libs/instance-factories/applications/templates/react/react-pattern-adapter.tsx +0 -1347
- package/libs/instance-factories/applications/templates/react/relationship-field-generator.ts +0 -150
- package/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.ts +0 -704
- package/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.ts +0 -84
- package/libs/instance-factories/applications/templates/react/view-dashboard-generator.ts +0 -150
- package/libs/instance-factories/applications/templates/react/view-detail-generator.ts +0 -150
- package/libs/instance-factories/applications/templates/react/view-form-generator.ts +0 -362
- package/libs/instance-factories/applications/templates/react/view-list-generator.ts +0 -98
- package/libs/instance-factories/applications/templates/react/view-router-generator.ts +0 -89
- package/libs/instance-factories/views/README.md +0 -62
- package/libs/instance-factories/views/index.d.ts +0 -13
- package/libs/instance-factories/views/index.d.ts.map +0 -1
- package/libs/instance-factories/views/index.js +0 -18
- package/libs/instance-factories/views/index.js.map +0 -1
- package/libs/instance-factories/views/index.ts +0 -45
- package/libs/instance-factories/views/react-components.yaml +0 -129
- package/libs/instance-factories/views/templates/ARCHITECTURE.md +0 -198
- package/libs/instance-factories/views/templates/react/adapters/antd-adapter.ts +0 -869
- package/libs/instance-factories/views/templates/react/adapters/mui-adapter.ts +0 -953
- package/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.ts +0 -806
- package/libs/instance-factories/views/templates/react/app-generator.ts +0 -55
- package/libs/instance-factories/views/templates/react/components-generator.ts +0 -938
- package/libs/instance-factories/views/templates/react/forms-generator.ts +0 -325
- package/libs/instance-factories/views/templates/react/frontend-package-json-generator.ts +0 -57
- package/libs/instance-factories/views/templates/react/hooks-generator.ts +0 -106
- package/libs/instance-factories/views/templates/react/index-css-generator.ts +0 -14
- package/libs/instance-factories/views/templates/react/index-html-generator.ts +0 -34
- package/libs/instance-factories/views/templates/react/main-tsx-generator.ts +0 -29
- package/libs/instance-factories/views/templates/react/react-component-generator.d.ts +0 -152
- package/libs/instance-factories/views/templates/react/react-component-generator.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/react/react-component-generator.js +0 -398
- package/libs/instance-factories/views/templates/react/react-component-generator.js.map +0 -1
- package/libs/instance-factories/views/templates/react/react-component-generator.ts +0 -533
- package/libs/instance-factories/views/templates/react/router-generator.ts +0 -197
- package/libs/instance-factories/views/templates/react/router-generic-generator.ts +0 -132
- package/libs/instance-factories/views/templates/react/shared-utils-generator.ts +0 -196
- package/libs/instance-factories/views/templates/react/spec-json-generator.ts +0 -17
- package/libs/instance-factories/views/templates/react/types-generator.ts +0 -76
- package/libs/instance-factories/views/templates/react/views-metadata-generator.ts +0 -42
- package/libs/instance-factories/views/templates/react/vite-config-generator.ts +0 -38
- package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js.map +0 -1
- package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.ts +0 -474
- package/libs/instance-factories/views/templates/shared/__tests__/composite-patterns.test.ts +0 -242
- package/libs/instance-factories/views/templates/shared/adapter-types.d.ts +0 -77
- package/libs/instance-factories/views/templates/shared/adapter-types.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/shared/adapter-types.js +0 -47
- package/libs/instance-factories/views/templates/shared/adapter-types.js.map +0 -1
- package/libs/instance-factories/views/templates/shared/adapter-types.ts +0 -142
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts +0 -63
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.js +0 -822
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.js.map +0 -1
- package/libs/instance-factories/views/templates/shared/atomic-components-registry.ts +0 -908
- package/libs/instance-factories/views/templates/shared/base-generator.d.ts +0 -247
- package/libs/instance-factories/views/templates/shared/base-generator.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/shared/base-generator.js +0 -363
- package/libs/instance-factories/views/templates/shared/base-generator.js.map +0 -1
- package/libs/instance-factories/views/templates/shared/base-generator.ts +0 -608
- package/libs/instance-factories/views/templates/shared/component-metadata.d.ts +0 -254
- package/libs/instance-factories/views/templates/shared/component-metadata.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/shared/component-metadata.js +0 -602
- package/libs/instance-factories/views/templates/shared/component-metadata.js.map +0 -1
- package/libs/instance-factories/views/templates/shared/component-metadata.ts +0 -803
- package/libs/instance-factories/views/templates/shared/composite-pattern-types.ts +0 -250
- package/libs/instance-factories/views/templates/shared/composite-patterns.ts +0 -535
- package/libs/instance-factories/views/templates/shared/index.ts +0 -68
- package/libs/instance-factories/views/templates/shared/pattern-validator.ts +0 -279
- package/libs/instance-factories/views/templates/shared/property-mapper.d.ts +0 -149
- package/libs/instance-factories/views/templates/shared/property-mapper.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/shared/property-mapper.js +0 -580
- package/libs/instance-factories/views/templates/shared/property-mapper.js.map +0 -1
- package/libs/instance-factories/views/templates/shared/property-mapper.ts +0 -700
- package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts +0 -143
- package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts.map +0 -1
- package/libs/instance-factories/views/templates/shared/syntax-mapper.js +0 -420
- package/libs/instance-factories/views/templates/shared/syntax-mapper.js.map +0 -1
- package/libs/instance-factories/views/templates/shared/syntax-mapper.ts +0 -539
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View files generator for ReactAppStarter
|
|
3
|
+
*
|
|
4
|
+
* Called by the realize engine. Iterates over the expanded spec's
|
|
5
|
+
* models × view types, dispatches to the right composer, and returns
|
|
6
|
+
* a filename → source map. Realize writes each file.
|
|
7
|
+
*
|
|
8
|
+
* Also emits the local helpers library (src/lib/entity-display.ts)
|
|
9
|
+
* so generated projects have zero @specverse/runtime runtime deps.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { emitView, type EmitContext, type ModelSpec, type ViewSpec, type RenderBodyFn } from './view-emitter.js';
|
|
13
|
+
import { composeListBody } from './list-body-composer.js';
|
|
14
|
+
import { composeDetailBody } from './detail-body-composer.js';
|
|
15
|
+
import { composeFormBody } from './form-body-composer.js';
|
|
16
|
+
import { composeDashboardBody } from './dashboard-body-composer.js';
|
|
17
|
+
import { emitEntityDisplay } from './helpers-emitter.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The four primary view types Factory B currently emits. Specialist
|
|
21
|
+
* types (board, timeline, calendar, etc.) are not yet implemented —
|
|
22
|
+
* if the expanded spec declares one, we skip it and log a TODO.
|
|
23
|
+
* These users can add composers under Phase 2e.
|
|
24
|
+
*/
|
|
25
|
+
const PRIMARY_VIEW_TYPES = ['list', 'detail', 'form', 'dashboard'] as const;
|
|
26
|
+
type PrimaryViewType = typeof PRIMARY_VIEW_TYPES[number];
|
|
27
|
+
|
|
28
|
+
const COMPOSER_BY_TYPE: Record<PrimaryViewType, RenderBodyFn> = {
|
|
29
|
+
list: composeListBody,
|
|
30
|
+
detail: composeDetailBody,
|
|
31
|
+
form: composeFormBody,
|
|
32
|
+
dashboard: composeDashboardBody,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Generator contract — the shape realize expects. */
|
|
36
|
+
export interface ViewsGeneratorContext {
|
|
37
|
+
/** The expanded spec (post-inference). */
|
|
38
|
+
spec: ExpandedSpec;
|
|
39
|
+
/** The resolved manifest configuration. Not currently read by this
|
|
40
|
+
* generator but passed by realize for parity with other generators. */
|
|
41
|
+
manifest?: unknown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ExpandedSpec {
|
|
45
|
+
/** Models keyed by name. */
|
|
46
|
+
models?: Record<string, ModelSpec>;
|
|
47
|
+
/** Views keyed by view name (e.g. "PostListView"). */
|
|
48
|
+
views?: Record<string, ViewSpec & { type: string; model?: string }>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface GeneratedFiles {
|
|
52
|
+
[relativePath: string]: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Generate all view files + local helpers.
|
|
57
|
+
*
|
|
58
|
+
* Paths are RELATIVE to the frontend root (`frontendDir` in the
|
|
59
|
+
* manifest). Realize prepends the absolute output path when writing.
|
|
60
|
+
*/
|
|
61
|
+
export async function generate(context: ViewsGeneratorContext): Promise<GeneratedFiles> {
|
|
62
|
+
const files: GeneratedFiles = {};
|
|
63
|
+
const spec = context.spec;
|
|
64
|
+
const models = spec.models ?? {};
|
|
65
|
+
const viewsBySpec = spec.views ?? {};
|
|
66
|
+
|
|
67
|
+
// Group the spec's views by model+type so we can decide, for each
|
|
68
|
+
// (model, type) pair, whether to use the user's view spec or emit
|
|
69
|
+
// a default.
|
|
70
|
+
const viewIndex = indexViews(viewsBySpec);
|
|
71
|
+
const skippedSpecialists: string[] = [];
|
|
72
|
+
|
|
73
|
+
for (const [modelName, model] of Object.entries(models)) {
|
|
74
|
+
for (const viewType of PRIMARY_VIEW_TYPES) {
|
|
75
|
+
const viewName = `${modelName}${capitalize(viewType)}View`;
|
|
76
|
+
// Prefer a user-defined view of that shape if one exists; fall
|
|
77
|
+
// back to a synthesized default.
|
|
78
|
+
const view = viewIndex.get(viewName) ?? synthesizeDefault(modelName, viewType);
|
|
79
|
+
const source = emitView({
|
|
80
|
+
view,
|
|
81
|
+
viewName,
|
|
82
|
+
model,
|
|
83
|
+
modelSchemas: models,
|
|
84
|
+
renderBody: COMPOSER_BY_TYPE[viewType],
|
|
85
|
+
});
|
|
86
|
+
files[`src/views/${viewName}.tsx`] = source;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Surface any specialist-type views the user declared but we can't
|
|
91
|
+
// emit yet. The runtime (ReactAppRuntime) handles these; in starter
|
|
92
|
+
// kit mode the user has to write them manually for now.
|
|
93
|
+
for (const [name, view] of Object.entries(viewsBySpec)) {
|
|
94
|
+
if (!PRIMARY_VIEW_TYPES.includes(view.type as PrimaryViewType)) {
|
|
95
|
+
skippedSpecialists.push(`${name} (type=${view.type})`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (skippedSpecialists.length > 0) {
|
|
99
|
+
console.warn(
|
|
100
|
+
`[ReactAppStarter] Skipped ${skippedSpecialists.length} specialist view(s) — ` +
|
|
101
|
+
`implement composers for: ${[...new Set(Object.values(viewsBySpec)
|
|
102
|
+
.filter(v => !PRIMARY_VIEW_TYPES.includes(v.type as PrimaryViewType))
|
|
103
|
+
.map(v => v.type))].join(', ')}. ` +
|
|
104
|
+
`Skipped: ${skippedSpecialists.join(', ')}`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Local helpers
|
|
109
|
+
files['src/lib/entity-display.ts'] = emitEntityDisplay();
|
|
110
|
+
|
|
111
|
+
return files;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
115
|
+
// Helpers
|
|
116
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
function indexViews(
|
|
119
|
+
views: Record<string, ViewSpec & { type: string; model?: string }>
|
|
120
|
+
): Map<string, ViewSpec & { type: string; model?: string }> {
|
|
121
|
+
const out = new Map<string, ViewSpec & { type: string; model?: string }>();
|
|
122
|
+
for (const [name, view] of Object.entries(views)) {
|
|
123
|
+
out.set(name, view);
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function synthesizeDefault(modelName: string, viewType: PrimaryViewType): ViewSpec {
|
|
129
|
+
return {
|
|
130
|
+
type: viewType,
|
|
131
|
+
model: modelName,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function capitalize(s: string): string {
|
|
136
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
137
|
+
}
|
|
@@ -393,22 +393,25 @@ import type { ParserEngine, InferenceEngine, RealizeEngine } from '@specverse/ty
|
|
|
393
393
|
process.exit(1);
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
//
|
|
396
|
+
// --static ejects to a standalone starter kit (ReactAppStarter).
|
|
397
|
+
// Default: whatever the manifest declares (ReactAppRuntime in the
|
|
398
|
+
// shipped templates). The swap is a convenience only — users can
|
|
399
|
+
// achieve the same by editing their manifest directly.
|
|
397
400
|
let effectiveManifestPath = manifestPath;
|
|
398
|
-
if (
|
|
401
|
+
if (options.static) {
|
|
399
402
|
const manifestContent = readFileSync(manifestPath, 'utf8');
|
|
400
|
-
if (/instanceFactory:\\s*["']?
|
|
403
|
+
if (/instanceFactory:\\s*["']?ReactAppRuntime["']?\\s*$/m.test(manifestContent)) {
|
|
401
404
|
const { tmpdir } = await import('os');
|
|
402
|
-
const
|
|
403
|
-
/instanceFactory:\\s*["']?
|
|
404
|
-
'instanceFactory: "
|
|
405
|
+
const staticManifest = manifestContent.replace(
|
|
406
|
+
/instanceFactory:\\s*["']?ReactAppRuntime["']?\\s*$/gm,
|
|
407
|
+
'instanceFactory: "ReactAppStarter"'
|
|
405
408
|
);
|
|
406
|
-
effectiveManifestPath = join(tmpdir(), 'specverse-
|
|
407
|
-
writeFileSync(effectiveManifestPath,
|
|
408
|
-
console.log(' Using
|
|
409
|
+
effectiveManifestPath = join(tmpdir(), 'specverse-static-manifest.yaml');
|
|
410
|
+
writeFileSync(effectiveManifestPath, staticManifest, 'utf8');
|
|
411
|
+
console.log(' Using static mode (standalone starter kit — ReactAppStarter)');
|
|
412
|
+
} else {
|
|
413
|
+
console.log(' Using static mode (manifest factory unchanged)');
|
|
409
414
|
}
|
|
410
|
-
} else {
|
|
411
|
-
console.log(' Using static mode (full frontend generation)');
|
|
412
415
|
}
|
|
413
416
|
|
|
414
417
|
const realizeEngine = registry.getEngineForCapability('realize') as RealizeEngine;
|
|
@@ -82,8 +82,11 @@ fastify.get('/api/runtime/info', async () => ({
|
|
|
82
82
|
services: ${JSON.stringify(servicesList)}
|
|
83
83
|
}));
|
|
84
84
|
|
|
85
|
-
${hasEvents ? `// Event history endpoint
|
|
86
|
-
|
|
85
|
+
${hasEvents ? `// Event history endpoint — runtime introspection, not part of
|
|
86
|
+
// the user's API surface. Lives under /api/runtime/ so it doesn't
|
|
87
|
+
// collide with the auto-generated Event model route (spec models
|
|
88
|
+
// named "Event" produce a GET /api/events of their own).
|
|
89
|
+
fastify.get('/api/runtime/events', async () => eventBus.getHistory());` : ''}
|
|
87
90
|
|
|
88
91
|
// Register routes
|
|
89
92
|
${routeImports}
|
|
@@ -102,7 +105,12 @@ const start = async () => {
|
|
|
102
105
|
${hasEvents ? ` // Register WebSocket bridge for real-time frontend events
|
|
103
106
|
await registerWebSocketBridge(fastify);` : ''}
|
|
104
107
|
const port = parseInt(process.env.PORT || '3000');
|
|
105
|
-
|
|
108
|
+
// Listen on :: (IPv6 wildcard) instead of 0.0.0.0 so the server
|
|
109
|
+
// accepts both IPv6 and IPv4-mapped connections. Node resolves
|
|
110
|
+
// 'localhost' to ::1 first; if the backend only binds IPv4, the
|
|
111
|
+
// vite dev-server WS proxy hits ECONNREFUSED on ::1 and doesn't
|
|
112
|
+
// fall back to 127.0.0.1 cleanly. Binding :: fixes both cases.
|
|
113
|
+
await fastify.listen({ port, host: '::' });
|
|
106
114
|
console.log(\`Server running at http://localhost:\${port}\`);
|
|
107
115
|
console.log(\`API endpoints: ${modelNames.map((n: string) => `/api/${n.toLowerCase()}s`).join(', ')}\`);
|
|
108
116
|
${hasEvents ? ` console.log(\`WebSocket: ws://localhost:\${port}/ws\`);
|
|
@@ -282,39 +282,49 @@ function generateEvolveMethod(model: any, modelName: string, modelVar: string, p
|
|
|
282
282
|
|
|
283
283
|
return `
|
|
284
284
|
/**
|
|
285
|
-
* Evolve ${modelName} through lifecycle
|
|
285
|
+
* Evolve ${modelName} through lifecycle "${lifecycleName}"
|
|
286
286
|
* States: ${states.join(' → ')}
|
|
287
|
+
*
|
|
288
|
+
* Accepts either the client shape { toState, lifecycleName? } or
|
|
289
|
+
* the direct column shape { ${lifecycleName}: ... }. The frontend
|
|
290
|
+
* runtime's useTransitionStateMutation always sends the former; the
|
|
291
|
+
* realized smoke-parity script can send either.
|
|
287
292
|
*/
|
|
288
293
|
public async evolve(id: string, data: any): Promise<any> {
|
|
289
|
-
// Validate input
|
|
290
|
-
const validationResult = this.validate(data, { operation: 'evolve' });
|
|
291
|
-
if (!validationResult.valid) {
|
|
292
|
-
throw new Error(\`Validation failed: \${validationResult.errors.join(', ')}\`);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
294
|
// Get current record to check lifecycle state
|
|
296
295
|
const current = await ${prismaDelegate}.findUnique({ where: { id: parseId(id) } });
|
|
297
296
|
if (!current) {
|
|
298
297
|
throw new Error('${modelName} not found');
|
|
299
298
|
}
|
|
300
299
|
|
|
300
|
+
// Normalize input: translate client { toState: X } shape to the
|
|
301
|
+
// lifecycle's actual column name. If the caller already sent the
|
|
302
|
+
// column directly, keep whatever they sent.
|
|
303
|
+
const targetLifecycle = data?.lifecycleName || '${lifecycleName}';
|
|
304
|
+
const targetState = data?.toState ?? data?.state ?? data?.[targetLifecycle];
|
|
305
|
+
if (!targetState) {
|
|
306
|
+
throw new Error('evolve requires toState (or ${lifecycleName}) in the request body');
|
|
307
|
+
}
|
|
308
|
+
|
|
301
309
|
${states.length > 0 ? `
|
|
302
|
-
// Validate lifecycle transition
|
|
303
|
-
const currentState = (current as any)
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (!allowed.includes(newState)) {
|
|
309
|
-
throw new Error(\`Invalid transition: \${currentState} → \${newState}. Allowed: \${allowed.join(', ') || 'none'}\`);
|
|
310
|
-
}
|
|
310
|
+
// Validate lifecycle transition against declared flow
|
|
311
|
+
const currentState = (current as any)[targetLifecycle];
|
|
312
|
+
const validTransitions: Record<string, string[]> = ${JSON.stringify(validTransitions)};
|
|
313
|
+
const allowed = validTransitions[currentState] || [];
|
|
314
|
+
if (!allowed.includes(targetState)) {
|
|
315
|
+
throw new Error(\`Invalid transition: \${currentState} → \${targetState}. Allowed: \${allowed.join(', ') || 'none'}\`);
|
|
311
316
|
}
|
|
312
317
|
` : ''}
|
|
313
318
|
|
|
319
|
+
// Build the Prisma update payload — only the lifecycle column
|
|
320
|
+
// changes. Strips toState/lifecycleName/state so Prisma doesn't
|
|
321
|
+
// reject unknown fields.
|
|
322
|
+
const updateData: any = { [targetLifecycle]: targetState };
|
|
323
|
+
|
|
314
324
|
// Update record
|
|
315
325
|
const ${modelVar} = await ${prismaDelegate}.update({
|
|
316
326
|
where: { id: parseId(id) },
|
|
317
|
-
data${generateIncludeRelationships(model)}
|
|
327
|
+
data: updateData${generateIncludeRelationships(model)}
|
|
318
328
|
});
|
|
319
329
|
|
|
320
330
|
// Publish CURED event
|
|
@@ -93,9 +93,15 @@ export function getApiBaseUrl(config: PathResolverConfig & { apiBaseUrl?: string
|
|
|
93
93
|
return '${VITE_API_BASE_URL}'; // Environment variable placeholder
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
// In monorepo mode, default to local backend
|
|
96
|
+
// In monorepo mode, default to local backend.
|
|
97
|
+
// Use explicit 127.0.0.1 (not `localhost`) to avoid Node's
|
|
98
|
+
// happy-eyeballs IPv6→IPv4 fallback. The vite dev-server WS proxy
|
|
99
|
+
// doesn't handle that fallback for WebSocket upgrades — it would
|
|
100
|
+
// try `[::1]:3000`, get ECONNREFUSED if the backend isn't on IPv6,
|
|
101
|
+
// and log the error instead of retrying on 127.0.0.1. Pinning
|
|
102
|
+
// 127.0.0.1 in the proxy target sidesteps that entirely.
|
|
97
103
|
const port = (config as any).serverPort || 3000;
|
|
98
|
-
return `http://
|
|
104
|
+
return `http://127.0.0.1:${port}`;
|
|
99
105
|
}
|
|
100
106
|
|
|
101
107
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specverse/engines",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "SpecVerse toolchain
|
|
3
|
+
"version": "4.2.0",
|
|
4
|
+
"description": "SpecVerse toolchain — parser, inference, realize, generators, AI, registry",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
"access": "public"
|
|
66
66
|
},
|
|
67
67
|
"license": "MIT"
|
|
68
|
-
}
|
|
68
|
+
}
|