@specverse/engines 6.33.0 → 6.34.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/dist/libs/instance-factories/communication/rabbitmq-events.yaml +11 -0
- package/dist/libs/instance-factories/controllers/fastify.yaml +11 -0
- package/dist/libs/instance-factories/managed/stripe-rest-sdk.yaml +78 -0
- package/dist/libs/instance-factories/managed/templates/stripe/stripe-client-generator.js +8 -0
- package/dist/libs/instance-factories/orms/prisma.yaml +11 -0
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +261 -4
- package/dist/realize/index.js.map +1 -1
- package/dist/realize/library/loader.d.ts.map +1 -1
- package/dist/realize/library/loader.js +81 -1
- package/dist/realize/library/loader.js.map +1 -1
- package/dist/realize/per-action-emitter.d.ts +9 -0
- package/dist/realize/per-action-emitter.d.ts.map +1 -1
- package/dist/realize/per-action-emitter.js.map +1 -1
- package/dist/realize/per-action-llm-emit.d.ts.map +1 -1
- package/dist/realize/per-action-llm-emit.js +5 -1
- package/dist/realize/per-action-llm-emit.js.map +1 -1
- package/dist/realize/per-action-runner.d.ts +45 -0
- package/dist/realize/per-action-runner.d.ts.map +1 -1
- package/dist/realize/per-action-runner.js +132 -0
- package/dist/realize/per-action-runner.js.map +1 -1
- package/dist/realize/resolver/index.d.ts +157 -0
- package/dist/realize/resolver/index.d.ts.map +1 -0
- package/dist/realize/resolver/index.js +307 -0
- package/dist/realize/resolver/index.js.map +1 -0
- package/dist/realize/runtime-emitters/dispatcher.d.ts +176 -0
- package/dist/realize/runtime-emitters/dispatcher.d.ts.map +1 -0
- package/dist/realize/runtime-emitters/dispatcher.js +76 -0
- package/dist/realize/runtime-emitters/dispatcher.js.map +1 -0
- package/dist/realize/runtime-emitters/executable.d.ts +57 -0
- package/dist/realize/runtime-emitters/executable.d.ts.map +1 -0
- package/dist/realize/runtime-emitters/executable.js +316 -0
- package/dist/realize/runtime-emitters/executable.js.map +1 -0
- package/dist/realize/runtime-emitters/library.d.ts +52 -0
- package/dist/realize/runtime-emitters/library.d.ts.map +1 -0
- package/dist/realize/runtime-emitters/library.js +349 -0
- package/dist/realize/runtime-emitters/library.js.map +1 -0
- package/dist/realize/runtime-emitters/managed.d.ts +44 -0
- package/dist/realize/runtime-emitters/managed.d.ts.map +1 -0
- package/dist/realize/runtime-emitters/managed.js +283 -0
- package/dist/realize/runtime-emitters/managed.js.map +1 -0
- package/dist/realize/runtime-emitters/messaging.d.ts +77 -0
- package/dist/realize/runtime-emitters/messaging.d.ts.map +1 -0
- package/dist/realize/runtime-emitters/messaging.js +423 -0
- package/dist/realize/runtime-emitters/messaging.js.map +1 -0
- package/dist/realize/runtime-emitters/service.d.ts +42 -0
- package/dist/realize/runtime-emitters/service.d.ts.map +1 -0
- package/dist/realize/runtime-emitters/service.js +355 -0
- package/dist/realize/runtime-emitters/service.js.map +1 -0
- package/dist/realize/types/instance-factory.d.ts +1 -1
- package/dist/realize/types/instance-factory.d.ts.map +1 -1
- package/libs/instance-factories/communication/rabbitmq-events.yaml +11 -0
- package/libs/instance-factories/controllers/fastify.yaml +11 -0
- package/libs/instance-factories/managed/stripe-rest-sdk.yaml +78 -0
- package/libs/instance-factories/managed/templates/stripe/stripe-client-generator.ts +26 -0
- package/libs/instance-factories/orms/prisma.yaml +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/realize/resolver/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-runtime emitter dispatcher — V2 Phase 3, Round 1.
|
|
3
|
+
*
|
|
4
|
+
* Proposal: 2026-05-08-COMPONENT-DEPENDENCIES-V2.md, "Realize bridge" section.
|
|
5
|
+
*
|
|
6
|
+
* The dispatcher is a small registry + lookup framework. The real work lives in
|
|
7
|
+
* each topology-specific emitter implementation (library.ts, and future
|
|
8
|
+
* service.ts / managed.ts / executable.ts / messaging.ts files).
|
|
9
|
+
*
|
|
10
|
+
* Round 1 ships: dispatcher framework + library topology emitter (this file +
|
|
11
|
+
* library.ts). The two cross-branch types — `ResolvedComponent` (Agent A) and
|
|
12
|
+
* `FactoryV2Metadata` / `InstanceFactory` (Agent B) — are imported from their
|
|
13
|
+
* canonical locations: Round 1d (this commit) reconciled the local stubs with
|
|
14
|
+
* the merged real types.
|
|
15
|
+
*
|
|
16
|
+
* Round 2 will add: service, managed, executable, messaging emitters + CLI wiring.
|
|
17
|
+
*/
|
|
18
|
+
import type { ComponentSpec, SpecVerseAST, InstanceFactory, FactoryTopology } from '@specverse/types';
|
|
19
|
+
import type { ResolvedComponent } from '../resolver/index.js';
|
|
20
|
+
export type { ResolvedComponent } from '../resolver/index.js';
|
|
21
|
+
export type { FactoryTopology, InstanceFactory } from '@specverse/types';
|
|
22
|
+
/** Alias kept for back-compat with the Round-1 stub naming. */
|
|
23
|
+
export type FactoryMetadata = InstanceFactory;
|
|
24
|
+
/**
|
|
25
|
+
* A single entry in a component's `import:` block.
|
|
26
|
+
* Mirrors the V2 Phase 1 schema additions (commit bb4b99b):
|
|
27
|
+
* - from: provider name (resolved via 4-step lookup)
|
|
28
|
+
* - version?: semver range (optional, defaults to ^latest)
|
|
29
|
+
* - select: array of bare or dotted operation names
|
|
30
|
+
*/
|
|
31
|
+
export interface ImportEntry {
|
|
32
|
+
from: string;
|
|
33
|
+
version?: string;
|
|
34
|
+
select: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Context passed to every runtime emitter.
|
|
38
|
+
* Carries the consumer-side view (component + import entry) alongside
|
|
39
|
+
* the resolved provider (Agent A) and the factory metadata (Agent B).
|
|
40
|
+
*/
|
|
41
|
+
export interface RuntimeEmitterContext {
|
|
42
|
+
/** The component that contains the `import:` block. */
|
|
43
|
+
consumerComponent: ComponentSpec;
|
|
44
|
+
/** The specific {from, version?, select} entry being emitted. */
|
|
45
|
+
importEntry: ImportEntry;
|
|
46
|
+
/**
|
|
47
|
+
* Resolver result for this import entry.
|
|
48
|
+
* Round 1 stub: callers construct this manually; Agent A's resolver will
|
|
49
|
+
* produce it automatically when integrated in Round 2.
|
|
50
|
+
*/
|
|
51
|
+
resolved: ResolvedComponent;
|
|
52
|
+
/**
|
|
53
|
+
* Factory metadata from the manifest's capabilityMappings.
|
|
54
|
+
* Round 1 stub: callers construct this manually; Agent B's schema +
|
|
55
|
+
* the registry-aware manifest-emitter will produce it when integrated.
|
|
56
|
+
*/
|
|
57
|
+
factory: FactoryMetadata;
|
|
58
|
+
/**
|
|
59
|
+
* Absolute path to the consumer component's realize output directory.
|
|
60
|
+
* Generated clients land at `<outputDir>/clients/<provider-name>.ts`.
|
|
61
|
+
*/
|
|
62
|
+
outputDir: string;
|
|
63
|
+
/**
|
|
64
|
+
* The full parsed spec, for cross-component type lookups.
|
|
65
|
+
* Optional in Round 1 — the library emitter doesn't need cross-spec
|
|
66
|
+
* lookups yet; future emitters may need it for server-bind code.
|
|
67
|
+
*/
|
|
68
|
+
spec?: SpecVerseAST;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Structured deployment-instance suggestion an emitter produces alongside
|
|
72
|
+
* its files/imports. The realize pipeline collects every emitter's
|
|
73
|
+
* suggestions into `<outputDir>/v2-deployment-suggestions.yaml` (V2 P3
|
|
74
|
+
* Round 3 follow-up), which the user merges into their deployment block
|
|
75
|
+
* manually. Auto-merge isn't safe — deployment shape is user-controlled
|
|
76
|
+
* (env-specific values, secrets, scaling parameters).
|
|
77
|
+
*
|
|
78
|
+
* Library-topology emitters do NOT produce suggestions (libraries are
|
|
79
|
+
* in-process imports, not deployment instances).
|
|
80
|
+
*/
|
|
81
|
+
export interface DeploymentInstanceSuggestion {
|
|
82
|
+
/** Provider name (importEntry.from) — anchors the suggestion to its import. */
|
|
83
|
+
provider: string;
|
|
84
|
+
/** Component that declared the import — for cross-checking which
|
|
85
|
+
* deployment-instance scope the suggestion belongs to. */
|
|
86
|
+
consumerComponent?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Which deployment-instance category this provider lands in. Mirrors
|
|
89
|
+
* the schema's InstancesSection keys (services, communications,
|
|
90
|
+
* infrastructure, …). Out-of-band categories should not be used.
|
|
91
|
+
*/
|
|
92
|
+
category: 'services' | 'communications' | 'infrastructure' | 'storage' | 'security' | 'monitoring';
|
|
93
|
+
/** Instance key under the category (lower-camelCase client name). */
|
|
94
|
+
key: string;
|
|
95
|
+
/** Pre-built config block — placeholder values use `<...>` markers. */
|
|
96
|
+
config: Record<string, unknown>;
|
|
97
|
+
/** Factory name driving the choice (manifest.capabilityMappings). */
|
|
98
|
+
factory: string;
|
|
99
|
+
/** Topology that emitted this suggestion. */
|
|
100
|
+
topology: FactoryTopology;
|
|
101
|
+
/** Optional review-time hints (TODOs, OAuth flows, etc.). */
|
|
102
|
+
reviewNotes?: string[];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* What a runtime emitter produces.
|
|
106
|
+
*/
|
|
107
|
+
export interface RuntimeEmitterResult {
|
|
108
|
+
/**
|
|
109
|
+
* Files to write into the consumer's output directory.
|
|
110
|
+
* Paths are relative to `outputDir`.
|
|
111
|
+
*/
|
|
112
|
+
files: Array<{
|
|
113
|
+
path: string;
|
|
114
|
+
content: string;
|
|
115
|
+
}>;
|
|
116
|
+
/**
|
|
117
|
+
* Import statements the consumer's main module (SalesReportController.ts)
|
|
118
|
+
* should add to wire up the generated client.
|
|
119
|
+
*/
|
|
120
|
+
imports: Array<{
|
|
121
|
+
from: string;
|
|
122
|
+
specifier: string;
|
|
123
|
+
}>;
|
|
124
|
+
/**
|
|
125
|
+
* Optional realize-time hints or warnings.
|
|
126
|
+
*/
|
|
127
|
+
notes?: string[];
|
|
128
|
+
/**
|
|
129
|
+
* V2 P3 R3 follow-up: structured deployment-instance suggestion. The
|
|
130
|
+
* free-text equivalent is in `notes` for human review; this field is
|
|
131
|
+
* the machine-readable version that the realize pipeline aggregates
|
|
132
|
+
* into v2-deployment-suggestions.yaml. Library-topology emissions
|
|
133
|
+
* omit this field.
|
|
134
|
+
*/
|
|
135
|
+
deploymentSuggestion?: DeploymentInstanceSuggestion;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Contract every topology-specific emitter must satisfy.
|
|
139
|
+
*/
|
|
140
|
+
export interface RuntimeEmitter {
|
|
141
|
+
/** The topology this emitter handles. Drives dispatch lookup. */
|
|
142
|
+
topology: FactoryTopology;
|
|
143
|
+
/** Emit files for one import entry. */
|
|
144
|
+
emit(ctx: RuntimeEmitterContext): Promise<RuntimeEmitterResult>;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Look up the correct emitter for the factory's topology.
|
|
148
|
+
*
|
|
149
|
+
* The emitters map is injected by the caller, making the dispatcher
|
|
150
|
+
* extensible without engine changes: register new emitters by adding
|
|
151
|
+
* entries to the map.
|
|
152
|
+
*
|
|
153
|
+
* @param factory - The resolved factory metadata (drives the topology lookup).
|
|
154
|
+
* @param emitters - Registry of topology → RuntimeEmitter. Typically built
|
|
155
|
+
* once per realize run by `buildDefaultEmitters()`.
|
|
156
|
+
* @returns The matching RuntimeEmitter.
|
|
157
|
+
* @throws Error if no emitter is registered for the factory's topology.
|
|
158
|
+
*/
|
|
159
|
+
export declare function dispatchRuntimeEmitter(factory: FactoryMetadata, emitters: Map<string, RuntimeEmitter>): RuntimeEmitter;
|
|
160
|
+
/**
|
|
161
|
+
* Build the default emitter registry for a realize run.
|
|
162
|
+
*
|
|
163
|
+
* Round 1 shipped library; Round 2 added service / managed / executable /
|
|
164
|
+
* messaging. All 5 are registered here so the realize-side dispatcher can
|
|
165
|
+
* pick whichever the factory's v2metadata.topology selects.
|
|
166
|
+
*
|
|
167
|
+
* The 'external' topology is intentionally NOT registered — V2's design
|
|
168
|
+
* defines it as a passthrough requiring manual wiring (no auto-emission).
|
|
169
|
+
* Specs that bind a factory with topology: 'external' will trip a clear
|
|
170
|
+
* "No runtime emitter registered" error, which is the desired behavior.
|
|
171
|
+
*
|
|
172
|
+
* Imports are deferred to avoid circular deps — each emitter file imports
|
|
173
|
+
* only from dispatcher.ts, not vice versa.
|
|
174
|
+
*/
|
|
175
|
+
export declare function buildDefaultEmitters(): Promise<Map<string, RuntimeEmitter>>;
|
|
176
|
+
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEzE,+DAA+D;AAC/D,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC;AAI9C;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,iBAAiB,EAAE,aAAa,CAAC;IACjC,iEAAiE;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB;;;;OAIG;IACH,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,4BAA4B;IAC3C,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB;+DAC2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,EAAE,UAAU,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC;IACnG,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,QAAQ,EAAE,eAAe,CAAC;IAC1B,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD;;;OAGG;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,4BAA4B,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,EAAE,eAAe,CAAC;IAC1B,uCAAuC;IACvC,IAAI,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACjE;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,cAAc,CAchB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAsBjF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-runtime emitter dispatcher — V2 Phase 3, Round 1.
|
|
3
|
+
*
|
|
4
|
+
* Proposal: 2026-05-08-COMPONENT-DEPENDENCIES-V2.md, "Realize bridge" section.
|
|
5
|
+
*
|
|
6
|
+
* The dispatcher is a small registry + lookup framework. The real work lives in
|
|
7
|
+
* each topology-specific emitter implementation (library.ts, and future
|
|
8
|
+
* service.ts / managed.ts / executable.ts / messaging.ts files).
|
|
9
|
+
*
|
|
10
|
+
* Round 1 ships: dispatcher framework + library topology emitter (this file +
|
|
11
|
+
* library.ts). The two cross-branch types — `ResolvedComponent` (Agent A) and
|
|
12
|
+
* `FactoryV2Metadata` / `InstanceFactory` (Agent B) — are imported from their
|
|
13
|
+
* canonical locations: Round 1d (this commit) reconciled the local stubs with
|
|
14
|
+
* the merged real types.
|
|
15
|
+
*
|
|
16
|
+
* Round 2 will add: service, managed, executable, messaging emitters + CLI wiring.
|
|
17
|
+
*/
|
|
18
|
+
// ─── Dispatcher ───────────────────────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Look up the correct emitter for the factory's topology.
|
|
21
|
+
*
|
|
22
|
+
* The emitters map is injected by the caller, making the dispatcher
|
|
23
|
+
* extensible without engine changes: register new emitters by adding
|
|
24
|
+
* entries to the map.
|
|
25
|
+
*
|
|
26
|
+
* @param factory - The resolved factory metadata (drives the topology lookup).
|
|
27
|
+
* @param emitters - Registry of topology → RuntimeEmitter. Typically built
|
|
28
|
+
* once per realize run by `buildDefaultEmitters()`.
|
|
29
|
+
* @returns The matching RuntimeEmitter.
|
|
30
|
+
* @throws Error if no emitter is registered for the factory's topology.
|
|
31
|
+
*/
|
|
32
|
+
export function dispatchRuntimeEmitter(factory, emitters) {
|
|
33
|
+
// V2 P3 R1d reconciliation: Agent B's loader populates factory.v2metadata
|
|
34
|
+
// (with topology defaulted from factory.category). Pre-V2 factories
|
|
35
|
+
// without v2metadata fall back to 'library' — the only emitter Round 1
|
|
36
|
+
// registers, so dispatch is deterministic.
|
|
37
|
+
const topology = factory.v2metadata?.topology ?? 'library';
|
|
38
|
+
const emitter = emitters.get(topology);
|
|
39
|
+
if (!emitter) {
|
|
40
|
+
const available = Array.from(emitters.keys()).sort().join(', ');
|
|
41
|
+
throw new Error(`No runtime emitter registered for topology '${topology}'. Available: ${available || '(none)'}`);
|
|
42
|
+
}
|
|
43
|
+
return emitter;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build the default emitter registry for a realize run.
|
|
47
|
+
*
|
|
48
|
+
* Round 1 shipped library; Round 2 added service / managed / executable /
|
|
49
|
+
* messaging. All 5 are registered here so the realize-side dispatcher can
|
|
50
|
+
* pick whichever the factory's v2metadata.topology selects.
|
|
51
|
+
*
|
|
52
|
+
* The 'external' topology is intentionally NOT registered — V2's design
|
|
53
|
+
* defines it as a passthrough requiring manual wiring (no auto-emission).
|
|
54
|
+
* Specs that bind a factory with topology: 'external' will trip a clear
|
|
55
|
+
* "No runtime emitter registered" error, which is the desired behavior.
|
|
56
|
+
*
|
|
57
|
+
* Imports are deferred to avoid circular deps — each emitter file imports
|
|
58
|
+
* only from dispatcher.ts, not vice versa.
|
|
59
|
+
*/
|
|
60
|
+
export async function buildDefaultEmitters() {
|
|
61
|
+
const [{ LibraryRuntimeEmitter }, { ServiceRuntimeEmitter }, { ManagedRuntimeEmitter }, { ExecutableRuntimeEmitter }, { MessagingRuntimeEmitter },] = await Promise.all([
|
|
62
|
+
import('./library.js'),
|
|
63
|
+
import('./service.js'),
|
|
64
|
+
import('./managed.js'),
|
|
65
|
+
import('./executable.js'),
|
|
66
|
+
import('./messaging.js'),
|
|
67
|
+
]);
|
|
68
|
+
const map = new Map();
|
|
69
|
+
map.set('library', new LibraryRuntimeEmitter());
|
|
70
|
+
map.set('service', new ServiceRuntimeEmitter());
|
|
71
|
+
map.set('managed', new ManagedRuntimeEmitter());
|
|
72
|
+
map.set('executable', new ExecutableRuntimeEmitter());
|
|
73
|
+
map.set('messaging', new MessagingRuntimeEmitter());
|
|
74
|
+
return map;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=dispatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAyIH,iFAAiF;AAEjF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAwB,EACxB,QAAqC;IAErC,0EAA0E;IAC1E,oEAAoE;IACpE,uEAAuE;IACvE,2CAA2C;IAC3C,MAAM,QAAQ,GAAoB,OAAO,CAAC,UAAU,EAAE,QAAQ,IAAI,SAAS,CAAC;IAC5E,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,+CAA+C,QAAQ,iBAAiB,SAAS,IAAI,QAAQ,EAAE,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,CACJ,EAAE,qBAAqB,EAAE,EACzB,EAAE,qBAAqB,EAAE,EACzB,EAAE,qBAAqB,EAAE,EACzB,EAAE,wBAAwB,EAAE,EAC5B,EAAE,uBAAuB,EAAE,EAC5B,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACpB,MAAM,CAAC,cAAc,CAAC;QACtB,MAAM,CAAC,cAAc,CAAC;QACtB,MAAM,CAAC,cAAc,CAAC;QACtB,MAAM,CAAC,iBAAiB,CAAC;QACzB,MAAM,CAAC,gBAAgB,CAAC;KACzB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,wBAAwB,EAAE,CAAC,CAAC;IACtD,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,uBAAuB,EAAE,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executable-runtime emitter — V2 Phase 3, Round 2.
|
|
3
|
+
*
|
|
4
|
+
* Handles `topology: 'executable'` factories: providers reached via
|
|
5
|
+
* `spawnSync` / `execSync` — local CLI binaries such as gitnexus, ffmpeg,
|
|
6
|
+
* or custom binaries.
|
|
7
|
+
*
|
|
8
|
+
* For each `import:` entry the consumer declares, this emitter produces:
|
|
9
|
+
* clients/<kebab-provider>.ts — spawnSync wrapper with typed interface
|
|
10
|
+
*
|
|
11
|
+
* The generated client module:
|
|
12
|
+
* - Emits an `assertBinaryAvailable()` function called at module load
|
|
13
|
+
* that runs `spawnSync('which', [binary])` (or `spawnSync(binary, ['--version'])`
|
|
14
|
+
* as fallback) to fail loud at boot if the binary isn't on PATH.
|
|
15
|
+
* - Exports a `<ProviderName>Client` TypeScript interface matching the
|
|
16
|
+
* selected operations from `import.select`.
|
|
17
|
+
* - Exports a `<providerName>Client` constant that implements the interface
|
|
18
|
+
* by dispatching to `spawnSync`:
|
|
19
|
+
* * Dotted op `Subcommand.action`: runs `spawnSync(binary, ['subcommand', 'action', ...args])`.
|
|
20
|
+
* * Bare entity: runs `spawnSync(binary, [entity.toLowerCase(), ...args])`.
|
|
21
|
+
* stdout is parsed as JSON; non-zero exit throws a clear Error.
|
|
22
|
+
*
|
|
23
|
+
* --- Binary name resolution ---
|
|
24
|
+
*
|
|
25
|
+
* The binary name is read from:
|
|
26
|
+
* 1. `factory.v2metadata.config?.binary` (explicit override)
|
|
27
|
+
* 2. `factory.name` lowercased (e.g. 'Gitnexus' → 'gitnexus')
|
|
28
|
+
*
|
|
29
|
+
* --- Select grammar ---
|
|
30
|
+
*
|
|
31
|
+
* Follows V2 D2 resolution (same as library.ts):
|
|
32
|
+
* - Dotted: `Subcommand.action` → dispatches `spawnSync(binary, ['subcommand', 'action', ...])`.
|
|
33
|
+
* - Bare: `EntityName` → dispatches `spawnSync(binary, [entityname, ...])`.
|
|
34
|
+
*
|
|
35
|
+
* --- No server file ---
|
|
36
|
+
*
|
|
37
|
+
* Subprocess providers don't have a server-bind file.
|
|
38
|
+
*
|
|
39
|
+
* --- Deployment instance hint ---
|
|
40
|
+
*
|
|
41
|
+
* Emitter notes include a hint to add the provider to
|
|
42
|
+
* `deployments.<env>.instances.infrastructure.<provider>` with
|
|
43
|
+
* `config: { binary: <name> }`.
|
|
44
|
+
*/
|
|
45
|
+
import type { RuntimeEmitter, RuntimeEmitterContext, RuntimeEmitterResult } from './dispatcher.js';
|
|
46
|
+
/**
|
|
47
|
+
* Executable-runtime emitter implementation.
|
|
48
|
+
*
|
|
49
|
+
* One call to `emit()` processes a single `import:` entry and produces
|
|
50
|
+
* one client file under `clients/<provider-filename>.ts`.
|
|
51
|
+
* No server-bind file is emitted (subprocess providers have no server).
|
|
52
|
+
*/
|
|
53
|
+
export declare class ExecutableRuntimeEmitter implements RuntimeEmitter {
|
|
54
|
+
readonly topology: "executable";
|
|
55
|
+
emit(ctx: RuntimeEmitterContext): Promise<RuntimeEmitterResult>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=executable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executable.d.ts","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/executable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAuOzB;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,cAAc;IAC7D,QAAQ,CAAC,QAAQ,EAAG,YAAY,CAAU;IAEpC,IAAI,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAsFtE"}
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executable-runtime emitter — V2 Phase 3, Round 2.
|
|
3
|
+
*
|
|
4
|
+
* Handles `topology: 'executable'` factories: providers reached via
|
|
5
|
+
* `spawnSync` / `execSync` — local CLI binaries such as gitnexus, ffmpeg,
|
|
6
|
+
* or custom binaries.
|
|
7
|
+
*
|
|
8
|
+
* For each `import:` entry the consumer declares, this emitter produces:
|
|
9
|
+
* clients/<kebab-provider>.ts — spawnSync wrapper with typed interface
|
|
10
|
+
*
|
|
11
|
+
* The generated client module:
|
|
12
|
+
* - Emits an `assertBinaryAvailable()` function called at module load
|
|
13
|
+
* that runs `spawnSync('which', [binary])` (or `spawnSync(binary, ['--version'])`
|
|
14
|
+
* as fallback) to fail loud at boot if the binary isn't on PATH.
|
|
15
|
+
* - Exports a `<ProviderName>Client` TypeScript interface matching the
|
|
16
|
+
* selected operations from `import.select`.
|
|
17
|
+
* - Exports a `<providerName>Client` constant that implements the interface
|
|
18
|
+
* by dispatching to `spawnSync`:
|
|
19
|
+
* * Dotted op `Subcommand.action`: runs `spawnSync(binary, ['subcommand', 'action', ...args])`.
|
|
20
|
+
* * Bare entity: runs `spawnSync(binary, [entity.toLowerCase(), ...args])`.
|
|
21
|
+
* stdout is parsed as JSON; non-zero exit throws a clear Error.
|
|
22
|
+
*
|
|
23
|
+
* --- Binary name resolution ---
|
|
24
|
+
*
|
|
25
|
+
* The binary name is read from:
|
|
26
|
+
* 1. `factory.v2metadata.config?.binary` (explicit override)
|
|
27
|
+
* 2. `factory.name` lowercased (e.g. 'Gitnexus' → 'gitnexus')
|
|
28
|
+
*
|
|
29
|
+
* --- Select grammar ---
|
|
30
|
+
*
|
|
31
|
+
* Follows V2 D2 resolution (same as library.ts):
|
|
32
|
+
* - Dotted: `Subcommand.action` → dispatches `spawnSync(binary, ['subcommand', 'action', ...])`.
|
|
33
|
+
* - Bare: `EntityName` → dispatches `spawnSync(binary, [entityname, ...])`.
|
|
34
|
+
*
|
|
35
|
+
* --- No server file ---
|
|
36
|
+
*
|
|
37
|
+
* Subprocess providers don't have a server-bind file.
|
|
38
|
+
*
|
|
39
|
+
* --- Deployment instance hint ---
|
|
40
|
+
*
|
|
41
|
+
* Emitter notes include a hint to add the provider to
|
|
42
|
+
* `deployments.<env>.instances.infrastructure.<provider>` with
|
|
43
|
+
* `config: { binary: <name> }`.
|
|
44
|
+
*/
|
|
45
|
+
// ─── Naming helpers (mirrors library.ts) ─────────────────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* Parse a select entry into head + optional tail.
|
|
48
|
+
* Dotted: `Subcommand.action` → { head: 'Subcommand', tail: 'action' }
|
|
49
|
+
* Bare: `EntityName` → { head: 'EntityName', tail: undefined }
|
|
50
|
+
*/
|
|
51
|
+
function parseSelectEntry(entry) {
|
|
52
|
+
const dotIndex = entry.indexOf('.');
|
|
53
|
+
if (dotIndex === -1) {
|
|
54
|
+
return { head: entry, tail: undefined };
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
head: entry.slice(0, dotIndex),
|
|
58
|
+
tail: entry.slice(dotIndex + 1),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Normalise a `from:` name into an array of words for identifier generation.
|
|
63
|
+
* Same implementation as library.ts — handles camelCase, scoped packages, hyphens.
|
|
64
|
+
*/
|
|
65
|
+
function toWords(fromName) {
|
|
66
|
+
const normalised = fromName.replace(/^@/, '').replace(/\//g, '-');
|
|
67
|
+
return normalised
|
|
68
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
69
|
+
.replace(/[^a-zA-Z0-9]+/g, ' ')
|
|
70
|
+
.trim()
|
|
71
|
+
.split(' ')
|
|
72
|
+
.filter(Boolean)
|
|
73
|
+
.map((w) => w.toLowerCase());
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Convert a from-name to a lower-camelCase client constant name.
|
|
77
|
+
* 'Gitnexus' → 'gitnexus', 'GitNexus' → 'gitNexus', '@ffmpeg/core' → 'ffmpegCore'
|
|
78
|
+
*/
|
|
79
|
+
function toClientName(fromName) {
|
|
80
|
+
const words = toWords(fromName);
|
|
81
|
+
if (words.length === 0)
|
|
82
|
+
return 'unknownClient';
|
|
83
|
+
return (words[0] +
|
|
84
|
+
words
|
|
85
|
+
.slice(1)
|
|
86
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
87
|
+
.join(''));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Convert a from-name to a PascalCase interface name suffix.
|
|
91
|
+
* 'Gitnexus' → 'Gitnexus', 'GitNexus' → 'Gitnexus', '@ffmpeg/core' → 'FfmpegCore'
|
|
92
|
+
*/
|
|
93
|
+
function toInterfaceName(fromName) {
|
|
94
|
+
const words = toWords(fromName);
|
|
95
|
+
return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Convert a from-name to a filesystem-safe kebab-case filename.
|
|
99
|
+
* 'Gitnexus' → 'gitnexus', 'GitNexus' → 'git-nexus', '@ffmpeg/core' → 'ffmpeg-core'
|
|
100
|
+
*/
|
|
101
|
+
function toFileName(fromName) {
|
|
102
|
+
return toWords(fromName).join('-');
|
|
103
|
+
}
|
|
104
|
+
// ─── Binary name resolution ───────────────────────────────────────────────────
|
|
105
|
+
/**
|
|
106
|
+
* Resolve the binary name for spawnSync.
|
|
107
|
+
*
|
|
108
|
+
* Priority:
|
|
109
|
+
* 1. `factory.v2metadata.config?.binary` (explicit override)
|
|
110
|
+
* 2. `factory.name` lowercased (e.g. 'Gitnexus' → 'gitnexus',
|
|
111
|
+
* 'SubprocessCLIAdapter' → 'subprocesscliadapter' — callers should
|
|
112
|
+
* prefer explicit `config.binary` for multi-word names)
|
|
113
|
+
*/
|
|
114
|
+
function resolveBinaryName(factory) {
|
|
115
|
+
const configBinary = factory.v2metadata
|
|
116
|
+
?.config?.binary;
|
|
117
|
+
if (configBinary && typeof configBinary === 'string' && configBinary.length > 0) {
|
|
118
|
+
return configBinary;
|
|
119
|
+
}
|
|
120
|
+
return factory.name.toLowerCase();
|
|
121
|
+
}
|
|
122
|
+
// ─── Code-generation helpers ──────────────────────────────────────────────────
|
|
123
|
+
/**
|
|
124
|
+
* Generate the `assertBinaryAvailable()` function that runs at module load.
|
|
125
|
+
*
|
|
126
|
+
* Uses `spawnSync('which', [binary])` as primary check (POSIX); on non-zero
|
|
127
|
+
* exit falls back to `spawnSync(binary, ['--version'])`. If both fail, throws
|
|
128
|
+
* a descriptive error pointing at the env-var escape hatch.
|
|
129
|
+
*
|
|
130
|
+
* The env-var name is SPECVERSE_<BINARY_UPPER>_PATH (e.g. SPECVERSE_PROFIT_CALC_PATH).
|
|
131
|
+
*/
|
|
132
|
+
function generateBinaryAvailabilityCheck(binary) {
|
|
133
|
+
const envVar = `SPECVERSE_${binary.toUpperCase().replace(/[^A-Z0-9]/g, '_')}_PATH`;
|
|
134
|
+
const lines = [];
|
|
135
|
+
lines.push(`import { spawnSync } from 'child_process';`);
|
|
136
|
+
lines.push('');
|
|
137
|
+
lines.push(`const BINARY = '${binary}';`);
|
|
138
|
+
lines.push(`const ENV_OVERRIDE = process.env['${envVar}'];`);
|
|
139
|
+
lines.push(`const EFFECTIVE_BINARY = ENV_OVERRIDE ?? BINARY;`);
|
|
140
|
+
lines.push('');
|
|
141
|
+
lines.push(`/** Assert the required binary is available on PATH before any calls are made. */`);
|
|
142
|
+
lines.push(`function assertBinaryAvailable(): void {`);
|
|
143
|
+
lines.push(` const check = spawnSync('which', [EFFECTIVE_BINARY], { encoding: 'utf-8' });`);
|
|
144
|
+
lines.push(` if (check.status !== 0) {`);
|
|
145
|
+
lines.push(` // Fallback: try --version directly (useful when 'which' itself is absent)`);
|
|
146
|
+
lines.push(` const direct = spawnSync(EFFECTIVE_BINARY, ['--version'], { encoding: 'utf-8' });`);
|
|
147
|
+
lines.push(` if (direct.status !== 0 && direct.error) {`);
|
|
148
|
+
lines.push(` throw new Error(\`Required binary \${EFFECTIVE_BINARY} not found on PATH. ` +
|
|
149
|
+
`Install it or update ${envVar} env var.\`);`);
|
|
150
|
+
lines.push(` }`);
|
|
151
|
+
lines.push(` }`);
|
|
152
|
+
lines.push(`}`);
|
|
153
|
+
lines.push('');
|
|
154
|
+
lines.push(`// Run at module load — catches missing-binary errors at app boot.`);
|
|
155
|
+
lines.push(`assertBinaryAvailable();`);
|
|
156
|
+
return lines.join('\n');
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Generate the TypeScript interface for the executable client type.
|
|
160
|
+
*
|
|
161
|
+
* Dotted entries (`Subcommand.action`) → typed `(...args: unknown[]) => unknown` method.
|
|
162
|
+
* Bare entries (`EntityName`) → typed `(...args: unknown[]) => unknown` method (passthrough).
|
|
163
|
+
*
|
|
164
|
+
* Unlike the library emitter, subprocess calls are synchronous (`spawnSync`), so
|
|
165
|
+
* the return type is `unknown` (not `Promise<unknown>`). Callers may wrap in a
|
|
166
|
+
* Promise if they need async composition; the underlying I/O is blocking.
|
|
167
|
+
*/
|
|
168
|
+
function generateInterface(interfaceName, selectEntries) {
|
|
169
|
+
const lines = [];
|
|
170
|
+
lines.push(`export type ${interfaceName}Client = {`);
|
|
171
|
+
const seen = new Set();
|
|
172
|
+
for (const entry of selectEntries) {
|
|
173
|
+
if (seen.has(entry))
|
|
174
|
+
continue;
|
|
175
|
+
seen.add(entry);
|
|
176
|
+
const { head, tail } = parseSelectEntry(entry);
|
|
177
|
+
if (tail === undefined) {
|
|
178
|
+
// Bare entity — passthrough all args as JSON-encoded CLI arguments.
|
|
179
|
+
lines.push(` /** Invokes: spawnSync(binary, ['${head.toLowerCase()}', ...JSON-encoded args]) */`);
|
|
180
|
+
lines.push(` ${head}(...args: unknown[]): unknown;`);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
// Dotted operation — subcommand + action dispatch.
|
|
184
|
+
lines.push(` /** Invokes: spawnSync(binary, ['${head.toLowerCase()}', '${tail}', ...JSON-encoded args]) */`);
|
|
185
|
+
lines.push(` ${tail}(...args: unknown[]): unknown;`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
lines.push('};');
|
|
189
|
+
return lines.join('\n');
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Generate the client constant — spawnSync-backed implementation.
|
|
193
|
+
*
|
|
194
|
+
* Each method:
|
|
195
|
+
* 1. JSON-encodes each argument via JSON.stringify.
|
|
196
|
+
* 2. Calls spawnSync with [subcommand, action, ...encodedArgs] (dotted) or
|
|
197
|
+
* [entityname, ...encodedArgs] (bare).
|
|
198
|
+
* 3. On non-zero exit, throws Error('<binary> <subcommand>: <stderr>').
|
|
199
|
+
* 4. Parses stdout as JSON and returns the result.
|
|
200
|
+
*/
|
|
201
|
+
function generateClientConstant(clientName, interfaceName, selectEntries) {
|
|
202
|
+
const lines = [];
|
|
203
|
+
lines.push(`export const ${clientName}Client: ${interfaceName}Client = {`);
|
|
204
|
+
const seen = new Set();
|
|
205
|
+
for (const entry of selectEntries) {
|
|
206
|
+
if (seen.has(entry))
|
|
207
|
+
continue;
|
|
208
|
+
seen.add(entry);
|
|
209
|
+
const { head, tail } = parseSelectEntry(entry);
|
|
210
|
+
if (tail === undefined) {
|
|
211
|
+
// Bare entity passthrough — proxy all args as JSON-encoded CLI arguments.
|
|
212
|
+
const subcommand = head.toLowerCase();
|
|
213
|
+
lines.push(` ${head}(...args: unknown[]): unknown {`);
|
|
214
|
+
lines.push(` const encodedArgs = args.map((a) => JSON.stringify(a));`);
|
|
215
|
+
lines.push(` const result = spawnSync(EFFECTIVE_BINARY, ['${subcommand}', ...encodedArgs], { encoding: 'utf-8' });`);
|
|
216
|
+
lines.push(` if (result.status !== 0) {`);
|
|
217
|
+
lines.push(` throw new Error(\`\${EFFECTIVE_BINARY} ${subcommand}: \${result.stderr}\`);`);
|
|
218
|
+
lines.push(` }`);
|
|
219
|
+
lines.push(` return JSON.parse(result.stdout);`);
|
|
220
|
+
lines.push(` },`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
// Dotted operation — subcommand (head) + action (tail) dispatch.
|
|
224
|
+
const subcommand = head.toLowerCase();
|
|
225
|
+
lines.push(` ${tail}(...args: unknown[]): unknown {`);
|
|
226
|
+
lines.push(` const encodedArgs = args.map((a) => JSON.stringify(a));`);
|
|
227
|
+
lines.push(` const result = spawnSync(EFFECTIVE_BINARY, ['${subcommand}', '${tail}', ...encodedArgs], { encoding: 'utf-8' });`);
|
|
228
|
+
lines.push(` if (result.status !== 0) {`);
|
|
229
|
+
lines.push(` throw new Error(\`\${EFFECTIVE_BINARY} ${subcommand}: \${result.stderr}\`);`);
|
|
230
|
+
lines.push(` }`);
|
|
231
|
+
lines.push(` return JSON.parse(result.stdout);`);
|
|
232
|
+
lines.push(` },`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
lines.push('};');
|
|
236
|
+
return lines.join('\n');
|
|
237
|
+
}
|
|
238
|
+
// ─── Executable emitter ───────────────────────────────────────────────────────
|
|
239
|
+
/**
|
|
240
|
+
* Executable-runtime emitter implementation.
|
|
241
|
+
*
|
|
242
|
+
* One call to `emit()` processes a single `import:` entry and produces
|
|
243
|
+
* one client file under `clients/<provider-filename>.ts`.
|
|
244
|
+
* No server-bind file is emitted (subprocess providers have no server).
|
|
245
|
+
*/
|
|
246
|
+
export class ExecutableRuntimeEmitter {
|
|
247
|
+
topology = 'executable';
|
|
248
|
+
async emit(ctx) {
|
|
249
|
+
const { importEntry, resolved, factory } = ctx;
|
|
250
|
+
const selectEntries = importEntry.select ?? [];
|
|
251
|
+
// Resolve binary name: config?.binary → factory.name.toLowerCase()
|
|
252
|
+
const binary = resolveBinaryName(factory);
|
|
253
|
+
// Derive naming from the import's `from:` field.
|
|
254
|
+
const fileName = toFileName(importEntry.from);
|
|
255
|
+
const clientName = toClientName(importEntry.from);
|
|
256
|
+
const interfaceName = toInterfaceName(importEntry.from);
|
|
257
|
+
// File path relative to outputDir.
|
|
258
|
+
const relFilePath = `clients/${fileName}.ts`;
|
|
259
|
+
// Build file header.
|
|
260
|
+
const headerLines = [
|
|
261
|
+
'// FACTORY-EMITTED — DO NOT EDIT (R8)',
|
|
262
|
+
`// Generated by executable-runtime emitter — V2 Phase 3`,
|
|
263
|
+
`// Provider: ${importEntry.from} (${resolved.source}) via factory: ${factory.name}`,
|
|
264
|
+
`// Binary: ${binary}`,
|
|
265
|
+
'',
|
|
266
|
+
];
|
|
267
|
+
// Build availability check block (includes `import { spawnSync }` and constant declaration).
|
|
268
|
+
const availabilityBlock = generateBinaryAvailabilityCheck(binary);
|
|
269
|
+
// Build interface.
|
|
270
|
+
const interfaceBlock = generateInterface(interfaceName, selectEntries);
|
|
271
|
+
// Build client constant.
|
|
272
|
+
const constantBlock = generateClientConstant(clientName, interfaceName, selectEntries);
|
|
273
|
+
// Assemble file.
|
|
274
|
+
const parts = [
|
|
275
|
+
...headerLines,
|
|
276
|
+
availabilityBlock,
|
|
277
|
+
'',
|
|
278
|
+
interfaceBlock,
|
|
279
|
+
'',
|
|
280
|
+
constantBlock,
|
|
281
|
+
'',
|
|
282
|
+
];
|
|
283
|
+
const content = parts.join('\n');
|
|
284
|
+
// Build the import entry for the consumer's controller file.
|
|
285
|
+
const consumerImport = {
|
|
286
|
+
from: `./clients/${fileName}`,
|
|
287
|
+
specifier: `${clientName}Client`,
|
|
288
|
+
};
|
|
289
|
+
// Notes: warnings + deployment instance hint.
|
|
290
|
+
const notes = [];
|
|
291
|
+
if (selectEntries.length === 0) {
|
|
292
|
+
notes.push(`Warning: import entry from '${importEntry.from}' has empty select: — no client members emitted.`);
|
|
293
|
+
}
|
|
294
|
+
// Deployment instance hint — provider lands in infrastructure category.
|
|
295
|
+
notes.push(`Deployment hint: add '${importEntry.from}' to deployments.<env>.instances.infrastructure` +
|
|
296
|
+
` with config: { binary: '${binary}' }. No process lifecycle; just a binary path requirement.`);
|
|
297
|
+
const deploymentSuggestion = {
|
|
298
|
+
provider: importEntry.from,
|
|
299
|
+
consumerComponent: ctx.consumerComponent?.name,
|
|
300
|
+
category: 'infrastructure',
|
|
301
|
+
key: clientName,
|
|
302
|
+
config: {
|
|
303
|
+
binary,
|
|
304
|
+
},
|
|
305
|
+
factory: factory.name,
|
|
306
|
+
topology: 'executable',
|
|
307
|
+
};
|
|
308
|
+
return {
|
|
309
|
+
files: [{ path: relFilePath, content }],
|
|
310
|
+
imports: [consumerImport],
|
|
311
|
+
notes,
|
|
312
|
+
deploymentSuggestion,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=executable.js.map
|