@specverse/engines 6.33.1 → 6.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/libs/instance-factories/communication/rabbitmq-events.yaml +11 -0
  2. package/dist/libs/instance-factories/controllers/fastify.yaml +11 -0
  3. package/dist/libs/instance-factories/managed/stripe-rest-sdk.yaml +78 -0
  4. package/dist/libs/instance-factories/managed/templates/stripe/stripe-client-generator.js +8 -0
  5. package/dist/libs/instance-factories/orms/prisma.yaml +11 -0
  6. package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +4 -1
  7. package/dist/realize/index.d.ts.map +1 -1
  8. package/dist/realize/index.js +246 -1
  9. package/dist/realize/index.js.map +1 -1
  10. package/dist/realize/library/loader.d.ts.map +1 -1
  11. package/dist/realize/library/loader.js +81 -1
  12. package/dist/realize/library/loader.js.map +1 -1
  13. package/dist/realize/per-action-emitter.d.ts +11 -33
  14. package/dist/realize/per-action-emitter.d.ts.map +1 -1
  15. package/dist/realize/per-action-emitter.js.map +1 -1
  16. package/dist/realize/per-action-llm-emit.d.ts.map +1 -1
  17. package/dist/realize/per-action-llm-emit.js +5 -1
  18. package/dist/realize/per-action-llm-emit.js.map +1 -1
  19. package/dist/realize/per-action-runner.d.ts +45 -0
  20. package/dist/realize/per-action-runner.d.ts.map +1 -1
  21. package/dist/realize/per-action-runner.js +132 -0
  22. package/dist/realize/per-action-runner.js.map +1 -1
  23. package/dist/realize/resolver/index.d.ts +157 -0
  24. package/dist/realize/resolver/index.d.ts.map +1 -0
  25. package/dist/realize/resolver/index.js +307 -0
  26. package/dist/realize/resolver/index.js.map +1 -0
  27. package/dist/realize/runtime-emitters/dispatcher.d.ts +176 -0
  28. package/dist/realize/runtime-emitters/dispatcher.d.ts.map +1 -0
  29. package/dist/realize/runtime-emitters/dispatcher.js +76 -0
  30. package/dist/realize/runtime-emitters/dispatcher.js.map +1 -0
  31. package/dist/realize/runtime-emitters/executable.d.ts +57 -0
  32. package/dist/realize/runtime-emitters/executable.d.ts.map +1 -0
  33. package/dist/realize/runtime-emitters/executable.js +316 -0
  34. package/dist/realize/runtime-emitters/executable.js.map +1 -0
  35. package/dist/realize/runtime-emitters/library.d.ts +52 -0
  36. package/dist/realize/runtime-emitters/library.d.ts.map +1 -0
  37. package/dist/realize/runtime-emitters/library.js +349 -0
  38. package/dist/realize/runtime-emitters/library.js.map +1 -0
  39. package/dist/realize/runtime-emitters/managed.d.ts +44 -0
  40. package/dist/realize/runtime-emitters/managed.d.ts.map +1 -0
  41. package/dist/realize/runtime-emitters/managed.js +283 -0
  42. package/dist/realize/runtime-emitters/managed.js.map +1 -0
  43. package/dist/realize/runtime-emitters/messaging.d.ts +77 -0
  44. package/dist/realize/runtime-emitters/messaging.d.ts.map +1 -0
  45. package/dist/realize/runtime-emitters/messaging.js +423 -0
  46. package/dist/realize/runtime-emitters/messaging.js.map +1 -0
  47. package/dist/realize/runtime-emitters/service.d.ts +42 -0
  48. package/dist/realize/runtime-emitters/service.d.ts.map +1 -0
  49. package/dist/realize/runtime-emitters/service.js +355 -0
  50. package/dist/realize/runtime-emitters/service.js.map +1 -0
  51. package/dist/realize/types/instance-factory.d.ts +1 -1
  52. package/dist/realize/types/instance-factory.d.ts.map +1 -1
  53. package/libs/instance-factories/communication/rabbitmq-events.yaml +11 -0
  54. package/libs/instance-factories/controllers/fastify.yaml +11 -0
  55. package/libs/instance-factories/managed/stripe-rest-sdk.yaml +78 -0
  56. package/libs/instance-factories/managed/templates/stripe/stripe-client-generator.ts +26 -0
  57. package/libs/instance-factories/orms/prisma.yaml +11 -0
  58. package/libs/instance-factories/services/templates/_shared/step-matching.ts +11 -29
  59. package/libs/instance-factories/services/templates/prisma/__tests__/behavior-generator.test.ts +85 -0
  60. package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +21 -1
  61. package/package.json +2 -2
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executable.js","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/executable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAQH,gFAAgF;AAEhF;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,KAAa;IACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QAC9B,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC;KAChC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,QAAgB;IAC/B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClE,OAAO,UAAU;SACd,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC;SAC9B,IAAI,EAAE;SACN,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,eAAe,CAAC;IAC/C,OAAO,CACL,KAAK,CAAC,CAAC,CAAE;QACT,KAAK;aACF,KAAK,CAAC,CAAC,CAAC;aACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aAClD,IAAI,CAAC,EAAE,CAAC,CACZ,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,QAAgB;IAClC,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,OAAyC;IAClE,MAAM,YAAY,GAAI,OAAO,CAAC,UAA2D;QACvF,EAAE,MAAM,EAAE,MAAM,CAAC;IACnB,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChF,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;GAQG;AACH,SAAS,+BAA+B,CAAC,MAAc;IACrD,MAAM,MAAM,GAAG,aAAa,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC;IACnF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACzD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,IAAI,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,qCAAqC,MAAM,KAAK,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAC;IAChG,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;IAC7F,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;IAC7F,KAAK,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;IACpG,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CACR,kFAAkF;QAChF,wBAAwB,MAAM,eAAe,CAChD,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACjF,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CACxB,aAAqB,EACrB,aAAuB;IAEvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,eAAe,aAAa,YAAY,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,oEAAoE;YACpE,KAAK,CAAC,IAAI,CACR,sCAAsC,IAAI,CAAC,WAAW,EAAE,8BAA8B,CACvF,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,gCAAgC,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,mDAAmD;YACnD,KAAK,CAAC,IAAI,CACR,sCAAsC,IAAI,CAAC,WAAW,EAAE,OAAO,IAAI,8BAA8B,CAClG,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,gCAAgC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,sBAAsB,CAC7B,UAAkB,EAClB,aAAqB,EACrB,aAAuB;IAEvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,gBAAgB,UAAU,WAAW,aAAa,YAAY,CAAC,CAAC;IAE3E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,0EAA0E;YAC1E,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,iCAAiC,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC1E,KAAK,CAAC,IAAI,CACR,oDAAoD,UAAU,6CAA6C,CAC5G,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CACR,gDAAgD,UAAU,yBAAyB,CACpF,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,iEAAiE;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,iCAAiC,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC1E,KAAK,CAAC,IAAI,CACR,oDAAoD,UAAU,OAAO,IAAI,6CAA6C,CACvH,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CACR,gDAAgD,UAAU,yBAAyB,CACpF,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,OAAO,wBAAwB;IAC1B,QAAQ,GAAG,YAAqB,CAAC;IAE1C,KAAK,CAAC,IAAI,CAAC,GAA0B;QACnC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;QAC/C,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,IAAI,EAAE,CAAC;QAE/C,mEAAmE;QACnE,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE1C,iDAAiD;QACjD,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,aAAa,GAAG,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAExD,mCAAmC;QACnC,MAAM,WAAW,GAAG,WAAW,QAAQ,KAAK,CAAC;QAE7C,qBAAqB;QACrB,MAAM,WAAW,GAAa;YAC5B,uCAAuC;YACvC,yDAAyD;YACzD,gBAAgB,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,kBAAkB,OAAO,CAAC,IAAI,EAAE;YACpF,cAAc,MAAM,EAAE;YACtB,EAAE;SACH,CAAC;QAEF,6FAA6F;QAC7F,MAAM,iBAAiB,GAAG,+BAA+B,CAAC,MAAM,CAAC,CAAC;QAElE,mBAAmB;QACnB,MAAM,cAAc,GAAG,iBAAiB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;QAEvE,yBAAyB;QACzB,MAAM,aAAa,GAAG,sBAAsB,CAAC,UAAU,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;QAEvF,iBAAiB;QACjB,MAAM,KAAK,GAAa;YACtB,GAAG,WAAW;YACd,iBAAiB;YACjB,EAAE;YACF,cAAc;YACd,EAAE;YACF,aAAa;YACb,EAAE;SACH,CAAC;QAEF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEjC,6DAA6D;QAC7D,MAAM,cAAc,GAAG;YACrB,IAAI,EAAE,aAAa,QAAQ,EAAE;YAC7B,SAAS,EAAE,GAAG,UAAU,QAAQ;SACjC,CAAC;QAEF,8CAA8C;QAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CACR,+BAA+B,WAAW,CAAC,IAAI,kDAAkD,CAClG,CAAC;QACJ,CAAC;QAED,wEAAwE;QACxE,KAAK,CAAC,IAAI,CACR,yBAAyB,WAAW,CAAC,IAAI,iDAAiD;YACxF,4BAA4B,MAAM,4DAA4D,CACjG,CAAC;QAEF,MAAM,oBAAoB,GAAG;YAC3B,QAAQ,EAAE,WAAW,CAAC,IAAI;YAC1B,iBAAiB,EAAG,GAAG,CAAC,iBAAyB,EAAE,IAAI;YACvD,QAAQ,EAAE,gBAAyB;YACnC,GAAG,EAAE,UAAU;YACf,MAAM,EAAE;gBACN,MAAM;aACP;YACD,OAAO,EAAE,OAAO,CAAC,IAAI;YACrB,QAAQ,EAAE,YAAqB;SAChC,CAAC;QAEF,OAAO;YACL,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;YACvC,OAAO,EAAE,CAAC,cAAc,CAAC;YACzB,KAAK;YACL,oBAAoB;SACrB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Library-runtime emitter — V2 Phase 3, Round 1.
3
+ *
4
+ * Handles `topology: 'library'` factories: providers that are consumed
5
+ * as in-process imports, with no deployment instance entry.
6
+ *
7
+ * For each `import:` entry the consumer declares, this emitter produces:
8
+ * clients/<provider-name>.ts — typed client module
9
+ *
10
+ * The typed client module:
11
+ * - Exports a `<ProviderName>Client` TypeScript interface matching
12
+ * the selected operations from `import.select`.
13
+ * - Exports a `<providerName>Client` constant that implements the
14
+ * interface by delegating to the resolved provider:
15
+ * * source = 'local' → relative import to the provider's module.
16
+ * * source = 'npm' → `import { X } from '<package-specifier>'`.
17
+ * * source = 'registry-*' → TODO comment + runtime throw (Round 1).
18
+ *
19
+ * The consuming controller (SalesReportController.ts, emitted by the
20
+ * per-action-emitter's mechanical scaffold) imports this client module
21
+ * and receives the client via constructor injection.
22
+ *
23
+ * --- Select grammar ---
24
+ *
25
+ * `import.select` entries follow two forms (V2 D2 resolution):
26
+ * - Dotted: `Charge.create` → typed function for the specific operation.
27
+ * - Bare: `AuthService` → re-export of the entity's interface.
28
+ *
29
+ * Both forms share the same file; the emitter deduplicates by head entity.
30
+ *
31
+ * --- Round 1 limitations ---
32
+ *
33
+ * - No actual operation signature lookup (operations are typed as
34
+ * `(...args: unknown[]) => Promise<unknown>` unless the spec is provided
35
+ * and the target operation can be located). Exact signatures land in
36
+ * Round 2 when the resolver wires in full cross-spec type lookup.
37
+ * - Registry sources (`registry-component`, `registry-factory`) emit a
38
+ * TODO comment and a `throw` for the client constant; they compile but
39
+ * blow up at runtime until Round 2 fills in the registry resolver.
40
+ */
41
+ import type { RuntimeEmitter, RuntimeEmitterContext, RuntimeEmitterResult } from './dispatcher.js';
42
+ /**
43
+ * Library-runtime emitter implementation.
44
+ *
45
+ * One call to `emit()` processes a single `import:` entry and produces
46
+ * one client file under `clients/<provider-filename>.ts`.
47
+ */
48
+ export declare class LibraryRuntimeEmitter implements RuntimeEmitter {
49
+ readonly topology: "library";
50
+ emit(ctx: RuntimeEmitterContext): Promise<RuntimeEmitterResult>;
51
+ }
52
+ //# sourceMappingURL=library.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/library.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAyQzB;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,QAAQ,CAAC,QAAQ,EAAG,SAAS,CAAU;IAEjC,IAAI,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA+EtE"}