@prisma/composer 0.2.0-dev.11 → 0.2.0-dev.13

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.
@@ -5,7 +5,7 @@ import { Input, StackServices } from "alchemy";
5
5
  import * as Effect from "effect/Effect";
6
6
  import * as Layer from "effect/Layer";
7
7
  import { State } from "alchemy/State/State";
8
- //#region ../../0-framework/1-core/core/dist/app-config-CVyObaOe.d.mts
8
+ //#region ../../0-framework/1-core/core/dist/app-config-S3etMyhL.d.mts
9
9
  //#region src/container-transport.d.ts
10
10
  /**
11
11
  * Carries resolved containers from the CLI process into the alchemy process
@@ -227,6 +227,8 @@ interface LowerOptions {
227
227
  readonly stage?: string;
228
228
  /** Alchemy state store for the stack. Defaults to the config's own state layer. */
229
229
  readonly state?: AlchemyStateLayer;
230
+ /** Explicit provider set for the stack. Defaults to the config's own merged `providers()` (`mergedProviders`) — the same override precedence as `state`. The dev stack module passes `localTargetProviders(...)` here (ADR-0041); `lower()` itself learns nothing about the local target. */
231
+ readonly providers?: Layer.Layer<never>;
230
232
  /**
231
233
  * Invoked once per deploy, during apply, with the Deploy operation's result
232
234
  * — the app and every node it deployed, resolved, in topo order.
@@ -363,6 +365,19 @@ interface ExtensionDescriptor {
363
365
  * in container-transport.ts.
364
366
  */
365
367
  readonly container?: ContainerDescriptor;
368
+ /**
369
+ * The extension's LOCAL TARGET counterpart (ADR-0041; naming, operator
370
+ * 2026-07-23 — "dev" names the user-facing feature only, the seam takes
371
+ * the concept's real noun) — a LAZY reference: an async thunk, never the
372
+ * descriptor object itself. This keeps the production control entry's
373
+ * static import graph free of local-target implementation code (operator
374
+ * directive) — the thunk is one line, dynamically importing the
375
+ * extension's own local-target entry by bare specifier
376
+ * (e.g. `() => import('@prisma/composer-prisma-cloud/local-target').then((m) => m.localTargetDescriptor())`),
377
+ * so nothing local-target-flavored is bundled into, or loaded by, any
378
+ * deploy path.
379
+ */
380
+ readonly localTarget?: () => Promise<LocalTargetDescriptor>;
366
381
  }
367
382
  /**
368
383
  * The deploy's one state store. It names its owning extension so core knows
@@ -390,6 +405,63 @@ interface TeardownInput {
390
405
  /** The stage name (`--stage`), or `undefined` for the default stage — for diagnostics/scope. */
391
406
  readonly stage: string | undefined;
392
407
  }
408
+ /** The extension's LOCAL TARGET counterpart (ADR-0041) — the local-target variant OF ExtensionDescriptor, hence the full qualifier. An extension without one is not local-target-capable (cannot back the "dev" feature). */
409
+ interface LocalTargetDescriptor {
410
+ /** Local providers for the SAME resource types this extension's lowering emits. Receives the app identity — unlike deploy's env-arg-free `providers()`, local providers are emulator clients and must know which app they provision for. */
411
+ providers(input: LocalTargetProvidersInput): Layer.Layer<never>;
412
+ /** A stable local identity — resolved without any platform call. */
413
+ readonly container: ContainerDescriptor;
414
+ /** Value sourcing (secrets/env-params) — runs where deploy's preflight runs. */
415
+ preflight?(input: PreflightInput): Promise<void>;
416
+ /** Ensure the emulator daemons this topology's node kinds need are running (idempotent; they persist across sessions). */
417
+ emulators?(input: LocalTargetEmulatorsInput): Promise<void>;
418
+ /** The dev session's view of the running app. Core renders it and never learns an emulator's API. */
419
+ attach(input: LocalTargetAttachInput): Promise<LocalTargetAttachment>;
420
+ /** `--fresh`: remove every local trace of the dev instance — emulator instances, state, data. */
421
+ teardown?(input: TeardownInput): Promise<void>;
422
+ }
423
+ interface LocalTargetProvidersInput {
424
+ /** This extension's resolved local-target container (its `input.appName` is the emulator app namespace). */
425
+ readonly container: ContainerInstance | undefined;
426
+ /** Absolute path of the dev state directory (`<cwd>/.prisma-composer/dev`). */
427
+ readonly devDir: string;
428
+ }
429
+ interface LocalTargetEmulatorsInput {
430
+ /** The loaded application graph — inspected for which node kinds need an emulator. */
431
+ readonly graph: Graph;
432
+ readonly container: ContainerInstance | undefined;
433
+ /** Absolute path of the dev state directory (`<cwd>/.prisma-composer/dev`). */
434
+ readonly devDir: string;
435
+ }
436
+ interface LocalTargetAttachInput {
437
+ readonly container: ContainerInstance | undefined;
438
+ readonly devDir: string;
439
+ }
440
+ interface LocalTargetAttachment {
441
+ /** Every service's local endpoint, for the front door. */
442
+ endpoints(): Promise<readonly {
443
+ readonly address: string;
444
+ readonly url: string;
445
+ }[]>;
446
+ /** Merged, line-oriented log stream across the app's services (including services that appear after later converges). Ends when `signal` aborts. */
447
+ logs(signal: AbortSignal): AsyncIterable<{
448
+ readonly service: string;
449
+ readonly line: string;
450
+ }>;
451
+ /** Stop the app's service instances (emulators and data persist). */
452
+ stopServices(): Promise<void>;
453
+ }
454
+ /** `<cwd>/.prisma-composer/dev` — the dev instance's app-scoped state directory (ADR-0041, ADR-0004's tool-state rule). "dev" names the user-facing feature/dir (naming, operator 2026-07-23) — this constant's name and value are unchanged by the localTarget rename. */
455
+ declare const DEV_DIR = ".prisma-composer/dev";
456
+ /**
457
+ * True when an extension only participates in assembly (every `nodes` entry
458
+ * is `kind: 'build'`, and it declares none of `providers`/`application`/
459
+ * `provisions`/`container`) — it owns no resources or services, so it has
460
+ * nothing to emulate and is exempt from local-target-capability requirements
461
+ * (ADR-0041). Shared by `localTargetProviders` and every local-target hook
462
+ * iteration.
463
+ */
464
+ declare function isBuildOnlyExtension(extension: ExtensionDescriptor): boolean;
393
465
  /**
394
466
  * What one registry entry can do. The `kind` discriminant is checked at every
395
467
  * lookup site against what the site needs — a resource node looked up against
@@ -415,5 +487,5 @@ interface PrismaAppConfig {
415
487
  /** Typed identity — exists so `prisma-composer.config.ts` gets checked against PrismaAppConfig where it is written. */
416
488
  declare function defineConfig(config: PrismaAppConfig): PrismaAppConfig;
417
489
  //#endregion
418
- export { containerEnvVarName as A, ProvisionEdge as C, TeardownInput as D, StateDescriptor as E, lowering as F, mergedProviders as I, resolveStateLayer as L, deserializeContainers as M, joinDeployment as N, buildConfig as O, lower as P, PrismaAppConfig as S, ServiceLowering as T, Lowering as _, Bundle as a, PackageInput as b, DeployedEntity as c, ExtensionDescriptor as d, LocateContainerInput as f, LoweredResult as g, LowerOptions as h, AssembleInput as i, defineConfig as j, containerEnv as k, DeployedNode as l, LowerError as m, ApplicationDescriptor as n, ContainerDescriptor as o, LowerContext as p, Artifact as r, ContainerInstance as s, AlchemyStateLayer as t, DeploymentResult as u, NodeDescriptor as v, ProvisionerDescriptor as w, PreflightInput as x, Outputs as y };
419
- //# sourceMappingURL=app-config-CVyObaOe-PF94uVBK.d.mts.map
490
+ export { ProvisionerDescriptor as A, joinDeployment as B, Lowering as C, PreflightInput as D, PackageInput as E, containerEnv as F, lowering as H, containerEnvVarName as I, defineConfig as L, StateDescriptor as M, TeardownInput as N, PrismaAppConfig as O, buildConfig as P, deserializeContainers as R, LoweredResult as S, Outputs as T, mergedProviders as U, lower as V, resolveStateLayer as W, LocalTargetProvidersInput as _, Bundle as a, LowerError as b, DEV_DIR as c, DeploymentResult as d, ExtensionDescriptor as f, LocalTargetEmulatorsInput as g, LocalTargetDescriptor as h, AssembleInput as i, ServiceLowering as j, ProvisionEdge as k, DeployedEntity as l, LocalTargetAttachment as m, ApplicationDescriptor as n, ContainerDescriptor as o, LocalTargetAttachInput as p, Artifact as r, ContainerInstance as s, AlchemyStateLayer as t, DeployedNode as u, LocateContainerInput as v, NodeDescriptor as w, LowerOptions as x, LowerContext as y, isBuildOnlyExtension as z };
491
+ //# sourceMappingURL=app-config-S3etMyhL-B8jqbr7j.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-config-S3etMyhL-B8jqbr7j.d.mts","names":[],"sources":["../../../0-framework/1-core/core/dist/app-config-S3etMyhL.d.mts"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ //#region ../../0-framework/1-core/core/dist/app-config-joXc-BKm.mjs
2
+ /** `<cwd>/.prisma-composer/dev` — the dev instance's app-scoped state directory (ADR-0041, ADR-0004's tool-state rule). "dev" names the user-facing feature/dir (naming, operator 2026-07-23) — this constant's name and value are unchanged by the localTarget rename. */
3
+ const DEV_DIR = ".prisma-composer/dev";
4
+ /**
5
+ * True when an extension only participates in assembly (every `nodes` entry
6
+ * is `kind: 'build'`, and it declares none of `providers`/`application`/
7
+ * `provisions`/`container`) — it owns no resources or services, so it has
8
+ * nothing to emulate and is exempt from local-target-capability requirements
9
+ * (ADR-0041). Shared by `localTargetProviders` and every local-target hook
10
+ * iteration.
11
+ */
12
+ function isBuildOnlyExtension(extension) {
13
+ return Object.values(extension.nodes).every((node) => node.kind === "build") && extension.providers === void 0 && extension.application === void 0 && extension.provisions === void 0 && extension.container === void 0;
14
+ }
15
+ /** Typed identity — exists so `prisma-composer.config.ts` gets checked against PrismaAppConfig where it is written. */
16
+ function defineConfig(config) {
17
+ return config;
18
+ }
19
+ //#endregion
20
+ export { defineConfig as n, isBuildOnlyExtension as r, DEV_DIR as t };
21
+
22
+ //# sourceMappingURL=app-config-joXc-BKm-CdcXqNMD.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-config-joXc-BKm-CdcXqNMD.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/app-config-joXc-BKm.mjs"],"sourcesContent":["//#region src/control/app-config.ts\n/** `<cwd>/.prisma-composer/dev` — the dev instance's app-scoped state directory (ADR-0041, ADR-0004's tool-state rule). \"dev\" names the user-facing feature/dir (naming, operator 2026-07-23) — this constant's name and value are unchanged by the localTarget rename. */\nconst DEV_DIR = \".prisma-composer/dev\";\n/**\n* True when an extension only participates in assembly (every `nodes` entry\n* is `kind: 'build'`, and it declares none of `providers`/`application`/\n* `provisions`/`container`) — it owns no resources or services, so it has\n* nothing to emulate and is exempt from local-target-capability requirements\n* (ADR-0041). Shared by `localTargetProviders` and every local-target hook\n* iteration.\n*/\nfunction isBuildOnlyExtension(extension) {\n\treturn Object.values(extension.nodes).every((node) => node.kind === \"build\") && extension.providers === void 0 && extension.application === void 0 && extension.provisions === void 0 && extension.container === void 0;\n}\n/** Typed identity — exists so `prisma-composer.config.ts` gets checked against PrismaAppConfig where it is written. */\nfunction defineConfig(config) {\n\treturn config;\n}\n//#endregion\nexport { defineConfig as n, isBuildOnlyExtension as r, DEV_DIR as t };\n\n//# sourceMappingURL=app-config-joXc-BKm.mjs.map"],"mappings":";;AAEA,MAAM,UAAU;;;;;;;;;AAShB,SAAS,qBAAqB,WAAW;CACxC,OAAO,OAAO,OAAO,UAAU,KAAK,CAAC,CAAC,OAAO,SAAS,KAAK,SAAS,OAAO,KAAK,UAAU,cAAc,KAAK,KAAK,UAAU,gBAAgB,KAAK,KAAK,UAAU,eAAe,KAAK,KAAK,UAAU,cAAc,KAAK;AACvN;;AAEA,SAAS,aAAa,QAAQ;CAC7B,OAAO;AACR"}
@@ -0,0 +1 @@
1
+ import "./app-config-S3etMyhL-B8jqbr7j.mjs";
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { A as containerEnvVarName, D as TeardownInput, E as StateDescriptor, M as deserializeContainers, S as PrismaAppConfig, d as ExtensionDescriptor, f as LocateContainerInput, j as defineConfig, k as containerEnv, o as ContainerDescriptor, s as ContainerInstance, v as NodeDescriptor, x as PreflightInput } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
- import "./config-BP2DrIX_.mjs";
3
- export { type ContainerDescriptor, type ContainerInstance, ExtensionDescriptor, type LocateContainerInput, NodeDescriptor, PreflightInput, PrismaAppConfig, StateDescriptor, TeardownInput, containerEnv, containerEnvVarName, defineConfig, deserializeContainers };
1
+ import { D as PreflightInput, F as containerEnv, I as containerEnvVarName, L as defineConfig, M as StateDescriptor, N as TeardownInput, O as PrismaAppConfig, R as deserializeContainers, _ as LocalTargetProvidersInput, c as DEV_DIR, f as ExtensionDescriptor, g as LocalTargetEmulatorsInput, h as LocalTargetDescriptor, m as LocalTargetAttachment, o as ContainerDescriptor, p as LocalTargetAttachInput, s as ContainerInstance, v as LocateContainerInput, w as NodeDescriptor, z as isBuildOnlyExtension } from "./app-config-S3etMyhL-B8jqbr7j.mjs";
2
+ import "./config-Dyw7i2w0.mjs";
3
+ export { type ContainerDescriptor, type ContainerInstance, DEV_DIR, ExtensionDescriptor, LocalTargetAttachInput, LocalTargetAttachment, LocalTargetDescriptor, LocalTargetEmulatorsInput, LocalTargetProvidersInput, type LocateContainerInput, NodeDescriptor, PreflightInput, PrismaAppConfig, StateDescriptor, TeardownInput, containerEnv, containerEnvVarName, defineConfig, deserializeContainers, isBuildOnlyExtension };
package/dist/config.mjs CHANGED
@@ -1,10 +1,3 @@
1
1
  import { n as containerEnvVarName, r as deserializeContainers, t as containerEnv } from "./container-transport-DKmKg5JQ-DKWs0ubK.mjs";
