gencow 0.1.255 → 0.1.257
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.
|
@@ -111,6 +111,19 @@ const SAFE_LOCAL_ERROR_CODES = new Map([
|
|
|
111
111
|
"Retryable: no, until `npx gencow@latest codegen` passes locally — run it, fix what it reports, then rerun your deploy command.",
|
|
112
112
|
},
|
|
113
113
|
],
|
|
114
|
+
[
|
|
115
|
+
"STATIC_ARTIFACT_INDEX_EMPTY",
|
|
116
|
+
{
|
|
117
|
+
message:
|
|
118
|
+
"Static deploy stopped before upload: the build output's index.html is empty or contains only whitespace.",
|
|
119
|
+
stage: "artifact",
|
|
120
|
+
action: (caught) => {
|
|
121
|
+
const dir = safeDisplayDir(caught);
|
|
122
|
+
const target = dir ?? "<build-output-dir>";
|
|
123
|
+
return `Retryable: yes, after the build writes an index.html with real content into ${target} — run \`ls -l ${target}/index.html\` to confirm its size is above 0 bytes and that it is not only whitespace, then rerun \`gencow static ${target}\`.`;
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
114
127
|
[
|
|
115
128
|
"STATIC_ARTIFACT_INDEX_MISSING",
|
|
116
129
|
{
|
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
import { lstatSync, readdirSync } from "fs";
|
|
1
|
+
import { lstatSync, readFileSync, readdirSync } from "fs";
|
|
2
2
|
import { join } from "path";
|
|
3
3
|
|
|
4
|
+
// Mirrors the Platform policy in packages/platform/src/static-site-entrypoint-policy.ts
|
|
5
|
+
// (isBlankIndexBytes). Keep both in step; the contract test in packages/platform/src/__tests__
|
|
6
|
+
// runs the same byte cases through both entrypoints.
|
|
7
|
+
const STATIC_INDEX_BLANK_SCAN_LIMIT_BYTES = 64 * 1024;
|
|
8
|
+
const UTF8_BOM = [0xef, 0xbb, 0xbf];
|
|
9
|
+
const ASCII_WHITESPACE = new Set([0x20, 0x09, 0x0a, 0x0d, 0x0c, 0x0b]);
|
|
10
|
+
|
|
11
|
+
function isBlankIndexBytes(bytes) {
|
|
12
|
+
if (bytes.length > STATIC_INDEX_BLANK_SCAN_LIMIT_BYTES) return false;
|
|
13
|
+
let index = 0;
|
|
14
|
+
if (bytes.length >= UTF8_BOM.length && UTF8_BOM.every((byte, offset) => bytes[offset] === byte)) {
|
|
15
|
+
index = UTF8_BOM.length;
|
|
16
|
+
}
|
|
17
|
+
for (; index < bytes.length; index += 1) {
|
|
18
|
+
if (!ASCII_WHITESPACE.has(bytes[index])) return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
4
23
|
function countFiles(dir, readdirSyncImpl) {
|
|
5
24
|
let count = 0;
|
|
6
25
|
for (const entry of readdirSyncImpl(dir, { withFileTypes: true })) {
|
|
@@ -16,19 +35,37 @@ export function buildStaticArtifactManifest({
|
|
|
16
35
|
displayDir = null,
|
|
17
36
|
lstatSyncImpl = lstatSync,
|
|
18
37
|
readdirSyncImpl = readdirSync,
|
|
38
|
+
readFileSyncImpl = readFileSync,
|
|
19
39
|
}) {
|
|
20
|
-
|
|
40
|
+
// Mirrors the Platform's static entrypoint policy: a root index.html must be a regular file that is
|
|
41
|
+
// not empty and not whitespace-only (optional BOM plus ASCII whitespace).
|
|
42
|
+
let entrypoint = "missing";
|
|
21
43
|
try {
|
|
22
|
-
|
|
44
|
+
const indexPath = join(rootDir, "index.html");
|
|
45
|
+
const stat = lstatSyncImpl(indexPath);
|
|
46
|
+
if (stat.isFile()) {
|
|
47
|
+
const blank =
|
|
48
|
+
stat.size <= STATIC_INDEX_BLANK_SCAN_LIMIT_BYTES &&
|
|
49
|
+
isBlankIndexBytes(readFileSyncImpl(indexPath));
|
|
50
|
+
entrypoint = stat.size === 0 || blank ? "empty" : "usable";
|
|
51
|
+
}
|
|
23
52
|
} catch {
|
|
24
|
-
|
|
53
|
+
entrypoint = "missing";
|
|
25
54
|
}
|
|
26
|
-
if (
|
|
55
|
+
if (entrypoint !== "usable") {
|
|
27
56
|
const source = selection?.startsWith("auto:")
|
|
28
57
|
? `Auto-detected ${selection.slice(5)}`
|
|
29
58
|
: "Selected directory";
|
|
30
59
|
// displayDir is the project-relative directory the user passed or the CLI detected. It is
|
|
31
60
|
// attached as a field (not interpolated) so the public renderer decides what is safe to show.
|
|
61
|
+
if (entrypoint === "empty") {
|
|
62
|
+
throw Object.assign(
|
|
63
|
+
new Error(
|
|
64
|
+
`${source} has an empty or whitespace-only index.html at its root. Refusing to replace the current frontend.`,
|
|
65
|
+
),
|
|
66
|
+
{ code: "STATIC_ARTIFACT_INDEX_EMPTY", displayDir },
|
|
67
|
+
);
|
|
68
|
+
}
|
|
32
69
|
throw Object.assign(
|
|
33
70
|
new Error(
|
|
34
71
|
`${source} does not contain index.html at its root. Refusing to replace the current frontend.`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gencow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.257",
|
|
4
4
|
"description": "Gencow — AI Backend Engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"better-auth": "1.7.11",
|
|
42
42
|
"postgres": "^3.4.9",
|
|
43
43
|
"@gencow/client": "0.2.8",
|
|
44
|
-
"@gencow/server": "0.1.3",
|
|
45
44
|
"@gencow/core": "0.1.47",
|
|
45
|
+
"@gencow/react": "0.2.8",
|
|
46
46
|
"@gencow/shared": "0.0.0",
|
|
47
|
-
"@gencow/
|
|
47
|
+
"@gencow/server": "0.1.3"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "node scripts/bundle-core.mjs && node scripts/bundle-shared.mjs && node scripts/bundle-server.mjs",
|
package/runtime/server.mjs
CHANGED
|
@@ -8843,8 +8843,8 @@ ${argsDigest}`;const signature=sign3(null,Buffer.from(payload),scheduledJobDeliv
|
|
|
8843
8843
|
THEN split_part(value, ':', 2)::bigint > (extract(epoch FROM clock_timestamp()) * 1000)::bigint
|
|
8844
8844
|
ELSE FALSE
|
|
8845
8845
|
END`}async function isDeploymentExecutorLifecycleAuthority(input2){const slotPort=deploymentExecutorSlotPort(input2.slotId);if(!slotPort||!input2.nodeId.trim())return false;try{if(await holdsActiveSlot(input2.db,input2.nodeId,slotPort))return true;if(!input2.allowAcceptanceCandidate)return false;const leaseRows=rowsFromUnknown4(await input2.db.execute(acceptanceLeasePortSql(input2.nodeId)));return leaseRows[0]?.leasePort===slotPort}catch{return false}}async function holdsActiveSlot(db,nodeId,slotPort){const nodeRows=rowsFromUnknown4(await db.execute(sql97`SELECT active_port AS "activePort" FROM platform_nodes WHERE id = ${nodeId} LIMIT 1`));const nodePort=nodeRows[0]?.activePort;if(nodePort!=null&&String(nodePort).trim()){return String(nodePort).trim()===slotPort}const runtimeRows=rowsFromUnknown4(await db.execute(sql97`SELECT value AS "activePort" FROM platform_runtime_state WHERE key = 'active_platform_port' LIMIT 1`));const runtimePort=runtimeRows[0]?.activePort;return runtimePort!=null&&String(runtimePort).trim()===slotPort}var DEPLOYMENT_ACCEPTANCE_LEASE_KEY_PREFIX;var init_deployment_executor_lifecycle_authority=__esm({"../platform/src/deployment-executor-lifecycle-authority.ts"(){"use strict";DEPLOYMENT_ACCEPTANCE_LEASE_KEY_PREFIX="deployment_acceptance_candidate"}});import{createHash as createHash43,randomUUID as randomUUID32}from"node:crypto";import{and as and13,desc as desc4,eq as eq16,inArray as inArray8,sql as sql98}from"drizzle-orm";var init_app_release_finalize_store=__esm({"../platform/src/app-release-finalize-store.ts"(){"use strict";init_schema();init_app_release_retention();init_app_release_attempt_failure_store();init_app_serving_route_static_store();init_app_serving_route_receipt_store();init_app_serving_route_convergence_poll();init_deployment_executor_lifecycle_authority()}});import{createHash as createHash44,randomUUID as randomUUID33}from"node:crypto";import{and as and14,eq as eq17}from"drizzle-orm";var init_app_release_store=__esm({"../platform/src/app-release-store.ts"(){"use strict";init_schema();init_app_release_unbound_attempt_lease();init_app_release_finalize_store();init_app_release_attempt_failure_store()}});function resolveDeploymentReleaseEnvironment(input2){if(input2.releaseEnvironment==="dev"||input2.releaseEnvironment==="prod"){return input2.releaseEnvironment}return input2.executionEnvironment==="dev"||input2.executionEnvironment==="prod"?input2.executionEnvironment:null}function releaseBindingMatchesExecutionScope(input2){if(input2.releaseEnvironment!=="dev"&&input2.releaseEnvironment!=="prod")return false;if(input2.component==="static"&&input2.executionEnvironment!=="static")return false;if(input2.component==="backend"&&input2.executionEnvironment==="static")return false;return input2.executionEnvironment==="static"||input2.executionEnvironment===input2.releaseEnvironment}function deploymentRecoveryScopesOverlap(input2){const candidateReleaseEnvironment=resolveDeploymentReleaseEnvironment({executionEnvironment:input2.candidateExecutionEnvironment,releaseEnvironment:input2.candidateReleaseEnvironment});const incomingReleaseEnvironment=resolveDeploymentReleaseEnvironment({executionEnvironment:input2.incomingExecutionEnvironment,releaseEnvironment:input2.incomingReleaseEnvironment});const candidateStaticUnbound=input2.candidateExecutionEnvironment==="static"&&candidateReleaseEnvironment===null;const incomingStaticUnbound=input2.incomingExecutionEnvironment==="static"&&incomingReleaseEnvironment===null;if(candidateStaticUnbound||incomingStaticUnbound)return true;if(incomingReleaseEnvironment!==null){return candidateReleaseEnvironment===incomingReleaseEnvironment}return input2.candidateExecutionEnvironment===input2.incomingExecutionEnvironment}var init_deployment_release_scope=__esm({"../platform/src/deployment-release-scope.ts"(){"use strict";init_app_release_store()}});import{mkdtemp,mkdir as mkdir4,rm,writeFile as writeFile3}from"node:fs/promises";import{tmpdir as tmpdir5}from"node:os";import{join as join15}from"node:path";async function withTarBufferFile(bundle,operation){const workDir=await mkdtemp(join15(tmpdir5(),"gencow-tar-buffer-"));const archivePath2=join15(workDir,"bundle.tar.gz");try{await writeFile3(archivePath2,bundle,{flag:"wx",mode:384});return await operation(archivePath2)}finally{await rm(workDir,{recursive:true,force:true})}}var init_tar_buffer_extract=__esm({"../platform/src/tar-buffer-extract.ts"(){"use strict";init_index_min()}});import{createHash as createHash45}from"node:crypto";import{createReadStream}from"node:fs";import{chmod as chmod2,cp,lstat as lstat2,mkdir as mkdir5,open as open4,readdir as readdir3}from"node:fs/promises";import{relative as relative11,resolve as resolve56,sep as sep2}from"node:path";function normalizePath2(path5){const normalized=path5.replace(/^\.\//u,"").replace(/\/+$/u,"").normalize("NFC");if(!normalized||Buffer.byteLength(normalized)>1024||normalized!==path5.replace(/^\.\//u,"").replace(/\/+$/u,"")||normalized.startsWith("/")||/^[A-Za-z]:/u.test(normalized)||normalized.includes("\\")||/[\u0000-\u001f\u007f]/u.test(normalized)||normalized.split("/").length>32||normalized.split("/").some(part=>!part||part==="."||part==="..")){throw new Error("unsafe artifact path")}return normalized}function hashArtifactClosure(files){const canonical=[...files].sort((left,right)=>left.path<right.path?-1:left.path>right.path?1:0);return createHash45("sha256").update(canonical.map(file2=>`${file2.path}\0${file2.size}\0${file2.sha256}
|
|
8846
|
-
`).join("")).digest("hex")}function validateArtifactFiles(files){const seen=new Set;const validated=files.map(file2=>{const keys2=Object.keys(file2).sort();const path5=normalizePath2(file2.path);if(keys2.join(",")!=="path,sha256,size"||seen.has(path5)||!Number.isSafeInteger(file2.size)||file2.size<0||!/^[a-f0-9]{64}$/u.test(file2.sha256)){throw new Error("invalid artifact file metadata")}seen.add(path5);return{path:path5,size:file2.size,sha256:file2.sha256}});return validated.sort((left,right)=>left.path<right.path?-1:left.path>right.path?1:0)}async function hashArtifactFile(path5){const hash9=createHash45("sha256");for await(const chunk2 of createReadStream(path5))hash9.update(chunk2);return hash9.digest("hex")}async function walk(root2,directory=root2){const files=[];const dirs=[directory];for(const entry of await readdir3(directory,{withFileTypes:true})){const path5=resolve56(directory,entry.name);const stats=await lstat2(path5);if(stats.isSymbolicLink())throw new Error("artifact link is forbidden");if(stats.isDirectory()){const nested=await walk(root2,path5);files.push(...nested.files);dirs.push(...nested.dirs);continue}if(!stats.isFile())throw new Error("artifact special file is forbidden");const artifactPath=relative11(root2,path5).split(sep2).join("/");files.push({path:artifactPath,size:stats.size,sha256:await hashArtifactFile(path5)})}return{files,dirs}}function sameFiles(left,right){return JSON.stringify(validateArtifactFiles(left))===JSON.stringify(validateArtifactFiles(right))}async function extractVerifiedArtifact(bundle,target,expectedFiles){const files=validateArtifactFiles(expectedFiles);const allowedFiles=new Set(files.map(file2=>file2.path));await mkdir5(target,{recursive:true,mode:448});await withTarBufferFile(bundle,async archivePath2=>{await fo({cwd:target,file:archivePath2,strict:true,noChmod:true,filter(entryPath,entry){const entryType=entry.type;const isDirectory=entryType==="Directory";if(isDirectory&&(entryPath==="."||entryPath==="./"))return false;const path5=normalizePath2(isDirectory?entryPath.replace(/\/+$/u,""):entryPath);if(isDirectory)return false;if(entryType!=="File"&&entryType!=="OldFile")throw new Error("unsafe artifact entry");if(!allowedFiles.has(path5))throw new Error("unexpected artifact file");return true}})});await verifyArtifactTree(target,files,false)}async function verifyArtifactTree(root2,expectedFiles,sealed){const tree=await walk(root2);if(!sameFiles(tree.files,expectedFiles))throw new Error("artifact file closure mismatch");if(!sealed)return;for(const file2 of tree.files){if(((await lstat2(resolve56(root2,file2.path))).mode&511)!==292){throw new Error("artifact file is not sealed")}}for(const directory of tree.dirs){if(((await lstat2(directory)).mode&511)!==365){throw new Error("artifact directory is not sealed")}}}async function syncPath(path5){const handle=await open4(path5,"r");try{await handle.sync()}finally{await handle.close()}}async function syncArtifactTree(root2){const tree=await walk(root2);for(const file2 of tree.files)await syncPath(resolve56(root2,file2.path));for(const directory of tree.dirs.reverse())await syncPath(directory)}async function sealArtifactTree(root2){const tree=await walk(root2);for(const file2 of tree.files)await chmod2(resolve56(root2,file2.path),292);for(const directory of tree.dirs.reverse())await chmod2(directory,365);await verifyArtifactTree(root2,tree.files,true)}async function makeArtifactTreeWritable(root2){const tree=await walk(root2);for(const directory of tree.dirs)await chmod2(directory,493);for(const file2 of tree.files)await chmod2(resolve56(root2,file2.path),420)}async function copyVerifiedArtifact(source,target,expectedFiles){await cp(source,target,{recursive:true,force:false,errorOnExist:true});await verifyArtifactTree(target,expectedFiles,false)}async function syncArtifactPath(path5){await syncPath(path5)}var init_app_deployment_artifact_filesystem=__esm({"../platform/src/app-deployment-artifact-filesystem.ts"(){"use strict";init_index_min();init_tar_buffer_extract()}});function parseArtifactMetadata(bytes2){if(bytes2.length===0||bytes2.length>MAX_ARTIFACT_METADATA_BYTES){throw new Error("artifact metadata size is invalid")}const parsed=JSON.parse(bytes2.toString("utf8"));if(!parsed||typeof parsed!=="object"||Array.isArray(parsed)||Object.keys(parsed).sort().join(",")!==FIELDS2.join(",")||parsed.version!==1||!SHA2566.test(parsed.appScopeSha256??"")||!SHA2566.test(parsed.artifactSha256??"")||!SHA2566.test(parsed.rawArchiveSha256??"")||!Number.isSafeInteger(parsed.rawArchiveBytes)||Number(parsed.rawArchiveBytes)<=0||Number(parsed.rawArchiveBytes)>MAX_RAW_ARCHIVE_BYTES||!Array.isArray(parsed.files)||parsed.files.length>1e4){throw new Error("artifact metadata is invalid")}return{version:1,appScopeSha256:parsed.appScopeSha256,artifactSha256:parsed.artifactSha256,rawArchiveSha256:parsed.rawArchiveSha256,rawArchiveBytes:parsed.rawArchiveBytes,files:validateArtifactFiles(parsed.files)}}var SHA2566,FIELDS2,MAX_ARTIFACT_METADATA_BYTES,MAX_RAW_ARCHIVE_BYTES;var init_app_deployment_artifact_metadata=__esm({"../platform/src/app-deployment-artifact-metadata.ts"(){"use strict";init_app_deployment_artifact_filesystem();SHA2566=/^[a-f0-9]{64}$/u;FIELDS2=["version","appScopeSha256","artifactSha256","rawArchiveSha256","rawArchiveBytes","files"].sort();MAX_ARTIFACT_METADATA_BYTES=16*1024*1024;MAX_RAW_ARCHIVE_BYTES=100*1024*1024}});import{createHash as createHash46,randomUUID as randomUUID34}from"node:crypto";import{chmod as chmod3,mkdir as mkdir6,mkdtemp as mkdtemp2,readFile as readFile5,rename as rename3,rm as rm2,stat as stat6,writeFile as writeFile4}from"node:fs/promises";import{dirname as dirname14,join as join16}from"node:path";function fail10(code,cause,stage,pathContext,failureKind,filesystemCode){throw new AppDeploymentArtifactError(code,cause===void 0?void 0:{cause},stage,filesystemCode,pathContext,failureKind)}function filesystemErrorCode(error62){const code=error62?.code;return typeof code==="string"&&/^[A-Z0-9_]{2,16}$/u.test(code)?code:void 0}function failStoreUnavailable(error62,stage,pathContext,failureKind="store_unavailable"){const code=filesystemErrorCode(error62);return fail10("ARTIFACT_STORE_UNAVAILABLE",error62,stage,pathContext,failureKind,code)}function failArtifactAbsent(error62,stage){return fail10("ARTIFACT_NOT_FOUND",error62,stage,"artifact_leaf","artifact_absent",filesystemErrorCode(error62))}function failArtifactIntegrity(cause,stage,pathContext,filesystemCode=filesystemErrorCode(cause)){return fail10("ARTIFACT_INTEGRITY_MISMATCH",cause,stage,pathContext,"integrity_invalid",filesystemCode)}function failFilesystemObservation(error62,stage,pathContext,missingKind){const code=filesystemErrorCode(error62);if(code==="ENOENT"&&missingKind==="artifact_absent")return failArtifactAbsent(error62,stage);if(code==="ENOENT"&&missingKind==="integrity_invalid"){return failArtifactIntegrity(error62,stage,pathContext,code)}if(code==="ENOENT"&&missingKind==="scope_missing"){return fail10("ARTIFACT_NOT_FOUND",error62,stage,pathContext,"scope_missing",code)}if(code&&["EISDIR","ENOTDIR","ELOOP"].includes(code)&&["artifact_leaf","ready_marker","metadata","bundle","source","cache_entry"].includes(pathContext)){return failArtifactIntegrity(error62,stage,pathContext,code)}return failStoreUnavailable(error62,stage,pathContext,"store_unavailable")}function sha2567(value2){return createHash46("sha256").update(value2).digest("hex")}function appScopeSha256(scope){const appId=String(scope.appId);if(typeof scope.appId==="number"&&(!Number.isSafeInteger(scope.appId)||scope.appId<=0)||!appId||appId.length>128||/[\u0000-\u001f\u007f]/u.test(appId)||!/^[a-z][a-z0-9_-]{0,31}$/u.test(scope.environment)){return fail10("ARTIFACT_ADMISSION_INVALID")}return sha2567(JSON.stringify([typeof scope.appId,appId,scope.environment]))}function parseArtifactRef(scope,artifactRef){const match2=ARTIFACT_REF2.exec(artifactRef);const expectedScope=appScopeSha256(scope);if(!match2){return fail10("ARTIFACT_ADMISSION_INVALID",void 0,"artifact_lookup","artifact_reference","reference_invalid")}if(match2[1]!==expectedScope){return fail10("ARTIFACT_NOT_FOUND",void 0,"artifact_lookup","artifact_reference","scope_mismatch")}return{appScopeSha256:match2[1],artifactSha256:match2[2]}}function artifactResult(path5,artifactRef,metadata){return{artifactRef,artifactSha256:metadata.artifactSha256,artifactBytes:metadata.rawArchiveBytes,rawArchiveSha256:metadata.rawArchiveSha256,artifactPath:path5,sourcePath:join16(path5,"source")}}async function isRenameCollision(error62,target){const code=error62?.code;if(code==="EEXIST"||code==="ENOTEMPTY")return true;if(code!=="EACCES")return false;return stat6(target).then(stats=>stats.isDirectory()).catch(()=>false)}async function finalizePublishedArtifact(target,parent,artifactSha256){const readyPath=join16(parent,`${artifactSha256}.ready`);await chmod3(target,365);try{await writeFile4(readyPath,artifactSha256,{mode:292,flag:"wx"});await syncArtifactPath(readyPath)}catch(error62){if(error62?.code!=="EEXIST")throw error62;if(await readFile5(readyPath,"utf8")!==artifactSha256){return fail10("ARTIFACT_INTEGRITY_MISMATCH")}}await syncArtifactPath(parent)}async function removeStaging(path5){await makeArtifactTreeWritable(path5).catch(()=>{});await rm2(path5,{recursive:true,force:true})}function createAppDeploymentArtifactStore(options){const statPath=options.statImpl??stat6;async function read(input2){const ref=parseArtifactRef(input2,input2.artifactRef);const path5=join16(options.artifactRoot,"v1",ref.appScopeSha256,ref.artifactSha256);const readyPath=join16(options.artifactRoot,"v1",ref.appScopeSha256,`${ref.artifactSha256}.ready`);const scopes=[{path:options.artifactRoot,context:"store_root"},{path:join16(options.artifactRoot,"v1"),context:"store_version"},{path:dirname14(path5),context:"app_scope"}];for(const scope of scopes){let scopeStats;try{scopeStats=await statPath(scope.path)}catch(error62){return failFilesystemObservation(error62,"artifact_store_scope",scope.context,"scope_missing")}if(!scopeStats.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_store_scope",scope.context)}}let artifactStats;try{artifactStats=await statPath(path5)}catch(error62){if(filesystemErrorCode(error62)==="ENOENT"){for(const scope of scopes){let currentScope;try{currentScope=await statPath(scope.path)}catch(scopeError){return failFilesystemObservation(scopeError,"artifact_store_scope",scope.context,"scope_missing")}if(!currentScope.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_store_scope",scope.context)}}}return failFilesystemObservation(error62,"artifact_lookup","artifact_leaf","artifact_absent")}if(!artifactStats.isDirectory()){return failArtifactIntegrity(void 0,"artifact_lookup","artifact_leaf")}let marker;let markerStats;try{marker=await readFile5(readyPath,"utf8");markerStats=await stat6(readyPath)}catch(error62){return failFilesystemObservation(error62,"artifact_lookup","ready_marker","integrity_invalid")}if(marker!==ref.artifactSha256||(markerStats.mode&511)!==292){return failArtifactIntegrity(void 0,"artifact_lookup","ready_marker")}let metadataStats;try{const metadataPath=join16(path5,"artifact.json");metadataStats=await stat6(metadataPath)}catch(error62){return failFilesystemObservation(error62,"artifact_verification","metadata","integrity_invalid")}if(metadataStats.size===0||metadataStats.size>MAX_ARTIFACT_METADATA_BYTES){return failArtifactIntegrity(void 0,"artifact_verification","metadata")}let metadataBytes;try{metadataBytes=await readFile5(join16(path5,"artifact.json"))}catch(error62){return failFilesystemObservation(error62,"artifact_verification","metadata","integrity_invalid")}let metadata;try{metadata=parseArtifactMetadata(metadataBytes)}catch(error62){return failArtifactIntegrity(error62,"artifact_verification","metadata")}const bundlePath=join16(path5,"source.tar.gz");let bundleStats;let bundleSha256;try{bundleStats=await stat6(bundlePath);bundleSha256=await hashArtifactFile(bundlePath)}catch(error62){return failFilesystemObservation(error62,"artifact_verification","bundle","integrity_invalid")}let artifactSealStats;try{artifactSealStats=await stat6(path5)}catch(error62){return failFilesystemObservation(error62,"artifact_verification","artifact_leaf","integrity_invalid")}if(metadata.appScopeSha256!==ref.appScopeSha256||metadata.artifactSha256!==ref.artifactSha256||hashArtifactClosure(metadata.files)!==metadata.artifactSha256||bundleStats.size!==metadata.rawArchiveBytes||bundleSha256!==metadata.rawArchiveSha256||(artifactSealStats.mode&511)!==365||(metadataStats.mode&511)!==292||(bundleStats.mode&511)!==292){return failArtifactIntegrity(void 0,"artifact_verification","metadata")}try{await verifyArtifactTree(join16(path5,"source"),metadata.files,true)}catch(error62){if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_verification","source","integrity_invalid")}return failArtifactIntegrity(error62,"artifact_verification","source")}return artifactResult(path5,input2.artifactRef,metadata)}async function publish(input2){const scopeHash=appScopeSha256(input2);let files;try{files=validateArtifactFiles(input2.admission.files);if(sha2567(input2.bundle)!==input2.admission.recomputed.rawArchiveSha256||input2.bundle.length!==input2.admission.recomputed.compressedBytes||hashArtifactClosure(files)!==input2.admission.sourceClosureSha256){return fail10("ARTIFACT_ADMISSION_INVALID")}}catch(error62){if(error62 instanceof AppDeploymentArtifactError)throw error62;return fail10("ARTIFACT_ADMISSION_INVALID")}const artifactSha256=input2.admission.sourceClosureSha256;const artifactRef=`app-artifact-v1.${scopeHash}.${artifactSha256}`;const parent=join16(options.artifactRoot,"v1",scopeHash);const target=join16(parent,artifactSha256);const tempRoot=join16(options.artifactRoot,".tmp");let rootStats;try{rootStats=await stat6(options.artifactRoot)}catch(error62){if(filesystemErrorCode(error62)==="ENOENT")rootStats=null;else return failFilesystemObservation(error62,"artifact_publish","store_root")}if(rootStats&&!rootStats.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_publish","store_root")}try{await mkdir6(parent,{recursive:true,mode:448});await mkdir6(tempRoot,{recursive:true,mode:448})}catch(error62){return failFilesystemObservation(error62,"artifact_publish","store_root")}let staging;try{staging=await mkdtemp2(join16(tempRoot,`${scopeHash}-${randomUUID34()}-`))}catch(error62){return failFilesystemObservation(error62,"artifact_publish","store_root")}const metadata={version:1,appScopeSha256:scopeHash,artifactSha256,rawArchiveSha256:input2.admission.recomputed.rawArchiveSha256,rawArchiveBytes:input2.bundle.length,files};try{const sourcePath=join16(staging,"source");await extractVerifiedArtifact(input2.bundle,sourcePath,files);await writeFile4(join16(staging,"source.tar.gz"),input2.bundle,{mode:384,flag:"wx"});await writeFile4(join16(staging,"artifact.json"),JSON.stringify(metadata),{mode:384,flag:"wx"});await syncArtifactTree(sourcePath);await syncArtifactPath(join16(staging,"source.tar.gz"));await syncArtifactPath(join16(staging,"artifact.json"));await sealArtifactTree(sourcePath);await chmod3(join16(staging,"source.tar.gz"),292);await chmod3(join16(staging,"artifact.json"),292);try{await rename3(staging,target)}catch(error62){if(!await isRenameCollision(error62,target))throw error62;await removeStaging(staging)}await finalizePublishedArtifact(target,parent,artifactSha256);return await read({...input2,artifactRef})}catch(error62){await removeStaging(staging).catch(()=>{});if(error62 instanceof AppDeploymentArtifactError)throw error62;if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_publish","artifact_leaf")}return fail10("ARTIFACT_INTEGRITY_MISMATCH")}}async function materialize(input2){const artifact=await read(input2);const ref=parseArtifactRef(input2,input2.artifactRef);if(!input2.nodeId||input2.nodeId.length>128||/[\u0000-\u001f\u007f]/u.test(input2.nodeId)){return fail10("ARTIFACT_CACHE_INTEGRITY_MISMATCH")}const nodeScope=sha2567(input2.nodeId);const parent=join16(options.cacheRoot,"v1",nodeScope,ref.appScopeSha256);const target=join16(parent,ref.artifactSha256);for(const scopePath of[options.cacheRoot,join16(options.cacheRoot,"v1"),join16(options.cacheRoot,"v1",nodeScope),parent]){let scopeStats;try{scopeStats=await stat6(scopePath)}catch(error62){if(filesystemErrorCode(error62)!=="ENOENT"){return failFilesystemObservation(error62,"artifact_cache","cache_scope")}try{await mkdir6(scopePath,{recursive:true,mode:448});scopeStats=await stat6(scopePath)}catch(createError){return failFilesystemObservation(createError,"artifact_cache","cache_scope","scope_missing")}}if(!scopeStats.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_cache","cache_scope")}}let metadata;try{metadata=parseArtifactMetadata(await readFile5(join16(artifact.artifactPath,"artifact.json")))}catch(error62){if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_verification","metadata","integrity_invalid")}return failArtifactIntegrity(error62,"artifact_verification","metadata")}try{const targetStats=await stat6(target);if(targetStats.isDirectory()){await chmod3(target,365);await verifyArtifactTree(target,metadata.files,true);return{...artifact,runtimePath:target,nodeScope}}return failArtifactIntegrity(void 0,"artifact_cache","cache_entry")}catch(error62){if(filesystemErrorCode(error62)!=="ENOENT"){if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_cache","cache_entry","integrity_invalid")}return fail10("ARTIFACT_CACHE_INTEGRITY_MISMATCH",error62,"artifact_cache","cache_entry","integrity_invalid")}}const staging=join16(parent,`.${ref.artifactSha256}-${randomUUID34()}`);try{await copyVerifiedArtifact(artifact.sourcePath,staging,metadata.files);await syncArtifactTree(staging);await sealArtifactTree(staging);await chmod3(staging,493);try{await rename3(staging,target)}catch(error62){if(!await isRenameCollision(error62,target))throw error62;await removeStaging(staging)}await chmod3(target,365);await syncArtifactPath(parent);await verifyArtifactTree(target,metadata.files,true);return{...artifact,runtimePath:target,nodeScope}}catch(error62){await removeStaging(staging).catch(()=>{});if(error62 instanceof AppDeploymentArtifactError)throw error62;if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_cache","cache_entry","integrity_invalid")}return fail10("ARTIFACT_CACHE_INTEGRITY_MISMATCH",error62,"artifact_cache","cache_entry","integrity_invalid")}}async function deleteArtifact(input2){const ref=parseArtifactRef(input2,input2.artifactRef);const parent=join16(options.artifactRoot,"v1",ref.appScopeSha256);const target=join16(parent,ref.artifactSha256);const readyPath=join16(parent,`${ref.artifactSha256}.ready`);await makeArtifactTreeWritable(target).catch(error62=>{if(error62.code!=="ENOENT")throw error62});await rm2(target,{recursive:true,force:true});await rm2(readyPath,{force:true})}return{publish,read,materialize,delete:deleteArtifact}}var ARTIFACT_REF2,AppDeploymentArtifactError;var init_app_deployment_artifact_store=__esm({"../platform/src/app-deployment-artifact-store.ts"(){"use strict";init_app_deployment_artifact_filesystem();init_app_deployment_artifact_metadata();ARTIFACT_REF2=/^app-artifact-v1\.([a-f0-9]{64})\.([a-f0-9]{64})$/u;AppDeploymentArtifactError=class extends Error{constructor(code,options,stage,filesystemCode,pathContext,failureKind){super(code,options);this.code=code;this.stage=stage;this.filesystemCode=filesystemCode;this.pathContext=pathContext;this.failureKind=failureKind;this.name="AppDeploymentArtifactError"}code;stage;filesystemCode;pathContext;failureKind}}});import{createHash as createHash47}from"node:crypto";function fail11(code,details){throw new DeployArchiveAdmissionError(code,details)}function normalizeEntryPath(rawPath,directory){if(!rawPath||Buffer.byteLength(rawPath)>1024||/[\u0000-\u001f\u007f]/.test(rawPath)||rawPath.includes("\\")){return fail11("DEPLOY_ARCHIVE_PATH_INVALID")}const withoutDot=rawPath.replace(/^\.\//,"");const normalized=(directory?withoutDot.replace(/\/+$/,""):withoutDot).normalize("NFC");const segments=normalized.split("/");if(!normalized||normalized!==(directory?withoutDot.replace(/\/+$/,""):withoutDot)||normalized.startsWith("/")||/^[A-Za-z]:/.test(normalized)||segments.some(segment=>!segment||segment==="."||segment==="..")){return fail11("DEPLOY_ARCHIVE_PATH_INVALID")}return normalized}function sha2568(value2){return createHash47("sha256").update(value2).digest("hex")}function equalContractValue(left,right){return JSON.stringify(left)===JSON.stringify(right)}function isMetadataFile(path5){return SELECTED_METADATA.has(path5)||PROJECT_AUTH_SCHEMA_PATTERN.test(path5)||LEGACY_AUTH_SCHEMA_PATTERN.test(path5)}function findRuntimeEntry(files){return files.find(file2=>RUNTIME_ENTRY_PATTERN.test(file2.path))?.path??null}async function inspectDeployArchive(bundle,overrides={}){const limits={...DEFAULT_LIMITS2,...overrides};if(bundle.length===0||bundle.length>limits.maxCompressedBytes){return fail11("DEPLOY_ARCHIVE_COMPRESSED_SIZE_LIMIT")}const paths=new Map;const knownDirectoryPrefixes=new Set;const caseFolded=new Map;const files=[];const metadata=new Map;let entryCount=0;let uncompressedBytes=0;let streamError=null;const inspectArchiveFile=archivePath2=>Ct({file:archivePath2,strict:true,onentry(entry){const isDirectory=entry.type==="Directory";if(!isDirectory&&entry.type!=="File"&&entry.type!=="OldFile"){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_ENTRY_TYPE_INVALID");entry.resume();return}if(isDirectory&&(entry.path==="."||entry.path==="./")){entry.resume();return}let path5;try{path5=normalizeEntryPath(entry.path,isDirectory)}catch(error62){streamError??=error62;entry.resume();return}entryCount+=1;if(entryCount>limits.maxEntries)streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_ENTRY_LIMIT");const segments=path5.split("/");if(segments.length>limits.maxDepth){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_DEPTH_LIMIT")}const prefixes=segments.map((_4,index27)=>segments.slice(0,index27+1).join("/"));const hasCaseFoldCollision=prefixes.some(prefix=>{const known=caseFolded.get(prefix.toLocaleLowerCase("en-US"));return known!==void 0&&known!==prefix});if(paths.has(path5)||hasCaseFoldCollision){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_PATH_COLLISION")}const ancestors=prefixes.slice(0,-1);for(const ancestor of ancestors){if(paths.get(ancestor)==="file"){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_PATH_COLLISION")}}if(!isDirectory&&knownDirectoryPrefixes.has(path5)){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_PATH_COLLISION")}paths.set(path5,isDirectory?"directory":"file");for(const ancestor of ancestors)knownDirectoryPrefixes.add(ancestor);for(const prefix of prefixes){const folded=prefix.toLocaleLowerCase("en-US");if(!caseFolded.has(folded))caseFolded.set(folded,prefix)}if(isDirectory){entry.resume();return}uncompressedBytes+=entry.size;if(uncompressedBytes>limits.maxUncompressedBytes){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_SIZE_LIMIT")}if(uncompressedBytes/bundle.length>limits.maxCompressionRatio){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_COMPRESSION_LIMIT")}const hash9=createHash47("sha256");const chunks=[];let actualBytes=0;const selectedMetadata=isMetadataFile(path5);const retain=selectedMetadata&&entry.size<=MAX_METADATA_BYTES;if(selectedMetadata&&!retain){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_METADATA_LIMIT")}entry.on("data",chunk2=>{actualBytes+=chunk2.length;hash9.update(chunk2);if(retain)chunks.push(Buffer.from(chunk2))});entry.on("end",()=>{if(actualBytes!==entry.size){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_SIZE_MISMATCH")}files.push({path:path5,size:actualBytes,sha256:hash9.digest("hex")});if(retain)metadata.set(path5,Buffer.concat(chunks))})}});try{await withTarBufferFile(bundle,inspectArchiveFile)}catch{const observedError2=streamError;return fail11(observedError2?.code??"DEPLOY_ARCHIVE_FORMAT_INVALID")}const observedError=streamError;if(observedError)return fail11(observedError.code);const lockfiles=[...LOCKFILES].filter(([path5])=>metadata.has(path5));const unsupportedLockfiles=[...UNSUPPORTED_LOCKFILES].filter(path5=>metadata.has(path5));if(unsupportedLockfiles.length>0){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANAGER_UNSUPPORTED",{files:unsupportedLockfiles.sort()})}if(lockfiles.length>1)return fail11("DEPLOY_ARCHIVE_DEPENDENCY_AMBIGUOUS");const projectAuth=[...metadata.keys()].filter(path5=>PROJECT_AUTH_SCHEMA_PATTERN.test(path5)).sort();const legacyAuth=[...metadata.keys()].filter(path5=>LEGACY_AUTH_SCHEMA_PATTERN.test(path5)).sort();if(projectAuth.length>1||legacyAuth.length>1||projectAuth.length&&legacyAuth.length){return fail11("DEPLOY_ARCHIVE_AUTH_SCHEMA_AMBIGUOUS",{files:[...projectAuth,...legacyAuth].sort()})}const authSchema=projectAuth[0]?{mode:"project",path:projectAuth[0]}:legacyAuth[0]?{mode:"legacy",path:legacyAuth[0]}:{mode:"builtin",path:null};files.sort((left,right)=>left.path<right.path?-1:left.path>right.path?1:0);const sourceClosureSha256=sha2568(files.map(file2=>`${file2.path}\0${file2.size}\0${file2.sha256}
|
|
8847
|
-
`).join(""));const lockfile=lockfiles[0];const packageBytes=metadata.get(PACKAGE_MANIFEST);let packageManagerDeclaration=null;if(packageBytes){try{const parsed=JSON.parse(packageBytes.toString("utf8"));packageManagerDeclaration=typeof parsed.packageManager==="string"?parsed.packageManager.trim():null}catch{return fail11("DEPLOY_ARCHIVE_PACKAGE_MANIFEST_INVALID")}}if(findRuntimeEntry(files)&&packageBytes){const dependencyLock=inspectPnpmDependencyLock({packageJsonText:packageBytes.toString("utf8"),pnpmLockText:lockfile?metadata.get(lockfile[0])?.toString("utf8"):null});if(!dependencyLock.ok){return fail11(dependencyLock.code,{files:[...dependencyLock.files]})}}const migrationBytes=metadata.get(MIGRATION_MANIFEST);let artifactIdentitySha256=null;let migrationCliVersion=null;if(migrationBytes){try{const manifest=JSON.parse(migrationBytes.toString("utf8"));artifactIdentitySha256=typeof manifest.artifactIdentitySha256==="string"?manifest.artifactIdentitySha256:null;migrationCliVersion=typeof manifest.cliVersion==="string"?manifest.cliVersion:null}catch{return fail11("MIGRATION_BUNDLE_MANIFEST_INVALID")}}const recomputed={rawArchiveSha256:sha2568(bundle),compressedBytes:bundle.length,uncompressedBytes,entryCount,fileCount:files.length,authSchema,dependencies:{packageManager:lockfile?.[1]??"none",manifestSha256:packageBytes?sha2568(packageBytes):null,lockfileSha256:lockfile?sha2568(metadata.get(lockfile[0])):null},migrationBundle:{manifestSha256:migrationBytes?sha2568(migrationBytes):null,requiredCapability:migrationBytes?artifactIdentitySha256?MIGRATION_ARTIFACT_IDENTITY_CAPABILITY_V2:MIGRATION_BUNDLE_CAPABILITY_V1:"none",...artifactIdentitySha256?{artifactIdentitySha256}:{}}};return{recomputed,sourceClosureSha256,files,packageManagerDeclaration,...migrationCliVersion?{migrationCliVersion}:{}}}function admitInspectedDeployArchive(input2){const hasRuntimeEntry=findRuntimeEntry(input2.inspection.files);if(input2.expectedRuntime==="server"){if(input2.inspection.recomputed.dependencies.manifestSha256===null){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANIFEST_REQUIRED")}if(input2.inspection.recomputed.dependencies.packageManager!=="pnpm"){return fail11("DEPLOY_ARCHIVE_PNPM_LOCK_REQUIRED")}if(input2.inspection.packageManagerDeclaration!==APPROVED_PACKAGE_MANAGER){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANAGER_VERSION_UNSUPPORTED")}if(!hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_ENTRY_REQUIRED")}else{if(hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_CONFLICT");if(!input2.inspection.files.some(file2=>file2.path==="index.html")){return fail11("STATIC_SITE_ENTRYPOINT_REQUIRED")}}if(input2.claim.declaredRuntime!==input2.expectedRuntime||input2.claim.sourceBundleSha256!==input2.inspection.recomputed.rawArchiveSha256||!equalContractValue(input2.claim.authSchema,input2.inspection.recomputed.authSchema)||!equalContractValue(input2.claim.dependencies,input2.inspection.recomputed.dependencies)||!equalContractValue(input2.claim.migrationBundle,input2.inspection.recomputed.migrationBundle)){return fail11("DEPLOY_CLAIM_MISMATCH")}return{...input2.inspection,contractHash:hashAdmittedDeployClaimV1(input2.claim)}}async function admitDeployArchive(input2){const inspected=await inspectDeployArchiveForRuntime(input2);return admitInspectedDeployArchive({inspection:inspected,claim:input2.claim,expectedRuntime:input2.expectedRuntime})}async function inspectDeployArchiveForRuntime(input2){const inspected=await inspectDeployArchive(input2.bundle,input2.limits);const hasRuntimeEntry=findRuntimeEntry(inspected.files);if(input2.expectedRuntime==="server"){if(inspected.recomputed.dependencies.manifestSha256===null){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANIFEST_REQUIRED")}if(!hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_ENTRY_REQUIRED");if(inspected.packageManagerDeclaration!==APPROVED_PACKAGE_MANAGER){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANAGER_VERSION_UNSUPPORTED")}}else{if(hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_CONFLICT");if(!inspected.files.some(file2=>file2.path==="index.html")){return fail11("STATIC_SITE_ENTRYPOINT_REQUIRED")}}return inspected}var PACKAGE_MANIFEST,APPROVED_PACKAGE_MANAGER,MIGRATION_MANIFEST,LOCKFILES,UNSUPPORTED_LOCKFILES,CANONICAL_DEPLOY_BACKEND_ROOT,PROJECT_AUTH_SCHEMA_PATTERN,LEGACY_AUTH_SCHEMA_PATTERN,RUNTIME_ENTRY_PATTERN,SELECTED_METADATA,DEFAULT_LIMITS2,MAX_METADATA_BYTES,DeployArchiveAdmissionError;var init_deploy_archive_admission=__esm({"../platform/src/deploy-archive-admission.ts"(){"use strict";init_index_min();init_dist();init_deploy_contract_admission();init_tar_buffer_extract();PACKAGE_MANIFEST="package.json";APPROVED_PACKAGE_MANAGER="pnpm@10.33.0";MIGRATION_MANIFEST=".gencow/migration-bundle-manifest.json";LOCKFILES=new Map([["pnpm-lock.yaml","pnpm"]]);UNSUPPORTED_LOCKFILES=new Set(["package-lock.json","npm-shrinkwrap.json","bun.lock","bun.lockb","yarn.lock"]);CANONICAL_DEPLOY_BACKEND_ROOT="gencow";PROJECT_AUTH_SCHEMA_PATTERN=new RegExp(`^${CANONICAL_DEPLOY_BACKEND_ROOT}/schema-auth\\.(?:ts|js)$`,"u");LEGACY_AUTH_SCHEMA_PATTERN=new RegExp(`^${CANONICAL_DEPLOY_BACKEND_ROOT}/(?:auth-schema\\.(?:ts|js)|generated/auth-schema\\.(?:ts|js))$`,"u");RUNTIME_ENTRY_PATTERN=new RegExp(`^${CANONICAL_DEPLOY_BACKEND_ROOT}/index\\.(?:ts|js)$`,"u");SELECTED_METADATA=new Set([PACKAGE_MANIFEST,MIGRATION_MANIFEST,...LOCKFILES.keys(),...UNSUPPORTED_LOCKFILES]);DEFAULT_LIMITS2={maxCompressedBytes:100*1024*1024,maxUncompressedBytes:200*1024*1024,maxEntries:1e4,maxDepth:32,maxCompressionRatio:100};MAX_METADATA_BYTES=1024*1024;DeployArchiveAdmissionError=class extends Error{constructor(code,details){super(code);this.code=code;this.details=details;this.name="DeployArchiveAdmissionError"}code;details}}});import{resolve as resolve57}from"node:path";import{and as and15,asc as asc2,eq as eq18,isNull as isNull7,ne as ne8,or as or7}from"drizzle-orm";function fail12(code,status,cause,publicDetails){throw new DeploymentAdmissionError(code,status,publicDetails,cause===void 0?void 0:{cause})}function mapArchiveAdmissionError(error62){console.warn("[deploy-admission] archive rejected",{code:error62.code,files:error62.details?.files??[]});const code=error62.code==="DEPLOY_ARCHIVE_AUTH_SCHEMA_AMBIGUOUS"?"AUTH_SCHEMA_PROVENANCE_AMBIGUOUS":error62.code;return fail12(code,400,error62,error62.details)}async function inspectDeploymentArchiveForRuntime(input2){try{return await inspectDeployArchiveForRuntime(input2)}catch(error62){if(error62 instanceof DeployArchiveAdmissionError)return mapArchiveAdmissionError(error62);throw error62}}async function admitDeploymentArchiveContract(input2){try{return await admitDeployArchive({bundle:input2.bundle,claim:input2.protocol.claim,expectedRuntime:input2.expectedRuntime})}catch(error62){if(error62 instanceof DeployArchiveAdmissionError)return mapArchiveAdmissionError(error62);throw error62}}function compareStableVersions(left,right){const parse4=value2=>value2.split("-")[0].split(".").map(Number);const[leftParts,rightParts]=[parse4(left),parse4(right)];for(let index27=0;index27<3;index27+=1){if(leftParts[index27]!==rightParts[index27])return leftParts[index27]-rightParts[index27]}return 0}function parseDeploymentProtocolRequest(input2){const encodedClaim=input2.getHeader(DEPLOY_CLAIM_HEADER);const protocol=input2.getHeader(DEPLOY_PROTOCOL_HEADER);const cliVersion=input2.getHeader(DEPLOY_CLI_VERSION_HEADER);if(!encodedClaim){if(protocol||cliVersion)return fail12("DEPLOY_CLAIM_HEADER_REQUIRED",400);if(input2.requireVersionedProtocol)return fail12("DEPLOY_CLI_UPGRADE_REQUIRED",426);return{lane:"legacy-observe",claim:null,contractHash:null}}let claim2;try{claim2=parseDeployClaimV1Header(encodedClaim)}catch(error62){return fail12("DEPLOY_CLAIM_INVALID",400,error62)}if(protocol!==String(claim2.protocolVersion)||cliVersion!==claim2.generatedBy.version){return fail12("DEPLOY_PROTOCOL_HEADER_MISMATCH",400)}if(compareStableVersions(cliVersion,MIN_DEPLOY_CLI_VERSION)<0){return fail12("DEPLOY_CLI_UPGRADE_REQUIRED",426)}if(claim2.declaredRuntime!==input2.expectedRuntime){return fail12("DEPLOY_RUNTIME_DECLARATION_MISMATCH",400)}return{lane:"v1-enforce",claim:claim2,contractHash:hashAdmittedDeployClaimV1(claim2)}}function deploymentProtocolResponseHeaders(lane){return{"X-Gencow-Deploy-Min-Protocol":"1","X-Gencow-Min-CLI-Version":MIN_DEPLOY_CLI_VERSION,"X-Gencow-Deploy-Lane":lane}}async function findCandidateCleanupDebt(input2){const unresolved=await input2.db.select({deploymentId:deployments.id}).from(deployments).leftJoin(appRuntimeInstances,and15(eq18(appRuntimeInstances.deploymentId,deployments.id),eq18(appRuntimeInstances.appId,deployments.appId))).where(and15(eq18(deployments.appId,input2.appId),eq18(deployments.env,input2.env),or7(and15(eq18(deployments.status,"failed"),eq18(deployments.candidateCleanupFailureCode,"RUNTIME_CANDIDATE_CLEANUP_INCOMPLETE")),and15(eq18(deployments.executorState,"recovery_required"),eq18(deployments.candidateCleanupFailureCode,"CANDIDATE_CLEANUP_PENDING"))),or7(isNull7(appRuntimeInstances.instanceId),ne8(appRuntimeInstances.state,"stopped"),isNull7(appRuntimeInstances.candidateCleanupCompletedAt)))).orderBy(asc2(deployments.id)).limit(1);return unresolved[0]??null}async function hasCandidateCleanupDebt(input2){return Boolean(await findCandidateCleanupDebt(input2))}async function assertCandidateCleanupTerminal(input2){if(await hasCandidateCleanupDebt(input2))fail12("RUNTIME_CANDIDATE_CLEANUP_INCOMPLETE",503)}async function findRecoveryRequiredDeployment(input2){const rows8=await input2.db.select({deploymentId:deployments.id,correlationId:deployments.correlationId,executionEnvironment:deployments.env,releaseEnvironment:appReleaseAttempts.environment,failureStage:deployments.failureStage,failureCode:deployments.failureCode}).from(deployments).leftJoin(appReleaseAttempts,and15(eq18(appReleaseAttempts.id,deployments.executorReleaseAttemptId),eq18(appReleaseAttempts.appId,deployments.appId))).where(and15(eq18(deployments.appId,input2.appId),eq18(deployments.status,"pending"),eq18(deployments.executorState,"recovery_required"))).orderBy(asc2(deployments.id));for(const row of rows8){if(!deploymentRecoveryScopesOverlap({candidateExecutionEnvironment:row.executionEnvironment,candidateReleaseEnvironment:row.releaseEnvironment,incomingExecutionEnvironment:input2.env,incomingReleaseEnvironment:input2.releaseEnvironment})){continue}if(row.executionEnvironment!=="static"&&row.failureStage==="route"&&row.failureCode===COMMITTED_ROUTE_BLOCKED_CODE){const exempt=await input2.db.select({id:deployments.id}).from(deployments).where(and15(eq18(deployments.id,row.deploymentId),eq18(deployments.appId,input2.appId),committedRouteBlockedSupersedable(input2.db))).limit(1);if(exempt[0])continue}if(await deploymentSupersededByNewerCommit({db:input2.db,appId:input2.appId,deploymentId:row.deploymentId})){continue}return{deploymentId:row.deploymentId,correlationId:row.correlationId}}return null}async function assertDeploymentRecoveryAdmissionOpen(input2){const blocker=await findRecoveryRequiredDeployment(input2);if(!blocker)return;const error62=new DeploymentAdmissionError("DEPLOYMENT_EXECUTOR_RECOVERY_REQUIRED",503);Object.assign(error62,{blockingOperationId:blocker.deploymentId,blockingCorrelationId:blocker.correlationId});throw error62}async function preallocateDeploymentRequest(input2){try{await assertCandidateCleanupTerminal({db:input2.db,appId:input2.appId,env:input2.env});await assertDeploymentRecoveryAdmissionOpen({db:input2.db,appId:input2.appId,env:input2.env,releaseEnvironment:input2.releaseEnvironment});return await preallocateDeploymentAttempt({db:input2.db,appId:input2.appId,env:input2.env,bundle:input2.bundle,declaredRuntime:input2.expectedRuntime,...input2.protocol.claim?{requestId:input2.protocol.claim.requestId,protocolVersion:input2.protocol.claim.protocolVersion,contractJson:JSON.stringify(input2.protocol.claim),contractHash:input2.protocol.contractHash}:{}})}catch(error62){if(error62?.message==="DEPLOY_IDEMPOTENCY_CONFLICT"){return fail12("DEPLOY_IDEMPOTENCY_CONFLICT",409,error62)}throw error62}}function classifyDeploymentReplay(attempt){if(!attempt.replayed)return{kind:"new"};if(attempt.status==="running"&&attempt.controlPlaneState==="active"){return{kind:"active"}}if(attempt.status==="failed")return{kind:"failed"};if(["received","admitted","materializing","candidate","ready"].includes(attempt.controlPlaneState)){return{kind:"resume",state:attempt.controlPlaneState}}return{kind:"in-progress"}}var DEPLOY_CLAIM_HEADER,DEPLOY_PROTOCOL_HEADER,DEPLOY_CLI_VERSION_HEADER,MIN_DEPLOY_CLI_VERSION,DeploymentAdmissionError;var init_deployment_request_admission=__esm({"../platform/src/deployment-request-admission.ts"(){"use strict";init_schema();init_deployment_committed_route_contract();init_deployment_superseded_by_newer_commit();init_deployment_release_scope();init_app_deployment_artifact_store();init_deploy_archive_admission();init_deploy_contract_admission();init_deployment_attempt_store();DEPLOY_CLAIM_HEADER="x-gencow-deploy-claim";DEPLOY_PROTOCOL_HEADER="x-gencow-deploy-protocol";DEPLOY_CLI_VERSION_HEADER="x-gencow-cli-version";MIN_DEPLOY_CLI_VERSION="0.1.189";DeploymentAdmissionError=class extends Error{constructor(code,status,publicDetails,options){super(code,options);this.code=code;this.status=status;this.publicDetails=publicDetails;this.name="DeploymentAdmissionError"}code;status;publicDetails}}});function isExactDependencyVersion(value2){return typeof value2==="string"&&value2.length<=128&&VERSION2.test(value2)}function isSafeDependencyDeclaration(value2){return typeof value2==="string"&&value2.length>0&&new TextEncoder().encode(value2).length<=256&&!CONTROL.test(value2)&&!/(?:password|secret|token|authorization)/iu.test(value2)&&(value2==="latest"||/^(?:workspace:)?[0-9vVxX*~^<>=|. +\-]+$/u.test(value2.replace(/[+-][0-9A-Za-z][0-9A-Za-z.-]*/gu,"")))}function safeDependencyDeclaration(value2){return isSafeDependencyDeclaration(value2)?value2:REDACTED_DECLARATION}function parseComparableVersion(value2){if(!isExactDependencyVersion(value2))return null;const match2=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u.exec(value2);if(!match2)return null;const prerelease=match2[4]?.split(".")??[];if(prerelease.some(id=>/^0\d+$/u.test(id)))return null;return{core:match2.slice(1,4).map(BigInt),prerelease}}function compareLockedToBom(locked,bom){const a=parseComparableVersion(locked);const b2=parseComparableVersion(bom);if(!a||!b2)return"unknown";for(const[index27,kind]of["major","minor","patch"].entries()){if(a.core[index27]!==b2.core[index27])return a.core[index27]>b2.core[index27]?"newer":kind}for(let i=0;i<Math.max(a.prerelease.length,b2.prerelease.length);i++){if(!a.prerelease.length)return"newer";if(!b2.prerelease.length)return"prerelease";const left=a.prerelease[i];const right=b2.prerelease[i];if(left===right)continue;if(left===void 0)return"prerelease";if(right===void 0)return"newer";const leftNumeric=/^\d+$/u.test(left);const rightNumeric=/^\d+$/u.test(right);if(leftNumeric!==rightNumeric)return leftNumeric?"prerelease":"newer";const newer=leftNumeric?BigInt(left)>BigInt(right):left>right;return newer?"newer":"prerelease"}return locked===bom?"matches":"build_metadata"}function formatDependencyVersionTable(packages,{includeExplanation=true}={}){const rows8=[["Package","package.json","Locked","Runtime BOM","Locked vs BOM"],...packages.map(p2=>[p2.packageName,safeDependencyDeclaration(p2.declared),parseComparableVersion(p2.lockedVersion)?p2.lockedVersion:"unknown",p2.bomVersion,DIFFERENCE_LABELS[compareLockedToBom(p2.lockedVersion,p2.bomVersion)]])];const widths=rows8[0].map((_4,column)=>Math.max(...rows8.map(row=>row[column].length)));const format=row=>row.map((cell,column)=>cell.padEnd(widths[column])).join(" | ").trimEnd();return[format(rows8[0]),widths.map(width=>"-".repeat(width)).join("-+-"),...rows8.slice(1).map(format),...includeExplanation?["Locked: pnpm-lock.yaml resolution, not a check of node_modules; unknown means unavailable."]:[]]}function formatLockedBomGuidance(packages,{includeStaleSummary=true}={}){const differences=packages.map(p2=>compareLockedToBom(p2.lockedVersion,p2.bomVersion));const mismatch=differences.some(difference=>difference!=="matches"&&difference!=="unknown");const older=differences.some(difference=>["major","minor","patch","prerelease"].includes(difference));return[...mismatch?["Local development may behave differently from hosted deployments because dependency versions differ.","Aligning local dependencies with the Runtime BOM helps keep behavior consistent."]:[],...older?[...includeStaleSummary?["Some lockfile resolutions are behind the hosted runtime."]:[],"Preview: gencow runtime sync --dry-run --install","Refresh and install: gencow runtime sync --install (preserves latest declarations)."]:[]]}var VERSION2,CONTROL,REDACTED_DECLARATION,DIFFERENCE_LABELS;var init_dependency_version_report=__esm({"../shared/dist/src/dependency-version-report.js"(){"use strict";VERSION2=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u;CONTROL=/[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/u;REDACTED_DECLARATION="[redacted declaration]";DIFFERENCE_LABELS={unknown:"Unknown",matches:"Matches",newer:"Newer than hosted runtime",major:"Major mismatch \u2014 possible compatibility issues",minor:"Minor mismatch",patch:"Patch mismatch",prerelease:"Prerelease mismatch",build_metadata:"Build metadata differs (same precedence)"}}});function object3(value2){return value2!==null&&typeof value2==="object"&&!Array.isArray(value2)}function isPackage(value2){return typeof value2==="string"&&bytes(value2)<=214&&PACKAGE.test(value2)}function isMismatch(value2){return value2==="non_major_mismatch"||value2==="major_mismatch"}function isPolicy(value2){return value2==="warn"||value2==="reject-major"||value2==="reject-all"}function isManagedBomDiagnostic(value2){if(!object3(value2)||value2.schemaVersion!==1||typeof value2.releaseId!=="string"||!RELEASE.test(value2.releaseId)||!isPolicy(value2.policy)||value2.decision!=="warn"&&value2.decision!=="block"||!Array.isArray(value2.packages)||value2.packages.length>MAX_MANAGED_BOM_PACKAGES||!Number.isSafeInteger(value2.totalPackages)||!Number.isSafeInteger(value2.omittedPackages)||value2.omittedPackages<0||value2.totalPackages<1||value2.totalPackages!==value2.packages.length+value2.omittedPackages)return false;const names=new Set;for(const row of value2.packages){if(!object3(row)||!isPackage(row.packageName)||names.has(row.packageName)||!isExactDependencyVersion(row.bomVersion)||row.lockedVersion!==void 0&&!isExactDependencyVersion(row.lockedVersion)||!isMismatch(row.classification)||typeof row.declarationRedacted!=="boolean"||(row.declarationRedacted?row.declared!==REDACTED:!isSafeDependencyDeclaration(row.declared)))return false;names.add(row.packageName)}try{return bytes(JSON.stringify(value2))<=MAX_MANAGED_BOM_DIAGNOSTIC_BYTES}catch{return false}}function buildManagedBomWarning(input2){const warning={code:input2.abort?"MANAGED_BOM_MISMATCH":"MANAGED_BOM_WARNING",phase:"dependencies",message:input2.abort?"Managed dependency policy blocked deployment.":"Managed dependency policy emitted a warning.",count:1};if(!RELEASE.test(input2.releaseId)||!input2.mismatches.length)return warning;const rows8=new Map;const names=new Set(input2.mismatches.map(row=>row.packageName));for(const row of[...input2.mismatches].sort((a,b2)=>a.packageName<b2.packageName?-1:a.packageName>b2.packageName?1:0)){if(rows8.size>=MAX_MANAGED_BOM_PACKAGES||rows8.has(row.packageName)||!isPackage(row.packageName)||!Object.hasOwn(input2.managedPackages,row.packageName)||input2.managedPackages[row.packageName]!==row.bomVersion||!isExactDependencyVersion(row.bomVersion)||!isMismatch(row.classification))continue;const safe=isSafeDependencyDeclaration(row.declared);rows8.set(row.packageName,{packageName:row.packageName,declared:safe?row.declared:REDACTED,declarationRedacted:!safe,bomVersion:row.bomVersion,...isExactDependencyVersion(row.lockedVersion)?{lockedVersion:row.lockedVersion}:{},classification:row.classification})}const managedBom={schemaVersion:1,releaseId:input2.releaseId,policy:input2.policy,decision:input2.abort?"block":"warn",packages:[...rows8.values()],totalPackages:names.size,omittedPackages:names.size-rows8.size};if(isManagedBomDiagnostic(managedBom))warning.managedBom=managedBom;return warning}function publicManagedBomWarning(value2){if(!object3(value2)||value2.code!=="MANAGED_BOM_WARNING"&&value2.code!=="MANAGED_BOM_MISMATCH")return null;const blocked2=value2.code==="MANAGED_BOM_MISMATCH";const result3={code:value2.code,phase:"dependencies",message:blocked2?"Managed dependency policy blocked deployment.":"Managed dependency policy emitted a warning.",count:Number.isSafeInteger(value2.count)&&value2.count>0?Math.min(1e3,value2.count):1};if(isManagedBomDiagnostic(value2.managedBom)&&value2.managedBom.decision===(blocked2?"block":"warn")){const d=value2.managedBom;result3.managedBom={schemaVersion:1,releaseId:d.releaseId,policy:d.policy,decision:d.decision,packages:d.packages.map(p2=>({packageName:p2.packageName,declared:p2.declared,declarationRedacted:p2.declarationRedacted,bomVersion:p2.bomVersion,...p2.lockedVersion!==void 0?{lockedVersion:p2.lockedVersion}:{},classification:p2.classification})),totalPackages:d.totalPackages,omittedPackages:d.omittedPackages}}return result3}var MAX_MANAGED_BOM_PACKAGES,MAX_MANAGED_BOM_DIAGNOSTIC_BYTES,RELEASE,PACKAGE,REDACTED,bytes;var init_managed_bom_diagnostic=__esm({"../shared/dist/src/managed-bom-diagnostic.js"(){"use strict";init_dependency_version_report();MAX_MANAGED_BOM_PACKAGES=128;MAX_MANAGED_BOM_DIAGNOSTIC_BYTES=128*1024;RELEASE=/^sha256:[a-f0-9]{64}$/u;PACKAGE=/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/u;REDACTED="[redacted declaration]";bytes=value2=>new TextEncoder().encode(value2).length}});function hasVerifiedDeploymentExecutorCompletion(operation){if(operation.executorState!=="completed"||!operation.receiptJson||!operation.receiptSha256){return false}try{const receipt=readVerifiedDeploymentExecutorReceipt(operation);return receipt?.phase==="completed"&&DEPLOYMENT_EXECUTOR_COMPLETED_RECEIPT_CODES.has(receipt.code)&&operation.executorState==="completed"}catch{return false}}function readVerifiedDeploymentExecutorReceipt(operation){if(!operation.receiptJson||!operation.receiptSha256)return null;try{const receipt=sanitizeDeploymentExecutorReceipt(JSON.parse(operation.receiptJson));return hashDeploymentExecutorReceipt(receipt)===operation.receiptSha256?receipt:null}catch{return null}}var POST_COMMIT_ROUTE_ACK_RECOVERED_CODE,RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED_CODE,STALE_STATIC_LIVE_RELEASE_CONVERGED_CODE,DEPLOYMENT_EXECUTOR_COMPLETED_RECEIPT_CODES;var init_deployment_executor_completion_contract=__esm({"../platform/src/deployment-executor-completion-contract.ts"(){"use strict";init_deployment_executor_operation();POST_COMMIT_ROUTE_ACK_RECOVERED_CODE="PLATFORM_DEPLOYMENT_EXECUTOR_POST_COMMIT_ROUTE_ACK_RECOVERED";RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED_CODE="RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED";STALE_STATIC_LIVE_RELEASE_CONVERGED_CODE="PLATFORM_STALE_STATIC_LIVE_RELEASE_CONVERGED";DEPLOYMENT_EXECUTOR_COMPLETED_RECEIPT_CODES=new Set(["PLATFORM_DEPLOYMENT_EXECUTOR_COMPLETED",POST_COMMIT_ROUTE_ACK_RECOVERED_CODE,RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED_CODE,STALE_STATIC_LIVE_RELEASE_CONVERGED_CODE])}});import{and as and16,eq as eq19}from"drizzle-orm";function mergeWarningSnapshot(old,warning){const conflict3=old?.managedBom&&warning.managedBom&&JSON.stringify(old.managedBom)!==JSON.stringify(warning.managedBom);if(old?.managedBomConflict||warning.managedBomConflict||conflict3){if(conflict3)console.warn("MANAGED_BOM_DIAGNOSTIC_INCOMPLETE");return{code:warning.code,phase:warning.phase,message:warning.message,count:Math.max(old?.count??0,warning.count),managedBomConflict:true}}return{...old?.managedBom?old:warning,count:Math.max(old?.count??0,warning.count)}}function normalizeWarningSnapshots(input2){if(!Array.isArray(input2)||input2.length>1e3)throw new Error("DEPLOYMENT_EXECUTOR_RECEIPT_WARNING_INVALID");const normalized=new Map;for(let offset=0;offset<input2.length;offset+=MAX_RECEIPT_WARNINGS){for(const warning of sanitizeDeploymentExecutorWarnings(input2.slice(offset,offset+MAX_RECEIPT_WARNINGS))){const key2=warningKey(warning);normalized.set(key2,{...warning,count:Math.min(1e3,warning.count+(normalized.get(key2)?.count??0))})}}const snapshots=new Map;for(const warning of input2){const key2=warningKey(warning);snapshots.set(key2,mergeWarningSnapshot(snapshots.get(key2),warning))}return[...normalized.values()].map(warning=>({...snapshots.get(warningKey(warning)),count:warning.count}))}function mergeDeploymentExecutorWarnings(prior=[],next=[]){const warnings=new Map;for(const warning of[...normalizeWarningSnapshots(prior),...normalizeWarningSnapshots(next)]){const key2=warningKey(warning);warnings.set(key2,mergeWarningSnapshot(warnings.get(key2),warning))}const incomplete=[...warnings.values()].some(w2=>w2.code===INCOMPLETE_WARNING.code);const retained=[...warnings.values()].filter(w2=>w2.code!==INCOMPLETE_WARNING.code);retained.sort((a,b2)=>Number(REQUIRED_WARNING_CODES.has(b2.code))-Number(REQUIRED_WARNING_CODES.has(a.code))||warningKey(a).localeCompare(warningKey(b2)));const overflow=incomplete||retained.length>MAX_RECEIPT_WARNINGS;return sanitizeDeploymentExecutorWarnings(overflow?[...retained.slice(0,MAX_RECEIPT_WARNINGS-1),{...INCOMPLETE_WARNING}]:retained)}async function readStoredDeploymentReceipt(input2){const rows8=await input2.db.select({receiptJson:deployments.executorReceiptJson,receiptSha256:deployments.executorReceiptSha256}).from(deployments).where(and16(eq19(deployments.id,input2.deploymentId),eq19(deployments.appId,input2.appId))).limit(1);return rows8[0]}function warningsFromStoredDeploymentReceipt(row){if(!row||row.receiptJson===null&&row.receiptSha256===null)return[];const verified=readVerifiedDeploymentExecutorReceipt(row);if(verified)return verified.warnings??[];if(row.receiptSha256===null&&row.receiptJson!==null){try{const legacy=sanitizeDeploymentExecutorReceipt(JSON.parse(row.receiptJson));if(!legacy.warnings?.length)return[]}catch{}}throw new Error("DEPLOYMENT_EXECUTOR_WARNING_RECEIPT_UNVERIFIED")}async function carryDeploymentExecutorWarnings(input2){let prior;let deferredSince;try{const row=await readStoredDeploymentReceipt(input2);prior=warningsFromStoredDeploymentReceipt(row);deferredSince=row?readVerifiedDeploymentExecutorReceipt(row)?.deferredSince:void 0}catch(error62){if(error62 instanceof Error&&error62.message==="DEPLOYMENT_EXECUTOR_WARNING_RECEIPT_UNVERIFIED"&&input2.receipt.phase==="recovery_required"&&input2.receipt.code==="DEPLOYMENT_EXECUTOR_LEASE_RECORD_INVALID")return input2.receipt;throw error62}const warnings=mergeDeploymentExecutorWarnings(prior,input2.receipt.warnings);const nonterminal=!["completed","failed","recovery_required"].includes(input2.receipt.phase);return{...input2.receipt,...nonterminal&&deferredSince&&!input2.receipt.deferredSince?{deferredSince}:{},...warnings.length?{warnings}:{}}}function publicDeploymentExecutorWarnings(warnings){return warnings.map(w2=>publicManagedBomWarning(w2)??{code:w2.code,phase:w2.phase,message:w2.message,count:w2.count})}var INCOMPLETE_WARNING,REQUIRED_WARNING_CODES,warningKey;var init_deployment_executor_warning_receipt=__esm({"../platform/src/deployment-executor-warning-receipt.ts"(){"use strict";init_schema();init_managed_bom_diagnostic();init_deployment_executor_completion_contract();init_deployment_executor_operation();INCOMPLETE_WARNING={code:"DEPLOYMENT_WARNINGS_INCOMPLETE",phase:"diagnostics",message:"Some deployment warnings were omitted because the receipt reached its capacity.",count:1};REQUIRED_WARNING_CODES=new Set(["MANAGED_BOM_WARNING","MANAGED_BOM_MISMATCH","ROUTE_CONVERGENCE_BLOCKED","PLATFORM_STALE_ROUTE_ONLY_RESUME","PLATFORM_STALE_PROJECTION_DEFERRED","PLATFORM_STALE_RELEASE_PROJECTION_SKIPPED"]);warningKey=warning=>`${warning.phase}:${warning.code}:${warning.message}`}});import{and as and17,asc as asc3,eq as eq20,gt as gt5,inArray as inArray9,lte as lte4,ne as ne9,notExists,or as or8,sql as sql99}from"drizzle-orm";import{alias as alias2}from"drizzle-orm/pg-core";async function findActiveAppDeploymentExecutor(input2){return(await input2.db.select({id:deployments.id,correlationId:deployments.correlationId}).from(deployments).where(and17(eq20(deployments.appId,input2.appId),eq20(deployments.status,"pending"),inArray9(deployments.executorState,[...NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES]))).limit(1))[0]??null}function attemptConditions(attempt){return and17(eq20(deployments.id,attempt.deploymentId),eq20(deployments.appId,attempt.appId),eq20(deployments.env,attempt.env),eq20(deployments.attemptId,attempt.attemptId))}async function enqueueDeploymentExecutorOperation(input2){const targetOwnerIdentity=parseDeploymentExecutorOwnerId(input2.targetOwnerId);if(!/^deployment-payload-v1\.[a-zA-Z0-9_-]{8,160}\.[a-f0-9]{64}$/u.test(input2.payloadRef)||!/^[a-z0-9][a-z0-9-]{0,62}$/u.test(input2.targetNodeId)||!/^[a-z0-9][a-z0-9-]{0,31}$/u.test(input2.targetSlotId)||!/^[a-f0-9]{40}$/u.test(input2.targetRevision)||!targetOwnerIdentity||targetOwnerIdentity.nodeId!==input2.targetNodeId||targetOwnerIdentity.slotId!==input2.targetSlotId||targetOwnerIdentity.revision!==input2.targetRevision||!/^[a-f0-9]{64}$/u.test(input2.targetGenerationDigest)||!input2.appInstanceId||!input2.userId||input2.releaseAttemptId!==void 0&&input2.releaseAttemptId!==null&&!/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u.test(input2.releaseAttemptId)||input2.localProjectDir!==void 0&&input2.localProjectDir!==null&&(input2.localProjectDir.length>4096||/[\0\r\n]/u.test(input2.localProjectDir)||input2.localProjectDir.normalize("NFC")!==input2.localProjectDir||!input2.localProjectDir.startsWith("/")&&!/^[A-Za-z]:[\\/]/u.test(input2.localProjectDir)||input2.localProjectDir.replaceAll("\\","/").split("/").includes(".."))||!Number.isSafeInteger(input2.payloadBytes)||input2.payloadBytes<=0||input2.payloadBytes>100*1024*1024){throw new Error("DEPLOYMENT_EXECUTOR_PAYLOAD_REF_INVALID")}const maxQueuedOperations=input2.maxQueuedOperations??DEFAULT_MAX_QUEUED_OPERATIONS;const maxQueuedBytes=input2.maxQueuedBytes??DEFAULT_MAX_QUEUED_BYTES;const maxUserOperations=input2.maxUserOperations??DEFAULT_MAX_USER_OPERATIONS;const maxUserBytes=input2.maxUserBytes??DEFAULT_MAX_USER_BYTES;if(!Number.isSafeInteger(maxQueuedOperations)||maxQueuedOperations<1||!Number.isSafeInteger(maxQueuedBytes)||maxQueuedBytes<input2.payloadBytes||!Number.isSafeInteger(maxUserOperations)||maxUserOperations<1||!Number.isSafeInteger(maxUserBytes)||maxUserBytes<input2.payloadBytes){throw new Error("DEPLOYMENT_EXECUTOR_CAPACITY_CONFIG_INVALID")}const[appBusy,capacityRows,userCapacityRows]=await Promise.all([findActiveAppDeploymentExecutor({db:input2.db,appId:input2.attempt.appId}),input2.db.select({count:sql99`count(*)::integer`,bytes:sql99`coalesce(sum(${deployments.executorPayloadBytes}), 0)::bigint`}).from(deployments).where(and17(eq20(deployments.status,"pending"),eq20(deployments.executorTargetNodeId,input2.targetNodeId),inArray9(deployments.executorState,[...NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES]))),input2.db.select({count:sql99`count(*)::integer`,bytes:sql99`coalesce(sum(${deployments.executorPayloadBytes}), 0)::bigint`,blockingOperationId:sql99`min(${deployments.id})::integer`,blockingCorrelationId:sql99`(array_agg(${deployments.correlationId} ORDER BY ${deployments.id}))[1]`}).from(deployments).innerJoin(apps,eq20(apps.id,deployments.appId)).where(and17(eq20(deployments.status,"pending"),eq20(apps.userId,input2.userId),eq20(deployments.executorState,"queued")))]);if(appBusy){throw new DeploymentExecutorAdmissionError("DEPLOYMENT_EXECUTOR_APP_BUSY",409,appBusy.id,appBusy.correlationId)}const queuedCount=Number(capacityRows[0]?.count??0);const queuedBytes=Number(capacityRows[0]?.bytes??0);if(queuedCount>=maxQueuedOperations||queuedBytes+input2.payloadBytes>maxQueuedBytes){throw new DeploymentExecutorAdmissionError("DEPLOYMENT_EXECUTOR_QUEUE_FULL",429)}const userCount=Number(userCapacityRows[0]?.count??0);const userBytes=Number(userCapacityRows[0]?.bytes??0);if(userCount>=maxUserOperations||userBytes+input2.payloadBytes>maxUserBytes){const blockingOperationId=Number(userCapacityRows[0]?.blockingOperationId??0);const blockingCorrelationId=userCapacityRows[0]?.blockingCorrelationId??null;throw new DeploymentExecutorAdmissionError("DEPLOYMENT_EXECUTOR_USER_QUEUE_FULL",429,Number.isSafeInteger(blockingOperationId)&&blockingOperationId>0?blockingOperationId:void 0,typeof blockingCorrelationId==="string"?blockingCorrelationId:void 0)}const now=input2.now??new Date;const expectedControlPlaneState=input2.expectedControlPlaneState??"admitted";const rows8=await input2.db.update(deployments).set({executorState:"queued",executorTargetNodeId:input2.targetNodeId,executorTargetSlotId:input2.targetSlotId,executorTargetRevision:input2.targetRevision,executorTargetOwnerId:input2.targetOwnerId,executorTargetGenerationDigest:input2.targetGenerationDigest,executorAppInstanceId:input2.appInstanceId,executorPayloadBytes:input2.payloadBytes,executorPayloadRef:input2.payloadRef,executorReleaseAttemptId:input2.releaseAttemptId??null,executorLocalProjectDir:input2.localProjectDir??null,executorQueuedAt:now,executorUpdatedAt:now}).where(and17(attemptConditions(input2.attempt),eq20(deployments.status,"pending"),eq20(deployments.controlPlaneState,expectedControlPlaneState),eq20(deployments.executorState,"not_queued"))).returning({id:deployments.id});if(rows8.length!==1){const conflictRows=await input2.db.select({status:deployments.status,controlPlaneState:deployments.controlPlaneState,executorState:deployments.executorState}).from(deployments).where(attemptConditions(input2.attempt)).limit(1);const conflict3=conflictRows[0];const safeState=value2=>typeof value2==="string"&&/^[a-z_]{2,40}$/u.test(value2)?value2.toUpperCase():"UNKNOWN";throw new Error(conflict3?`DEPLOYMENT_EXECUTOR_ENQUEUE_CONFLICT_${safeState(conflict3.status)}_${safeState(conflict3.controlPlaneState)}_${safeState(conflict3.executorState)}`:"DEPLOYMENT_EXECUTOR_ENQUEUE_CONFLICT_ATTEMPT_ABSENT")}}async function finishDeploymentExecutorOperation(input2){assertDeploymentExecutorTransition(input2.operation.executorState,input2.state);const receipt=sanitizeDeploymentExecutorReceipt(await carryDeploymentExecutorWarnings({db:input2.db,...input2.operation,receipt:input2.receipt}));const receiptJson=JSON.stringify(receipt);const now=input2.now??new Date;const rows8=await input2.db.update(deployments).set({executorState:input2.state,...input2.state==="recovery_required"?{}:{executorPayloadRef:null},executorReceiptJson:receiptJson,executorReceiptSha256:hashDeploymentExecutorReceipt(receipt),executorUpdatedAt:now,...input2.activation?{bundleHash:input2.activation.bundleHash,status:"running",controlPlaneState:"active",callableBackend:input2.activation.callableBackend,failureStage:null,failureCode:null,errorMessage:null}:{},...input2.failure?{failureStage:input2.failure.stage,failureCode:input2.failure.code,candidateCleanupFailureCode:input2.failure.candidateCleanupFailureCode??null,errorMessage:input2.failure.legacyMessage.slice(0,300)}:{},...input2.state==="failed"?{status:"failed",controlPlaneState:"failed"}:{},...input2.clearLease===false?{}:{attemptOwnerId:null,attemptLeaseExpiresAt:null}}).where(and17(eq20(deployments.id,input2.operation.deploymentId),eq20(deployments.appId,input2.operation.appId),eq20(deployments.attemptId,input2.operation.attemptId),eq20(deployments.attemptOwnerId,input2.operation.ownerId),eq20(deployments.executorLeaseEpoch,input2.operation.leaseEpoch),input2.allowExpiredLease?lte4(deployments.attemptLeaseExpiresAt,now):gt5(deployments.attemptLeaseExpiresAt,now),eq20(deployments.executorState,input2.operation.executorState))).returning({id:deployments.id});if(rows8.length!==1)throw new Error("DEPLOYMENT_EXECUTOR_TERMINAL_CONFLICT");input2.operation.executorState=input2.state}async function getOwnedDeploymentExecutorStatus(input2){const rows8=await input2.db.select({deploymentId:deployments.id,appId:deployments.appId,appName:apps.name,appPort:apps.port,currentStaticDeployId:apps.currentStaticDeployId,currentStaticGenerationRef:apps.currentStaticGenerationRef,appInstanceId:apps.instanceId,executorAppInstanceId:deployments.executorAppInstanceId,releaseAttemptId:deployments.executorReleaseAttemptId,releaseEnvironment:appReleaseAttempts.environment,staticSize:apps.staticSize,bundleHash:deployments.bundleHash,status:deployments.status,controlPlaneState:deployments.controlPlaneState,executorState:deployments.executorState,environment:deployments.env,targetNodeId:deployments.executorTargetNodeId,targetSlotId:deployments.executorTargetSlotId,targetRevision:deployments.executorTargetRevision,targetOwnerId:deployments.executorTargetOwnerId,targetGenerationDigest:deployments.executorTargetGenerationDigest,correlationId:deployments.correlationId,failureStage:deployments.failureStage,failureCode:deployments.failureCode,candidateCleanupFailureCode:deployments.candidateCleanupFailureCode,receiptJson:deployments.executorReceiptJson,receiptSha256:deployments.executorReceiptSha256,queuedAt:deployments.executorQueuedAt}).from(deployments).innerJoin(apps,eq20(apps.id,deployments.appId)).leftJoin(appReleaseAttempts,and17(eq20(appReleaseAttempts.id,deployments.executorReleaseAttemptId),eq20(appReleaseAttempts.appId,deployments.appId))).where(and17(eq20(deployments.id,input2.deploymentId),eq20(apps.userId,input2.userId))).limit(1);return rows8[0]??null}var NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES,DEFAULT_MAX_QUEUED_OPERATIONS,DEFAULT_MAX_QUEUED_BYTES,DEFAULT_MAX_USER_OPERATIONS,DEFAULT_MAX_USER_BYTES,DeploymentExecutorAdmissionError;var init_deployment_executor_store=__esm({"../platform/src/deployment-executor-store.ts"(){"use strict";init_deployment_executor_warning_receipt();init_schema();init_postgres_temporal2();init_deployment_failure_contract();init_deployment_release_scope();init_deployment_executor_operation();NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES=["queued","claimed","database_preparing","schema_executing","runtime_preparing","candidate_attesting","committing","reconciling"];DEFAULT_MAX_QUEUED_OPERATIONS=128;DEFAULT_MAX_QUEUED_BYTES=512*1024*1024;DEFAULT_MAX_USER_OPERATIONS=8;DEFAULT_MAX_USER_BYTES=200*1024*1024;DeploymentExecutorAdmissionError=class extends Error{constructor(code,httpStatus,blockingOperationId,blockingCorrelationId,requestId){super(code);this.code=code;this.httpStatus=httpStatus;this.blockingOperationId=blockingOperationId;this.blockingCorrelationId=blockingCorrelationId;this.requestId=requestId}code;httpStatus;blockingOperationId;blockingCorrelationId;requestId}}});function recoveryDeadlineDiagnostic(operation,statusAction){const seal=operation.deadlineSeal;if(operation.state!=="failed_delete_recovery_required"||!seal)return{};return{error:`Delete stopped in the ${seal.stage} stage and passed its recovery deadline. Inspect the same operation with ${statusAction}.`,stage:seal.stage,failedState:seal.failedState,...seal.causeCode?{causeCode:seal.causeCode}:{},stateImpact:DEADLINE_STATE_IMPACT[seal.stage],retryPrecondition:"Run the app delete again; it reopens this same operation. If it stops at the same stage with the same cause code, Platform must clear that cause first.",retryClass:"retryable-infra",userAction:"RETRY"}}function runtimeAbsenceDiagnostic(operation,statusAction){if(operation.lastErrorCode!=="APP_DELETE_RUNTIME_EXTERNAL_ABSENCE_SCOPE_REQUIRED"&&operation.lastErrorCode!=="APP_DELETE_RUNTIME_EXTERNAL_ABSENCE_UNPROVEN"){return{}}const stage=operation.state==="blocked_runtime_outcome_unknown"?"runtime-absence":operation.state==="failed_catalog_cleanup"?"pre-catalog":void 0;if(!stage)return{};const scopeRequired=operation.lastErrorCode==="APP_DELETE_RUNTIME_EXTERNAL_ABSENCE_SCOPE_REQUIRED";return{error:scopeRequired?`Delete cleanup is waiting for Platform to restore exact app placement and ownership. Inspect the same operation with ${statusAction}.`:`Delete cleanup is waiting for Platform to complete exact runtime-absence observation. Inspect the same operation with ${statusAction}.`,stage,capability:"runtime-absence",stateImpact:stage==="pre-catalog"?"The tenant database cleanup step completed, but independent absence is not yet verified; catalog deletion was not recorded. Runtime may have changed.":"The same delete receipt remains active; this runtime proof did not delete the catalog. Runtime or tenant database cleanup may already have occurred.",retryable:false,retryPrecondition:scopeRequired?"Platform must restore exact app placement, current node ownership, and app incarnation; then recheck the same receipt.":"Platform must complete exact runtime absence observation; then recheck the same receipt.",retryClass:"platform-action",userAction:"VIEW_DELETE_STATUS",nextAction:"VIEW_DELETE_STATUS"}}function catalogOnlyEffectDiagnostic(operation,statusAction){return operation.state==="failed_catalog_cleanup"&&["APP_DELETE_CATALOG_ONLY_EFFECTS_PRESENT","APP_DELETE_CATALOG_ONLY_IDENTITY_CHANGED"].includes(operation.lastErrorCode??"")?{error:`Delete cleanup found a changed catalog identity or runtime, deployment, child, or serving-route effect after admission. Inspect the same operation with ${statusAction}.`,stage:"pre-catalog",capability:"catalog-effect-reconciliation",stateImpact:"Tenant database cleanup may have completed, but catalog deletion was not recorded; the same app and delete receipt remain authoritative.",retryable:false,retryPrecondition:"Platform must classify and safely clear the newly observed effect, then reconcile the same delete receipt.",retryClass:"platform-action",userAction:"VIEW_DELETE_STATUS",nextAction:"VIEW_DELETE_STATUS"}:{}}function appDeleteStateDiagnostics(operation,statusAction){return{...runtimeAbsenceDiagnostic(operation,statusAction),...catalogOnlyEffectDiagnostic(operation,statusAction),...recoveryDeadlineDiagnostic(operation,statusAction)}}function blockedActiveWorkDiagnostic(operation,statusAction){if(operation.state!=="blocked_active_work")return{};return{error:`Delete is waiting for the app runtime to become idle and is being retried automatically. Inspect the same operation with ${statusAction}.`,stage:"runtime-stop",...operation.lastErrorCode?{causeCode:operation.lastErrorCode}:{},stateImpact:"The app is still running; its tenant data, routes, and catalog row were not changed by this delete.",retryable:true,retryPrecondition:"No action is needed first: the Platform retries this same operation about every 30 seconds until its recovery deadline. If it then reports failed_delete_recovery_required, run the app delete again.",retryClass:"platform-action",userAction:"VIEW_DELETE_STATUS",nextAction:"VIEW_DELETE_STATUS"}}var DEADLINE_STATE_IMPACT;var init_app_delete_result_diagnostics=__esm({"../platform/src/app-delete-result-diagnostics.ts"(){"use strict";DEADLINE_STATE_IMPACT={admission:"Deletion had not started any destructive step; the app, its routes, runtime, and tenant data are unchanged.","runtime-stop":"The app runtime stop did not finish. Tenant data and the app catalog row were not deleted.","tenant-database":"The runtime is stopped but tenant database cleanup did not finish. The app catalog row was not deleted.","catalog-finalize":"Runtime stop and tenant database cleanup may already be done, but the app catalog row was not deleted."}}});import{sql as sql100}from"drizzle-orm";function decodeAppDeleteErrorCode(stored){if(!stored?.startsWith(SEAL_PREFIX))return{code:stored,seal:null};const[failedState,cause,...extra]=stored.slice(SEAL_PREFIX.length).split(":");const stage=APP_DELETE_STAGE_BY_STATE[failedState??""];if(extra.length>0||!stage||!cause||cause!==NO_CAUSE&&!STABLE_CAUSE_PATTERN.test(cause)){return{code:APP_DELETE_RECOVERY_DEADLINE_CODE,seal:null}}return{code:APP_DELETE_RECOVERY_DEADLINE_CODE,seal:{failedState,stage,causeCode:cause===NO_CAUSE?null:cause}}}var APP_DELETE_RECOVERY_DEADLINE_CODE,SEAL_PREFIX,NO_CAUSE,STABLE_CAUSE_PATTERN,APP_DELETE_STAGE_BY_STATE;var init_app_delete_recovery_deadline=__esm({"../platform/src/app-delete-recovery-deadline.ts"(){"use strict";init_schema();APP_DELETE_RECOVERY_DEADLINE_CODE="APP_DELETE_RECOVERY_DEADLINE_EXCEEDED";SEAL_PREFIX=`${APP_DELETE_RECOVERY_DEADLINE_CODE}:`;NO_CAUSE="NONE";STABLE_CAUSE_PATTERN=/^[A-Z][A-Z0-9_]{2,127}$/u;APP_DELETE_STAGE_BY_STATE={accepted:"admission",stopping_children:"admission",draining_runtime:"runtime-stop",stop_dispatched:"runtime-stop",blocked_ownership_ambiguous:"runtime-stop",blocked_active_work:"runtime-stop",blocked_runtime_outcome_unknown:"runtime-stop",runtime_absent:"tenant-database",tenant_db_drop_pending:"tenant-database",failed_tenant_db_cleanup:"tenant-database",catalog_delete_pending:"catalog-finalize",failed_catalog_cleanup:"catalog-finalize",blocked_catalog_outcome_unknown:"catalog-finalize"}}});import{sql as sql101}from"drizzle-orm";async function redriveRejectedServingRouteDeliveryInTransaction(input2){await input2.tx.execute(sql101`
|
|
8846
|
+
`).join("")).digest("hex")}function validateArtifactFiles(files){const seen=new Set;const validated=files.map(file2=>{const keys2=Object.keys(file2).sort();const path5=normalizePath2(file2.path);if(keys2.join(",")!=="path,sha256,size"||seen.has(path5)||!Number.isSafeInteger(file2.size)||file2.size<0||!/^[a-f0-9]{64}$/u.test(file2.sha256)){throw new Error("invalid artifact file metadata")}seen.add(path5);return{path:path5,size:file2.size,sha256:file2.sha256}});return validated.sort((left,right)=>left.path<right.path?-1:left.path>right.path?1:0)}async function hashArtifactFile(path5){const hash9=createHash45("sha256");for await(const chunk2 of createReadStream(path5))hash9.update(chunk2);return hash9.digest("hex")}async function walk(root2,directory=root2){const files=[];const dirs=[directory];for(const entry of await readdir3(directory,{withFileTypes:true})){const path5=resolve56(directory,entry.name);const stats=await lstat2(path5);if(stats.isSymbolicLink())throw new Error("artifact link is forbidden");if(stats.isDirectory()){const nested=await walk(root2,path5);files.push(...nested.files);dirs.push(...nested.dirs);continue}if(!stats.isFile())throw new Error("artifact special file is forbidden");const artifactPath=relative11(root2,path5).split(sep2).join("/");files.push({path:artifactPath,size:stats.size,sha256:await hashArtifactFile(path5)})}return{files,dirs}}function sameFiles(left,right){return JSON.stringify(validateArtifactFiles(left))===JSON.stringify(validateArtifactFiles(right))}async function extractVerifiedArtifact(bundle,target,expectedFiles){const files=validateArtifactFiles(expectedFiles);const allowedFiles=new Set(files.map(file2=>file2.path));await mkdir5(target,{recursive:true,mode:448});await withTarBufferFile(bundle,async archivePath2=>{await fo({cwd:target,file:archivePath2,strict:true,noChmod:true,filter(entryPath,entry){const entryType=entry.type;const isDirectory=entryType==="Directory";if(isDirectory&&(entryPath==="."||entryPath==="./"))return false;const path5=normalizePath2(isDirectory?entryPath.replace(/\/+$/u,""):entryPath);if(isDirectory)return false;if(entryType!=="File"&&entryType!=="OldFile")throw new Error("unsafe artifact entry");if(!allowedFiles.has(path5))throw new Error("unexpected artifact file");return true}})});await verifyArtifactTree(target,files,false)}async function verifyArtifactTree(root2,expectedFiles,sealed){const tree=await walk(root2);if(!sameFiles(tree.files,expectedFiles))throw new Error("artifact file closure mismatch");if(!sealed)return;for(const file2 of tree.files){if(((await lstat2(resolve56(root2,file2.path))).mode&511)!==292){throw new Error("artifact file is not sealed")}}for(const directory of tree.dirs){if(((await lstat2(directory)).mode&511)!==365){throw new Error("artifact directory is not sealed")}}}async function syncPath(path5){const handle=await open4(path5,"r");try{await handle.sync()}finally{await handle.close()}}async function syncArtifactTree(root2){const tree=await walk(root2);for(const file2 of tree.files)await syncPath(resolve56(root2,file2.path));for(const directory of tree.dirs.reverse())await syncPath(directory)}async function sealArtifactTree(root2){const tree=await walk(root2);for(const file2 of tree.files)await chmod2(resolve56(root2,file2.path),292);for(const directory of tree.dirs.reverse())await chmod2(directory,365);await verifyArtifactTree(root2,tree.files,true)}async function makeArtifactTreeWritable(root2){const tree=await walk(root2);for(const directory of tree.dirs)await chmod2(directory,493);for(const file2 of tree.files)await chmod2(resolve56(root2,file2.path),420)}async function copyVerifiedArtifact(source,target,expectedFiles){await cp(source,target,{recursive:true,force:false,errorOnExist:true});await verifyArtifactTree(target,expectedFiles,false)}async function syncArtifactPath(path5){await syncPath(path5)}var init_app_deployment_artifact_filesystem=__esm({"../platform/src/app-deployment-artifact-filesystem.ts"(){"use strict";init_index_min();init_tar_buffer_extract()}});function parseArtifactMetadata(bytes2){if(bytes2.length===0||bytes2.length>MAX_ARTIFACT_METADATA_BYTES){throw new Error("artifact metadata size is invalid")}const parsed=JSON.parse(bytes2.toString("utf8"));if(!parsed||typeof parsed!=="object"||Array.isArray(parsed)||Object.keys(parsed).sort().join(",")!==FIELDS2.join(",")||parsed.version!==1||!SHA2566.test(parsed.appScopeSha256??"")||!SHA2566.test(parsed.artifactSha256??"")||!SHA2566.test(parsed.rawArchiveSha256??"")||!Number.isSafeInteger(parsed.rawArchiveBytes)||Number(parsed.rawArchiveBytes)<=0||Number(parsed.rawArchiveBytes)>MAX_RAW_ARCHIVE_BYTES||!Array.isArray(parsed.files)||parsed.files.length>1e4){throw new Error("artifact metadata is invalid")}return{version:1,appScopeSha256:parsed.appScopeSha256,artifactSha256:parsed.artifactSha256,rawArchiveSha256:parsed.rawArchiveSha256,rawArchiveBytes:parsed.rawArchiveBytes,files:validateArtifactFiles(parsed.files)}}var SHA2566,FIELDS2,MAX_ARTIFACT_METADATA_BYTES,MAX_RAW_ARCHIVE_BYTES;var init_app_deployment_artifact_metadata=__esm({"../platform/src/app-deployment-artifact-metadata.ts"(){"use strict";init_app_deployment_artifact_filesystem();SHA2566=/^[a-f0-9]{64}$/u;FIELDS2=["version","appScopeSha256","artifactSha256","rawArchiveSha256","rawArchiveBytes","files"].sort();MAX_ARTIFACT_METADATA_BYTES=16*1024*1024;MAX_RAW_ARCHIVE_BYTES=100*1024*1024}});import{createHash as createHash46,randomUUID as randomUUID34}from"node:crypto";import{chmod as chmod3,mkdir as mkdir6,mkdtemp as mkdtemp2,readFile as readFile5,rename as rename3,rm as rm2,stat as stat6,writeFile as writeFile4}from"node:fs/promises";import{dirname as dirname14,join as join16}from"node:path";function fail10(code,cause,stage,pathContext,failureKind,filesystemCode){throw new AppDeploymentArtifactError(code,cause===void 0?void 0:{cause},stage,filesystemCode,pathContext,failureKind)}function filesystemErrorCode(error62){const code=error62?.code;return typeof code==="string"&&/^[A-Z0-9_]{2,16}$/u.test(code)?code:void 0}function failStoreUnavailable(error62,stage,pathContext,failureKind="store_unavailable"){const code=filesystemErrorCode(error62);return fail10("ARTIFACT_STORE_UNAVAILABLE",error62,stage,pathContext,failureKind,code)}function failArtifactAbsent(error62,stage){return fail10("ARTIFACT_NOT_FOUND",error62,stage,"artifact_leaf","artifact_absent",filesystemErrorCode(error62))}function failArtifactIntegrity(cause,stage,pathContext,filesystemCode=filesystemErrorCode(cause)){return fail10("ARTIFACT_INTEGRITY_MISMATCH",cause,stage,pathContext,"integrity_invalid",filesystemCode)}function failFilesystemObservation(error62,stage,pathContext,missingKind){const code=filesystemErrorCode(error62);if(code==="ENOENT"&&missingKind==="artifact_absent")return failArtifactAbsent(error62,stage);if(code==="ENOENT"&&missingKind==="integrity_invalid"){return failArtifactIntegrity(error62,stage,pathContext,code)}if(code==="ENOENT"&&missingKind==="scope_missing"){return fail10("ARTIFACT_NOT_FOUND",error62,stage,pathContext,"scope_missing",code)}if(code&&["EISDIR","ENOTDIR","ELOOP"].includes(code)&&["artifact_leaf","ready_marker","metadata","bundle","source","cache_entry"].includes(pathContext)){return failArtifactIntegrity(error62,stage,pathContext,code)}return failStoreUnavailable(error62,stage,pathContext,"store_unavailable")}function sha2567(value2){return createHash46("sha256").update(value2).digest("hex")}function appScopeSha256(scope){const appId=String(scope.appId);if(typeof scope.appId==="number"&&(!Number.isSafeInteger(scope.appId)||scope.appId<=0)||!appId||appId.length>128||/[\u0000-\u001f\u007f]/u.test(appId)||!/^[a-z][a-z0-9_-]{0,31}$/u.test(scope.environment)){return fail10("ARTIFACT_ADMISSION_INVALID")}return sha2567(JSON.stringify([typeof scope.appId,appId,scope.environment]))}function parseArtifactRef(scope,artifactRef){const match2=ARTIFACT_REF2.exec(artifactRef);const expectedScope=appScopeSha256(scope);if(!match2){return fail10("ARTIFACT_ADMISSION_INVALID",void 0,"artifact_lookup","artifact_reference","reference_invalid")}if(match2[1]!==expectedScope){return fail10("ARTIFACT_NOT_FOUND",void 0,"artifact_lookup","artifact_reference","scope_mismatch")}return{appScopeSha256:match2[1],artifactSha256:match2[2]}}function artifactResult(path5,artifactRef,metadata){return{artifactRef,artifactSha256:metadata.artifactSha256,artifactBytes:metadata.rawArchiveBytes,rawArchiveSha256:metadata.rawArchiveSha256,artifactPath:path5,sourcePath:join16(path5,"source")}}async function isRenameCollision(error62,target){const code=error62?.code;if(code==="EEXIST"||code==="ENOTEMPTY")return true;if(code!=="EACCES")return false;return stat6(target).then(stats=>stats.isDirectory()).catch(()=>false)}async function finalizePublishedArtifact(target,parent,artifactSha256){const readyPath=join16(parent,`${artifactSha256}.ready`);await chmod3(target,365);try{await writeFile4(readyPath,artifactSha256,{mode:292,flag:"wx"});await syncArtifactPath(readyPath)}catch(error62){if(error62?.code!=="EEXIST")throw error62;if(await readFile5(readyPath,"utf8")!==artifactSha256){return fail10("ARTIFACT_INTEGRITY_MISMATCH")}}await syncArtifactPath(parent)}async function removeStaging(path5){await makeArtifactTreeWritable(path5).catch(()=>{});await rm2(path5,{recursive:true,force:true})}function createAppDeploymentArtifactStore(options){const statPath=options.statImpl??stat6;async function read(input2){const ref=parseArtifactRef(input2,input2.artifactRef);const path5=join16(options.artifactRoot,"v1",ref.appScopeSha256,ref.artifactSha256);const readyPath=join16(options.artifactRoot,"v1",ref.appScopeSha256,`${ref.artifactSha256}.ready`);const scopes=[{path:options.artifactRoot,context:"store_root"},{path:join16(options.artifactRoot,"v1"),context:"store_version"},{path:dirname14(path5),context:"app_scope"}];for(const scope of scopes){let scopeStats;try{scopeStats=await statPath(scope.path)}catch(error62){return failFilesystemObservation(error62,"artifact_store_scope",scope.context,"scope_missing")}if(!scopeStats.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_store_scope",scope.context)}}let artifactStats;try{artifactStats=await statPath(path5)}catch(error62){if(filesystemErrorCode(error62)==="ENOENT"){for(const scope of scopes){let currentScope;try{currentScope=await statPath(scope.path)}catch(scopeError){return failFilesystemObservation(scopeError,"artifact_store_scope",scope.context,"scope_missing")}if(!currentScope.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_store_scope",scope.context)}}}return failFilesystemObservation(error62,"artifact_lookup","artifact_leaf","artifact_absent")}if(!artifactStats.isDirectory()){return failArtifactIntegrity(void 0,"artifact_lookup","artifact_leaf")}let marker;let markerStats;try{marker=await readFile5(readyPath,"utf8");markerStats=await stat6(readyPath)}catch(error62){return failFilesystemObservation(error62,"artifact_lookup","ready_marker","integrity_invalid")}if(marker!==ref.artifactSha256||(markerStats.mode&511)!==292){return failArtifactIntegrity(void 0,"artifact_lookup","ready_marker")}let metadataStats;try{const metadataPath=join16(path5,"artifact.json");metadataStats=await stat6(metadataPath)}catch(error62){return failFilesystemObservation(error62,"artifact_verification","metadata","integrity_invalid")}if(metadataStats.size===0||metadataStats.size>MAX_ARTIFACT_METADATA_BYTES){return failArtifactIntegrity(void 0,"artifact_verification","metadata")}let metadataBytes;try{metadataBytes=await readFile5(join16(path5,"artifact.json"))}catch(error62){return failFilesystemObservation(error62,"artifact_verification","metadata","integrity_invalid")}let metadata;try{metadata=parseArtifactMetadata(metadataBytes)}catch(error62){return failArtifactIntegrity(error62,"artifact_verification","metadata")}const bundlePath=join16(path5,"source.tar.gz");let bundleStats;let bundleSha256;try{bundleStats=await stat6(bundlePath);bundleSha256=await hashArtifactFile(bundlePath)}catch(error62){return failFilesystemObservation(error62,"artifact_verification","bundle","integrity_invalid")}let artifactSealStats;try{artifactSealStats=await stat6(path5)}catch(error62){return failFilesystemObservation(error62,"artifact_verification","artifact_leaf","integrity_invalid")}if(metadata.appScopeSha256!==ref.appScopeSha256||metadata.artifactSha256!==ref.artifactSha256||hashArtifactClosure(metadata.files)!==metadata.artifactSha256||bundleStats.size!==metadata.rawArchiveBytes||bundleSha256!==metadata.rawArchiveSha256||(artifactSealStats.mode&511)!==365||(metadataStats.mode&511)!==292||(bundleStats.mode&511)!==292){return failArtifactIntegrity(void 0,"artifact_verification","metadata")}try{await verifyArtifactTree(join16(path5,"source"),metadata.files,true)}catch(error62){if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_verification","source","integrity_invalid")}return failArtifactIntegrity(error62,"artifact_verification","source")}return artifactResult(path5,input2.artifactRef,metadata)}async function publish(input2){const scopeHash=appScopeSha256(input2);let files;try{files=validateArtifactFiles(input2.admission.files);if(sha2567(input2.bundle)!==input2.admission.recomputed.rawArchiveSha256||input2.bundle.length!==input2.admission.recomputed.compressedBytes||hashArtifactClosure(files)!==input2.admission.sourceClosureSha256){return fail10("ARTIFACT_ADMISSION_INVALID")}}catch(error62){if(error62 instanceof AppDeploymentArtifactError)throw error62;return fail10("ARTIFACT_ADMISSION_INVALID")}const artifactSha256=input2.admission.sourceClosureSha256;const artifactRef=`app-artifact-v1.${scopeHash}.${artifactSha256}`;const parent=join16(options.artifactRoot,"v1",scopeHash);const target=join16(parent,artifactSha256);const tempRoot=join16(options.artifactRoot,".tmp");let rootStats;try{rootStats=await stat6(options.artifactRoot)}catch(error62){if(filesystemErrorCode(error62)==="ENOENT")rootStats=null;else return failFilesystemObservation(error62,"artifact_publish","store_root")}if(rootStats&&!rootStats.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_publish","store_root")}try{await mkdir6(parent,{recursive:true,mode:448});await mkdir6(tempRoot,{recursive:true,mode:448})}catch(error62){return failFilesystemObservation(error62,"artifact_publish","store_root")}let staging;try{staging=await mkdtemp2(join16(tempRoot,`${scopeHash}-${randomUUID34()}-`))}catch(error62){return failFilesystemObservation(error62,"artifact_publish","store_root")}const metadata={version:1,appScopeSha256:scopeHash,artifactSha256,rawArchiveSha256:input2.admission.recomputed.rawArchiveSha256,rawArchiveBytes:input2.bundle.length,files};try{const sourcePath=join16(staging,"source");await extractVerifiedArtifact(input2.bundle,sourcePath,files);await writeFile4(join16(staging,"source.tar.gz"),input2.bundle,{mode:384,flag:"wx"});await writeFile4(join16(staging,"artifact.json"),JSON.stringify(metadata),{mode:384,flag:"wx"});await syncArtifactTree(sourcePath);await syncArtifactPath(join16(staging,"source.tar.gz"));await syncArtifactPath(join16(staging,"artifact.json"));await sealArtifactTree(sourcePath);await chmod3(join16(staging,"source.tar.gz"),292);await chmod3(join16(staging,"artifact.json"),292);try{await rename3(staging,target)}catch(error62){if(!await isRenameCollision(error62,target))throw error62;await removeStaging(staging)}await finalizePublishedArtifact(target,parent,artifactSha256);return await read({...input2,artifactRef})}catch(error62){await removeStaging(staging).catch(()=>{});if(error62 instanceof AppDeploymentArtifactError)throw error62;if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_publish","artifact_leaf")}return fail10("ARTIFACT_INTEGRITY_MISMATCH")}}async function materialize(input2){const artifact=await read(input2);const ref=parseArtifactRef(input2,input2.artifactRef);if(!input2.nodeId||input2.nodeId.length>128||/[\u0000-\u001f\u007f]/u.test(input2.nodeId)){return fail10("ARTIFACT_CACHE_INTEGRITY_MISMATCH")}const nodeScope=sha2567(input2.nodeId);const parent=join16(options.cacheRoot,"v1",nodeScope,ref.appScopeSha256);const target=join16(parent,ref.artifactSha256);for(const scopePath of[options.cacheRoot,join16(options.cacheRoot,"v1"),join16(options.cacheRoot,"v1",nodeScope),parent]){let scopeStats;try{scopeStats=await stat6(scopePath)}catch(error62){if(filesystemErrorCode(error62)!=="ENOENT"){return failFilesystemObservation(error62,"artifact_cache","cache_scope")}try{await mkdir6(scopePath,{recursive:true,mode:448});scopeStats=await stat6(scopePath)}catch(createError){return failFilesystemObservation(createError,"artifact_cache","cache_scope","scope_missing")}}if(!scopeStats.isDirectory()){return failFilesystemObservation(Object.assign(new Error,{code:"ENOTDIR"}),"artifact_cache","cache_scope")}}let metadata;try{metadata=parseArtifactMetadata(await readFile5(join16(artifact.artifactPath,"artifact.json")))}catch(error62){if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_verification","metadata","integrity_invalid")}return failArtifactIntegrity(error62,"artifact_verification","metadata")}try{const targetStats=await stat6(target);if(targetStats.isDirectory()){await chmod3(target,365);await verifyArtifactTree(target,metadata.files,true);return{...artifact,runtimePath:target,nodeScope}}return failArtifactIntegrity(void 0,"artifact_cache","cache_entry")}catch(error62){if(filesystemErrorCode(error62)!=="ENOENT"){if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_cache","cache_entry","integrity_invalid")}return fail10("ARTIFACT_CACHE_INTEGRITY_MISMATCH",error62,"artifact_cache","cache_entry","integrity_invalid")}}const staging=join16(parent,`.${ref.artifactSha256}-${randomUUID34()}`);try{await copyVerifiedArtifact(artifact.sourcePath,staging,metadata.files);await syncArtifactTree(staging);await sealArtifactTree(staging);await chmod3(staging,493);try{await rename3(staging,target)}catch(error62){if(!await isRenameCollision(error62,target))throw error62;await removeStaging(staging)}await chmod3(target,365);await syncArtifactPath(parent);await verifyArtifactTree(target,metadata.files,true);return{...artifact,runtimePath:target,nodeScope}}catch(error62){await removeStaging(staging).catch(()=>{});if(error62 instanceof AppDeploymentArtifactError)throw error62;if(filesystemErrorCode(error62)){return failFilesystemObservation(error62,"artifact_cache","cache_entry","integrity_invalid")}return fail10("ARTIFACT_CACHE_INTEGRITY_MISMATCH",error62,"artifact_cache","cache_entry","integrity_invalid")}}async function deleteArtifact(input2){const ref=parseArtifactRef(input2,input2.artifactRef);const parent=join16(options.artifactRoot,"v1",ref.appScopeSha256);const target=join16(parent,ref.artifactSha256);const readyPath=join16(parent,`${ref.artifactSha256}.ready`);await makeArtifactTreeWritable(target).catch(error62=>{if(error62.code!=="ENOENT")throw error62});await rm2(target,{recursive:true,force:true});await rm2(readyPath,{force:true})}return{publish,read,materialize,delete:deleteArtifact}}var ARTIFACT_REF2,AppDeploymentArtifactError;var init_app_deployment_artifact_store=__esm({"../platform/src/app-deployment-artifact-store.ts"(){"use strict";init_app_deployment_artifact_filesystem();init_app_deployment_artifact_metadata();ARTIFACT_REF2=/^app-artifact-v1\.([a-f0-9]{64})\.([a-f0-9]{64})$/u;AppDeploymentArtifactError=class extends Error{constructor(code,options,stage,filesystemCode,pathContext,failureKind){super(code,options);this.code=code;this.stage=stage;this.filesystemCode=filesystemCode;this.pathContext=pathContext;this.failureKind=failureKind;this.name="AppDeploymentArtifactError"}code;stage;filesystemCode;pathContext;failureKind}}});function createBlankIndexScanner(){let bomPossible=true;let bomMatched=0;let hasContent=false;return{push(chunk2){for(const byte of chunk2){if(hasContent)return;if(bomPossible){if(byte===UTF8_BOM[bomMatched]){bomMatched+=1;if(bomMatched===UTF8_BOM.length)bomPossible=false;continue}if(bomMatched>0){hasContent=true;return}bomPossible=false}if(!ASCII_WHITESPACE.has(byte)){hasContent=true;return}}},finish(){return!hasContent&&bomMatched!==1&&bomMatched!==2}}}function staticSiteEntrypointRejection(entry){if(!entry||!entry.isFile)return STATIC_SITE_ENTRYPOINT_MISSING_CODE;if(entry.size===0||entry.blank)return STATIC_ARTIFACT_INDEX_EMPTY_CODE;return null}var STATIC_SITE_ENTRYPOINT_MISSING_CODE,STATIC_ARTIFACT_INDEX_EMPTY_CODE,STATIC_INDEX_BLANK_SCAN_LIMIT_BYTES,UTF8_BOM,ASCII_WHITESPACE;var init_static_site_entrypoint_policy=__esm({"../platform/src/static-site-entrypoint-policy.ts"(){"use strict";STATIC_SITE_ENTRYPOINT_MISSING_CODE="STATIC_SITE_ENTRYPOINT_REQUIRED";STATIC_ARTIFACT_INDEX_EMPTY_CODE="STATIC_ARTIFACT_INDEX_EMPTY";STATIC_INDEX_BLANK_SCAN_LIMIT_BYTES=64*1024;UTF8_BOM=[239,187,191];ASCII_WHITESPACE=new Set([32,9,10,13,12,11])}});import{createHash as createHash47}from"node:crypto";function fail11(code,details){throw new DeployArchiveAdmissionError(code,details)}function normalizeEntryPath(rawPath,directory){if(!rawPath||Buffer.byteLength(rawPath)>1024||/[\u0000-\u001f\u007f]/.test(rawPath)||rawPath.includes("\\")){return fail11("DEPLOY_ARCHIVE_PATH_INVALID")}const withoutDot=rawPath.replace(/^\.\//,"");const normalized=(directory?withoutDot.replace(/\/+$/,""):withoutDot).normalize("NFC");const segments=normalized.split("/");if(!normalized||normalized!==(directory?withoutDot.replace(/\/+$/,""):withoutDot)||normalized.startsWith("/")||/^[A-Za-z]:/.test(normalized)||segments.some(segment=>!segment||segment==="."||segment==="..")){return fail11("DEPLOY_ARCHIVE_PATH_INVALID")}return normalized}function sha2568(value2){return createHash47("sha256").update(value2).digest("hex")}function equalContractValue(left,right){return JSON.stringify(left)===JSON.stringify(right)}function isMetadataFile(path5){return SELECTED_METADATA.has(path5)||PROJECT_AUTH_SCHEMA_PATTERN.test(path5)||LEGACY_AUTH_SCHEMA_PATTERN.test(path5)}function findRootIndexEntry(inspection){const entry=inspection.files.find(file2=>file2.path==="index.html");return entry?{isFile:true,size:entry.size,blank:inspection.rootIndexBlank===true}:void 0}function findRuntimeEntry(files){return files.find(file2=>RUNTIME_ENTRY_PATTERN.test(file2.path))?.path??null}async function inspectDeployArchive(bundle,overrides={}){const limits={...DEFAULT_LIMITS2,...overrides};if(bundle.length===0||bundle.length>limits.maxCompressedBytes){return fail11("DEPLOY_ARCHIVE_COMPRESSED_SIZE_LIMIT")}const paths=new Map;const knownDirectoryPrefixes=new Set;const caseFolded=new Map;const files=[];let rootIndexBlank=null;const metadata=new Map;let entryCount=0;let uncompressedBytes=0;let streamError=null;const inspectArchiveFile=archivePath2=>Ct({file:archivePath2,strict:true,onentry(entry){const isDirectory=entry.type==="Directory";if(!isDirectory&&entry.type!=="File"&&entry.type!=="OldFile"){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_ENTRY_TYPE_INVALID");entry.resume();return}if(isDirectory&&(entry.path==="."||entry.path==="./")){entry.resume();return}let path5;try{path5=normalizeEntryPath(entry.path,isDirectory)}catch(error62){streamError??=error62;entry.resume();return}entryCount+=1;if(entryCount>limits.maxEntries)streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_ENTRY_LIMIT");const segments=path5.split("/");if(segments.length>limits.maxDepth){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_DEPTH_LIMIT")}const prefixes=segments.map((_4,index27)=>segments.slice(0,index27+1).join("/"));const hasCaseFoldCollision=prefixes.some(prefix=>{const known=caseFolded.get(prefix.toLocaleLowerCase("en-US"));return known!==void 0&&known!==prefix});if(paths.has(path5)||hasCaseFoldCollision){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_PATH_COLLISION")}const ancestors=prefixes.slice(0,-1);for(const ancestor of ancestors){if(paths.get(ancestor)==="file"){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_PATH_COLLISION")}}if(!isDirectory&&knownDirectoryPrefixes.has(path5)){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_PATH_COLLISION")}paths.set(path5,isDirectory?"directory":"file");for(const ancestor of ancestors)knownDirectoryPrefixes.add(ancestor);for(const prefix of prefixes){const folded=prefix.toLocaleLowerCase("en-US");if(!caseFolded.has(folded))caseFolded.set(folded,prefix)}if(isDirectory){entry.resume();return}uncompressedBytes+=entry.size;if(uncompressedBytes>limits.maxUncompressedBytes){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_SIZE_LIMIT")}if(uncompressedBytes/bundle.length>limits.maxCompressionRatio){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_COMPRESSION_LIMIT")}const hash9=createHash47("sha256");const chunks=[];let actualBytes=0;const isRootIndex=path5==="index.html";const blankScanner=isRootIndex&&entry.size<=STATIC_INDEX_BLANK_SCAN_LIMIT_BYTES?createBlankIndexScanner():null;const selectedMetadata=isMetadataFile(path5);const retain=selectedMetadata&&entry.size<=MAX_METADATA_BYTES;if(selectedMetadata&&!retain){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_METADATA_LIMIT")}entry.on("data",chunk2=>{actualBytes+=chunk2.length;hash9.update(chunk2);blankScanner?.push(chunk2);if(retain)chunks.push(Buffer.from(chunk2))});entry.on("end",()=>{if(actualBytes!==entry.size){streamError??=new DeployArchiveAdmissionError("DEPLOY_ARCHIVE_SIZE_MISMATCH")}files.push({path:path5,size:actualBytes,sha256:hash9.digest("hex")});if(isRootIndex)rootIndexBlank=blankScanner?.finish()??false;if(retain)metadata.set(path5,Buffer.concat(chunks))})}});try{await withTarBufferFile(bundle,inspectArchiveFile)}catch{const observedError2=streamError;return fail11(observedError2?.code??"DEPLOY_ARCHIVE_FORMAT_INVALID")}const observedError=streamError;if(observedError)return fail11(observedError.code);const lockfiles=[...LOCKFILES].filter(([path5])=>metadata.has(path5));const unsupportedLockfiles=[...UNSUPPORTED_LOCKFILES].filter(path5=>metadata.has(path5));if(unsupportedLockfiles.length>0){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANAGER_UNSUPPORTED",{files:unsupportedLockfiles.sort()})}if(lockfiles.length>1)return fail11("DEPLOY_ARCHIVE_DEPENDENCY_AMBIGUOUS");const projectAuth=[...metadata.keys()].filter(path5=>PROJECT_AUTH_SCHEMA_PATTERN.test(path5)).sort();const legacyAuth=[...metadata.keys()].filter(path5=>LEGACY_AUTH_SCHEMA_PATTERN.test(path5)).sort();if(projectAuth.length>1||legacyAuth.length>1||projectAuth.length&&legacyAuth.length){return fail11("DEPLOY_ARCHIVE_AUTH_SCHEMA_AMBIGUOUS",{files:[...projectAuth,...legacyAuth].sort()})}const authSchema=projectAuth[0]?{mode:"project",path:projectAuth[0]}:legacyAuth[0]?{mode:"legacy",path:legacyAuth[0]}:{mode:"builtin",path:null};files.sort((left,right)=>left.path<right.path?-1:left.path>right.path?1:0);const sourceClosureSha256=sha2568(files.map(file2=>`${file2.path}\0${file2.size}\0${file2.sha256}
|
|
8847
|
+
`).join(""));const lockfile=lockfiles[0];const packageBytes=metadata.get(PACKAGE_MANIFEST);let packageManagerDeclaration=null;if(packageBytes){try{const parsed=JSON.parse(packageBytes.toString("utf8"));packageManagerDeclaration=typeof parsed.packageManager==="string"?parsed.packageManager.trim():null}catch{return fail11("DEPLOY_ARCHIVE_PACKAGE_MANIFEST_INVALID")}}if(findRuntimeEntry(files)&&packageBytes){const dependencyLock=inspectPnpmDependencyLock({packageJsonText:packageBytes.toString("utf8"),pnpmLockText:lockfile?metadata.get(lockfile[0])?.toString("utf8"):null});if(!dependencyLock.ok){return fail11(dependencyLock.code,{files:[...dependencyLock.files]})}}const migrationBytes=metadata.get(MIGRATION_MANIFEST);let artifactIdentitySha256=null;let migrationCliVersion=null;if(migrationBytes){try{const manifest=JSON.parse(migrationBytes.toString("utf8"));artifactIdentitySha256=typeof manifest.artifactIdentitySha256==="string"?manifest.artifactIdentitySha256:null;migrationCliVersion=typeof manifest.cliVersion==="string"?manifest.cliVersion:null}catch{return fail11("MIGRATION_BUNDLE_MANIFEST_INVALID")}}const recomputed={rawArchiveSha256:sha2568(bundle),compressedBytes:bundle.length,uncompressedBytes,entryCount,fileCount:files.length,authSchema,dependencies:{packageManager:lockfile?.[1]??"none",manifestSha256:packageBytes?sha2568(packageBytes):null,lockfileSha256:lockfile?sha2568(metadata.get(lockfile[0])):null},migrationBundle:{manifestSha256:migrationBytes?sha2568(migrationBytes):null,requiredCapability:migrationBytes?artifactIdentitySha256?MIGRATION_ARTIFACT_IDENTITY_CAPABILITY_V2:MIGRATION_BUNDLE_CAPABILITY_V1:"none",...artifactIdentitySha256?{artifactIdentitySha256}:{}}};return{recomputed,sourceClosureSha256,files,rootIndexBlank,packageManagerDeclaration,...migrationCliVersion?{migrationCliVersion}:{}}}function admitInspectedDeployArchive(input2){const hasRuntimeEntry=findRuntimeEntry(input2.inspection.files);if(input2.expectedRuntime==="server"){if(input2.inspection.recomputed.dependencies.manifestSha256===null){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANIFEST_REQUIRED")}if(input2.inspection.recomputed.dependencies.packageManager!=="pnpm"){return fail11("DEPLOY_ARCHIVE_PNPM_LOCK_REQUIRED")}if(input2.inspection.packageManagerDeclaration!==APPROVED_PACKAGE_MANAGER){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANAGER_VERSION_UNSUPPORTED")}if(!hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_ENTRY_REQUIRED")}else{if(hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_CONFLICT");const entrypointRejection=staticSiteEntrypointRejection(findRootIndexEntry(input2.inspection));if(entrypointRejection)return fail11(entrypointRejection)}if(input2.claim.declaredRuntime!==input2.expectedRuntime||input2.claim.sourceBundleSha256!==input2.inspection.recomputed.rawArchiveSha256||!equalContractValue(input2.claim.authSchema,input2.inspection.recomputed.authSchema)||!equalContractValue(input2.claim.dependencies,input2.inspection.recomputed.dependencies)||!equalContractValue(input2.claim.migrationBundle,input2.inspection.recomputed.migrationBundle)){return fail11("DEPLOY_CLAIM_MISMATCH")}return{...input2.inspection,contractHash:hashAdmittedDeployClaimV1(input2.claim)}}async function admitDeployArchive(input2){const inspected=await inspectDeployArchiveForRuntime(input2);return admitInspectedDeployArchive({inspection:inspected,claim:input2.claim,expectedRuntime:input2.expectedRuntime})}async function inspectDeployArchiveForRuntime(input2){const inspected=await inspectDeployArchive(input2.bundle,input2.limits);const hasRuntimeEntry=findRuntimeEntry(inspected.files);if(input2.expectedRuntime==="server"){if(inspected.recomputed.dependencies.manifestSha256===null){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANIFEST_REQUIRED")}if(!hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_ENTRY_REQUIRED");if(inspected.packageManagerDeclaration!==APPROVED_PACKAGE_MANAGER){return fail11("DEPLOY_ARCHIVE_PACKAGE_MANAGER_VERSION_UNSUPPORTED")}}else{if(hasRuntimeEntry)return fail11("DEPLOY_ARCHIVE_RUNTIME_CONFLICT");const entrypointRejection=staticSiteEntrypointRejection(findRootIndexEntry(inspected));if(entrypointRejection)return fail11(entrypointRejection)}return inspected}var PACKAGE_MANIFEST,APPROVED_PACKAGE_MANAGER,MIGRATION_MANIFEST,LOCKFILES,UNSUPPORTED_LOCKFILES,CANONICAL_DEPLOY_BACKEND_ROOT,PROJECT_AUTH_SCHEMA_PATTERN,LEGACY_AUTH_SCHEMA_PATTERN,RUNTIME_ENTRY_PATTERN,SELECTED_METADATA,DEFAULT_LIMITS2,MAX_METADATA_BYTES,DeployArchiveAdmissionError;var init_deploy_archive_admission=__esm({"../platform/src/deploy-archive-admission.ts"(){"use strict";init_index_min();init_dist();init_deploy_contract_admission();init_tar_buffer_extract();init_static_site_entrypoint_policy();PACKAGE_MANIFEST="package.json";APPROVED_PACKAGE_MANAGER="pnpm@10.33.0";MIGRATION_MANIFEST=".gencow/migration-bundle-manifest.json";LOCKFILES=new Map([["pnpm-lock.yaml","pnpm"]]);UNSUPPORTED_LOCKFILES=new Set(["package-lock.json","npm-shrinkwrap.json","bun.lock","bun.lockb","yarn.lock"]);CANONICAL_DEPLOY_BACKEND_ROOT="gencow";PROJECT_AUTH_SCHEMA_PATTERN=new RegExp(`^${CANONICAL_DEPLOY_BACKEND_ROOT}/schema-auth\\.(?:ts|js)$`,"u");LEGACY_AUTH_SCHEMA_PATTERN=new RegExp(`^${CANONICAL_DEPLOY_BACKEND_ROOT}/(?:auth-schema\\.(?:ts|js)|generated/auth-schema\\.(?:ts|js))$`,"u");RUNTIME_ENTRY_PATTERN=new RegExp(`^${CANONICAL_DEPLOY_BACKEND_ROOT}/index\\.(?:ts|js)$`,"u");SELECTED_METADATA=new Set([PACKAGE_MANIFEST,MIGRATION_MANIFEST,...LOCKFILES.keys(),...UNSUPPORTED_LOCKFILES]);DEFAULT_LIMITS2={maxCompressedBytes:100*1024*1024,maxUncompressedBytes:200*1024*1024,maxEntries:1e4,maxDepth:32,maxCompressionRatio:100};MAX_METADATA_BYTES=1024*1024;DeployArchiveAdmissionError=class extends Error{constructor(code,details){super(code);this.code=code;this.details=details;this.name="DeployArchiveAdmissionError"}code;details}}});import{resolve as resolve57}from"node:path";import{and as and15,asc as asc2,eq as eq18,isNull as isNull7,ne as ne8,or as or7}from"drizzle-orm";function fail12(code,status,cause,publicDetails){throw new DeploymentAdmissionError(code,status,publicDetails,cause===void 0?void 0:{cause})}function mapArchiveAdmissionError(error62){console.warn("[deploy-admission] archive rejected",{code:error62.code,files:error62.details?.files??[]});const code=error62.code==="DEPLOY_ARCHIVE_AUTH_SCHEMA_AMBIGUOUS"?"AUTH_SCHEMA_PROVENANCE_AMBIGUOUS":error62.code;return fail12(code,400,error62,error62.details)}async function inspectDeploymentArchiveForRuntime(input2){try{return await inspectDeployArchiveForRuntime(input2)}catch(error62){if(error62 instanceof DeployArchiveAdmissionError)return mapArchiveAdmissionError(error62);throw error62}}async function admitDeploymentArchiveContract(input2){try{return await admitDeployArchive({bundle:input2.bundle,claim:input2.protocol.claim,expectedRuntime:input2.expectedRuntime})}catch(error62){if(error62 instanceof DeployArchiveAdmissionError)return mapArchiveAdmissionError(error62);throw error62}}function compareStableVersions(left,right){const parse4=value2=>value2.split("-")[0].split(".").map(Number);const[leftParts,rightParts]=[parse4(left),parse4(right)];for(let index27=0;index27<3;index27+=1){if(leftParts[index27]!==rightParts[index27])return leftParts[index27]-rightParts[index27]}return 0}function parseDeploymentProtocolRequest(input2){const encodedClaim=input2.getHeader(DEPLOY_CLAIM_HEADER);const protocol=input2.getHeader(DEPLOY_PROTOCOL_HEADER);const cliVersion=input2.getHeader(DEPLOY_CLI_VERSION_HEADER);if(!encodedClaim){if(protocol||cliVersion)return fail12("DEPLOY_CLAIM_HEADER_REQUIRED",400);if(input2.requireVersionedProtocol)return fail12("DEPLOY_CLI_UPGRADE_REQUIRED",426);return{lane:"legacy-observe",claim:null,contractHash:null}}let claim2;try{claim2=parseDeployClaimV1Header(encodedClaim)}catch(error62){return fail12("DEPLOY_CLAIM_INVALID",400,error62)}if(protocol!==String(claim2.protocolVersion)||cliVersion!==claim2.generatedBy.version){return fail12("DEPLOY_PROTOCOL_HEADER_MISMATCH",400)}if(compareStableVersions(cliVersion,MIN_DEPLOY_CLI_VERSION)<0){return fail12("DEPLOY_CLI_UPGRADE_REQUIRED",426)}if(claim2.declaredRuntime!==input2.expectedRuntime){return fail12("DEPLOY_RUNTIME_DECLARATION_MISMATCH",400)}return{lane:"v1-enforce",claim:claim2,contractHash:hashAdmittedDeployClaimV1(claim2)}}function deploymentProtocolResponseHeaders(lane){return{"X-Gencow-Deploy-Min-Protocol":"1","X-Gencow-Min-CLI-Version":MIN_DEPLOY_CLI_VERSION,"X-Gencow-Deploy-Lane":lane}}async function findCandidateCleanupDebt(input2){const unresolved=await input2.db.select({deploymentId:deployments.id}).from(deployments).leftJoin(appRuntimeInstances,and15(eq18(appRuntimeInstances.deploymentId,deployments.id),eq18(appRuntimeInstances.appId,deployments.appId))).where(and15(eq18(deployments.appId,input2.appId),eq18(deployments.env,input2.env),or7(and15(eq18(deployments.status,"failed"),eq18(deployments.candidateCleanupFailureCode,"RUNTIME_CANDIDATE_CLEANUP_INCOMPLETE")),and15(eq18(deployments.executorState,"recovery_required"),eq18(deployments.candidateCleanupFailureCode,"CANDIDATE_CLEANUP_PENDING"))),or7(isNull7(appRuntimeInstances.instanceId),ne8(appRuntimeInstances.state,"stopped"),isNull7(appRuntimeInstances.candidateCleanupCompletedAt)))).orderBy(asc2(deployments.id)).limit(1);return unresolved[0]??null}async function hasCandidateCleanupDebt(input2){return Boolean(await findCandidateCleanupDebt(input2))}async function assertCandidateCleanupTerminal(input2){if(await hasCandidateCleanupDebt(input2))fail12("RUNTIME_CANDIDATE_CLEANUP_INCOMPLETE",503)}async function findRecoveryRequiredDeployment(input2){const rows8=await input2.db.select({deploymentId:deployments.id,correlationId:deployments.correlationId,executionEnvironment:deployments.env,releaseEnvironment:appReleaseAttempts.environment,failureStage:deployments.failureStage,failureCode:deployments.failureCode}).from(deployments).leftJoin(appReleaseAttempts,and15(eq18(appReleaseAttempts.id,deployments.executorReleaseAttemptId),eq18(appReleaseAttempts.appId,deployments.appId))).where(and15(eq18(deployments.appId,input2.appId),eq18(deployments.status,"pending"),eq18(deployments.executorState,"recovery_required"))).orderBy(asc2(deployments.id));for(const row of rows8){if(!deploymentRecoveryScopesOverlap({candidateExecutionEnvironment:row.executionEnvironment,candidateReleaseEnvironment:row.releaseEnvironment,incomingExecutionEnvironment:input2.env,incomingReleaseEnvironment:input2.releaseEnvironment})){continue}if(row.executionEnvironment!=="static"&&row.failureStage==="route"&&row.failureCode===COMMITTED_ROUTE_BLOCKED_CODE){const exempt=await input2.db.select({id:deployments.id}).from(deployments).where(and15(eq18(deployments.id,row.deploymentId),eq18(deployments.appId,input2.appId),committedRouteBlockedSupersedable(input2.db))).limit(1);if(exempt[0])continue}if(await deploymentSupersededByNewerCommit({db:input2.db,appId:input2.appId,deploymentId:row.deploymentId})){continue}return{deploymentId:row.deploymentId,correlationId:row.correlationId}}return null}async function assertDeploymentRecoveryAdmissionOpen(input2){const blocker=await findRecoveryRequiredDeployment(input2);if(!blocker)return;const error62=new DeploymentAdmissionError("DEPLOYMENT_EXECUTOR_RECOVERY_REQUIRED",503);Object.assign(error62,{blockingOperationId:blocker.deploymentId,blockingCorrelationId:blocker.correlationId});throw error62}async function preallocateDeploymentRequest(input2){try{await assertCandidateCleanupTerminal({db:input2.db,appId:input2.appId,env:input2.env});await assertDeploymentRecoveryAdmissionOpen({db:input2.db,appId:input2.appId,env:input2.env,releaseEnvironment:input2.releaseEnvironment});return await preallocateDeploymentAttempt({db:input2.db,appId:input2.appId,env:input2.env,bundle:input2.bundle,declaredRuntime:input2.expectedRuntime,...input2.protocol.claim?{requestId:input2.protocol.claim.requestId,protocolVersion:input2.protocol.claim.protocolVersion,contractJson:JSON.stringify(input2.protocol.claim),contractHash:input2.protocol.contractHash}:{}})}catch(error62){if(error62?.message==="DEPLOY_IDEMPOTENCY_CONFLICT"){return fail12("DEPLOY_IDEMPOTENCY_CONFLICT",409,error62)}throw error62}}function classifyDeploymentReplay(attempt){if(!attempt.replayed)return{kind:"new"};if(attempt.status==="running"&&attempt.controlPlaneState==="active"){return{kind:"active"}}if(attempt.status==="failed")return{kind:"failed"};if(["received","admitted","materializing","candidate","ready"].includes(attempt.controlPlaneState)){return{kind:"resume",state:attempt.controlPlaneState}}return{kind:"in-progress"}}var DEPLOY_CLAIM_HEADER,DEPLOY_PROTOCOL_HEADER,DEPLOY_CLI_VERSION_HEADER,MIN_DEPLOY_CLI_VERSION,DeploymentAdmissionError;var init_deployment_request_admission=__esm({"../platform/src/deployment-request-admission.ts"(){"use strict";init_schema();init_deployment_committed_route_contract();init_deployment_superseded_by_newer_commit();init_deployment_release_scope();init_app_deployment_artifact_store();init_deploy_archive_admission();init_deploy_contract_admission();init_deployment_attempt_store();DEPLOY_CLAIM_HEADER="x-gencow-deploy-claim";DEPLOY_PROTOCOL_HEADER="x-gencow-deploy-protocol";DEPLOY_CLI_VERSION_HEADER="x-gencow-cli-version";MIN_DEPLOY_CLI_VERSION="0.1.189";DeploymentAdmissionError=class extends Error{constructor(code,status,publicDetails,options){super(code,options);this.code=code;this.status=status;this.publicDetails=publicDetails;this.name="DeploymentAdmissionError"}code;status;publicDetails}}});function isExactDependencyVersion(value2){return typeof value2==="string"&&value2.length<=128&&VERSION2.test(value2)}function isSafeDependencyDeclaration(value2){return typeof value2==="string"&&value2.length>0&&new TextEncoder().encode(value2).length<=256&&!CONTROL.test(value2)&&!/(?:password|secret|token|authorization)/iu.test(value2)&&(value2==="latest"||/^(?:workspace:)?[0-9vVxX*~^<>=|. +\-]+$/u.test(value2.replace(/[+-][0-9A-Za-z][0-9A-Za-z.-]*/gu,"")))}function safeDependencyDeclaration(value2){return isSafeDependencyDeclaration(value2)?value2:REDACTED_DECLARATION}function parseComparableVersion(value2){if(!isExactDependencyVersion(value2))return null;const match2=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u.exec(value2);if(!match2)return null;const prerelease=match2[4]?.split(".")??[];if(prerelease.some(id=>/^0\d+$/u.test(id)))return null;return{core:match2.slice(1,4).map(BigInt),prerelease}}function compareLockedToBom(locked,bom){const a=parseComparableVersion(locked);const b2=parseComparableVersion(bom);if(!a||!b2)return"unknown";for(const[index27,kind]of["major","minor","patch"].entries()){if(a.core[index27]!==b2.core[index27])return a.core[index27]>b2.core[index27]?"newer":kind}for(let i=0;i<Math.max(a.prerelease.length,b2.prerelease.length);i++){if(!a.prerelease.length)return"newer";if(!b2.prerelease.length)return"prerelease";const left=a.prerelease[i];const right=b2.prerelease[i];if(left===right)continue;if(left===void 0)return"prerelease";if(right===void 0)return"newer";const leftNumeric=/^\d+$/u.test(left);const rightNumeric=/^\d+$/u.test(right);if(leftNumeric!==rightNumeric)return leftNumeric?"prerelease":"newer";const newer=leftNumeric?BigInt(left)>BigInt(right):left>right;return newer?"newer":"prerelease"}return locked===bom?"matches":"build_metadata"}function formatDependencyVersionTable(packages,{includeExplanation=true}={}){const rows8=[["Package","package.json","Locked","Runtime BOM","Locked vs BOM"],...packages.map(p2=>[p2.packageName,safeDependencyDeclaration(p2.declared),parseComparableVersion(p2.lockedVersion)?p2.lockedVersion:"unknown",p2.bomVersion,DIFFERENCE_LABELS[compareLockedToBom(p2.lockedVersion,p2.bomVersion)]])];const widths=rows8[0].map((_4,column)=>Math.max(...rows8.map(row=>row[column].length)));const format=row=>row.map((cell,column)=>cell.padEnd(widths[column])).join(" | ").trimEnd();return[format(rows8[0]),widths.map(width=>"-".repeat(width)).join("-+-"),...rows8.slice(1).map(format),...includeExplanation?["Locked: pnpm-lock.yaml resolution, not a check of node_modules; unknown means unavailable."]:[]]}function formatLockedBomGuidance(packages,{includeStaleSummary=true}={}){const differences=packages.map(p2=>compareLockedToBom(p2.lockedVersion,p2.bomVersion));const mismatch=differences.some(difference=>difference!=="matches"&&difference!=="unknown");const older=differences.some(difference=>["major","minor","patch","prerelease"].includes(difference));return[...mismatch?["Local development may behave differently from hosted deployments because dependency versions differ.","Aligning local dependencies with the Runtime BOM helps keep behavior consistent."]:[],...older?[...includeStaleSummary?["Some lockfile resolutions are behind the hosted runtime."]:[],"Preview: gencow runtime sync --dry-run --install","Refresh and install: gencow runtime sync --install (preserves latest declarations)."]:[]]}var VERSION2,CONTROL,REDACTED_DECLARATION,DIFFERENCE_LABELS;var init_dependency_version_report=__esm({"../shared/dist/src/dependency-version-report.js"(){"use strict";VERSION2=/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/u;CONTROL=/[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/u;REDACTED_DECLARATION="[redacted declaration]";DIFFERENCE_LABELS={unknown:"Unknown",matches:"Matches",newer:"Newer than hosted runtime",major:"Major mismatch \u2014 possible compatibility issues",minor:"Minor mismatch",patch:"Patch mismatch",prerelease:"Prerelease mismatch",build_metadata:"Build metadata differs (same precedence)"}}});function object3(value2){return value2!==null&&typeof value2==="object"&&!Array.isArray(value2)}function isPackage(value2){return typeof value2==="string"&&bytes(value2)<=214&&PACKAGE.test(value2)}function isMismatch(value2){return value2==="non_major_mismatch"||value2==="major_mismatch"}function isPolicy(value2){return value2==="warn"||value2==="reject-major"||value2==="reject-all"}function isManagedBomDiagnostic(value2){if(!object3(value2)||value2.schemaVersion!==1||typeof value2.releaseId!=="string"||!RELEASE.test(value2.releaseId)||!isPolicy(value2.policy)||value2.decision!=="warn"&&value2.decision!=="block"||!Array.isArray(value2.packages)||value2.packages.length>MAX_MANAGED_BOM_PACKAGES||!Number.isSafeInteger(value2.totalPackages)||!Number.isSafeInteger(value2.omittedPackages)||value2.omittedPackages<0||value2.totalPackages<1||value2.totalPackages!==value2.packages.length+value2.omittedPackages)return false;const names=new Set;for(const row of value2.packages){if(!object3(row)||!isPackage(row.packageName)||names.has(row.packageName)||!isExactDependencyVersion(row.bomVersion)||row.lockedVersion!==void 0&&!isExactDependencyVersion(row.lockedVersion)||!isMismatch(row.classification)||typeof row.declarationRedacted!=="boolean"||(row.declarationRedacted?row.declared!==REDACTED:!isSafeDependencyDeclaration(row.declared)))return false;names.add(row.packageName)}try{return bytes(JSON.stringify(value2))<=MAX_MANAGED_BOM_DIAGNOSTIC_BYTES}catch{return false}}function buildManagedBomWarning(input2){const warning={code:input2.abort?"MANAGED_BOM_MISMATCH":"MANAGED_BOM_WARNING",phase:"dependencies",message:input2.abort?"Managed dependency policy blocked deployment.":"Managed dependency policy emitted a warning.",count:1};if(!RELEASE.test(input2.releaseId)||!input2.mismatches.length)return warning;const rows8=new Map;const names=new Set(input2.mismatches.map(row=>row.packageName));for(const row of[...input2.mismatches].sort((a,b2)=>a.packageName<b2.packageName?-1:a.packageName>b2.packageName?1:0)){if(rows8.size>=MAX_MANAGED_BOM_PACKAGES||rows8.has(row.packageName)||!isPackage(row.packageName)||!Object.hasOwn(input2.managedPackages,row.packageName)||input2.managedPackages[row.packageName]!==row.bomVersion||!isExactDependencyVersion(row.bomVersion)||!isMismatch(row.classification))continue;const safe=isSafeDependencyDeclaration(row.declared);rows8.set(row.packageName,{packageName:row.packageName,declared:safe?row.declared:REDACTED,declarationRedacted:!safe,bomVersion:row.bomVersion,...isExactDependencyVersion(row.lockedVersion)?{lockedVersion:row.lockedVersion}:{},classification:row.classification})}const managedBom={schemaVersion:1,releaseId:input2.releaseId,policy:input2.policy,decision:input2.abort?"block":"warn",packages:[...rows8.values()],totalPackages:names.size,omittedPackages:names.size-rows8.size};if(isManagedBomDiagnostic(managedBom))warning.managedBom=managedBom;return warning}function publicManagedBomWarning(value2){if(!object3(value2)||value2.code!=="MANAGED_BOM_WARNING"&&value2.code!=="MANAGED_BOM_MISMATCH")return null;const blocked2=value2.code==="MANAGED_BOM_MISMATCH";const result3={code:value2.code,phase:"dependencies",message:blocked2?"Managed dependency policy blocked deployment.":"Managed dependency policy emitted a warning.",count:Number.isSafeInteger(value2.count)&&value2.count>0?Math.min(1e3,value2.count):1};if(isManagedBomDiagnostic(value2.managedBom)&&value2.managedBom.decision===(blocked2?"block":"warn")){const d=value2.managedBom;result3.managedBom={schemaVersion:1,releaseId:d.releaseId,policy:d.policy,decision:d.decision,packages:d.packages.map(p2=>({packageName:p2.packageName,declared:p2.declared,declarationRedacted:p2.declarationRedacted,bomVersion:p2.bomVersion,...p2.lockedVersion!==void 0?{lockedVersion:p2.lockedVersion}:{},classification:p2.classification})),totalPackages:d.totalPackages,omittedPackages:d.omittedPackages}}return result3}var MAX_MANAGED_BOM_PACKAGES,MAX_MANAGED_BOM_DIAGNOSTIC_BYTES,RELEASE,PACKAGE,REDACTED,bytes;var init_managed_bom_diagnostic=__esm({"../shared/dist/src/managed-bom-diagnostic.js"(){"use strict";init_dependency_version_report();MAX_MANAGED_BOM_PACKAGES=128;MAX_MANAGED_BOM_DIAGNOSTIC_BYTES=128*1024;RELEASE=/^sha256:[a-f0-9]{64}$/u;PACKAGE=/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/u;REDACTED="[redacted declaration]";bytes=value2=>new TextEncoder().encode(value2).length}});function hasVerifiedDeploymentExecutorCompletion(operation){if(operation.executorState!=="completed"||!operation.receiptJson||!operation.receiptSha256){return false}try{const receipt=readVerifiedDeploymentExecutorReceipt(operation);return receipt?.phase==="completed"&&DEPLOYMENT_EXECUTOR_COMPLETED_RECEIPT_CODES.has(receipt.code)&&operation.executorState==="completed"}catch{return false}}function readVerifiedDeploymentExecutorReceipt(operation){if(!operation.receiptJson||!operation.receiptSha256)return null;try{const receipt=sanitizeDeploymentExecutorReceipt(JSON.parse(operation.receiptJson));return hashDeploymentExecutorReceipt(receipt)===operation.receiptSha256?receipt:null}catch{return null}}var POST_COMMIT_ROUTE_ACK_RECOVERED_CODE,RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED_CODE,STALE_STATIC_LIVE_RELEASE_CONVERGED_CODE,DEPLOYMENT_EXECUTOR_COMPLETED_RECEIPT_CODES;var init_deployment_executor_completion_contract=__esm({"../platform/src/deployment-executor-completion-contract.ts"(){"use strict";init_deployment_executor_operation();POST_COMMIT_ROUTE_ACK_RECOVERED_CODE="PLATFORM_DEPLOYMENT_EXECUTOR_POST_COMMIT_ROUTE_ACK_RECOVERED";RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED_CODE="RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED";STALE_STATIC_LIVE_RELEASE_CONVERGED_CODE="PLATFORM_STALE_STATIC_LIVE_RELEASE_CONVERGED";DEPLOYMENT_EXECUTOR_COMPLETED_RECEIPT_CODES=new Set(["PLATFORM_DEPLOYMENT_EXECUTOR_COMPLETED",POST_COMMIT_ROUTE_ACK_RECOVERED_CODE,RUNTIME_COMMITTED_ACTIVATION_ROUTE_REPAIRED_CODE,STALE_STATIC_LIVE_RELEASE_CONVERGED_CODE])}});import{and as and16,eq as eq19}from"drizzle-orm";function mergeWarningSnapshot(old,warning){const conflict3=old?.managedBom&&warning.managedBom&&JSON.stringify(old.managedBom)!==JSON.stringify(warning.managedBom);if(old?.managedBomConflict||warning.managedBomConflict||conflict3){if(conflict3)console.warn("MANAGED_BOM_DIAGNOSTIC_INCOMPLETE");return{code:warning.code,phase:warning.phase,message:warning.message,count:Math.max(old?.count??0,warning.count),managedBomConflict:true}}return{...old?.managedBom?old:warning,count:Math.max(old?.count??0,warning.count)}}function normalizeWarningSnapshots(input2){if(!Array.isArray(input2)||input2.length>1e3)throw new Error("DEPLOYMENT_EXECUTOR_RECEIPT_WARNING_INVALID");const normalized=new Map;for(let offset=0;offset<input2.length;offset+=MAX_RECEIPT_WARNINGS){for(const warning of sanitizeDeploymentExecutorWarnings(input2.slice(offset,offset+MAX_RECEIPT_WARNINGS))){const key2=warningKey(warning);normalized.set(key2,{...warning,count:Math.min(1e3,warning.count+(normalized.get(key2)?.count??0))})}}const snapshots=new Map;for(const warning of input2){const key2=warningKey(warning);snapshots.set(key2,mergeWarningSnapshot(snapshots.get(key2),warning))}return[...normalized.values()].map(warning=>({...snapshots.get(warningKey(warning)),count:warning.count}))}function mergeDeploymentExecutorWarnings(prior=[],next=[]){const warnings=new Map;for(const warning of[...normalizeWarningSnapshots(prior),...normalizeWarningSnapshots(next)]){const key2=warningKey(warning);warnings.set(key2,mergeWarningSnapshot(warnings.get(key2),warning))}const incomplete=[...warnings.values()].some(w2=>w2.code===INCOMPLETE_WARNING.code);const retained=[...warnings.values()].filter(w2=>w2.code!==INCOMPLETE_WARNING.code);retained.sort((a,b2)=>Number(REQUIRED_WARNING_CODES.has(b2.code))-Number(REQUIRED_WARNING_CODES.has(a.code))||warningKey(a).localeCompare(warningKey(b2)));const overflow=incomplete||retained.length>MAX_RECEIPT_WARNINGS;return sanitizeDeploymentExecutorWarnings(overflow?[...retained.slice(0,MAX_RECEIPT_WARNINGS-1),{...INCOMPLETE_WARNING}]:retained)}async function readStoredDeploymentReceipt(input2){const rows8=await input2.db.select({receiptJson:deployments.executorReceiptJson,receiptSha256:deployments.executorReceiptSha256}).from(deployments).where(and16(eq19(deployments.id,input2.deploymentId),eq19(deployments.appId,input2.appId))).limit(1);return rows8[0]}function warningsFromStoredDeploymentReceipt(row){if(!row||row.receiptJson===null&&row.receiptSha256===null)return[];const verified=readVerifiedDeploymentExecutorReceipt(row);if(verified)return verified.warnings??[];if(row.receiptSha256===null&&row.receiptJson!==null){try{const legacy=sanitizeDeploymentExecutorReceipt(JSON.parse(row.receiptJson));if(!legacy.warnings?.length)return[]}catch{}}throw new Error("DEPLOYMENT_EXECUTOR_WARNING_RECEIPT_UNVERIFIED")}async function carryDeploymentExecutorWarnings(input2){let prior;let deferredSince;try{const row=await readStoredDeploymentReceipt(input2);prior=warningsFromStoredDeploymentReceipt(row);deferredSince=row?readVerifiedDeploymentExecutorReceipt(row)?.deferredSince:void 0}catch(error62){if(error62 instanceof Error&&error62.message==="DEPLOYMENT_EXECUTOR_WARNING_RECEIPT_UNVERIFIED"&&input2.receipt.phase==="recovery_required"&&input2.receipt.code==="DEPLOYMENT_EXECUTOR_LEASE_RECORD_INVALID")return input2.receipt;throw error62}const warnings=mergeDeploymentExecutorWarnings(prior,input2.receipt.warnings);const nonterminal=!["completed","failed","recovery_required"].includes(input2.receipt.phase);return{...input2.receipt,...nonterminal&&deferredSince&&!input2.receipt.deferredSince?{deferredSince}:{},...warnings.length?{warnings}:{}}}function publicDeploymentExecutorWarnings(warnings){return warnings.map(w2=>publicManagedBomWarning(w2)??{code:w2.code,phase:w2.phase,message:w2.message,count:w2.count})}var INCOMPLETE_WARNING,REQUIRED_WARNING_CODES,warningKey;var init_deployment_executor_warning_receipt=__esm({"../platform/src/deployment-executor-warning-receipt.ts"(){"use strict";init_schema();init_managed_bom_diagnostic();init_deployment_executor_completion_contract();init_deployment_executor_operation();INCOMPLETE_WARNING={code:"DEPLOYMENT_WARNINGS_INCOMPLETE",phase:"diagnostics",message:"Some deployment warnings were omitted because the receipt reached its capacity.",count:1};REQUIRED_WARNING_CODES=new Set(["MANAGED_BOM_WARNING","MANAGED_BOM_MISMATCH","ROUTE_CONVERGENCE_BLOCKED","PLATFORM_STALE_ROUTE_ONLY_RESUME","PLATFORM_STALE_PROJECTION_DEFERRED","PLATFORM_STALE_RELEASE_PROJECTION_SKIPPED"]);warningKey=warning=>`${warning.phase}:${warning.code}:${warning.message}`}});import{and as and17,asc as asc3,eq as eq20,gt as gt5,inArray as inArray9,lte as lte4,ne as ne9,notExists,or as or8,sql as sql99}from"drizzle-orm";import{alias as alias2}from"drizzle-orm/pg-core";async function findActiveAppDeploymentExecutor(input2){return(await input2.db.select({id:deployments.id,correlationId:deployments.correlationId}).from(deployments).where(and17(eq20(deployments.appId,input2.appId),eq20(deployments.status,"pending"),inArray9(deployments.executorState,[...NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES]))).limit(1))[0]??null}function attemptConditions(attempt){return and17(eq20(deployments.id,attempt.deploymentId),eq20(deployments.appId,attempt.appId),eq20(deployments.env,attempt.env),eq20(deployments.attemptId,attempt.attemptId))}async function enqueueDeploymentExecutorOperation(input2){const targetOwnerIdentity=parseDeploymentExecutorOwnerId(input2.targetOwnerId);if(!/^deployment-payload-v1\.[a-zA-Z0-9_-]{8,160}\.[a-f0-9]{64}$/u.test(input2.payloadRef)||!/^[a-z0-9][a-z0-9-]{0,62}$/u.test(input2.targetNodeId)||!/^[a-z0-9][a-z0-9-]{0,31}$/u.test(input2.targetSlotId)||!/^[a-f0-9]{40}$/u.test(input2.targetRevision)||!targetOwnerIdentity||targetOwnerIdentity.nodeId!==input2.targetNodeId||targetOwnerIdentity.slotId!==input2.targetSlotId||targetOwnerIdentity.revision!==input2.targetRevision||!/^[a-f0-9]{64}$/u.test(input2.targetGenerationDigest)||!input2.appInstanceId||!input2.userId||input2.releaseAttemptId!==void 0&&input2.releaseAttemptId!==null&&!/^[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u.test(input2.releaseAttemptId)||input2.localProjectDir!==void 0&&input2.localProjectDir!==null&&(input2.localProjectDir.length>4096||/[\0\r\n]/u.test(input2.localProjectDir)||input2.localProjectDir.normalize("NFC")!==input2.localProjectDir||!input2.localProjectDir.startsWith("/")&&!/^[A-Za-z]:[\\/]/u.test(input2.localProjectDir)||input2.localProjectDir.replaceAll("\\","/").split("/").includes(".."))||!Number.isSafeInteger(input2.payloadBytes)||input2.payloadBytes<=0||input2.payloadBytes>100*1024*1024){throw new Error("DEPLOYMENT_EXECUTOR_PAYLOAD_REF_INVALID")}const maxQueuedOperations=input2.maxQueuedOperations??DEFAULT_MAX_QUEUED_OPERATIONS;const maxQueuedBytes=input2.maxQueuedBytes??DEFAULT_MAX_QUEUED_BYTES;const maxUserOperations=input2.maxUserOperations??DEFAULT_MAX_USER_OPERATIONS;const maxUserBytes=input2.maxUserBytes??DEFAULT_MAX_USER_BYTES;if(!Number.isSafeInteger(maxQueuedOperations)||maxQueuedOperations<1||!Number.isSafeInteger(maxQueuedBytes)||maxQueuedBytes<input2.payloadBytes||!Number.isSafeInteger(maxUserOperations)||maxUserOperations<1||!Number.isSafeInteger(maxUserBytes)||maxUserBytes<input2.payloadBytes){throw new Error("DEPLOYMENT_EXECUTOR_CAPACITY_CONFIG_INVALID")}const[appBusy,capacityRows,userCapacityRows]=await Promise.all([findActiveAppDeploymentExecutor({db:input2.db,appId:input2.attempt.appId}),input2.db.select({count:sql99`count(*)::integer`,bytes:sql99`coalesce(sum(${deployments.executorPayloadBytes}), 0)::bigint`}).from(deployments).where(and17(eq20(deployments.status,"pending"),eq20(deployments.executorTargetNodeId,input2.targetNodeId),inArray9(deployments.executorState,[...NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES]))),input2.db.select({count:sql99`count(*)::integer`,bytes:sql99`coalesce(sum(${deployments.executorPayloadBytes}), 0)::bigint`,blockingOperationId:sql99`min(${deployments.id})::integer`,blockingCorrelationId:sql99`(array_agg(${deployments.correlationId} ORDER BY ${deployments.id}))[1]`}).from(deployments).innerJoin(apps,eq20(apps.id,deployments.appId)).where(and17(eq20(deployments.status,"pending"),eq20(apps.userId,input2.userId),eq20(deployments.executorState,"queued")))]);if(appBusy){throw new DeploymentExecutorAdmissionError("DEPLOYMENT_EXECUTOR_APP_BUSY",409,appBusy.id,appBusy.correlationId)}const queuedCount=Number(capacityRows[0]?.count??0);const queuedBytes=Number(capacityRows[0]?.bytes??0);if(queuedCount>=maxQueuedOperations||queuedBytes+input2.payloadBytes>maxQueuedBytes){throw new DeploymentExecutorAdmissionError("DEPLOYMENT_EXECUTOR_QUEUE_FULL",429)}const userCount=Number(userCapacityRows[0]?.count??0);const userBytes=Number(userCapacityRows[0]?.bytes??0);if(userCount>=maxUserOperations||userBytes+input2.payloadBytes>maxUserBytes){const blockingOperationId=Number(userCapacityRows[0]?.blockingOperationId??0);const blockingCorrelationId=userCapacityRows[0]?.blockingCorrelationId??null;throw new DeploymentExecutorAdmissionError("DEPLOYMENT_EXECUTOR_USER_QUEUE_FULL",429,Number.isSafeInteger(blockingOperationId)&&blockingOperationId>0?blockingOperationId:void 0,typeof blockingCorrelationId==="string"?blockingCorrelationId:void 0)}const now=input2.now??new Date;const expectedControlPlaneState=input2.expectedControlPlaneState??"admitted";const rows8=await input2.db.update(deployments).set({executorState:"queued",executorTargetNodeId:input2.targetNodeId,executorTargetSlotId:input2.targetSlotId,executorTargetRevision:input2.targetRevision,executorTargetOwnerId:input2.targetOwnerId,executorTargetGenerationDigest:input2.targetGenerationDigest,executorAppInstanceId:input2.appInstanceId,executorPayloadBytes:input2.payloadBytes,executorPayloadRef:input2.payloadRef,executorReleaseAttemptId:input2.releaseAttemptId??null,executorLocalProjectDir:input2.localProjectDir??null,executorQueuedAt:now,executorUpdatedAt:now}).where(and17(attemptConditions(input2.attempt),eq20(deployments.status,"pending"),eq20(deployments.controlPlaneState,expectedControlPlaneState),eq20(deployments.executorState,"not_queued"))).returning({id:deployments.id});if(rows8.length!==1){const conflictRows=await input2.db.select({status:deployments.status,controlPlaneState:deployments.controlPlaneState,executorState:deployments.executorState}).from(deployments).where(attemptConditions(input2.attempt)).limit(1);const conflict3=conflictRows[0];const safeState=value2=>typeof value2==="string"&&/^[a-z_]{2,40}$/u.test(value2)?value2.toUpperCase():"UNKNOWN";throw new Error(conflict3?`DEPLOYMENT_EXECUTOR_ENQUEUE_CONFLICT_${safeState(conflict3.status)}_${safeState(conflict3.controlPlaneState)}_${safeState(conflict3.executorState)}`:"DEPLOYMENT_EXECUTOR_ENQUEUE_CONFLICT_ATTEMPT_ABSENT")}}async function finishDeploymentExecutorOperation(input2){assertDeploymentExecutorTransition(input2.operation.executorState,input2.state);const receipt=sanitizeDeploymentExecutorReceipt(await carryDeploymentExecutorWarnings({db:input2.db,...input2.operation,receipt:input2.receipt}));const receiptJson=JSON.stringify(receipt);const now=input2.now??new Date;const rows8=await input2.db.update(deployments).set({executorState:input2.state,...input2.state==="recovery_required"?{}:{executorPayloadRef:null},executorReceiptJson:receiptJson,executorReceiptSha256:hashDeploymentExecutorReceipt(receipt),executorUpdatedAt:now,...input2.activation?{bundleHash:input2.activation.bundleHash,status:"running",controlPlaneState:"active",callableBackend:input2.activation.callableBackend,failureStage:null,failureCode:null,errorMessage:null}:{},...input2.failure?{failureStage:input2.failure.stage,failureCode:input2.failure.code,candidateCleanupFailureCode:input2.failure.candidateCleanupFailureCode??null,errorMessage:input2.failure.legacyMessage.slice(0,300)}:{},...input2.state==="failed"?{status:"failed",controlPlaneState:"failed"}:{},...input2.clearLease===false?{}:{attemptOwnerId:null,attemptLeaseExpiresAt:null}}).where(and17(eq20(deployments.id,input2.operation.deploymentId),eq20(deployments.appId,input2.operation.appId),eq20(deployments.attemptId,input2.operation.attemptId),eq20(deployments.attemptOwnerId,input2.operation.ownerId),eq20(deployments.executorLeaseEpoch,input2.operation.leaseEpoch),input2.allowExpiredLease?lte4(deployments.attemptLeaseExpiresAt,now):gt5(deployments.attemptLeaseExpiresAt,now),eq20(deployments.executorState,input2.operation.executorState))).returning({id:deployments.id});if(rows8.length!==1)throw new Error("DEPLOYMENT_EXECUTOR_TERMINAL_CONFLICT");input2.operation.executorState=input2.state}async function getOwnedDeploymentExecutorStatus(input2){const rows8=await input2.db.select({deploymentId:deployments.id,appId:deployments.appId,appName:apps.name,appPort:apps.port,currentStaticDeployId:apps.currentStaticDeployId,currentStaticGenerationRef:apps.currentStaticGenerationRef,appInstanceId:apps.instanceId,executorAppInstanceId:deployments.executorAppInstanceId,releaseAttemptId:deployments.executorReleaseAttemptId,releaseEnvironment:appReleaseAttempts.environment,staticSize:apps.staticSize,bundleHash:deployments.bundleHash,status:deployments.status,controlPlaneState:deployments.controlPlaneState,executorState:deployments.executorState,environment:deployments.env,targetNodeId:deployments.executorTargetNodeId,targetSlotId:deployments.executorTargetSlotId,targetRevision:deployments.executorTargetRevision,targetOwnerId:deployments.executorTargetOwnerId,targetGenerationDigest:deployments.executorTargetGenerationDigest,correlationId:deployments.correlationId,failureStage:deployments.failureStage,failureCode:deployments.failureCode,candidateCleanupFailureCode:deployments.candidateCleanupFailureCode,receiptJson:deployments.executorReceiptJson,receiptSha256:deployments.executorReceiptSha256,queuedAt:deployments.executorQueuedAt}).from(deployments).innerJoin(apps,eq20(apps.id,deployments.appId)).leftJoin(appReleaseAttempts,and17(eq20(appReleaseAttempts.id,deployments.executorReleaseAttemptId),eq20(appReleaseAttempts.appId,deployments.appId))).where(and17(eq20(deployments.id,input2.deploymentId),eq20(apps.userId,input2.userId))).limit(1);return rows8[0]??null}var NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES,DEFAULT_MAX_QUEUED_OPERATIONS,DEFAULT_MAX_QUEUED_BYTES,DEFAULT_MAX_USER_OPERATIONS,DEFAULT_MAX_USER_BYTES,DeploymentExecutorAdmissionError;var init_deployment_executor_store=__esm({"../platform/src/deployment-executor-store.ts"(){"use strict";init_deployment_executor_warning_receipt();init_schema();init_postgres_temporal2();init_deployment_failure_contract();init_deployment_release_scope();init_deployment_executor_operation();NONTERMINAL_DEPLOYMENT_EXECUTOR_STATES=["queued","claimed","database_preparing","schema_executing","runtime_preparing","candidate_attesting","committing","reconciling"];DEFAULT_MAX_QUEUED_OPERATIONS=128;DEFAULT_MAX_QUEUED_BYTES=512*1024*1024;DEFAULT_MAX_USER_OPERATIONS=8;DEFAULT_MAX_USER_BYTES=200*1024*1024;DeploymentExecutorAdmissionError=class extends Error{constructor(code,httpStatus,blockingOperationId,blockingCorrelationId,requestId){super(code);this.code=code;this.httpStatus=httpStatus;this.blockingOperationId=blockingOperationId;this.blockingCorrelationId=blockingCorrelationId;this.requestId=requestId}code;httpStatus;blockingOperationId;blockingCorrelationId;requestId}}});function recoveryDeadlineDiagnostic(operation,statusAction){const seal=operation.deadlineSeal;if(operation.state!=="failed_delete_recovery_required"||!seal)return{};return{error:`Delete stopped in the ${seal.stage} stage and passed its recovery deadline. Inspect the same operation with ${statusAction}.`,stage:seal.stage,failedState:seal.failedState,...seal.causeCode?{causeCode:seal.causeCode}:{},stateImpact:DEADLINE_STATE_IMPACT[seal.stage],retryPrecondition:"Run the app delete again; it reopens this same operation. If it stops at the same stage with the same cause code, Platform must clear that cause first.",retryClass:"retryable-infra",userAction:"RETRY"}}function runtimeAbsenceDiagnostic(operation,statusAction){if(operation.lastErrorCode!=="APP_DELETE_RUNTIME_EXTERNAL_ABSENCE_SCOPE_REQUIRED"&&operation.lastErrorCode!=="APP_DELETE_RUNTIME_EXTERNAL_ABSENCE_UNPROVEN"){return{}}const stage=operation.state==="blocked_runtime_outcome_unknown"?"runtime-absence":operation.state==="failed_catalog_cleanup"?"pre-catalog":void 0;if(!stage)return{};const scopeRequired=operation.lastErrorCode==="APP_DELETE_RUNTIME_EXTERNAL_ABSENCE_SCOPE_REQUIRED";return{error:scopeRequired?`Delete cleanup is waiting for Platform to restore exact app placement and ownership. Inspect the same operation with ${statusAction}.`:`Delete cleanup is waiting for Platform to complete exact runtime-absence observation. Inspect the same operation with ${statusAction}.`,stage,capability:"runtime-absence",stateImpact:stage==="pre-catalog"?"The tenant database cleanup step completed, but independent absence is not yet verified; catalog deletion was not recorded. Runtime may have changed.":"The same delete receipt remains active; this runtime proof did not delete the catalog. Runtime or tenant database cleanup may already have occurred.",retryable:false,retryPrecondition:scopeRequired?"Platform must restore exact app placement, current node ownership, and app incarnation; then recheck the same receipt.":"Platform must complete exact runtime absence observation; then recheck the same receipt.",retryClass:"platform-action",userAction:"VIEW_DELETE_STATUS",nextAction:"VIEW_DELETE_STATUS"}}function catalogOnlyEffectDiagnostic(operation,statusAction){return operation.state==="failed_catalog_cleanup"&&["APP_DELETE_CATALOG_ONLY_EFFECTS_PRESENT","APP_DELETE_CATALOG_ONLY_IDENTITY_CHANGED"].includes(operation.lastErrorCode??"")?{error:`Delete cleanup found a changed catalog identity or runtime, deployment, child, or serving-route effect after admission. Inspect the same operation with ${statusAction}.`,stage:"pre-catalog",capability:"catalog-effect-reconciliation",stateImpact:"Tenant database cleanup may have completed, but catalog deletion was not recorded; the same app and delete receipt remain authoritative.",retryable:false,retryPrecondition:"Platform must classify and safely clear the newly observed effect, then reconcile the same delete receipt.",retryClass:"platform-action",userAction:"VIEW_DELETE_STATUS",nextAction:"VIEW_DELETE_STATUS"}:{}}function appDeleteStateDiagnostics(operation,statusAction){return{...runtimeAbsenceDiagnostic(operation,statusAction),...catalogOnlyEffectDiagnostic(operation,statusAction),...recoveryDeadlineDiagnostic(operation,statusAction)}}function blockedActiveWorkDiagnostic(operation,statusAction){if(operation.state!=="blocked_active_work")return{};return{error:`Delete is waiting for the app runtime to become idle and is being retried automatically. Inspect the same operation with ${statusAction}.`,stage:"runtime-stop",...operation.lastErrorCode?{causeCode:operation.lastErrorCode}:{},stateImpact:"The app is still running; its tenant data, routes, and catalog row were not changed by this delete.",retryable:true,retryPrecondition:"No action is needed first: the Platform retries this same operation about every 30 seconds until its recovery deadline. If it then reports failed_delete_recovery_required, run the app delete again.",retryClass:"platform-action",userAction:"VIEW_DELETE_STATUS",nextAction:"VIEW_DELETE_STATUS"}}var DEADLINE_STATE_IMPACT;var init_app_delete_result_diagnostics=__esm({"../platform/src/app-delete-result-diagnostics.ts"(){"use strict";DEADLINE_STATE_IMPACT={admission:"Deletion had not started any destructive step; the app, its routes, runtime, and tenant data are unchanged.","runtime-stop":"The app runtime stop did not finish. Tenant data and the app catalog row were not deleted.","tenant-database":"The runtime is stopped but tenant database cleanup did not finish. The app catalog row was not deleted.","catalog-finalize":"Runtime stop and tenant database cleanup may already be done, but the app catalog row was not deleted."}}});import{sql as sql100}from"drizzle-orm";function decodeAppDeleteErrorCode(stored){if(!stored?.startsWith(SEAL_PREFIX))return{code:stored,seal:null};const[failedState,cause,...extra]=stored.slice(SEAL_PREFIX.length).split(":");const stage=APP_DELETE_STAGE_BY_STATE[failedState??""];if(extra.length>0||!stage||!cause||cause!==NO_CAUSE&&!STABLE_CAUSE_PATTERN.test(cause)){return{code:APP_DELETE_RECOVERY_DEADLINE_CODE,seal:null}}return{code:APP_DELETE_RECOVERY_DEADLINE_CODE,seal:{failedState,stage,causeCode:cause===NO_CAUSE?null:cause}}}var APP_DELETE_RECOVERY_DEADLINE_CODE,SEAL_PREFIX,NO_CAUSE,STABLE_CAUSE_PATTERN,APP_DELETE_STAGE_BY_STATE;var init_app_delete_recovery_deadline=__esm({"../platform/src/app-delete-recovery-deadline.ts"(){"use strict";init_schema();APP_DELETE_RECOVERY_DEADLINE_CODE="APP_DELETE_RECOVERY_DEADLINE_EXCEEDED";SEAL_PREFIX=`${APP_DELETE_RECOVERY_DEADLINE_CODE}:`;NO_CAUSE="NONE";STABLE_CAUSE_PATTERN=/^[A-Z][A-Z0-9_]{2,127}$/u;APP_DELETE_STAGE_BY_STATE={accepted:"admission",stopping_children:"admission",draining_runtime:"runtime-stop",stop_dispatched:"runtime-stop",blocked_ownership_ambiguous:"runtime-stop",blocked_active_work:"runtime-stop",blocked_runtime_outcome_unknown:"runtime-stop",runtime_absent:"tenant-database",tenant_db_drop_pending:"tenant-database",failed_tenant_db_cleanup:"tenant-database",catalog_delete_pending:"catalog-finalize",failed_catalog_cleanup:"catalog-finalize",blocked_catalog_outcome_unknown:"catalog-finalize"}}});import{sql as sql101}from"drizzle-orm";async function redriveRejectedServingRouteDeliveryInTransaction(input2){await input2.tx.execute(sql101`
|
|
8848
8848
|
SELECT set_config('app.current_user_id', '', true),
|
|
8849
8849
|
set_config('app.current_user_role', 'system', true),
|
|
8850
8850
|
set_config('app.internal_system', 'true', true)
|
package/runtime/tooling.mjs
CHANGED
|
@@ -6825,10 +6825,15 @@ var nodeBuiltinExternals = Array.from(
|
|
|
6825
6825
|
])
|
|
6826
6826
|
);
|
|
6827
6827
|
function readBuildMessageSourcePosition(error62) {
|
|
6828
|
-
const
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6828
|
+
const candidates = [error62, error62?.errors?.[0]];
|
|
6829
|
+
for (const candidate of candidates) {
|
|
6830
|
+
const source = candidate;
|
|
6831
|
+
const position = source?.position ?? source?.location ?? source;
|
|
6832
|
+
if (!position || typeof position.file !== "string" || !Number.isInteger(position.line)) continue;
|
|
6833
|
+
const column = Number.isInteger(position.column) ? position.column : 1;
|
|
6834
|
+
return `${position.file}:${position.line}:${column}`;
|
|
6835
|
+
}
|
|
6836
|
+
return null;
|
|
6832
6837
|
}
|
|
6833
6838
|
function resolveAppEntryDefault(functionsDirAbs) {
|
|
6834
6839
|
return resolveFunctionsImportPath(resolve10(functionsDirAbs));
|
|
@@ -55,11 +55,21 @@ const nodeBuiltinExternals = Array.from(
|
|
|
55
55
|
]),
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
+
// Bun reports one syntax error as a BuildMessage with `position`; two or more arrive as an
|
|
59
|
+
// AggregateError with no `position`, so read `errors[0].position`. `location` is the esbuild shape.
|
|
58
60
|
function readBuildMessageSourcePosition(error: unknown): string | null {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
const candidates = [error, (error as { errors?: unknown } | null)?.errors?.[0]];
|
|
62
|
+
for (const candidate of candidates as unknown[]) {
|
|
63
|
+
const source = candidate as { position?: unknown; location?: unknown } | null | undefined;
|
|
64
|
+
const position = (source?.position ?? source?.location ?? source) as
|
|
65
|
+
| { file?: unknown; line?: unknown; column?: unknown }
|
|
66
|
+
| null
|
|
67
|
+
| undefined;
|
|
68
|
+
if (!position || typeof position.file !== "string" || !Number.isInteger(position.line)) continue;
|
|
69
|
+
const column = Number.isInteger(position.column) ? position.column : 1;
|
|
70
|
+
return `${position.file}:${position.line}:${column}`;
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
function resolveAppEntryDefault(functionsDirAbs: string): string {
|