@prisma/composer 0.23.0 → 0.24.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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-CooZZhD4.d.mts
8
+ //#region ../../0-framework/1-core/core/dist/app-config-jGcCcxK4.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
@@ -143,7 +143,10 @@ interface ProvisionerDescriptor {
143
143
  * that assignment.
144
144
  */
145
145
  interface ServiceLowering<P = unknown, S = unknown> {
146
- /** Makes the platform-specific thing that will host the service — identity-bearing infrastructure only, no code runs. */
146
+ /**
147
+ * Makes the platform-specific thing that will host the service — identity-bearing infrastructure only, no code runs.
148
+ * Runs before any node lowers, so it must not read `ctx.lowered` or `ctx.services`.
149
+ */
147
150
  provision(ctx: LowerContext): Effect.Effect<P, unknown, unknown>;
148
151
  /**
149
152
  * Encodes the typed Config into the service's runtime environment. Boot-side
@@ -197,6 +200,8 @@ interface LowerContext {
197
200
  readonly lowered: ReadonlyMap<NodeId, Outputs>;
198
201
  /** Every provisioned param value minted this lowering, keyed by edge id (ADR-0031). */
199
202
  readonly provisioned: ReadonlyMap<string, unknown>;
203
+ /** Every service's `provision()` product by address, made before any node serializes. */
204
+ readonly services?: ReadonlyMap<string, unknown>;
200
205
  }
201
206
  /**
202
207
  * The values a node provides to its dependents — what a consumer's declared
@@ -632,4 +637,4 @@ interface PrismaAppConfig {
632
637
  declare function defineConfig(config: PrismaAppConfig): PrismaAppConfig;
633
638
  //#endregion
634
639
  export { readPreflightPayload as $, PrismaAppConfig as A, TeardownInput as B, LoweredResult as C, PackageInput as D, Outputs as E, ReporterDescriptor as F, deserializeContainers as G, containerEnv as H, RunOutcome as I, lower as J, isBuildOnlyExtension as K, RunReporter as L, ProvisionerDescriptor as M, ReportAttachInput as N, PreflightInput as O, ReportBeginInput as P, preflightEnvVarName as Q, ServiceLowering as R, LowerOptions as S, NodeDescriptor as T, containerEnvVarName as U, buildConfig as V, defineConfig as W, mergedProviders as X, lowering as Y, preflightEnv as Z, LocalTargetEmulatorsInput as _, Bundle as a, LowerContext as b, ContainerInstance as c, DeployedNode as d, resolveStateLayer as et, DeploymentResult as f, LocalTargetDescriptor as g, LocalTargetAttachment as h, AssembleInput as i, ProvisionEdge as j, PreflightPayload as k, DEV_DIR as l, LocalTargetAttachInput as m, ApplicationDescriptor as n, ContainerCredentials as o, ExtensionDescriptor as p, joinDeployment as q, Artifact as r, ContainerDescriptor as s, AlchemyStateLayer as t, DeployedEntity as u, LocalTargetProvidersInput as v, Lowering as w, LowerError as x, LocateContainerInput as y, StateDescriptor as z };
635
- //# sourceMappingURL=app-config-CooZZhD4-EAGtxAPU.d.mts.map
640
+ //# sourceMappingURL=app-config-jGcCcxK4-DnzGGbDS.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-config-jGcCcxK4-DnzGGbDS.d.mts","names":[],"sources":["../../../0-framework/1-core/core/dist/app-config-jGcCcxK4.d.mts"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import "./app-config-jGcCcxK4-DnzGGbDS.mjs";
package/dist/config.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as readPreflightPayload, A as PrismaAppConfig, B as TeardownInput, F as ReporterDescriptor, G as deserializeContainers, H as containerEnv, I as RunOutcome, K as isBuildOnlyExtension, L as RunReporter, N as ReportAttachInput, O as PreflightInput, P as ReportBeginInput, Q as preflightEnvVarName, T as NodeDescriptor, U as containerEnvVarName, W as defineConfig, Z as preflightEnv, _ as LocalTargetEmulatorsInput, c as ContainerInstance, g as LocalTargetDescriptor, h as LocalTargetAttachment, k as PreflightPayload, l as DEV_DIR, m as LocalTargetAttachInput, o as ContainerCredentials, p as ExtensionDescriptor, s as ContainerDescriptor, u as DeployedEntity, v as LocalTargetProvidersInput, y as LocateContainerInput, z as StateDescriptor } from "./app-config-CooZZhD4-EAGtxAPU.mjs";
2
- import "./config-BmK1pGlA.mjs";
1
+ import { $ as readPreflightPayload, A as PrismaAppConfig, B as TeardownInput, F as ReporterDescriptor, G as deserializeContainers, H as containerEnv, I as RunOutcome, K as isBuildOnlyExtension, L as RunReporter, N as ReportAttachInput, O as PreflightInput, P as ReportBeginInput, Q as preflightEnvVarName, T as NodeDescriptor, U as containerEnvVarName, W as defineConfig, Z as preflightEnv, _ as LocalTargetEmulatorsInput, c as ContainerInstance, g as LocalTargetDescriptor, h as LocalTargetAttachment, k as PreflightPayload, l as DEV_DIR, m as LocalTargetAttachInput, o as ContainerCredentials, p as ExtensionDescriptor, s as ContainerDescriptor, u as DeployedEntity, v as LocalTargetProvidersInput, y as LocateContainerInput, z as StateDescriptor } from "./app-config-jGcCcxK4-DnzGGbDS.mjs";
2
+ import "./config-BGtKERz-.mjs";
3
3
  export { type ContainerCredentials, type ContainerDescriptor, type ContainerInstance, DEV_DIR, type DeployedEntity, ExtensionDescriptor, LocalTargetAttachInput, LocalTargetAttachment, LocalTargetDescriptor, LocalTargetEmulatorsInput, LocalTargetProvidersInput, type LocateContainerInput, NodeDescriptor, PreflightInput, type PreflightPayload, PrismaAppConfig, ReportAttachInput, ReportBeginInput, ReporterDescriptor, RunOutcome, RunReporter, StateDescriptor, TeardownInput, containerEnv, containerEnvVarName, defineConfig, deserializeContainers, isBuildOnlyExtension, preflightEnv, preflightEnvVarName, readPreflightPayload };
@@ -1,8 +1,8 @@
1
1
  import { ht as CliStructuredError } from "./graph-types-BTTaRnih-BF6PobQ3.mjs";
2
- import { u as DeployedEntity } from "./app-config-CooZZhD4-EAGtxAPU.mjs";
3
- import "./config-BmK1pGlA.mjs";
2
+ import { u as DeployedEntity } from "./app-config-jGcCcxK4-DnzGGbDS.mjs";
3
+ import "./config-BGtKERz-.mjs";
4
4
  import "./index-DeocL1di.mjs";
5
- import "./deploy-BmK1pGlA.mjs";
5
+ import "./deploy-BGtKERz-.mjs";
6
6
  //#region ../../0-framework/0-foundation/foundation/dist/result.d.mts
7
7
  //#region src/result.d.ts
8
8
  /**
@@ -0,0 +1 @@
1
+ import "./app-config-jGcCcxK4-DnzGGbDS.mjs";
package/dist/deploy.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { C as LoweredResult, D as PackageInput, E as Outputs, J as lower, M as ProvisionerDescriptor, R as ServiceLowering, S as LowerOptions, V as buildConfig, X as mergedProviders, Y as lowering, a as Bundle, b as LowerContext, d as DeployedNode, et as resolveStateLayer, f as DeploymentResult, i as AssembleInput, j as ProvisionEdge, n as ApplicationDescriptor, q as joinDeployment, r as Artifact, t as AlchemyStateLayer, u as DeployedEntity, w as Lowering, x as LowerError } from "./app-config-CooZZhD4-EAGtxAPU.mjs";
2
- import "./deploy-BmK1pGlA.mjs";
1
+ import { C as LoweredResult, D as PackageInput, E as Outputs, J as lower, M as ProvisionerDescriptor, R as ServiceLowering, S as LowerOptions, V as buildConfig, X as mergedProviders, Y as lowering, a as Bundle, b as LowerContext, d as DeployedNode, et as resolveStateLayer, f as DeploymentResult, i as AssembleInput, j as ProvisionEdge, n as ApplicationDescriptor, q as joinDeployment, r as Artifact, t as AlchemyStateLayer, u as DeployedEntity, w as Lowering, x as LowerError } from "./app-config-jGcCcxK4-DnzGGbDS.mjs";
2
+ import "./deploy-BGtKERz-.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
@@ -234,20 +234,29 @@ function lowering(root, config, opts) {
234
234
  });
235
235
  provisioned.set(edgeId, ref);
236
236
  }
237
+ const services = /* @__PURE__ */ new Map();
238
+ const ctxFor = (id, node) => ({
239
+ id,
240
+ address: id,
241
+ node,
242
+ graph,
243
+ opts,
244
+ application: applications.get(node.extension),
245
+ container: containers.get(node.extension),
246
+ lowered,
247
+ provisioned,
248
+ services
249
+ });
250
+ for (const { id, node } of graph.nodes) {
251
+ if (node.kind !== "service") continue;
252
+ const descriptor = yield* descriptorFor(extensions, node, id);
253
+ if (descriptor.kind !== "service") continue;
254
+ services.set(id, yield* descriptor.provision(ctxFor(id, node)));
255
+ }
237
256
  for (const { id, node } of graph.nodes) {
238
257
  if (node.kind === "module") continue;
239
258
  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
- };
259
+ const ctx = ctxFor(id, node);
251
260
  const descriptor = yield* descriptorFor(extensions, node, id);
252
261
  if (descriptor.kind === "resource") {
253
262
  const result = yield* descriptor(ctx);
@@ -260,7 +269,7 @@ function lowering(root, config, opts) {
260
269
  }
261
270
  if (descriptor.kind !== "service") return yield* Effect.fail(wrongKindError(node.extension, node.type, node.kind, descriptor.kind));
262
271
  const service = node;
263
- const provisionedNode = yield* descriptor.provision(ctx);
272
+ const provisionedNode = services.get(id);
264
273
  const typedConfig = buildConfig(service, id, graph, lowered, provisioned);
265
274
  const serialized = yield* descriptor.serialize(ctx, provisionedNode, typedConfig);
266
275
  const bundle = opts.bundles[id];
@@ -1 +1 @@
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-BfKAg2Ap.mjs\";\nimport { r as deserializeContainers } from \"./container-transport-HcvNOGZL.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 { LowerError, buildConfig, joinDeployment, lower, lowering, mergedProviders, resolveStateLayer };\n\n//# sourceMappingURL=deploy.mjs.map"],"mappings":"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"}
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-BfKAg2Ap.mjs\";\nimport { r as deserializeContainers } from \"./container-transport-HcvNOGZL.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\tconst services = /* @__PURE__ */ new Map();\n\t\tconst ctxFor = (id, node) => ({\n\t\t\tid,\n\t\t\taddress: id,\n\t\t\tnode,\n\t\t\tgraph,\n\t\t\topts,\n\t\t\tapplication: applications.get(node.extension),\n\t\t\tcontainer: containers.get(node.extension),\n\t\t\tlowered,\n\t\t\tprovisioned,\n\t\t\tservices\n\t\t});\n\t\tfor (const { id, node } of graph.nodes) {\n\t\t\tif (node.kind !== \"service\") continue;\n\t\t\tconst descriptor = yield* descriptorFor(extensions, node, id);\n\t\t\tif (descriptor.kind !== \"service\") continue;\n\t\t\tservices.set(id, yield* descriptor.provision(ctxFor(id, node)));\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 = ctxFor(id, node);\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 = services.get(id);\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 { LowerError, buildConfig, joinDeployment, lower, lowering, mergedProviders, resolveStateLayer };\n\n//# sourceMappingURL=deploy.mjs.map"],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ //#region ../../0-framework/2-authoring/bundle-paths/dist/index.mjs
4
+ /**
5
+ * The path-containment predicate and bundle-link validation shared by every
6
+ * assembly and packaging seam (node/nextjs adapters, the compute artifact
7
+ * writer, the local extractor). This predicate is the enforcement point of
8
+ * ADR-0047's boundary — a symlink may be preserved only while its target
9
+ * stays inside the assembled bundle — so it exists exactly once.
10
+ *
11
+ * Windows cannot create `dir`/`file` symlinks without Developer Mode or an
12
+ * elevated token (`EPERM`). Directory junctions need no such privilege, so
13
+ * assemble uses them on win32; file links fall back to a copy of the target.
14
+ */
15
+ /** How a platform materializes a bundle link without needing symlink privilege. */
16
+ function bundleLinkStrategy(platform, type) {
17
+ if (platform !== "win32") return "symlink";
18
+ return type === "dir" ? "junction" : "symlink-with-copy-fallback";
19
+ }
20
+ function isNotPermitted(error) {
21
+ return error instanceof Error && Reflect.get(error, "code") === "EPERM";
22
+ }
23
+ /**
24
+ * Creates a link at `linkPath` whose stored target is `target`.
25
+ * `resolvedTarget` is the absolute path of that target in the destination
26
+ * tree — junctions require it. The win32 file-copy fallback reads
27
+ * `copySource` (source-tree path) when set, otherwise `resolvedTarget`, and
28
+ * only when the target exists and stays inside `copyWithinRoot` (ADR-0047:
29
+ * never dereference an escaping link into the artifact).
30
+ *
31
+ * Junction/symlink strategies may temporarily store an escaping
32
+ * `resolvedTarget` (pnpm absolute junctions into the tracing-root store);
33
+ * later staging rewrites them, and `assertBundleSymlinksStayInside` is the
34
+ * final gate. Only the file-copy fallback must refuse escapes — copying would
35
+ * materialize deploy-machine content as a regular file with no link left to
36
+ * validate.
37
+ */
38
+ async function createBundleLink(linkPath, target, type, options) {
39
+ const strategy = bundleLinkStrategy(options.platform ?? process.platform, type);
40
+ if (strategy === "junction") {
41
+ await fs.promises.symlink(options.resolvedTarget, linkPath, "junction");
42
+ return;
43
+ }
44
+ if (strategy === "symlink") {
45
+ await fs.promises.symlink(target, linkPath, type);
46
+ return;
47
+ }
48
+ try {
49
+ await fs.promises.symlink(target, linkPath, "file");
50
+ } catch (error) {
51
+ if (!isNotPermitted(error)) throw error;
52
+ if (!isWithin(path.resolve(options.copyWithinRoot), path.resolve(options.resolvedTarget))) throw new Error(`refusing to materialize a file link whose target escapes the bundle: ${linkPath} -> ${options.resolvedTarget}`, { cause: error });
53
+ const copyFrom = options.copySource ?? options.resolvedTarget;
54
+ try {
55
+ await fs.promises.stat(copyFrom);
56
+ } catch {
57
+ throw new Error(`the assembled bundle contains a dangling symlink: ${linkPath}`);
58
+ }
59
+ await fs.promises.copyFile(copyFrom, linkPath);
60
+ }
61
+ }
62
+ /**
63
+ * Map a link's stored target from the source tree into the destination tree.
64
+ * pnpm on Windows often materializes directory links as junctions with absolute
65
+ * targets; copying those verbatim leaves them pointing at the source, which
66
+ * `assertBundleSymlinksStayInside` correctly rejects as an escape.
67
+ */
68
+ function mapLinkIntoDestination(sourceRoot, destinationRoot, sourcePath, destinationPath, rawTarget) {
69
+ const resolvedSource = path.resolve(path.dirname(sourcePath), rawTarget);
70
+ if (isWithin(sourceRoot, resolvedSource)) {
71
+ const resolvedTarget = path.resolve(destinationRoot, path.relative(sourceRoot, resolvedSource));
72
+ return {
73
+ target: path.relative(path.dirname(destinationPath), resolvedTarget),
74
+ resolvedTarget
75
+ };
76
+ }
77
+ return {
78
+ target: rawTarget,
79
+ resolvedTarget: path.resolve(path.dirname(destinationPath), rawTarget)
80
+ };
81
+ }
82
+ /** Restores directory-link metadata lost by `fs.cp` on Windows. */
83
+ async function repairWindowsDirectorySymlinks(root) {
84
+ if (process.platform !== "win32") return;
85
+ const visit = async (directory) => {
86
+ for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {
87
+ const full = path.join(directory, entry.name);
88
+ if (entry.isSymbolicLink()) {
89
+ const target = await fs.promises.readlink(full);
90
+ if (path.isAbsolute(target)) continue;
91
+ const resolvedTarget = path.resolve(path.dirname(full), target);
92
+ if (!isWithin(root, resolvedTarget)) continue;
93
+ try {
94
+ if (!(await fs.promises.stat(resolvedTarget)).isDirectory()) continue;
95
+ } catch {
96
+ continue;
97
+ }
98
+ await fs.promises.unlink(full);
99
+ await createBundleLink(full, target, "dir", {
100
+ resolvedTarget,
101
+ copyWithinRoot: root
102
+ });
103
+ } else if (entry.isDirectory()) await visit(full);
104
+ }
105
+ };
106
+ await visit(root);
107
+ }
108
+ /** Copy without `fs.cp`'s symlink privilege requirement: real files first, then links. */
109
+ async function copyTreeVerbatimWalk(source, destination) {
110
+ const sourceRoot = path.resolve(source);
111
+ const destinationRoot = path.resolve(destination);
112
+ const links = [];
113
+ const copyNonLinks = async (sourceDir, destinationDir) => {
114
+ await fs.promises.mkdir(destinationDir, { recursive: true });
115
+ for (const entry of await fs.promises.readdir(sourceDir, { withFileTypes: true })) {
116
+ const sourcePath = path.join(sourceDir, entry.name);
117
+ const destinationPath = path.join(destinationDir, entry.name);
118
+ if (entry.isSymbolicLink()) links.push({
119
+ sourcePath,
120
+ destinationPath
121
+ });
122
+ else if (entry.isDirectory()) await copyNonLinks(sourcePath, destinationPath);
123
+ else if (entry.isFile()) await fs.promises.copyFile(sourcePath, destinationPath);
124
+ }
125
+ };
126
+ await copyNonLinks(source, destination);
127
+ for (const { sourcePath, destinationPath } of links) {
128
+ const rawTarget = await fs.promises.readlink(sourcePath);
129
+ const resolvedSource = path.resolve(path.dirname(sourcePath), rawTarget);
130
+ let type = "file";
131
+ try {
132
+ type = (await fs.promises.stat(resolvedSource)).isDirectory() ? "dir" : "file";
133
+ } catch {}
134
+ const mapped = mapLinkIntoDestination(sourceRoot, destinationRoot, sourcePath, destinationPath, rawTarget);
135
+ await fs.promises.mkdir(path.dirname(destinationPath), { recursive: true });
136
+ await createBundleLink(destinationPath, mapped.target, type, {
137
+ resolvedTarget: mapped.resolvedTarget,
138
+ copySource: resolvedSource,
139
+ copyWithinRoot: destinationRoot
140
+ });
141
+ }
142
+ }
143
+ async function copyTreeVerbatim(source, destination) {
144
+ await copyTreeVerbatimWalk(source, destination);
145
+ }
146
+ /** Lexical containment: `candidate` is `root` itself or below it. Both paths
147
+ * must already be absolute or share a resolution base; no filesystem access. */
148
+ function isWithin(root, candidate) {
149
+ const relative = path.relative(root, candidate);
150
+ return relative === "" || !relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative);
151
+ }
152
+ /** Walks the assembled bundle and rejects a dangling symlink or one whose
153
+ * resolved target escapes the bundle root. Symlinked directories are not
154
+ * descended: their targets are validated, and their contents belong to the
155
+ * target's own location. */
156
+ async function assertBundleSymlinksStayInside(bundleDir) {
157
+ const realRoot = await fs.promises.realpath(bundleDir);
158
+ const walk = async (directory) => {
159
+ for (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {
160
+ const full = path.join(directory, entry.name);
161
+ if (entry.isSymbolicLink()) {
162
+ let realTarget;
163
+ try {
164
+ realTarget = await fs.promises.realpath(full);
165
+ } catch {
166
+ throw new Error(`the assembled bundle contains a dangling symlink: ${full}`);
167
+ }
168
+ if (!isWithin(realRoot, realTarget)) throw new Error(`the assembled bundle contains a symlink whose target escapes the bundle: ${full} -> ${await fs.promises.readlink(full)}`);
169
+ } else if (entry.isDirectory()) await walk(full);
170
+ }
171
+ };
172
+ await walk(bundleDir);
173
+ }
174
+ //#endregion
175
+ export { repairWindowsDirectorySymlinks as a, isWithin as i, copyTreeVerbatim as n, createBundleLink as r, assertBundleSymlinksStayInside as t };
176
+
177
+ //# sourceMappingURL=dist-DiYPSVUE.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dist-DiYPSVUE.mjs","names":[],"sources":["../../../0-framework/2-authoring/bundle-paths/dist/index.mjs"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n//#region src/bundle-paths.ts\n/**\n* The path-containment predicate and bundle-link validation shared by every\n* assembly and packaging seam (node/nextjs adapters, the compute artifact\n* writer, the local extractor). This predicate is the enforcement point of\n* ADR-0047's boundary — a symlink may be preserved only while its target\n* stays inside the assembled bundle — so it exists exactly once.\n*\n* Windows cannot create `dir`/`file` symlinks without Developer Mode or an\n* elevated token (`EPERM`). Directory junctions need no such privilege, so\n* assemble uses them on win32; file links fall back to a copy of the target.\n*/\n/** How a platform materializes a bundle link without needing symlink privilege. */\nfunction bundleLinkStrategy(platform, type) {\n\tif (platform !== \"win32\") return \"symlink\";\n\treturn type === \"dir\" ? \"junction\" : \"symlink-with-copy-fallback\";\n}\nfunction isNotPermitted(error) {\n\treturn error instanceof Error && Reflect.get(error, \"code\") === \"EPERM\";\n}\n/**\n* Creates a link at `linkPath` whose stored target is `target`.\n* `resolvedTarget` is the absolute path of that target in the destination\n* tree — junctions require it. The win32 file-copy fallback reads\n* `copySource` (source-tree path) when set, otherwise `resolvedTarget`, and\n* only when the target exists and stays inside `copyWithinRoot` (ADR-0047:\n* never dereference an escaping link into the artifact).\n*\n* Junction/symlink strategies may temporarily store an escaping\n* `resolvedTarget` (pnpm absolute junctions into the tracing-root store);\n* later staging rewrites them, and `assertBundleSymlinksStayInside` is the\n* final gate. Only the file-copy fallback must refuse escapes — copying would\n* materialize deploy-machine content as a regular file with no link left to\n* validate.\n*/\nasync function createBundleLink(linkPath, target, type, options) {\n\tconst strategy = bundleLinkStrategy(options.platform ?? process.platform, type);\n\tif (strategy === \"junction\") {\n\t\tawait fs.promises.symlink(options.resolvedTarget, linkPath, \"junction\");\n\t\treturn;\n\t}\n\tif (strategy === \"symlink\") {\n\t\tawait fs.promises.symlink(target, linkPath, type);\n\t\treturn;\n\t}\n\ttry {\n\t\tawait fs.promises.symlink(target, linkPath, \"file\");\n\t} catch (error) {\n\t\tif (!isNotPermitted(error)) throw error;\n\t\tif (!isWithin(path.resolve(options.copyWithinRoot), path.resolve(options.resolvedTarget))) throw new Error(`refusing to materialize a file link whose target escapes the bundle: ${linkPath} -> ${options.resolvedTarget}`, { cause: error });\n\t\tconst copyFrom = options.copySource ?? options.resolvedTarget;\n\t\ttry {\n\t\t\tawait fs.promises.stat(copyFrom);\n\t\t} catch {\n\t\t\tthrow new Error(`the assembled bundle contains a dangling symlink: ${linkPath}`);\n\t\t}\n\t\tawait fs.promises.copyFile(copyFrom, linkPath);\n\t}\n}\n/**\n* Map a link's stored target from the source tree into the destination tree.\n* pnpm on Windows often materializes directory links as junctions with absolute\n* targets; copying those verbatim leaves them pointing at the source, which\n* `assertBundleSymlinksStayInside` correctly rejects as an escape.\n*/\nfunction mapLinkIntoDestination(sourceRoot, destinationRoot, sourcePath, destinationPath, rawTarget) {\n\tconst resolvedSource = path.resolve(path.dirname(sourcePath), rawTarget);\n\tif (isWithin(sourceRoot, resolvedSource)) {\n\t\tconst resolvedTarget = path.resolve(destinationRoot, path.relative(sourceRoot, resolvedSource));\n\t\treturn {\n\t\t\ttarget: path.relative(path.dirname(destinationPath), resolvedTarget),\n\t\t\tresolvedTarget\n\t\t};\n\t}\n\treturn {\n\t\ttarget: rawTarget,\n\t\tresolvedTarget: path.resolve(path.dirname(destinationPath), rawTarget)\n\t};\n}\n/** Restores directory-link metadata lost by `fs.cp` on Windows. */\nasync function repairWindowsDirectorySymlinks(root) {\n\tif (process.platform !== \"win32\") return;\n\tconst visit = async (directory) => {\n\t\tfor (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n\t\t\tconst full = path.join(directory, entry.name);\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\tconst target = await fs.promises.readlink(full);\n\t\t\t\tif (path.isAbsolute(target)) continue;\n\t\t\t\tconst resolvedTarget = path.resolve(path.dirname(full), target);\n\t\t\t\tif (!isWithin(root, resolvedTarget)) continue;\n\t\t\t\ttry {\n\t\t\t\t\tif (!(await fs.promises.stat(resolvedTarget)).isDirectory()) continue;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait fs.promises.unlink(full);\n\t\t\t\tawait createBundleLink(full, target, \"dir\", {\n\t\t\t\t\tresolvedTarget,\n\t\t\t\t\tcopyWithinRoot: root\n\t\t\t\t});\n\t\t\t} else if (entry.isDirectory()) await visit(full);\n\t\t}\n\t};\n\tawait visit(root);\n}\n/** Copy without `fs.cp`'s symlink privilege requirement: real files first, then links. */\nasync function copyTreeVerbatimWalk(source, destination) {\n\tconst sourceRoot = path.resolve(source);\n\tconst destinationRoot = path.resolve(destination);\n\tconst links = [];\n\tconst copyNonLinks = async (sourceDir, destinationDir) => {\n\t\tawait fs.promises.mkdir(destinationDir, { recursive: true });\n\t\tfor (const entry of await fs.promises.readdir(sourceDir, { withFileTypes: true })) {\n\t\t\tconst sourcePath = path.join(sourceDir, entry.name);\n\t\t\tconst destinationPath = path.join(destinationDir, entry.name);\n\t\t\tif (entry.isSymbolicLink()) links.push({\n\t\t\t\tsourcePath,\n\t\t\t\tdestinationPath\n\t\t\t});\n\t\t\telse if (entry.isDirectory()) await copyNonLinks(sourcePath, destinationPath);\n\t\t\telse if (entry.isFile()) await fs.promises.copyFile(sourcePath, destinationPath);\n\t\t}\n\t};\n\tawait copyNonLinks(source, destination);\n\tfor (const { sourcePath, destinationPath } of links) {\n\t\tconst rawTarget = await fs.promises.readlink(sourcePath);\n\t\tconst resolvedSource = path.resolve(path.dirname(sourcePath), rawTarget);\n\t\tlet type = \"file\";\n\t\ttry {\n\t\t\ttype = (await fs.promises.stat(resolvedSource)).isDirectory() ? \"dir\" : \"file\";\n\t\t} catch {}\n\t\tconst mapped = mapLinkIntoDestination(sourceRoot, destinationRoot, sourcePath, destinationPath, rawTarget);\n\t\tawait fs.promises.mkdir(path.dirname(destinationPath), { recursive: true });\n\t\tawait createBundleLink(destinationPath, mapped.target, type, {\n\t\t\tresolvedTarget: mapped.resolvedTarget,\n\t\t\tcopySource: resolvedSource,\n\t\t\tcopyWithinRoot: destinationRoot\n\t\t});\n\t}\n}\nasync function copyTreeVerbatim(source, destination) {\n\tawait copyTreeVerbatimWalk(source, destination);\n}\n/** Lexical containment: `candidate` is `root` itself or below it. Both paths\n* must already be absolute or share a resolution base; no filesystem access. */\nfunction isWithin(root, candidate) {\n\tconst relative = path.relative(root, candidate);\n\treturn relative === \"\" || !relative.startsWith(`..${path.sep}`) && relative !== \"..\" && !path.isAbsolute(relative);\n}\n/** Walks the assembled bundle and rejects a dangling symlink or one whose\n* resolved target escapes the bundle root. Symlinked directories are not\n* descended: their targets are validated, and their contents belong to the\n* target's own location. */\nasync function assertBundleSymlinksStayInside(bundleDir) {\n\tconst realRoot = await fs.promises.realpath(bundleDir);\n\tconst walk = async (directory) => {\n\t\tfor (const entry of await fs.promises.readdir(directory, { withFileTypes: true })) {\n\t\t\tconst full = path.join(directory, entry.name);\n\t\t\tif (entry.isSymbolicLink()) {\n\t\t\t\tlet realTarget;\n\t\t\t\ttry {\n\t\t\t\t\trealTarget = await fs.promises.realpath(full);\n\t\t\t\t} catch {\n\t\t\t\t\tthrow new Error(`the assembled bundle contains a dangling symlink: ${full}`);\n\t\t\t\t}\n\t\t\t\tif (!isWithin(realRoot, realTarget)) throw new Error(`the assembled bundle contains a symlink whose target escapes the bundle: ${full} -> ${await fs.promises.readlink(full)}`);\n\t\t\t} else if (entry.isDirectory()) await walk(full);\n\t\t}\n\t};\n\tawait walk(bundleDir);\n}\n//#endregion\nexport { assertBundleSymlinksStayInside, bundleLinkStrategy, copyTreeVerbatim, createBundleLink, isWithin, repairWindowsDirectorySymlinks };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAS,mBAAmB,UAAU,MAAM;CAC3C,IAAI,aAAa,SAAS,OAAO;CACjC,OAAO,SAAS,QAAQ,aAAa;AACtC;AACA,SAAS,eAAe,OAAO;CAC9B,OAAO,iBAAiB,SAAS,QAAQ,IAAI,OAAO,MAAM,MAAM;AACjE;;;;;;;;;;;;;;;;AAgBA,eAAe,iBAAiB,UAAU,QAAQ,MAAM,SAAS;CAChE,MAAM,WAAW,mBAAmB,QAAQ,YAAY,QAAQ,UAAU,IAAI;CAC9E,IAAI,aAAa,YAAY;EAC5B,MAAM,GAAG,SAAS,QAAQ,QAAQ,gBAAgB,UAAU,UAAU;EACtE;CACD;CACA,IAAI,aAAa,WAAW;EAC3B,MAAM,GAAG,SAAS,QAAQ,QAAQ,UAAU,IAAI;EAChD;CACD;CACA,IAAI;EACH,MAAM,GAAG,SAAS,QAAQ,QAAQ,UAAU,MAAM;CACnD,SAAS,OAAO;EACf,IAAI,CAAC,eAAe,KAAK,GAAG,MAAM;EAClC,IAAI,CAAC,SAAS,KAAK,QAAQ,QAAQ,cAAc,GAAG,KAAK,QAAQ,QAAQ,cAAc,CAAC,GAAG,MAAM,IAAI,MAAM,wEAAwE,SAAS,MAAM,QAAQ,kBAAkB,EAAE,OAAO,MAAM,CAAC;EAC5O,MAAM,WAAW,QAAQ,cAAc,QAAQ;EAC/C,IAAI;GACH,MAAM,GAAG,SAAS,KAAK,QAAQ;EAChC,QAAQ;GACP,MAAM,IAAI,MAAM,qDAAqD,UAAU;EAChF;EACA,MAAM,GAAG,SAAS,SAAS,UAAU,QAAQ;CAC9C;AACD;;;;;;;AAOA,SAAS,uBAAuB,YAAY,iBAAiB,YAAY,iBAAiB,WAAW;CACpG,MAAM,iBAAiB,KAAK,QAAQ,KAAK,QAAQ,UAAU,GAAG,SAAS;CACvE,IAAI,SAAS,YAAY,cAAc,GAAG;EACzC,MAAM,iBAAiB,KAAK,QAAQ,iBAAiB,KAAK,SAAS,YAAY,cAAc,CAAC;EAC9F,OAAO;GACN,QAAQ,KAAK,SAAS,KAAK,QAAQ,eAAe,GAAG,cAAc;GACnE;EACD;CACD;CACA,OAAO;EACN,QAAQ;EACR,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,eAAe,GAAG,SAAS;CACtE;AACD;;AAEA,eAAe,+BAA+B,MAAM;CACnD,IAAI,QAAQ,aAAa,SAAS;CAClC,MAAM,QAAQ,OAAO,cAAc;EAClC,KAAK,MAAM,SAAS,MAAM,GAAG,SAAS,QAAQ,WAAW,EAAE,eAAe,KAAK,CAAC,GAAG;GAClF,MAAM,OAAO,KAAK,KAAK,WAAW,MAAM,IAAI;GAC5C,IAAI,MAAM,eAAe,GAAG;IAC3B,MAAM,SAAS,MAAM,GAAG,SAAS,SAAS,IAAI;IAC9C,IAAI,KAAK,WAAW,MAAM,GAAG;IAC7B,MAAM,iBAAiB,KAAK,QAAQ,KAAK,QAAQ,IAAI,GAAG,MAAM;IAC9D,IAAI,CAAC,SAAS,MAAM,cAAc,GAAG;IACrC,IAAI;KACH,IAAI,EAAE,MAAM,GAAG,SAAS,KAAK,cAAc,EAAA,CAAG,YAAY,GAAG;IAC9D,QAAQ;KACP;IACD;IACA,MAAM,GAAG,SAAS,OAAO,IAAI;IAC7B,MAAM,iBAAiB,MAAM,QAAQ,OAAO;KAC3C;KACA,gBAAgB;IACjB,CAAC;GACF,OAAO,IAAI,MAAM,YAAY,GAAG,MAAM,MAAM,IAAI;EACjD;CACD;CACA,MAAM,MAAM,IAAI;AACjB;;AAEA,eAAe,qBAAqB,QAAQ,aAAa;CACxD,MAAM,aAAa,KAAK,QAAQ,MAAM;CACtC,MAAM,kBAAkB,KAAK,QAAQ,WAAW;CAChD,MAAM,QAAQ,CAAC;CACf,MAAM,eAAe,OAAO,WAAW,mBAAmB;EACzD,MAAM,GAAG,SAAS,MAAM,gBAAgB,EAAE,WAAW,KAAK,CAAC;EAC3D,KAAK,MAAM,SAAS,MAAM,GAAG,SAAS,QAAQ,WAAW,EAAE,eAAe,KAAK,CAAC,GAAG;GAClF,MAAM,aAAa,KAAK,KAAK,WAAW,MAAM,IAAI;GAClD,MAAM,kBAAkB,KAAK,KAAK,gBAAgB,MAAM,IAAI;GAC5D,IAAI,MAAM,eAAe,GAAG,MAAM,KAAK;IACtC;IACA;GACD,CAAC;QACI,IAAI,MAAM,YAAY,GAAG,MAAM,aAAa,YAAY,eAAe;QACvE,IAAI,MAAM,OAAO,GAAG,MAAM,GAAG,SAAS,SAAS,YAAY,eAAe;EAChF;CACD;CACA,MAAM,aAAa,QAAQ,WAAW;CACtC,KAAK,MAAM,EAAE,YAAY,qBAAqB,OAAO;EACpD,MAAM,YAAY,MAAM,GAAG,SAAS,SAAS,UAAU;EACvD,MAAM,iBAAiB,KAAK,QAAQ,KAAK,QAAQ,UAAU,GAAG,SAAS;EACvE,IAAI,OAAO;EACX,IAAI;GACH,QAAQ,MAAM,GAAG,SAAS,KAAK,cAAc,EAAA,CAAG,YAAY,IAAI,QAAQ;EACzE,QAAQ,CAAC;EACT,MAAM,SAAS,uBAAuB,YAAY,iBAAiB,YAAY,iBAAiB,SAAS;EACzG,MAAM,GAAG,SAAS,MAAM,KAAK,QAAQ,eAAe,GAAG,EAAE,WAAW,KAAK,CAAC;EAC1E,MAAM,iBAAiB,iBAAiB,OAAO,QAAQ,MAAM;GAC5D,gBAAgB,OAAO;GACvB,YAAY;GACZ,gBAAgB;EACjB,CAAC;CACF;AACD;AACA,eAAe,iBAAiB,QAAQ,aAAa;CACpD,MAAM,qBAAqB,QAAQ,WAAW;AAC/C;;;AAGA,SAAS,SAAS,MAAM,WAAW;CAClC,MAAM,WAAW,KAAK,SAAS,MAAM,SAAS;CAC9C,OAAO,aAAa,MAAM,CAAC,SAAS,WAAW,KAAK,KAAK,KAAK,KAAK,aAAa,QAAQ,CAAC,KAAK,WAAW,QAAQ;AAClH;;;;;AAKA,eAAe,+BAA+B,WAAW;CACxD,MAAM,WAAW,MAAM,GAAG,SAAS,SAAS,SAAS;CACrD,MAAM,OAAO,OAAO,cAAc;EACjC,KAAK,MAAM,SAAS,MAAM,GAAG,SAAS,QAAQ,WAAW,EAAE,eAAe,KAAK,CAAC,GAAG;GAClF,MAAM,OAAO,KAAK,KAAK,WAAW,MAAM,IAAI;GAC5C,IAAI,MAAM,eAAe,GAAG;IAC3B,IAAI;IACJ,IAAI;KACH,aAAa,MAAM,GAAG,SAAS,SAAS,IAAI;IAC7C,QAAQ;KACP,MAAM,IAAI,MAAM,qDAAqD,MAAM;IAC5E;IACA,IAAI,CAAC,SAAS,UAAU,UAAU,GAAG,MAAM,IAAI,MAAM,4EAA4E,KAAK,MAAM,MAAM,GAAG,SAAS,SAAS,IAAI,GAAG;GAC/K,OAAO,IAAI,MAAM,YAAY,GAAG,MAAM,KAAK,IAAI;EAChD;CACD;CACA,MAAM,KAAK,SAAS;AACrB"}
@@ -1,4 +1,4 @@
1
- import { A as PrismaAppConfig, _ as LocalTargetEmulatorsInput, c as ContainerInstance, g as LocalTargetDescriptor, h as LocalTargetAttachment, l as DEV_DIR, m as LocalTargetAttachInput, v as LocalTargetProvidersInput } from "./app-config-CooZZhD4-EAGtxAPU.mjs";
1
+ import { A as PrismaAppConfig, _ as LocalTargetEmulatorsInput, c as ContainerInstance, g as LocalTargetDescriptor, h as LocalTargetAttachment, l as DEV_DIR, m as LocalTargetAttachInput, v as LocalTargetProvidersInput } from "./app-config-jGcCcxK4-DnzGGbDS.mjs";
2
2
  import * as Layer from "effect/Layer";
3
3
  //#region ../../0-framework/1-core/core/dist/local-target.d.mts
4
4
  //#region src/control/local-target.d.ts
@@ -1,6 +1,6 @@
1
- import { a as Bundle, i as AssembleInput, p as ExtensionDescriptor } from "./app-config-CooZZhD4-EAGtxAPU.mjs";
2
- import "./config-BmK1pGlA.mjs";
3
- import "./deploy-BmK1pGlA.mjs";
1
+ import { a as Bundle, i as AssembleInput, p as ExtensionDescriptor } from "./app-config-jGcCcxK4-DnzGGbDS.mjs";
2
+ import "./config-BGtKERz-.mjs";
3
+ import "./deploy-BGtKERz-.mjs";
4
4
  import { t as NextjsBuildAdapter } from "./nextjs-DLyeRR7M-D7UOddVQ.mjs";
5
5
  //#region ../../0-framework/2-authoring/nextjs/dist/control.d.mts
6
6
  //#region src/control/build.d.ts
@@ -1,4 +1,4 @@
1
- import { i as repairWindowsDirectorySymlinks, n as copyTreeVerbatim, r as isWithin, t as assertBundleSymlinksStayInside } from "./dist-D1TA1xGC.mjs";
1
+ import { a as repairWindowsDirectorySymlinks, i as isWithin, n as copyTreeVerbatim, r as createBundleLink, t as assertBundleSymlinksStayInside } from "./dist-DiYPSVUE.mjs";
2
2
  import * as fs$1 from "node:fs";
3
3
  import * as path$1 from "node:path";
4
4
  import { fileURLToPath } from "node:url";
@@ -100,7 +100,6 @@ async function missingLinkTargets(bundleDir) {
100
100
  const missing = [];
101
101
  for (const linkPath of await collectSymlinks(bundleDir)) {
102
102
  const rawTarget = await fs$1.promises.readlink(linkPath);
103
- if (path$1.isAbsolute(rawTarget)) continue;
104
103
  const target = path$1.resolve(path$1.dirname(linkPath), rawTarget);
105
104
  if (!isWithin(bundleDir, target) || await lstatIfPresent(target) !== void 0) continue;
106
105
  if (await hasSymlinkAncestor(bundleDir, target)) continue;
@@ -109,6 +108,44 @@ async function missingLinkTargets(bundleDir) {
109
108
  return missing;
110
109
  }
111
110
  /**
111
+ * Absolute junctions (pnpm on Windows) often point from `.next/standalone`
112
+ * straight into the app's `node_modules/.pnpm/...` under the tracing root —
113
+ * outside the standalone copy root. After `copyTreeVerbatim` those links still
114
+ * escape the assembled bundle; stage the real target under the bundle at the
115
+ * same tracing-root-relative path and repoint the link.
116
+ */
117
+ async function stageEscapingTracingRootLinks(bundleDir, tracedRootReal) {
118
+ const nodeModulesRoot = path$1.join(tracedRootReal, "node_modules");
119
+ const stagedSources = /* @__PURE__ */ new Set();
120
+ for (const linkPath of await collectSymlinks(bundleDir)) {
121
+ const rawTarget = await fs$1.promises.readlink(linkPath);
122
+ let resolved = path$1.resolve(path$1.dirname(linkPath), rawTarget);
123
+ if (await lstatIfPresent(resolved) === void 0) continue;
124
+ try {
125
+ resolved = await fs$1.promises.realpath(resolved);
126
+ } catch {
127
+ continue;
128
+ }
129
+ if (isWithin(bundleDir, resolved)) continue;
130
+ if (!isWithin(nodeModulesRoot, resolved) && resolved !== nodeModulesRoot) continue;
131
+ const stagedAt = path$1.join(bundleDir, path$1.relative(tracedRootReal, resolved));
132
+ if (await lstatIfPresent(stagedAt) === void 0) {
133
+ await fs$1.promises.mkdir(path$1.dirname(stagedAt), { recursive: true });
134
+ if ((await fs$1.promises.stat(resolved)).isDirectory()) await copyTreeVerbatim(resolved, stagedAt);
135
+ else await fs$1.promises.copyFile(resolved, stagedAt);
136
+ stagedSources.add(resolved);
137
+ }
138
+ const type = (await fs$1.promises.stat(stagedAt)).isDirectory() ? "dir" : "file";
139
+ await fs$1.promises.unlink(linkPath);
140
+ await createBundleLink(linkPath, path$1.relative(path$1.dirname(linkPath), stagedAt), type, {
141
+ resolvedTarget: stagedAt,
142
+ copySource: stagedAt,
143
+ copyWithinRoot: bundleDir
144
+ });
145
+ }
146
+ return [...stagedSources];
147
+ }
148
+ /**
112
149
  * pnpm can leave a traced hoist link in standalone while omitting the virtual-
113
150
  * store directory it targets. The same target still exists at the corresponding
114
151
  * path under outputFileTracingRoot. Stage only that exact, real in-root target;
@@ -137,6 +174,7 @@ async function stageMissingStandaloneLinkTargets(bundleDir, manifest) {
137
174
  staged = true;
138
175
  }
139
176
  }
177
+ for (const source of await stageEscapingTracingRootLinks(bundleDir, tracedRootReal)) stagedSources.add(source);
140
178
  return [...stagedSources];
141
179
  }
142
180
  /** The built standalone server.js for a nextjs build — `appDir`'s standalone root plus the app subpath Next recorded. Single-sourced so `assemble()` (deploy) and the integration-test seam can't drift. */