2
- //#region ../../0-framework/1-core/core/dist/config.mjs
3
- /** Typed identity exists so `prisma-composer.config.ts` gets checked against PrismaAppConfig where it is written. */
4
- function defineConfig(config) {
5
- return config;
6
- }
7
- //#endregion
8
- export { containerEnv, containerEnvVarName, defineConfig, deserializeContainers };
9
-
10
- //# sourceMappingURL=config.mjs.map
2
+ import { n as defineConfig, r as isBuildOnlyExtension, t as DEV_DIR } from "./app-config-joXc-BKm-CdcXqNMD.mjs";
3
+ export { DEV_DIR, containerEnv, containerEnvVarName, defineConfig, deserializeContainers, isBuildOnlyExtension };
@@ -0,0 +1 @@
1
+ import "./app-config-S3etMyhL-B8jqbr7j.mjs";
@@ -0,0 +1,313 @@
1
+ import { s as isParamSource, t as Load } from "./graph-CP16cJyH-D5IW87Y-.mjs";
2
+ import { r as deserializeContainers } from "./container-transport-DKmKg5JQ-DKWs0ubK.mjs";
3
+ import * as Alchemy from "alchemy";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ //#region ../../0-framework/1-core/core/dist/deploy-H3PKi0ZR.mjs
7
+ var LowerError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "LowerError";
11
+ }
12
+ };
13
+ /**
14
+ * Resolves one SERVICE-OWN param to its config value. The full resolution
15
+ * order across both value channels:
16
+ *
17
+ * 1. A param claiming BOTH a provision-time binding and a `provision` need
18
+ * (ADR-0031) is a loud error — two sources for one value.
19
+ * 2. A provision-time binding (a schema-validated literal, or an opaque
20
+ * `ParamSource` the target resolves at boot per ADR-0019) beats the
21
+ * declared `default`.
22
+ * 3. A framework-minted `provision` need is resolved per dependency EDGE
23
+ * against the consumer extension's registry — that path fills CONNECTION
24
+ * params in `buildConfig`'s inputs loop, never this function. A
25
+ * service-own param has no edge to mint against, so an unbound need here
26
+ * falls through like any unbound param.
27
+ * 4. The `default`, else absent (only legal when `optional`), else a loud
28
+ * error naming the param, the service, and the fix.
29
+ */
30
+ function resolveParam(node, serviceId, name, param, bound) {
31
+ if (bound !== void 0) {
32
+ if (param.provision !== void 0) throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") has two sources claiming one value: a provision-time binding (${isParamSource(bound) ? "a param source" : "a literal value"}) AND a framework provision need ("${String(param.provision.brand)}") on its declaration — remove the binding or drop the \`provision\` facet.`);
33
+ if (isParamSource(bound)) return bound;
34
+ const result = param.schema["~standard"].validate(bound);
35
+ if (result instanceof Promise) throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") uses an async Standard Schema — a provision-time literal value requires a synchronous validator.`);
36
+ if (result.issues !== void 0) {
37
+ const messages = result.issues.map((issue) => issue.message).join("; ");
38
+ throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") received an invalid provision-time value: ${messages}`);
39
+ }
40
+ return result.value;
41
+ }
42
+ if (param.default !== void 0) return param.default;
43
+ if (param.optional === true) return void 0;
44
+ throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") has no default, is not optional, and was not bound at provision — bind it with a literal value or a param source (e.g. envParam('NAME')) on its provision() call, or give it a default.`);
45
+ }
46
+ /**
47
+ * Assembles a service's typed Config. Connection params come from the
48
+ * dependency edge's lowered outputs — or, for a param carrying a `provision`
49
+ * need (ADR-0031), from `provisioned` (keyed by edge id): the framework mints
50
+ * it, the producer hands nothing over. The service's own params resolve via
51
+ * `resolveParam` (provision-time binding, then default, then loud
52
+ * unbound-required failure).
53
+ *
54
+ * This is also where the connection contract is enforced: a producer that fails to
55
+ * supply a required param its consumer's connection declares fails the deploy
56
+ * here, naming the edge, rather than reaching the consumer as `undefined`.
57
+ */
58
+ function buildConfig(node, id, graph, lowered, provisioned) {
59
+ const inputs = {};
60
+ for (const [inputName, inputNode] of Object.entries(node.inputs)) {
61
+ const edge = graph.edges.find((e) => e.to === id && e.input === inputName && e.kind === "dependency");
62
+ const producedOutputs = edge !== void 0 ? lowered.get(edge.from) ?? {} : {};
63
+ const values = {};
64
+ for (const [name, param] of Object.entries(inputNode.connection.params)) {
65
+ if (param.provision !== void 0) {
66
+ values[name] = provisioned.get(`${id}.${inputName}`);
67
+ continue;
68
+ }
69
+ const value = producedOutputs[name];
70
+ if (value === void 0 && param.optional !== true && edge !== void 0) throw new LowerError(`Connection input "${id}.${inputName}" declares param "${name}", but its producer "${edge.from}" did not supply it — the producer's outputs carry [${Object.keys(producedOutputs).join(", ") || "nothing"}]. Add "${name}" to the outputs the producer returns from its lowering, or declare the param optional on the connection.`);
71
+ values[name] = value;
72
+ }
73
+ inputs[inputName] = values;
74
+ }
75
+ const boundParams = new Map(graph.params.filter((binding) => binding.serviceAddress === id).map((b) => [b.slot, b.binding]));
76
+ const service = {};
77
+ for (const [name, param] of Object.entries(node.params)) {
78
+ const value = resolveParam(node, id, name, param, boundParams.get(name));
79
+ if (value !== void 0) service[name] = value;
80
+ }
81
+ return {
82
+ service,
83
+ inputs
84
+ };
85
+ }
86
+ /**
87
+ * Joins resolved report entries back to their graph nodes — the last step of a
88
+ * deploy report, run inside the Action with apply's resolved values.
89
+ *
90
+ * The entries cross Alchemy's action-input boundary, so they carry addresses
91
+ * and plain entities only; the graph is held by closure on this side. That
92
+ * split is why this join exists at all, and it is what keeps functions and
93
+ * Standard Schemas (which a node carries, and which the plan's input hash
94
+ * would have to serialize) out of the input.
95
+ *
96
+ * Skips an address the graph no longer holds: entries are data, the graph is
97
+ * truth.
98
+ */
99
+ function joinDeployment(graph, entries) {
100
+ const nodes = [];
101
+ for (const entry of entries) {
102
+ const node = graph.nodes.find((n) => n.id === entry.address)?.node;
103
+ if (node === void 0 || node.kind !== "service" && node.kind !== "resource") continue;
104
+ nodes.push({
105
+ address: entry.address,
106
+ node,
107
+ entities: entry.entities
108
+ });
109
+ }
110
+ return nodes;
111
+ }
112
+ function missingBundleError(id) {
113
+ return new LowerError(`No bundle provided for service "${id}" (opts.bundles["${id}"] is required).`);
114
+ }
115
+ function duplicateExtensionError(id) {
116
+ return new LowerError(`Extension "${id}" is listed more than once in \`extensions\` — each extension id must be unique.`);
117
+ }
118
+ /** Registries as extension id → descriptor. Fails on a duplicate id — the CLI validates config, but lowering() is the programmatic escape hatch that doesn't. */
119
+ function extensionsById(config) {
120
+ const map = /* @__PURE__ */ new Map();
121
+ for (const extension of config.extensions) {
122
+ if (map.has(extension.id)) return Effect.fail(duplicateExtensionError(extension.id));
123
+ map.set(extension.id, extension);
124
+ }
125
+ return Effect.succeed(map);
126
+ }
127
+ function unknownExtensionError(extension, id) {
128
+ return new LowerError(`No extension "${extension}" is configured (needed by node "${id}") — add it to prisma-composer.config.ts's \`extensions\` (import its /control entry and list its descriptor).`);
129
+ }
130
+ function unknownNodeTypeError(extension, type) {
131
+ return new LowerError(`Extension "${extension.id}" has no descriptor for node type "${type}" (known: ${Object.keys(extension.nodes).join(", ")}).`);
132
+ }
133
+ /** A provisioned param's need brand isn't registered by the consumer's extension (ADR-0031). */
134
+ function unknownProvisionerError(extension, brand, edgeId) {
135
+ const known = extension.provisions !== void 0 && extension.provisions.size > 0 ? Array.from(extension.provisions.keys(), String).join(", ") : "(none registered)";
136
+ return new LowerError(`Extension "${extension.id}" has no provisioner for need "${String(brand)}" (needed by edge "${edgeId}") (known: ${known}).`);
137
+ }
138
+ /** A provisioned edge whose consumer and provider nodes belong to different extensions (ADR-0031). */
139
+ function crossExtensionProvisionError(edgeId) {
140
+ return new LowerError(`Provisioned edge "${edgeId}" spans two extensions — cross-extension provisioned edges aren't supported yet.`);
141
+ }
142
+ /**
143
+ * More than one provisioned param on one connection (ADR-0031). One edge mints
144
+ * ONE value, keyed by edge id, so a second need on the same connection would
145
+ * silently receive the first's value under the first's brand.
146
+ */
147
+ function multipleProvisionedParamsError(edgeId, names) {
148
+ return new LowerError(`Connection input "${edgeId}" declares more than one provisioned param (${names.join(", ")}) — only one provisioned param per connection is supported.`);
149
+ }
150
+ function wrongKindError(extension, type, expected, got) {
151
+ return new LowerError(`Extension "${extension}"'s descriptor for node type "${type}" is a "${got}" descriptor — this node needs a "${expected}" descriptor.`);
152
+ }
153
+ /** Looks up one node's descriptor: extension by `node.extension`, then descriptor by `node.type`, then the kind check. */
154
+ function descriptorFor(extensions, node, id) {
155
+ const extension = extensions.get(node.extension);
156
+ if (extension === void 0) return Effect.fail(unknownExtensionError(node.extension, id));
157
+ const descriptor = extension.nodes[node.type];
158
+ if (descriptor === void 0) return Effect.fail(unknownNodeTypeError(extension, node.type));
159
+ if (descriptor.kind !== node.kind) return Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));
160
+ return Effect.succeed(descriptor);
161
+ }
162
+ /**
163
+ * The state-layer precedence a deploy resolves to: an explicit opts.state
164
+ * always wins; failing that, the config's own (required) state descriptor,
165
+ * created with its owning extension's resolved container (`undefined` when
166
+ * that extension declared none). A pure function so the precedence is
167
+ * testable without booting Alchemy.
168
+ */
169
+ function resolveStateLayer(opts, config, containers) {
170
+ return opts.state ?? config.state.create(containers.get(config.state.extension));
171
+ }
172
+ /**
173
+ * All configured extensions' providers merged, config array order — an
174
+ * extension without `providers` is skipped; no used-extensions-only
175
+ * filtering (ADR-0017's pinned providers rule).
176
+ */
177
+ function mergedProviders(config) {
178
+ const [first, ...rest] = config.extensions.flatMap((extension) => extension.providers !== void 0 ? [extension.providers()] : []);
179
+ return first === void 0 ? Layer.empty : Layer.mergeAll(first, ...rest);
180
+ }
181
+ /**
182
+ * Composable form for mixed stacks: hand-wired Alchemy resources alongside Prisma App nodes in one stack effect.
183
+ * Fails with LowerError or whatever an extension's lowering raises — the error type is open.
184
+ */
185
+ function lowering(root, config, opts) {
186
+ return Effect.gen(function* () {
187
+ const graph = Load(root, { id: opts.name });
188
+ const extensions = yield* extensionsById(config);
189
+ const containers = deserializeContainers(config.extensions, process.env);
190
+ const lowered = /* @__PURE__ */ new Map();
191
+ const entries = [];
192
+ const provisioned = /* @__PURE__ */ new Map();
193
+ const applications = /* @__PURE__ */ new Map();
194
+ for (const descriptor of config.extensions) {
195
+ if (descriptor.application === void 0) continue;
196
+ const appCtx = {
197
+ id: graph.root.id,
198
+ address: "",
199
+ node: graph.root.node,
200
+ graph,
201
+ opts,
202
+ application: void 0,
203
+ container: containers.get(descriptor.id),
204
+ lowered,
205
+ provisioned
206
+ };
207
+ applications.set(descriptor.id, yield* descriptor.application.provision(appCtx));
208
+ }
209
+ for (const edge of graph.edges) {
210
+ if (edge.kind !== "dependency") continue;
211
+ const consumer = graph.nodes.find((n) => n.id === edge.to)?.node;
212
+ if (consumer === void 0 || consumer.kind !== "service") continue;
213
+ const slot = consumer.inputs[edge.input];
214
+ if (slot === void 0) continue;
215
+ const provisionedParams = Object.entries(slot.connection.params).filter(([, param]) => param.provision !== void 0);
216
+ if (provisionedParams.length === 0) continue;
217
+ const edgeId = `${edge.to}.${edge.input}`;
218
+ if (provisionedParams.length > 1) return yield* Effect.fail(multipleProvisionedParamsError(edgeId, provisionedParams.map(([name]) => name)));
219
+ const need = provisionedParams[0]?.[1].provision;
220
+ if (need === void 0) continue;
221
+ const provider = graph.nodes.find((n) => n.id === edge.from)?.node;
222
+ if (provider === void 0 || provider.kind !== "service" && provider.kind !== "resource") continue;
223
+ if (consumer.extension !== provider.extension) return yield* Effect.fail(crossExtensionProvisionError(edgeId));
224
+ const extension = extensions.get(consumer.extension);
225
+ if (extension === void 0) return yield* Effect.fail(unknownExtensionError(consumer.extension, edge.to));
226
+ const provisioner = extension.provisions?.get(need.brand);
227
+ if (provisioner === void 0) return yield* Effect.fail(unknownProvisionerError(extension, need.brand, edgeId));
228
+ const ref = yield* provisioner.provision({
229
+ edgeId,
230
+ consumerAddress: edge.to,
231
+ providerAddress: edge.from,
232
+ input: edge.input,
233
+ need
234
+ });
235
+ provisioned.set(edgeId, ref);
236
+ }
237
+ for (const { id, node } of graph.nodes) {
238
+ if (node.kind === "module") continue;
239
+ if (node.kind === "dependency") continue;
240
+ const ctx = {
241
+ id,
242
+ address: id,
243
+ node,
244
+ graph,
245
+ opts,
246
+ application: applications.get(node.extension),
247
+ container: containers.get(node.extension),
248
+ lowered,
249
+ provisioned
250
+ };
251
+ const descriptor = yield* descriptorFor(extensions, node, id);
252
+ if (descriptor.kind === "resource") {
253
+ const result = yield* descriptor(ctx);
254
+ lowered.set(id, result.outputs);
255
+ entries.push({
256
+ address: id,
257
+ entities: result.entities
258
+ });
259
+ continue;
260
+ }
261
+ if (descriptor.kind !== "service") return yield* Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));
262
+ const service = node;
263
+ const provisionedNode = yield* descriptor.provision(ctx);
264
+ const typedConfig = buildConfig(service, id, graph, lowered, provisioned);
265
+ const serialized = yield* descriptor.serialize(ctx, provisionedNode, typedConfig);
266
+ const bundle = opts.bundles[id];
267
+ if (bundle === void 0) return yield* Effect.fail(missingBundleError(id));
268
+ const artifact = yield* descriptor.package(ctx, {
269
+ assembled: {
270
+ dir: bundle.dir,
271
+ entry: bundle.entry
272
+ },
273
+ address: id
274
+ });
275
+ const result = yield* descriptor.deploy(ctx, provisionedNode, artifact, serialized);
276
+ lowered.set(id, result.outputs);
277
+ entries.push({
278
+ address: id,
279
+ entities: result.entities
280
+ });
281
+ }
282
+ if (opts.report !== void 0) {
283
+ const report = opts.report;
284
+ yield* Alchemy.Action("composer-deployment-report", (input) => Effect.sync(() => {
285
+ report({
286
+ app: opts.name,
287
+ nodes: joinDeployment(graph, input.entries)
288
+ });
289
+ }))({
290
+ nonce: Date.now(),
291
+ entries
292
+ });
293
+ }
294
+ });
295
+ }
296
+ /**
297
+ * The whole-stack wrapper: Load → route each node through the config's
298
+ * extension registries → an Alchemy Stack (the default export the alchemy
299
+ * CLI consumes).
300
+ */
301
+ function lower(root, config, opts) {
302
+ const stackEffect = Effect.orDie(lowering(root, config, opts));
303
+ const containers = deserializeContainers(config.extensions, process.env);
304
+ const providers = opts.providers ?? mergedProviders(config);
305
+ return Alchemy.Stack(opts.name, {
306
+ providers,
307
+ state: resolveStateLayer(opts, config, containers)
308
+ }, stackEffect);
309
+ }
310
+ //#endregion
311
+ export { lowering as a, lower as i, buildConfig as n, mergedProviders as o, joinDeployment as r, resolveStateLayer as s, LowerError as t };
312
+
313
+ //# sourceMappingURL=deploy-H3PKi0ZR-Chgm12Bn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-H3PKi0ZR-Chgm12Bn.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/deploy-H3PKi0ZR.mjs"],"sourcesContent":["import { o as isParamSource, t as Load } from \"./graph-CP16cJyH.mjs\";\nimport { r as deserializeContainers } from \"./container-transport-DKmKg5JQ.mjs\";\nimport * as Alchemy from \"alchemy\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\n//#region src/control/deploy.ts\nvar LowerError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = \"LowerError\";\n\t}\n};\n/**\n* Resolves one SERVICE-OWN param to its config value. The full resolution\n* order across both value channels:\n*\n* 1. A param claiming BOTH a provision-time binding and a `provision` need\n* (ADR-0031) is a loud error — two sources for one value.\n* 2. A provision-time binding (a schema-validated literal, or an opaque\n* `ParamSource` the target resolves at boot per ADR-0019) beats the\n* declared `default`.\n* 3. A framework-minted `provision` need is resolved per dependency EDGE\n* against the consumer extension's registry — that path fills CONNECTION\n* params in `buildConfig`'s inputs loop, never this function. A\n* service-own param has no edge to mint against, so an unbound need here\n* falls through like any unbound param.\n* 4. The `default`, else absent (only legal when `optional`), else a loud\n* error naming the param, the service, and the fix.\n*/\nfunction resolveParam(node, serviceId, name, param, bound) {\n\tif (bound !== void 0) {\n\t\tif (param.provision !== void 0) throw new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") has two sources claiming one value: a provision-time binding (${isParamSource(bound) ? \"a param source\" : \"a literal value\"}) AND a framework provision need (\"${String(param.provision.brand)}\") on its declaration — remove the binding or drop the \\`provision\\` facet.`);\n\t\tif (isParamSource(bound)) return bound;\n\t\tconst result = param.schema[\"~standard\"].validate(bound);\n\t\tif (result instanceof Promise) throw new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") uses an async Standard Schema — a provision-time literal value requires a synchronous validator.`);\n\t\tif (result.issues !== void 0) {\n\t\t\tconst messages = result.issues.map((issue) => issue.message).join(\"; \");\n\t\t\tthrow new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") received an invalid provision-time value: ${messages}`);\n\t\t}\n\t\treturn result.value;\n\t}\n\tif (param.default !== void 0) return param.default;\n\tif (param.optional === true) return void 0;\n\tthrow new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") has no default, is not optional, and was not bound at provision — bind it with a literal value or a param source (e.g. envParam('NAME')) on its provision() call, or give it a default.`);\n}\n/**\n* Assembles a service's typed Config. Connection params come from the\n* dependency edge's lowered outputs — or, for a param carrying a `provision`\n* need (ADR-0031), from `provisioned` (keyed by edge id): the framework mints\n* it, the producer hands nothing over. The service's own params resolve via\n* `resolveParam` (provision-time binding, then default, then loud\n* unbound-required failure).\n*\n* This is also where the connection contract is enforced: a producer that fails to\n* supply a required param its consumer's connection declares fails the deploy\n* here, naming the edge, rather than reaching the consumer as `undefined`.\n*/\nfunction buildConfig(node, id, graph, lowered, provisioned) {\n\tconst inputs = {};\n\tfor (const [inputName, inputNode] of Object.entries(node.inputs)) {\n\t\tconst edge = graph.edges.find((e) => e.to === id && e.input === inputName && e.kind === \"dependency\");\n\t\tconst producedOutputs = edge !== void 0 ? lowered.get(edge.from) ?? {} : {};\n\t\tconst values = {};\n\t\tfor (const [name, param] of Object.entries(inputNode.connection.params)) {\n\t\t\tif (param.provision !== void 0) {\n\t\t\t\tvalues[name] = provisioned.get(`${id}.${inputName}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst value = producedOutputs[name];\n\t\t\tif (value === void 0 && param.optional !== true && edge !== void 0) throw new LowerError(`Connection input \"${id}.${inputName}\" declares param \"${name}\", but its producer \"${edge.from}\" did not supply it — the producer's outputs carry [${Object.keys(producedOutputs).join(\", \") || \"nothing\"}]. Add \"${name}\" to the outputs the producer returns from its lowering, or declare the param optional on the connection.`);\n\t\t\tvalues[name] = value;\n\t\t}\n\t\tinputs[inputName] = values;\n\t}\n\tconst boundParams = new Map(graph.params.filter((binding) => binding.serviceAddress === id).map((b) => [b.slot, b.binding]));\n\tconst service = {};\n\tfor (const [name, param] of Object.entries(node.params)) {\n\t\tconst value = resolveParam(node, id, name, param, boundParams.get(name));\n\t\tif (value !== void 0) service[name] = value;\n\t}\n\treturn {\n\t\tservice,\n\t\tinputs\n\t};\n}\n/**\n* Joins resolved report entries back to their graph nodes — the last step of a\n* deploy report, run inside the Action with apply's resolved values.\n*\n* The entries cross Alchemy's action-input boundary, so they carry addresses\n* and plain entities only; the graph is held by closure on this side. That\n* split is why this join exists at all, and it is what keeps functions and\n* Standard Schemas (which a node carries, and which the plan's input hash\n* would have to serialize) out of the input.\n*\n* Skips an address the graph no longer holds: entries are data, the graph is\n* truth.\n*/\nfunction joinDeployment(graph, entries) {\n\tconst nodes = [];\n\tfor (const entry of entries) {\n\t\tconst node = graph.nodes.find((n) => n.id === entry.address)?.node;\n\t\tif (node === void 0 || node.kind !== \"service\" && node.kind !== \"resource\") continue;\n\t\tnodes.push({\n\t\t\taddress: entry.address,\n\t\t\tnode,\n\t\t\tentities: entry.entities\n\t\t});\n\t}\n\treturn nodes;\n}\nfunction missingBundleError(id) {\n\treturn new LowerError(`No bundle provided for service \"${id}\" (opts.bundles[\"${id}\"] is required).`);\n}\nfunction duplicateExtensionError(id) {\n\treturn new LowerError(`Extension \"${id}\" is listed more than once in \\`extensions\\` — each extension id must be unique.`);\n}\n/** Registries as extension id → descriptor. Fails on a duplicate id — the CLI validates config, but lowering() is the programmatic escape hatch that doesn't. */\nfunction extensionsById(config) {\n\tconst map = /* @__PURE__ */ new Map();\n\tfor (const extension of config.extensions) {\n\t\tif (map.has(extension.id)) return Effect.fail(duplicateExtensionError(extension.id));\n\t\tmap.set(extension.id, extension);\n\t}\n\treturn Effect.succeed(map);\n}\nfunction unknownExtensionError(extension, id) {\n\treturn new LowerError(`No extension \"${extension}\" is configured (needed by node \"${id}\") — add it to prisma-composer.config.ts's \\`extensions\\` (import its /control entry and list its descriptor).`);\n}\nfunction unknownNodeTypeError(extension, type) {\n\treturn new LowerError(`Extension \"${extension.id}\" has no descriptor for node type \"${type}\" (known: ${Object.keys(extension.nodes).join(\", \")}).`);\n}\n/** A provisioned param's need brand isn't registered by the consumer's extension (ADR-0031). */\nfunction unknownProvisionerError(extension, brand, edgeId) {\n\tconst known = extension.provisions !== void 0 && extension.provisions.size > 0 ? Array.from(extension.provisions.keys(), String).join(\", \") : \"(none registered)\";\n\treturn new LowerError(`Extension \"${extension.id}\" has no provisioner for need \"${String(brand)}\" (needed by edge \"${edgeId}\") (known: ${known}).`);\n}\n/** A provisioned edge whose consumer and provider nodes belong to different extensions (ADR-0031). */\nfunction crossExtensionProvisionError(edgeId) {\n\treturn new LowerError(`Provisioned edge \"${edgeId}\" spans two extensions — cross-extension provisioned edges aren't supported yet.`);\n}\n/**\n* More than one provisioned param on one connection (ADR-0031). One edge mints\n* ONE value, keyed by edge id, so a second need on the same connection would\n* silently receive the first's value under the first's brand.\n*/\nfunction multipleProvisionedParamsError(edgeId, names) {\n\treturn new LowerError(`Connection input \"${edgeId}\" declares more than one provisioned param (${names.join(\", \")}) — only one provisioned param per connection is supported.`);\n}\nfunction wrongKindError(extension, type, expected, got) {\n\treturn new LowerError(`Extension \"${extension}\"'s descriptor for node type \"${type}\" is a \"${got}\" descriptor — this node needs a \"${expected}\" descriptor.`);\n}\n/** Looks up one node's descriptor: extension by `node.extension`, then descriptor by `node.type`, then the kind check. */\nfunction descriptorFor(extensions, node, id) {\n\tconst extension = extensions.get(node.extension);\n\tif (extension === void 0) return Effect.fail(unknownExtensionError(node.extension, id));\n\tconst descriptor = extension.nodes[node.type];\n\tif (descriptor === void 0) return Effect.fail(unknownNodeTypeError(extension, node.type));\n\tif (descriptor.kind !== node.kind) return Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));\n\treturn Effect.succeed(descriptor);\n}\n/**\n* The state-layer precedence a deploy resolves to: an explicit opts.state\n* always wins; failing that, the config's own (required) state descriptor,\n* created with its owning extension's resolved container (`undefined` when\n* that extension declared none). A pure function so the precedence is\n* testable without booting Alchemy.\n*/\nfunction resolveStateLayer(opts, config, containers) {\n\treturn opts.state ?? config.state.create(containers.get(config.state.extension));\n}\n/**\n* All configured extensions' providers merged, config array order — an\n* extension without `providers` is skipped; no used-extensions-only\n* filtering (ADR-0017's pinned providers rule).\n*/\nfunction mergedProviders(config) {\n\tconst [first, ...rest] = config.extensions.flatMap((extension) => extension.providers !== void 0 ? [extension.providers()] : []);\n\treturn first === void 0 ? Layer.empty : Layer.mergeAll(first, ...rest);\n}\n/**\n* Composable form for mixed stacks: hand-wired Alchemy resources alongside Prisma App nodes in one stack effect.\n* Fails with LowerError or whatever an extension's lowering raises — the error type is open.\n*/\nfunction lowering(root, config, opts) {\n\treturn Effect.gen(function* () {\n\t\tconst graph = Load(root, { id: opts.name });\n\t\tconst extensions = yield* extensionsById(config);\n\t\tconst containers = deserializeContainers(config.extensions, process.env);\n\t\tconst lowered = /* @__PURE__ */ new Map();\n\t\tconst entries = [];\n\t\tconst provisioned = /* @__PURE__ */ new Map();\n\t\tconst applications = /* @__PURE__ */ new Map();\n\t\tfor (const descriptor of config.extensions) {\n\t\t\tif (descriptor.application === void 0) continue;\n\t\t\tconst appCtx = {\n\t\t\t\tid: graph.root.id,\n\t\t\t\taddress: \"\",\n\t\t\t\tnode: graph.root.node,\n\t\t\t\tgraph,\n\t\t\t\topts,\n\t\t\t\tapplication: void 0,\n\t\t\t\tcontainer: containers.get(descriptor.id),\n\t\t\t\tlowered,\n\t\t\t\tprovisioned\n\t\t\t};\n\t\t\tapplications.set(descriptor.id, yield* descriptor.application.provision(appCtx));\n\t\t}\n\t\tfor (const edge of graph.edges) {\n\t\t\tif (edge.kind !== \"dependency\") continue;\n\t\t\tconst consumer = graph.nodes.find((n) => n.id === edge.to)?.node;\n\t\t\tif (consumer === void 0 || consumer.kind !== \"service\") continue;\n\t\t\tconst slot = consumer.inputs[edge.input];\n\t\t\tif (slot === void 0) continue;\n\t\t\tconst provisionedParams = Object.entries(slot.connection.params).filter(([, param]) => param.provision !== void 0);\n\t\t\tif (provisionedParams.length === 0) continue;\n\t\t\tconst edgeId = `${edge.to}.${edge.input}`;\n\t\t\tif (provisionedParams.length > 1) return yield* Effect.fail(multipleProvisionedParamsError(edgeId, provisionedParams.map(([name]) => name)));\n\t\t\tconst need = provisionedParams[0]?.[1].provision;\n\t\t\tif (need === void 0) continue;\n\t\t\tconst provider = graph.nodes.find((n) => n.id === edge.from)?.node;\n\t\t\tif (provider === void 0 || provider.kind !== \"service\" && provider.kind !== \"resource\") continue;\n\t\t\tif (consumer.extension !== provider.extension) return yield* Effect.fail(crossExtensionProvisionError(edgeId));\n\t\t\tconst extension = extensions.get(consumer.extension);\n\t\t\tif (extension === void 0) return yield* Effect.fail(unknownExtensionError(consumer.extension, edge.to));\n\t\t\tconst provisioner = extension.provisions?.get(need.brand);\n\t\t\tif (provisioner === void 0) return yield* Effect.fail(unknownProvisionerError(extension, need.brand, edgeId));\n\t\t\tconst ref = yield* provisioner.provision({\n\t\t\t\tedgeId,\n\t\t\t\tconsumerAddress: edge.to,\n\t\t\t\tproviderAddress: edge.from,\n\t\t\t\tinput: edge.input,\n\t\t\t\tneed\n\t\t\t});\n\t\t\tprovisioned.set(edgeId, ref);\n\t\t}\n\t\tfor (const { id, node } of graph.nodes) {\n\t\t\tif (node.kind === \"module\") continue;\n\t\t\tif (node.kind === \"dependency\") continue;\n\t\t\tconst ctx = {\n\t\t\t\tid,\n\t\t\t\taddress: id,\n\t\t\t\tnode,\n\t\t\t\tgraph,\n\t\t\t\topts,\n\t\t\t\tapplication: applications.get(node.extension),\n\t\t\t\tcontainer: containers.get(node.extension),\n\t\t\t\tlowered,\n\t\t\t\tprovisioned\n\t\t\t};\n\t\t\tconst descriptor = yield* descriptorFor(extensions, node, id);\n\t\t\tif (descriptor.kind === \"resource\") {\n\t\t\t\tconst result = yield* descriptor(ctx);\n\t\t\t\tlowered.set(id, result.outputs);\n\t\t\t\tentries.push({\n\t\t\t\t\taddress: id,\n\t\t\t\t\tentities: result.entities\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (descriptor.kind !== \"service\") return yield* Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));\n\t\t\tconst service = node;\n\t\t\tconst provisionedNode = yield* descriptor.provision(ctx);\n\t\t\tconst typedConfig = buildConfig(service, id, graph, lowered, provisioned);\n\t\t\tconst serialized = yield* descriptor.serialize(ctx, provisionedNode, typedConfig);\n\t\t\tconst bundle = opts.bundles[id];\n\t\t\tif (bundle === void 0) return yield* Effect.fail(missingBundleError(id));\n\t\t\tconst artifact = yield* descriptor.package(ctx, {\n\t\t\t\tassembled: {\n\t\t\t\t\tdir: bundle.dir,\n\t\t\t\t\tentry: bundle.entry\n\t\t\t\t},\n\t\t\t\taddress: id\n\t\t\t});\n\t\t\tconst result = yield* descriptor.deploy(ctx, provisionedNode, artifact, serialized);\n\t\t\tlowered.set(id, result.outputs);\n\t\t\tentries.push({\n\t\t\t\taddress: id,\n\t\t\t\tentities: result.entities\n\t\t\t});\n\t\t}\n\t\tif (opts.report !== void 0) {\n\t\t\tconst report = opts.report;\n\t\t\tyield* Alchemy.Action(\"composer-deployment-report\", (input) => Effect.sync(() => {\n\t\t\t\treport({\n\t\t\t\t\tapp: opts.name,\n\t\t\t\t\tnodes: joinDeployment(graph, input.entries)\n\t\t\t\t});\n\t\t\t}))({\n\t\t\t\tnonce: Date.now(),\n\t\t\t\tentries\n\t\t\t});\n\t\t}\n\t});\n}\n/**\n* The whole-stack wrapper: Load → route each node through the config's\n* extension registries → an Alchemy Stack (the default export the alchemy\n* CLI consumes).\n*/\nfunction lower(root, config, opts) {\n\tconst stackEffect = Effect.orDie(lowering(root, config, opts));\n\tconst containers = deserializeContainers(config.extensions, process.env);\n\tconst providers = opts.providers ?? mergedProviders(config);\n\treturn Alchemy.Stack(opts.name, {\n\t\tproviders,\n\t\tstate: resolveStateLayer(opts, config, containers)\n\t}, stackEffect);\n}\n//#endregion\nexport { lowering as a, lower as i, buildConfig as n, mergedProviders as o, joinDeployment as r, resolveStateLayer as s, LowerError as t };\n\n//# sourceMappingURL=deploy-H3PKi0ZR.mjs.map"],"mappings":"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"}
package/dist/deploy.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { C as ProvisionEdge, F as lowering, I as mergedProviders, L as resolveStateLayer, N as joinDeployment, O as buildConfig, P as lower, T as ServiceLowering, _ as Lowering, a as Bundle, b as PackageInput, c as DeployedEntity, g as LoweredResult, h as LowerOptions, i as AssembleInput, l as DeployedNode, m as LowerError, n as ApplicationDescriptor, p as LowerContext, r as Artifact, t as AlchemyStateLayer, u as DeploymentResult, w as ProvisionerDescriptor, y as Outputs } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
- import "./deploy-BP2DrIX_.mjs";
1
+ import { A as ProvisionerDescriptor, B as joinDeployment, C as Lowering, E as PackageInput, H as lowering, P as buildConfig, S as LoweredResult, T as Outputs, U as mergedProviders, V as lower, W as resolveStateLayer, a as Bundle, b as LowerError, d as DeploymentResult, i as AssembleInput, j as ServiceLowering, k as ProvisionEdge, l as DeployedEntity, n as ApplicationDescriptor, r as Artifact, t as AlchemyStateLayer, u as DeployedNode, x as LowerOptions, y as LowerContext } from "./app-config-S3etMyhL-B8jqbr7j.mjs";
2
+ import "./deploy-Dyw7i2w0.mjs";
3
3
  export { AlchemyStateLayer, ApplicationDescriptor, Artifact, AssembleInput, Bundle, DeployedEntity, DeployedNode, DeploymentResult, LowerContext, LowerError, LowerOptions, LoweredResult, Lowering, Outputs, PackageInput, ProvisionEdge, ProvisionerDescriptor, ServiceLowering, buildConfig, joinDeployment, lower, lowering, mergedProviders, resolveStateLayer };
