@prisma/composer-prisma-cloud 0.16.0-dev.3 → 0.16.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/pack.mjs +1 -1
- package/dist/auth/pack.mjs.map +1 -1
- package/dist/auth/testing.mjs +1 -1
- package/dist/auth/testing.mjs.map +1 -1
- package/dist/buckets-main.mjs +4 -7
- package/dist/buckets-main.mjs.map +1 -1
- package/dist/control.mjs +1 -1
- package/dist/local-target.mjs +1 -1
- package/dist/{s3-credentials-resource-D_qSGYMM-CnDQrSMW.mjs → s3-credentials-resource-D_qSGYMM-BiT5e-MA.mjs} +1 -8
- package/dist/s3-credentials-resource-D_qSGYMM-BiT5e-MA.mjs.map +1 -0
- package/package.json +18 -18
- package/dist/s3-credentials-resource-D_qSGYMM-CnDQrSMW.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-credentials-resource-D_qSGYMM-BiT5e-MA.mjs","names":["Config","randomBytes","managementClientLayer"],"sources":["../../../1-prisma-cloud/0-lowering/lowering/dist/credentials-DhT4a38W.mjs","../../../1-prisma-cloud/0-lowering/lowering/dist/database-url-claim-m_nGXIHa.mjs","../../../0-framework/2-authoring/bundle-paths/dist/index.mjs","../../../1-prisma-cloud/0-lowering/lowering/dist/compute.mjs","../../../1-prisma-cloud/0-lowering/lowering/dist/index.mjs","../../../1-prisma-cloud/0-lowering/s3-protocol/dist/index.mjs","../../../1-prisma-cloud/1-extensions/target/dist/s3-credentials-resource-D_qSGYMM.mjs"],"sourcesContent":["import * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Config from \"effect/Config\";\n//#region src/credentials.ts\n/**\n* The Prisma service token used to authenticate Management API calls. Kept\n* as a Redacted value so it never lands in logs or error output.\n*/\nvar PrismaCredentials = class extends Context.Service()(\"PrismaCredentials\") {};\n/** Resolve the token from the `PRISMA_SERVICE_TOKEN` environment variable. */\nconst fromEnv = () => Layer.effect(PrismaCredentials, Effect.gen(function* () {\n\treturn { token: yield* Config.redacted(\"PRISMA_SERVICE_TOKEN\") };\n}));\nconst DEFAULT_BASE_URL = \"https://api.prisma.io\";\nconst isLoopbackHost = (hostname) => hostname === \"localhost\" || hostname.endsWith(\".localhost\") || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n/** Same validation as upstream alchemy's `PrismaEnvironment`: an HTTP(S) origin, HTTPS unless loopback, no credentials, no path/query/fragment. */\nconst normalizeBaseUrl = (value) => Effect.try({\n\ttry: () => {\n\t\tconst url = new URL(value);\n\t\tif (url.protocol !== \"https:\" && url.protocol !== \"http:\") throw new Error(\"Prisma Management API URL must use HTTP or HTTPS.\");\n\t\tif (url.username.length > 0 || url.password.length > 0) throw new Error(\"Prisma Management API URL must not contain credentials.\");\n\t\tif (url.protocol === \"http:\" && !isLoopbackHost(url.hostname)) throw new Error(\"Prisma Management API URL must use HTTPS unless it targets a loopback host.\");\n\t\tif (url.pathname !== \"/\" && url.pathname !== \"\" || url.search.length > 0 || url.hash.length > 0) throw new Error(\"Prisma Management API URL must be an origin without a path, query, or fragment.\");\n\t\treturn url.origin;\n\t},\n\tcatch: (cause) => cause instanceof Error ? cause : /* @__PURE__ */ new Error(`Invalid Prisma Management API URL: ${String(cause)}`)\n});\n/**\n* The Management API origin every Prisma-Cloud client in this package uses —\n* Composer's own SDK client AND upstream alchemy's postgres providers resolve\n* it through this one function, so `PRISMA_API_URL` can never point them at\n* different hosts. Mirrors upstream alchemy's `PrismaEnvironment` resolution:\n* `PRISMA_API_URL`, then `PRISMA_MANAGEMENT_API_URL`, then the public origin,\n* normalized and validated identically.\n*/\nconst managementApiBaseUrl = (env) => env !== void 0 ? normalizeBaseUrl(env[\"PRISMA_API_URL\"] || env[\"PRISMA_MANAGEMENT_API_URL\"] || DEFAULT_BASE_URL) : Config.string(\"PRISMA_API_URL\").pipe(Config.orElse(() => Config.string(\"PRISMA_MANAGEMENT_API_URL\")), Config.withDefault(DEFAULT_BASE_URL), Effect.flatMap(normalizeBaseUrl));\n//#endregion\nexport { fromEnv as n, managementApiBaseUrl as r, PrismaCredentials as t };\n\n//# sourceMappingURL=credentials-DhT4a38W.mjs.map","import { r as managementApiBaseUrl, t as PrismaCredentials } from \"./credentials-DhT4a38W.mjs\";\nimport { createManagementApiClient } from \"@prisma/management-api-sdk\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Data from \"effect/Data\";\nimport * as Option from \"effect/Option\";\n//#region src/client.ts\n/**\n* The typed Prisma Management API client, built once from the resolved\n* credentials. Providers yield this in their outer Effect and call it inside\n* `reconcile` / `delete`.\n*/\nvar ManagementClient = class extends Context.Service()(\"PrismaManagementClient\") {};\n/**\n* By default the base URL comes from `managementApiBaseUrl()` — the SAME\n* resolver upstream's providers use (see providers.ts), so `PRISMA_API_URL`\n* can never split the postgres family and the compute/bucket/state clients\n* across hosts. `apiOrigin` overrides it (tests point it at a fake).\n*/\nconst layer = (options) => Layer.effect(ManagementClient, Effect.gen(function* () {\n\tconst { token } = yield* PrismaCredentials;\n\tconst baseUrl = options?.apiOrigin ?? (yield* managementApiBaseUrl());\n\treturn createManagementApiClient({\n\t\ttoken: Redacted.value(token),\n\t\tbaseUrl\n\t});\n}));\n//#endregion\n//#region src/http.ts\n/** A non-2xx response from the Management API (or a transport failure). */\nvar PrismaApiError = class extends Data.TaggedError(\"PrismaApiError\") {};\nconst attempt = (f) => Effect.tryPromise({\n\ttry: f,\n\tcatch: (cause) => new PrismaApiError({\n\t\tstatus: 0,\n\t\tmessage: String(cause)\n\t})\n});\nconst fail = (r) => Effect.fail(new PrismaApiError({\n\tstatus: r.response.status,\n\tmessage: JSON.stringify(r.error)\n}));\n/** Unwrap `data`, failing on any API error. Preserves the SDK's response type. */\nconst call = (f) => attempt(f).pipe(Effect.flatMap((r) => r.error !== void 0 || r.data === void 0 ? fail(r) : Effect.succeed(r.data)));\n/** Fire-and-forget a call, tolerating a 404 (already deleted). */\nconst callVoid = (f) => attempt(f).pipe(Effect.flatMap((r) => r.response.status === 404 || r.error === void 0 ? Effect.void : fail(r)));\n/**\n* Fire a CREATE call, tolerating a 409 (it already exists). Gives the caller\n* create-only semantics: the thing is created when absent, and an existing one\n* — whoever created it — is left exactly as it is.\n*/\nconst callCreateOnly = (f) => attempt(f).pipe(Effect.flatMap((r) => r.response.status === 409 || r.error === void 0 ? Effect.void : fail(r)));\n//#endregion\n//#region src/pagination.ts\n/** Far beyond any real collection size per listing; hitting it means the API's pagination is broken. */\nconst MAX_PAGES = 1e3;\nconst brokenPaginationError = (description, reason) => new PrismaApiError({\n\tstatus: 0,\n\tmessage: `listing ${description} ${reason} — the Management API pagination appears broken; refusing to continue with a possibly incomplete listing.`\n});\n/** {@link drivePages} in its most common shape: every page's rows, accumulated. */\nconst collectPages = (description, fetchPage) => Effect.gen(function* () {\n\tconst rows = [];\n\tyield* drivePages(description, fetchPage, (data) => {\n\t\trows.push(...data);\n\t\treturn false;\n\t});\n\treturn rows;\n});\n/**\n* Drives a cursor-paginated Management API listing with a guard against\n* broken pagination: a cursor that does not advance, more pages reported\n* without a cursor to fetch them with, or more than {@link MAX_PAGES} pages,\n* FAILS instead of hanging forever or returning a listing known to be\n* incomplete. `onPage` receives each page's rows as they arrive; returning\n* `true` stops early (the caller found what it wanted).\n*/\nconst drivePages = (description, fetchPage, onPage) => Effect.gen(function* () {\n\tlet cursor;\n\tfor (let pageCount = 0;; pageCount++) {\n\t\tif (pageCount >= MAX_PAGES) return yield* Effect.fail(brokenPaginationError(description, `did not finish within ${String(MAX_PAGES)} pages`));\n\t\tconst page = yield* fetchPage(cursor);\n\t\tif (onPage(page.data)) return;\n\t\tif (!page.pagination.hasMore) return;\n\t\tconst next = page.pagination.nextCursor;\n\t\tif (next === null) return yield* Effect.fail(brokenPaginationError(description, \"reported more pages but returned no cursor\"));\n\t\tif (next === cursor) return yield* Effect.fail(brokenPaginationError(description, \"returned a non-advancing cursor\"));\n\t\tcursor = next;\n\t}\n});\n/**\n* {@link drivePages} for Promise-based callers (e.g. target's preflight,\n* which speaks the SDK's `{data, error}` shape directly). Same guard, same\n* errors; deliberately a sibling loop rather than a wrapper, because routing\n* a Promise fetch through Effect and back (`Effect.tryPromise` +\n* `runPromise`) would re-wrap the caller's own thrown errors. `fetchPage`\n* rejections propagate untouched.\n*/\nasync function drivePagesAsync(description, fetchPage, onPage) {\n\tlet cursor;\n\tfor (let pageCount = 0;; pageCount++) {\n\t\tif (pageCount >= MAX_PAGES) throw brokenPaginationError(description, `did not finish within ${String(MAX_PAGES)} pages`);\n\t\tconst page = await fetchPage(cursor);\n\t\tif (onPage(page.data)) return;\n\t\tif (!page.pagination.hasMore) return;\n\t\tconst next = page.pagination.nextCursor;\n\t\tif (next === null) throw brokenPaginationError(description, \"reported more pages but returned no cursor\");\n\t\tif (next === cursor) throw brokenPaginationError(description, \"returned a non-advancing cursor\");\n\t\tcursor = next;\n\t}\n}\n//#endregion\n//#region src/container.ts\n/** Raised with `ensure: false` when the app's Project (or a named stage's Branch) doesn't exist. */\nvar ContainerNotFoundError = class extends Data.TaggedError(\"ContainerNotFoundError\") {};\nconst listAllProjects = (client) => collectPages(\"projects\", (cursor) => call(() => client.GET(\"/v1/projects\", { params: { query: cursor === void 0 ? {} : { cursor } } })));\n/**\n* Workspace ids circulate in two shapes: `wksp_`-prefixed and bare. Compare\n* bare-to-bare so a `wksp_`-prefixed API id still matches a bare configured\n* one (the same normalization `state/bootstrap.ts` applies to the same\n* `/v1/projects` listing).\n*/\nconst bareWorkspaceId = (id) => id.startsWith(\"wksp_\") ? id.slice(5) : id;\n/**\n* Finds the app's Project by logical id or name in the workspace, creating\n* one if absent. Logical id match (exact, workspace-unique) is preferred over\n* display-name match (oldest-wins fallback for projects without a logical id).\n* Creates one if none match, unless `ensure` is `false` (find-only —\n* `destroy`), in which case an absent Project fails with\n* `ContainerNotFoundError`. No ownership marker and no `--project` override\n* (both deferred — see ADR-0019).\n*/\nconst resolveProject = (client, workspaceId, appName, ensure) => Effect.gen(function* () {\n\tconst workspaceProjects = (yield* listAllProjects(client)).filter((p) => bareWorkspaceId(p.workspace.id) === bareWorkspaceId(workspaceId));\n\tconst logicalIdMatch = workspaceProjects.find((p) => p.logicalId != null && p.logicalId === appName);\n\tif (logicalIdMatch !== void 0) return logicalIdMatch.id;\n\tconst nameMatch = workspaceProjects.filter((p) => p.name === appName).sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];\n\tif (nameMatch !== void 0) return nameMatch.id;\n\tif (!ensure) return yield* Effect.fail(new ContainerNotFoundError({ appName }));\n\treturn (yield* call(() => client.POST(\"/v1/projects\", { body: {\n\t\tname: appName,\n\t\tworkspaceId,\n\t\tcreateDatabase: false,\n\t\tlogicalId: appName\n\t} })).pipe(Effect.catch((err) => err.status === 409 ? Effect.fail(new PrismaApiError({\n\t\tstatus: 409,\n\t\tmessage: \"a project with this name already exists in the workspace; rename your Composer module or free the name.\"\n\t})) : Effect.fail(err)))).data.id;\n});\n/**\n* The project's implicit default Branch — every live Project owns exactly\n* one (a platform invariant). The list endpoint has no `isDefault` filter,\n* so this pages through the Branches (bounded — drivePages) and returns as\n* soon as a page contains it. Never creates one: its absence means the\n* platform's invariant is broken, which is not something a deploy can\n* repair.\n*/\nconst resolveDefaultBranchId = (client, projectId) => Effect.gen(function* () {\n\tlet found;\n\tyield* drivePages(`branches of project ${projectId}`, (cursor) => call(() => client.GET(\"/v1/projects/{projectId}/branches\", { params: {\n\t\tpath: { projectId },\n\t\tquery: cursor === void 0 ? {} : { cursor }\n\t} })), (data) => {\n\t\tfound = data.find((b) => b.isDefault)?.id;\n\t\treturn found !== void 0;\n\t});\n\tif (found !== void 0) return found;\n\treturn yield* Effect.fail(new PrismaApiError({\n\t\tstatus: 0,\n\t\tmessage: `project ${projectId} has no default Branch — the platform guarantees every live Project owns one; contact support.`\n\t}));\n});\nconst findBranchId = (client, projectId, gitName) => call(() => client.GET(\"/v1/projects/{projectId}/branches\", { params: {\n\tpath: { projectId },\n\tquery: { gitName }\n} })).pipe(Effect.map((page) => page.data[0]?.id));\n/**\n* Finds the stage's Branch by its exact `gitName`, creating it if absent\n* unless `ensure` is `false` (find-only — `destroy`), in which case an\n* absent Branch fails with `ContainerNotFoundError`. The Management API has\n* no server-side \"create-or-return\" idempotency (`POST\n* /v1/projects/:id/branches` 409s on a duplicate `gitName`, with no request\n* field to make that a no-op), so idempotency is client-side: observe\n* first, and on a racing 409 from create, re-observe rather than fail.\n*/\nconst resolveBranch = (client, projectId, gitName, appName, ensure) => Effect.gen(function* () {\n\tconst existing = yield* findBranchId(client, projectId, gitName);\n\tif (existing !== void 0) return existing;\n\tif (!ensure) return yield* Effect.fail(new ContainerNotFoundError({\n\t\tappName,\n\t\tstage: gitName\n\t}));\n\treturn yield* call(() => client.POST(\"/v1/projects/{projectId}/branches\", {\n\t\tparams: { path: { projectId } },\n\t\tbody: { gitName }\n\t})).pipe(Effect.map((r) => r.data.id), Effect.catch((err) => err.status === 409 ? findBranchId(client, projectId, gitName).pipe(Effect.flatMap((id) => id === void 0 ? Effect.fail(err) : Effect.succeed(id))) : Effect.fail(err)));\n});\n/**\n* Resolves the two containers a stage's deploy runs into (ADR-0019): the\n* app's **Project**, found-or-created by name, and — for a named stage\n* only — its **Branch**, found-or-created by `gitName`. The default stage\n* (no `stage`) creates no Branch; `branchId` is omitted, and the project's\n* default Branch's id is read into `defaultBranchId` instead. With `ensure:\n* false` (`destroy`), nothing is created — an absent Project or Branch\n* fails with `ContainerNotFoundError` instead.\n*/\nconst resolveContainer = (opts) => Effect.gen(function* () {\n\tconst client = yield* ManagementClient;\n\tconst ensure = opts.ensure ?? true;\n\tconst projectId = yield* resolveProject(client, opts.workspaceId, opts.appName, ensure);\n\tif (opts.stage === void 0) return {\n\t\tprojectId,\n\t\tdefaultBranchId: yield* resolveDefaultBranchId(client, projectId)\n\t};\n\treturn {\n\t\tprojectId,\n\t\tbranchId: yield* resolveBranch(client, projectId, opts.stage, opts.appName, ensure)\n\t};\n});\n/**\n* Soft-deletes a Branch. Tolerates a 404 (already gone). The API refuses if\n* the Branch still has live members or is the production/default Branch —\n* that surfaces as a `PrismaApiError`.\n*/\nconst deleteBranch = (branchId) => Effect.gen(function* () {\n\tconst client = yield* ManagementClient;\n\tyield* callVoid(() => client.DELETE(\"/v1/branches/{branchId}\", { params: { path: { branchId } } }));\n});\n/**\n* Deletes a Project. Tolerates a 404 (already gone). The API refuses with a\n* 400 if the Project still has live dependencies (e.g. another stage's\n* Branch/resources) — that surfaces as a `PrismaApiError`.\n*/\nconst deleteProject = (projectId) => Effect.gen(function* () {\n\tconst client = yield* ManagementClient;\n\tyield* callVoid(() => client.DELETE(\"/v1/projects/{id}\", { params: { path: { id: projectId } } }));\n});\n//#endregion\n//#region src/database-url-claim.ts\n/**\n* Claims the platform's `DATABASE_URL` / `DATABASE_URL_POOLED` variables for\n* the app's project with the placeholder `\"-\"`, before the platform can seed\n* them: on a project with no production `DATABASE_URL`, Prisma Cloud fills\n* one in on the next compute deploy, handing live credentials to any service\n* that reads `process.env.DATABASE_URL` behind the framework's back. The\n* claim is create-only, so whoever writes first wins; any connect attempt\n* against `\"-\"` fails loudly (the API rejects an empty value).\n*\n* Deliberately NOT alchemy resources: Composer must never patch or delete\n* these variables, and a state row would plan exactly those calls.\n*/\nconst PLACEHOLDER_VALUE = \"-\";\n/** The two names Prisma Cloud fills in for itself, and that no Composer service may bind. */\nconst RESERVED_DATABASE_URL_KEYS = [\"DATABASE_URL\", \"DATABASE_URL_POOLED\"];\n/**\n* Both environment classes, each at PROJECT level (no branch id). A preview\n* branch with no override of its own reads the project-level preview row, so\n* these two rows cover every stage the app will ever deploy — including\n* stages that do not exist yet.\n*/\nconst ENVIRONMENT_CLASSES = [\"production\", \"preview\"];\nconst claim = (client, projectId, key, environmentClass) => callCreateOnly(() => client.POST(\"/v1/environment-variables\", { body: {\n\tprojectId,\n\tclass: environmentClass,\n\tkey,\n\tvalue: PLACEHOLDER_VALUE\n} }));\n/**\n* Claims both keys in both classes for `projectId`, create-only: a 409 means\n* the variable already exists — whether Prisma Cloud seeded it or an earlier\n* deploy claimed it — and is skipped, never overwritten and never removed.\n* Repeating it is always safe. Does nothing when no {@link ManagementClient}\n* is in context (the local target has no Management API).\n*/\nconst claimDatabaseUrlKeys = (projectId) => Effect.gen(function* () {\n\tconst client = yield* Effect.serviceOption(ManagementClient);\n\tif (Option.isNone(client)) return;\n\tfor (const key of RESERVED_DATABASE_URL_KEYS) for (const environmentClass of ENVIRONMENT_CLASSES) yield* claim(client.value, projectId, key, environmentClass);\n});\n//#endregion\nexport { deleteProject as a, collectPages as c, PrismaApiError as d, call as f, deleteBranch as i, drivePages as l, layer as m, claimDatabaseUrlKeys as n, resolveContainer as o, ManagementClient as p, ContainerNotFoundError as r, resolveDefaultBranchId as s, RESERVED_DATABASE_URL_KEYS as t, drivePagesAsync as u };\n\n//# sourceMappingURL=database-url-claim-m_nGXIHa.mjs.map","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/** 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\tconst resolvedTarget = path.resolve(path.dirname(full), target);\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 fs.promises.symlink(target, full, \"dir\");\n\t\t\t} else if (entry.isDirectory()) await visit(full);\n\t\t}\n\t};\n\tawait visit(root);\n}\nasync function copyTreeVerbatim(source, destination) {\n\tawait fs.promises.cp(source, destination, {\n\t\trecursive: true,\n\t\tverbatimSymlinks: true\n\t});\n\tawait repairWindowsDirectorySymlinks(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, copyTreeVerbatim, isWithin, repairWindowsDirectorySymlinks };\n\n//# sourceMappingURL=index.mjs.map","import { n as packageComputeArtifact, t as ARTIFACT_CONTENT_TYPE } from \"./artifact-CoKVIyRH.mjs\";\nimport * as Effect from \"effect/Effect\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Output from \"alchemy/Output\";\nimport { Resource } from \"alchemy\";\n//#region src/compute/deployment-edge.ts\n/**\n* Orders a deployment AFTER the environment rows it boots with: the platform\n* materializes rows into a deployment at create time and never re-reads them\n* (PRO-211). Alchemy schedules only on resource references inside prop\n* values, and upstream's `Prisma.Deployment` has no environment prop, so the\n* edge rides `app`: every variable's id threads through it, and the platform\n* still receives the app id. `app` is the ONLY safe prop — upstream's diff\n* treats `{portMapping, skipCodeUpload, artifactPath, artifactContentType}`\n* as one block and returns \"no opinion\" if any is unresolved (a brand-new\n* variable always is), which would silently skip the artifact comparison.\n* Ordering only: shipping a CHANGED value is `Deployment.triggers`' job (the\n* compute descriptor declares one member per environment row).\n*/\nconst appAfterEnvironment = (app, environment) => environment.length === 0 ? app : Output.flatMap(Output.all(app, ...environment.map((variable) => variable.environmentVariableId)), () => app);\n//#endregion\n//#region src/compute/ServiceKey.ts\n/**\n* The `ServiceKey` Alchemy resource (ADR-0030) — mints a random 256-bit key\n* ONCE at create and keeps it STABLE across deploys, so an unchanged edge\n* no-ops on redeploy. Same mint-once-stable lifecycle as `S3Credentials`\n* (`packages/1-prisma-cloud/1-extensions/target/src/s3-credentials-resource.ts`):\n* Web Crypto only (`crypto.getRandomValues` — no `node:` import), persisted in\n* Alchemy state; on every later apply the provider returns the persisted\n* attributes (`reconcile`'s `output`) unchanged. One resource per RPC edge;\n* rotation is destroy/recreate.\n*/\n/** The `ServiceKey` resource constructor — `yield* Prisma.ServiceKey(id, {})` in the lowering. */\nconst ServiceKey = Resource(\"PrismaCloud.ServiceKey\");\n/** A fresh 256-bit key as 64 lowercase hex chars (Web Crypto — no node import). */\nfunction mintServiceKey() {\n\tconst bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));\n\treturn { value: Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\") };\n}\n/**\n* The `ServiceKey` provider service. `reconcile` runs for create and update;\n* it returns the persisted `output` when present (a redeploy reuses the\n* stored key — the no-op property) and mints a fresh key only on first\n* create. Nothing to enumerate (`list` → `[]`) or tear down (`delete` →\n* no-op; the key lives only in state).\n*/\nconst serviceKeyProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ output }) => Effect.sync(() => output ?? mintServiceKey()),\n\tdelete: () => Effect.void\n};\n/** The `ServiceKey` provider layer — merged into the Prisma Cloud extension's `providers()`. */\nconst ServiceKeyProvider = () => Provider.effect(ServiceKey, Effect.succeed(serviceKeyProviderService));\n//#endregion\nexport { ARTIFACT_CONTENT_TYPE, ServiceKey, ServiceKeyProvider, appAfterEnvironment, mintServiceKey, packageComputeArtifact, serviceKeyProviderService };\n\n//# sourceMappingURL=compute.mjs.map","import { n as fromEnv, r as managementApiBaseUrl, t as PrismaCredentials } from \"./credentials-DhT4a38W.mjs\";\nimport { a as deleteProject, c as collectPages, i as deleteBranch, l as drivePages, m as layer, n as claimDatabaseUrlKeys, o as resolveContainer, p as ManagementClient, r as ContainerNotFoundError, s as resolveDefaultBranchId, t as RESERVED_DATABASE_URL_KEYS, u as drivePagesAsync } from \"./database-url-claim-m_nGXIHa.mjs\";\nimport { n as packageComputeArtifact, t as ARTIFACT_CONTENT_TYPE } from \"./artifact-CoKVIyRH.mjs\";\nimport { ServiceKey, ServiceKeyProvider, appAfterEnvironment, mintServiceKey, serviceKeyProviderService } from \"./compute.mjs\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as NodeHttpClient from \"@effect/platform-node/NodeHttpClient\";\nimport * as Prisma from \"alchemy/Prisma\";\nimport * as Provider from \"alchemy/Provider\";\n//#region src/providers.ts\n/** The collection of Prisma resource providers. */\nvar Providers = class extends Provider.ProviderCollection()(\"PrismaComposer\") {};\n/**\n* Upstream's `PrismaEnvironment`, built from Composer's own env credentials —\n* no profile store, so no TTY prompt and no non-interactive hard-fail:\n* `PRISMA_SERVICE_TOKEN` (redacted, via `PrismaCredentials`) plus the base\n* URL from `managementApiBaseUrl()` — the SAME resolver `client.ts` uses,\n* so `PRISMA_API_URL` moves the postgres family and the compute/bucket/state\n* clients together, never one without the other.\n*/\nconst prismaEnvironment = () => Layer.effect(Prisma.PrismaEnvironment, Effect.gen(function* () {\n\tconst { token } = yield* PrismaCredentials;\n\treturn {\n\t\ttype: \"serviceToken\",\n\t\tserviceToken: token,\n\t\tsource: {\n\t\t\ttype: \"env\",\n\t\t\tdetails: \"PRISMA_SERVICE_TOKEN\"\n\t\t},\n\t\tbaseUrl: yield* managementApiBaseUrl()\n\t};\n}));\n/**\n* Upstream alchemy's live providers for the postgres family (Project,\n* Database, Connection), the compute family (App, Deployment,\n* EnvironmentVariable), and the bucket family (Bucket, BucketAccessKey),\n* over upstream's management client, authenticated by\n* {@link prismaEnvironment}.\n*\n* Composed from the per-resource provider layers rather than upstream's own\n* `providers()` bundle: that bundle pulls in the profile store\n* (`AlchemyProfile`/`CredentialsStore`), and Composer deliberately runs\n* without one — no TTY prompt, no non-interactive hard-fail.\n*/\nconst upstreamPrismaProviders = () => Layer.mergeAll(Prisma.ProjectProvider(), Prisma.DatabaseProvider(), Prisma.ConnectionProvider(), Prisma.AppProvider(), Prisma.DeploymentProvider(), Prisma.EnvironmentVariableProvider(), Prisma.BucketProvider(), Prisma.BucketAccessKeyProvider()).pipe(Layer.provideMerge(Prisma.PrismaClientLive), Layer.provide(NodeHttpClient.layerNodeHttp), Layer.provideMerge(prismaEnvironment()));\n/**\n* The Prisma provider bundle: every resource provider, the Management API\n* client, and env-based credentials. Plug into a stack with\n* `{ providers: Prisma.providers() }`.\n*\n* The node transport is also the bundle's ambient `HttpClient`: upstream's\n* `Deployment` artifact upload needs node's explicit Content-Length (fetch\n* streams chunked), and upstream documents the ambient client as the\n* supported way to provide it. Invariant: no Composer provider may resolve\n* the ambient `HttpClient` — each carries its own client — or it would\n* silently get this override. Filed upstream: export the scoped upload\n* client, after which this becomes a private layer.\n*/\nconst providers = () => Layer.effect(Providers, Provider.collection([\n\tPrisma.Project,\n\tPrisma.Database,\n\tPrisma.Connection,\n\tPrisma.App,\n\tPrisma.Deployment,\n\tPrisma.EnvironmentVariable,\n\tPrisma.Bucket,\n\tPrisma.BucketAccessKey\n])).pipe(Layer.provide(upstreamPrismaProviders()), Layer.provideMerge(NodeHttpClient.layerNodeHttp), Layer.provideMerge(layer()), Layer.provideMerge(fromEnv()), Layer.orDie);\n//#endregion\nexport { ARTIFACT_CONTENT_TYPE, ContainerNotFoundError, ManagementClient, PrismaCredentials, Providers, RESERVED_DATABASE_URL_KEYS, ServiceKey, ServiceKeyProvider, appAfterEnvironment, claimDatabaseUrlKeys, collectPages, deleteBranch, deleteProject, drivePages, drivePagesAsync, fromEnv, managementApiBaseUrl, layer as managementClientLayer, mintServiceKey, packageComputeArtifact, providers, resolveContainer, resolveDefaultBranchId, serviceKeyProviderService };\n\n//# sourceMappingURL=index.mjs.map","import { createHash, createHmac, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nconst DEFAULT_CONTENT_TYPE$1 = \"application/octet-stream\";\nconst TMP_DIR_NAME = \".tmp\";\nconst META_DIR_NAME = \".meta\";\nconst RESERVED_SEGMENTS = /* @__PURE__ */ new Set([TMP_DIR_NAME, META_DIR_NAME]);\nconst BUCKET_NAME_RE = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;\nfunction etagOf$1(bytes) {\n\treturn `\"${createHash(\"sha256\").update(bytes).digest(\"hex\")}\"`;\n}\nfunction isErrnoException(err) {\n\treturn err instanceof Error && \"code\" in err;\n}\nfunction isEnoent(err) {\n\treturn isErrnoException(err) && err.code === \"ENOENT\";\n}\n/**\n* Splits a key into its `/` segments, rejecting anything that could escape\n* the bucket dir or collide with the reserved `.tmp`/`.meta` namespaces:\n* `..` segments, an empty segment (leading/trailing/doubled `/`, which also\n* catches a leading-slash \"absolute\" key), or a segment literally `.tmp` or\n* `.meta` at any depth.\n*/\nfunction keySegments(key) {\n\tconst segments = key.split(\"/\");\n\tfor (const segment of segments) if (segment === \"\" || segment === \".\" || segment === \"..\" || RESERVED_SEGMENTS.has(segment)) throw new Error(`invalid object key: \"${key}\"`);\n\treturn segments;\n}\n/** `<bucketDir>/<key's segments>`, double-checked to still resolve inside `bucketDir`. */\nfunction objectPath(bucketDir, key) {\n\tconst target = path.join(bucketDir, ...keySegments(key));\n\tconst resolvedRoot = path.resolve(bucketDir) + path.sep;\n\tif (!(path.resolve(target) + path.sep).startsWith(resolvedRoot)) throw new Error(`invalid object key: \"${key}\"`);\n\treturn target;\n}\n/** `<bucketDir>/.meta/<key's segments>.json` — mirrors `objectPath`'s tree under `.meta`. */\nfunction sidecarPath(bucketDir, key) {\n\tconst segments = keySegments(key);\n\tconst last = segments[segments.length - 1];\n\tconst dirs = segments.slice(0, -1);\n\treturn path.join(bucketDir, META_DIR_NAME, ...dirs, `${last}.json`);\n}\n/** Write-temp-then-rename: never leaves a reader observing a partial file. */\nasync function writeAtomic(finalPath, tmpRoot, bytes) {\n\tawait fs.mkdir(tmpRoot, { recursive: true });\n\tconst tmpPath = path.join(tmpRoot, randomUUID());\n\tawait fs.writeFile(tmpPath, bytes);\n\tawait fs.mkdir(path.dirname(finalPath), { recursive: true });\n\tawait fs.rename(tmpPath, finalPath);\n}\nfunction isSidecar(value) {\n\treturn typeof value === \"object\" && value !== null && \"contentType\" in value && typeof value.contentType === \"string\" && \"etag\" in value && typeof value.etag === \"string\";\n}\nasync function readSidecar(sidecar) {\n\tlet raw;\n\ttry {\n\t\traw = await fs.readFile(sidecar, \"utf8\");\n\t} catch (err) {\n\t\tif (isEnoent(err)) return null;\n\t\tthrow err;\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (isSidecar(parsed)) return parsed;\n\t} catch {}\n\treturn null;\n}\n/** Read the object's bytes plus its metadata — adopting a sidecar-less file (dropped in by a developer) by computing and lazily persisting one. `null` when the object is missing. */\nasync function readObject(bucketDir, key) {\n\tconst target = objectPath(bucketDir, key);\n\tlet bytes;\n\ttry {\n\t\tbytes = await fs.readFile(target);\n\t} catch (err) {\n\t\tif (isEnoent(err)) return null;\n\t\tthrow err;\n\t}\n\tconst existing = await readSidecar(sidecarPath(bucketDir, key));\n\tif (existing) return {\n\t\tbytes,\n\t\tmeta: existing\n\t};\n\tconst meta = {\n\t\tcontentType: DEFAULT_CONTENT_TYPE$1,\n\t\tetag: etagOf$1(bytes)\n\t};\n\tawait writeAtomic(sidecarPath(bucketDir, key), path.join(bucketDir, TMP_DIR_NAME), Buffer.from(JSON.stringify(meta)));\n\treturn {\n\t\tbytes,\n\t\tmeta\n\t};\n}\n/** Remove now-empty directories from `startDir` up to (never including) `root`. */\nasync function pruneEmptyDirs(root, startDir) {\n\tconst resolvedRoot = path.resolve(root);\n\tlet dir = path.resolve(startDir);\n\twhile (dir !== resolvedRoot && dir.startsWith(resolvedRoot + path.sep)) {\n\t\tlet entries;\n\t\ttry {\n\t\t\tentries = await fs.readdir(dir);\n\t\t} catch (err) {\n\t\t\tif (isEnoent(err)) {\n\t\t\t\tdir = path.dirname(dir);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t\tif (entries.length > 0) break;\n\t\ttry {\n\t\t\tawait fs.rmdir(dir);\n\t\t} catch (err) {\n\t\t\tif (!isEnoent(err)) throw err;\n\t\t}\n\t\tdir = path.dirname(dir);\n\t}\n}\n/** Recursively lists every object key under `dir`, skipping `.tmp`/`.meta` at any depth. */\nasync function walkKeys(dir) {\n\tconst keys = [];\n\tasync function walk(current, prefix) {\n\t\tlet entries;\n\t\ttry {\n\t\t\tentries = await fs.readdir(current, { withFileTypes: true });\n\t\t} catch (err) {\n\t\t\tif (isEnoent(err)) return;\n\t\t\tthrow err;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (RESERVED_SEGMENTS.has(entry.name)) continue;\n\t\t\tconst rel = prefix === \"\" ? entry.name : `${prefix}/${entry.name}`;\n\t\t\tif (entry.isDirectory()) await walk(path.join(current, entry.name), rel);\n\t\t\telse if (entry.isFile()) keys.push(rel);\n\t\t}\n\t}\n\tawait walk(dir, \"\");\n\treturn keys;\n}\n/**\n* A disk-backed `ObjectStore`: object bytes and a metadata sidecar under a\n* per-bucket directory the caller resolves. See the module doc for the\n* unknown-bucket / invalid-key failure shapes.\n*/\nfunction fsStore(resolveBucketDir) {\n\tfunction resolveDir(bucket) {\n\t\tif (!BUCKET_NAME_RE.test(bucket)) return void 0;\n\t\treturn resolveBucketDir(bucket);\n\t}\n\treturn {\n\t\tasync put(bucket, key, bytes, opts = {}) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) throw new Error(`no such bucket: \"${bucket}\"`);\n\t\t\tconst target = objectPath(dir, key);\n\t\t\tconst tmpRoot = path.join(dir, TMP_DIR_NAME);\n\t\t\tconst etag = etagOf$1(bytes);\n\t\t\tconst contentType = opts.contentType ?? DEFAULT_CONTENT_TYPE$1;\n\t\t\tawait writeAtomic(target, tmpRoot, bytes);\n\t\t\tawait writeAtomic(sidecarPath(dir, key), tmpRoot, Buffer.from(JSON.stringify({\n\t\t\t\tcontentType,\n\t\t\t\tetag\n\t\t\t})));\n\t\t\treturn { etag };\n\t\t},\n\t\tasync get(bucket, key, opts = {}) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return null;\n\t\t\tconst found = await readObject(dir, key);\n\t\t\tif (!found) return null;\n\t\t\tconst { bytes, meta } = found;\n\t\t\tconst size = bytes.byteLength;\n\t\t\tif (opts.range) {\n\t\t\t\tconst start = opts.range.start;\n\t\t\t\tconst end = opts.range.end === void 0 ? size - 1 : Math.min(opts.range.end, size - 1);\n\t\t\t\treturn {\n\t\t\t\t\tbytes: start > end ? /* @__PURE__ */ new Uint8Array(0) : bytes.subarray(start, end + 1),\n\t\t\t\t\tetag: meta.etag,\n\t\t\t\t\tcontentType: meta.contentType,\n\t\t\t\t\tsize\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tbytes: new Uint8Array(bytes),\n\t\t\t\tetag: meta.etag,\n\t\t\t\tcontentType: meta.contentType,\n\t\t\t\tsize\n\t\t\t};\n\t\t},\n\t\tasync head(bucket, key) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return null;\n\t\t\tconst found = await readObject(dir, key);\n\t\t\tif (!found) return null;\n\t\t\treturn {\n\t\t\t\tetag: found.meta.etag,\n\t\t\t\tsize: found.bytes.byteLength,\n\t\t\t\tcontentType: found.meta.contentType\n\t\t\t};\n\t\t},\n\t\tasync delete(bucket, key) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return;\n\t\t\tconst target = objectPath(dir, key);\n\t\t\tconst sidecar = sidecarPath(dir, key);\n\t\t\ttry {\n\t\t\t\tawait fs.unlink(target);\n\t\t\t} catch (err) {\n\t\t\t\tif (!isEnoent(err)) throw err;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait fs.unlink(sidecar);\n\t\t\t} catch (err) {\n\t\t\t\tif (!isEnoent(err)) throw err;\n\t\t\t}\n\t\t\tawait pruneEmptyDirs(dir, path.dirname(target));\n\t\t\tawait pruneEmptyDirs(path.join(dir, META_DIR_NAME), path.dirname(sidecar));\n\t\t},\n\t\tasync list(bucket, opts = {}) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return {\n\t\t\t\tkeys: [],\n\t\t\t\tisTruncated: false\n\t\t\t};\n\t\t\tconst prefix = opts.prefix ?? \"\";\n\t\t\tconst maxKeys = opts.maxKeys ?? 1e3;\n\t\t\tconst token = opts.continuationToken;\n\t\t\tconst matching = (await walkKeys(dir)).filter((key) => key.startsWith(prefix)).sort().filter((key) => token === void 0 ? true : key > token);\n\t\t\tconst page = matching.slice(0, maxKeys);\n\t\t\tconst isTruncated = matching.length > maxKeys;\n\t\t\tconst last = page.at(-1);\n\t\t\treturn {\n\t\t\t\tkeys: page,\n\t\t\t\tisTruncated,\n\t\t\t\t...isTruncated && last !== void 0 ? { nextContinuationToken: last } : {}\n\t\t\t};\n\t\t}\n\t};\n}\n//#endregion\n//#region src/sigv4.ts\n/**\n* AWS SigV4 verification for the S3 wire protocol (spec § 2 auth). The payload\n* hash comes from the client — `x-amz-content-sha256` (a real hash or\n* `UNSIGNED-PAYLOAD`) for header auth, `UNSIGNED-PAYLOAD` for presign — and is\n* never re-hashed; the verifier trusts what was signed, like a real S3 endpoint.\n* Runtime engine code (`node:crypto`); not re-exported from the authoring barrel.\n*\n* Also owns `mintKeyPair` (local-dev spec § 1) — the one key-pair generator\n* both the deploy-time `S3Credentials` resource and the local dev bucket\n* emulator's credential provisioning use.\n*/\nfunction randomBytes(n) {\n\treturn crypto.getRandomValues(new Uint8Array(n));\n}\nfunction toHexUpper(bytes) {\n\treturn Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\").toUpperCase();\n}\n/** A fresh SigV4 key pair: an AKIA-prefixed id and a 40-char base64 secret. */\nfunction mintKeyPair() {\n\treturn {\n\t\taccessKeyId: `AKIA${toHexUpper(randomBytes(8))}`,\n\t\tsecretAccessKey: btoa(String.fromCharCode(...randomBytes(30)))\n\t};\n}\nconst ALGORITHM = \"AWS4-HMAC-SHA256\";\nconst UNSIGNED_PAYLOAD = \"UNSIGNED-PAYLOAD\";\nfunction sha256Hex(data) {\n\treturn createHash(\"sha256\").update(data).digest(\"hex\");\n}\nfunction hmac(key, data) {\n\treturn createHmac(\"sha256\", key).update(data).digest();\n}\n/** AWS canonical URI encoding: every byte except the unreserved set is %XX. */\nfunction awsUriEncode(value) {\n\treturn encodeURIComponent(value).replace(/[!'()*]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%7E/g, \"~\");\n}\nfunction parseCredential(credential) {\n\tconst parts = credential.split(\"/\");\n\tif (parts.length !== 5 || parts[4] !== \"aws4_request\") return null;\n\tconst [accessKeyId, date, region, service] = parts;\n\tif (!accessKeyId || !date || !region || !service) return null;\n\treturn {\n\t\taccessKeyId,\n\t\tdate,\n\t\tregion,\n\t\tservice\n\t};\n}\nfunction signingKey(secret, scope) {\n\treturn hmac(hmac(hmac(hmac(`AWS4${secret}`, scope.date), scope.region), scope.service), \"aws4_request\");\n}\nfunction canonicalHeaders(url, req, signedHeaders) {\n\treturn signedHeaders.map((name) => {\n\t\treturn `${name}:${(name === \"host\" ? url.host : req.headers.get(name) ?? \"\").trim().replace(/\\s+/g, \" \")}\\n`;\n\t}).join(\"\");\n}\nfunction canonicalQuery(url, exclude) {\n\tconst entries = [];\n\tfor (const [key, value] of url.searchParams.entries()) {\n\t\tif (exclude !== void 0 && key === exclude) continue;\n\t\tentries.push([awsUriEncode(key), awsUriEncode(value)]);\n\t}\n\tconst cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;\n\tentries.sort(([ak, av], [bk, bv]) => cmp(ak, bk) || cmp(av, bv));\n\treturn entries.map(([k, v]) => `${k}=${v}`).join(\"&\");\n}\nfunction stringToSign(amzDate, scope, canonicalRequest) {\n\tconst scopeString = `${scope.date}/${scope.region}/${scope.service}/aws4_request`;\n\treturn [\n\t\tALGORITHM,\n\t\tamzDate,\n\t\tscopeString,\n\t\tsha256Hex(canonicalRequest)\n\t].join(\"\\n\");\n}\nfunction signatureMatches(expected, provided) {\n\tconst a = Buffer.from(expected, \"hex\");\n\tconst b = Buffer.from(provided, \"hex\");\n\treturn a.length === b.length && a.length > 0 && timingSafeEqual(a, b);\n}\n/** `YYYYMMDDTHHMMSSZ` → epoch ms, or null when malformed. */\nfunction parseAmzDate(amzDate) {\n\tconst match = /^(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})Z$/.exec(amzDate);\n\tif (!match) return null;\n\tconst [, y, mo, d, h, mi, s] = match;\n\treturn Date.UTC(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi), Number(s));\n}\nfunction parseAuthorizationHeader(header) {\n\tif (!header.startsWith(`${ALGORITHM} `)) return null;\n\tconst rest = header.slice(17);\n\tconst fields = /* @__PURE__ */ new Map();\n\tfor (const part of rest.split(\",\")) {\n\t\tconst eq = part.indexOf(\"=\");\n\t\tif (eq === -1) continue;\n\t\tfields.set(part.slice(0, eq).trim(), part.slice(eq + 1).trim());\n\t}\n\tconst credential = fields.get(\"Credential\");\n\tconst signedHeaders = fields.get(\"SignedHeaders\");\n\tconst signature = fields.get(\"Signature\");\n\tif (!credential || !signedHeaders || !signature) return null;\n\treturn {\n\t\tcredential,\n\t\tsignedHeaders: signedHeaders.split(\";\"),\n\t\tsignature\n\t};\n}\n/** The one signing core both auth forms share: check the access key, rebuild the canonical request, derive the key, compare in constant time. */\nfunction verifySignature(req, url, credentials, params) {\n\tif (params.scope.accessKeyId !== credentials.accessKeyId) return {\n\t\tok: false,\n\t\treason: \"unknown access key\"\n\t};\n\tconst canonicalRequest = [\n\t\treq.method,\n\t\turl.pathname,\n\t\tcanonicalQuery(url, params.excludeQuery),\n\t\tcanonicalHeaders(url, req, params.signedHeaders),\n\t\tparams.signedHeaders.join(\";\"),\n\t\tparams.payloadHash\n\t].join(\"\\n\");\n\treturn signatureMatches(hmac(signingKey(credentials.secretAccessKey, params.scope), stringToSign(params.amzDate, params.scope, canonicalRequest)).toString(\"hex\"), params.signature) ? { ok: true } : {\n\t\tok: false,\n\t\treason: \"signature mismatch\"\n\t};\n}\nfunction verifyHeader(req, url, credentials) {\n\tconst auth = parseAuthorizationHeader(req.headers.get(\"authorization\") ?? \"\");\n\tif (!auth) return {\n\t\tok: false,\n\t\treason: \"malformed Authorization header\"\n\t};\n\tconst scope = parseCredential(auth.credential);\n\tif (!scope) return {\n\t\tok: false,\n\t\treason: \"malformed credential scope\"\n\t};\n\tconst amzDate = req.headers.get(\"x-amz-date\");\n\tif (!amzDate) return {\n\t\tok: false,\n\t\treason: \"missing x-amz-date\"\n\t};\n\tconst payloadHash = req.headers.get(\"x-amz-content-sha256\");\n\tif (!payloadHash) return {\n\t\tok: false,\n\t\treason: \"missing x-amz-content-sha256\"\n\t};\n\treturn verifySignature(req, url, credentials, {\n\t\tscope,\n\t\tamzDate,\n\t\tsignedHeaders: auth.signedHeaders,\n\t\tpayloadHash,\n\t\tsignature: auth.signature\n\t});\n}\nfunction verifyPresigned(req, url, credentials, now) {\n\tconst q = url.searchParams;\n\tif (q.get(\"X-Amz-Algorithm\") !== ALGORITHM) return {\n\t\tok: false,\n\t\treason: \"unsupported presign algorithm\"\n\t};\n\tconst credentialRaw = q.get(\"X-Amz-Credential\");\n\tconst amzDate = q.get(\"X-Amz-Date\");\n\tconst expiresRaw = q.get(\"X-Amz-Expires\");\n\tconst signedHeadersRaw = q.get(\"X-Amz-SignedHeaders\");\n\tconst signature = q.get(\"X-Amz-Signature\");\n\tif (!credentialRaw || !amzDate || !expiresRaw || !signedHeadersRaw || !signature) return {\n\t\tok: false,\n\t\treason: \"incomplete presign parameters\"\n\t};\n\tconst scope = parseCredential(credentialRaw);\n\tif (!scope) return {\n\t\tok: false,\n\t\treason: \"malformed credential scope\"\n\t};\n\tconst signedAt = parseAmzDate(amzDate);\n\tconst expires = Number(expiresRaw);\n\tif (signedAt === null || !Number.isFinite(expires)) return {\n\t\tok: false,\n\t\treason: \"malformed presign date\"\n\t};\n\tif (now.getTime() > signedAt + expires * 1e3) return {\n\t\tok: false,\n\t\treason: \"presign expired\"\n\t};\n\treturn verifySignature(req, url, credentials, {\n\t\tscope,\n\t\tamzDate,\n\t\tsignedHeaders: signedHeadersRaw.split(\";\"),\n\t\tpayloadHash: UNSIGNED_PAYLOAD,\n\t\tsignature,\n\t\texcludeQuery: \"X-Amz-Signature\"\n\t});\n}\n/**\n* Verify a request's SigV4 signature against a single credential pair. Picks\n* the presigned form when `X-Amz-Signature` is present, otherwise the\n* `Authorization`-header form. `now` is injectable for deterministic\n* expiry tests.\n*/\nfunction verifyRequest(req, credentials, now = /* @__PURE__ */ new Date()) {\n\tconst url = new URL(req.url);\n\tif (url.searchParams.has(\"X-Amz-Signature\")) return verifyPresigned(req, url, credentials, now);\n\tif (req.headers.has(\"authorization\")) return verifyHeader(req, url, credentials);\n\treturn {\n\t\tok: false,\n\t\treason: \"unsigned request\"\n\t};\n}\n//#endregion\n//#region src/handler.ts\nconst DEFAULT_CONTENT_TYPE = \"application/octet-stream\";\n/** Path-style: `/{bucket}/{key…}`. Each segment is percent-decoded. */\nfunction parseTarget(url) {\n\tconst segments = url.pathname.split(\"/\").filter((s) => s.length > 0);\n\tif (segments.length === 0) return null;\n\tconst [bucket, ...keyParts] = segments;\n\treturn {\n\t\tbucket: decodeURIComponent(bucket ?? \"\"),\n\t\tkey: keyParts.map(decodeURIComponent).join(\"/\")\n\t};\n}\n/** `bytes=a-b` (inclusive) or `bytes=a-` (open-ended). Null when absent/malformed. */\nfunction parseRange(header) {\n\tif (!header) return null;\n\tconst match = /^bytes=(\\d+)-(\\d*)$/.exec(header.trim());\n\tif (!match) return null;\n\tconst start = Number(match[1]);\n\treturn match[2] ? {\n\t\tstart,\n\t\tend: Number(match[2])\n\t} : { start };\n}\nfunction xmlEscape(value) {\n\treturn value.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\").replace(/'/g, \"'\");\n}\nfunction listXml(bucket, prefix, maxKeys, result) {\n\tconst contents = result.keys.map((k) => `<Contents><Key>${xmlEscape(k)}</Key></Contents>`).join(\"\");\n\tconst next = result.isTruncated && result.nextContinuationToken !== void 0 ? `<NextContinuationToken>${xmlEscape(result.nextContinuationToken)}</NextContinuationToken>` : \"\";\n\treturn `<?xml version=\"1.0\" encoding=\"UTF-8\"?><ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>${xmlEscape(bucket)}</Name><Prefix>${xmlEscape(prefix)}</Prefix><KeyCount>${result.keys.length}</KeyCount><MaxKeys>${maxKeys}</MaxKeys><IsTruncated>${result.isTruncated}</IsTruncated>` + contents + next + \"</ListBucketResult>\";\n}\nconst DEFAULT_MAX_KEYS$1 = 1e3;\nasync function handleList(store, bucket, url) {\n\tconst prefix = url.searchParams.get(\"prefix\") ?? \"\";\n\tconst continuationToken = url.searchParams.get(\"continuation-token\");\n\tconst maxKeysRaw = url.searchParams.get(\"max-keys\");\n\tconst maxKeys = maxKeysRaw !== null && Number.isFinite(Number(maxKeysRaw)) ? Number(maxKeysRaw) : DEFAULT_MAX_KEYS$1;\n\tconst result = await store.list(bucket, {\n\t\tprefix,\n\t\tmaxKeys,\n\t\t...continuationToken !== null ? { continuationToken } : {}\n\t});\n\treturn new Response(listXml(bucket, prefix, maxKeys, result), {\n\t\tstatus: 200,\n\t\theaders: { \"content-type\": \"application/xml\" }\n\t});\n}\n/** aws-chunked / flexible-checksum PUTs frame the body as chunks + a trailer (signalled by `x-amz-content-sha256: STREAMING-…` or `content-encoding: aws-chunked`); the seed signature still verifies, so reject them (501) rather than store the raw framing as the object bytes. Decoding is out of scope. */\nfunction isStreamingPut(req) {\n\tconst contentSha = req.headers.get(\"x-amz-content-sha256\") ?? \"\";\n\tconst contentEncoding = req.headers.get(\"content-encoding\") ?? \"\";\n\treturn contentSha.startsWith(\"STREAMING-\") || contentEncoding.split(\",\").some((e) => e.trim() === \"aws-chunked\");\n}\nasync function handlePut(store, t, req) {\n\tif (isStreamingPut(req)) return new Response(\"aws-chunked / flexible checksums not supported; set requestChecksumCalculation: 'WHEN_REQUIRED'\", { status: 501 });\n\tconst body = new Uint8Array(await req.arrayBuffer());\n\tconst contentType = req.headers.get(\"content-type\") ?? DEFAULT_CONTENT_TYPE;\n\tconst { etag } = await store.put(t.bucket, t.key, body, { contentType });\n\treturn new Response(null, {\n\t\tstatus: 200,\n\t\theaders: { etag }\n\t});\n}\n/** The etag/content-type/content-length/accept-ranges headers GET and HEAD share — `contentLength` is the slice length for GET, the total object size for HEAD. */\nfunction metaHeaders(meta) {\n\treturn new Headers({\n\t\tetag: meta.etag,\n\t\t\"content-type\": meta.contentType,\n\t\t\"content-length\": String(meta.contentLength),\n\t\t\"accept-ranges\": \"bytes\"\n\t});\n}\nasync function handleGet(store, t, req) {\n\tconst range = parseRange(req.headers.get(\"range\"));\n\tconst object = await store.get(t.bucket, t.key, range ? { range } : void 0);\n\tif (!object) return new Response(null, { status: 404 });\n\tconst headers = metaHeaders({\n\t\tetag: object.etag,\n\t\tcontentType: object.contentType,\n\t\tcontentLength: object.bytes.byteLength\n\t});\n\tif (!range) return new Response(object.bytes, {\n\t\tstatus: 200,\n\t\theaders\n\t});\n\tif (range.start >= object.size && object.size > 0) return new Response(null, {\n\t\tstatus: 416,\n\t\theaders: { \"content-range\": `bytes */${object.size}` }\n\t});\n\tconst end = range.end === void 0 ? object.size - 1 : Math.min(range.end, object.size - 1);\n\theaders.set(\"content-range\", `bytes ${range.start}-${end}/${object.size}`);\n\treturn new Response(object.bytes, {\n\t\tstatus: 206,\n\t\theaders\n\t});\n}\nasync function handleHead(store, t) {\n\tconst meta = await store.head(t.bucket, t.key);\n\tif (!meta) return new Response(null, { status: 404 });\n\treturn new Response(null, {\n\t\tstatus: 200,\n\t\theaders: metaHeaders({\n\t\t\tetag: meta.etag,\n\t\t\tcontentType: meta.contentType,\n\t\t\tcontentLength: meta.size\n\t\t})\n\t});\n}\nasync function handleDelete(store, t) {\n\tawait store.delete(t.bucket, t.key);\n\treturn new Response(null, { status: 204 });\n}\nfunction createS3Handler(opts) {\n\tconst { store, credentials } = opts;\n\treturn async (req) => {\n\t\tif (!verifyRequest(req, credentials).ok) return new Response(null, { status: 403 });\n\t\tconst url = new URL(req.url);\n\t\tconst target = parseTarget(url);\n\t\tif (!target) return new Response(null, { status: 400 });\n\t\tif (req.method === \"GET\" && url.searchParams.get(\"list-type\") === \"2\" && target.key === \"\") return handleList(store, target.bucket, url);\n\t\tif (target.key === \"\") return new Response(null, { status: 400 });\n\t\tswitch (req.method) {\n\t\t\tcase \"PUT\": return handlePut(store, target, req);\n\t\t\tcase \"GET\": return handleGet(store, target, req);\n\t\t\tcase \"HEAD\": return handleHead(store, target);\n\t\t\tcase \"DELETE\": return handleDelete(store, target);\n\t\t\tdefault: return new Response(null, { status: 405 });\n\t\t}\n\t};\n}\n//#endregion\n//#region src/memory-store.ts\n/**\n* An in-memory `ObjectStore` for the protocol tests — the same contract the\n* Postgres store (D3) implements. Test-only; never wired into a deployed\n* service. Not re-exported from the authoring barrel.\n*/\nconst DEFAULT_MAX_KEYS = 1e3;\nfunction etagOf(bytes) {\n\treturn `\"${createHash(\"sha256\").update(bytes).digest(\"hex\")}\"`;\n}\nvar MemoryObjectStore = class {\n\tentries = /* @__PURE__ */ new Map();\n\tid(bucket, key) {\n\t\treturn `${bucket}\\x00${key}`;\n\t}\n\tasync put(bucket, key, bytes, opts = {}) {\n\t\tconst copy = bytes.slice();\n\t\tconst etag = etagOf(copy);\n\t\tthis.entries.set(this.id(bucket, key), {\n\t\t\tbytes: copy,\n\t\t\tetag,\n\t\t\tcontentType: opts.contentType ?? \"application/octet-stream\"\n\t\t});\n\t\treturn { etag };\n\t}\n\tasync get(bucket, key, opts = {}) {\n\t\tconst entry = this.entries.get(this.id(bucket, key));\n\t\tif (!entry) return null;\n\t\tconst size = entry.bytes.byteLength;\n\t\tif (opts.range) {\n\t\t\tconst start = opts.range.start;\n\t\t\tconst end = opts.range.end === void 0 ? size - 1 : Math.min(opts.range.end, size - 1);\n\t\t\treturn {\n\t\t\t\tbytes: start > end ? /* @__PURE__ */ new Uint8Array(0) : entry.bytes.slice(start, end + 1),\n\t\t\t\tetag: entry.etag,\n\t\t\t\tcontentType: entry.contentType,\n\t\t\t\tsize\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tbytes: entry.bytes.slice(),\n\t\t\tetag: entry.etag,\n\t\t\tcontentType: entry.contentType,\n\t\t\tsize\n\t\t};\n\t}\n\tasync head(bucket, key) {\n\t\tconst entry = this.entries.get(this.id(bucket, key));\n\t\tif (!entry) return null;\n\t\treturn {\n\t\t\tetag: entry.etag,\n\t\t\tsize: entry.bytes.byteLength,\n\t\t\tcontentType: entry.contentType\n\t\t};\n\t}\n\tasync delete(bucket, key) {\n\t\tthis.entries.delete(this.id(bucket, key));\n\t}\n\tasync list(bucket, opts = {}) {\n\t\tconst prefix = opts.prefix ?? \"\";\n\t\tconst maxKeys = opts.maxKeys ?? DEFAULT_MAX_KEYS;\n\t\tconst token = opts.continuationToken;\n\t\tconst prefixHit = `${bucket}\\x00${prefix}`;\n\t\tconst matching = [...this.entries.keys()].filter((id) => id.startsWith(prefixHit)).map((id) => id.slice(bucket.length + 1)).sort().filter((key) => token === void 0 ? true : key > token);\n\t\tconst page = matching.slice(0, maxKeys);\n\t\tconst isTruncated = matching.length > maxKeys;\n\t\tconst last = page.at(-1);\n\t\treturn {\n\t\t\tkeys: page,\n\t\t\tisTruncated,\n\t\t\t...isTruncated && last !== void 0 ? { nextContinuationToken: last } : {}\n\t\t};\n\t}\n};\n//#endregion\nexport { MemoryObjectStore, createS3Handler, fsStore, mintKeyPair, verifyRequest };\n\n//# sourceMappingURL=index.mjs.map","import { a as isEnvParamSource, c as paramName, n as secretName, o as isGeneratedParamSource } from \"./secret-Dgyg1WyG.mjs\";\nimport { i as withConnectionRetry, n as normalizeSslMode } from \"./pg-connection-3qou2HW9.mjs\";\nimport { inputManifest, isSecretSource, paramManifest } from \"@internal/core\";\nimport { blindCast } from \"@internal/foundation/casts\";\nimport { ManagementClient, deleteBranch, deleteProject, fromEnv, managementClientLayer, resolveContainer } from \"@internal/lowering\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport { Resource } from \"alchemy\";\nimport * as Provider from \"alchemy/Provider\";\nimport { loadConfig } from \"@prisma/orm-toolchain/config-loader\";\nimport { resolve } from \"pathe\";\nimport { createPostgresControlClient } from \"@prisma/orm-postgres/control\";\nimport { readRef } from \"@prisma/orm-toolchain/migration-tools/refs\";\nimport { APP_SPACE_ID, readContractSpaceHeadRef, spaceMigrationDirectory, spaceRefsDirectory } from \"@prisma/orm-toolchain/migration-tools/spaces\";\nimport pg from \"pg\";\nimport { mintKeyPair } from \"@internal/s3-protocol\";\n//#region src/container.ts\nconst PRISMA_CLOUD_EXTENSION_ID = \"@prisma/composer-prisma-cloud\";\n/** Accepts exactly what Alchemy's own `--stage` validation accepts (pinned 2.0.0-beta.59, `Cli/commands/_shared.ts`), rewritten without overlapping quantifiers so it cannot backtrack catastrophically. Asserted before a Branch id is exposed as a stage. */\nconst ALCHEMY_STAGE_PATTERN = /^[a-z0-9][-_a-z0-9]*$/i;\nfunction invalidAlchemyStageError(branchId) {\n\treturn /* @__PURE__ */ new Error(`${PRISMA_CLOUD_EXTENSION_ID}: the resolved Branch id \"${branchId}\" does not match Alchemy's stage pattern ^[a-z0-9][-_a-z0-9]*\\$ (case-insensitive) — it cannot scope the deploy state. The platform should never return such an id; contact support.`);\n}\nvar PrismaCloudContainer = class {\n\tinput;\n\tprojectId;\n\tbranchId;\n\tdefaultBranchId;\n\tbranchless;\n\t/** The deterministic Alchemy stage (ContainerInstance SPI): the stage Branch's id, or the default Branch's id for the default stage. Absent only for the dev container, which resolves no Branch. */\n\talchemyStage;\n\tconstructor(input, projectId, branchId, defaultBranchId, branchless = false) {\n\t\tthis.input = input;\n\t\tthis.projectId = projectId;\n\t\tthis.branchId = branchId;\n\t\tthis.defaultBranchId = defaultBranchId;\n\t\tthis.branchless = branchless;\n\t\tconst stageBranchId = branchId ?? defaultBranchId;\n\t\tif (stageBranchId !== void 0 && !ALCHEMY_STAGE_PATTERN.test(stageBranchId)) throw invalidAlchemyStageError(stageBranchId);\n\t\tthis.alchemyStage = stageBranchId;\n\t}\n\tserialize() {\n\t\treturn JSON.stringify({\n\t\t\tinput: this.input,\n\t\t\tprojectId: this.projectId,\n\t\t\t...this.branchId !== void 0 ? { branchId: this.branchId } : {},\n\t\t\t...this.defaultBranchId !== void 0 ? { defaultBranchId: this.defaultBranchId } : {},\n\t\t\t...this.branchless ? { branchless: true } : {}\n\t\t});\n\t}\n};\n/** `instanceof` — parent-side instances and child-side deserialized instances are both constructed by this module. */\nfunction isPrismaCloudContainer(value) {\n\treturn value instanceof PrismaCloudContainer;\n}\n/** Narrow-or-throw for hook inputs. */\nfunction prismaCloudContainerOf(value) {\n\tif (!isPrismaCloudContainer(value)) throw new Error(\"the Prisma Cloud container was not resolved — the extension's container descriptor did not run.\");\n\treturn value;\n}\nfunction isRecord(value) {\n\treturn typeof value === \"object\" && value !== null;\n}\nfunction invalidPayloadError(reason) {\n\treturn /* @__PURE__ */ new Error(`${PRISMA_CLOUD_EXTENSION_ID}: invalid container transport payload — ${reason}.`);\n}\n/**\n* Reconstructs a `PrismaCloudContainer` from `serialize()`'s JSON output —\n* real narrowing, no casts. Exported so `dev/container.ts`'s\n* `devContainerDescriptor` can reuse it verbatim (local-dev spec § 5) — the\n* dev and deploy container descriptors deserialize the identical wire shape.\n*/\nfunction deserialize(serialized) {\n\tlet parsed;\n\ttry {\n\t\tparsed = JSON.parse(serialized);\n\t} catch (error) {\n\t\tthrow invalidPayloadError(`not valid JSON (${error instanceof Error ? error.message : String(error)})`);\n\t}\n\tif (!isRecord(parsed)) throw invalidPayloadError(\"not an object\");\n\tconst input = parsed[\"input\"];\n\tif (!isRecord(input)) throw invalidPayloadError(\"\\\"input\\\" is not an object\");\n\tconst appName = input[\"appName\"];\n\tif (typeof appName !== \"string\") throw invalidPayloadError(\"\\\"input.appName\\\" is not a string\");\n\tconst stage = input[\"stage\"];\n\tif (stage !== void 0 && typeof stage !== \"string\") throw invalidPayloadError(\"\\\"input.stage\\\" is not a string or absent\");\n\tconst projectId = parsed[\"projectId\"];\n\tif (typeof projectId !== \"string\") throw invalidPayloadError(\"\\\"projectId\\\" is not a string\");\n\tconst branchId = parsed[\"branchId\"];\n\tif (branchId !== void 0 && typeof branchId !== \"string\") throw invalidPayloadError(\"\\\"branchId\\\" is not a string or absent\");\n\tconst defaultBranchId = parsed[\"defaultBranchId\"];\n\tif (defaultBranchId !== void 0 && typeof defaultBranchId !== \"string\") throw invalidPayloadError(\"\\\"defaultBranchId\\\" is not a string or absent\");\n\tconst branchless = parsed[\"branchless\"];\n\tif (branchless !== void 0 && typeof branchless !== \"boolean\") throw invalidPayloadError(\"\\\"branchless\\\" is not a boolean or absent\");\n\treturn new PrismaCloudContainer({\n\t\tappName,\n\t\tstage\n\t}, projectId, branchId, defaultBranchId, branchless ?? false);\n}\nconst workspaceRequiredError = () => /* @__PURE__ */ new Error(\"environment variable PRISMA_WORKSPACE_ID is required.\");\nconst tokenRequiredError = () => /* @__PURE__ */ new Error(\"environment variable PRISMA_SERVICE_TOKEN is required.\");\n/**\n* The caller's workspace id, or — only when the caller passed no credentials\n* at all — the env protocol, which is what the alchemy child process and\n* existing programmatic hosts have set.\n*/\nfunction requireWorkspaceId(credentials) {\n\tconst workspaceId = credentials === void 0 ? process.env[\"PRISMA_WORKSPACE_ID\"] : credentials.workspaceId;\n\tif (workspaceId === void 0 || workspaceId.length === 0) throw workspaceRequiredError();\n\treturn workspaceId;\n}\nfunction requireTokenUnlessInjected(client) {\n\tif (client === void 0 && (process.env[\"PRISMA_SERVICE_TOKEN\"] ?? \"\").length === 0) throw tokenRequiredError();\n}\nfunction clientFor(credentials, deps) {\n\treturn credentials?.client ?? deps?.client;\n}\n/** Runs against the injected client when there is one, and against an env-built one otherwise. */\nfunction runWithClient(program, client) {\n\treturn Effect.runPromise(client !== void 0 ? program.pipe(Effect.provideService(ManagementClient, client)) : program.pipe(Effect.provide(managementClientLayer().pipe(Layer.provide(fromEnv())))));\n}\nasync function ensureContainer(input, credentials, deps) {\n\tconst workspaceId = requireWorkspaceId(credentials);\n\tconst client = clientFor(credentials, deps);\n\trequireTokenUnlessInjected(client);\n\tconst outcome = await runWithClient(resolveContainer({\n\t\tworkspaceId,\n\t\tappName: input.appName,\n\t\t...input.stage !== void 0 ? { stage: input.stage } : {},\n\t\tensure: true\n\t}).pipe(Effect.map((c) => ({\n\t\tok: true,\n\t\tcontainer: c\n\t})), Effect.catchTag(\"PrismaApiError\", (e) => Effect.succeed({\n\t\tok: false,\n\t\tmessage: `Prisma Management API error resolving containers: ${e.message}.`\n\t}))), client);\n\tif (!outcome.ok) throw new Error(outcome.message);\n\treturn new PrismaCloudContainer(input, outcome.container.projectId, outcome.container.branchId, outcome.container.defaultBranchId);\n}\nasync function locateContainer(input, credentials, deps) {\n\tconst workspaceId = requireWorkspaceId(credentials);\n\tconst client = clientFor(credentials, deps);\n\trequireTokenUnlessInjected(client);\n\tconst outcome = await runWithClient(resolveContainer({\n\t\tworkspaceId,\n\t\tappName: input.appName,\n\t\t...input.stage !== void 0 ? { stage: input.stage } : {},\n\t\tensure: false\n\t}).pipe(Effect.map((c) => ({\n\t\tok: true,\n\t\tcontainer: c\n\t})), Effect.catchTag(\"ContainerNotFoundError\", () => Effect.succeed({ ok: false })), Effect.catchTag(\"PrismaApiError\", (e) => Effect.fail(/* @__PURE__ */ new Error(`Prisma Management API error resolving containers: ${e.message}.`)))), client);\n\tif (!outcome.ok) return void 0;\n\treturn new PrismaCloudContainer(input, outcome.container.projectId, outcome.container.branchId, outcome.container.defaultBranchId);\n}\n/**\n* Soft-deletes a named stage's Branch after a successful `alchemy destroy`\n* has removed its members — the Management API refuses to delete a Branch\n* that still has live members.\n*/\nasync function removeStageBranch(branchId, credentials, deps) {\n\tconst client = clientFor(credentials, deps);\n\trequireTokenUnlessInjected(client);\n\tconst outcome = await runWithClient(deleteBranch(branchId).pipe(Effect.map(() => ({ ok: true })), Effect.catchTag(\"PrismaApiError\", (e) => Effect.succeed({\n\t\tok: false,\n\t\tmessage: `Failed to delete the stage Branch: ${e.message}.`\n\t}))), client);\n\tif (!outcome.ok) throw new Error(outcome.message);\n}\n/**\n* Best-effort cleanup after a successful `--production` destroy: removes\n* the app's Project so hand-run stacks don't accumulate as empty Projects\n* (they eventually hit the workspace's plan limit). Unlike `removeStageBranch`,\n* this never throws: the destroy itself already succeeded, and the API's own\n* 400 (\"still has dependencies\") is the only check that matters — failing\n* the command over a cleanup step would be worse than leaving a Project shell.\n*/\nasync function removeAppProject(projectId, credentials, deps) {\n\tconst client = clientFor(credentials, deps);\n\tif (client === void 0 && (process.env[\"PRISMA_SERVICE_TOKEN\"] ?? \"\").length === 0) {\n\t\tconsole.warn(`Skipped removing the Project (${projectId}): PRISMA_SERVICE_TOKEN is not set.`);\n\t\treturn;\n\t}\n\tconst outcome = await runWithClient(deleteProject(projectId).pipe(Effect.map(() => ({ ok: true })), Effect.catchTag(\"PrismaApiError\", (e) => Effect.succeed({\n\t\tok: false,\n\t\terror: e\n\t}))), client);\n\tif (outcome.ok) {\n\t\tconsole.log(`Removed the Project (${projectId}) — nothing was left in it.`);\n\t\treturn;\n\t}\n\tif (outcome.error.status === 400) {\n\t\tconsole.log(`Kept the Project (${projectId}) — it still has another stage's resources.`);\n\t\treturn;\n\t}\n\tconsole.warn(`Could not remove the Project (${projectId}) after destroy: ${outcome.error.message}.`);\n}\nfunction containerDescriptor(deps) {\n\treturn {\n\t\tensure: (input, credentials) => ensureContainer(input, credentials, deps),\n\t\tlocate: (input, credentials) => locateContainer(input, credentials, deps),\n\t\tremove: (instance, credentials) => instance.input.stage !== void 0 ? removeStageBranch(instance.branchId ?? missingBranchId(instance), credentials, deps) : removeAppProject(instance.projectId, credentials, deps),\n\t\tdeserialize\n\t};\n}\n/** Defensive: a named-stage container always resolves a Branch together with its stage — `ensure`/`locate`/`deserialize` never produce one without the other. */\nfunction missingBranchId(instance) {\n\tthrow new Error(`${PRISMA_CLOUD_EXTENSION_ID}: a named-stage (\"${instance.input.stage}\") container instance is missing its branchId — this is a bug in ensure/locate/deserialize.`);\n}\n//#endregion\n//#region src/generated-param-resource.ts\n/**\n* The `GeneratedParam` Alchemy resource — generates a random value ONCE at\n* create and keeps it STABLE across deploys, so an unchanged service no-ops on\n* redeploy. The value is `bytes` random bytes produced with the Web Crypto\n* global (`crypto.getRandomValues` — no `node:` import, matching this package's\n* runtime-coupling invariant), base64-encoded, and persisted in Alchemy state;\n* on every later apply the provider returns the persisted attributes\n* (`reconcile`'s `output`) unchanged — the same way `S3Credentials` keeps its\n* pair stable. Changing `bytes` on an existing resource KEEPS the old value\n* (reconcile short-circuits on the persisted output); rotation is\n* destroy/recreate.\n*\n* One resource per `generatedParam()`-bound input leaf, provisioned by the\n* compute descriptor's serialize step; the resource id derives from the input\n* document row key and the leaf path, so the value is stable per service+leaf.\n*\n* Deploy-time only: imports `alchemy`. Imported by `control/extension.ts` and\n* tests, never by `index.ts` / the authoring entry.\n*/\n/** The `GeneratedParam` resource constructor — `yield* GeneratedParam(id, { bytes })` in the lowering. */\nconst GeneratedParam = Resource(\"PrismaCloud.GeneratedParam\");\n/** A fresh generated value: `bytes` random bytes, base64. */\nfunction generateValue(bytes) {\n\tconst random = crypto.getRandomValues(new Uint8Array(bytes));\n\treturn { value: btoa(String.fromCharCode(...random)) };\n}\n/**\n* The `GeneratedParam` provider service. `reconcile` runs for create and\n* update; it returns the persisted `output` when present (a redeploy reuses the\n* stored value — the no-op property, and the reason a `bytes` change does not\n* re-generate) and generates a fresh value only on first create. Nothing to\n* enumerate (`list` → `[]`) or tear down (`delete` → no-op; the value lives\n* only in state). Exported so tests can drive it directly.\n*/\nconst generatedParamProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ news, output }) => Effect.sync(() => output ?? generateValue(news.bytes)),\n\tdelete: () => Effect.void\n};\n/** The `GeneratedParam` provider layer — merged into the extension descriptor's `providers()`. */\nconst GeneratedParamProvider = () => Provider.effect(GeneratedParam, Effect.succeed(generatedParamProviderService));\n//#endregion\n//#region src/orm-config.ts\n/**\n* Resolves a `postgres` resource's `prisma.config.ts` path to the\n* project facts the deploy needs (ADR-0022, slice 2): the on-disk migrations\n* directory the control client's `migrate` reads, and the declared\n* extension packs. Deploy-time only: loads PN's config (via c12) and applies\n* PN's own convention — `migrations.dir`, or the default `migrations/`,\n* relative to the config file's directory (mirrors the CLI's\n* `resolveMigrationPaths`). Imported by `control.ts` + tests, never by\n* `index.ts` / the `./orm` authoring entry.\n*\n* `pathe` (not `node:path`) does the path work so the shipped source carries no\n* `node:` import — the same discipline `control.ts` already follows by\n* delegating fs/tar to `@internal/lowering` (invariant 5).\n*/\n/** Loads the config at `configPath` and resolves the facts the deploy consumes. */\nasync function resolveOrmConfig(configPath) {\n\tconst loaded = await loadConfig(configPath);\n\tif (!loaded.ok) throw loaded.failure;\n\tconst config = loaded.value.config;\n\treturn {\n\t\tmigrationsDir: resolve(configPath, \"..\", config.migrations?.dir ?? \"migrations\"),\n\t\textensionPacks: blindCast(config.extensions ?? [])\n\t};\n}\n/**\n* The pack-head identity entries the `OrmMigration` resource folds into its\n* diff key: `\"<packId>:<headRefHash>\"` — each pack's contract-space head ref,\n* identified by its storage hash — sorted by pack id, so a pack upgrade (or a\n* pack added/removed) produces a distinct deploy step. A pack without a\n* `contractSpace` contributes `\"-\"` for its head — it declares no migratable\n* space, but its presence still belongs in the key.\n*/\nfunction packHeadRefHashes(packs) {\n\treturn packs.map((pack) => `${pack.id}:${pack.contractSpace?.headRef.hash ?? \"-\"}`).sort();\n}\n//#endregion\n//#region src/orm-migrate.ts\n/**\n* The Prisma ORM migration step of the deploy lowering (ADR-0022, slice 2) —\n* the safety-critical decision that brings a live database to a target REF\n* using ONLY Prisma ORM's authored migrations.\n*\n* Deploy-time only: this module imports `@prisma/orm-postgres/control` (which\n* transitively pulls PN's control/migration machinery + `pg`). It is imported\n* by the deploy descriptors and this package's tests, NEVER by `index.ts` / the\n* `./orm` authoring entry — so it never lands in an app runtime bundle\n* (the index-isolation invariant holds).\n*\n* The target is a ref `{ hash, invariants }` — not a bare `storageHash`. A\n* ref's `invariants` are named postconditions established by `data`-class\n* migration steps (e.g. a backfill), recorded monotonically on the live\n* marker. Keying on the hash alone would make a pure data-invariant change an\n* A→A self-edge the deploy wrongly skips. The decision, given the live marker\n* and the target ref (see {@link decideMigrationAction}):\n* - marker at ref.hash AND ref.invariants ⊆ marker.invariants → no-op\n* - otherwise → `migrate`\n*\n* Replay-only (ADR-0022 as revised): the pipeline replays what was authored,\n* it never authors. A fresh database (no marker) is not special — its start\n* point is empty and `migrate` walks the AUTHORED graph from empty to the\n* target, so the first deploy applies the committed baseline like any other\n* migration. No synthesis of any kind runs at deploy: never `dbInit` (schema\n* synthesized from the contract) and never `dbUpdate` (synthesized\n* diff-and-apply). A missing authored path (`MIGRATION_PATH_NOT_FOUND`) is a\n* structured refusal whose message names the two exits — `prisma db update`\n* for local iteration, `prisma contract emit && prisma migration plan` to\n* author the path for shipping. A runner failure fails the deploy as a typed\n* `OrmMigrationError` (not swallowed). PN applies each migration in its own\n* transaction, so a failed apply is atomic and resume-safe — the marker and\n* schema are left as the last committed step.\n*/\n/** A deploy-failing migration error — surfaced, never swallowed. */\nvar OrmMigrationError = class extends Error {\n\tcode;\n\t/** PN's structured explanation, when present. */\n\twhy;\n\tconstructor(code, summary, why) {\n\t\tsuper(`Prisma ORM migrate (${code}): ${summary}`);\n\t\tthis.name = \"OrmMigrationError\";\n\t\tthis.code = code;\n\t\tthis.why = why;\n\t}\n};\n/**\n* The replay-only refusal for a missing authored path. The pipeline never\n* authors schema, so the only fix is to bring one of the two sides along:\n* update the database directly (local iteration) or author and commit the\n* missing migrations (shipping). The same message serves a deploy against a\n* cloud database and a `dev` run against the local emulator database.\n*/\nfunction noPathRefusal(summary, markerHashBefore, aggregate) {\n\treturn `${aggregate ? \"The committed migrations/ directory has no authored path to the target in every declared migration space\" : markerHashBefore === null ? \"The database carries no schema marker and the committed migrations/ directory has no authored path from empty to the target\" : `The committed migrations/ directory has no authored path from the database's current schema (${markerHashBefore}) to the target`} — the deploy pipeline only replays authored migrations, it never creates schema itself. Iterating locally? Bring the database along with \\`prisma db update\\`. Shipping? Author the migration path — \\`prisma contract emit && prisma migration plan --name <slug>\\` (baseline first if the migration graph is empty) — and commit migrations/. (${summary})`;\n}\n/**\n* The target `storageHash` a contract heads to — `contractJson.storage.storageHash`.\n* Read defensively: `contractJson` crosses the boundary as `unknown`.\n*/\nfunction targetStorageHash(contractJson) {\n\tif (typeof contractJson === \"object\" && contractJson !== null && \"storage\" in contractJson) {\n\t\tconst storage = contractJson.storage;\n\t\tif (typeof storage === \"object\" && storage !== null && \"storageHash\" in storage) {\n\t\t\tconst hash = storage.storageHash;\n\t\t\tif (typeof hash === \"string\" && hash.length > 0) return hash;\n\t\t}\n\t}\n\tthrow new OrmMigrationError(\"CONTRACT_INVALID\", \"the contract has no storage.storageHash — cannot determine the target schema version\");\n}\n/**\n* Resolve the deploy's target ref from the migrations dir.\n*\n* - `targetRef` named: read `migrations/app/refs/<name>.json` — fail loudly\n* (`TARGET_REF_NOT_FOUND`) when the ref doesn't exist or can't be parsed.\n* - Default: the app space's head. PN synthesizes the app head from the\n* emitted contract — `{ hash: contract.storage.storageHash, invariants: [] }`\n* (`contract emit` writes no app-space `refs/head.json` today; extension\n* spaces have one on disk). When a future PN version does emit one, the\n* on-disk `head.json` wins — read via `readContractSpaceHeadRef`, exactly\n* the loader PN's own migrate uses.\n*/\nasync function resolveTargetRef(migrationsDir, contractJson, targetRef) {\n\tif (targetRef !== void 0) {\n\t\tconst refsDir = spaceRefsDirectory(spaceMigrationDirectory(migrationsDir, APP_SPACE_ID));\n\t\ttry {\n\t\t\tconst ref = await readRef(refsDir, targetRef);\n\t\t\treturn {\n\t\t\t\thash: ref.hash,\n\t\t\t\tinvariants: ref.invariants\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new OrmMigrationError(\"TARGET_REF_NOT_FOUND\", `targetRef \"${targetRef}\" could not be read from ${refsDir}`, error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\tconst head = await readContractSpaceHeadRef(migrationsDir, APP_SPACE_ID);\n\tif (head !== null) return {\n\t\thash: head.hash,\n\t\tinvariants: head.invariants\n\t};\n\treturn {\n\t\thash: targetStorageHash(contractJson),\n\t\tinvariants: []\n\t};\n}\n/**\n* The pure migration decision, mirroring PN's own verifier: the database is\n* AT the target when the marker's hash equals the ref's hash AND every ref\n* invariant is on the marker (marker invariants are monotonic). Anything\n* else — different hash, missing invariant (the A→A data-only self-edge),\n* or a fresh DB (whose start point is empty) — walks the authored graph via\n* `migrate`. The pipeline never synthesizes.\n*/\nfunction decideMigrationAction(marker, ref) {\n\tconst markerInvariants = new Set(marker?.invariants ?? []);\n\tconst missing = ref.invariants.filter((id) => !markerInvariants.has(id));\n\tif (marker !== null && marker.storageHash === ref.hash && missing.length === 0) return \"noop\";\n\treturn \"migrate\";\n}\n/**\n* Bring the database at `url` to the target ref via PN's authored migrations.\n* Reads the live marker, decides no-op / migrate\n* ({@link decideMigrationAction}), applies, and throws a typed\n* {@link OrmMigrationError} on a no-path or runner failure. `migrationsDir` is\n* the on-disk migrations root and `ref` the resolved target\n* ({@link resolveTargetRef} — both resolved by the lowering, which also keys\n* the OrmMigration resource on them). `refName` (the resource's `targetRef`,\n* when set) is threaded into `migrate` so PN targets the named ref's hash and\n* plans an invariant-bearing path.\n*/\nasync function applyOrmMigration(opts) {\n\tconst connection = normalizeSslMode(opts.url);\n\treturn withConnectionRetry(() => runMigration(connection, opts.contractJson, opts.migrationsDir, opts.ref, opts.refName, opts.extensionPacks ?? []), { shouldRetry: (error) => !(error instanceof OrmMigrationError) });\n}\nasync function runMigration(connection, contractJson, migrationsDir, ref, refName, extensionPacks) {\n\tconst client = createPostgresControlClient({\n\t\tconnection,\n\t\textensions: extensionPacks\n\t});\n\tawait client.connect();\n\ttry {\n\t\tconst marker = await client.readMarker();\n\t\tconst markerHashBefore = marker?.storageHash ?? null;\n\t\tlet action = decideMigrationAction(marker, ref);\n\t\tif (action === \"noop\") {\n\t\t\tif (extensionPacks.length === 0) return {\n\t\t\t\taction,\n\t\t\t\ttargetHash: ref.hash,\n\t\t\t\tmarkerHashBefore\n\t\t\t};\n\t\t\taction = \"migrate\";\n\t\t}\n\t\tconst result = await client.migrate({\n\t\t\tcontract: contractJson,\n\t\t\tmigrationsDir,\n\t\t\t...refName !== void 0 ? {\n\t\t\t\trefHash: ref.hash,\n\t\t\t\trefInvariants: ref.invariants,\n\t\t\t\trefName\n\t\t\t} : {}\n\t\t});\n\t\tif (!result.ok) {\n\t\t\tif (result.failure.code === \"MIGRATION_PATH_NOT_FOUND\") throw new OrmMigrationError(\"MIGRATION_PATH_NOT_FOUND\", noPathRefusal(result.failure.summary, markerHashBefore, extensionPacks.length > 0), result.failure.why);\n\t\t\tthrow new OrmMigrationError(\"RUNNER_FAILED\", result.failure.summary, result.failure.why);\n\t\t}\n\t\treturn {\n\t\t\taction,\n\t\t\ttargetHash: ref.hash,\n\t\t\tmarkerHashBefore\n\t\t};\n\t} finally {\n\t\tawait client.close();\n\t}\n}\n//#endregion\n//#region src/orm-migration-resource.ts\n/**\n* The `OrmMigration` Alchemy resource (ADR-0022) — the migration\n* step modeled as a tracked resource so it participates in deploy state: keyed\n* on the target REF identity (`targetHash` + sorted `invariants`), an\n* unchanged redeploy is an Alchemy-level no-op (on top of the marker read),\n* and a contract change — or a DATA-ONLY change that adds a ref invariant at\n* the same hash — re-runs the migration.\n*\n* Its provider's `reconcile` receives the RESOLVED props at apply-time — in\n* particular the concrete DB `url` (a lazy `Output` until the Connection\n* provisions) — and delegates to the proven `applyOrmMigration` decision. The\n* provider is a standalone `Provider<OrmMigration>` layer; the extension\n* descriptor merges it into its `providers()` (`Layer.merge(Prisma.providers(),\n* OrmMigrationProvider())`), and Alchemy resolves it at apply via a direct\n* provider-tag lookup (`tryFindProviderByType`) — no change to `@internal/lowering`.\n*\n* Deploy-time only: imports `@prisma/orm-postgres/control` (via the helper) +\n* `alchemy`. Imported by `control.ts` and tests, never by `index.ts` / the\n* `./orm` authoring entry — index isolation holds.\n*/\n/** The `OrmMigration` resource constructor — `yield* OrmMigration(id, props)` in the lowering. */\nconst OrmMigration = Resource(\"PrismaOrm.Migration\");\n/**\n* The `OrmMigration` provider service. `reconcile` runs for both create and\n* update (Alchemy's unified lifecycle); `applyOrmMigration` is idempotent via\n* the live marker read, so it is safe to run for either — the marker decides\n* no-op / migrate. A migration has nothing to enumerate (`list` → `[]`)\n* and nothing to tear down on its own (`delete` → no-op; the DB's own deletion\n* handles teardown). Exported so tests can drive `reconcile` directly, without\n* building an Effect layer.\n*/\nconst ormMigrationProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ news }) => Effect.tryPromise({\n\t\ttry: async () => {\n\t\t\tconst extensionPacks = news.packHeadRefHashes.length > 0 ? (await resolveOrmConfig(news.configPath)).extensionPacks : [];\n\t\t\treturn applyOrmMigration({\n\t\t\t\turl: news.url,\n\t\t\t\tcontractJson: news.contractJson,\n\t\t\t\tmigrationsDir: news.migrationsDir,\n\t\t\t\tref: {\n\t\t\t\t\thash: news.targetHash,\n\t\t\t\t\tinvariants: news.invariants\n\t\t\t\t},\n\t\t\t\textensionPacks,\n\t\t\t\t...news.refName !== void 0 ? { refName: news.refName } : {}\n\t\t\t});\n\t\t},\n\t\tcatch: (error) => error\n\t}).pipe(Effect.map((outcome) => ({\n\t\tstorageHash: outcome.targetHash,\n\t\tinvariants: news.invariants\n\t}))),\n\tdelete: () => Effect.void\n};\n/** The `OrmMigration` provider layer — merged into the extension descriptor's `providers()`. */\nconst OrmMigrationProvider = () => Provider.effect(OrmMigration, Effect.succeed(ormMigrationProviderService));\n//#endregion\n//#region src/pg-warm-resource.ts\n/**\n* The `PgWarm` Alchemy resource (slice 3, FT-5226) — warm a freshly-provisioned\n* Prisma Postgres database at apply-time so it is ready by deploy-end, and the\n* first real connection (a service's runtime client, or the migration) doesn't\n* eat the cold-start reject.\n*\n* The DB `url` is a lazy `Output` at lowering time, so warming must be an\n* apply-time tracked resource (same pattern as `OrmMigration`): its `reconcile`\n* receives the RESOLVED url and connects with `withConnectionRetry` + `select 1`,\n* riding out the cold-start. Shared by BOTH the bare-`postgres` and the\n* `postgres` lowerings; keyed on the connection `url`, so an unchanged\n* redeploy is a no-op (warming is idempotent anyway).\n*\n* Deploy-time only: imports `pg` directly + `alchemy`. Imported by `control.ts`\n* and tests, never by `index.ts` / the `./orm` authoring entry — the\n* isolation invariants hold.\n*/\n/** The `PgWarm` resource constructor — `yield* PgWarm(id, { url })` in a lowering. */\nconst PgWarm = Resource(\"PrismaCloud.PgWarm\");\n/**\n* Connect (retrying the cold-start) and run `select 1`, then release the\n* connection. Exported so tests can drive it directly; `retry` overrides the\n* bounded retry's defaults.\n*/\nasync function warmDatabase(url, retry = {}) {\n\tawait withConnectionRetry(async () => {\n\t\tconst client = new pg.Client({ connectionString: normalizeSslMode(url) });\n\t\tclient.on(\"error\", (error) => console.error(\"pg warm client socket error\", error));\n\t\tawait client.connect();\n\t\ttry {\n\t\t\tawait client.query(\"select 1\");\n\t\t} finally {\n\t\t\tawait client.end();\n\t\t}\n\t}, retry);\n}\n/**\n* The `PgWarm` provider service. `reconcile` warms the DB (retrying the\n* cold-start) and echoes the `url` so a downstream resource that reads\n* `warm.url` runs only after the DB is warm. Idempotent — safe on redeploy;\n* nothing to enumerate (`list` → `[]`) or tear down (`delete` → no-op; the DB's\n* own deletion handles teardown). Exported so tests can drive it directly.\n*/\nconst pgWarmProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ news }) => Effect.tryPromise({\n\t\ttry: () => warmDatabase(news.url),\n\t\tcatch: (error) => error\n\t}).pipe(Effect.map(() => ({ url: news.url }))),\n\tdelete: () => Effect.void\n};\n/** The `PgWarm` provider layer — merged into the extension descriptor's `providers()`. */\nconst PgWarmProvider = () => Provider.effect(PgWarm, Effect.succeed(pgWarmProviderService));\n//#endregion\n//#region src/preflight-names.ts\nfunction dedupedNames(entries) {\n\tconst byName = /* @__PURE__ */ new Map();\n\tfor (const entry of entries) if (!byName.has(entry.name)) byName.set(entry.name, entry);\n\treturn [...byName.values()];\n}\n/** Every `envSecret` leaf of one input binding: its platform name, found by the same dumb recursive descent the serializer uses (ADR-0042). */\nfunction collectSecretLeafNames(binding, serviceAddress, out) {\n\tif (isGeneratedParamSource(binding)) return;\n\tif (isSecretSource(binding)) {\n\t\tout.push(secretName(binding, `an input-binding secret leaf of service \"${serviceAddress}\"`));\n\t\treturn;\n\t}\n\tif (typeof binding !== \"object\" || binding === null) return;\n\tconst members = Array.isArray(binding) ? binding : Object.values(binding);\n\tfor (const member of members) collectSecretLeafNames(member, serviceAddress, out);\n}\n/** Walks each service's input binding for `envSecret` leaves, and `graph.params` for env-sourced params (ADR-0042). */\nfunction collectPreflightNames(graph) {\n\tconst secretEntries = [];\n\tfor (const { serviceAddress, binding } of inputManifest(graph)) {\n\t\tconst leafNames = [];\n\t\tcollectSecretLeafNames(binding, serviceAddress, leafNames);\n\t\tfor (const name of leafNames) secretEntries.push({\n\t\t\tname,\n\t\t\tserviceAddress\n\t\t});\n\t}\n\tconst envParams = dedupedNames(paramManifest(graph).filter((binding) => isEnvParamSource(binding.binding)).map((binding) => ({\n\t\tname: paramName(binding),\n\t\tserviceAddress: binding.serviceAddress\n\t})));\n\treturn {\n\t\tsecrets: dedupedNames(secretEntries),\n\t\tenvParams\n\t};\n}\n//#endregion\n//#region src/s3-credentials-resource.ts\n/**\n* The `S3Credentials` Alchemy resource (S5) — mints a random SigV4 key pair\n* ONCE at create and keeps it STABLE across deploys, so an unchanged module\n* no-ops on redeploy. The pair is generated by `@internal/s3-protocol`'s\n* `mintKeyPair` (moved there per the local-dev spec § 1, so deploy and local\n* dev credential minting share one implementation) and persisted in Alchemy\n* state; on every later apply the provider returns the persisted attributes\n* (`reconcile`'s `output`) unchanged — the same way the postgres resource\n* keeps a Connection stable. Rotation is destroy/recreate (a platform ask,\n* not solved here).\n*\n* Deploy-time only: imports `alchemy`. Imported by `control.ts` and tests,\n* never by `index.ts` / the authoring entry.\n*/\n/** The `S3Credentials` resource constructor — `yield* S3Credentials(id, {})` in the lowering. */\nconst S3Credentials = Resource(\"PrismaCloud.S3Credentials\");\n/**\n* The `S3Credentials` provider service. `reconcile` runs for create and update;\n* it returns the persisted `output` when present (a redeploy reuses the stored\n* pair — the no-op property) and mints a fresh pair only on first create.\n* Nothing to enumerate (`list` → `[]`) or tear down (`delete` → no-op; the pair\n* lives only in state). Exported so tests can drive it directly.\n*/\nconst s3CredentialsProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ output }) => Effect.sync(() => output ?? mintKeyPair()),\n\tdelete: () => Effect.void\n};\n/** The `S3Credentials` provider layer — merged into the extension descriptor's `providers()`. */\nconst S3CredentialsProvider = () => Provider.effect(S3Credentials, Effect.succeed(s3CredentialsProviderService));\n//#endregion\nexport { prismaCloudContainerOf as _, PgWarmProvider as a, resolveTargetRef as c, GeneratedParam as d, GeneratedParamProvider as f, deserialize as g, containerDescriptor as h, PgWarm as i, packHeadRefHashes as l, PrismaCloudContainer as m, S3CredentialsProvider as n, OrmMigration as o, PRISMA_CLOUD_EXTENSION_ID as p, collectPreflightNames as r, OrmMigrationProvider as s, S3Credentials as t, resolveOrmConfig as u };\n\n//# sourceMappingURL=s3-credentials-resource-D_qSGYMM.mjs.map"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/composer-prisma-cloud",
|
|
3
|
-
"version": "0.16.0-dev.
|
|
3
|
+
"version": "0.16.0-dev.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Prisma Cloud target for Prisma Composer: compute(), postgres() (ORM-managed, via /orm), rawPostgres(), the target extension, and first-party modules realized on Prisma Cloud (cron).",
|
|
6
6
|
"exports": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@effect/platform-bun": "4.0.0-rc.112",
|
|
38
38
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
39
39
|
"@effect/platform-node-shared": "4.0.0-rc.112",
|
|
40
|
-
"@prisma/composer": "0.16.0-dev.
|
|
40
|
+
"@prisma/composer": "0.16.0-dev.4",
|
|
41
41
|
"@prisma/management-api-sdk": "^1.60.0",
|
|
42
42
|
"@prisma/orm-toolchain": "8.0.0-rc.8",
|
|
43
43
|
"@standard-schema/spec": "^1.1.0",
|
|
@@ -53,22 +53,22 @@
|
|
|
53
53
|
"@prisma/orm-postgres": "8.0.0-rc.8"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@internal/auth": "0.16.0-dev.
|
|
57
|
-
"@internal/core": "0.16.0-dev.
|
|
58
|
-
"@internal/cron": "0.16.0-dev.
|
|
59
|
-
"@internal/dev-emulators": "0.16.0-dev.
|
|
60
|
-
"@internal/email": "0.16.0-dev.
|
|
61
|
-
"@internal/foundation": "0.16.0-dev.
|
|
62
|
-
"@internal/local-target": "0.16.0-dev.
|
|
63
|
-
"@internal/lowering": "0.16.0-dev.
|
|
64
|
-
"@internal/nextjs": "0.16.0-dev.
|
|
65
|
-
"@internal/node": "0.16.0-dev.
|
|
66
|
-
"@internal/prisma-cloud": "0.16.0-dev.
|
|
67
|
-
"@internal/s3-protocol": "0.16.0-dev.
|
|
68
|
-
"@internal/service-rpc": "0.16.0-dev.
|
|
69
|
-
"@internal/storage": "0.16.0-dev.
|
|
70
|
-
"@internal/streams": "0.16.0-dev.
|
|
71
|
-
"@internal/tsdown-config": "0.16.0-dev.
|
|
56
|
+
"@internal/auth": "0.16.0-dev.4",
|
|
57
|
+
"@internal/core": "0.16.0-dev.4",
|
|
58
|
+
"@internal/cron": "0.16.0-dev.4",
|
|
59
|
+
"@internal/dev-emulators": "0.16.0-dev.4",
|
|
60
|
+
"@internal/email": "0.16.0-dev.4",
|
|
61
|
+
"@internal/foundation": "0.16.0-dev.4",
|
|
62
|
+
"@internal/local-target": "0.16.0-dev.4",
|
|
63
|
+
"@internal/lowering": "0.16.0-dev.4",
|
|
64
|
+
"@internal/nextjs": "0.16.0-dev.4",
|
|
65
|
+
"@internal/node": "0.16.0-dev.4",
|
|
66
|
+
"@internal/prisma-cloud": "0.16.0-dev.4",
|
|
67
|
+
"@internal/s3-protocol": "0.16.0-dev.4",
|
|
68
|
+
"@internal/service-rpc": "0.16.0-dev.4",
|
|
69
|
+
"@internal/storage": "0.16.0-dev.4",
|
|
70
|
+
"@internal/streams": "0.16.0-dev.4",
|
|
71
|
+
"@internal/tsdown-config": "0.16.0-dev.4",
|
|
72
72
|
"@prisma/orm-postgres": "8.0.0-rc.8",
|
|
73
73
|
"@types/node": "^26.0.1",
|
|
74
74
|
"typescript": "^6.0.3"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"s3-credentials-resource-D_qSGYMM-CnDQrSMW.mjs","names":["Config","randomBytes","managementClientLayer"],"sources":["../../../1-prisma-cloud/0-lowering/lowering/dist/credentials-DhT4a38W.mjs","../../../1-prisma-cloud/0-lowering/lowering/dist/database-url-claim-m_nGXIHa.mjs","../../../0-framework/2-authoring/bundle-paths/dist/index.mjs","../../../1-prisma-cloud/0-lowering/lowering/dist/compute.mjs","../../../1-prisma-cloud/0-lowering/lowering/dist/index.mjs","../../../1-prisma-cloud/0-lowering/s3-protocol/dist/index.mjs","../../../1-prisma-cloud/1-extensions/target/dist/s3-credentials-resource-D_qSGYMM.mjs"],"sourcesContent":["import * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Config from \"effect/Config\";\n//#region src/credentials.ts\n/**\n* The Prisma service token used to authenticate Management API calls. Kept\n* as a Redacted value so it never lands in logs or error output.\n*/\nvar PrismaCredentials = class extends Context.Service()(\"PrismaCredentials\") {};\n/** Resolve the token from the `PRISMA_SERVICE_TOKEN` environment variable. */\nconst fromEnv = () => Layer.effect(PrismaCredentials, Effect.gen(function* () {\n\treturn { token: yield* Config.redacted(\"PRISMA_SERVICE_TOKEN\") };\n}));\nconst DEFAULT_BASE_URL = \"https://api.prisma.io\";\nconst isLoopbackHost = (hostname) => hostname === \"localhost\" || hostname.endsWith(\".localhost\") || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n/** Same validation as upstream alchemy's `PrismaEnvironment`: an HTTP(S) origin, HTTPS unless loopback, no credentials, no path/query/fragment. */\nconst normalizeBaseUrl = (value) => Effect.try({\n\ttry: () => {\n\t\tconst url = new URL(value);\n\t\tif (url.protocol !== \"https:\" && url.protocol !== \"http:\") throw new Error(\"Prisma Management API URL must use HTTP or HTTPS.\");\n\t\tif (url.username.length > 0 || url.password.length > 0) throw new Error(\"Prisma Management API URL must not contain credentials.\");\n\t\tif (url.protocol === \"http:\" && !isLoopbackHost(url.hostname)) throw new Error(\"Prisma Management API URL must use HTTPS unless it targets a loopback host.\");\n\t\tif (url.pathname !== \"/\" && url.pathname !== \"\" || url.search.length > 0 || url.hash.length > 0) throw new Error(\"Prisma Management API URL must be an origin without a path, query, or fragment.\");\n\t\treturn url.origin;\n\t},\n\tcatch: (cause) => cause instanceof Error ? cause : /* @__PURE__ */ new Error(`Invalid Prisma Management API URL: ${String(cause)}`)\n});\n/**\n* The Management API origin every Prisma-Cloud client in this package uses —\n* Composer's own SDK client AND upstream alchemy's postgres providers resolve\n* it through this one function, so `PRISMA_API_URL` can never point them at\n* different hosts. Mirrors upstream alchemy's `PrismaEnvironment` resolution:\n* `PRISMA_API_URL`, then `PRISMA_MANAGEMENT_API_URL`, then the public origin,\n* normalized and validated identically.\n*/\nconst managementApiBaseUrl = (env) => env !== void 0 ? normalizeBaseUrl(env[\"PRISMA_API_URL\"] || env[\"PRISMA_MANAGEMENT_API_URL\"] || DEFAULT_BASE_URL) : Config.string(\"PRISMA_API_URL\").pipe(Config.orElse(() => Config.string(\"PRISMA_MANAGEMENT_API_URL\")), Config.withDefault(DEFAULT_BASE_URL), Effect.flatMap(normalizeBaseUrl));\n//#endregion\nexport { fromEnv as n, managementApiBaseUrl as r, PrismaCredentials as t };\n\n//# sourceMappingURL=credentials-DhT4a38W.mjs.map","import { r as managementApiBaseUrl, t as PrismaCredentials } from \"./credentials-DhT4a38W.mjs\";\nimport { createManagementApiClient } from \"@prisma/management-api-sdk\";\nimport * as Context from \"effect/Context\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport * as Data from \"effect/Data\";\nimport * as Option from \"effect/Option\";\n//#region src/client.ts\n/**\n* The typed Prisma Management API client, built once from the resolved\n* credentials. Providers yield this in their outer Effect and call it inside\n* `reconcile` / `delete`.\n*/\nvar ManagementClient = class extends Context.Service()(\"PrismaManagementClient\") {};\n/**\n* By default the base URL comes from `managementApiBaseUrl()` — the SAME\n* resolver upstream's providers use (see providers.ts), so `PRISMA_API_URL`\n* can never split the postgres family and the compute/bucket/state clients\n* across hosts. `apiOrigin` overrides it (tests point it at a fake).\n*/\nconst layer = (options) => Layer.effect(ManagementClient, Effect.gen(function* () {\n\tconst { token } = yield* PrismaCredentials;\n\tconst baseUrl = options?.apiOrigin ?? (yield* managementApiBaseUrl());\n\treturn createManagementApiClient({\n\t\ttoken: Redacted.value(token),\n\t\tbaseUrl\n\t});\n}));\n//#endregion\n//#region src/http.ts\n/** A non-2xx response from the Management API (or a transport failure). */\nvar PrismaApiError = class extends Data.TaggedError(\"PrismaApiError\") {};\nconst attempt = (f) => Effect.tryPromise({\n\ttry: f,\n\tcatch: (cause) => new PrismaApiError({\n\t\tstatus: 0,\n\t\tmessage: String(cause)\n\t})\n});\nconst fail = (r) => Effect.fail(new PrismaApiError({\n\tstatus: r.response.status,\n\tmessage: JSON.stringify(r.error)\n}));\n/** Unwrap `data`, failing on any API error. Preserves the SDK's response type. */\nconst call = (f) => attempt(f).pipe(Effect.flatMap((r) => r.error !== void 0 || r.data === void 0 ? fail(r) : Effect.succeed(r.data)));\n/** Fire-and-forget a call, tolerating a 404 (already deleted). */\nconst callVoid = (f) => attempt(f).pipe(Effect.flatMap((r) => r.response.status === 404 || r.error === void 0 ? Effect.void : fail(r)));\n/**\n* Fire a CREATE call, tolerating a 409 (it already exists). Gives the caller\n* create-only semantics: the thing is created when absent, and an existing one\n* — whoever created it — is left exactly as it is.\n*/\nconst callCreateOnly = (f) => attempt(f).pipe(Effect.flatMap((r) => r.response.status === 409 || r.error === void 0 ? Effect.void : fail(r)));\n//#endregion\n//#region src/pagination.ts\n/** Far beyond any real collection size per listing; hitting it means the API's pagination is broken. */\nconst MAX_PAGES = 1e3;\nconst brokenPaginationError = (description, reason) => new PrismaApiError({\n\tstatus: 0,\n\tmessage: `listing ${description} ${reason} — the Management API pagination appears broken; refusing to continue with a possibly incomplete listing.`\n});\n/** {@link drivePages} in its most common shape: every page's rows, accumulated. */\nconst collectPages = (description, fetchPage) => Effect.gen(function* () {\n\tconst rows = [];\n\tyield* drivePages(description, fetchPage, (data) => {\n\t\trows.push(...data);\n\t\treturn false;\n\t});\n\treturn rows;\n});\n/**\n* Drives a cursor-paginated Management API listing with a guard against\n* broken pagination: a cursor that does not advance, more pages reported\n* without a cursor to fetch them with, or more than {@link MAX_PAGES} pages,\n* FAILS instead of hanging forever or returning a listing known to be\n* incomplete. `onPage` receives each page's rows as they arrive; returning\n* `true` stops early (the caller found what it wanted).\n*/\nconst drivePages = (description, fetchPage, onPage) => Effect.gen(function* () {\n\tlet cursor;\n\tfor (let pageCount = 0;; pageCount++) {\n\t\tif (pageCount >= MAX_PAGES) return yield* Effect.fail(brokenPaginationError(description, `did not finish within ${String(MAX_PAGES)} pages`));\n\t\tconst page = yield* fetchPage(cursor);\n\t\tif (onPage(page.data)) return;\n\t\tif (!page.pagination.hasMore) return;\n\t\tconst next = page.pagination.nextCursor;\n\t\tif (next === null) return yield* Effect.fail(brokenPaginationError(description, \"reported more pages but returned no cursor\"));\n\t\tif (next === cursor) return yield* Effect.fail(brokenPaginationError(description, \"returned a non-advancing cursor\"));\n\t\tcursor = next;\n\t}\n});\n/**\n* {@link drivePages} for Promise-based callers (e.g. target's preflight,\n* which speaks the SDK's `{data, error}` shape directly). Same guard, same\n* errors; deliberately a sibling loop rather than a wrapper, because routing\n* a Promise fetch through Effect and back (`Effect.tryPromise` +\n* `runPromise`) would re-wrap the caller's own thrown errors. `fetchPage`\n* rejections propagate untouched.\n*/\nasync function drivePagesAsync(description, fetchPage, onPage) {\n\tlet cursor;\n\tfor (let pageCount = 0;; pageCount++) {\n\t\tif (pageCount >= MAX_PAGES) throw brokenPaginationError(description, `did not finish within ${String(MAX_PAGES)} pages`);\n\t\tconst page = await fetchPage(cursor);\n\t\tif (onPage(page.data)) return;\n\t\tif (!page.pagination.hasMore) return;\n\t\tconst next = page.pagination.nextCursor;\n\t\tif (next === null) throw brokenPaginationError(description, \"reported more pages but returned no cursor\");\n\t\tif (next === cursor) throw brokenPaginationError(description, \"returned a non-advancing cursor\");\n\t\tcursor = next;\n\t}\n}\n//#endregion\n//#region src/container.ts\n/** Raised with `ensure: false` when the app's Project (or a named stage's Branch) doesn't exist. */\nvar ContainerNotFoundError = class extends Data.TaggedError(\"ContainerNotFoundError\") {};\nconst listAllProjects = (client) => collectPages(\"projects\", (cursor) => call(() => client.GET(\"/v1/projects\", { params: { query: cursor === void 0 ? {} : { cursor } } })));\n/**\n* Workspace ids circulate in two shapes: `wksp_`-prefixed and bare. Compare\n* bare-to-bare so a `wksp_`-prefixed API id still matches a bare configured\n* one (the same normalization `state/bootstrap.ts` applies to the same\n* `/v1/projects` listing).\n*/\nconst bareWorkspaceId = (id) => id.startsWith(\"wksp_\") ? id.slice(5) : id;\n/**\n* Finds the app's Project by logical id or name in the workspace, creating\n* one if absent. Logical id match (exact, workspace-unique) is preferred over\n* display-name match (oldest-wins fallback for projects without a logical id).\n* Creates one if none match, unless `ensure` is `false` (find-only —\n* `destroy`), in which case an absent Project fails with\n* `ContainerNotFoundError`. No ownership marker and no `--project` override\n* (both deferred — see ADR-0019).\n*/\nconst resolveProject = (client, workspaceId, appName, ensure) => Effect.gen(function* () {\n\tconst workspaceProjects = (yield* listAllProjects(client)).filter((p) => bareWorkspaceId(p.workspace.id) === bareWorkspaceId(workspaceId));\n\tconst logicalIdMatch = workspaceProjects.find((p) => p.logicalId != null && p.logicalId === appName);\n\tif (logicalIdMatch !== void 0) return logicalIdMatch.id;\n\tconst nameMatch = workspaceProjects.filter((p) => p.name === appName).sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];\n\tif (nameMatch !== void 0) return nameMatch.id;\n\tif (!ensure) return yield* Effect.fail(new ContainerNotFoundError({ appName }));\n\treturn (yield* call(() => client.POST(\"/v1/projects\", { body: {\n\t\tname: appName,\n\t\tworkspaceId,\n\t\tcreateDatabase: false,\n\t\tlogicalId: appName\n\t} })).pipe(Effect.catch((err) => err.status === 409 ? Effect.fail(new PrismaApiError({\n\t\tstatus: 409,\n\t\tmessage: \"a project with this name already exists in the workspace; rename your Composer module or free the name.\"\n\t})) : Effect.fail(err)))).data.id;\n});\n/**\n* The project's implicit default Branch — every live Project owns exactly\n* one (a platform invariant). The list endpoint has no `isDefault` filter,\n* so this pages through the Branches (bounded — drivePages) and returns as\n* soon as a page contains it. Never creates one: its absence means the\n* platform's invariant is broken, which is not something a deploy can\n* repair.\n*/\nconst resolveDefaultBranchId = (client, projectId) => Effect.gen(function* () {\n\tlet found;\n\tyield* drivePages(`branches of project ${projectId}`, (cursor) => call(() => client.GET(\"/v1/projects/{projectId}/branches\", { params: {\n\t\tpath: { projectId },\n\t\tquery: cursor === void 0 ? {} : { cursor }\n\t} })), (data) => {\n\t\tfound = data.find((b) => b.isDefault)?.id;\n\t\treturn found !== void 0;\n\t});\n\tif (found !== void 0) return found;\n\treturn yield* Effect.fail(new PrismaApiError({\n\t\tstatus: 0,\n\t\tmessage: `project ${projectId} has no default Branch — the platform guarantees every live Project owns one; contact support.`\n\t}));\n});\nconst findBranchId = (client, projectId, gitName) => call(() => client.GET(\"/v1/projects/{projectId}/branches\", { params: {\n\tpath: { projectId },\n\tquery: { gitName }\n} })).pipe(Effect.map((page) => page.data[0]?.id));\n/**\n* Finds the stage's Branch by its exact `gitName`, creating it if absent\n* unless `ensure` is `false` (find-only — `destroy`), in which case an\n* absent Branch fails with `ContainerNotFoundError`. The Management API has\n* no server-side \"create-or-return\" idempotency (`POST\n* /v1/projects/:id/branches` 409s on a duplicate `gitName`, with no request\n* field to make that a no-op), so idempotency is client-side: observe\n* first, and on a racing 409 from create, re-observe rather than fail.\n*/\nconst resolveBranch = (client, projectId, gitName, appName, ensure) => Effect.gen(function* () {\n\tconst existing = yield* findBranchId(client, projectId, gitName);\n\tif (existing !== void 0) return existing;\n\tif (!ensure) return yield* Effect.fail(new ContainerNotFoundError({\n\t\tappName,\n\t\tstage: gitName\n\t}));\n\treturn yield* call(() => client.POST(\"/v1/projects/{projectId}/branches\", {\n\t\tparams: { path: { projectId } },\n\t\tbody: { gitName }\n\t})).pipe(Effect.map((r) => r.data.id), Effect.catch((err) => err.status === 409 ? findBranchId(client, projectId, gitName).pipe(Effect.flatMap((id) => id === void 0 ? Effect.fail(err) : Effect.succeed(id))) : Effect.fail(err)));\n});\n/**\n* Resolves the two containers a stage's deploy runs into (ADR-0019): the\n* app's **Project**, found-or-created by name, and — for a named stage\n* only — its **Branch**, found-or-created by `gitName`. The default stage\n* (no `stage`) creates no Branch; `branchId` is omitted, and the project's\n* default Branch's id is read into `defaultBranchId` instead. With `ensure:\n* false` (`destroy`), nothing is created — an absent Project or Branch\n* fails with `ContainerNotFoundError` instead.\n*/\nconst resolveContainer = (opts) => Effect.gen(function* () {\n\tconst client = yield* ManagementClient;\n\tconst ensure = opts.ensure ?? true;\n\tconst projectId = yield* resolveProject(client, opts.workspaceId, opts.appName, ensure);\n\tif (opts.stage === void 0) return {\n\t\tprojectId,\n\t\tdefaultBranchId: yield* resolveDefaultBranchId(client, projectId)\n\t};\n\treturn {\n\t\tprojectId,\n\t\tbranchId: yield* resolveBranch(client, projectId, opts.stage, opts.appName, ensure)\n\t};\n});\n/**\n* Soft-deletes a Branch. Tolerates a 404 (already gone). The API refuses if\n* the Branch still has live members or is the production/default Branch —\n* that surfaces as a `PrismaApiError`.\n*/\nconst deleteBranch = (branchId) => Effect.gen(function* () {\n\tconst client = yield* ManagementClient;\n\tyield* callVoid(() => client.DELETE(\"/v1/branches/{branchId}\", { params: { path: { branchId } } }));\n});\n/**\n* Deletes a Project. Tolerates a 404 (already gone). The API refuses with a\n* 400 if the Project still has live dependencies (e.g. another stage's\n* Branch/resources) — that surfaces as a `PrismaApiError`.\n*/\nconst deleteProject = (projectId) => Effect.gen(function* () {\n\tconst client = yield* ManagementClient;\n\tyield* callVoid(() => client.DELETE(\"/v1/projects/{id}\", { params: { path: { id: projectId } } }));\n});\n//#endregion\n//#region src/database-url-claim.ts\n/**\n* Claims the platform's `DATABASE_URL` / `DATABASE_URL_POOLED` variables for\n* the app's project with the placeholder `\"-\"`, before the platform can seed\n* them: on a project with no production `DATABASE_URL`, Prisma Cloud fills\n* one in on the next compute deploy, handing live credentials to any service\n* that reads `process.env.DATABASE_URL` behind the framework's back. The\n* claim is create-only, so whoever writes first wins; any connect attempt\n* against `\"-\"` fails loudly (the API rejects an empty value).\n*\n* Deliberately NOT alchemy resources: Composer must never patch or delete\n* these variables, and a state row would plan exactly those calls.\n*/\nconst PLACEHOLDER_VALUE = \"-\";\n/** The two names Prisma Cloud fills in for itself, and that no Composer service may bind. */\nconst RESERVED_DATABASE_URL_KEYS = [\"DATABASE_URL\", \"DATABASE_URL_POOLED\"];\n/**\n* Both environment classes, each at PROJECT level (no branch id). A preview\n* branch with no override of its own reads the project-level preview row, so\n* these two rows cover every stage the app will ever deploy — including\n* stages that do not exist yet.\n*/\nconst ENVIRONMENT_CLASSES = [\"production\", \"preview\"];\nconst claim = (client, projectId, key, environmentClass) => callCreateOnly(() => client.POST(\"/v1/environment-variables\", { body: {\n\tprojectId,\n\tclass: environmentClass,\n\tkey,\n\tvalue: PLACEHOLDER_VALUE\n} }));\n/**\n* Claims both keys in both classes for `projectId`, create-only: a 409 means\n* the variable already exists — whether Prisma Cloud seeded it or an earlier\n* deploy claimed it — and is skipped, never overwritten and never removed.\n* Repeating it is always safe. Does nothing when no {@link ManagementClient}\n* is in context (the local target has no Management API).\n*/\nconst claimDatabaseUrlKeys = (projectId) => Effect.gen(function* () {\n\tconst client = yield* Effect.serviceOption(ManagementClient);\n\tif (Option.isNone(client)) return;\n\tfor (const key of RESERVED_DATABASE_URL_KEYS) for (const environmentClass of ENVIRONMENT_CLASSES) yield* claim(client.value, projectId, key, environmentClass);\n});\n//#endregion\nexport { deleteProject as a, collectPages as c, PrismaApiError as d, call as f, deleteBranch as i, drivePages as l, layer as m, claimDatabaseUrlKeys as n, resolveContainer as o, ManagementClient as p, ContainerNotFoundError as r, resolveDefaultBranchId as s, RESERVED_DATABASE_URL_KEYS as t, drivePagesAsync as u };\n\n//# sourceMappingURL=database-url-claim-m_nGXIHa.mjs.map","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/** 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, isWithin };\n\n//# sourceMappingURL=index.mjs.map","import { n as packageComputeArtifact, t as ARTIFACT_CONTENT_TYPE } from \"./artifact-CoKVIyRH.mjs\";\nimport * as Effect from \"effect/Effect\";\nimport * as Provider from \"alchemy/Provider\";\nimport * as Output from \"alchemy/Output\";\nimport { Resource } from \"alchemy\";\n//#region src/compute/deployment-edge.ts\n/**\n* Orders a deployment AFTER the environment rows it boots with: the platform\n* materializes rows into a deployment at create time and never re-reads them\n* (PRO-211). Alchemy schedules only on resource references inside prop\n* values, and upstream's `Prisma.Deployment` has no environment prop, so the\n* edge rides `app`: every variable's id threads through it, and the platform\n* still receives the app id. `app` is the ONLY safe prop — upstream's diff\n* treats `{portMapping, skipCodeUpload, artifactPath, artifactContentType}`\n* as one block and returns \"no opinion\" if any is unresolved (a brand-new\n* variable always is), which would silently skip the artifact comparison.\n* Ordering only: shipping a CHANGED value is `Deployment.triggers`' job (the\n* compute descriptor declares one member per environment row).\n*/\nconst appAfterEnvironment = (app, environment) => environment.length === 0 ? app : Output.flatMap(Output.all(app, ...environment.map((variable) => variable.environmentVariableId)), () => app);\n//#endregion\n//#region src/compute/ServiceKey.ts\n/**\n* The `ServiceKey` Alchemy resource (ADR-0030) — mints a random 256-bit key\n* ONCE at create and keeps it STABLE across deploys, so an unchanged edge\n* no-ops on redeploy. Same mint-once-stable lifecycle as `S3Credentials`\n* (`packages/1-prisma-cloud/1-extensions/target/src/s3-credentials-resource.ts`):\n* Web Crypto only (`crypto.getRandomValues` — no `node:` import), persisted in\n* Alchemy state; on every later apply the provider returns the persisted\n* attributes (`reconcile`'s `output`) unchanged. One resource per RPC edge;\n* rotation is destroy/recreate.\n*/\n/** The `ServiceKey` resource constructor — `yield* Prisma.ServiceKey(id, {})` in the lowering. */\nconst ServiceKey = Resource(\"PrismaCloud.ServiceKey\");\n/** A fresh 256-bit key as 64 lowercase hex chars (Web Crypto — no node import). */\nfunction mintServiceKey() {\n\tconst bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(32));\n\treturn { value: Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\") };\n}\n/**\n* The `ServiceKey` provider service. `reconcile` runs for create and update;\n* it returns the persisted `output` when present (a redeploy reuses the\n* stored key — the no-op property) and mints a fresh key only on first\n* create. Nothing to enumerate (`list` → `[]`) or tear down (`delete` →\n* no-op; the key lives only in state).\n*/\nconst serviceKeyProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ output }) => Effect.sync(() => output ?? mintServiceKey()),\n\tdelete: () => Effect.void\n};\n/** The `ServiceKey` provider layer — merged into the Prisma Cloud extension's `providers()`. */\nconst ServiceKeyProvider = () => Provider.effect(ServiceKey, Effect.succeed(serviceKeyProviderService));\n//#endregion\nexport { ARTIFACT_CONTENT_TYPE, ServiceKey, ServiceKeyProvider, appAfterEnvironment, mintServiceKey, packageComputeArtifact, serviceKeyProviderService };\n\n//# sourceMappingURL=compute.mjs.map","import { n as fromEnv, r as managementApiBaseUrl, t as PrismaCredentials } from \"./credentials-DhT4a38W.mjs\";\nimport { a as deleteProject, c as collectPages, i as deleteBranch, l as drivePages, m as layer, n as claimDatabaseUrlKeys, o as resolveContainer, p as ManagementClient, r as ContainerNotFoundError, s as resolveDefaultBranchId, t as RESERVED_DATABASE_URL_KEYS, u as drivePagesAsync } from \"./database-url-claim-m_nGXIHa.mjs\";\nimport { n as packageComputeArtifact, t as ARTIFACT_CONTENT_TYPE } from \"./artifact-CoKVIyRH.mjs\";\nimport { ServiceKey, ServiceKeyProvider, appAfterEnvironment, mintServiceKey, serviceKeyProviderService } from \"./compute.mjs\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as NodeHttpClient from \"@effect/platform-node/NodeHttpClient\";\nimport * as Prisma from \"alchemy/Prisma\";\nimport * as Provider from \"alchemy/Provider\";\n//#region src/providers.ts\n/** The collection of Prisma resource providers. */\nvar Providers = class extends Provider.ProviderCollection()(\"PrismaComposer\") {};\n/**\n* Upstream's `PrismaEnvironment`, built from Composer's own env credentials —\n* no profile store, so no TTY prompt and no non-interactive hard-fail:\n* `PRISMA_SERVICE_TOKEN` (redacted, via `PrismaCredentials`) plus the base\n* URL from `managementApiBaseUrl()` — the SAME resolver `client.ts` uses,\n* so `PRISMA_API_URL` moves the postgres family and the compute/bucket/state\n* clients together, never one without the other.\n*/\nconst prismaEnvironment = () => Layer.effect(Prisma.PrismaEnvironment, Effect.gen(function* () {\n\tconst { token } = yield* PrismaCredentials;\n\treturn {\n\t\ttype: \"serviceToken\",\n\t\tserviceToken: token,\n\t\tsource: {\n\t\t\ttype: \"env\",\n\t\t\tdetails: \"PRISMA_SERVICE_TOKEN\"\n\t\t},\n\t\tbaseUrl: yield* managementApiBaseUrl()\n\t};\n}));\n/**\n* Upstream alchemy's live providers for the postgres family (Project,\n* Database, Connection), the compute family (App, Deployment,\n* EnvironmentVariable), and the bucket family (Bucket, BucketAccessKey),\n* over upstream's management client, authenticated by\n* {@link prismaEnvironment}.\n*\n* Composed from the per-resource provider layers rather than upstream's own\n* `providers()` bundle: that bundle pulls in the profile store\n* (`AlchemyProfile`/`CredentialsStore`), and Composer deliberately runs\n* without one — no TTY prompt, no non-interactive hard-fail.\n*/\nconst upstreamPrismaProviders = () => Layer.mergeAll(Prisma.ProjectProvider(), Prisma.DatabaseProvider(), Prisma.ConnectionProvider(), Prisma.AppProvider(), Prisma.DeploymentProvider(), Prisma.EnvironmentVariableProvider(), Prisma.BucketProvider(), Prisma.BucketAccessKeyProvider()).pipe(Layer.provideMerge(Prisma.PrismaClientLive), Layer.provide(NodeHttpClient.layerNodeHttp), Layer.provideMerge(prismaEnvironment()));\n/**\n* The Prisma provider bundle: every resource provider, the Management API\n* client, and env-based credentials. Plug into a stack with\n* `{ providers: Prisma.providers() }`.\n*\n* The node transport is also the bundle's ambient `HttpClient`: upstream's\n* `Deployment` artifact upload needs node's explicit Content-Length (fetch\n* streams chunked), and upstream documents the ambient client as the\n* supported way to provide it. Invariant: no Composer provider may resolve\n* the ambient `HttpClient` — each carries its own client — or it would\n* silently get this override. Filed upstream: export the scoped upload\n* client, after which this becomes a private layer.\n*/\nconst providers = () => Layer.effect(Providers, Provider.collection([\n\tPrisma.Project,\n\tPrisma.Database,\n\tPrisma.Connection,\n\tPrisma.App,\n\tPrisma.Deployment,\n\tPrisma.EnvironmentVariable,\n\tPrisma.Bucket,\n\tPrisma.BucketAccessKey\n])).pipe(Layer.provide(upstreamPrismaProviders()), Layer.provideMerge(NodeHttpClient.layerNodeHttp), Layer.provideMerge(layer()), Layer.provideMerge(fromEnv()), Layer.orDie);\n//#endregion\nexport { ARTIFACT_CONTENT_TYPE, ContainerNotFoundError, ManagementClient, PrismaCredentials, Providers, RESERVED_DATABASE_URL_KEYS, ServiceKey, ServiceKeyProvider, appAfterEnvironment, claimDatabaseUrlKeys, collectPages, deleteBranch, deleteProject, drivePages, drivePagesAsync, fromEnv, managementApiBaseUrl, layer as managementClientLayer, mintServiceKey, packageComputeArtifact, providers, resolveContainer, resolveDefaultBranchId, serviceKeyProviderService };\n\n//# sourceMappingURL=index.mjs.map","import { createHash, createHmac, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nconst DEFAULT_CONTENT_TYPE$1 = \"application/octet-stream\";\nconst TMP_DIR_NAME = \".tmp\";\nconst META_DIR_NAME = \".meta\";\nconst RESERVED_SEGMENTS = /* @__PURE__ */ new Set([TMP_DIR_NAME, META_DIR_NAME]);\nconst BUCKET_NAME_RE = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;\nfunction etagOf$1(bytes) {\n\treturn `\"${createHash(\"sha256\").update(bytes).digest(\"hex\")}\"`;\n}\nfunction isErrnoException(err) {\n\treturn err instanceof Error && \"code\" in err;\n}\nfunction isEnoent(err) {\n\treturn isErrnoException(err) && err.code === \"ENOENT\";\n}\n/**\n* Splits a key into its `/` segments, rejecting anything that could escape\n* the bucket dir or collide with the reserved `.tmp`/`.meta` namespaces:\n* `..` segments, an empty segment (leading/trailing/doubled `/`, which also\n* catches a leading-slash \"absolute\" key), or a segment literally `.tmp` or\n* `.meta` at any depth.\n*/\nfunction keySegments(key) {\n\tconst segments = key.split(\"/\");\n\tfor (const segment of segments) if (segment === \"\" || segment === \".\" || segment === \"..\" || RESERVED_SEGMENTS.has(segment)) throw new Error(`invalid object key: \"${key}\"`);\n\treturn segments;\n}\n/** `<bucketDir>/<key's segments>`, double-checked to still resolve inside `bucketDir`. */\nfunction objectPath(bucketDir, key) {\n\tconst target = path.join(bucketDir, ...keySegments(key));\n\tconst resolvedRoot = path.resolve(bucketDir) + path.sep;\n\tif (!(path.resolve(target) + path.sep).startsWith(resolvedRoot)) throw new Error(`invalid object key: \"${key}\"`);\n\treturn target;\n}\n/** `<bucketDir>/.meta/<key's segments>.json` — mirrors `objectPath`'s tree under `.meta`. */\nfunction sidecarPath(bucketDir, key) {\n\tconst segments = keySegments(key);\n\tconst last = segments[segments.length - 1];\n\tconst dirs = segments.slice(0, -1);\n\treturn path.join(bucketDir, META_DIR_NAME, ...dirs, `${last}.json`);\n}\n/** Write-temp-then-rename: never leaves a reader observing a partial file. */\nasync function writeAtomic(finalPath, tmpRoot, bytes) {\n\tawait fs.mkdir(tmpRoot, { recursive: true });\n\tconst tmpPath = path.join(tmpRoot, randomUUID());\n\tawait fs.writeFile(tmpPath, bytes);\n\tawait fs.mkdir(path.dirname(finalPath), { recursive: true });\n\tawait fs.rename(tmpPath, finalPath);\n}\nfunction isSidecar(value) {\n\treturn typeof value === \"object\" && value !== null && \"contentType\" in value && typeof value.contentType === \"string\" && \"etag\" in value && typeof value.etag === \"string\";\n}\nasync function readSidecar(sidecar) {\n\tlet raw;\n\ttry {\n\t\traw = await fs.readFile(sidecar, \"utf8\");\n\t} catch (err) {\n\t\tif (isEnoent(err)) return null;\n\t\tthrow err;\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (isSidecar(parsed)) return parsed;\n\t} catch {}\n\treturn null;\n}\n/** Read the object's bytes plus its metadata — adopting a sidecar-less file (dropped in by a developer) by computing and lazily persisting one. `null` when the object is missing. */\nasync function readObject(bucketDir, key) {\n\tconst target = objectPath(bucketDir, key);\n\tlet bytes;\n\ttry {\n\t\tbytes = await fs.readFile(target);\n\t} catch (err) {\n\t\tif (isEnoent(err)) return null;\n\t\tthrow err;\n\t}\n\tconst existing = await readSidecar(sidecarPath(bucketDir, key));\n\tif (existing) return {\n\t\tbytes,\n\t\tmeta: existing\n\t};\n\tconst meta = {\n\t\tcontentType: DEFAULT_CONTENT_TYPE$1,\n\t\tetag: etagOf$1(bytes)\n\t};\n\tawait writeAtomic(sidecarPath(bucketDir, key), path.join(bucketDir, TMP_DIR_NAME), Buffer.from(JSON.stringify(meta)));\n\treturn {\n\t\tbytes,\n\t\tmeta\n\t};\n}\n/** Remove now-empty directories from `startDir` up to (never including) `root`. */\nasync function pruneEmptyDirs(root, startDir) {\n\tconst resolvedRoot = path.resolve(root);\n\tlet dir = path.resolve(startDir);\n\twhile (dir !== resolvedRoot && dir.startsWith(resolvedRoot + path.sep)) {\n\t\tlet entries;\n\t\ttry {\n\t\t\tentries = await fs.readdir(dir);\n\t\t} catch (err) {\n\t\t\tif (isEnoent(err)) {\n\t\t\t\tdir = path.dirname(dir);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t\tif (entries.length > 0) break;\n\t\ttry {\n\t\t\tawait fs.rmdir(dir);\n\t\t} catch (err) {\n\t\t\tif (!isEnoent(err)) throw err;\n\t\t}\n\t\tdir = path.dirname(dir);\n\t}\n}\n/** Recursively lists every object key under `dir`, skipping `.tmp`/`.meta` at any depth. */\nasync function walkKeys(dir) {\n\tconst keys = [];\n\tasync function walk(current, prefix) {\n\t\tlet entries;\n\t\ttry {\n\t\t\tentries = await fs.readdir(current, { withFileTypes: true });\n\t\t} catch (err) {\n\t\t\tif (isEnoent(err)) return;\n\t\t\tthrow err;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (RESERVED_SEGMENTS.has(entry.name)) continue;\n\t\t\tconst rel = prefix === \"\" ? entry.name : `${prefix}/${entry.name}`;\n\t\t\tif (entry.isDirectory()) await walk(path.join(current, entry.name), rel);\n\t\t\telse if (entry.isFile()) keys.push(rel);\n\t\t}\n\t}\n\tawait walk(dir, \"\");\n\treturn keys;\n}\n/**\n* A disk-backed `ObjectStore`: object bytes and a metadata sidecar under a\n* per-bucket directory the caller resolves. See the module doc for the\n* unknown-bucket / invalid-key failure shapes.\n*/\nfunction fsStore(resolveBucketDir) {\n\tfunction resolveDir(bucket) {\n\t\tif (!BUCKET_NAME_RE.test(bucket)) return void 0;\n\t\treturn resolveBucketDir(bucket);\n\t}\n\treturn {\n\t\tasync put(bucket, key, bytes, opts = {}) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) throw new Error(`no such bucket: \"${bucket}\"`);\n\t\t\tconst target = objectPath(dir, key);\n\t\t\tconst tmpRoot = path.join(dir, TMP_DIR_NAME);\n\t\t\tconst etag = etagOf$1(bytes);\n\t\t\tconst contentType = opts.contentType ?? DEFAULT_CONTENT_TYPE$1;\n\t\t\tawait writeAtomic(target, tmpRoot, bytes);\n\t\t\tawait writeAtomic(sidecarPath(dir, key), tmpRoot, Buffer.from(JSON.stringify({\n\t\t\t\tcontentType,\n\t\t\t\tetag\n\t\t\t})));\n\t\t\treturn { etag };\n\t\t},\n\t\tasync get(bucket, key, opts = {}) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return null;\n\t\t\tconst found = await readObject(dir, key);\n\t\t\tif (!found) return null;\n\t\t\tconst { bytes, meta } = found;\n\t\t\tconst size = bytes.byteLength;\n\t\t\tif (opts.range) {\n\t\t\t\tconst start = opts.range.start;\n\t\t\t\tconst end = opts.range.end === void 0 ? size - 1 : Math.min(opts.range.end, size - 1);\n\t\t\t\treturn {\n\t\t\t\t\tbytes: start > end ? /* @__PURE__ */ new Uint8Array(0) : bytes.subarray(start, end + 1),\n\t\t\t\t\tetag: meta.etag,\n\t\t\t\t\tcontentType: meta.contentType,\n\t\t\t\t\tsize\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tbytes: new Uint8Array(bytes),\n\t\t\t\tetag: meta.etag,\n\t\t\t\tcontentType: meta.contentType,\n\t\t\t\tsize\n\t\t\t};\n\t\t},\n\t\tasync head(bucket, key) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return null;\n\t\t\tconst found = await readObject(dir, key);\n\t\t\tif (!found) return null;\n\t\t\treturn {\n\t\t\t\tetag: found.meta.etag,\n\t\t\t\tsize: found.bytes.byteLength,\n\t\t\t\tcontentType: found.meta.contentType\n\t\t\t};\n\t\t},\n\t\tasync delete(bucket, key) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return;\n\t\t\tconst target = objectPath(dir, key);\n\t\t\tconst sidecar = sidecarPath(dir, key);\n\t\t\ttry {\n\t\t\t\tawait fs.unlink(target);\n\t\t\t} catch (err) {\n\t\t\t\tif (!isEnoent(err)) throw err;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait fs.unlink(sidecar);\n\t\t\t} catch (err) {\n\t\t\t\tif (!isEnoent(err)) throw err;\n\t\t\t}\n\t\t\tawait pruneEmptyDirs(dir, path.dirname(target));\n\t\t\tawait pruneEmptyDirs(path.join(dir, META_DIR_NAME), path.dirname(sidecar));\n\t\t},\n\t\tasync list(bucket, opts = {}) {\n\t\t\tconst dir = resolveDir(bucket);\n\t\t\tif (dir === void 0) return {\n\t\t\t\tkeys: [],\n\t\t\t\tisTruncated: false\n\t\t\t};\n\t\t\tconst prefix = opts.prefix ?? \"\";\n\t\t\tconst maxKeys = opts.maxKeys ?? 1e3;\n\t\t\tconst token = opts.continuationToken;\n\t\t\tconst matching = (await walkKeys(dir)).filter((key) => key.startsWith(prefix)).sort().filter((key) => token === void 0 ? true : key > token);\n\t\t\tconst page = matching.slice(0, maxKeys);\n\t\t\tconst isTruncated = matching.length > maxKeys;\n\t\t\tconst last = page.at(-1);\n\t\t\treturn {\n\t\t\t\tkeys: page,\n\t\t\t\tisTruncated,\n\t\t\t\t...isTruncated && last !== void 0 ? { nextContinuationToken: last } : {}\n\t\t\t};\n\t\t}\n\t};\n}\n//#endregion\n//#region src/sigv4.ts\n/**\n* AWS SigV4 verification for the S3 wire protocol (spec § 2 auth). The payload\n* hash comes from the client — `x-amz-content-sha256` (a real hash or\n* `UNSIGNED-PAYLOAD`) for header auth, `UNSIGNED-PAYLOAD` for presign — and is\n* never re-hashed; the verifier trusts what was signed, like a real S3 endpoint.\n* Runtime engine code (`node:crypto`); not re-exported from the authoring barrel.\n*\n* Also owns `mintKeyPair` (local-dev spec § 1) — the one key-pair generator\n* both the deploy-time `S3Credentials` resource and the local dev bucket\n* emulator's credential provisioning use.\n*/\nfunction randomBytes(n) {\n\treturn crypto.getRandomValues(new Uint8Array(n));\n}\nfunction toHexUpper(bytes) {\n\treturn Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\").toUpperCase();\n}\n/** A fresh SigV4 key pair: an AKIA-prefixed id and a 40-char base64 secret. */\nfunction mintKeyPair() {\n\treturn {\n\t\taccessKeyId: `AKIA${toHexUpper(randomBytes(8))}`,\n\t\tsecretAccessKey: btoa(String.fromCharCode(...randomBytes(30)))\n\t};\n}\nconst ALGORITHM = \"AWS4-HMAC-SHA256\";\nconst UNSIGNED_PAYLOAD = \"UNSIGNED-PAYLOAD\";\nfunction sha256Hex(data) {\n\treturn createHash(\"sha256\").update(data).digest(\"hex\");\n}\nfunction hmac(key, data) {\n\treturn createHmac(\"sha256\", key).update(data).digest();\n}\n/** AWS canonical URI encoding: every byte except the unreserved set is %XX. */\nfunction awsUriEncode(value) {\n\treturn encodeURIComponent(value).replace(/[!'()*]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`).replace(/%7E/g, \"~\");\n}\nfunction parseCredential(credential) {\n\tconst parts = credential.split(\"/\");\n\tif (parts.length !== 5 || parts[4] !== \"aws4_request\") return null;\n\tconst [accessKeyId, date, region, service] = parts;\n\tif (!accessKeyId || !date || !region || !service) return null;\n\treturn {\n\t\taccessKeyId,\n\t\tdate,\n\t\tregion,\n\t\tservice\n\t};\n}\nfunction signingKey(secret, scope) {\n\treturn hmac(hmac(hmac(hmac(`AWS4${secret}`, scope.date), scope.region), scope.service), \"aws4_request\");\n}\nfunction canonicalHeaders(url, req, signedHeaders) {\n\treturn signedHeaders.map((name) => {\n\t\treturn `${name}:${(name === \"host\" ? url.host : req.headers.get(name) ?? \"\").trim().replace(/\\s+/g, \" \")}\\n`;\n\t}).join(\"\");\n}\nfunction canonicalQuery(url, exclude) {\n\tconst entries = [];\n\tfor (const [key, value] of url.searchParams.entries()) {\n\t\tif (exclude !== void 0 && key === exclude) continue;\n\t\tentries.push([awsUriEncode(key), awsUriEncode(value)]);\n\t}\n\tconst cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;\n\tentries.sort(([ak, av], [bk, bv]) => cmp(ak, bk) || cmp(av, bv));\n\treturn entries.map(([k, v]) => `${k}=${v}`).join(\"&\");\n}\nfunction stringToSign(amzDate, scope, canonicalRequest) {\n\tconst scopeString = `${scope.date}/${scope.region}/${scope.service}/aws4_request`;\n\treturn [\n\t\tALGORITHM,\n\t\tamzDate,\n\t\tscopeString,\n\t\tsha256Hex(canonicalRequest)\n\t].join(\"\\n\");\n}\nfunction signatureMatches(expected, provided) {\n\tconst a = Buffer.from(expected, \"hex\");\n\tconst b = Buffer.from(provided, \"hex\");\n\treturn a.length === b.length && a.length > 0 && timingSafeEqual(a, b);\n}\n/** `YYYYMMDDTHHMMSSZ` → epoch ms, or null when malformed. */\nfunction parseAmzDate(amzDate) {\n\tconst match = /^(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})Z$/.exec(amzDate);\n\tif (!match) return null;\n\tconst [, y, mo, d, h, mi, s] = match;\n\treturn Date.UTC(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi), Number(s));\n}\nfunction parseAuthorizationHeader(header) {\n\tif (!header.startsWith(`${ALGORITHM} `)) return null;\n\tconst rest = header.slice(17);\n\tconst fields = /* @__PURE__ */ new Map();\n\tfor (const part of rest.split(\",\")) {\n\t\tconst eq = part.indexOf(\"=\");\n\t\tif (eq === -1) continue;\n\t\tfields.set(part.slice(0, eq).trim(), part.slice(eq + 1).trim());\n\t}\n\tconst credential = fields.get(\"Credential\");\n\tconst signedHeaders = fields.get(\"SignedHeaders\");\n\tconst signature = fields.get(\"Signature\");\n\tif (!credential || !signedHeaders || !signature) return null;\n\treturn {\n\t\tcredential,\n\t\tsignedHeaders: signedHeaders.split(\";\"),\n\t\tsignature\n\t};\n}\n/** The one signing core both auth forms share: check the access key, rebuild the canonical request, derive the key, compare in constant time. */\nfunction verifySignature(req, url, credentials, params) {\n\tif (params.scope.accessKeyId !== credentials.accessKeyId) return {\n\t\tok: false,\n\t\treason: \"unknown access key\"\n\t};\n\tconst canonicalRequest = [\n\t\treq.method,\n\t\turl.pathname,\n\t\tcanonicalQuery(url, params.excludeQuery),\n\t\tcanonicalHeaders(url, req, params.signedHeaders),\n\t\tparams.signedHeaders.join(\";\"),\n\t\tparams.payloadHash\n\t].join(\"\\n\");\n\treturn signatureMatches(hmac(signingKey(credentials.secretAccessKey, params.scope), stringToSign(params.amzDate, params.scope, canonicalRequest)).toString(\"hex\"), params.signature) ? { ok: true } : {\n\t\tok: false,\n\t\treason: \"signature mismatch\"\n\t};\n}\nfunction verifyHeader(req, url, credentials) {\n\tconst auth = parseAuthorizationHeader(req.headers.get(\"authorization\") ?? \"\");\n\tif (!auth) return {\n\t\tok: false,\n\t\treason: \"malformed Authorization header\"\n\t};\n\tconst scope = parseCredential(auth.credential);\n\tif (!scope) return {\n\t\tok: false,\n\t\treason: \"malformed credential scope\"\n\t};\n\tconst amzDate = req.headers.get(\"x-amz-date\");\n\tif (!amzDate) return {\n\t\tok: false,\n\t\treason: \"missing x-amz-date\"\n\t};\n\tconst payloadHash = req.headers.get(\"x-amz-content-sha256\");\n\tif (!payloadHash) return {\n\t\tok: false,\n\t\treason: \"missing x-amz-content-sha256\"\n\t};\n\treturn verifySignature(req, url, credentials, {\n\t\tscope,\n\t\tamzDate,\n\t\tsignedHeaders: auth.signedHeaders,\n\t\tpayloadHash,\n\t\tsignature: auth.signature\n\t});\n}\nfunction verifyPresigned(req, url, credentials, now) {\n\tconst q = url.searchParams;\n\tif (q.get(\"X-Amz-Algorithm\") !== ALGORITHM) return {\n\t\tok: false,\n\t\treason: \"unsupported presign algorithm\"\n\t};\n\tconst credentialRaw = q.get(\"X-Amz-Credential\");\n\tconst amzDate = q.get(\"X-Amz-Date\");\n\tconst expiresRaw = q.get(\"X-Amz-Expires\");\n\tconst signedHeadersRaw = q.get(\"X-Amz-SignedHeaders\");\n\tconst signature = q.get(\"X-Amz-Signature\");\n\tif (!credentialRaw || !amzDate || !expiresRaw || !signedHeadersRaw || !signature) return {\n\t\tok: false,\n\t\treason: \"incomplete presign parameters\"\n\t};\n\tconst scope = parseCredential(credentialRaw);\n\tif (!scope) return {\n\t\tok: false,\n\t\treason: \"malformed credential scope\"\n\t};\n\tconst signedAt = parseAmzDate(amzDate);\n\tconst expires = Number(expiresRaw);\n\tif (signedAt === null || !Number.isFinite(expires)) return {\n\t\tok: false,\n\t\treason: \"malformed presign date\"\n\t};\n\tif (now.getTime() > signedAt + expires * 1e3) return {\n\t\tok: false,\n\t\treason: \"presign expired\"\n\t};\n\treturn verifySignature(req, url, credentials, {\n\t\tscope,\n\t\tamzDate,\n\t\tsignedHeaders: signedHeadersRaw.split(\";\"),\n\t\tpayloadHash: UNSIGNED_PAYLOAD,\n\t\tsignature,\n\t\texcludeQuery: \"X-Amz-Signature\"\n\t});\n}\n/**\n* Verify a request's SigV4 signature against a single credential pair. Picks\n* the presigned form when `X-Amz-Signature` is present, otherwise the\n* `Authorization`-header form. `now` is injectable for deterministic\n* expiry tests.\n*/\nfunction verifyRequest(req, credentials, now = /* @__PURE__ */ new Date()) {\n\tconst url = new URL(req.url);\n\tif (url.searchParams.has(\"X-Amz-Signature\")) return verifyPresigned(req, url, credentials, now);\n\tif (req.headers.has(\"authorization\")) return verifyHeader(req, url, credentials);\n\treturn {\n\t\tok: false,\n\t\treason: \"unsigned request\"\n\t};\n}\n//#endregion\n//#region src/handler.ts\nconst DEFAULT_CONTENT_TYPE = \"application/octet-stream\";\n/** Path-style: `/{bucket}/{key…}`. Each segment is percent-decoded. */\nfunction parseTarget(url) {\n\tconst segments = url.pathname.split(\"/\").filter((s) => s.length > 0);\n\tif (segments.length === 0) return null;\n\tconst [bucket, ...keyParts] = segments;\n\treturn {\n\t\tbucket: decodeURIComponent(bucket ?? \"\"),\n\t\tkey: keyParts.map(decodeURIComponent).join(\"/\")\n\t};\n}\n/** `bytes=a-b` (inclusive) or `bytes=a-` (open-ended). Null when absent/malformed. */\nfunction parseRange(header) {\n\tif (!header) return null;\n\tconst match = /^bytes=(\\d+)-(\\d*)$/.exec(header.trim());\n\tif (!match) return null;\n\tconst start = Number(match[1]);\n\treturn match[2] ? {\n\t\tstart,\n\t\tend: Number(match[2])\n\t} : { start };\n}\nfunction xmlEscape(value) {\n\treturn value.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\").replace(/\"/g, \""\").replace(/'/g, \"'\");\n}\nfunction listXml(bucket, prefix, maxKeys, result) {\n\tconst contents = result.keys.map((k) => `<Contents><Key>${xmlEscape(k)}</Key></Contents>`).join(\"\");\n\tconst next = result.isTruncated && result.nextContinuationToken !== void 0 ? `<NextContinuationToken>${xmlEscape(result.nextContinuationToken)}</NextContinuationToken>` : \"\";\n\treturn `<?xml version=\"1.0\" encoding=\"UTF-8\"?><ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>${xmlEscape(bucket)}</Name><Prefix>${xmlEscape(prefix)}</Prefix><KeyCount>${result.keys.length}</KeyCount><MaxKeys>${maxKeys}</MaxKeys><IsTruncated>${result.isTruncated}</IsTruncated>` + contents + next + \"</ListBucketResult>\";\n}\nconst DEFAULT_MAX_KEYS$1 = 1e3;\nasync function handleList(store, bucket, url) {\n\tconst prefix = url.searchParams.get(\"prefix\") ?? \"\";\n\tconst continuationToken = url.searchParams.get(\"continuation-token\");\n\tconst maxKeysRaw = url.searchParams.get(\"max-keys\");\n\tconst maxKeys = maxKeysRaw !== null && Number.isFinite(Number(maxKeysRaw)) ? Number(maxKeysRaw) : DEFAULT_MAX_KEYS$1;\n\tconst result = await store.list(bucket, {\n\t\tprefix,\n\t\tmaxKeys,\n\t\t...continuationToken !== null ? { continuationToken } : {}\n\t});\n\treturn new Response(listXml(bucket, prefix, maxKeys, result), {\n\t\tstatus: 200,\n\t\theaders: { \"content-type\": \"application/xml\" }\n\t});\n}\n/** aws-chunked / flexible-checksum PUTs frame the body as chunks + a trailer (signalled by `x-amz-content-sha256: STREAMING-…` or `content-encoding: aws-chunked`); the seed signature still verifies, so reject them (501) rather than store the raw framing as the object bytes. Decoding is out of scope. */\nfunction isStreamingPut(req) {\n\tconst contentSha = req.headers.get(\"x-amz-content-sha256\") ?? \"\";\n\tconst contentEncoding = req.headers.get(\"content-encoding\") ?? \"\";\n\treturn contentSha.startsWith(\"STREAMING-\") || contentEncoding.split(\",\").some((e) => e.trim() === \"aws-chunked\");\n}\nasync function handlePut(store, t, req) {\n\tif (isStreamingPut(req)) return new Response(\"aws-chunked / flexible checksums not supported; set requestChecksumCalculation: 'WHEN_REQUIRED'\", { status: 501 });\n\tconst body = new Uint8Array(await req.arrayBuffer());\n\tconst contentType = req.headers.get(\"content-type\") ?? DEFAULT_CONTENT_TYPE;\n\tconst { etag } = await store.put(t.bucket, t.key, body, { contentType });\n\treturn new Response(null, {\n\t\tstatus: 200,\n\t\theaders: { etag }\n\t});\n}\n/** The etag/content-type/content-length/accept-ranges headers GET and HEAD share — `contentLength` is the slice length for GET, the total object size for HEAD. */\nfunction metaHeaders(meta) {\n\treturn new Headers({\n\t\tetag: meta.etag,\n\t\t\"content-type\": meta.contentType,\n\t\t\"content-length\": String(meta.contentLength),\n\t\t\"accept-ranges\": \"bytes\"\n\t});\n}\nasync function handleGet(store, t, req) {\n\tconst range = parseRange(req.headers.get(\"range\"));\n\tconst object = await store.get(t.bucket, t.key, range ? { range } : void 0);\n\tif (!object) return new Response(null, { status: 404 });\n\tconst headers = metaHeaders({\n\t\tetag: object.etag,\n\t\tcontentType: object.contentType,\n\t\tcontentLength: object.bytes.byteLength\n\t});\n\tif (!range) return new Response(object.bytes, {\n\t\tstatus: 200,\n\t\theaders\n\t});\n\tif (range.start >= object.size && object.size > 0) return new Response(null, {\n\t\tstatus: 416,\n\t\theaders: { \"content-range\": `bytes */${object.size}` }\n\t});\n\tconst end = range.end === void 0 ? object.size - 1 : Math.min(range.end, object.size - 1);\n\theaders.set(\"content-range\", `bytes ${range.start}-${end}/${object.size}`);\n\treturn new Response(object.bytes, {\n\t\tstatus: 206,\n\t\theaders\n\t});\n}\nasync function handleHead(store, t) {\n\tconst meta = await store.head(t.bucket, t.key);\n\tif (!meta) return new Response(null, { status: 404 });\n\treturn new Response(null, {\n\t\tstatus: 200,\n\t\theaders: metaHeaders({\n\t\t\tetag: meta.etag,\n\t\t\tcontentType: meta.contentType,\n\t\t\tcontentLength: meta.size\n\t\t})\n\t});\n}\nasync function handleDelete(store, t) {\n\tawait store.delete(t.bucket, t.key);\n\treturn new Response(null, { status: 204 });\n}\nfunction createS3Handler(opts) {\n\tconst { store, credentials } = opts;\n\treturn async (req) => {\n\t\tif (!verifyRequest(req, credentials).ok) return new Response(null, { status: 403 });\n\t\tconst url = new URL(req.url);\n\t\tconst target = parseTarget(url);\n\t\tif (!target) return new Response(null, { status: 400 });\n\t\tif (req.method === \"GET\" && url.searchParams.get(\"list-type\") === \"2\" && target.key === \"\") return handleList(store, target.bucket, url);\n\t\tif (target.key === \"\") return new Response(null, { status: 400 });\n\t\tswitch (req.method) {\n\t\t\tcase \"PUT\": return handlePut(store, target, req);\n\t\t\tcase \"GET\": return handleGet(store, target, req);\n\t\t\tcase \"HEAD\": return handleHead(store, target);\n\t\t\tcase \"DELETE\": return handleDelete(store, target);\n\t\t\tdefault: return new Response(null, { status: 405 });\n\t\t}\n\t};\n}\n//#endregion\n//#region src/memory-store.ts\n/**\n* An in-memory `ObjectStore` for the protocol tests — the same contract the\n* Postgres store (D3) implements. Test-only; never wired into a deployed\n* service. Not re-exported from the authoring barrel.\n*/\nconst DEFAULT_MAX_KEYS = 1e3;\nfunction etagOf(bytes) {\n\treturn `\"${createHash(\"sha256\").update(bytes).digest(\"hex\")}\"`;\n}\nvar MemoryObjectStore = class {\n\tentries = /* @__PURE__ */ new Map();\n\tid(bucket, key) {\n\t\treturn `${bucket}\\x00${key}`;\n\t}\n\tasync put(bucket, key, bytes, opts = {}) {\n\t\tconst copy = bytes.slice();\n\t\tconst etag = etagOf(copy);\n\t\tthis.entries.set(this.id(bucket, key), {\n\t\t\tbytes: copy,\n\t\t\tetag,\n\t\t\tcontentType: opts.contentType ?? \"application/octet-stream\"\n\t\t});\n\t\treturn { etag };\n\t}\n\tasync get(bucket, key, opts = {}) {\n\t\tconst entry = this.entries.get(this.id(bucket, key));\n\t\tif (!entry) return null;\n\t\tconst size = entry.bytes.byteLength;\n\t\tif (opts.range) {\n\t\t\tconst start = opts.range.start;\n\t\t\tconst end = opts.range.end === void 0 ? size - 1 : Math.min(opts.range.end, size - 1);\n\t\t\treturn {\n\t\t\t\tbytes: start > end ? /* @__PURE__ */ new Uint8Array(0) : entry.bytes.slice(start, end + 1),\n\t\t\t\tetag: entry.etag,\n\t\t\t\tcontentType: entry.contentType,\n\t\t\t\tsize\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tbytes: entry.bytes.slice(),\n\t\t\tetag: entry.etag,\n\t\t\tcontentType: entry.contentType,\n\t\t\tsize\n\t\t};\n\t}\n\tasync head(bucket, key) {\n\t\tconst entry = this.entries.get(this.id(bucket, key));\n\t\tif (!entry) return null;\n\t\treturn {\n\t\t\tetag: entry.etag,\n\t\t\tsize: entry.bytes.byteLength,\n\t\t\tcontentType: entry.contentType\n\t\t};\n\t}\n\tasync delete(bucket, key) {\n\t\tthis.entries.delete(this.id(bucket, key));\n\t}\n\tasync list(bucket, opts = {}) {\n\t\tconst prefix = opts.prefix ?? \"\";\n\t\tconst maxKeys = opts.maxKeys ?? DEFAULT_MAX_KEYS;\n\t\tconst token = opts.continuationToken;\n\t\tconst prefixHit = `${bucket}\\x00${prefix}`;\n\t\tconst matching = [...this.entries.keys()].filter((id) => id.startsWith(prefixHit)).map((id) => id.slice(bucket.length + 1)).sort().filter((key) => token === void 0 ? true : key > token);\n\t\tconst page = matching.slice(0, maxKeys);\n\t\tconst isTruncated = matching.length > maxKeys;\n\t\tconst last = page.at(-1);\n\t\treturn {\n\t\t\tkeys: page,\n\t\t\tisTruncated,\n\t\t\t...isTruncated && last !== void 0 ? { nextContinuationToken: last } : {}\n\t\t};\n\t}\n};\n//#endregion\nexport { MemoryObjectStore, createS3Handler, fsStore, mintKeyPair, verifyRequest };\n\n//# sourceMappingURL=index.mjs.map","import { a as isEnvParamSource, c as paramName, n as secretName, o as isGeneratedParamSource } from \"./secret-Dgyg1WyG.mjs\";\nimport { i as withConnectionRetry, n as normalizeSslMode } from \"./pg-connection-3qou2HW9.mjs\";\nimport { inputManifest, isSecretSource, paramManifest } from \"@internal/core\";\nimport { blindCast } from \"@internal/foundation/casts\";\nimport { ManagementClient, deleteBranch, deleteProject, fromEnv, managementClientLayer, resolveContainer } from \"@internal/lowering\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport { Resource } from \"alchemy\";\nimport * as Provider from \"alchemy/Provider\";\nimport { loadConfig } from \"@prisma/orm-toolchain/config-loader\";\nimport { resolve } from \"pathe\";\nimport { createPostgresControlClient } from \"@prisma/orm-postgres/control\";\nimport { readRef } from \"@prisma/orm-toolchain/migration-tools/refs\";\nimport { APP_SPACE_ID, readContractSpaceHeadRef, spaceMigrationDirectory, spaceRefsDirectory } from \"@prisma/orm-toolchain/migration-tools/spaces\";\nimport pg from \"pg\";\nimport { mintKeyPair } from \"@internal/s3-protocol\";\n//#region src/container.ts\nconst PRISMA_CLOUD_EXTENSION_ID = \"@prisma/composer-prisma-cloud\";\n/** Accepts exactly what Alchemy's own `--stage` validation accepts (pinned 2.0.0-beta.59, `Cli/commands/_shared.ts`), rewritten without overlapping quantifiers so it cannot backtrack catastrophically. Asserted before a Branch id is exposed as a stage. */\nconst ALCHEMY_STAGE_PATTERN = /^[a-z0-9][-_a-z0-9]*$/i;\nfunction invalidAlchemyStageError(branchId) {\n\treturn /* @__PURE__ */ new Error(`${PRISMA_CLOUD_EXTENSION_ID}: the resolved Branch id \"${branchId}\" does not match Alchemy's stage pattern ^[a-z0-9][-_a-z0-9]*\\$ (case-insensitive) — it cannot scope the deploy state. The platform should never return such an id; contact support.`);\n}\nvar PrismaCloudContainer = class {\n\tinput;\n\tprojectId;\n\tbranchId;\n\tdefaultBranchId;\n\tbranchless;\n\t/** The deterministic Alchemy stage (ContainerInstance SPI): the stage Branch's id, or the default Branch's id for the default stage. Absent only for the dev container, which resolves no Branch. */\n\talchemyStage;\n\tconstructor(input, projectId, branchId, defaultBranchId, branchless = false) {\n\t\tthis.input = input;\n\t\tthis.projectId = projectId;\n\t\tthis.branchId = branchId;\n\t\tthis.defaultBranchId = defaultBranchId;\n\t\tthis.branchless = branchless;\n\t\tconst stageBranchId = branchId ?? defaultBranchId;\n\t\tif (stageBranchId !== void 0 && !ALCHEMY_STAGE_PATTERN.test(stageBranchId)) throw invalidAlchemyStageError(stageBranchId);\n\t\tthis.alchemyStage = stageBranchId;\n\t}\n\tserialize() {\n\t\treturn JSON.stringify({\n\t\t\tinput: this.input,\n\t\t\tprojectId: this.projectId,\n\t\t\t...this.branchId !== void 0 ? { branchId: this.branchId } : {},\n\t\t\t...this.defaultBranchId !== void 0 ? { defaultBranchId: this.defaultBranchId } : {},\n\t\t\t...this.branchless ? { branchless: true } : {}\n\t\t});\n\t}\n};\n/** `instanceof` — parent-side instances and child-side deserialized instances are both constructed by this module. */\nfunction isPrismaCloudContainer(value) {\n\treturn value instanceof PrismaCloudContainer;\n}\n/** Narrow-or-throw for hook inputs. */\nfunction prismaCloudContainerOf(value) {\n\tif (!isPrismaCloudContainer(value)) throw new Error(\"the Prisma Cloud container was not resolved — the extension's container descriptor did not run.\");\n\treturn value;\n}\nfunction isRecord(value) {\n\treturn typeof value === \"object\" && value !== null;\n}\nfunction invalidPayloadError(reason) {\n\treturn /* @__PURE__ */ new Error(`${PRISMA_CLOUD_EXTENSION_ID}: invalid container transport payload — ${reason}.`);\n}\n/**\n* Reconstructs a `PrismaCloudContainer` from `serialize()`'s JSON output —\n* real narrowing, no casts. Exported so `dev/container.ts`'s\n* `devContainerDescriptor` can reuse it verbatim (local-dev spec § 5) — the\n* dev and deploy container descriptors deserialize the identical wire shape.\n*/\nfunction deserialize(serialized) {\n\tlet parsed;\n\ttry {\n\t\tparsed = JSON.parse(serialized);\n\t} catch (error) {\n\t\tthrow invalidPayloadError(`not valid JSON (${error instanceof Error ? error.message : String(error)})`);\n\t}\n\tif (!isRecord(parsed)) throw invalidPayloadError(\"not an object\");\n\tconst input = parsed[\"input\"];\n\tif (!isRecord(input)) throw invalidPayloadError(\"\\\"input\\\" is not an object\");\n\tconst appName = input[\"appName\"];\n\tif (typeof appName !== \"string\") throw invalidPayloadError(\"\\\"input.appName\\\" is not a string\");\n\tconst stage = input[\"stage\"];\n\tif (stage !== void 0 && typeof stage !== \"string\") throw invalidPayloadError(\"\\\"input.stage\\\" is not a string or absent\");\n\tconst projectId = parsed[\"projectId\"];\n\tif (typeof projectId !== \"string\") throw invalidPayloadError(\"\\\"projectId\\\" is not a string\");\n\tconst branchId = parsed[\"branchId\"];\n\tif (branchId !== void 0 && typeof branchId !== \"string\") throw invalidPayloadError(\"\\\"branchId\\\" is not a string or absent\");\n\tconst defaultBranchId = parsed[\"defaultBranchId\"];\n\tif (defaultBranchId !== void 0 && typeof defaultBranchId !== \"string\") throw invalidPayloadError(\"\\\"defaultBranchId\\\" is not a string or absent\");\n\tconst branchless = parsed[\"branchless\"];\n\tif (branchless !== void 0 && typeof branchless !== \"boolean\") throw invalidPayloadError(\"\\\"branchless\\\" is not a boolean or absent\");\n\treturn new PrismaCloudContainer({\n\t\tappName,\n\t\tstage\n\t}, projectId, branchId, defaultBranchId, branchless ?? false);\n}\nconst workspaceRequiredError = () => /* @__PURE__ */ new Error(\"environment variable PRISMA_WORKSPACE_ID is required.\");\nconst tokenRequiredError = () => /* @__PURE__ */ new Error(\"environment variable PRISMA_SERVICE_TOKEN is required.\");\n/**\n* The caller's workspace id, or — only when the caller passed no credentials\n* at all — the env protocol, which is what the alchemy child process and\n* existing programmatic hosts have set.\n*/\nfunction requireWorkspaceId(credentials) {\n\tconst workspaceId = credentials === void 0 ? process.env[\"PRISMA_WORKSPACE_ID\"] : credentials.workspaceId;\n\tif (workspaceId === void 0 || workspaceId.length === 0) throw workspaceRequiredError();\n\treturn workspaceId;\n}\nfunction requireTokenUnlessInjected(client) {\n\tif (client === void 0 && (process.env[\"PRISMA_SERVICE_TOKEN\"] ?? \"\").length === 0) throw tokenRequiredError();\n}\nfunction clientFor(credentials, deps) {\n\treturn credentials?.client ?? deps?.client;\n}\n/** Runs against the injected client when there is one, and against an env-built one otherwise. */\nfunction runWithClient(program, client) {\n\treturn Effect.runPromise(client !== void 0 ? program.pipe(Effect.provideService(ManagementClient, client)) : program.pipe(Effect.provide(managementClientLayer().pipe(Layer.provide(fromEnv())))));\n}\nasync function ensureContainer(input, credentials, deps) {\n\tconst workspaceId = requireWorkspaceId(credentials);\n\tconst client = clientFor(credentials, deps);\n\trequireTokenUnlessInjected(client);\n\tconst outcome = await runWithClient(resolveContainer({\n\t\tworkspaceId,\n\t\tappName: input.appName,\n\t\t...input.stage !== void 0 ? { stage: input.stage } : {},\n\t\tensure: true\n\t}).pipe(Effect.map((c) => ({\n\t\tok: true,\n\t\tcontainer: c\n\t})), Effect.catchTag(\"PrismaApiError\", (e) => Effect.succeed({\n\t\tok: false,\n\t\tmessage: `Prisma Management API error resolving containers: ${e.message}.`\n\t}))), client);\n\tif (!outcome.ok) throw new Error(outcome.message);\n\treturn new PrismaCloudContainer(input, outcome.container.projectId, outcome.container.branchId, outcome.container.defaultBranchId);\n}\nasync function locateContainer(input, credentials, deps) {\n\tconst workspaceId = requireWorkspaceId(credentials);\n\tconst client = clientFor(credentials, deps);\n\trequireTokenUnlessInjected(client);\n\tconst outcome = await runWithClient(resolveContainer({\n\t\tworkspaceId,\n\t\tappName: input.appName,\n\t\t...input.stage !== void 0 ? { stage: input.stage } : {},\n\t\tensure: false\n\t}).pipe(Effect.map((c) => ({\n\t\tok: true,\n\t\tcontainer: c\n\t})), Effect.catchTag(\"ContainerNotFoundError\", () => Effect.succeed({ ok: false })), Effect.catchTag(\"PrismaApiError\", (e) => Effect.fail(/* @__PURE__ */ new Error(`Prisma Management API error resolving containers: ${e.message}.`)))), client);\n\tif (!outcome.ok) return void 0;\n\treturn new PrismaCloudContainer(input, outcome.container.projectId, outcome.container.branchId, outcome.container.defaultBranchId);\n}\n/**\n* Soft-deletes a named stage's Branch after a successful `alchemy destroy`\n* has removed its members — the Management API refuses to delete a Branch\n* that still has live members.\n*/\nasync function removeStageBranch(branchId, credentials, deps) {\n\tconst client = clientFor(credentials, deps);\n\trequireTokenUnlessInjected(client);\n\tconst outcome = await runWithClient(deleteBranch(branchId).pipe(Effect.map(() => ({ ok: true })), Effect.catchTag(\"PrismaApiError\", (e) => Effect.succeed({\n\t\tok: false,\n\t\tmessage: `Failed to delete the stage Branch: ${e.message}.`\n\t}))), client);\n\tif (!outcome.ok) throw new Error(outcome.message);\n}\n/**\n* Best-effort cleanup after a successful `--production` destroy: removes\n* the app's Project so hand-run stacks don't accumulate as empty Projects\n* (they eventually hit the workspace's plan limit). Unlike `removeStageBranch`,\n* this never throws: the destroy itself already succeeded, and the API's own\n* 400 (\"still has dependencies\") is the only check that matters — failing\n* the command over a cleanup step would be worse than leaving a Project shell.\n*/\nasync function removeAppProject(projectId, credentials, deps) {\n\tconst client = clientFor(credentials, deps);\n\tif (client === void 0 && (process.env[\"PRISMA_SERVICE_TOKEN\"] ?? \"\").length === 0) {\n\t\tconsole.warn(`Skipped removing the Project (${projectId}): PRISMA_SERVICE_TOKEN is not set.`);\n\t\treturn;\n\t}\n\tconst outcome = await runWithClient(deleteProject(projectId).pipe(Effect.map(() => ({ ok: true })), Effect.catchTag(\"PrismaApiError\", (e) => Effect.succeed({\n\t\tok: false,\n\t\terror: e\n\t}))), client);\n\tif (outcome.ok) {\n\t\tconsole.log(`Removed the Project (${projectId}) — nothing was left in it.`);\n\t\treturn;\n\t}\n\tif (outcome.error.status === 400) {\n\t\tconsole.log(`Kept the Project (${projectId}) — it still has another stage's resources.`);\n\t\treturn;\n\t}\n\tconsole.warn(`Could not remove the Project (${projectId}) after destroy: ${outcome.error.message}.`);\n}\nfunction containerDescriptor(deps) {\n\treturn {\n\t\tensure: (input, credentials) => ensureContainer(input, credentials, deps),\n\t\tlocate: (input, credentials) => locateContainer(input, credentials, deps),\n\t\tremove: (instance, credentials) => instance.input.stage !== void 0 ? removeStageBranch(instance.branchId ?? missingBranchId(instance), credentials, deps) : removeAppProject(instance.projectId, credentials, deps),\n\t\tdeserialize\n\t};\n}\n/** Defensive: a named-stage container always resolves a Branch together with its stage — `ensure`/`locate`/`deserialize` never produce one without the other. */\nfunction missingBranchId(instance) {\n\tthrow new Error(`${PRISMA_CLOUD_EXTENSION_ID}: a named-stage (\"${instance.input.stage}\") container instance is missing its branchId — this is a bug in ensure/locate/deserialize.`);\n}\n//#endregion\n//#region src/generated-param-resource.ts\n/**\n* The `GeneratedParam` Alchemy resource — generates a random value ONCE at\n* create and keeps it STABLE across deploys, so an unchanged service no-ops on\n* redeploy. The value is `bytes` random bytes produced with the Web Crypto\n* global (`crypto.getRandomValues` — no `node:` import, matching this package's\n* runtime-coupling invariant), base64-encoded, and persisted in Alchemy state;\n* on every later apply the provider returns the persisted attributes\n* (`reconcile`'s `output`) unchanged — the same way `S3Credentials` keeps its\n* pair stable. Changing `bytes` on an existing resource KEEPS the old value\n* (reconcile short-circuits on the persisted output); rotation is\n* destroy/recreate.\n*\n* One resource per `generatedParam()`-bound input leaf, provisioned by the\n* compute descriptor's serialize step; the resource id derives from the input\n* document row key and the leaf path, so the value is stable per service+leaf.\n*\n* Deploy-time only: imports `alchemy`. Imported by `control/extension.ts` and\n* tests, never by `index.ts` / the authoring entry.\n*/\n/** The `GeneratedParam` resource constructor — `yield* GeneratedParam(id, { bytes })` in the lowering. */\nconst GeneratedParam = Resource(\"PrismaCloud.GeneratedParam\");\n/** A fresh generated value: `bytes` random bytes, base64. */\nfunction generateValue(bytes) {\n\tconst random = crypto.getRandomValues(new Uint8Array(bytes));\n\treturn { value: btoa(String.fromCharCode(...random)) };\n}\n/**\n* The `GeneratedParam` provider service. `reconcile` runs for create and\n* update; it returns the persisted `output` when present (a redeploy reuses the\n* stored value — the no-op property, and the reason a `bytes` change does not\n* re-generate) and generates a fresh value only on first create. Nothing to\n* enumerate (`list` → `[]`) or tear down (`delete` → no-op; the value lives\n* only in state). Exported so tests can drive it directly.\n*/\nconst generatedParamProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ news, output }) => Effect.sync(() => output ?? generateValue(news.bytes)),\n\tdelete: () => Effect.void\n};\n/** The `GeneratedParam` provider layer — merged into the extension descriptor's `providers()`. */\nconst GeneratedParamProvider = () => Provider.effect(GeneratedParam, Effect.succeed(generatedParamProviderService));\n//#endregion\n//#region src/orm-config.ts\n/**\n* Resolves a `postgres` resource's `prisma.config.ts` path to the\n* project facts the deploy needs (ADR-0022, slice 2): the on-disk migrations\n* directory the control client's `migrate` reads, and the declared\n* extension packs. Deploy-time only: loads PN's config (via c12) and applies\n* PN's own convention — `migrations.dir`, or the default `migrations/`,\n* relative to the config file's directory (mirrors the CLI's\n* `resolveMigrationPaths`). Imported by `control.ts` + tests, never by\n* `index.ts` / the `./orm` authoring entry.\n*\n* `pathe` (not `node:path`) does the path work so the shipped source carries no\n* `node:` import — the same discipline `control.ts` already follows by\n* delegating fs/tar to `@internal/lowering` (invariant 5).\n*/\n/** Loads the config at `configPath` and resolves the facts the deploy consumes. */\nasync function resolveOrmConfig(configPath) {\n\tconst loaded = await loadConfig(configPath);\n\tif (!loaded.ok) throw loaded.failure;\n\tconst config = loaded.value.config;\n\treturn {\n\t\tmigrationsDir: resolve(configPath, \"..\", config.migrations?.dir ?? \"migrations\"),\n\t\textensionPacks: blindCast(config.extensions ?? [])\n\t};\n}\n/**\n* The pack-head identity entries the `OrmMigration` resource folds into its\n* diff key: `\"<packId>:<headRefHash>\"` — each pack's contract-space head ref,\n* identified by its storage hash — sorted by pack id, so a pack upgrade (or a\n* pack added/removed) produces a distinct deploy step. A pack without a\n* `contractSpace` contributes `\"-\"` for its head — it declares no migratable\n* space, but its presence still belongs in the key.\n*/\nfunction packHeadRefHashes(packs) {\n\treturn packs.map((pack) => `${pack.id}:${pack.contractSpace?.headRef.hash ?? \"-\"}`).sort();\n}\n//#endregion\n//#region src/orm-migrate.ts\n/**\n* The Prisma ORM migration step of the deploy lowering (ADR-0022, slice 2) —\n* the safety-critical decision that brings a live database to a target REF\n* using ONLY Prisma ORM's authored migrations.\n*\n* Deploy-time only: this module imports `@prisma/orm-postgres/control` (which\n* transitively pulls PN's control/migration machinery + `pg`). It is imported\n* by the deploy descriptors and this package's tests, NEVER by `index.ts` / the\n* `./orm` authoring entry — so it never lands in an app runtime bundle\n* (the index-isolation invariant holds).\n*\n* The target is a ref `{ hash, invariants }` — not a bare `storageHash`. A\n* ref's `invariants` are named postconditions established by `data`-class\n* migration steps (e.g. a backfill), recorded monotonically on the live\n* marker. Keying on the hash alone would make a pure data-invariant change an\n* A→A self-edge the deploy wrongly skips. The decision, given the live marker\n* and the target ref (see {@link decideMigrationAction}):\n* - marker at ref.hash AND ref.invariants ⊆ marker.invariants → no-op\n* - otherwise → `migrate`\n*\n* Replay-only (ADR-0022 as revised): the pipeline replays what was authored,\n* it never authors. A fresh database (no marker) is not special — its start\n* point is empty and `migrate` walks the AUTHORED graph from empty to the\n* target, so the first deploy applies the committed baseline like any other\n* migration. No synthesis of any kind runs at deploy: never `dbInit` (schema\n* synthesized from the contract) and never `dbUpdate` (synthesized\n* diff-and-apply). A missing authored path (`MIGRATION_PATH_NOT_FOUND`) is a\n* structured refusal whose message names the two exits — `prisma db update`\n* for local iteration, `prisma contract emit && prisma migration plan` to\n* author the path for shipping. A runner failure fails the deploy as a typed\n* `OrmMigrationError` (not swallowed). PN applies each migration in its own\n* transaction, so a failed apply is atomic and resume-safe — the marker and\n* schema are left as the last committed step.\n*/\n/** A deploy-failing migration error — surfaced, never swallowed. */\nvar OrmMigrationError = class extends Error {\n\tcode;\n\t/** PN's structured explanation, when present. */\n\twhy;\n\tconstructor(code, summary, why) {\n\t\tsuper(`Prisma ORM migrate (${code}): ${summary}`);\n\t\tthis.name = \"OrmMigrationError\";\n\t\tthis.code = code;\n\t\tthis.why = why;\n\t}\n};\n/**\n* The replay-only refusal for a missing authored path. The pipeline never\n* authors schema, so the only fix is to bring one of the two sides along:\n* update the database directly (local iteration) or author and commit the\n* missing migrations (shipping). The same message serves a deploy against a\n* cloud database and a `dev` run against the local emulator database.\n*/\nfunction noPathRefusal(summary, markerHashBefore, aggregate) {\n\treturn `${aggregate ? \"The committed migrations/ directory has no authored path to the target in every declared migration space\" : markerHashBefore === null ? \"The database carries no schema marker and the committed migrations/ directory has no authored path from empty to the target\" : `The committed migrations/ directory has no authored path from the database's current schema (${markerHashBefore}) to the target`} — the deploy pipeline only replays authored migrations, it never creates schema itself. Iterating locally? Bring the database along with \\`prisma db update\\`. Shipping? Author the migration path — \\`prisma contract emit && prisma migration plan --name <slug>\\` (baseline first if the migration graph is empty) — and commit migrations/. (${summary})`;\n}\n/**\n* The target `storageHash` a contract heads to — `contractJson.storage.storageHash`.\n* Read defensively: `contractJson` crosses the boundary as `unknown`.\n*/\nfunction targetStorageHash(contractJson) {\n\tif (typeof contractJson === \"object\" && contractJson !== null && \"storage\" in contractJson) {\n\t\tconst storage = contractJson.storage;\n\t\tif (typeof storage === \"object\" && storage !== null && \"storageHash\" in storage) {\n\t\t\tconst hash = storage.storageHash;\n\t\t\tif (typeof hash === \"string\" && hash.length > 0) return hash;\n\t\t}\n\t}\n\tthrow new OrmMigrationError(\"CONTRACT_INVALID\", \"the contract has no storage.storageHash — cannot determine the target schema version\");\n}\n/**\n* Resolve the deploy's target ref from the migrations dir.\n*\n* - `targetRef` named: read `migrations/app/refs/<name>.json` — fail loudly\n* (`TARGET_REF_NOT_FOUND`) when the ref doesn't exist or can't be parsed.\n* - Default: the app space's head. PN synthesizes the app head from the\n* emitted contract — `{ hash: contract.storage.storageHash, invariants: [] }`\n* (`contract emit` writes no app-space `refs/head.json` today; extension\n* spaces have one on disk). When a future PN version does emit one, the\n* on-disk `head.json` wins — read via `readContractSpaceHeadRef`, exactly\n* the loader PN's own migrate uses.\n*/\nasync function resolveTargetRef(migrationsDir, contractJson, targetRef) {\n\tif (targetRef !== void 0) {\n\t\tconst refsDir = spaceRefsDirectory(spaceMigrationDirectory(migrationsDir, APP_SPACE_ID));\n\t\ttry {\n\t\t\tconst ref = await readRef(refsDir, targetRef);\n\t\t\treturn {\n\t\t\t\thash: ref.hash,\n\t\t\t\tinvariants: ref.invariants\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new OrmMigrationError(\"TARGET_REF_NOT_FOUND\", `targetRef \"${targetRef}\" could not be read from ${refsDir}`, error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\tconst head = await readContractSpaceHeadRef(migrationsDir, APP_SPACE_ID);\n\tif (head !== null) return {\n\t\thash: head.hash,\n\t\tinvariants: head.invariants\n\t};\n\treturn {\n\t\thash: targetStorageHash(contractJson),\n\t\tinvariants: []\n\t};\n}\n/**\n* The pure migration decision, mirroring PN's own verifier: the database is\n* AT the target when the marker's hash equals the ref's hash AND every ref\n* invariant is on the marker (marker invariants are monotonic). Anything\n* else — different hash, missing invariant (the A→A data-only self-edge),\n* or a fresh DB (whose start point is empty) — walks the authored graph via\n* `migrate`. The pipeline never synthesizes.\n*/\nfunction decideMigrationAction(marker, ref) {\n\tconst markerInvariants = new Set(marker?.invariants ?? []);\n\tconst missing = ref.invariants.filter((id) => !markerInvariants.has(id));\n\tif (marker !== null && marker.storageHash === ref.hash && missing.length === 0) return \"noop\";\n\treturn \"migrate\";\n}\n/**\n* Bring the database at `url` to the target ref via PN's authored migrations.\n* Reads the live marker, decides no-op / migrate\n* ({@link decideMigrationAction}), applies, and throws a typed\n* {@link OrmMigrationError} on a no-path or runner failure. `migrationsDir` is\n* the on-disk migrations root and `ref` the resolved target\n* ({@link resolveTargetRef} — both resolved by the lowering, which also keys\n* the OrmMigration resource on them). `refName` (the resource's `targetRef`,\n* when set) is threaded into `migrate` so PN targets the named ref's hash and\n* plans an invariant-bearing path.\n*/\nasync function applyOrmMigration(opts) {\n\tconst connection = normalizeSslMode(opts.url);\n\treturn withConnectionRetry(() => runMigration(connection, opts.contractJson, opts.migrationsDir, opts.ref, opts.refName, opts.extensionPacks ?? []), { shouldRetry: (error) => !(error instanceof OrmMigrationError) });\n}\nasync function runMigration(connection, contractJson, migrationsDir, ref, refName, extensionPacks) {\n\tconst client = createPostgresControlClient({\n\t\tconnection,\n\t\textensions: extensionPacks\n\t});\n\tawait client.connect();\n\ttry {\n\t\tconst marker = await client.readMarker();\n\t\tconst markerHashBefore = marker?.storageHash ?? null;\n\t\tlet action = decideMigrationAction(marker, ref);\n\t\tif (action === \"noop\") {\n\t\t\tif (extensionPacks.length === 0) return {\n\t\t\t\taction,\n\t\t\t\ttargetHash: ref.hash,\n\t\t\t\tmarkerHashBefore\n\t\t\t};\n\t\t\taction = \"migrate\";\n\t\t}\n\t\tconst result = await client.migrate({\n\t\t\tcontract: contractJson,\n\t\t\tmigrationsDir,\n\t\t\t...refName !== void 0 ? {\n\t\t\t\trefHash: ref.hash,\n\t\t\t\trefInvariants: ref.invariants,\n\t\t\t\trefName\n\t\t\t} : {}\n\t\t});\n\t\tif (!result.ok) {\n\t\t\tif (result.failure.code === \"MIGRATION_PATH_NOT_FOUND\") throw new OrmMigrationError(\"MIGRATION_PATH_NOT_FOUND\", noPathRefusal(result.failure.summary, markerHashBefore, extensionPacks.length > 0), result.failure.why);\n\t\t\tthrow new OrmMigrationError(\"RUNNER_FAILED\", result.failure.summary, result.failure.why);\n\t\t}\n\t\treturn {\n\t\t\taction,\n\t\t\ttargetHash: ref.hash,\n\t\t\tmarkerHashBefore\n\t\t};\n\t} finally {\n\t\tawait client.close();\n\t}\n}\n//#endregion\n//#region src/orm-migration-resource.ts\n/**\n* The `OrmMigration` Alchemy resource (ADR-0022) — the migration\n* step modeled as a tracked resource so it participates in deploy state: keyed\n* on the target REF identity (`targetHash` + sorted `invariants`), an\n* unchanged redeploy is an Alchemy-level no-op (on top of the marker read),\n* and a contract change — or a DATA-ONLY change that adds a ref invariant at\n* the same hash — re-runs the migration.\n*\n* Its provider's `reconcile` receives the RESOLVED props at apply-time — in\n* particular the concrete DB `url` (a lazy `Output` until the Connection\n* provisions) — and delegates to the proven `applyOrmMigration` decision. The\n* provider is a standalone `Provider<OrmMigration>` layer; the extension\n* descriptor merges it into its `providers()` (`Layer.merge(Prisma.providers(),\n* OrmMigrationProvider())`), and Alchemy resolves it at apply via a direct\n* provider-tag lookup (`tryFindProviderByType`) — no change to `@internal/lowering`.\n*\n* Deploy-time only: imports `@prisma/orm-postgres/control` (via the helper) +\n* `alchemy`. Imported by `control.ts` and tests, never by `index.ts` / the\n* `./orm` authoring entry — index isolation holds.\n*/\n/** The `OrmMigration` resource constructor — `yield* OrmMigration(id, props)` in the lowering. */\nconst OrmMigration = Resource(\"PrismaOrm.Migration\");\n/**\n* The `OrmMigration` provider service. `reconcile` runs for both create and\n* update (Alchemy's unified lifecycle); `applyOrmMigration` is idempotent via\n* the live marker read, so it is safe to run for either — the marker decides\n* no-op / migrate. A migration has nothing to enumerate (`list` → `[]`)\n* and nothing to tear down on its own (`delete` → no-op; the DB's own deletion\n* handles teardown). Exported so tests can drive `reconcile` directly, without\n* building an Effect layer.\n*/\nconst ormMigrationProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ news }) => Effect.tryPromise({\n\t\ttry: async () => {\n\t\t\tconst extensionPacks = news.packHeadRefHashes.length > 0 ? (await resolveOrmConfig(news.configPath)).extensionPacks : [];\n\t\t\treturn applyOrmMigration({\n\t\t\t\turl: news.url,\n\t\t\t\tcontractJson: news.contractJson,\n\t\t\t\tmigrationsDir: news.migrationsDir,\n\t\t\t\tref: {\n\t\t\t\t\thash: news.targetHash,\n\t\t\t\t\tinvariants: news.invariants\n\t\t\t\t},\n\t\t\t\textensionPacks,\n\t\t\t\t...news.refName !== void 0 ? { refName: news.refName } : {}\n\t\t\t});\n\t\t},\n\t\tcatch: (error) => error\n\t}).pipe(Effect.map((outcome) => ({\n\t\tstorageHash: outcome.targetHash,\n\t\tinvariants: news.invariants\n\t}))),\n\tdelete: () => Effect.void\n};\n/** The `OrmMigration` provider layer — merged into the extension descriptor's `providers()`. */\nconst OrmMigrationProvider = () => Provider.effect(OrmMigration, Effect.succeed(ormMigrationProviderService));\n//#endregion\n//#region src/pg-warm-resource.ts\n/**\n* The `PgWarm` Alchemy resource (slice 3, FT-5226) — warm a freshly-provisioned\n* Prisma Postgres database at apply-time so it is ready by deploy-end, and the\n* first real connection (a service's runtime client, or the migration) doesn't\n* eat the cold-start reject.\n*\n* The DB `url` is a lazy `Output` at lowering time, so warming must be an\n* apply-time tracked resource (same pattern as `OrmMigration`): its `reconcile`\n* receives the RESOLVED url and connects with `withConnectionRetry` + `select 1`,\n* riding out the cold-start. Shared by BOTH the bare-`postgres` and the\n* `postgres` lowerings; keyed on the connection `url`, so an unchanged\n* redeploy is a no-op (warming is idempotent anyway).\n*\n* Deploy-time only: imports `pg` directly + `alchemy`. Imported by `control.ts`\n* and tests, never by `index.ts` / the `./orm` authoring entry — the\n* isolation invariants hold.\n*/\n/** The `PgWarm` resource constructor — `yield* PgWarm(id, { url })` in a lowering. */\nconst PgWarm = Resource(\"PrismaCloud.PgWarm\");\n/**\n* Connect (retrying the cold-start) and run `select 1`, then release the\n* connection. Exported so tests can drive it directly; `retry` overrides the\n* bounded retry's defaults.\n*/\nasync function warmDatabase(url, retry = {}) {\n\tawait withConnectionRetry(async () => {\n\t\tconst client = new pg.Client({ connectionString: normalizeSslMode(url) });\n\t\tclient.on(\"error\", (error) => console.error(\"pg warm client socket error\", error));\n\t\tawait client.connect();\n\t\ttry {\n\t\t\tawait client.query(\"select 1\");\n\t\t} finally {\n\t\t\tawait client.end();\n\t\t}\n\t}, retry);\n}\n/**\n* The `PgWarm` provider service. `reconcile` warms the DB (retrying the\n* cold-start) and echoes the `url` so a downstream resource that reads\n* `warm.url` runs only after the DB is warm. Idempotent — safe on redeploy;\n* nothing to enumerate (`list` → `[]`) or tear down (`delete` → no-op; the DB's\n* own deletion handles teardown). Exported so tests can drive it directly.\n*/\nconst pgWarmProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ news }) => Effect.tryPromise({\n\t\ttry: () => warmDatabase(news.url),\n\t\tcatch: (error) => error\n\t}).pipe(Effect.map(() => ({ url: news.url }))),\n\tdelete: () => Effect.void\n};\n/** The `PgWarm` provider layer — merged into the extension descriptor's `providers()`. */\nconst PgWarmProvider = () => Provider.effect(PgWarm, Effect.succeed(pgWarmProviderService));\n//#endregion\n//#region src/preflight-names.ts\nfunction dedupedNames(entries) {\n\tconst byName = /* @__PURE__ */ new Map();\n\tfor (const entry of entries) if (!byName.has(entry.name)) byName.set(entry.name, entry);\n\treturn [...byName.values()];\n}\n/** Every `envSecret` leaf of one input binding: its platform name, found by the same dumb recursive descent the serializer uses (ADR-0042). */\nfunction collectSecretLeafNames(binding, serviceAddress, out) {\n\tif (isGeneratedParamSource(binding)) return;\n\tif (isSecretSource(binding)) {\n\t\tout.push(secretName(binding, `an input-binding secret leaf of service \"${serviceAddress}\"`));\n\t\treturn;\n\t}\n\tif (typeof binding !== \"object\" || binding === null) return;\n\tconst members = Array.isArray(binding) ? binding : Object.values(binding);\n\tfor (const member of members) collectSecretLeafNames(member, serviceAddress, out);\n}\n/** Walks each service's input binding for `envSecret` leaves, and `graph.params` for env-sourced params (ADR-0042). */\nfunction collectPreflightNames(graph) {\n\tconst secretEntries = [];\n\tfor (const { serviceAddress, binding } of inputManifest(graph)) {\n\t\tconst leafNames = [];\n\t\tcollectSecretLeafNames(binding, serviceAddress, leafNames);\n\t\tfor (const name of leafNames) secretEntries.push({\n\t\t\tname,\n\t\t\tserviceAddress\n\t\t});\n\t}\n\tconst envParams = dedupedNames(paramManifest(graph).filter((binding) => isEnvParamSource(binding.binding)).map((binding) => ({\n\t\tname: paramName(binding),\n\t\tserviceAddress: binding.serviceAddress\n\t})));\n\treturn {\n\t\tsecrets: dedupedNames(secretEntries),\n\t\tenvParams\n\t};\n}\n//#endregion\n//#region src/s3-credentials-resource.ts\n/**\n* The `S3Credentials` Alchemy resource (S5) — mints a random SigV4 key pair\n* ONCE at create and keeps it STABLE across deploys, so an unchanged module\n* no-ops on redeploy. The pair is generated by `@internal/s3-protocol`'s\n* `mintKeyPair` (moved there per the local-dev spec § 1, so deploy and local\n* dev credential minting share one implementation) and persisted in Alchemy\n* state; on every later apply the provider returns the persisted attributes\n* (`reconcile`'s `output`) unchanged — the same way the postgres resource\n* keeps a Connection stable. Rotation is destroy/recreate (a platform ask,\n* not solved here).\n*\n* Deploy-time only: imports `alchemy`. Imported by `control.ts` and tests,\n* never by `index.ts` / the authoring entry.\n*/\n/** The `S3Credentials` resource constructor — `yield* S3Credentials(id, {})` in the lowering. */\nconst S3Credentials = Resource(\"PrismaCloud.S3Credentials\");\n/**\n* The `S3Credentials` provider service. `reconcile` runs for create and update;\n* it returns the persisted `output` when present (a redeploy reuses the stored\n* pair — the no-op property) and mints a fresh pair only on first create.\n* Nothing to enumerate (`list` → `[]`) or tear down (`delete` → no-op; the pair\n* lives only in state). Exported so tests can drive it directly.\n*/\nconst s3CredentialsProviderService = {\n\tlist: () => Effect.succeed([]),\n\treconcile: ({ output }) => Effect.sync(() => output ?? mintKeyPair()),\n\tdelete: () => Effect.void\n};\n/** The `S3Credentials` provider layer — merged into the extension descriptor's `providers()`. */\nconst S3CredentialsProvider = () => Provider.effect(S3Credentials, Effect.succeed(s3CredentialsProviderService));\n//#endregion\nexport { prismaCloudContainerOf as _, PgWarmProvider as a, resolveTargetRef as c, GeneratedParam as d, GeneratedParamProvider as f, deserialize as g, containerDescriptor as h, PgWarm as i, packHeadRefHashes as l, PrismaCloudContainer as m, S3CredentialsProvider as n, OrmMigration as o, PRISMA_CLOUD_EXTENSION_ID as p, collectPreflightNames as r, OrmMigrationProvider as s, S3Credentials as t, resolveOrmConfig as u };\n\n//# sourceMappingURL=s3-credentials-resource-D_qSGYMM.mjs.map"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAI,oBAAoB,cAAc,QAAQ,QAAQ,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;;AAE9E,MAAM,gBAAgB,MAAM,OAAO,mBAAmB,OAAO,IAAI,aAAa;CAC7E,OAAO,EAAE,OAAO,OAAOA,SAAO,SAAS,sBAAsB,EAAE;AAChE,CAAC,CAAC;AACF,MAAM,mBAAmB;AACzB,MAAM,kBAAkB,aAAa,aAAa,eAAe,SAAS,SAAS,YAAY,KAAK,aAAa,eAAe,aAAa;;AAE7I,MAAM,oBAAoB,UAAU,OAAO,IAAI;CAC9C,WAAW;EACV,MAAM,MAAM,IAAI,IAAI,KAAK;EACzB,IAAI,IAAI,aAAa,YAAY,IAAI,aAAa,SAAS,MAAM,IAAI,MAAM,mDAAmD;EAC9H,IAAI,IAAI,SAAS,SAAS,KAAK,IAAI,SAAS,SAAS,GAAG,MAAM,IAAI,MAAM,yDAAyD;EACjI,IAAI,IAAI,aAAa,WAAW,CAAC,eAAe,IAAI,QAAQ,GAAG,MAAM,IAAI,MAAM,6EAA6E;EAC5J,IAAI,IAAI,aAAa,OAAO,IAAI,aAAa,MAAM,IAAI,OAAO,SAAS,KAAK,IAAI,KAAK,SAAS,GAAG,MAAM,IAAI,MAAM,iFAAiF;EAClM,OAAO,IAAI;CACZ;CACA,QAAQ,UAAU,iBAAiB,QAAQ,wBAAwB,IAAI,MAAM,sCAAsC,OAAO,KAAK,GAAG;AACnI,CAAC;;;;;;;;;AASD,MAAM,wBAAwB,QAAQ,QAAQ,KAAK,IAAI,iBAAiB,IAAI,qBAAqB,IAAI,gCAAgC,gBAAgB,IAAIA,SAAO,OAAO,gBAAgB,CAAC,CAAC,KAAKA,SAAO,aAAaA,SAAO,OAAO,2BAA2B,CAAC,GAAGA,SAAO,YAAY,gBAAgB,GAAG,OAAO,QAAQ,gBAAgB,CAAC;;;;;;;;ACtBrU,IAAI,mBAAmB,cAAc,QAAQ,QAAQ,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC;;;;;;;AAOlF,MAAM,SAAS,YAAY,MAAM,OAAO,kBAAkB,OAAO,IAAI,aAAa;CACjF,MAAM,EAAE,UAAU,OAAO;CACzB,MAAM,UAAU,SAAS,cAAc,OAAO,qBAAqB;CACnE,OAAO,0BAA0B;EAChC,OAAO,SAAS,MAAM,KAAK;EAC3B;CACD,CAAC;AACF,CAAC,CAAC;;AAIF,IAAI,iBAAiB,cAAc,KAAK,YAAY,gBAAgB,CAAC,CAAC,CAAC;AACvE,MAAM,WAAW,MAAM,OAAO,WAAW;CACxC,KAAK;CACL,QAAQ,UAAU,IAAI,eAAe;EACpC,QAAQ;EACR,SAAS,OAAO,KAAK;CACtB,CAAC;AACF,CAAC;AACD,MAAM,QAAQ,MAAM,OAAO,KAAK,IAAI,eAAe;CAClD,QAAQ,EAAE,SAAS;CACnB,SAAS,KAAK,UAAU,EAAE,KAAK;AAChC,CAAC,CAAC;;AAEF,MAAM,QAAQ,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,MAAM,EAAE,UAAU,KAAK,KAAK,EAAE,SAAS,KAAK,IAAI,KAAK,CAAC,IAAI,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC;;AAErI,MAAM,YAAY,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,MAAM,EAAE,SAAS,WAAW,OAAO,EAAE,UAAU,KAAK,IAAI,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC;;;;;;AAMtI,MAAM,kBAAkB,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,SAAS,MAAM,EAAE,SAAS,WAAW,OAAO,EAAE,UAAU,KAAK,IAAI,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC;;AAI5I,MAAM,YAAY;AAClB,MAAM,yBAAyB,aAAa,WAAW,IAAI,eAAe;CACzE,QAAQ;CACR,SAAS,WAAW,YAAY,GAAG,OAAO;AAC3C,CAAC;;AAED,MAAM,gBAAgB,aAAa,cAAc,OAAO,IAAI,aAAa;CACxE,MAAM,OAAO,CAAC;CACd,OAAO,WAAW,aAAa,YAAY,SAAS;EACnD,KAAK,KAAK,GAAG,IAAI;EACjB,OAAO;CACR,CAAC;CACD,OAAO;AACR,CAAC;;;;;;;;;AASD,MAAM,cAAc,aAAa,WAAW,WAAW,OAAO,IAAI,aAAa;CAC9E,IAAI;CACJ,KAAK,IAAI,YAAY,IAAI,aAAa;EACrC,IAAI,aAAa,WAAW,OAAO,OAAO,OAAO,KAAK,sBAAsB,aAAa,yBAAyB,OAAO,SAAS,EAAE,OAAO,CAAC;EAC5I,MAAM,OAAO,OAAO,UAAU,MAAM;EACpC,IAAI,OAAO,KAAK,IAAI,GAAG;EACvB,IAAI,CAAC,KAAK,WAAW,SAAS;EAC9B,MAAM,OAAO,KAAK,WAAW;EAC7B,IAAI,SAAS,MAAM,OAAO,OAAO,OAAO,KAAK,sBAAsB,aAAa,4CAA4C,CAAC;EAC7H,IAAI,SAAS,QAAQ,OAAO,OAAO,OAAO,KAAK,sBAAsB,aAAa,iCAAiC,CAAC;EACpH,SAAS;CACV;AACD,CAAC;;;;;;;;;AASD,eAAe,gBAAgB,aAAa,WAAW,QAAQ;CAC9D,IAAI;CACJ,KAAK,IAAI,YAAY,IAAI,aAAa;EACrC,IAAI,aAAa,WAAW,MAAM,sBAAsB,aAAa,yBAAyB,OAAO,SAAS,EAAE,OAAO;EACvH,MAAM,OAAO,MAAM,UAAU,MAAM;EACnC,IAAI,OAAO,KAAK,IAAI,GAAG;EACvB,IAAI,CAAC,KAAK,WAAW,SAAS;EAC9B,MAAM,OAAO,KAAK,WAAW;EAC7B,IAAI,SAAS,MAAM,MAAM,sBAAsB,aAAa,4CAA4C;EACxG,IAAI,SAAS,QAAQ,MAAM,sBAAsB,aAAa,iCAAiC;EAC/F,SAAS;CACV;AACD;;AAIA,IAAI,yBAAyB,cAAc,KAAK,YAAY,wBAAwB,CAAC,CAAC,CAAC;AACvF,MAAM,mBAAmB,WAAW,aAAa,aAAa,WAAW,WAAW,OAAO,IAAI,gBAAgB,EAAE,QAAQ,EAAE,OAAO,WAAW,KAAK,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;;;;;;;AAO3K,MAAM,mBAAmB,OAAO,GAAG,WAAW,OAAO,IAAI,GAAG,MAAM,CAAC,IAAI;;;;;;;;;;AAUvE,MAAM,kBAAkB,QAAQ,aAAa,SAAS,WAAW,OAAO,IAAI,aAAa;CACxF,MAAM,qBAAqB,OAAO,gBAAgB,MAAM,EAAA,CAAG,QAAQ,MAAM,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,WAAW,CAAC;CACzI,MAAM,iBAAiB,kBAAkB,MAAM,MAAM,EAAE,aAAa,QAAQ,EAAE,cAAc,OAAO;CACnG,IAAI,mBAAmB,KAAK,GAAG,OAAO,eAAe;CACrD,MAAM,YAAY,kBAAkB,QAAQ,MAAM,EAAE,SAAS,OAAO,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC;CAC7H,IAAI,cAAc,KAAK,GAAG,OAAO,UAAU;CAC3C,IAAI,CAAC,QAAQ,OAAO,OAAO,OAAO,KAAK,IAAI,uBAAuB,EAAE,QAAQ,CAAC,CAAC;CAC9E,QAAQ,OAAO,WAAW,OAAO,KAAK,gBAAgB,EAAE,MAAM;EAC7D,MAAM;EACN;EACA,gBAAgB;EAChB,WAAW;CACZ,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,OAAO,QAAQ,IAAI,WAAW,MAAM,OAAO,KAAK,IAAI,eAAe;EACpF,QAAQ;EACR,SAAS;CACV,CAAC,CAAC,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC,EAAA,CAAG,KAAK;AAChC,CAAC;;;;;;;;;AASD,MAAM,0BAA0B,QAAQ,cAAc,OAAO,IAAI,aAAa;CAC7E,IAAI;CACJ,OAAO,WAAW,uBAAuB,cAAc,WAAW,WAAW,OAAO,IAAI,qCAAqC,EAAE,QAAQ;EACtI,MAAM,EAAE,UAAU;EAClB,OAAO,WAAW,KAAK,IAAI,CAAC,IAAI,EAAE,OAAO;CAC1C,EAAE,CAAC,CAAC,IAAI,SAAS;EAChB,QAAQ,KAAK,MAAM,MAAM,EAAE,SAAS,CAAC,EAAE;EACvC,OAAO,UAAU,KAAK;CACvB,CAAC;CACD,IAAI,UAAU,KAAK,GAAG,OAAO;CAC7B,OAAO,OAAO,OAAO,KAAK,IAAI,eAAe;EAC5C,QAAQ;EACR,SAAS,WAAW,UAAU;CAC/B,CAAC,CAAC;AACH,CAAC;AACD,MAAM,gBAAgB,QAAQ,WAAW,YAAY,WAAW,OAAO,IAAI,qCAAqC,EAAE,QAAQ;CACzH,MAAM,EAAE,UAAU;CAClB,OAAO,EAAE,QAAQ;AAClB,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,SAAS,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC;;;;;;;;;;AAUjD,MAAM,iBAAiB,QAAQ,WAAW,SAAS,SAAS,WAAW,OAAO,IAAI,aAAa;CAC9F,MAAM,WAAW,OAAO,aAAa,QAAQ,WAAW,OAAO;CAC/D,IAAI,aAAa,KAAK,GAAG,OAAO;CAChC,IAAI,CAAC,QAAQ,OAAO,OAAO,OAAO,KAAK,IAAI,uBAAuB;EACjE;EACA,OAAO;CACR,CAAC,CAAC;CACF,OAAO,OAAO,WAAW,OAAO,KAAK,qCAAqC;EACzE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE;EAC9B,MAAM,EAAE,QAAQ;CACjB,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,OAAO,QAAQ,IAAI,WAAW,MAAM,aAAa,QAAQ,WAAW,OAAO,CAAC,CAAC,KAAK,OAAO,SAAS,OAAO,OAAO,KAAK,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,QAAQ,EAAE,CAAC,CAAC,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC;AACnO,CAAC;;;;;;;;;;AAUD,MAAM,oBAAoB,SAAS,OAAO,IAAI,aAAa;CAC1D,MAAM,SAAS,OAAO;CACtB,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,YAAY,OAAO,eAAe,QAAQ,KAAK,aAAa,KAAK,SAAS,MAAM;CACtF,IAAI,KAAK,UAAU,KAAK,GAAG,OAAO;EACjC;EACA,iBAAiB,OAAO,uBAAuB,QAAQ,SAAS;CACjE;CACA,OAAO;EACN;EACA,UAAU,OAAO,cAAc,QAAQ,WAAW,KAAK,OAAO,KAAK,SAAS,MAAM;CACnF;AACD,CAAC;;;;;;AAMD,MAAM,gBAAgB,aAAa,OAAO,IAAI,aAAa;CAC1D,MAAM,SAAS,OAAO;CACtB,OAAO,eAAe,OAAO,OAAO,2BAA2B,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AACnG,CAAC;;;;;;AAMD,MAAM,iBAAiB,cAAc,OAAO,IAAI,aAAa;CAC5D,MAAM,SAAS,OAAO;CACtB,OAAO,eAAe,OAAO,OAAO,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,EAAE,CAAC,CAAC;AAClG,CAAC;;;;;;;;;;;;;AAeD,MAAM,oBAAoB;;AAE1B,MAAM,6BAA6B,CAAC,gBAAgB,qBAAqB;;;;;;;AAOzE,MAAM,sBAAsB,CAAC,cAAc,SAAS;AACpD,MAAM,SAAS,QAAQ,WAAW,KAAK,qBAAqB,qBAAqB,OAAO,KAAK,6BAA6B,EAAE,MAAM;CACjI;CACA,OAAO;CACP;CACA,OAAO;AACR,EAAE,CAAC,CAAC;;;;;;;;AAQJ,MAAM,wBAAwB,cAAc,OAAO,IAAI,aAAa;CACnE,MAAM,SAAS,OAAO,OAAO,cAAc,gBAAgB;CAC3D,IAAI,OAAO,OAAO,MAAM,GAAG;CAC3B,KAAK,MAAM,OAAO,4BAA4B,KAAK,MAAM,oBAAoB,qBAAqB,OAAO,MAAM,OAAO,OAAO,WAAW,KAAK,gBAAgB;AAC9J,CAAC;;;;;;;;;;;;AC5QD,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;;;;;;;;;;;;;;;;ACIA,MAAM,uBAAuB,KAAK,gBAAgB,YAAY,WAAW,IAAI,MAAM,OAAO,QAAQ,OAAO,IAAI,KAAK,GAAG,YAAY,KAAK,aAAa,SAAS,qBAAqB,CAAC,SAAS,GAAG;;;;;;;;;;;;AAc9L,MAAM,aAAa,SAAS,wBAAwB;;AAEpD,SAAS,iBAAiB;CACzB,MAAM,QAAQ,OAAO,gCAAgC,IAAI,WAAW,EAAE,CAAC;CACvE,OAAO,EAAE,OAAO,MAAM,KAAK,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;AACpF;;;;;;;;AAQA,MAAM,4BAA4B;CACjC,YAAY,OAAO,QAAQ,CAAC,CAAC;CAC7B,YAAY,EAAE,aAAa,OAAO,WAAW,UAAU,eAAe,CAAC;CACvE,cAAc,OAAO;AACtB;;AAEA,MAAM,2BAA2B,SAAS,OAAO,YAAY,OAAO,QAAQ,yBAAyB,CAAC;;;;ACzCtG,IAAI,YAAY,cAAc,SAAS,mBAAmB,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;;;;;;;;;AAS/E,MAAM,0BAA0B,MAAM,OAAO,OAAO,mBAAmB,OAAO,IAAI,aAAa;CAC9F,MAAM,EAAE,UAAU,OAAO;CACzB,OAAO;EACN,MAAM;EACN,cAAc;EACd,QAAQ;GACP,MAAM;GACN,SAAS;EACV;EACA,SAAS,OAAO,qBAAqB;CACtC;AACD,CAAC,CAAC;;;;;;;;;;;;;AAaF,MAAM,gCAAgC,MAAM,SAAS,OAAO,gBAAgB,GAAG,OAAO,iBAAiB,GAAG,OAAO,mBAAmB,GAAG,OAAO,YAAY,GAAG,OAAO,mBAAmB,GAAG,OAAO,4BAA4B,GAAG,OAAO,eAAe,GAAG,OAAO,wBAAwB,CAAC,CAAC,CAAC,KAAK,MAAM,aAAa,OAAO,gBAAgB,GAAG,MAAM,QAAQ,eAAe,aAAa,GAAG,MAAM,aAAa,kBAAkB,CAAC,CAAC;;;;;;;;;;;;;;AAcja,MAAM,kBAAkB,MAAM,OAAO,WAAW,SAAS,WAAW;CACnE,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;AACR,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,QAAQ,wBAAwB,CAAC,GAAG,MAAM,aAAa,eAAe,aAAa,GAAG,MAAM,aAAa,MAAM,CAAC,GAAG,MAAM,aAAa,QAAQ,CAAC,GAAG,MAAM,KAAK;;;;;;;;;;;;;;ACuL5K,SAASC,cAAY,GAAG;CACvB,OAAO,OAAO,gBAAgB,IAAI,WAAW,CAAC,CAAC;AAChD;AACA,SAAS,WAAW,OAAO;CAC1B,OAAO,MAAM,KAAK,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,YAAY;AACvF;;AAEA,SAAS,cAAc;CACtB,OAAO;EACN,aAAa,OAAO,WAAWA,cAAY,CAAC,CAAC;EAC7C,iBAAiB,KAAK,OAAO,aAAa,GAAGA,cAAY,EAAE,CAAC,CAAC;CAC9D;AACD;;;ACrPA,MAAM,4BAA4B;;AAElC,MAAM,wBAAwB;AAC9B,SAAS,yBAAyB,UAAU;CAC3C,uBAAuB,IAAI,MAAM,GAAG,0BAA0B,4BAA4B,SAAS,qLAAqL;AACzR;AACA,IAAI,uBAAuB,MAAM;CAChC;CACA;CACA;CACA;CACA;;CAEA;CACA,YAAY,OAAO,WAAW,UAAU,iBAAiB,aAAa,OAAO;EAC5E,KAAK,QAAQ;EACb,KAAK,YAAY;EACjB,KAAK,WAAW;EAChB,KAAK,kBAAkB;EACvB,KAAK,aAAa;EAClB,MAAM,gBAAgB,YAAY;EAClC,IAAI,kBAAkB,KAAK,KAAK,CAAC,sBAAsB,KAAK,aAAa,GAAG,MAAM,yBAAyB,aAAa;EACxH,KAAK,eAAe;CACrB;CACA,YAAY;EACX,OAAO,KAAK,UAAU;GACrB,OAAO,KAAK;GACZ,WAAW,KAAK;GAChB,GAAG,KAAK,aAAa,KAAK,IAAI,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;GAC7D,GAAG,KAAK,oBAAoB,KAAK,IAAI,EAAE,iBAAiB,KAAK,gBAAgB,IAAI,CAAC;GAClF,GAAG,KAAK,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;EAC9C,CAAC;CACF;AACD;;AAEA,SAAS,uBAAuB,OAAO;CACtC,OAAO,iBAAiB;AACzB;;AAEA,SAAS,uBAAuB,OAAO;CACtC,IAAI,CAAC,uBAAuB,KAAK,GAAG,MAAM,IAAI,MAAM,iGAAiG;CACrJ,OAAO;AACR;AACA,SAAS,SAAS,OAAO;CACxB,OAAO,OAAO,UAAU,YAAY,UAAU;AAC/C;AACA,SAAS,oBAAoB,QAAQ;CACpC,uBAAuB,IAAI,MAAM,GAAG,0BAA0B,0CAA0C,OAAO,EAAE;AAClH;;;;;;;AAOA,SAAS,YAAY,YAAY;CAChC,IAAI;CACJ,IAAI;EACH,SAAS,KAAK,MAAM,UAAU;CAC/B,SAAS,OAAO;EACf,MAAM,oBAAoB,mBAAmB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,EAAE;CACvG;CACA,IAAI,CAAC,SAAS,MAAM,GAAG,MAAM,oBAAoB,eAAe;CAChE,MAAM,QAAQ,OAAO;CACrB,IAAI,CAAC,SAAS,KAAK,GAAG,MAAM,oBAAoB,4BAA4B;CAC5E,MAAM,UAAU,MAAM;CACtB,IAAI,OAAO,YAAY,UAAU,MAAM,oBAAoB,mCAAmC;CAC9F,MAAM,QAAQ,MAAM;CACpB,IAAI,UAAU,KAAK,KAAK,OAAO,UAAU,UAAU,MAAM,oBAAoB,2CAA2C;CACxH,MAAM,YAAY,OAAO;CACzB,IAAI,OAAO,cAAc,UAAU,MAAM,oBAAoB,+BAA+B;CAC5F,MAAM,WAAW,OAAO;CACxB,IAAI,aAAa,KAAK,KAAK,OAAO,aAAa,UAAU,MAAM,oBAAoB,wCAAwC;CAC3H,MAAM,kBAAkB,OAAO;CAC/B,IAAI,oBAAoB,KAAK,KAAK,OAAO,oBAAoB,UAAU,MAAM,oBAAoB,+CAA+C;CAChJ,MAAM,aAAa,OAAO;CAC1B,IAAI,eAAe,KAAK,KAAK,OAAO,eAAe,WAAW,MAAM,oBAAoB,2CAA2C;CACnI,OAAO,IAAI,qBAAqB;EAC/B;EACA;CACD,GAAG,WAAW,UAAU,iBAAiB,cAAc,KAAK;AAC7D;AACA,MAAM,+CAA+C,IAAI,MAAM,uDAAuD;AACtH,MAAM,2CAA2C,IAAI,MAAM,wDAAwD;;;;;;AAMnH,SAAS,mBAAmB,aAAa;CACxC,MAAM,cAAc,gBAAgB,KAAK,IAAI,QAAQ,IAAI,yBAAyB,YAAY;CAC9F,IAAI,gBAAgB,KAAK,KAAK,YAAY,WAAW,GAAG,MAAM,uBAAuB;CACrF,OAAO;AACR;AACA,SAAS,2BAA2B,QAAQ;CAC3C,IAAI,WAAW,KAAK,MAAM,QAAQ,IAAI,2BAA2B,GAAA,CAAI,WAAW,GAAG,MAAM,mBAAmB;AAC7G;AACA,SAAS,UAAU,aAAa,MAAM;CACrC,OAAO,aAAa,UAAU,MAAM;AACrC;;AAEA,SAAS,cAAc,SAAS,QAAQ;CACvC,OAAO,OAAO,WAAW,WAAW,KAAK,IAAI,QAAQ,KAAK,OAAO,eAAe,kBAAkB,MAAM,CAAC,IAAI,QAAQ,KAAK,OAAO,QAAQC,MAAsB,CAAC,CAAC,KAAK,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAClM;AACA,eAAe,gBAAgB,OAAO,aAAa,MAAM;CACxD,MAAM,cAAc,mBAAmB,WAAW;CAClD,MAAM,SAAS,UAAU,aAAa,IAAI;CAC1C,2BAA2B,MAAM;CACjC,MAAM,UAAU,MAAM,cAAc,iBAAiB;EACpD;EACA,SAAS,MAAM;EACf,GAAG,MAAM,UAAU,KAAK,IAAI,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;EACtD,QAAQ;CACT,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,OAAO;EAC1B,IAAI;EACJ,WAAW;CACZ,EAAE,GAAG,OAAO,SAAS,mBAAmB,MAAM,OAAO,QAAQ;EAC5D,IAAI;EACJ,SAAS,qDAAqD,EAAE,QAAQ;CACzE,CAAC,CAAC,CAAC,GAAG,MAAM;CACZ,IAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,MAAM,QAAQ,OAAO;CAChD,OAAO,IAAI,qBAAqB,OAAO,QAAQ,UAAU,WAAW,QAAQ,UAAU,UAAU,QAAQ,UAAU,eAAe;AAClI;AACA,eAAe,gBAAgB,OAAO,aAAa,MAAM;CACxD,MAAM,cAAc,mBAAmB,WAAW;CAClD,MAAM,SAAS,UAAU,aAAa,IAAI;CAC1C,2BAA2B,MAAM;CACjC,MAAM,UAAU,MAAM,cAAc,iBAAiB;EACpD;EACA,SAAS,MAAM;EACf,GAAG,MAAM,UAAU,KAAK,IAAI,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;EACtD,QAAQ;CACT,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,OAAO;EAC1B,IAAI;EACJ,WAAW;CACZ,EAAE,GAAG,OAAO,SAAS,gCAAgC,OAAO,QAAQ,EAAE,IAAI,MAAM,CAAC,CAAC,GAAG,OAAO,SAAS,mBAAmB,MAAM,OAAO,qBAAqB,IAAI,MAAM,qDAAqD,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM;CACjP,IAAI,CAAC,QAAQ,IAAI,OAAO,KAAK;CAC7B,OAAO,IAAI,qBAAqB,OAAO,QAAQ,UAAU,WAAW,QAAQ,UAAU,UAAU,QAAQ,UAAU,eAAe;AAClI;;;;;;AAMA,eAAe,kBAAkB,UAAU,aAAa,MAAM;CAC7D,MAAM,SAAS,UAAU,aAAa,IAAI;CAC1C,2BAA2B,MAAM;CACjC,MAAM,UAAU,MAAM,cAAc,aAAa,QAAQ,CAAC,CAAC,KAAK,OAAO,WAAW,EAAE,IAAI,KAAK,EAAE,GAAG,OAAO,SAAS,mBAAmB,MAAM,OAAO,QAAQ;EACzJ,IAAI;EACJ,SAAS,sCAAsC,EAAE,QAAQ;CAC1D,CAAC,CAAC,CAAC,GAAG,MAAM;CACZ,IAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,MAAM,QAAQ,OAAO;AACjD;;;;;;;;;AASA,eAAe,iBAAiB,WAAW,aAAa,MAAM;CAC7D,MAAM,SAAS,UAAU,aAAa,IAAI;CAC1C,IAAI,WAAW,KAAK,MAAM,QAAQ,IAAI,2BAA2B,GAAA,CAAI,WAAW,GAAG;EAClF,QAAQ,KAAK,iCAAiC,UAAU,oCAAoC;EAC5F;CACD;CACA,MAAM,UAAU,MAAM,cAAc,cAAc,SAAS,CAAC,CAAC,KAAK,OAAO,WAAW,EAAE,IAAI,KAAK,EAAE,GAAG,OAAO,SAAS,mBAAmB,MAAM,OAAO,QAAQ;EAC3J,IAAI;EACJ,OAAO;CACR,CAAC,CAAC,CAAC,GAAG,MAAM;CACZ,IAAI,QAAQ,IAAI;EACf,QAAQ,IAAI,wBAAwB,UAAU,4BAA4B;EAC1E;CACD;CACA,IAAI,QAAQ,MAAM,WAAW,KAAK;EACjC,QAAQ,IAAI,qBAAqB,UAAU,4CAA4C;EACvF;CACD;CACA,QAAQ,KAAK,iCAAiC,UAAU,mBAAmB,QAAQ,MAAM,QAAQ,EAAE;AACpG;AACA,SAAS,oBAAoB,MAAM;CAClC,OAAO;EACN,SAAS,OAAO,gBAAgB,gBAAgB,OAAO,aAAa,IAAI;EACxE,SAAS,OAAO,gBAAgB,gBAAgB,OAAO,aAAa,IAAI;EACxE,SAAS,UAAU,gBAAgB,SAAS,MAAM,UAAU,KAAK,IAAI,kBAAkB,SAAS,YAAY,gBAAgB,QAAQ,GAAG,aAAa,IAAI,IAAI,iBAAiB,SAAS,WAAW,aAAa,IAAI;EAClN;CACD;AACD;;AAEA,SAAS,gBAAgB,UAAU;CAClC,MAAM,IAAI,MAAM,GAAG,0BAA0B,oBAAoB,SAAS,MAAM,MAAM,4FAA4F;AACnL;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,iBAAiB,SAAS,4BAA4B;;AAE5D,SAAS,cAAc,OAAO;CAC7B,MAAM,SAAS,OAAO,gBAAgB,IAAI,WAAW,KAAK,CAAC;CAC3D,OAAO,EAAE,OAAO,KAAK,OAAO,aAAa,GAAG,MAAM,CAAC,EAAE;AACtD;;;;;;;;;AASA,MAAM,gCAAgC;CACrC,YAAY,OAAO,QAAQ,CAAC,CAAC;CAC7B,YAAY,EAAE,MAAM,aAAa,OAAO,WAAW,UAAU,cAAc,KAAK,KAAK,CAAC;CACtF,cAAc,OAAO;AACtB;;AAEA,MAAM,+BAA+B,SAAS,OAAO,gBAAgB,OAAO,QAAQ,6BAA6B,CAAC;;;;;;;;;;;;;;;;AAkBlH,eAAe,iBAAiB,YAAY;CAC3C,MAAM,SAAS,MAAM,WAAW,UAAU;CAC1C,IAAI,CAAC,OAAO,IAAI,MAAM,OAAO;CAC7B,MAAM,SAAS,OAAO,MAAM;CAC5B,OAAO;EACN,eAAe,QAAQ,YAAY,MAAM,OAAO,YAAY,OAAO,YAAY;EAC/E,gBAAgB,UAAU,OAAO,cAAc,CAAC,CAAC;CAClD;AACD;;;;;;;;;AASA,SAAS,kBAAkB,OAAO;CACjC,OAAO,MAAM,KAAK,SAAS,GAAG,KAAK,GAAG,GAAG,KAAK,eAAe,QAAQ,QAAQ,KAAK,CAAC,CAAC,KAAK;AAC1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,IAAI,oBAAoB,cAAc,MAAM;CAC3C;;CAEA;CACA,YAAY,MAAM,SAAS,KAAK;EAC/B,MAAM,uBAAuB,KAAK,KAAK,SAAS;EAChD,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,MAAM;CACZ;AACD;;;;;;;;AAQA,SAAS,cAAc,SAAS,kBAAkB,WAAW;CAC5D,OAAO,GAAG,YAAY,6GAA6G,qBAAqB,OAAO,gIAAgI,gGAAgG,iBAAiB,iBAAiB,oVAAoV,QAAQ;AAC9vB;;;;;AAKA,SAAS,kBAAkB,cAAc;CACxC,IAAI,OAAO,iBAAiB,YAAY,iBAAiB,QAAQ,aAAa,cAAc;EAC3F,MAAM,UAAU,aAAa;EAC7B,IAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,iBAAiB,SAAS;GAChF,MAAM,OAAO,QAAQ;GACrB,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,GAAG,OAAO;EACzD;CACD;CACA,MAAM,IAAI,kBAAkB,oBAAoB,sFAAsF;AACvI;;;;;;;;;;;;;AAaA,eAAe,iBAAiB,eAAe,cAAc,WAAW;CACvE,IAAI,cAAc,KAAK,GAAG;EACzB,MAAM,UAAU,mBAAmB,wBAAwB,eAAe,YAAY,CAAC;EACvF,IAAI;GACH,MAAM,MAAM,MAAM,QAAQ,SAAS,SAAS;GAC5C,OAAO;IACN,MAAM,IAAI;IACV,YAAY,IAAI;GACjB;EACD,SAAS,OAAO;GACf,MAAM,IAAI,kBAAkB,wBAAwB,cAAc,UAAU,2BAA2B,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EACzK;CACD;CACA,MAAM,OAAO,MAAM,yBAAyB,eAAe,YAAY;CACvE,IAAI,SAAS,MAAM,OAAO;EACzB,MAAM,KAAK;EACX,YAAY,KAAK;CAClB;CACA,OAAO;EACN,MAAM,kBAAkB,YAAY;EACpC,YAAY,CAAC;CACd;AACD;;;;;;;;;AASA,SAAS,sBAAsB,QAAQ,KAAK;CAC3C,MAAM,mBAAmB,IAAI,IAAI,QAAQ,cAAc,CAAC,CAAC;CACzD,MAAM,UAAU,IAAI,WAAW,QAAQ,OAAO,CAAC,iBAAiB,IAAI,EAAE,CAAC;CACvE,IAAI,WAAW,QAAQ,OAAO,gBAAgB,IAAI,QAAQ,QAAQ,WAAW,GAAG,OAAO;CACvF,OAAO;AACR;;;;;;;;;;;;AAYA,eAAe,kBAAkB,MAAM;CACtC,MAAM,aAAa,iBAAiB,KAAK,GAAG;CAC5C,OAAO,0BAA0B,aAAa,YAAY,KAAK,cAAc,KAAK,eAAe,KAAK,KAAK,KAAK,SAAS,KAAK,kBAAkB,CAAC,CAAC,GAAG,EAAE,cAAc,UAAU,EAAE,iBAAiB,mBAAmB,CAAC;AACvN;AACA,eAAe,aAAa,YAAY,cAAc,eAAe,KAAK,SAAS,gBAAgB;CAClG,MAAM,SAAS,4BAA4B;EAC1C;EACA,YAAY;CACb,CAAC;CACD,MAAM,OAAO,QAAQ;CACrB,IAAI;EACH,MAAM,SAAS,MAAM,OAAO,WAAW;EACvC,MAAM,mBAAmB,QAAQ,eAAe;EAChD,IAAI,SAAS,sBAAsB,QAAQ,GAAG;EAC9C,IAAI,WAAW,QAAQ;GACtB,IAAI,eAAe,WAAW,GAAG,OAAO;IACvC;IACA,YAAY,IAAI;IAChB;GACD;GACA,SAAS;EACV;EACA,MAAM,SAAS,MAAM,OAAO,QAAQ;GACnC,UAAU;GACV;GACA,GAAG,YAAY,KAAK,IAAI;IACvB,SAAS,IAAI;IACb,eAAe,IAAI;IACnB;GACD,IAAI,CAAC;EACN,CAAC;EACD,IAAI,CAAC,OAAO,IAAI;GACf,IAAI,OAAO,QAAQ,SAAS,4BAA4B,MAAM,IAAI,kBAAkB,4BAA4B,cAAc,OAAO,QAAQ,SAAS,kBAAkB,eAAe,SAAS,CAAC,GAAG,OAAO,QAAQ,GAAG;GACtN,MAAM,IAAI,kBAAkB,iBAAiB,OAAO,QAAQ,SAAS,OAAO,QAAQ,GAAG;EACxF;EACA,OAAO;GACN;GACA,YAAY,IAAI;GAChB;EACD;CACD,UAAU;EACT,MAAM,OAAO,MAAM;CACpB;AACD;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAM,eAAe,SAAS,qBAAqB;;;;;;;;;;AAUnD,MAAM,8BAA8B;CACnC,YAAY,OAAO,QAAQ,CAAC,CAAC;CAC7B,YAAY,EAAE,WAAW,OAAO,WAAW;EAC1C,KAAK,YAAY;GAChB,MAAM,iBAAiB,KAAK,kBAAkB,SAAS,KAAK,MAAM,iBAAiB,KAAK,UAAU,EAAA,CAAG,iBAAiB,CAAC;GACvH,OAAO,kBAAkB;IACxB,KAAK,KAAK;IACV,cAAc,KAAK;IACnB,eAAe,KAAK;IACpB,KAAK;KACJ,MAAM,KAAK;KACX,YAAY,KAAK;IAClB;IACA;IACA,GAAG,KAAK,YAAY,KAAK,IAAI,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;GAC3D,CAAC;EACF;EACA,QAAQ,UAAU;CACnB,CAAC,CAAC,CAAC,KAAK,OAAO,KAAK,aAAa;EAChC,aAAa,QAAQ;EACrB,YAAY,KAAK;CAClB,EAAE,CAAC;CACH,cAAc,OAAO;AACtB;;AAEA,MAAM,6BAA6B,SAAS,OAAO,cAAc,OAAO,QAAQ,2BAA2B,CAAC;;;;;;;;;;;;;;;;;;;AAqB5G,MAAM,SAAS,SAAS,oBAAoB;;;;;;AAM5C,eAAe,aAAa,KAAK,QAAQ,CAAC,GAAG;CAC5C,MAAM,oBAAoB,YAAY;EACrC,MAAM,SAAS,IAAI,GAAG,OAAO,EAAE,kBAAkB,iBAAiB,GAAG,EAAE,CAAC;EACxE,OAAO,GAAG,UAAU,UAAU,QAAQ,MAAM,+BAA+B,KAAK,CAAC;EACjF,MAAM,OAAO,QAAQ;EACrB,IAAI;GACH,MAAM,OAAO,MAAM,UAAU;EAC9B,UAAU;GACT,MAAM,OAAO,IAAI;EAClB;CACD,GAAG,KAAK;AACT;;;;;;;;AAQA,MAAM,wBAAwB;CAC7B,YAAY,OAAO,QAAQ,CAAC,CAAC;CAC7B,YAAY,EAAE,WAAW,OAAO,WAAW;EAC1C,WAAW,aAAa,KAAK,GAAG;EAChC,QAAQ,UAAU;CACnB,CAAC,CAAC,CAAC,KAAK,OAAO,WAAW,EAAE,KAAK,KAAK,IAAI,EAAE,CAAC;CAC7C,cAAc,OAAO;AACtB;;AAEA,MAAM,uBAAuB,SAAS,OAAO,QAAQ,OAAO,QAAQ,qBAAqB,CAAC;AAG1F,SAAS,aAAa,SAAS;CAC9B,MAAM,yBAAyB,IAAI,IAAI;CACvC,KAAK,MAAM,SAAS,SAAS,IAAI,CAAC,OAAO,IAAI,MAAM,IAAI,GAAG,OAAO,IAAI,MAAM,MAAM,KAAK;CACtF,OAAO,CAAC,GAAG,OAAO,OAAO,CAAC;AAC3B;;AAEA,SAAS,uBAAuB,SAAS,gBAAgB,KAAK;CAC7D,IAAI,uBAAuB,OAAO,GAAG;CACrC,IAAI,eAAe,OAAO,GAAG;EAC5B,IAAI,KAAK,WAAW,SAAS,4CAA4C,eAAe,EAAE,CAAC;EAC3F;CACD;CACA,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;CACrD,MAAM,UAAU,MAAM,QAAQ,OAAO,IAAI,UAAU,OAAO,OAAO,OAAO;CACxE,KAAK,MAAM,UAAU,SAAS,uBAAuB,QAAQ,gBAAgB,GAAG;AACjF;;AAEA,SAAS,sBAAsB,OAAO;CACrC,MAAM,gBAAgB,CAAC;CACvB,KAAK,MAAM,EAAE,gBAAgB,aAAa,cAAc,KAAK,GAAG;EAC/D,MAAM,YAAY,CAAC;EACnB,uBAAuB,SAAS,gBAAgB,SAAS;EACzD,KAAK,MAAM,QAAQ,WAAW,cAAc,KAAK;GAChD;GACA;EACD,CAAC;CACF;CACA,MAAM,YAAY,aAAa,cAAc,KAAK,CAAC,CAAC,QAAQ,YAAY,iBAAiB,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,aAAa;EAC5H,MAAM,UAAU,OAAO;EACvB,gBAAgB,QAAQ;CACzB,EAAE,CAAC;CACH,OAAO;EACN,SAAS,aAAa,aAAa;EACnC;CACD;AACD;;;;;;;;;;;;;;;;AAkBA,MAAM,gBAAgB,SAAS,2BAA2B;;;;;;;;AAQ1D,MAAM,+BAA+B;CACpC,YAAY,OAAO,QAAQ,CAAC,CAAC;CAC7B,YAAY,EAAE,aAAa,OAAO,WAAW,UAAU,YAAY,CAAC;CACpE,cAAc,OAAO;AACtB;;AAEA,MAAM,8BAA8B,SAAS,OAAO,eAAe,OAAO,QAAQ,4BAA4B,CAAC"}
|