@prisma/composer-prisma-cloud 0.16.0 → 0.17.0-dev.2
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.d.mts +15 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +19 -20
- package/dist/control.mjs.map +1 -1
- package/dist/local-target.mjs +1 -1
- package/dist/local-target.mjs.map +1 -1
- package/dist/{s3-credentials-resource-D_qSGYMM-CnDQrSMW.mjs → s3-credentials-resource-CDab6Xhp-DhYo1-tR.mjs} +13 -13
- package/dist/s3-credentials-resource-CDab6Xhp-DhYo1-tR.mjs.map +1 -0
- package/package.json +18 -18
- package/dist/s3-credentials-resource-D_qSGYMM-CnDQrSMW.mjs.map +0 -1
package/dist/buckets-main.mjs
CHANGED
|
@@ -629,9 +629,6 @@ function main() {
|
|
|
629
629
|
buckets: {},
|
|
630
630
|
credentials: {}
|
|
631
631
|
};
|
|
632
|
-
function schedulePersist() {
|
|
633
|
-
stateFile.write(state);
|
|
634
|
-
}
|
|
635
632
|
const store = fsStore((physicalName) => state.buckets[physicalName]?.dir);
|
|
636
633
|
function json(res, status, body) {
|
|
637
634
|
res.writeHead(status, { "content-type": "application/json" });
|
|
@@ -661,7 +658,7 @@ function main() {
|
|
|
661
658
|
name,
|
|
662
659
|
dir: parsed.dir
|
|
663
660
|
};
|
|
664
|
-
|
|
661
|
+
await stateFile.write(state);
|
|
665
662
|
res.writeHead(204);
|
|
666
663
|
res.end();
|
|
667
664
|
}
|
|
@@ -680,14 +677,14 @@ function main() {
|
|
|
680
677
|
app,
|
|
681
678
|
secretAccessKey: parsed.secretAccessKey
|
|
682
679
|
};
|
|
683
|
-
|
|
680
|
+
await stateFile.write(state);
|
|
684
681
|
res.writeHead(204);
|
|
685
682
|
res.end();
|
|
686
683
|
}
|
|
687
|
-
function handleDeleteApp(res, app) {
|
|
684
|
+
async function handleDeleteApp(res, app) {
|
|
688
685
|
for (const [key, reg] of Object.entries(state.buckets)) if (reg.app === app) delete state.buckets[key];
|
|
689
686
|
for (const [key, cred] of Object.entries(state.credentials)) if (cred.app === app) delete state.credentials[key];
|
|
690
|
-
|
|
687
|
+
await stateFile.write(state);
|
|
691
688
|
res.writeHead(204);
|
|
692
689
|
res.end();
|
|
693
690
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buckets-main.mjs","names":["fs"],"sources":["../../../1-prisma-cloud/0-lowering/s3-protocol/dist/index.mjs","../../../1-prisma-cloud/0-lowering/dev-emulators/dist/buckets-main.mjs"],"sourcesContent":["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 { c as readOwnVersion, f as StateFile, p as readJsonFile, t as isValidSegment } from \"./segments-D-anjQ84.mjs\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as http from \"node:http\";\nimport { createS3Handler, fsStore } from \"@internal/s3-protocol\";\n//#region src/buckets-main.ts\n/**\n* The bucket emulator daemon (local-dev spec § 2 `buckets-main.ts`): the S3\n* wire protocol (`@internal/s3-protocol`'s handler + `fsStore`) over\n* registered per-app, per-bucket directories, multi-tenant via physical\n* names `<app>--<name>`. Admin lives under `/_pcdev/` (the underscore can't\n* collide with a valid bucket name). Plain `node:http`.\n*\n* Runs as its own OS process, started by `daemon.ts`'s `ensureDaemon` via\n* `process.execPath <this file> --port <n> --state-dir <dir>`.\n*/\nconst STATE_MODE = 384;\nconst PHYSICAL_BUCKET_NAME_RE = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;\nconst MULTIPART_MESSAGE = \"multipart upload is not supported by the local dev bucket emulator yet\";\nfunction isBucketRegistration(value) {\n\treturn typeof value === \"object\" && value !== null && \"app\" in value && typeof value.app === \"string\" && \"name\" in value && typeof value.name === \"string\" && \"dir\" in value && typeof value.dir === \"string\";\n}\nfunction isCredentialRecord(value) {\n\treturn typeof value === \"object\" && value !== null && \"app\" in value && typeof value.app === \"string\" && \"secretAccessKey\" in value && typeof value.secretAccessKey === \"string\";\n}\nfunction isBucketsState(value) {\n\treturn typeof value === \"object\" && value !== null && \"buckets\" in value && typeof value.buckets === \"object\" && value.buckets !== null && Object.values(value.buckets).every(isBucketRegistration) && \"credentials\" in value && typeof value.credentials === \"object\" && value.credentials !== null && Object.values(value.credentials).every(isCredentialRecord);\n}\nfunction isBucketBody(value) {\n\treturn typeof value === \"object\" && value !== null && \"dir\" in value && typeof value.dir === \"string\";\n}\nfunction isCredentialsBody(value) {\n\treturn typeof value === \"object\" && value !== null && \"accessKeyId\" in value && typeof value.accessKeyId === \"string\" && \"secretAccessKey\" in value && typeof value.secretAccessKey === \"string\";\n}\nfunction parseArgs(argv) {\n\tlet port;\n\tlet stateDir;\n\tfor (let i = 0; i < argv.length; i++) if (argv[i] === \"--port\") port = Number(argv[i + 1]);\n\telse if (argv[i] === \"--state-dir\") stateDir = argv[i + 1];\n\tif (port === void 0 || Number.isNaN(port)) throw new Error(\"buckets-main: --port <n> is required\");\n\tif (stateDir === void 0) throw new Error(\"buckets-main: --state-dir <dir> is required\");\n\treturn {\n\t\tport,\n\t\tstateDir\n\t};\n}\nfunction readBody(req) {\n\treturn new Promise((resolve, reject) => {\n\t\tconst chunks = [];\n\t\treq.on(\"data\", (chunk) => chunks.push(chunk));\n\t\treq.on(\"end\", () => resolve(Buffer.concat(chunks)));\n\t\treq.on(\"error\", reject);\n\t});\n}\nfunction toWebHeaders(nodeHeaders) {\n\tconst headers = new Headers();\n\tfor (const [key, value] of Object.entries(nodeHeaders)) {\n\t\tif (value === void 0) continue;\n\t\tif (Array.isArray(value)) for (const v of value) headers.append(key, v);\n\t\telse headers.set(key, value);\n\t}\n\treturn headers;\n}\nasync function sendWebResponse(res, webRes) {\n\tconst headers = {};\n\twebRes.headers.forEach((value, key) => {\n\t\theaders[key] = value;\n\t});\n\tconst buf = Buffer.from(await webRes.arrayBuffer());\n\tres.writeHead(webRes.status, headers);\n\tres.end(buf);\n}\nfunction main() {\n\tconst { port, stateDir } = parseArgs(process.argv.slice(2));\n\tconst ownVersion = readOwnVersion();\n\tconst stateJsonPath = path.join(stateDir, \"state.json\");\n\tconst stateFile = new StateFile(stateJsonPath, STATE_MODE);\n\tlet state = {\n\t\tbuckets: {},\n\t\tcredentials: {}\n\t};\n\tfunction schedulePersist() {\n\t\tstateFile.write(state);\n\t}\n\tconst store = fsStore((physicalName) => state.buckets[physicalName]?.dir);\n\tfunction json(res, status, body) {\n\t\tres.writeHead(status, { \"content-type\": \"application/json\" });\n\t\tres.end(JSON.stringify(body));\n\t}\n\tfunction text(res, status, body) {\n\t\tres.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\tres.end(body);\n\t}\n\tfunction badSegment(res, segment) {\n\t\ttext(res, 400, `invalid path segment \"${segment}\": must match /^[a-z0-9][a-z0-9-]*$/ and be at most 63 characters`);\n\t}\n\tasync function handlePutBucket(req, res, app, name) {\n\t\tconst physicalName = `${app}--${name}`;\n\t\tif (!PHYSICAL_BUCKET_NAME_RE.test(physicalName)) return text(res, 400, `invalid bucket \"${physicalName}\" (app \"${app}\", name \"${name}\"): the physical bucket name must match /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/ and be at most 63 characters`);\n\t\tconst raw = await readBody(req);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw.toString(\"utf8\"));\n\t\t} catch {\n\t\t\treturn text(res, 400, \"malformed JSON body\");\n\t\t}\n\t\tif (!isBucketBody(parsed)) return text(res, 400, \"malformed bucket body: expected { \\\"dir\\\": string }\");\n\t\tawait fs.promises.mkdir(parsed.dir, { recursive: true });\n\t\tstate.buckets[physicalName] = {\n\t\t\tapp,\n\t\t\tname,\n\t\t\tdir: parsed.dir\n\t\t};\n\t\tschedulePersist();\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\tasync function handlePutCredentials(req, res, app) {\n\t\tconst raw = await readBody(req);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw.toString(\"utf8\"));\n\t\t} catch {\n\t\t\treturn text(res, 400, \"malformed JSON body\");\n\t\t}\n\t\tif (!isCredentialsBody(parsed)) return text(res, 400, \"malformed credentials body: expected { \\\"accessKeyId\\\", \\\"secretAccessKey\\\" }\");\n\t\tconst existing = state.credentials[parsed.accessKeyId];\n\t\tif (existing && existing.app !== app) return text(res, 409, `accessKeyId \"${parsed.accessKeyId}\" is already registered by a different app`);\n\t\tstate.credentials[parsed.accessKeyId] = {\n\t\t\tapp,\n\t\t\tsecretAccessKey: parsed.secretAccessKey\n\t\t};\n\t\tschedulePersist();\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\tfunction handleDeleteApp(res, app) {\n\t\tfor (const [key, reg] of Object.entries(state.buckets)) if (reg.app === app) delete state.buckets[key];\n\t\tfor (const [key, cred] of Object.entries(state.credentials)) if (cred.app === app) delete state.credentials[key];\n\t\tschedulePersist();\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\t/** Path-style addressing: the bucket is the first non-empty path segment. Mirrors the handler's own `parseTarget`, which isn't exported. */\n\tfunction bucketFromPath(pathname) {\n\t\tconst first = pathname.split(\"/\").find((s) => s.length > 0);\n\t\treturn first !== void 0 ? decodeURIComponent(first) : void 0;\n\t}\n\t/**\n\t* Credentials accepted for THIS request's target bucket only — its\n\t* owning app, derived from the bucket's registration (the authoritative\n\t* source for the `<app>--<name>` split; unregistered apps/names may\n\t* themselves contain `--`, so the registration is trusted over re-parsing\n\t* the string). An unknown bucket or an app with no registered credentials\n\t* yields no candidates, which still resolves through the real 403 path\n\t* below — never a bespoke \"unknown bucket\" shortcut that would reveal\n\t* anything.\n\t*/\n\tfunction credentialsForBucket(bucket) {\n\t\tconst owningApp = bucket !== void 0 ? state.buckets[bucket]?.app : void 0;\n\t\tif (owningApp === void 0) return [];\n\t\treturn Object.entries(state.credentials).filter(([, rec]) => rec.app === owningApp).map(([accessKeyId, rec]) => ({\n\t\t\taccessKeyId,\n\t\t\tsecretAccessKey: rec.secretAccessKey\n\t\t}));\n\t}\n\tasync function handleS3Wire(req, res, url) {\n\t\tif (url.searchParams.has(\"uploads\") || url.searchParams.has(\"uploadId\") || url.searchParams.has(\"partNumber\")) return text(res, 501, MULTIPART_MESSAGE);\n\t\tconst method = req.method ?? \"GET\";\n\t\tconst bodyBuf = method !== \"GET\" && method !== \"HEAD\" ? await readBody(req) : void 0;\n\t\tconst fullUrl = `http://${req.headers.host ?? `127.0.0.1:${String(port)}`}${req.url ?? \"/\"}`;\n\t\tconst headers = toWebHeaders(req.headers);\n\t\tconst candidates = credentialsForBucket(bucketFromPath(url.pathname));\n\t\tif (candidates.length === 0) candidates.push({\n\t\t\taccessKeyId: \"\",\n\t\t\tsecretAccessKey: \"\"\n\t\t});\n\t\tlet last;\n\t\tfor (const credentials of candidates) {\n\t\t\tconst webReq = new Request(fullUrl, {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\t...bodyBuf && bodyBuf.length > 0 ? { body: bodyBuf } : {}\n\t\t\t});\n\t\t\tconst webRes = await createS3Handler({\n\t\t\t\tstore,\n\t\t\t\tcredentials\n\t\t\t})(webReq);\n\t\t\tif (webRes.status !== 403) return sendWebResponse(res, webRes);\n\t\t\tlast = webRes;\n\t\t}\n\t\tif (last) await sendWebResponse(res, last);\n\t}\n\tasync function handleRequest(req, res) {\n\t\tconst url = new URL(req.url ?? \"/\", `http://127.0.0.1:${String(port)}`);\n\t\tconst method = req.method ?? \"GET\";\n\t\tif (method === \"GET\" && url.pathname === \"/health\") return json(res, 200, { version: ownVersion });\n\t\tif (url.pathname === \"/_pcdev/health\" || url.pathname.startsWith(\"/_pcdev/\")) {\n\t\t\tconst segments = url.pathname.split(\"/\").filter((s) => s.length > 0).map((s) => decodeURIComponent(s));\n\t\t\tif (method === \"GET\" && segments.length === 2 && segments[1] === \"health\") return json(res, 200, { version: ownVersion });\n\t\t\tif (segments[1] === \"apps\" && segments.length >= 3) {\n\t\t\t\tconst app = segments[2];\n\t\t\t\tif (app === void 0 || !isValidSegment(app)) return badSegment(res, app ?? \"\");\n\t\t\t\tif (method === \"PUT\" && segments.length === 5 && segments[3] === \"buckets\") {\n\t\t\t\t\tconst name = segments[4];\n\t\t\t\t\tif (name === void 0 || !isValidSegment(name)) return badSegment(res, name ?? \"\");\n\t\t\t\t\treturn handlePutBucket(req, res, app, name);\n\t\t\t\t}\n\t\t\t\tif (method === \"PUT\" && segments.length === 4 && segments[3] === \"credentials\") return handlePutCredentials(req, res, app);\n\t\t\t\tif (method === \"DELETE\" && segments.length === 3) return handleDeleteApp(res, app);\n\t\t\t}\n\t\t\tres.writeHead(404);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\treturn handleS3Wire(req, res, url);\n\t}\n\tconst server = http.createServer((req, res) => {\n\t\thandleRequest(req, res).catch((err) => {\n\t\t\tif (!res.headersSent) res.writeHead(500, { \"content-type\": \"text/plain\" });\n\t\t\tres.end(err instanceof Error ? err.message : String(err));\n\t\t});\n\t});\n\tasync function shutdown() {\n\t\tawait stateFile.flush();\n\t\tserver.close();\n\t\tprocess.exit(0);\n\t}\n\tprocess.on(\"SIGTERM\", () => void shutdown());\n\tprocess.on(\"SIGINT\", () => void shutdown());\n\treadJsonFile(stateJsonPath, isBucketsState).then((loaded) => {\n\t\tif (loaded) state = loaded;\n\t\tserver.listen(port, \"127.0.0.1\", () => {\n\t\t\tconsole.log(`[dev-emulators] buckets-main listening on 127.0.0.1:${String(port)}`);\n\t\t});\n\t}).catch((err) => {\n\t\tconsole.error(\"buckets-main: failed to load state\", err);\n\t\tprocess.exit(1);\n\t});\n}\nmain();\n//#endregion\nexport {};\n\n//# sourceMappingURL=buckets-main.mjs.map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"buckets-main.mjs","names":["fs"],"sources":["../../../1-prisma-cloud/0-lowering/s3-protocol/dist/index.mjs","../../../1-prisma-cloud/0-lowering/dev-emulators/dist/buckets-main.mjs"],"sourcesContent":["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 { c as readOwnVersion, f as StateFile, p as readJsonFile, t as isValidSegment } from \"./segments-D-anjQ84.mjs\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as http from \"node:http\";\nimport { createS3Handler, fsStore } from \"@internal/s3-protocol\";\n//#region src/buckets-main.ts\n/**\n* The bucket emulator daemon (local-dev spec § 2 `buckets-main.ts`): the S3\n* wire protocol (`@internal/s3-protocol`'s handler + `fsStore`) over\n* registered per-app, per-bucket directories, multi-tenant via physical\n* names `<app>--<name>`. Admin lives under `/_pcdev/` (the underscore can't\n* collide with a valid bucket name). Plain `node:http`.\n*\n* Runs as its own OS process, started by `daemon.ts`'s `ensureDaemon` via\n* `process.execPath <this file> --port <n> --state-dir <dir>`.\n*/\nconst STATE_MODE = 384;\nconst PHYSICAL_BUCKET_NAME_RE = /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/;\nconst MULTIPART_MESSAGE = \"multipart upload is not supported by the local dev bucket emulator yet\";\nfunction isBucketRegistration(value) {\n\treturn typeof value === \"object\" && value !== null && \"app\" in value && typeof value.app === \"string\" && \"name\" in value && typeof value.name === \"string\" && \"dir\" in value && typeof value.dir === \"string\";\n}\nfunction isCredentialRecord(value) {\n\treturn typeof value === \"object\" && value !== null && \"app\" in value && typeof value.app === \"string\" && \"secretAccessKey\" in value && typeof value.secretAccessKey === \"string\";\n}\nfunction isBucketsState(value) {\n\treturn typeof value === \"object\" && value !== null && \"buckets\" in value && typeof value.buckets === \"object\" && value.buckets !== null && Object.values(value.buckets).every(isBucketRegistration) && \"credentials\" in value && typeof value.credentials === \"object\" && value.credentials !== null && Object.values(value.credentials).every(isCredentialRecord);\n}\nfunction isBucketBody(value) {\n\treturn typeof value === \"object\" && value !== null && \"dir\" in value && typeof value.dir === \"string\";\n}\nfunction isCredentialsBody(value) {\n\treturn typeof value === \"object\" && value !== null && \"accessKeyId\" in value && typeof value.accessKeyId === \"string\" && \"secretAccessKey\" in value && typeof value.secretAccessKey === \"string\";\n}\nfunction parseArgs(argv) {\n\tlet port;\n\tlet stateDir;\n\tfor (let i = 0; i < argv.length; i++) if (argv[i] === \"--port\") port = Number(argv[i + 1]);\n\telse if (argv[i] === \"--state-dir\") stateDir = argv[i + 1];\n\tif (port === void 0 || Number.isNaN(port)) throw new Error(\"buckets-main: --port <n> is required\");\n\tif (stateDir === void 0) throw new Error(\"buckets-main: --state-dir <dir> is required\");\n\treturn {\n\t\tport,\n\t\tstateDir\n\t};\n}\nfunction readBody(req) {\n\treturn new Promise((resolve, reject) => {\n\t\tconst chunks = [];\n\t\treq.on(\"data\", (chunk) => chunks.push(chunk));\n\t\treq.on(\"end\", () => resolve(Buffer.concat(chunks)));\n\t\treq.on(\"error\", reject);\n\t});\n}\nfunction toWebHeaders(nodeHeaders) {\n\tconst headers = new Headers();\n\tfor (const [key, value] of Object.entries(nodeHeaders)) {\n\t\tif (value === void 0) continue;\n\t\tif (Array.isArray(value)) for (const v of value) headers.append(key, v);\n\t\telse headers.set(key, value);\n\t}\n\treturn headers;\n}\nasync function sendWebResponse(res, webRes) {\n\tconst headers = {};\n\twebRes.headers.forEach((value, key) => {\n\t\theaders[key] = value;\n\t});\n\tconst buf = Buffer.from(await webRes.arrayBuffer());\n\tres.writeHead(webRes.status, headers);\n\tres.end(buf);\n}\nfunction main() {\n\tconst { port, stateDir } = parseArgs(process.argv.slice(2));\n\tconst ownVersion = readOwnVersion();\n\tconst stateJsonPath = path.join(stateDir, \"state.json\");\n\tconst stateFile = new StateFile(stateJsonPath, STATE_MODE);\n\tlet state = {\n\t\tbuckets: {},\n\t\tcredentials: {}\n\t};\n\tconst store = fsStore((physicalName) => state.buckets[physicalName]?.dir);\n\tfunction json(res, status, body) {\n\t\tres.writeHead(status, { \"content-type\": \"application/json\" });\n\t\tres.end(JSON.stringify(body));\n\t}\n\tfunction text(res, status, body) {\n\t\tres.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\tres.end(body);\n\t}\n\tfunction badSegment(res, segment) {\n\t\ttext(res, 400, `invalid path segment \"${segment}\": must match /^[a-z0-9][a-z0-9-]*$/ and be at most 63 characters`);\n\t}\n\tasync function handlePutBucket(req, res, app, name) {\n\t\tconst physicalName = `${app}--${name}`;\n\t\tif (!PHYSICAL_BUCKET_NAME_RE.test(physicalName)) return text(res, 400, `invalid bucket \"${physicalName}\" (app \"${app}\", name \"${name}\"): the physical bucket name must match /^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$/ and be at most 63 characters`);\n\t\tconst raw = await readBody(req);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw.toString(\"utf8\"));\n\t\t} catch {\n\t\t\treturn text(res, 400, \"malformed JSON body\");\n\t\t}\n\t\tif (!isBucketBody(parsed)) return text(res, 400, \"malformed bucket body: expected { \\\"dir\\\": string }\");\n\t\tawait fs.promises.mkdir(parsed.dir, { recursive: true });\n\t\tstate.buckets[physicalName] = {\n\t\t\tapp,\n\t\t\tname,\n\t\t\tdir: parsed.dir\n\t\t};\n\t\tawait stateFile.write(state);\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\tasync function handlePutCredentials(req, res, app) {\n\t\tconst raw = await readBody(req);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw.toString(\"utf8\"));\n\t\t} catch {\n\t\t\treturn text(res, 400, \"malformed JSON body\");\n\t\t}\n\t\tif (!isCredentialsBody(parsed)) return text(res, 400, \"malformed credentials body: expected { \\\"accessKeyId\\\", \\\"secretAccessKey\\\" }\");\n\t\tconst existing = state.credentials[parsed.accessKeyId];\n\t\tif (existing && existing.app !== app) return text(res, 409, `accessKeyId \"${parsed.accessKeyId}\" is already registered by a different app`);\n\t\tstate.credentials[parsed.accessKeyId] = {\n\t\t\tapp,\n\t\t\tsecretAccessKey: parsed.secretAccessKey\n\t\t};\n\t\tawait stateFile.write(state);\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\tasync function handleDeleteApp(res, app) {\n\t\tfor (const [key, reg] of Object.entries(state.buckets)) if (reg.app === app) delete state.buckets[key];\n\t\tfor (const [key, cred] of Object.entries(state.credentials)) if (cred.app === app) delete state.credentials[key];\n\t\tawait stateFile.write(state);\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\t/** Path-style addressing: the bucket is the first non-empty path segment. Mirrors the handler's own `parseTarget`, which isn't exported. */\n\tfunction bucketFromPath(pathname) {\n\t\tconst first = pathname.split(\"/\").find((s) => s.length > 0);\n\t\treturn first !== void 0 ? decodeURIComponent(first) : void 0;\n\t}\n\t/**\n\t* Credentials accepted for THIS request's target bucket only — its\n\t* owning app, derived from the bucket's registration (the authoritative\n\t* source for the `<app>--<name>` split; unregistered apps/names may\n\t* themselves contain `--`, so the registration is trusted over re-parsing\n\t* the string). An unknown bucket or an app with no registered credentials\n\t* yields no candidates, which still resolves through the real 403 path\n\t* below — never a bespoke \"unknown bucket\" shortcut that would reveal\n\t* anything.\n\t*/\n\tfunction credentialsForBucket(bucket) {\n\t\tconst owningApp = bucket !== void 0 ? state.buckets[bucket]?.app : void 0;\n\t\tif (owningApp === void 0) return [];\n\t\treturn Object.entries(state.credentials).filter(([, rec]) => rec.app === owningApp).map(([accessKeyId, rec]) => ({\n\t\t\taccessKeyId,\n\t\t\tsecretAccessKey: rec.secretAccessKey\n\t\t}));\n\t}\n\tasync function handleS3Wire(req, res, url) {\n\t\tif (url.searchParams.has(\"uploads\") || url.searchParams.has(\"uploadId\") || url.searchParams.has(\"partNumber\")) return text(res, 501, MULTIPART_MESSAGE);\n\t\tconst method = req.method ?? \"GET\";\n\t\tconst bodyBuf = method !== \"GET\" && method !== \"HEAD\" ? await readBody(req) : void 0;\n\t\tconst fullUrl = `http://${req.headers.host ?? `127.0.0.1:${String(port)}`}${req.url ?? \"/\"}`;\n\t\tconst headers = toWebHeaders(req.headers);\n\t\tconst candidates = credentialsForBucket(bucketFromPath(url.pathname));\n\t\tif (candidates.length === 0) candidates.push({\n\t\t\taccessKeyId: \"\",\n\t\t\tsecretAccessKey: \"\"\n\t\t});\n\t\tlet last;\n\t\tfor (const credentials of candidates) {\n\t\t\tconst webReq = new Request(fullUrl, {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\t...bodyBuf && bodyBuf.length > 0 ? { body: bodyBuf } : {}\n\t\t\t});\n\t\t\tconst webRes = await createS3Handler({\n\t\t\t\tstore,\n\t\t\t\tcredentials\n\t\t\t})(webReq);\n\t\t\tif (webRes.status !== 403) return sendWebResponse(res, webRes);\n\t\t\tlast = webRes;\n\t\t}\n\t\tif (last) await sendWebResponse(res, last);\n\t}\n\tasync function handleRequest(req, res) {\n\t\tconst url = new URL(req.url ?? \"/\", `http://127.0.0.1:${String(port)}`);\n\t\tconst method = req.method ?? \"GET\";\n\t\tif (method === \"GET\" && url.pathname === \"/health\") return json(res, 200, { version: ownVersion });\n\t\tif (url.pathname === \"/_pcdev/health\" || url.pathname.startsWith(\"/_pcdev/\")) {\n\t\t\tconst segments = url.pathname.split(\"/\").filter((s) => s.length > 0).map((s) => decodeURIComponent(s));\n\t\t\tif (method === \"GET\" && segments.length === 2 && segments[1] === \"health\") return json(res, 200, { version: ownVersion });\n\t\t\tif (segments[1] === \"apps\" && segments.length >= 3) {\n\t\t\t\tconst app = segments[2];\n\t\t\t\tif (app === void 0 || !isValidSegment(app)) return badSegment(res, app ?? \"\");\n\t\t\t\tif (method === \"PUT\" && segments.length === 5 && segments[3] === \"buckets\") {\n\t\t\t\t\tconst name = segments[4];\n\t\t\t\t\tif (name === void 0 || !isValidSegment(name)) return badSegment(res, name ?? \"\");\n\t\t\t\t\treturn handlePutBucket(req, res, app, name);\n\t\t\t\t}\n\t\t\t\tif (method === \"PUT\" && segments.length === 4 && segments[3] === \"credentials\") return handlePutCredentials(req, res, app);\n\t\t\t\tif (method === \"DELETE\" && segments.length === 3) return handleDeleteApp(res, app);\n\t\t\t}\n\t\t\tres.writeHead(404);\n\t\t\tres.end();\n\t\t\treturn;\n\t\t}\n\t\treturn handleS3Wire(req, res, url);\n\t}\n\tconst server = http.createServer((req, res) => {\n\t\thandleRequest(req, res).catch((err) => {\n\t\t\tif (!res.headersSent) res.writeHead(500, { \"content-type\": \"text/plain\" });\n\t\t\tres.end(err instanceof Error ? err.message : String(err));\n\t\t});\n\t});\n\tasync function shutdown() {\n\t\tawait stateFile.flush();\n\t\tserver.close();\n\t\tprocess.exit(0);\n\t}\n\tprocess.on(\"SIGTERM\", () => void shutdown());\n\tprocess.on(\"SIGINT\", () => void shutdown());\n\treadJsonFile(stateJsonPath, isBucketsState).then((loaded) => {\n\t\tif (loaded) state = loaded;\n\t\tserver.listen(port, \"127.0.0.1\", () => {\n\t\t\tconsole.log(`[dev-emulators] buckets-main listening on 127.0.0.1:${String(port)}`);\n\t\t});\n\t}).catch((err) => {\n\t\tconsole.error(\"buckets-main: failed to load state\", err);\n\t\tprocess.exit(1);\n\t});\n}\nmain();\n//#endregion\nexport {};\n\n//# sourceMappingURL=buckets-main.mjs.map"],"mappings":"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"}
|
package/dist/control.d.mts
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
import { t as ProviderParamEntry } from "./serializer-BD_6nkr4-DWn5NNTC.mjs";
|
|
2
|
+
import "effect/Context";
|
|
2
3
|
import "effect/Effect";
|
|
4
|
+
import "effect/Layer";
|
|
5
|
+
import "effect/Config";
|
|
6
|
+
import { createManagementApiClient, paths } from "@prisma/management-api-sdk";
|
|
7
|
+
import "effect/Redacted";
|
|
8
|
+
import "alchemy/Provider";
|
|
3
9
|
import * as Output from "alchemy/Output";
|
|
4
|
-
import
|
|
10
|
+
import { Resource } from "alchemy";
|
|
11
|
+
import { EnvironmentVariable } from "alchemy/Prisma";
|
|
5
12
|
import { ExtensionDescriptor, StateDescriptor } from "@prisma/composer/config";
|
|
13
|
+
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/index.d.mts
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/container.d.ts
|
|
16
|
+
/** The region ids the Management API accepts for a new Project — the platform's published contract, not a Composer-owned list. */
|
|
17
|
+
type ProjectRegion = NonNullable<NonNullable<paths['/v1/projects']['post']['requestBody']>['content']['application/json']['region']>;
|
|
18
|
+
//#endregion
|
|
6
19
|
//#region ../../1-prisma-cloud/1-extensions/target/dist/control.d.mts
|
|
7
20
|
//#region src/descriptors/shared.d.ts
|
|
8
21
|
/**
|
|
@@ -60,7 +73,7 @@ interface PrismaCloudOptions {
|
|
|
60
73
|
/** Defaults to the PRISMA_WORKSPACE_ID environment variable. */
|
|
61
74
|
workspaceId?: string;
|
|
62
75
|
/** Defaults to the PRISMA_REGION environment variable when set. */
|
|
63
|
-
region?:
|
|
76
|
+
region?: ProjectRegion;
|
|
64
77
|
}
|
|
65
78
|
/**
|
|
66
79
|
* One brand's deploy-side value registration: edge-derived (`value(refs)`,
|
package/dist/control.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.mts","names":[],"sources":["../../../1-prisma-cloud/1-extensions/target/dist/control.d.mts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../../../1-prisma-cloud/0-lowering/lowering/dist/index.d.mts","../../../1-prisma-cloud/1-extensions/target/dist/control.d.mts"],"mappings":";;;;;;;;;;;;;;;;KAkBK,gBAAgB,YAAY,YAAY;;;;;;;;;;;;;;;;;;;UCInC,sBAAsB;;;;;;;;WAQrB,QAAQ,6BAA6B,OAAO;;;;;;;;UAQ7C;WACC,gBAAgB,OAAO;;;;;;;;;;;;UAYxB,6BAA6B;WAC5B,kBAAkB,aAAa,8BAA8B,oBAAoB,OAAO;;;;;cAKrF,mBAAmB;UACvB;;EAER;;EAEA,SAAS;;;;;;;;KAQN,qBAAqB,KAAK,0BAA0B,KAAK;;;;;;;;;;iBAU7C,oBAAoB,kBAAkB,sBAAsB,QAAQ,oBAAoB,sBAAsB,oBAAoB,gBAAgB;cACrJ,iBAAiB,oBAAoB,gBAAgB;;cAErD,cAAc,OAAO,uBAAuB"}
|
package/dist/control.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { o as paramBindingFor, s as paramName } from "./secret-Dgyg1WyG-Dzz95fGI
|
|
|
2
2
|
import { a as encode, c as paramEntries, d as serializeInput, n as configKey, o as encodeParamPointer, r as decodeParamPointer, s as isParamPointerRow } from "./serializer-DTCrRl7S-CN0q1ZFB.mjs";
|
|
3
3
|
import { a as provisionedEdges, n as SELF_ORIGIN, r as STREAMS_API_KEY, t as RESERVED_PROVIDER_PARAMS } from "./provisioned-edges-DKsBi7uK-BmsYKWZI.mjs";
|
|
4
4
|
import { n as requiredPackHeadOf } from "./required-pack-head-CMMJ2LaU-CfWu5JMj.mjs";
|
|
5
|
-
import { A as collectPages, C as appAfterEnvironment, D as RESERVED_DATABASE_URL_KEYS, E as PrismaApiError, F as fromEnv, I as managementApiBaseUrl, M as layer, N as resolveDefaultBranchId, O as call, P as PrismaCredentials, S as ServiceKeyProvider, T as ManagementClient, _ as resolveTargetRef, a as PRISMA_CLOUD_EXTENSION_ID, b as providers, d as collectPreflightNames, f as containerDescriptor, g as resolveOrmConfig, h as prismaCloudContainerOf, i as OrmMigrationProvider, j as drivePagesAsync, k as claimDatabaseUrlKeys, l as S3Credentials, m as packHeadRefHashes, n as GeneratedParamProvider, o as PgWarm, r as OrmMigration, s as PgWarmProvider, t as GeneratedParam, u as S3CredentialsProvider, w as isWithin, x as ServiceKey } from "./s3-credentials-resource-
|
|
5
|
+
import { A as collectPages, C as appAfterEnvironment, D as RESERVED_DATABASE_URL_KEYS, E as PrismaApiError, F as fromEnv, I as managementApiBaseUrl, M as layer, N as resolveDefaultBranchId, O as call, P as PrismaCredentials, S as ServiceKeyProvider, T as ManagementClient, _ as resolveTargetRef, a as PRISMA_CLOUD_EXTENSION_ID, b as providers, d as collectPreflightNames, f as containerDescriptor, g as resolveOrmConfig, h as prismaCloudContainerOf, i as OrmMigrationProvider, j as drivePagesAsync, k as claimDatabaseUrlKeys, l as S3Credentials, m as packHeadRefHashes, n as GeneratedParamProvider, o as PgWarm, r as OrmMigration, s as PgWarmProvider, t as GeneratedParam, u as S3CredentialsProvider, w as isWithin, x as ServiceKey } from "./s3-credentials-resource-CDab6Xhp-DhYo1-tR.mjs";
|
|
6
6
|
import { r as isPostgresResourceNode } from "./orm-postgres-ChW2Ewj7-Dnas0G3L.mjs";
|
|
7
7
|
import { isParamSource } from "@prisma/composer";
|
|
8
8
|
import { blindCast } from "@prisma/composer/casts";
|
|
@@ -1501,7 +1501,7 @@ const stageDatabase = ({ id, application, region }) => Effect.gen(function* () {
|
|
|
1501
1501
|
const branchId = attachmentBranchIdOf(application, id);
|
|
1502
1502
|
const db = yield* Prisma$1.Database(`${id}-db`, {
|
|
1503
1503
|
project: projectIdOf(application),
|
|
1504
|
-
region: region ?? "
|
|
1504
|
+
region: region ?? "inherit",
|
|
1505
1505
|
...branchId !== void 0 ? { branchId } : { name: id }
|
|
1506
1506
|
});
|
|
1507
1507
|
const conn = yield* Prisma$1.Connection(`${id}-conn`, {
|
|
@@ -1578,7 +1578,7 @@ function computeDescriptor(o) {
|
|
|
1578
1578
|
const svc = yield* Prisma$1.App(`${id}-svc`, {
|
|
1579
1579
|
project: projectId,
|
|
1580
1580
|
displayName: id,
|
|
1581
|
-
regionId: o().region
|
|
1581
|
+
...o().region !== void 0 ? { regionId: o().region } : {},
|
|
1582
1582
|
...branchId !== void 0 ? { branchId } : {}
|
|
1583
1583
|
});
|
|
1584
1584
|
return {
|
|
@@ -1811,10 +1811,15 @@ async function fillMissing(client, projectId, branchId, key, value) {
|
|
|
1811
1811
|
const tokenRequiredError = () => /* @__PURE__ */ new Error("environment variable PRISMA_SERVICE_TOKEN is required for deploy preflight.");
|
|
1812
1812
|
const listFailedError = (key, error) => /* @__PURE__ */ new Error(`deploy preflight: Prisma Management API error listing "${key}": ${JSON.stringify(error)}.`);
|
|
1813
1813
|
const fillFailedError = (key, error) => /* @__PURE__ */ new Error(`deploy preflight: failed to provision "${key}" from the deploy shell: ${JSON.stringify(error)}.`);
|
|
1814
|
-
function missingError(missing, branchId, stage) {
|
|
1815
|
-
const
|
|
1816
|
-
const
|
|
1817
|
-
|
|
1814
|
+
function missingError(missing, projectId, branchId, stage) {
|
|
1815
|
+
const lines = missing.map((m) => ` - ${m.name} (used by service "${m.serviceAddress}")`);
|
|
1816
|
+
const countPhrase = missing.length === 1 ? "1 required setting has" : `${missing.length} required settings have`;
|
|
1817
|
+
const scopeFlag = branchId === void 0 ? "--role production" : `--branch "${stage ?? branchId}"`;
|
|
1818
|
+
const commands = missing.map((m) => `prisma project env add ${m.name}="<value>" --project ${projectId} ${scopeFlag}`);
|
|
1819
|
+
const runStep = commands.length === 1 ? `Run: ${commands[0]}` : `Run, once per setting:\n${commands.map((cmd) => ` ${cmd}`).join("\n")}`;
|
|
1820
|
+
const consoleStep = branchId === void 0 ? "add each one under Production. Those values apply when the default branch deploys to production." : `add each one under Preview. Preview values apply to every branch deploy, including "${stage ?? branchId}".`;
|
|
1821
|
+
return /* @__PURE__ */ new Error(`Deploy failed. ${countPhrase} no value:\n${lines.join("\n")}\n\nSet the value in one of these two places, then deploy again:
|
|
1822
|
+
- ${runStep}\n - Or in the Prisma Console: open the project, go to Environment variables, and ${consoleStep}`);
|
|
1818
1823
|
}
|
|
1819
1824
|
async function managementClient() {
|
|
1820
1825
|
if ((process.env["PRISMA_SERVICE_TOKEN"] ?? "").length === 0) throw tokenRequiredError();
|
|
@@ -1856,7 +1861,7 @@ async function runPreflight(input, deps) {
|
|
|
1856
1861
|
}
|
|
1857
1862
|
missing.push(meta);
|
|
1858
1863
|
}
|
|
1859
|
-
if (missing.length > 0) throw missingError(missing, branchId, input.stage);
|
|
1864
|
+
if (missing.length > 0) throw missingError(missing, projectId, branchId, input.stage);
|
|
1860
1865
|
return updatedAt;
|
|
1861
1866
|
}
|
|
1862
1867
|
/**
|
|
@@ -2168,10 +2173,6 @@ const prismaState = () => ({
|
|
|
2168
2173
|
});
|
|
2169
2174
|
}
|
|
2170
2175
|
});
|
|
2171
|
-
const KNOWN_REGION_SET = new Set(Prisma$1.KNOWN_REGION_IDS);
|
|
2172
|
-
function isComputeRegion(value) {
|
|
2173
|
-
return KNOWN_REGION_SET.has(value);
|
|
2174
|
-
}
|
|
2175
2176
|
/** Prisma.providers()'s ProviderCollection doesn't structurally unify with Alchemy's inferred providers Layer (a @internal/lowering typings gap); it satisfies it at runtime. */
|
|
2176
2177
|
function asProvidersLayer(layer) {
|
|
2177
2178
|
return layer;
|
|
@@ -2231,11 +2232,10 @@ const PROVIDER_PARAMS = buildProviderParams(RESERVED_PROVIDER_PARAMS, PROVIDER_P
|
|
|
2231
2232
|
* `PRISMA_WORKSPACE_ID`: nothing in this file reads `ResolvedCloudOptions.workspaceId`
|
|
2232
2233
|
* downstream — it exists only so a caller MAY pin an explicit workspace, and
|
|
2233
2234
|
* the real workspace check for a real deploy lives where the value actually
|
|
2234
|
-
* matters, `container.ts`'s `ensureContainer`/`locateContainer`.
|
|
2235
|
-
*
|
|
2236
|
-
*
|
|
2237
|
-
*
|
|
2238
|
-
* `PRISMA_REGION` and must not fail on its absence (local-dev spec § 5).
|
|
2235
|
+
* matters, `container.ts`'s `ensureContainer`/`locateContainer`. An absent
|
|
2236
|
+
* `PRISMA_REGION` resolves to `undefined` without touching anything else —
|
|
2237
|
+
* required for `prisma-composer dev`, which never sets `PRISMA_REGION` and
|
|
2238
|
+
* must not fail on its absence (local-dev spec § 5).
|
|
2239
2239
|
*/
|
|
2240
2240
|
function resolveOptions(opts) {
|
|
2241
2241
|
const workspaceId = opts.workspaceId ?? process.env["PRISMA_WORKSPACE_ID"] ?? "";
|
|
@@ -2249,10 +2249,9 @@ function resolveOptions(opts) {
|
|
|
2249
2249
|
workspaceId,
|
|
2250
2250
|
providerParams: PROVIDER_PARAMS
|
|
2251
2251
|
};
|
|
2252
|
-
if (!isComputeRegion(region)) throw new Error(`prismaCloud(): environment variable PRISMA_REGION="${region}" is not a known region (expected one of: ${Prisma$1.KNOWN_REGION_IDS.join(", ")}).`);
|
|
2253
2252
|
return {
|
|
2254
2253
|
workspaceId,
|
|
2255
|
-
region,
|
|
2254
|
+
region: blindCast(region),
|
|
2256
2255
|
providerParams: PROVIDER_PARAMS
|
|
2257
2256
|
};
|
|
2258
2257
|
}
|
|
@@ -2280,7 +2279,7 @@ const prismaCloud = (opts = {}) => {
|
|
|
2280
2279
|
const o = lazyOptions(opts, pointerUpdatedAtLookup(preflightTimestamps, process.env));
|
|
2281
2280
|
return {
|
|
2282
2281
|
id: PRISMA_CLOUD_EXTENSION_ID,
|
|
2283
|
-
container: containerDescriptor(),
|
|
2282
|
+
container: containerDescriptor({ region: () => o().region }),
|
|
2284
2283
|
providers: () => asProvidersLayer(Layer.mergeAll(providers(), PgWarmProvider(), OrmMigrationProvider(), S3CredentialsProvider(), GeneratedParamProvider(), ServiceKeyProvider())),
|
|
2285
2284
|
preflight: (input) => runPreflight(input).then((timestamps) => {
|
|
2286
2285
|
for (const [name, updatedAt] of timestamps) preflightTimestamps.set(name, updatedAt);
|