package/dist/deploy.mjs CHANGED
@@ -1,312 +1,2 @@
1
- import { s as isParamSource, t as Load } from "./graph-CP16cJyH-D5IW87Y-.mjs";
2
- import { r as deserializeContainers } from "./container-transport-DKmKg5JQ-DKWs0ubK.mjs";
3
- import * as Alchemy from "alchemy";
4
- import * as Effect from "effect/Effect";
5
- import * as Layer from "effect/Layer";
6
- //#region ../../0-framework/1-core/core/dist/deploy.mjs
7
- var LowerError = class extends Error {
8
- constructor(message) {
9
- super(message);
10
- this.name = "LowerError";
11
- }
12
- };
13
- /**
14
- * Resolves one SERVICE-OWN param to its config value. The full resolution
15
- * order across both value channels:
16
- *
17
- * 1. A param claiming BOTH a provision-time binding and a `provision` need
18
- * (ADR-0031) is a loud error — two sources for one value.
19
- * 2. A provision-time binding (a schema-validated literal, or an opaque
20
- * `ParamSource` the target resolves at boot per ADR-0019) beats the
21
- * declared `default`.
22
- * 3. A framework-minted `provision` need is resolved per dependency EDGE
23
- * against the consumer extension's registry — that path fills CONNECTION
24
- * params in `buildConfig`'s inputs loop, never this function. A
25
- * service-own param has no edge to mint against, so an unbound need here
26
- * falls through like any unbound param.
27
- * 4. The `default`, else absent (only legal when `optional`), else a loud
28
- * error naming the param, the service, and the fix.
29
- */
30
- function resolveParam(node, serviceId, name, param, bound) {
31
- if (bound !== void 0) {
32
- if (param.provision !== void 0) throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") has two sources claiming one value: a provision-time binding (${isParamSource(bound) ? "a param source" : "a literal value"}) AND a framework provision need ("${String(param.provision.brand)}") on its declaration — remove the binding or drop the \`provision\` facet.`);
33
- if (isParamSource(bound)) return bound;
34
- const result = param.schema["~standard"].validate(bound);
35
- if (result instanceof Promise) throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") uses an async Standard Schema — a provision-time literal value requires a synchronous validator.`);
36
- if (result.issues !== void 0) {
37
- const messages = result.issues.map((issue) => issue.message).join("; ");
38
- throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") received an invalid provision-time value: ${messages}`);
39
- }
40
- return result.value;
41
- }
42
- if (param.default !== void 0) return param.default;
43
- if (param.optional === true) return void 0;
44
- throw new LowerError(`Param "${name}" of "${serviceId}" (service "${node.name}") has no default, is not optional, and was not bound at provision — bind it with a literal value or a param source (e.g. envParam('NAME')) on its provision() call, or give it a default.`);
45
- }
46
- /**
47
- * Assembles a service's typed Config. Connection params come from the
48
- * dependency edge's lowered outputs — or, for a param carrying a `provision`
49
- * need (ADR-0031), from `provisioned` (keyed by edge id): the framework mints
50
- * it, the producer hands nothing over. The service's own params resolve via
51
- * `resolveParam` (provision-time binding, then default, then loud
52
- * unbound-required failure).
53
- *
54
- * This is also where the connection contract is enforced: a producer that fails to
55
- * supply a required param its consumer's connection declares fails the deploy
56
- * here, naming the edge, rather than reaching the consumer as `undefined`.
57
- */
58
- function buildConfig(node, id, graph, lowered, provisioned) {
59
- const inputs = {};
60
- for (const [inputName, inputNode] of Object.entries(node.inputs)) {
61
- const edge = graph.edges.find((e) => e.to === id && e.input === inputName && e.kind === "dependency");
62
- const producedOutputs = edge !== void 0 ? lowered.get(edge.from) ?? {} : {};
63
- const values = {};
64
- for (const [name, param] of Object.entries(inputNode.connection.params)) {
65
- if (param.provision !== void 0) {
66
- values[name] = provisioned.get(`${id}.${inputName}`);
67
- continue;
68
- }
69
- const value = producedOutputs[name];
70
- if (value === void 0 && param.optional !== true && edge !== void 0) throw new LowerError(`Connection input "${id}.${inputName}" declares param "${name}", but its producer "${edge.from}" did not supply it — the producer's outputs carry [${Object.keys(producedOutputs).join(", ") || "nothing"}]. Add "${name}" to the outputs the producer returns from its lowering, or declare the param optional on the connection.`);
71
- values[name] = value;
72
- }
73
- inputs[inputName] = values;
74
- }
75
- const boundParams = new Map(graph.params.filter((binding) => binding.serviceAddress === id).map((b) => [b.slot, b.binding]));
76
- const service = {};
77
- for (const [name, param] of Object.entries(node.params)) {
78
- const value = resolveParam(node, id, name, param, boundParams.get(name));
79
- if (value !== void 0) service[name] = value;
80
- }
81
- return {
82
- service,
83
- inputs
84
- };
85
- }
86
- /**
87
- * Joins resolved report entries back to their graph nodes — the last step of a
88
- * deploy report, run inside the Action with apply's resolved values.
89
- *
90
- * The entries cross Alchemy's action-input boundary, so they carry addresses
91
- * and plain entities only; the graph is held by closure on this side. That
92
- * split is why this join exists at all, and it is what keeps functions and
93
- * Standard Schemas (which a node carries, and which the plan's input hash
94
- * would have to serialize) out of the input.
95
- *
96
- * Skips an address the graph no longer holds: entries are data, the graph is
97
- * truth.
98
- */
99
- function joinDeployment(graph, entries) {
100
- const nodes = [];
101
- for (const entry of entries) {
102
- const node = graph.nodes.find((n) => n.id === entry.address)?.node;
103
- if (node === void 0 || node.kind !== "service" && node.kind !== "resource") continue;
104
- nodes.push({
105
- address: entry.address,
106
- node,
107
- entities: entry.entities
108
- });
109
- }
110
- return nodes;
111
- }
112
- function missingBundleError(id) {
113
- return new LowerError(`No bundle provided for service "${id}" (opts.bundles["${id}"] is required).`);
114
- }
115
- function duplicateExtensionError(id) {
116
- return new LowerError(`Extension "${id}" is listed more than once in \`extensions\` — each extension id must be unique.`);
117
- }
118
- /** Registries as extension id → descriptor. Fails on a duplicate id — the CLI validates config, but lowering() is the programmatic escape hatch that doesn't. */
119
- function extensionsById(config) {
120
- const map = /* @__PURE__ */ new Map();
121
- for (const extension of config.extensions) {
122
- if (map.has(extension.id)) return Effect.fail(duplicateExtensionError(extension.id));
123
- map.set(extension.id, extension);
124
- }
125
- return Effect.succeed(map);
126
- }
127
- function unknownExtensionError(extension, id) {
128
- return new LowerError(`No extension "${extension}" is configured (needed by node "${id}") — add it to prisma-composer.config.ts's \`extensions\` (import its /control entry and list its descriptor).`);
129
- }
130
- function unknownNodeTypeError(extension, type) {
131
- return new LowerError(`Extension "${extension.id}" has no descriptor for node type "${type}" (known: ${Object.keys(extension.nodes).join(", ")}).`);
132
- }
133
- /** A provisioned param's need brand isn't registered by the consumer's extension (ADR-0031). */
134
- function unknownProvisionerError(extension, brand, edgeId) {
135
- const known = extension.provisions !== void 0 && extension.provisions.size > 0 ? Array.from(extension.provisions.keys(), String).join(", ") : "(none registered)";
136
- return new LowerError(`Extension "${extension.id}" has no provisioner for need "${String(brand)}" (needed by edge "${edgeId}") (known: ${known}).`);
137
- }
138
- /** A provisioned edge whose consumer and provider nodes belong to different extensions (ADR-0031). */
139
- function crossExtensionProvisionError(edgeId) {
140
- return new LowerError(`Provisioned edge "${edgeId}" spans two extensions — cross-extension provisioned edges aren't supported yet.`);
141
- }
142
- /**
143
- * More than one provisioned param on one connection (ADR-0031). One edge mints
144
- * ONE value, keyed by edge id, so a second need on the same connection would
145
- * silently receive the first's value under the first's brand.
146
- */
147
- function multipleProvisionedParamsError(edgeId, names) {
148
- return new LowerError(`Connection input "${edgeId}" declares more than one provisioned param (${names.join(", ")}) — only one provisioned param per connection is supported.`);
149
- }
150
- function wrongKindError(extension, type, expected, got) {
151
- return new LowerError(`Extension "${extension}"'s descriptor for node type "${type}" is a "${got}" descriptor — this node needs a "${expected}" descriptor.`);
152
- }
153
- /** Looks up one node's descriptor: extension by `node.extension`, then descriptor by `node.type`, then the kind check. */
154
- function descriptorFor(extensions, node, id) {
155
- const extension = extensions.get(node.extension);
156
- if (extension === void 0) return Effect.fail(unknownExtensionError(node.extension, id));
157
- const descriptor = extension.nodes[node.type];
158
- if (descriptor === void 0) return Effect.fail(unknownNodeTypeError(extension, node.type));
159
- if (descriptor.kind !== node.kind) return Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));
160
- return Effect.succeed(descriptor);
161
- }
162
- /**
163
- * The state-layer precedence a deploy resolves to: an explicit opts.state
164
- * always wins; failing that, the config's own (required) state descriptor,
165
- * created with its owning extension's resolved container (`undefined` when
166
- * that extension declared none). A pure function so the precedence is
167
- * testable without booting Alchemy.
168
- */
169
- function resolveStateLayer(opts, config, containers) {
170
- return opts.state ?? config.state.create(containers.get(config.state.extension));
171
- }
172
- /**
173
- * All configured extensions' providers merged, config array order — an
174
- * extension without `providers` is skipped; no used-extensions-only
175
- * filtering (ADR-0017's pinned providers rule).
176
- */
177
- function mergedProviders(config) {
178
- const [first, ...rest] = config.extensions.flatMap((extension) => extension.providers !== void 0 ? [extension.providers()] : []);
179
- return first === void 0 ? Layer.empty : Layer.mergeAll(first, ...rest);
180
- }
181
- /**
182
- * Composable form for mixed stacks: hand-wired Alchemy resources alongside Prisma App nodes in one stack effect.
183
- * Fails with LowerError or whatever an extension's lowering raises — the error type is open.
184
- */
185
- function lowering(root, config, opts) {
186
- return Effect.gen(function* () {
187
- const graph = Load(root, { id: opts.name });
188
- const extensions = yield* extensionsById(config);
189
- const containers = deserializeContainers(config.extensions, process.env);
190
- const lowered = /* @__PURE__ */ new Map();
191
- const entries = [];
192
- const provisioned = /* @__PURE__ */ new Map();
193
- const applications = /* @__PURE__ */ new Map();
194
- for (const descriptor of config.extensions) {
195
- if (descriptor.application === void 0) continue;
196
- const appCtx = {
197
- id: graph.root.id,
198
- address: "",
199
- node: graph.root.node,
200
- graph,
201
- opts,
202
- application: void 0,
203
- container: containers.get(descriptor.id),
204
- lowered,
205
- provisioned
206
- };
207
- applications.set(descriptor.id, yield* descriptor.application.provision(appCtx));
208
- }
209
- for (const edge of graph.edges) {
210
- if (edge.kind !== "dependency") continue;
211
- const consumer = graph.nodes.find((n) => n.id === edge.to)?.node;
212
- if (consumer === void 0 || consumer.kind !== "service") continue;
213
- const slot = consumer.inputs[edge.input];
214
- if (slot === void 0) continue;
215
- const provisionedParams = Object.entries(slot.connection.params).filter(([, param]) => param.provision !== void 0);
216
- if (provisionedParams.length === 0) continue;
217
- const edgeId = `${edge.to}.${edge.input}`;
218
- if (provisionedParams.length > 1) return yield* Effect.fail(multipleProvisionedParamsError(edgeId, provisionedParams.map(([name]) => name)));
219
- const need = provisionedParams[0]?.[1].provision;
220
- if (need === void 0) continue;
221
- const provider = graph.nodes.find((n) => n.id === edge.from)?.node;
222
- if (provider === void 0 || provider.kind !== "service" && provider.kind !== "resource") continue;
223
- if (consumer.extension !== provider.extension) return yield* Effect.fail(crossExtensionProvisionError(edgeId));
224
- const extension = extensions.get(consumer.extension);
225
- if (extension === void 0) return yield* Effect.fail(unknownExtensionError(consumer.extension, edge.to));
226
- const provisioner = extension.provisions?.get(need.brand);
227
- if (provisioner === void 0) return yield* Effect.fail(unknownProvisionerError(extension, need.brand, edgeId));
228
- const ref = yield* provisioner.provision({
229
- edgeId,
230
- consumerAddress: edge.to,
231
- providerAddress: edge.from,
232
- input: edge.input,
233
- need
234
- });
235
- provisioned.set(edgeId, ref);
236
- }
237
- for (const { id, node } of graph.nodes) {
238
- if (node.kind === "module") continue;
239
- if (node.kind === "dependency") continue;
240
- const ctx = {
241
- id,
242
- address: id,
243
- node,
244
- graph,
245
- opts,
246
- application: applications.get(node.extension),
247
- container: containers.get(node.extension),
248
- lowered,
249
- provisioned
250
- };
251
- const descriptor = yield* descriptorFor(extensions, node, id);
252
- if (descriptor.kind === "resource") {
253
- const result = yield* descriptor(ctx);
254
- lowered.set(id, result.outputs);
255
- entries.push({
256
- address: id,
257
- entities: result.entities
258
- });
259
- continue;
260
- }
261
- if (descriptor.kind !== "service") return yield* Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));
262
- const service = node;
263
- const provisionedNode = yield* descriptor.provision(ctx);
264
- const typedConfig = buildConfig(service, id, graph, lowered, provisioned);
265
- const serialized = yield* descriptor.serialize(ctx, provisionedNode, typedConfig);
266
- const bundle = opts.bundles[id];
267
- if (bundle === void 0) return yield* Effect.fail(missingBundleError(id));
268
- const artifact = yield* descriptor.package(ctx, {
269
- assembled: {
270
- dir: bundle.dir,
271
- entry: bundle.entry
272
- },
273
- address: id
274
- });
275
- const result = yield* descriptor.deploy(ctx, provisionedNode, artifact, serialized);
276
- lowered.set(id, result.outputs);
277
- entries.push({
278
- address: id,
279
- entities: result.entities
280
- });
281
- }
282
- if (opts.report !== void 0) {
283
- const report = opts.report;
284
- yield* Alchemy.Action("composer-deployment-report", (input) => Effect.sync(() => {
285
- report({
286
- app: opts.name,
287
- nodes: joinDeployment(graph, input.entries)
288
- });
289
- }))({
290
- nonce: Date.now(),
291
- entries
292
- });
293
- }
294
- });
295
- }
296
- /**
297
- * The whole-stack wrapper: Load → route each node through the config's
298
- * extension registries → an Alchemy Stack (the default export the alchemy
299
- * CLI consumes).
300
- */
301
- function lower(root, config, opts) {
302
- const stackEffect = Effect.orDie(lowering(root, config, opts));
303
- const containers = deserializeContainers(config.extensions, process.env);
304
- return Alchemy.Stack(opts.name, {
305
- providers: mergedProviders(config),
306
- state: resolveStateLayer(opts, config, containers)
307
- }, stackEffect);
308
- }
309
- //#endregion
1
+ import { a as lowering, i as lower, n as buildConfig, o as mergedProviders, r as joinDeployment, s as resolveStateLayer, t as LowerError } from "./deploy-H3PKi0ZR-Chgm12Bn.mjs";
310
2
  export { LowerError, buildConfig, joinDeployment, lower, lowering, mergedProviders, resolveStateLayer };
311
-
312
- //# sourceMappingURL=deploy.mjs.map
@@ -0,0 +1,29 @@
1
+ import { O as PrismaAppConfig, _ as LocalTargetProvidersInput, c as DEV_DIR, g as LocalTargetEmulatorsInput, h as LocalTargetDescriptor, m as LocalTargetAttachment, p as LocalTargetAttachInput, s as ContainerInstance } from "./app-config-S3etMyhL-B8jqbr7j.mjs";
2
+ import * as Layer from "effect/Layer";
3
+ //#region ../../0-framework/1-core/core/dist/local-target.d.mts
4
+ //#region src/control/local-target.d.ts
5
+ /**
6
+ * Resolves every non-build-only configured extension's lazy `localTarget`
7
+ * thunk, once (ADR-0041's lazy local-target reference — operator directive:
8
+ * the production control entry carries only the thunk, never the
9
+ * descriptor, so resolving it is this module's job, not something a deploy
10
+ * path ever does). A build-only extension (`isBuildOnlyExtension`) owns no
11
+ * resources or services and is skipped entirely — never even checked for a
12
+ * `localTarget` thunk. Every other configured extension must be
13
+ * local-target-capable, or the dev command cannot bring the app up at all,
14
+ * so a missing thunk throws naming the extension. The generated dev stack
15
+ * module calls this once and threads the resolved map through every
16
+ * subsequent hook, including `localTargetProviders`.
17
+ */
18
+ declare function resolveLocalTargets(config: PrismaAppConfig): Promise<ReadonlyMap<string, LocalTargetDescriptor>>;
19
+ /**
20
+ * All configured extensions' local-target providers merged, config array
21
+ * order (ADR-0041), from the ALREADY-RESOLVED descriptor map
22
+ * (`resolveLocalTargets`'s product — this function itself never touches a
23
+ * `localTarget` thunk). The generated dev stack module is this
24
+ * aggregator's one caller, passing the result as `LowerOptions.providers`.
25
+ */
26
+ declare function localTargetProviders(resolved: ReadonlyMap<string, LocalTargetDescriptor>, containers: ReadonlyMap<string, ContainerInstance>, devDir: string): Layer.Layer<never>;
27
+ //#endregion
28
+ export { DEV_DIR, type LocalTargetAttachInput, type LocalTargetAttachment, type LocalTargetDescriptor, type LocalTargetEmulatorsInput, type LocalTargetProvidersInput, localTargetProviders, resolveLocalTargets };
29
+ //# sourceMappingURL=local-target.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-target.d.mts","names":[],"sources":["../../../0-framework/1-core/core/dist/local-target.d.mts"],"mappings":";;;;;;;;;;;;;;;;;iBAgBiB,oBAAoB,QAAQ,kBAAkB,QAAQ,oBAAoB;;;;;;;;iBAQ1E,qBAAqB,UAAU,oBAAoB,wBAAwB,YAAY,oBAAoB,oBAAoB,iBAAiB,MAAM"}
@@ -0,0 +1,47 @@
1
+ import { r as isBuildOnlyExtension, t as DEV_DIR } from "./app-config-joXc-BKm-CdcXqNMD.mjs";
2
+ import { t as LowerError } from "./deploy-H3PKi0ZR-Chgm12Bn.mjs";
3
+ import * as Layer from "effect/Layer";
4
+ //#region ../../0-framework/1-core/core/dist/local-target.mjs
5
+ /** The local-target stack's own provider aggregation (ADR-0041; naming, operator 2026-07-23 — the seam is `localTarget`, "dev" names the user-facing feature only) — the local-target counterpart of `deploy.ts`'s `mergedProviders`, kept in its own module so `lower()` learns nothing about it (deploy.ts's REVISED — operator review of #162). */
6
+ function noLocalTargetSupportError(id) {
7
+ return new LowerError(`extension "${id}" has no dev support — it declares no \`localTarget\` descriptor (ADR-0041).`);
8
+ }
9
+ /**
10
+ * Resolves every non-build-only configured extension's lazy `localTarget`
11
+ * thunk, once (ADR-0041's lazy local-target reference — operator directive:
12
+ * the production control entry carries only the thunk, never the
13
+ * descriptor, so resolving it is this module's job, not something a deploy
14
+ * path ever does). A build-only extension (`isBuildOnlyExtension`) owns no
15
+ * resources or services and is skipped entirely — never even checked for a
16
+ * `localTarget` thunk. Every other configured extension must be
17
+ * local-target-capable, or the dev command cannot bring the app up at all,
18
+ * so a missing thunk throws naming the extension. The generated dev stack
19
+ * module calls this once and threads the resolved map through every
20
+ * subsequent hook, including `localTargetProviders`.
21
+ */
22
+ async function resolveLocalTargets(config) {
23
+ const entries = await Promise.all(config.extensions.flatMap((extension) => {
24
+ if (isBuildOnlyExtension(extension)) return [];
25
+ if (extension.localTarget === void 0) throw noLocalTargetSupportError(extension.id);
26
+ return [extension.localTarget().then((descriptor) => [extension.id, descriptor])];
27
+ }));
28
+ return new Map(entries);
29
+ }
30
+ /**
31
+ * All configured extensions' local-target providers merged, config array
32
+ * order (ADR-0041), from the ALREADY-RESOLVED descriptor map
33
+ * (`resolveLocalTargets`'s product — this function itself never touches a
34
+ * `localTarget` thunk). The generated dev stack module is this
35
+ * aggregator's one caller, passing the result as `LowerOptions.providers`.
36
+ */
37
+ function localTargetProviders(resolved, containers, devDir) {
38
+ const [first, ...rest] = [...resolved.entries()].map(([id, descriptor]) => descriptor.providers({
39
+ container: containers.get(id),
40
+ devDir
41
+ }));
42
+ return first === void 0 ? Layer.empty : Layer.mergeAll(first, ...rest);
43
+ }
44
+ //#endregion
45
+ export { DEV_DIR, localTargetProviders, resolveLocalTargets };
46
+
47
+ //# sourceMappingURL=local-target.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-target.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/local-target.mjs"],"sourcesContent":["import { t as LowerError } from \"./deploy-H3PKi0ZR.mjs\";\nimport { r as isBuildOnlyExtension, t as DEV_DIR } from \"./app-config-joXc-BKm.mjs\";\nimport * as Layer from \"effect/Layer\";\n//#region src/control/local-target.ts\n/** The local-target stack's own provider aggregation (ADR-0041; naming, operator 2026-07-23 — the seam is `localTarget`, \"dev\" names the user-facing feature only) — the local-target counterpart of `deploy.ts`'s `mergedProviders`, kept in its own module so `lower()` learns nothing about it (deploy.ts's REVISED — operator review of #162). */\nfunction noLocalTargetSupportError(id) {\n\treturn new LowerError(`extension \"${id}\" has no dev support — it declares no \\`localTarget\\` descriptor (ADR-0041).`);\n}\n/**\n* Resolves every non-build-only configured extension's lazy `localTarget`\n* thunk, once (ADR-0041's lazy local-target reference — operator directive:\n* the production control entry carries only the thunk, never the\n* descriptor, so resolving it is this module's job, not something a deploy\n* path ever does). A build-only extension (`isBuildOnlyExtension`) owns no\n* resources or services and is skipped entirely — never even checked for a\n* `localTarget` thunk. Every other configured extension must be\n* local-target-capable, or the dev command cannot bring the app up at all,\n* so a missing thunk throws naming the extension. The generated dev stack\n* module calls this once and threads the resolved map through every\n* subsequent hook, including `localTargetProviders`.\n*/\nasync function resolveLocalTargets(config) {\n\tconst entries = await Promise.all(config.extensions.flatMap((extension) => {\n\t\tif (isBuildOnlyExtension(extension)) return [];\n\t\tif (extension.localTarget === void 0) throw noLocalTargetSupportError(extension.id);\n\t\treturn [extension.localTarget().then((descriptor) => [extension.id, descriptor])];\n\t}));\n\treturn new Map(entries);\n}\n/**\n* All configured extensions' local-target providers merged, config array\n* order (ADR-0041), from the ALREADY-RESOLVED descriptor map\n* (`resolveLocalTargets`'s product — this function itself never touches a\n* `localTarget` thunk). The generated dev stack module is this\n* aggregator's one caller, passing the result as `LowerOptions.providers`.\n*/\nfunction localTargetProviders(resolved, containers, devDir) {\n\tconst [first, ...rest] = [...resolved.entries()].map(([id, descriptor]) => descriptor.providers({\n\t\tcontainer: containers.get(id),\n\t\tdevDir\n\t}));\n\treturn first === void 0 ? Layer.empty : Layer.mergeAll(first, ...rest);\n}\n//#endregion\nexport { DEV_DIR, localTargetProviders, resolveLocalTargets };\n\n//# sourceMappingURL=local-target.mjs.map"],"mappings":";;;;;AAKA,SAAS,0BAA0B,IAAI;CACtC,OAAO,IAAI,WAAW,cAAc,GAAG,6EAA6E;AACrH;;;;;;;;;;;;;;AAcA,eAAe,oBAAoB,QAAQ;CAC1C,MAAM,UAAU,MAAM,QAAQ,IAAI,OAAO,WAAW,SAAS,cAAc;EAC1E,IAAI,qBAAqB,SAAS,GAAG,OAAO,CAAC;EAC7C,IAAI,UAAU,gBAAgB,KAAK,GAAG,MAAM,0BAA0B,UAAU,EAAE;EAClF,OAAO,CAAC,UAAU,YAAY,CAAC,CAAC,MAAM,eAAe,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC;CACjF,CAAC,CAAC;CACF,OAAO,IAAI,IAAI,OAAO;AACvB;;;;;;;;AAQA,SAAS,qBAAqB,UAAU,YAAY,QAAQ;CAC3D,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,gBAAgB,WAAW,UAAU;EAC/F,WAAW,WAAW,IAAI,EAAE;EAC5B;CACD,CAAC,CAAC;CACF,OAAO,UAAU,KAAK,IAAI,MAAM,QAAQ,MAAM,SAAS,OAAO,GAAG,IAAI;AACtE"}
@@ -1,6 +1,6 @@
1
- import { a as Bundle, d as ExtensionDescriptor, i as AssembleInput } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
- import "./config-BP2DrIX_.mjs";
3
- import "./deploy-BP2DrIX_.mjs";
1
+ import { a as Bundle, f as ExtensionDescriptor, i as AssembleInput } from "./app-config-S3etMyhL-B8jqbr7j.mjs";
2
+ import "./config-Dyw7i2w0.mjs";
3
+ import "./deploy-Dyw7i2w0.mjs";
4
4
  import { t as NextjsBuildAdapter } from "./nextjs-DLyeRR7M-DwnBjryZ.mjs";
5
5
  //#region ../../0-framework/2-authoring/nextjs/dist/control.d.mts
6
6
  //#region src/control/build.d.ts
@@ -1,6 +1,6 @@
1
- import { a as Bundle, d as ExtensionDescriptor, i as AssembleInput } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
- import "./config-BP2DrIX_.mjs";
3
- import "./deploy-BP2DrIX_.mjs";
1
+ import { a as Bundle, f as ExtensionDescriptor, i as AssembleInput } from "./app-config-S3etMyhL-B8jqbr7j.mjs";
2
+ import "./config-Dyw7i2w0.mjs";
3
+ import "./deploy-Dyw7i2w0.mjs";
4
4
  //#region ../../0-framework/2-authoring/node/dist/control.d.mts
5
5
  //#region src/control/build.d.ts
6
6
  declare function assemble(input: AssembleInput): Promise<Bundle>;
package/dist/report.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { u as DeploymentResult } from "./app-config-CVyObaOe-PF94uVBK.mjs";
2
- import "./deploy-BP2DrIX_.mjs";
1
+ import { d as DeploymentResult } from "./app-config-S3etMyhL-B8jqbr7j.mjs";
2
+ import "./deploy-Dyw7i2w0.mjs";
3
3
  //#region ../../0-framework/3-tooling/cli/dist/report.d.mts
4
4
  //#region src/render-deployment.d.ts
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/composer",
3
- "version": "0.2.0-dev.11",
3
+ "version": "0.2.0-dev.13",
4
4
  "type": "module",
5
5
  "description": "Prisma Composer — build a Prisma App by composing Modules. Core authoring, deploy pipeline, the prisma-composer CLI, and the service-rpc/node/nextjs authoring surfaces.",
6
6
  "bin": {
@@ -10,6 +10,7 @@
10
10
  ".": "./dist/index.mjs",
11
11
  "./config": "./dist/config.mjs",
12
12
  "./deploy": "./dist/deploy.mjs",
13
+ "./local-target": "./dist/local-target.mjs",
13
14
  "./report": "./dist/report.mjs",
14
15
  "./testing": "./dist/testing.mjs",
15
16
  "./casts": "./dist/casts.mjs",
@@ -37,15 +38,15 @@
37
38
  "@prisma/management-api-sdk": "^1.50.0"
38
39
  },
39
40
  "devDependencies": {
40
- "@internal/assemble": "0.2.0-dev.11",
41
- "@internal/cli": "0.2.0-dev.11",
42
- "@internal/core": "0.2.0-dev.11",
43
- "@internal/foundation": "0.2.0-dev.11",
44
- "@internal/lowering": "0.2.0-dev.11",
45
- "@internal/nextjs": "0.2.0-dev.11",
46
- "@internal/node": "0.2.0-dev.11",
47
- "@internal/service-rpc": "0.2.0-dev.11",
48
- "@internal/tsdown-config": "0.2.0-dev.11",
41
+ "@internal/assemble": "0.2.0-dev.13",
42
+ "@internal/cli": "0.2.0-dev.13",
43
+ "@internal/core": "0.2.0-dev.13",
44
+ "@internal/foundation": "0.2.0-dev.13",
45
+ "@internal/lowering": "0.2.0-dev.13",
46
+ "@internal/nextjs": "0.2.0-dev.13",
47
+ "@internal/node": "0.2.0-dev.13",
48
+ "@internal/service-rpc": "0.2.0-dev.13",
49
+ "@internal/tsdown-config": "0.2.0-dev.13",
49
50
  "@types/node": "^25.9.3",
50
51
  "tsdown": "^0.22.7",
51
52
  "typescript": "^6.0.3"
@@ -0,0 +1 @@
1
+ export * from '@internal/core/local-target';
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-config-CVyObaOe-PF94uVBK.d.mts","names":[],"sources":["../../../0-framework/1-core/core/dist/app-config-CVyObaOe.d.mts"],"mappings":";;;;;;;;;;;;;;;;;;;;UAmBU;;WAEC;;WAEA;;;;;;;UAOD;WACC,OAAO;;EAEhB;;;;;;;;;;;;UAYQ,oBAAoB,UAAU,oBAAoB;;EAE1D,OAAO,OAAO,uBAAuB,QAAQ;;EAE7C,OAAO,OAAO,uBAAuB,QAAQ;;EAE7C,OAAO,UAAU,IAAI;;EAErB,YAAY,qBAAqB;;;iBAGlB,oBAAoB;;iBAEpB,aAAa,WAAW,oBAAoB,qBAAqB;;UAExE;WACC;WACA,YAAY;;;;;;iBAMN,sBAAsB,qBAAqB,+BAA+B,KAAK,SAAS,sCAAsC,oBAAoB;;;;KAI9J,oBAAoB,MAAM,MAAM,cAAc;;;;;;UAMzC;EACR,UAAU,KAAK,eAAe,OAAO;;;;;;;;UAQ7B;WACC;WACA;WACA;WACA;;WAEA,MAAM;;;UAGP;;EAER,UAAU,MAAM,gBAAgB,OAAO;;;;;;;;;;;;;;UAc/B,gBAAgB,aAAa;;EAErC,UAAU,KAAK,eAAe,OAAO,OAAO;;;;;;EAM5C,UAAU,KAAK,cAAc,aAAa,GAAG,QAAQ,SAAS,OAAO,OAAO;;;;;;EAM5E,QAAQ,KAAK,cAAc,OAAO,eAAe,OAAO,OAAO;;EAE/D,OAAO,KAAK,cAAc,aAAa,GAAG,UAAU,UAAU,YAAY,IAAI,OAAO,OAAO;;;UAGpF;;WAEC,WAAW;;WAEX;;;KAGN,YAAY,KAAK,iBAAiB,OAAO,OAAO;UAC3C;WACC,IAAI;;;;;;WAMJ;WACA,MAAM,cAAc;WACpB,OAAO;WACP,MAAM;;;;;;WAMN;;;;;;;WAOA,WAAW;;WAEX,SAAS,YAAY,QAAQ;;WAE7B,aAAa;;;;;;;;;KASnB,UAAU,SAAS;;;;;;;;;;;;;UAad;WACC;WACA;WACA;WACA,UAAU,SAAS;;;;;;;;;;;;;;UAcpB;WACC,SAAS;WACT,mBAAmB,MAAM;;;UAG1B;WACC;WACA,MAAM,cAAc;WACpB,mBAAmB;;;UAGpB;WACC;WACA,gBAAgB;;UAEjB;;WAEC;WACA,SAAS,eAAe;WACxB;;WAEA,QAAQ;;;;;;;;WAQR,UAAU,QAAQ;;;UAGnB;WACC;WACA;;;;;;;;WAQA;;;UAGD;WACC,OAAO;;WAEP;;WAEA;;;UAGD;WACC;WACA;;cAEG,mBAAmB;EAC/B,YAAY;;;;;;;;;;;;;;iBAcG,YAAY,MAAM,aAAa,IAAI,QAAQ,OAAO,OAAO,SAAS,YAAY,QAAQ,UAAU,aAAa,+BAA+B;;;;;;;;;;;;;;iBAc5I,eAAe,OAAO,OAAO;EAC5C;EACA,mBAAmB;eACN;;;;;;;;iBAQE,kBAAkB,MAAM,cAAc,QAAQ,iBAAiB,YAAY,oBAAoB,qBAAqB;;;;;;iBAMpH,gBAAgB,QAAQ,kBAAkB,MAAM;;;;;iBAKhD,SAAS,MAAM,YAAY,QAAQ,iBAAiB,MAAM,eAAe,OAAO,kBAAkB;;;;;;iBAMlG,MAAM,MAAM,YAAY,QAAQ,iBAAiB,MAAM,eAAe,OAAO,OAAO,QAAQ,uDAAuD;;;;;;;;UAQ1J;;WAEC;;WAEA,OAAO,eAAe;;WAEtB,aAAa,oBAAoB;;WAEjC,cAAc;;WAEd,kBAAkB,MAAM;;;;;;;;WAQxB,aAAa,OAAO,mBAAmB;;;;;;;;;WASvC,YAAY,OAAO,kBAAkB;;;;;;;;WAQrC,YAAY;;;;;;UAMb;;WAEC;;EAET,OAAO,WAAW,gCAAgC;;;UAG1C;;WAEC,OAAO;;WAEP,WAAW;;WAEX;;;UAGD;;WAEC,WAAW;;WAEX;;;;;;;KAON;WACM;IACP;WACO;IACP;WACO;EACT,SAAS,OAAO,gBAAgB,QAAQ;;;;;;;UAOhC;WACC,YAAY;WACZ,OAAO;;;iBAGD,aAAa,QAAQ,kBAAkB"}
@@ -1 +0,0 @@
1
- import "./app-config-CVyObaOe-PF94uVBK.mjs";
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/config.mjs"],"sourcesContent":["import { n as containerEnvVarName, r as deserializeContainers, t as containerEnv } from \"./container-transport-DKmKg5JQ.mjs\";\n//#region src/control/app-config.ts\n/** Typed identity — exists so `prisma-composer.config.ts` gets checked against PrismaAppConfig where it is written. */\nfunction defineConfig(config) {\n\treturn config;\n}\n//#endregion\nexport { containerEnv, containerEnvVarName, defineConfig, deserializeContainers };\n\n//# sourceMappingURL=config.mjs.map"],"mappings":";;;AAGA,SAAS,aAAa,QAAQ;CAC7B,OAAO;AACR"}
@@ -1 +0,0 @@
1
- import "./app-config-CVyObaOe-PF94uVBK.mjs";
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/deploy.mjs"],"sourcesContent":["import { o as isParamSource, t as Load } from \"./graph-CP16cJyH.mjs\";\nimport { r as deserializeContainers } from \"./container-transport-DKmKg5JQ.mjs\";\nimport * as Alchemy from \"alchemy\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\n//#region src/control/deploy.ts\nvar LowerError = class extends Error {\n\tconstructor(message) {\n\t\tsuper(message);\n\t\tthis.name = \"LowerError\";\n\t}\n};\n/**\n* Resolves one SERVICE-OWN param to its config value. The full resolution\n* order across both value channels:\n*\n* 1. A param claiming BOTH a provision-time binding and a `provision` need\n* (ADR-0031) is a loud error — two sources for one value.\n* 2. A provision-time binding (a schema-validated literal, or an opaque\n* `ParamSource` the target resolves at boot per ADR-0019) beats the\n* declared `default`.\n* 3. A framework-minted `provision` need is resolved per dependency EDGE\n* against the consumer extension's registry — that path fills CONNECTION\n* params in `buildConfig`'s inputs loop, never this function. A\n* service-own param has no edge to mint against, so an unbound need here\n* falls through like any unbound param.\n* 4. The `default`, else absent (only legal when `optional`), else a loud\n* error naming the param, the service, and the fix.\n*/\nfunction resolveParam(node, serviceId, name, param, bound) {\n\tif (bound !== void 0) {\n\t\tif (param.provision !== void 0) throw new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") has two sources claiming one value: a provision-time binding (${isParamSource(bound) ? \"a param source\" : \"a literal value\"}) AND a framework provision need (\"${String(param.provision.brand)}\") on its declaration — remove the binding or drop the \\`provision\\` facet.`);\n\t\tif (isParamSource(bound)) return bound;\n\t\tconst result = param.schema[\"~standard\"].validate(bound);\n\t\tif (result instanceof Promise) throw new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") uses an async Standard Schema — a provision-time literal value requires a synchronous validator.`);\n\t\tif (result.issues !== void 0) {\n\t\t\tconst messages = result.issues.map((issue) => issue.message).join(\"; \");\n\t\t\tthrow new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") received an invalid provision-time value: ${messages}`);\n\t\t}\n\t\treturn result.value;\n\t}\n\tif (param.default !== void 0) return param.default;\n\tif (param.optional === true) return void 0;\n\tthrow new LowerError(`Param \"${name}\" of \"${serviceId}\" (service \"${node.name}\") has no default, is not optional, and was not bound at provision — bind it with a literal value or a param source (e.g. envParam('NAME')) on its provision() call, or give it a default.`);\n}\n/**\n* Assembles a service's typed Config. Connection params come from the\n* dependency edge's lowered outputs — or, for a param carrying a `provision`\n* need (ADR-0031), from `provisioned` (keyed by edge id): the framework mints\n* it, the producer hands nothing over. The service's own params resolve via\n* `resolveParam` (provision-time binding, then default, then loud\n* unbound-required failure).\n*\n* This is also where the connection contract is enforced: a producer that fails to\n* supply a required param its consumer's connection declares fails the deploy\n* here, naming the edge, rather than reaching the consumer as `undefined`.\n*/\nfunction buildConfig(node, id, graph, lowered, provisioned) {\n\tconst inputs = {};\n\tfor (const [inputName, inputNode] of Object.entries(node.inputs)) {\n\t\tconst edge = graph.edges.find((e) => e.to === id && e.input === inputName && e.kind === \"dependency\");\n\t\tconst producedOutputs = edge !== void 0 ? lowered.get(edge.from) ?? {} : {};\n\t\tconst values = {};\n\t\tfor (const [name, param] of Object.entries(inputNode.connection.params)) {\n\t\t\tif (param.provision !== void 0) {\n\t\t\t\tvalues[name] = provisioned.get(`${id}.${inputName}`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst value = producedOutputs[name];\n\t\t\tif (value === void 0 && param.optional !== true && edge !== void 0) throw new LowerError(`Connection input \"${id}.${inputName}\" declares param \"${name}\", but its producer \"${edge.from}\" did not supply it — the producer's outputs carry [${Object.keys(producedOutputs).join(\", \") || \"nothing\"}]. Add \"${name}\" to the outputs the producer returns from its lowering, or declare the param optional on the connection.`);\n\t\t\tvalues[name] = value;\n\t\t}\n\t\tinputs[inputName] = values;\n\t}\n\tconst boundParams = new Map(graph.params.filter((binding) => binding.serviceAddress === id).map((b) => [b.slot, b.binding]));\n\tconst service = {};\n\tfor (const [name, param] of Object.entries(node.params)) {\n\t\tconst value = resolveParam(node, id, name, param, boundParams.get(name));\n\t\tif (value !== void 0) service[name] = value;\n\t}\n\treturn {\n\t\tservice,\n\t\tinputs\n\t};\n}\n/**\n* Joins resolved report entries back to their graph nodes — the last step of a\n* deploy report, run inside the Action with apply's resolved values.\n*\n* The entries cross Alchemy's action-input boundary, so they carry addresses\n* and plain entities only; the graph is held by closure on this side. That\n* split is why this join exists at all, and it is what keeps functions and\n* Standard Schemas (which a node carries, and which the plan's input hash\n* would have to serialize) out of the input.\n*\n* Skips an address the graph no longer holds: entries are data, the graph is\n* truth.\n*/\nfunction joinDeployment(graph, entries) {\n\tconst nodes = [];\n\tfor (const entry of entries) {\n\t\tconst node = graph.nodes.find((n) => n.id === entry.address)?.node;\n\t\tif (node === void 0 || node.kind !== \"service\" && node.kind !== \"resource\") continue;\n\t\tnodes.push({\n\t\t\taddress: entry.address,\n\t\t\tnode,\n\t\t\tentities: entry.entities\n\t\t});\n\t}\n\treturn nodes;\n}\nfunction missingBundleError(id) {\n\treturn new LowerError(`No bundle provided for service \"${id}\" (opts.bundles[\"${id}\"] is required).`);\n}\nfunction duplicateExtensionError(id) {\n\treturn new LowerError(`Extension \"${id}\" is listed more than once in \\`extensions\\` — each extension id must be unique.`);\n}\n/** Registries as extension id → descriptor. Fails on a duplicate id — the CLI validates config, but lowering() is the programmatic escape hatch that doesn't. */\nfunction extensionsById(config) {\n\tconst map = /* @__PURE__ */ new Map();\n\tfor (const extension of config.extensions) {\n\t\tif (map.has(extension.id)) return Effect.fail(duplicateExtensionError(extension.id));\n\t\tmap.set(extension.id, extension);\n\t}\n\treturn Effect.succeed(map);\n}\nfunction unknownExtensionError(extension, id) {\n\treturn new LowerError(`No extension \"${extension}\" is configured (needed by node \"${id}\") — add it to prisma-composer.config.ts's \\`extensions\\` (import its /control entry and list its descriptor).`);\n}\nfunction unknownNodeTypeError(extension, type) {\n\treturn new LowerError(`Extension \"${extension.id}\" has no descriptor for node type \"${type}\" (known: ${Object.keys(extension.nodes).join(\", \")}).`);\n}\n/** A provisioned param's need brand isn't registered by the consumer's extension (ADR-0031). */\nfunction unknownProvisionerError(extension, brand, edgeId) {\n\tconst known = extension.provisions !== void 0 && extension.provisions.size > 0 ? Array.from(extension.provisions.keys(), String).join(\", \") : \"(none registered)\";\n\treturn new LowerError(`Extension \"${extension.id}\" has no provisioner for need \"${String(brand)}\" (needed by edge \"${edgeId}\") (known: ${known}).`);\n}\n/** A provisioned edge whose consumer and provider nodes belong to different extensions (ADR-0031). */\nfunction crossExtensionProvisionError(edgeId) {\n\treturn new LowerError(`Provisioned edge \"${edgeId}\" spans two extensions — cross-extension provisioned edges aren't supported yet.`);\n}\n/**\n* More than one provisioned param on one connection (ADR-0031). One edge mints\n* ONE value, keyed by edge id, so a second need on the same connection would\n* silently receive the first's value under the first's brand.\n*/\nfunction multipleProvisionedParamsError(edgeId, names) {\n\treturn new LowerError(`Connection input \"${edgeId}\" declares more than one provisioned param (${names.join(\", \")}) — only one provisioned param per connection is supported.`);\n}\nfunction wrongKindError(extension, type, expected, got) {\n\treturn new LowerError(`Extension \"${extension}\"'s descriptor for node type \"${type}\" is a \"${got}\" descriptor — this node needs a \"${expected}\" descriptor.`);\n}\n/** Looks up one node's descriptor: extension by `node.extension`, then descriptor by `node.type`, then the kind check. */\nfunction descriptorFor(extensions, node, id) {\n\tconst extension = extensions.get(node.extension);\n\tif (extension === void 0) return Effect.fail(unknownExtensionError(node.extension, id));\n\tconst descriptor = extension.nodes[node.type];\n\tif (descriptor === void 0) return Effect.fail(unknownNodeTypeError(extension, node.type));\n\tif (descriptor.kind !== node.kind) return Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));\n\treturn Effect.succeed(descriptor);\n}\n/**\n* The state-layer precedence a deploy resolves to: an explicit opts.state\n* always wins; failing that, the config's own (required) state descriptor,\n* created with its owning extension's resolved container (`undefined` when\n* that extension declared none). A pure function so the precedence is\n* testable without booting Alchemy.\n*/\nfunction resolveStateLayer(opts, config, containers) {\n\treturn opts.state ?? config.state.create(containers.get(config.state.extension));\n}\n/**\n* All configured extensions' providers merged, config array order — an\n* extension without `providers` is skipped; no used-extensions-only\n* filtering (ADR-0017's pinned providers rule).\n*/\nfunction mergedProviders(config) {\n\tconst [first, ...rest] = config.extensions.flatMap((extension) => extension.providers !== void 0 ? [extension.providers()] : []);\n\treturn first === void 0 ? Layer.empty : Layer.mergeAll(first, ...rest);\n}\n/**\n* Composable form for mixed stacks: hand-wired Alchemy resources alongside Prisma App nodes in one stack effect.\n* Fails with LowerError or whatever an extension's lowering raises — the error type is open.\n*/\nfunction lowering(root, config, opts) {\n\treturn Effect.gen(function* () {\n\t\tconst graph = Load(root, { id: opts.name });\n\t\tconst extensions = yield* extensionsById(config);\n\t\tconst containers = deserializeContainers(config.extensions, process.env);\n\t\tconst lowered = /* @__PURE__ */ new Map();\n\t\tconst entries = [];\n\t\tconst provisioned = /* @__PURE__ */ new Map();\n\t\tconst applications = /* @__PURE__ */ new Map();\n\t\tfor (const descriptor of config.extensions) {\n\t\t\tif (descriptor.application === void 0) continue;\n\t\t\tconst appCtx = {\n\t\t\t\tid: graph.root.id,\n\t\t\t\taddress: \"\",\n\t\t\t\tnode: graph.root.node,\n\t\t\t\tgraph,\n\t\t\t\topts,\n\t\t\t\tapplication: void 0,\n\t\t\t\tcontainer: containers.get(descriptor.id),\n\t\t\t\tlowered,\n\t\t\t\tprovisioned\n\t\t\t};\n\t\t\tapplications.set(descriptor.id, yield* descriptor.application.provision(appCtx));\n\t\t}\n\t\tfor (const edge of graph.edges) {\n\t\t\tif (edge.kind !== \"dependency\") continue;\n\t\t\tconst consumer = graph.nodes.find((n) => n.id === edge.to)?.node;\n\t\t\tif (consumer === void 0 || consumer.kind !== \"service\") continue;\n\t\t\tconst slot = consumer.inputs[edge.input];\n\t\t\tif (slot === void 0) continue;\n\t\t\tconst provisionedParams = Object.entries(slot.connection.params).filter(([, param]) => param.provision !== void 0);\n\t\t\tif (provisionedParams.length === 0) continue;\n\t\t\tconst edgeId = `${edge.to}.${edge.input}`;\n\t\t\tif (provisionedParams.length > 1) return yield* Effect.fail(multipleProvisionedParamsError(edgeId, provisionedParams.map(([name]) => name)));\n\t\t\tconst need = provisionedParams[0]?.[1].provision;\n\t\t\tif (need === void 0) continue;\n\t\t\tconst provider = graph.nodes.find((n) => n.id === edge.from)?.node;\n\t\t\tif (provider === void 0 || provider.kind !== \"service\" && provider.kind !== \"resource\") continue;\n\t\t\tif (consumer.extension !== provider.extension) return yield* Effect.fail(crossExtensionProvisionError(edgeId));\n\t\t\tconst extension = extensions.get(consumer.extension);\n\t\t\tif (extension === void 0) return yield* Effect.fail(unknownExtensionError(consumer.extension, edge.to));\n\t\t\tconst provisioner = extension.provisions?.get(need.brand);\n\t\t\tif (provisioner === void 0) return yield* Effect.fail(unknownProvisionerError(extension, need.brand, edgeId));\n\t\t\tconst ref = yield* provisioner.provision({\n\t\t\t\tedgeId,\n\t\t\t\tconsumerAddress: edge.to,\n\t\t\t\tproviderAddress: edge.from,\n\t\t\t\tinput: edge.input,\n\t\t\t\tneed\n\t\t\t});\n\t\t\tprovisioned.set(edgeId, ref);\n\t\t}\n\t\tfor (const { id, node } of graph.nodes) {\n\t\t\tif (node.kind === \"module\") continue;\n\t\t\tif (node.kind === \"dependency\") continue;\n\t\t\tconst ctx = {\n\t\t\t\tid,\n\t\t\t\taddress: id,\n\t\t\t\tnode,\n\t\t\t\tgraph,\n\t\t\t\topts,\n\t\t\t\tapplication: applications.get(node.extension),\n\t\t\t\tcontainer: containers.get(node.extension),\n\t\t\t\tlowered,\n\t\t\t\tprovisioned\n\t\t\t};\n\t\t\tconst descriptor = yield* descriptorFor(extensions, node, id);\n\t\t\tif (descriptor.kind === \"resource\") {\n\t\t\t\tconst result = yield* descriptor(ctx);\n\t\t\t\tlowered.set(id, result.outputs);\n\t\t\t\tentries.push({\n\t\t\t\t\taddress: id,\n\t\t\t\t\tentities: result.entities\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (descriptor.kind !== \"service\") return yield* Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));\n\t\t\tconst service = node;\n\t\t\tconst provisionedNode = yield* descriptor.provision(ctx);\n\t\t\tconst typedConfig = buildConfig(service, id, graph, lowered, provisioned);\n\t\t\tconst serialized = yield* descriptor.serialize(ctx, provisionedNode, typedConfig);\n\t\t\tconst bundle = opts.bundles[id];\n\t\t\tif (bundle === void 0) return yield* Effect.fail(missingBundleError(id));\n\t\t\tconst artifact = yield* descriptor.package(ctx, {\n\t\t\t\tassembled: {\n\t\t\t\t\tdir: bundle.dir,\n\t\t\t\t\tentry: bundle.entry\n\t\t\t\t},\n\t\t\t\taddress: id\n\t\t\t});\n\t\t\tconst result = yield* descriptor.deploy(ctx, provisionedNode, artifact, serialized);\n\t\t\tlowered.set(id, result.outputs);\n\t\t\tentries.push({\n\t\t\t\taddress: id,\n\t\t\t\tentities: result.entities\n\t\t\t});\n\t\t}\n\t\tif (opts.report !== void 0) {\n\t\t\tconst report = opts.report;\n\t\t\tyield* Alchemy.Action(\"composer-deployment-report\", (input) => Effect.sync(() => {\n\t\t\t\treport({\n\t\t\t\t\tapp: opts.name,\n\t\t\t\t\tnodes: joinDeployment(graph, input.entries)\n\t\t\t\t});\n\t\t\t}))({\n\t\t\t\tnonce: Date.now(),\n\t\t\t\tentries\n\t\t\t});\n\t\t}\n\t});\n}\n/**\n* The whole-stack wrapper: Load → route each node through the config's\n* extension registries → an Alchemy Stack (the default export the alchemy\n* CLI consumes).\n*/\nfunction lower(root, config, opts) {\n\tconst stackEffect = Effect.orDie(lowering(root, config, opts));\n\tconst containers = deserializeContainers(config.extensions, process.env);\n\treturn Alchemy.Stack(opts.name, {\n\t\tproviders: mergedProviders(config),\n\t\tstate: resolveStateLayer(opts, config, containers)\n\t}, stackEffect);\n}\n//#endregion\nexport { LowerError, buildConfig, joinDeployment, lower, lowering, mergedProviders, resolveStateLayer };\n\n//# sourceMappingURL=deploy.mjs.map"],"mappings":"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"}