@prisma/composer-prisma-cloud 0.29.1 → 0.30.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/pack.mjs +1 -1
- package/dist/auth/pack.mjs.map +1 -1
- package/dist/auth/testing.mjs +4005 -1808
- package/dist/auth/testing.mjs.map +1 -1
- package/dist/compute-main.mjs +2 -1
- package/dist/compute-main.mjs.map +1 -1
- package/dist/control.d.mts +1 -1
- package/dist/control.mjs +32 -17
- package/dist/control.mjs.map +1 -1
- package/dist/{get-port-BYnpbW5H.mjs → get-port-CwLPc-ca.mjs} +7 -2
- package/dist/{get-port-BYnpbW5H.mjs.map → get-port-CwLPc-ca.mjs.map} +1 -1
- package/dist/local-target.mjs +37 -9
- package/dist/local-target.mjs.map +1 -1
- package/dist/postgres-main.mjs +1 -1
- package/dist/{s3-credentials-resource-CySVP49N-bNV7rH_d.mjs → s3-credentials-resource-BZjtuopJ-V_3xXzMD.mjs} +12 -8
- package/dist/s3-credentials-resource-BZjtuopJ-V_3xXzMD.mjs.map +1 -0
- package/package.json +28 -28
- package/dist/s3-credentials-resource-CySVP49N-bNV7rH_d.mjs.map +0 -1
package/dist/compute-main.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as readOwnVersion, i as readJsonFile, r as isValidSegment, t as StateFile } from "./segments-DRPHe3kK-BNgikNpo.mjs";
|
|
2
|
-
import { n as portNumbers, t as
|
|
2
|
+
import { n as getPorts, r as portNumbers, t as clearLockedPorts } from "./get-port-CwLPc-ca.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
import * as path from "node:path";
|
|
@@ -516,6 +516,7 @@ function main() {
|
|
|
516
516
|
}
|
|
517
517
|
delete state[app];
|
|
518
518
|
schedulePersist();
|
|
519
|
+
clearLockedPorts();
|
|
519
520
|
}
|
|
520
521
|
await fs.promises.rm(path.join(stateDir, "logs", app), {
|
|
521
522
|
recursive: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute-main.mjs","names":["getPort"],"sources":["../../../1-prisma-cloud/0-lowering/dev-emulators/dist/compute-main.mjs"],"sourcesContent":["import { l as readOwnVersion, m as readJsonFile, p as StateFile, t as isValidSegment } from \"./segments-DRPHe3kK.mjs\";\nimport * as fs from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport * as path from \"node:path\";\nimport getPort, { portNumbers } from \"get-port\";\nimport * as http from \"node:http\";\n//#region src/compute-main.ts\n/**\n* The Compute emulator daemon (local-dev spec § 2 `compute-main.ts`): a small\n* local counterpart of the platform's compute service. Owns service child\n* processes (spawned `bun bootstrap.js` from a real packaged artifact),\n* supervises them (crash backoff, held after repeated fast crashes), and\n* serves a loopback JSON admin API plus per-service log streaming.\n*\n* Runs as its own OS process, started by `daemon.ts`'s `ensureDaemon` via\n* `process.execPath <this file> --port <n> --state-dir <dir>`. Everything it\n* needs travels on argv and each request's own body — it reads no\n* environment variable of its own.\n*/\nconst MIN_SERVICE_PORT = 3e3;\nconst MAX_SERVICE_PORT = 65535;\nconst TERMINATE_GRACE_MS = 5e3;\nconst STABLE_UPTIME_MS = 3e4;\nconst BASE_BACKOFF_MS = 1e3;\nconst MAX_BACKOFF_MS = 3e4;\nconst MAX_CONSECUTIVE_FAST_EXITS = 5;\nconst LOG_POLL_INTERVAL_MS = 100;\nconst APPS_STATE_MODE = 384;\nconst BUN_NOT_FOUND_MESSAGE = \"local dev runs services under bun — the Prisma Compute runtime — and `bun` was not found on PATH. Install it: https://bun.sh.\";\nfunction isServiceStatus(value) {\n\treturn value === \"running\" || value === \"backoff\" || value === \"held\" || value === \"stopped\";\n}\nfunction isStringRecord(value) {\n\treturn typeof value === \"object\" && value !== null && Object.values(value).every((v) => typeof v === \"string\");\n}\nfunction isServiceRecord(value) {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (!(\"id\" in value) || typeof value.id !== \"string\") return false;\n\tif (!(\"address\" in value) || typeof value.address !== \"string\") return false;\n\tif (!(\"port\" in value) || typeof value.port !== \"number\") return false;\n\tif (!(\"status\" in value) || !isServiceStatus(value.status)) return false;\n\tif (!(\"logPath\" in value) || typeof value.logPath !== \"string\") return false;\n\tif (\"pid\" in value && value.pid !== void 0 && typeof value.pid !== \"number\") return false;\n\tif (\"lastExitCode\" in value && value.lastExitCode !== void 0 && typeof value.lastExitCode !== \"number\") return false;\n\tif (\"artifactHash\" in value && value.artifactHash !== void 0 && typeof value.artifactHash !== \"string\") return false;\n\tif (\"artifactDir\" in value && value.artifactDir !== void 0 && typeof value.artifactDir !== \"string\") return false;\n\tif (\"env\" in value && value.env !== void 0 && !isStringRecord(value.env)) return false;\n\treturn true;\n}\nfunction isAppRecord(value) {\n\treturn typeof value === \"object\" && value !== null && \"services\" in value && typeof value.services === \"object\" && value.services !== null && Object.values(value.services).every(isServiceRecord);\n}\nfunction isAppsState(value) {\n\treturn typeof value === \"object\" && value !== null && Object.values(value).every(isAppRecord);\n}\nfunction isDeploymentBody(value) {\n\treturn typeof value === \"object\" && value !== null && \"address\" in value && typeof value.address === \"string\" && \"artifactDir\" in value && typeof value.artifactDir === \"string\" && \"artifactHash\" in value && typeof value.artifactHash === \"string\" && \"env\" in value && isStringRecord(value.env) && \"port\" in value && typeof value.port === \"number\";\n}\nfunction sleep(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n/** Append-only per-service log file — child stdout/stderr plus `[emulator]` supervision lines. No rotation in v1. */\nvar ServiceLog = class {\n\tfilePath;\n\tfd;\n\tconstructor(filePath) {\n\t\tthis.filePath = filePath;\n\t}\n\tensureOpen() {\n\t\tif (this.fd === void 0) {\n\t\t\tfs.mkdirSync(path.dirname(this.filePath), { recursive: true });\n\t\t\tthis.fd = fs.openSync(this.filePath, \"a\");\n\t\t}\n\t\treturn this.fd;\n\t}\n\twriteRaw(chunk) {\n\t\tfs.writeSync(this.ensureOpen(), chunk);\n\t}\n\twriteLine(line) {\n\t\tfs.writeSync(this.ensureOpen(), `${line}\\n`);\n\t}\n\t/** Empties the file — a fresh service start begins a clean log; past sessions' and past deployments' output is not kept. */\n\tclear() {\n\t\tfs.ftruncateSync(this.ensureOpen(), 0);\n\t}\n\t/** Closes the fd if one was ever opened. Idempotent. */\n\tclose() {\n\t\tif (this.fd === void 0) return;\n\t\tfs.closeSync(this.fd);\n\t\tthis.fd = void 0;\n\t}\n};\nfunction parseArgs(argv) {\n\tlet port;\n\tlet stateDir;\n\tfor (let i = 0; i < argv.length; i++) if (argv[i] === \"--port\") port = Number(argv[i + 1]);\n\telse if (argv[i] === \"--state-dir\") stateDir = argv[i + 1];\n\tif (port === void 0 || Number.isNaN(port)) throw new Error(\"compute-main: --port <n> is required\");\n\tif (stateDir === void 0) throw new Error(\"compute-main: --state-dir <dir> is required\");\n\treturn {\n\t\tport,\n\t\tstateDir\n\t};\n}\n/** Resolves `bun` from THIS request's env PATH — never the daemon's own. POSIX-only (Windows is out of scope). */\nfunction resolveBunOnPath(env) {\n\tconst pathVar = env[\"PATH\"];\n\tif (!pathVar) return void 0;\n\tfor (const dir of pathVar.split(path.delimiter)) {\n\t\tif (dir === \"\") continue;\n\t\tconst candidate = path.join(dir, \"bun\");\n\t\ttry {\n\t\t\tfs.accessSync(candidate, fs.constants.X_OK);\n\t\t\treturn candidate;\n\t\t} catch {}\n\t}\n}\nfunction main() {\n\tconst { port, stateDir } = parseArgs(process.argv.slice(2));\n\tconst ownVersion = readOwnVersion();\n\tconst appsJsonPath = path.join(stateDir, \"apps.json\");\n\tconst stateFile = new StateFile(appsJsonPath, APPS_STATE_MODE);\n\tlet state = {};\n\tconst runtimes = /* @__PURE__ */ new Map();\n\tconst logGeneration = /* @__PURE__ */ new Map();\n\tfunction runtimeKey(app, id) {\n\t\treturn `${app}/${id}`;\n\t}\n\tfunction getRuntime(app, id) {\n\t\tconst key = runtimeKey(app, id);\n\t\tlet rt = runtimes.get(key);\n\t\tif (!rt) {\n\t\t\trt = {\n\t\t\t\tchild: void 0,\n\t\t\t\tconsecutiveFastExits: 0,\n\t\t\t\tstartedAt: void 0,\n\t\t\t\tstableTimer: void 0,\n\t\t\t\tbackoffTimer: void 0,\n\t\t\t\texpectedExit: false,\n\t\t\t\tlog: void 0\n\t\t\t};\n\t\t\truntimes.set(key, rt);\n\t\t}\n\t\treturn rt;\n\t}\n\tfunction serviceLogPath(app, id) {\n\t\treturn path.join(stateDir, \"logs\", app, `${id}.log`);\n\t}\n\tfunction getLog(app, id, logPath) {\n\t\tconst rt = getRuntime(app, id);\n\t\tif (!rt.log) rt.log = new ServiceLog(logPath);\n\t\treturn rt.log;\n\t}\n\tfunction schedulePersist() {\n\t\tstateFile.write(state);\n\t}\n\tfunction clearStableTimer(rt) {\n\t\tif (rt.stableTimer) clearTimeout(rt.stableTimer);\n\t\trt.stableTimer = void 0;\n\t}\n\tfunction clearBackoffTimer(rt) {\n\t\tif (rt.backoffTimer) clearTimeout(rt.backoffTimer);\n\t\trt.backoffTimer = void 0;\n\t}\n\tfunction usedServicePorts() {\n\t\tconst ports = /* @__PURE__ */ new Set();\n\t\tfor (const app of Object.values(state)) for (const svc of Object.values(app.services)) ports.add(svc.port);\n\t\treturn ports;\n\t}\n\t/**\n\t* The smallest genuinely free port at or above `MIN_SERVICE_PORT`,\n\t* excluding this daemon's own persisted allocations — persistence and\n\t* the range policy stay ours; whether a candidate is actually bindable\n\t* is `get-port`'s (spec § 2's dependency razor).\n\t*/\n\tasync function smallestUnusedServicePort() {\n\t\treturn getPort({\n\t\t\tport: portNumbers(MIN_SERVICE_PORT, MAX_SERVICE_PORT),\n\t\t\texclude: usedServicePorts()\n\t\t});\n\t}\n\tasync function getOrCreateService(app, id) {\n\t\tlet appRec = state[app];\n\t\tif (!appRec) {\n\t\t\tappRec = { services: {} };\n\t\t\tstate[app] = appRec;\n\t\t}\n\t\tlet svc = appRec.services[id];\n\t\tif (svc) return svc;\n\t\tsvc = {\n\t\t\tid,\n\t\t\taddress: id,\n\t\t\tport: await smallestUnusedServicePort(),\n\t\t\tstatus: \"stopped\",\n\t\t\tlogPath: serviceLogPath(app, id)\n\t\t};\n\t\tappRec.services[id] = svc;\n\t\tschedulePersist();\n\t\treturn svc;\n\t}\n\tfunction waitForExit(child) {\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once(\"exit\", () => resolve());\n\t\t});\n\t}\n\t/** SIGTERM, wait up to `graceMs`, SIGKILL. Marks the exit as expected so supervision doesn't fire. */\n\tasync function killChild(rt, graceMs) {\n\t\tconst child = rt.child;\n\t\tif (!child || child.pid === void 0) return;\n\t\trt.expectedExit = true;\n\t\tconst exited = waitForExit(child);\n\t\tchild.kill(\"SIGTERM\");\n\t\tconst timedOut = Symbol(\"timeout\");\n\t\tif (await Promise.race([exited.then(() => void 0), sleep(graceMs).then(() => timedOut)]) === timedOut) {\n\t\t\tchild.kill(\"SIGKILL\");\n\t\t\tawait exited;\n\t\t}\n\t}\n\tfunction handleChildExit(app, id, svc, rt, code) {\n\t\tclearStableTimer(rt);\n\t\trt.child = void 0;\n\t\tdelete svc.pid;\n\t\tif (code !== null) svc.lastExitCode = code;\n\t\tif (rt.expectedExit) {\n\t\t\trt.expectedExit = false;\n\t\t\tschedulePersist();\n\t\t\treturn;\n\t\t}\n\t\tconst uptime = rt.startedAt !== void 0 ? Date.now() - rt.startedAt : 0;\n\t\tif (uptime >= STABLE_UPTIME_MS) rt.consecutiveFastExits = 0;\n\t\tconst attemptNumber = rt.consecutiveFastExits;\n\t\tif (uptime < STABLE_UPTIME_MS) rt.consecutiveFastExits += 1;\n\t\tif (rt.consecutiveFastExits >= MAX_CONSECUTIVE_FAST_EXITS) {\n\t\t\tsvc.status = \"held\";\n\t\t\tschedulePersist();\n\t\t\tgetLog(app, id, svc.logPath).writeLine(`[emulator] held after ${String(MAX_CONSECUTIVE_FAST_EXITS)} consecutive fast exits — send a new deployment to resume`);\n\t\t\treturn;\n\t\t}\n\t\tconst delayMs = Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** attemptNumber);\n\t\tsvc.status = \"backoff\";\n\t\tschedulePersist();\n\t\tgetLog(app, id, svc.logPath).writeLine(`[emulator] exited (code ${code === null ? \"null\" : String(code)}) — restarting in ${String(delayMs / 1e3)}s`);\n\t\trt.backoffTimer = setTimeout(() => {\n\t\t\trt.backoffTimer = void 0;\n\t\t\tspawnService(app, id, svc, rt, false);\n\t\t}, delayMs);\n\t}\n\tasync function spawnService(app, id, svc, rt, fresh) {\n\t\tconst env = svc.env ?? {};\n\t\tconst artifactDir = svc.artifactDir ?? \".\";\n\t\tconst bunPath = resolveBunOnPath(env);\n\t\tif (!bunPath) {\n\t\t\tsvc.status = \"stopped\";\n\t\t\tdelete svc.pid;\n\t\t\tschedulePersist();\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tmessage: BUN_NOT_FOUND_MESSAGE\n\t\t\t};\n\t\t}\n\t\tconst log = getLog(app, id, svc.logPath);\n\t\tif (fresh) {\n\t\t\tlog.clear();\n\t\t\tlogGeneration.set(svc.logPath, (logGeneration.get(svc.logPath) ?? 0) + 1);\n\t\t}\n\t\tconst child = spawn(bunPath, [\"bootstrap.js\"], {\n\t\t\tcwd: artifactDir,\n\t\t\tenv,\n\t\t\tstdio: [\n\t\t\t\t\"ignore\",\n\t\t\t\t\"pipe\",\n\t\t\t\t\"pipe\"\n\t\t\t]\n\t\t});\n\t\trt.child = child;\n\t\trt.expectedExit = false;\n\t\trt.startedAt = Date.now();\n\t\tclearStableTimer(rt);\n\t\trt.stableTimer = setTimeout(() => {\n\t\t\trt.consecutiveFastExits = 0;\n\t\t}, STABLE_UPTIME_MS);\n\t\tchild.stdout?.on(\"data\", (chunk) => log.writeRaw(chunk));\n\t\tchild.stderr?.on(\"data\", (chunk) => log.writeRaw(chunk));\n\t\tchild.on(\"exit\", (code) => handleChildExit(app, id, svc, rt, code));\n\t\tsvc.status = \"running\";\n\t\tif (child.pid !== void 0) svc.pid = child.pid;\n\t\tschedulePersist();\n\t\treturn { ok: true };\n\t}\n\tasync function stopService(svc, rt) {\n\t\tclearBackoffTimer(rt);\n\t\tclearStableTimer(rt);\n\t\tawait killChild(rt, TERMINATE_GRACE_MS);\n\t\tsvc.status = \"stopped\";\n\t\tdelete svc.pid;\n\t\tschedulePersist();\n\t}\n\t/**\n\t* The session-resume signal: Alchemy's no-op reconcile never fires a\n\t* deployment PUT, so nothing else restarts a service a previous session\n\t* stopped. Reuses the exact deployment-PUT start rules — same spawn\n\t* path, same supervision reset, and an explicit resume clears `held`\n\t* the same way a deployment PUT does — but from the service's already\n\t* STORED deployment spec, since no new one arrives with a start.\n\t*/\n\tasync function startService(app, id, svc) {\n\t\tif (svc.artifactHash === void 0) return;\n\t\tif (svc.status === \"running\") return;\n\t\tconst rt = getRuntime(app, id);\n\t\tclearBackoffTimer(rt);\n\t\tclearStableTimer(rt);\n\t\trt.consecutiveFastExits = 0;\n\t\tawait spawnService(app, id, svc, rt, true);\n\t}\n\tfunction json(res, status, body) {\n\t\tconst text = JSON.stringify(body);\n\t\tres.writeHead(status, { \"content-type\": \"application/json\" });\n\t\tres.end(text);\n\t}\n\tfunction text(res, status, body) {\n\t\tres.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\tres.end(body);\n\t}\n\tfunction badSegment(res, segment) {\n\t\ttext(res, 400, `invalid path segment \"${segment}\": must match /^[a-z0-9][a-z0-9-]*$/ and be at most 63 characters`);\n\t}\n\tfunction readBody(req) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst chunks = [];\n\t\t\treq.on(\"data\", (chunk) => chunks.push(chunk));\n\t\t\treq.on(\"end\", () => resolve(Buffer.concat(chunks)));\n\t\t\treq.on(\"error\", reject);\n\t\t});\n\t}\n\tfunction serviceView(svc) {\n\t\treturn {\n\t\t\tid: svc.id,\n\t\t\taddress: svc.address,\n\t\t\tport: svc.port,\n\t\t\turl: `http://localhost:${String(svc.port)}`,\n\t\t\tstatus: svc.status,\n\t\t\t...svc.pid !== void 0 ? { pid: svc.pid } : {},\n\t\t\t...svc.lastExitCode !== void 0 ? { lastExitCode: svc.lastExitCode } : {},\n\t\t\t...svc.artifactHash !== void 0 ? { artifactHash: svc.artifactHash } : {},\n\t\t\tlogPath: svc.logPath\n\t\t};\n\t}\n\tfunction envEquals(a, b) {\n\t\tif (!a) return false;\n\t\tconst aKeys = Object.keys(a);\n\t\tconst bKeys = Object.keys(b);\n\t\tif (aKeys.length !== bKeys.length) return false;\n\t\treturn aKeys.every((k) => a[k] === b[k]);\n\t}\n\tasync function handleDeployment(req, res, app, id) {\n\t\tconst raw = await readBody(req);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw.toString(\"utf8\"));\n\t\t} catch {\n\t\t\treturn text(res, 400, \"malformed JSON body\");\n\t\t}\n\t\tif (!isDeploymentBody(parsed)) return text(res, 400, \"malformed deployment body\");\n\t\tconst svc = await getOrCreateService(app, id);\n\t\tconst rt = getRuntime(app, id);\n\t\tconst changed = svc.artifactHash !== parsed.artifactHash || !envEquals(svc.env, parsed.env);\n\t\tif (svc.status === \"running\") {\n\t\t\tif (!changed) {\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait killChild(rt, TERMINATE_GRACE_MS);\n\t\t} else clearBackoffTimer(rt);\n\t\tsvc.address = parsed.address;\n\t\tsvc.port = parsed.port;\n\t\tclearStableTimer(rt);\n\t\trt.consecutiveFastExits = 0;\n\t\tsvc.artifactHash = parsed.artifactHash;\n\t\tsvc.env = parsed.env;\n\t\tsvc.artifactDir = parsed.artifactDir;\n\t\tschedulePersist();\n\t\tconst result = await spawnService(app, id, svc, rt, true);\n\t\tif (!result.ok) return text(res, 500, result.message ?? \"failed to start the service\");\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\t/** Byte offset a follow should start at to show the last `tailLines` complete lines; `<= 0` (or an empty file) starts at the current end, no backlog. */\n\tfunction startOffsetForTail(logPath, tailLines) {\n\t\tlet size = 0;\n\t\ttry {\n\t\t\tsize = fs.statSync(logPath).size;\n\t\t} catch {\n\t\t\treturn 0;\n\t\t}\n\t\tif (tailLines <= 0 || size === 0) return size;\n\t\tconst fd = fs.openSync(logPath, \"r\");\n\t\ttry {\n\t\t\tconst buf = Buffer.alloc(size);\n\t\t\tfs.readSync(fd, buf, 0, size, 0);\n\t\t\tlet seen = 0;\n\t\t\tfor (let i = size - 1; i >= 0; i -= 1) {\n\t\t\t\tif (buf[i] !== 10) continue;\n\t\t\t\tif (i === size - 1) continue;\n\t\t\t\tseen += 1;\n\t\t\t\tif (seen === tailLines) return i + 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t} finally {\n\t\t\tfs.closeSync(fd);\n\t\t}\n\t}\n\tfunction handleFollowLogs(res, logPath, tailLines) {\n\t\tfs.mkdirSync(path.dirname(logPath), { recursive: true });\n\t\tif (!fs.existsSync(logPath)) fs.closeSync(fs.openSync(logPath, \"a\"));\n\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\tlet offset = startOffsetForTail(logPath, tailLines);\n\t\tlet generation = logGeneration.get(logPath) ?? 0;\n\t\tlet stopped = false;\n\t\tlet timer;\n\t\tconst tick = () => {\n\t\t\tif (stopped) return;\n\t\t\tconst currentGeneration = logGeneration.get(logPath) ?? 0;\n\t\t\tif (currentGeneration !== generation) {\n\t\t\t\tgeneration = currentGeneration;\n\t\t\t\toffset = 0;\n\t\t\t}\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = fs.statSync(logPath);\n\t\t\t} catch {\n\t\t\t\tstat = void 0;\n\t\t\t}\n\t\t\tif (stat && stat.size < offset) offset = 0;\n\t\t\tif (stat && stat.size > offset) {\n\t\t\t\tconst fd = fs.openSync(logPath, \"r\");\n\t\t\t\tconst buf = Buffer.alloc(stat.size - offset);\n\t\t\t\tfs.readSync(fd, buf, 0, buf.length, offset);\n\t\t\t\tfs.closeSync(fd);\n\t\t\t\toffset = stat.size;\n\t\t\t\tres.write(buf);\n\t\t\t}\n\t\t\tif (!stopped) timer = setTimeout(tick, LOG_POLL_INTERVAL_MS);\n\t\t};\n\t\ttick();\n\t\tconst stop = () => {\n\t\t\tstopped = true;\n\t\t\tif (timer) clearTimeout(timer);\n\t\t};\n\t\tres.on(\"close\", stop);\n\t}\n\tasync function handleRequest(req, res) {\n\t\tconst url = new URL(req.url ?? \"/\", `http://127.0.0.1:${String(port)}`);\n\t\tconst method = req.method ?? \"GET\";\n\t\tconst segments = url.pathname.split(\"/\").filter((s) => s.length > 0).map((s) => decodeURIComponent(s));\n\t\tif (method === \"GET\" && segments.length === 1 && segments[0] === \"health\") return json(res, 200, { version: ownVersion });\n\t\tif (segments[0] === \"apps\" && segments.length >= 2) {\n\t\t\tconst app = segments[1];\n\t\t\tif (app === void 0 || !isValidSegment(app)) return badSegment(res, app ?? \"\");\n\t\t\tif (method === \"PUT\" && segments.length === 4 && segments[2] === \"services\") {\n\t\t\t\tconst id = segments[3];\n\t\t\t\tif (id === void 0 || !isValidSegment(id)) return badSegment(res, id ?? \"\");\n\t\t\t\tconst svc = await getOrCreateService(app, id);\n\t\t\t\treturn json(res, 200, {\n\t\t\t\t\tport: svc.port,\n\t\t\t\t\turl: `http://localhost:${String(svc.port)}`\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (method === \"PUT\" && segments.length === 5 && segments[2] === \"services\" && segments[4] === \"deployment\") {\n\t\t\t\tconst id = segments[3];\n\t\t\t\tif (id === void 0 || !isValidSegment(id)) return badSegment(res, id ?? \"\");\n\t\t\t\treturn handleDeployment(req, res, app, id);\n\t\t\t}\n\t\t\tif (method === \"GET\" && segments.length === 3 && segments[2] === \"services\") {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\treturn json(res, 200, appRec ? Object.values(appRec.services).map(serviceView) : []);\n\t\t\t}\n\t\t\tif (method === \"GET\" && segments.length === 5 && segments[2] === \"services\" && segments[4] === \"logs\") {\n\t\t\t\tconst id = segments[3];\n\t\t\t\tif (id === void 0 || !isValidSegment(id)) return badSegment(res, id ?? \"\");\n\t\t\t\tconst svc = state[app]?.services[id];\n\t\t\t\tif (!svc) return text(res, 404, `no such service \"${id}\" in app \"${app}\"`);\n\t\t\t\tif (url.searchParams.get(\"follow\") === \"1\") {\n\t\t\t\t\tconst tailParam = url.searchParams.get(\"tail\");\n\t\t\t\t\tconst tailLines = tailParam === null ? 0 : Math.max(0, Number.parseInt(tailParam, 10) || 0);\n\t\t\t\t\thandleFollowLogs(res, svc.logPath, tailLines);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst content = fs.existsSync(svc.logPath) ? fs.readFileSync(svc.logPath) : Buffer.alloc(0);\n\t\t\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\t\t\tres.end(content);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method === \"POST\" && segments.length === 3 && segments[2] === \"stop\") {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\tif (appRec) await Promise.all(Object.entries(appRec.services).map(([id, svc]) => stopService(svc, getRuntime(app, id))));\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method === \"POST\" && segments.length === 3 && segments[2] === \"start\") {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\tif (appRec) await Promise.all(Object.entries(appRec.services).map(([id, svc]) => startService(app, id, svc)));\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method === \"DELETE\" && segments.length === 2) {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\tif (appRec) {\n\t\t\t\t\tawait Promise.all(Object.entries(appRec.services).map(([id, svc]) => stopService(svc, getRuntime(app, id))));\n\t\t\t\t\tfor (const id of Object.keys(appRec.services)) {\n\t\t\t\t\t\tconst key = runtimeKey(app, id);\n\t\t\t\t\t\truntimes.get(key)?.log?.close();\n\t\t\t\t\t\truntimes.delete(key);\n\t\t\t\t\t}\n\t\t\t\t\tdelete state[app];\n\t\t\t\t\tschedulePersist();\n\t\t\t\t}\n\t\t\t\tawait fs.promises.rm(path.join(stateDir, \"logs\", app), {\n\t\t\t\t\trecursive: true,\n\t\t\t\t\tforce: true\n\t\t\t\t});\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tres.writeHead(404);\n\t\tres.end();\n\t}\n\tconst server = http.createServer((req, res) => {\n\t\thandleRequest(req, res).catch((err) => {\n\t\t\tif (!res.headersSent) res.writeHead(500, { \"content-type\": \"text/plain\" });\n\t\t\tres.end(err instanceof Error ? err.message : String(err));\n\t\t});\n\t});\n\tlet shuttingDown = false;\n\tasync function shutdown() {\n\t\tif (shuttingDown) return;\n\t\tshuttingDown = true;\n\t\tconst kills = [];\n\t\tfor (const rt of runtimes.values()) {\n\t\t\tclearBackoffTimer(rt);\n\t\t\tclearStableTimer(rt);\n\t\t\tif (rt.child) kills.push(killChild(rt, TERMINATE_GRACE_MS));\n\t\t}\n\t\tawait Promise.all(kills);\n\t\tawait stateFile.flush();\n\t\tserver.close();\n\t\tprocess.exit(0);\n\t}\n\tprocess.on(\"SIGTERM\", () => void shutdown());\n\tprocess.on(\"SIGINT\", () => void shutdown());\n\treadJsonFile(appsJsonPath, isAppsState).then((loaded) => {\n\t\tif (loaded) {\n\t\t\tfor (const appRec of Object.values(loaded)) for (const svc of Object.values(appRec.services)) if (svc.status === \"running\" || svc.status === \"backoff\") {\n\t\t\t\tsvc.status = \"stopped\";\n\t\t\t\tdelete svc.pid;\n\t\t\t}\n\t\t\tstate = loaded;\n\t\t}\n\t\tserver.listen(port, \"127.0.0.1\", () => {\n\t\t\tconsole.log(`[dev-emulators] compute-main listening on 127.0.0.1:${String(port)}`);\n\t\t});\n\t}).catch((err) => {\n\t\tconsole.error(\"compute-main: failed to load state\", err);\n\t\tprocess.exit(1);\n\t});\n}\nmain();\n//#endregion\nexport {};\n\n//# sourceMappingURL=compute-main.mjs.map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compute-main.mjs","names":["getPort"],"sources":["../../../1-prisma-cloud/0-lowering/dev-emulators/dist/compute-main.mjs"],"sourcesContent":["import { l as readOwnVersion, m as readJsonFile, p as StateFile, t as isValidSegment } from \"./segments-DRPHe3kK.mjs\";\nimport * as fs from \"node:fs\";\nimport { spawn } from \"node:child_process\";\nimport * as path from \"node:path\";\nimport getPort, { clearLockedPorts, portNumbers } from \"get-port\";\nimport * as http from \"node:http\";\n//#region src/compute-main.ts\n/**\n* The Compute emulator daemon (local-dev spec § 2 `compute-main.ts`): a small\n* local counterpart of the platform's compute service. Owns service child\n* processes (spawned `bun bootstrap.js` from a real packaged artifact),\n* supervises them (crash backoff, held after repeated fast crashes), and\n* serves a loopback JSON admin API plus per-service log streaming.\n*\n* Runs as its own OS process, started by `daemon.ts`'s `ensureDaemon` via\n* `process.execPath <this file> --port <n> --state-dir <dir>`. Everything it\n* needs travels on argv and each request's own body — it reads no\n* environment variable of its own.\n*/\nconst MIN_SERVICE_PORT = 3e3;\nconst MAX_SERVICE_PORT = 65535;\nconst TERMINATE_GRACE_MS = 5e3;\nconst STABLE_UPTIME_MS = 3e4;\nconst BASE_BACKOFF_MS = 1e3;\nconst MAX_BACKOFF_MS = 3e4;\nconst MAX_CONSECUTIVE_FAST_EXITS = 5;\nconst LOG_POLL_INTERVAL_MS = 100;\nconst APPS_STATE_MODE = 384;\nconst BUN_NOT_FOUND_MESSAGE = \"local dev runs services under bun — the Prisma Compute runtime — and `bun` was not found on PATH. Install it: https://bun.sh.\";\nfunction isServiceStatus(value) {\n\treturn value === \"running\" || value === \"backoff\" || value === \"held\" || value === \"stopped\";\n}\nfunction isStringRecord(value) {\n\treturn typeof value === \"object\" && value !== null && Object.values(value).every((v) => typeof v === \"string\");\n}\nfunction isServiceRecord(value) {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (!(\"id\" in value) || typeof value.id !== \"string\") return false;\n\tif (!(\"address\" in value) || typeof value.address !== \"string\") return false;\n\tif (!(\"port\" in value) || typeof value.port !== \"number\") return false;\n\tif (!(\"status\" in value) || !isServiceStatus(value.status)) return false;\n\tif (!(\"logPath\" in value) || typeof value.logPath !== \"string\") return false;\n\tif (\"pid\" in value && value.pid !== void 0 && typeof value.pid !== \"number\") return false;\n\tif (\"lastExitCode\" in value && value.lastExitCode !== void 0 && typeof value.lastExitCode !== \"number\") return false;\n\tif (\"artifactHash\" in value && value.artifactHash !== void 0 && typeof value.artifactHash !== \"string\") return false;\n\tif (\"artifactDir\" in value && value.artifactDir !== void 0 && typeof value.artifactDir !== \"string\") return false;\n\tif (\"env\" in value && value.env !== void 0 && !isStringRecord(value.env)) return false;\n\treturn true;\n}\nfunction isAppRecord(value) {\n\treturn typeof value === \"object\" && value !== null && \"services\" in value && typeof value.services === \"object\" && value.services !== null && Object.values(value.services).every(isServiceRecord);\n}\nfunction isAppsState(value) {\n\treturn typeof value === \"object\" && value !== null && Object.values(value).every(isAppRecord);\n}\nfunction isDeploymentBody(value) {\n\treturn typeof value === \"object\" && value !== null && \"address\" in value && typeof value.address === \"string\" && \"artifactDir\" in value && typeof value.artifactDir === \"string\" && \"artifactHash\" in value && typeof value.artifactHash === \"string\" && \"env\" in value && isStringRecord(value.env) && \"port\" in value && typeof value.port === \"number\";\n}\nfunction sleep(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n/** Append-only per-service log file — child stdout/stderr plus `[emulator]` supervision lines. No rotation in v1. */\nvar ServiceLog = class {\n\tfilePath;\n\tfd;\n\tconstructor(filePath) {\n\t\tthis.filePath = filePath;\n\t}\n\tensureOpen() {\n\t\tif (this.fd === void 0) {\n\t\t\tfs.mkdirSync(path.dirname(this.filePath), { recursive: true });\n\t\t\tthis.fd = fs.openSync(this.filePath, \"a\");\n\t\t}\n\t\treturn this.fd;\n\t}\n\twriteRaw(chunk) {\n\t\tfs.writeSync(this.ensureOpen(), chunk);\n\t}\n\twriteLine(line) {\n\t\tfs.writeSync(this.ensureOpen(), `${line}\\n`);\n\t}\n\t/** Empties the file — a fresh service start begins a clean log; past sessions' and past deployments' output is not kept. */\n\tclear() {\n\t\tfs.ftruncateSync(this.ensureOpen(), 0);\n\t}\n\t/** Closes the fd if one was ever opened. Idempotent. */\n\tclose() {\n\t\tif (this.fd === void 0) return;\n\t\tfs.closeSync(this.fd);\n\t\tthis.fd = void 0;\n\t}\n};\nfunction parseArgs(argv) {\n\tlet port;\n\tlet stateDir;\n\tfor (let i = 0; i < argv.length; i++) if (argv[i] === \"--port\") port = Number(argv[i + 1]);\n\telse if (argv[i] === \"--state-dir\") stateDir = argv[i + 1];\n\tif (port === void 0 || Number.isNaN(port)) throw new Error(\"compute-main: --port <n> is required\");\n\tif (stateDir === void 0) throw new Error(\"compute-main: --state-dir <dir> is required\");\n\treturn {\n\t\tport,\n\t\tstateDir\n\t};\n}\n/** Resolves `bun` from THIS request's env PATH — never the daemon's own. POSIX-only (Windows is out of scope). */\nfunction resolveBunOnPath(env) {\n\tconst pathVar = env[\"PATH\"];\n\tif (!pathVar) return void 0;\n\tfor (const dir of pathVar.split(path.delimiter)) {\n\t\tif (dir === \"\") continue;\n\t\tconst candidate = path.join(dir, \"bun\");\n\t\ttry {\n\t\t\tfs.accessSync(candidate, fs.constants.X_OK);\n\t\t\treturn candidate;\n\t\t} catch {}\n\t}\n}\nfunction main() {\n\tconst { port, stateDir } = parseArgs(process.argv.slice(2));\n\tconst ownVersion = readOwnVersion();\n\tconst appsJsonPath = path.join(stateDir, \"apps.json\");\n\tconst stateFile = new StateFile(appsJsonPath, APPS_STATE_MODE);\n\tlet state = {};\n\tconst runtimes = /* @__PURE__ */ new Map();\n\tconst logGeneration = /* @__PURE__ */ new Map();\n\tfunction runtimeKey(app, id) {\n\t\treturn `${app}/${id}`;\n\t}\n\tfunction getRuntime(app, id) {\n\t\tconst key = runtimeKey(app, id);\n\t\tlet rt = runtimes.get(key);\n\t\tif (!rt) {\n\t\t\trt = {\n\t\t\t\tchild: void 0,\n\t\t\t\tconsecutiveFastExits: 0,\n\t\t\t\tstartedAt: void 0,\n\t\t\t\tstableTimer: void 0,\n\t\t\t\tbackoffTimer: void 0,\n\t\t\t\texpectedExit: false,\n\t\t\t\tlog: void 0\n\t\t\t};\n\t\t\truntimes.set(key, rt);\n\t\t}\n\t\treturn rt;\n\t}\n\tfunction serviceLogPath(app, id) {\n\t\treturn path.join(stateDir, \"logs\", app, `${id}.log`);\n\t}\n\tfunction getLog(app, id, logPath) {\n\t\tconst rt = getRuntime(app, id);\n\t\tif (!rt.log) rt.log = new ServiceLog(logPath);\n\t\treturn rt.log;\n\t}\n\tfunction schedulePersist() {\n\t\tstateFile.write(state);\n\t}\n\tfunction clearStableTimer(rt) {\n\t\tif (rt.stableTimer) clearTimeout(rt.stableTimer);\n\t\trt.stableTimer = void 0;\n\t}\n\tfunction clearBackoffTimer(rt) {\n\t\tif (rt.backoffTimer) clearTimeout(rt.backoffTimer);\n\t\trt.backoffTimer = void 0;\n\t}\n\tfunction usedServicePorts() {\n\t\tconst ports = /* @__PURE__ */ new Set();\n\t\tfor (const app of Object.values(state)) for (const svc of Object.values(app.services)) ports.add(svc.port);\n\t\treturn ports;\n\t}\n\t/**\n\t* The smallest genuinely free port at or above `MIN_SERVICE_PORT`,\n\t* excluding this daemon's own persisted allocations — persistence and\n\t* the range policy stay ours; whether a candidate is actually bindable\n\t* is `get-port`'s (spec § 2's dependency razor).\n\t*/\n\tasync function smallestUnusedServicePort() {\n\t\treturn getPort({\n\t\t\tport: portNumbers(MIN_SERVICE_PORT, MAX_SERVICE_PORT),\n\t\t\texclude: usedServicePorts()\n\t\t});\n\t}\n\tasync function getOrCreateService(app, id) {\n\t\tlet appRec = state[app];\n\t\tif (!appRec) {\n\t\t\tappRec = { services: {} };\n\t\t\tstate[app] = appRec;\n\t\t}\n\t\tlet svc = appRec.services[id];\n\t\tif (svc) return svc;\n\t\tsvc = {\n\t\t\tid,\n\t\t\taddress: id,\n\t\t\tport: await smallestUnusedServicePort(),\n\t\t\tstatus: \"stopped\",\n\t\t\tlogPath: serviceLogPath(app, id)\n\t\t};\n\t\tappRec.services[id] = svc;\n\t\tschedulePersist();\n\t\treturn svc;\n\t}\n\tfunction waitForExit(child) {\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once(\"exit\", () => resolve());\n\t\t});\n\t}\n\t/** SIGTERM, wait up to `graceMs`, SIGKILL. Marks the exit as expected so supervision doesn't fire. */\n\tasync function killChild(rt, graceMs) {\n\t\tconst child = rt.child;\n\t\tif (!child || child.pid === void 0) return;\n\t\trt.expectedExit = true;\n\t\tconst exited = waitForExit(child);\n\t\tchild.kill(\"SIGTERM\");\n\t\tconst timedOut = Symbol(\"timeout\");\n\t\tif (await Promise.race([exited.then(() => void 0), sleep(graceMs).then(() => timedOut)]) === timedOut) {\n\t\t\tchild.kill(\"SIGKILL\");\n\t\t\tawait exited;\n\t\t}\n\t}\n\tfunction handleChildExit(app, id, svc, rt, code) {\n\t\tclearStableTimer(rt);\n\t\trt.child = void 0;\n\t\tdelete svc.pid;\n\t\tif (code !== null) svc.lastExitCode = code;\n\t\tif (rt.expectedExit) {\n\t\t\trt.expectedExit = false;\n\t\t\tschedulePersist();\n\t\t\treturn;\n\t\t}\n\t\tconst uptime = rt.startedAt !== void 0 ? Date.now() - rt.startedAt : 0;\n\t\tif (uptime >= STABLE_UPTIME_MS) rt.consecutiveFastExits = 0;\n\t\tconst attemptNumber = rt.consecutiveFastExits;\n\t\tif (uptime < STABLE_UPTIME_MS) rt.consecutiveFastExits += 1;\n\t\tif (rt.consecutiveFastExits >= MAX_CONSECUTIVE_FAST_EXITS) {\n\t\t\tsvc.status = \"held\";\n\t\t\tschedulePersist();\n\t\t\tgetLog(app, id, svc.logPath).writeLine(`[emulator] held after ${String(MAX_CONSECUTIVE_FAST_EXITS)} consecutive fast exits — send a new deployment to resume`);\n\t\t\treturn;\n\t\t}\n\t\tconst delayMs = Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** attemptNumber);\n\t\tsvc.status = \"backoff\";\n\t\tschedulePersist();\n\t\tgetLog(app, id, svc.logPath).writeLine(`[emulator] exited (code ${code === null ? \"null\" : String(code)}) — restarting in ${String(delayMs / 1e3)}s`);\n\t\trt.backoffTimer = setTimeout(() => {\n\t\t\trt.backoffTimer = void 0;\n\t\t\tspawnService(app, id, svc, rt, false);\n\t\t}, delayMs);\n\t}\n\tasync function spawnService(app, id, svc, rt, fresh) {\n\t\tconst env = svc.env ?? {};\n\t\tconst artifactDir = svc.artifactDir ?? \".\";\n\t\tconst bunPath = resolveBunOnPath(env);\n\t\tif (!bunPath) {\n\t\t\tsvc.status = \"stopped\";\n\t\t\tdelete svc.pid;\n\t\t\tschedulePersist();\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tmessage: BUN_NOT_FOUND_MESSAGE\n\t\t\t};\n\t\t}\n\t\tconst log = getLog(app, id, svc.logPath);\n\t\tif (fresh) {\n\t\t\tlog.clear();\n\t\t\tlogGeneration.set(svc.logPath, (logGeneration.get(svc.logPath) ?? 0) + 1);\n\t\t}\n\t\tconst child = spawn(bunPath, [\"bootstrap.js\"], {\n\t\t\tcwd: artifactDir,\n\t\t\tenv,\n\t\t\tstdio: [\n\t\t\t\t\"ignore\",\n\t\t\t\t\"pipe\",\n\t\t\t\t\"pipe\"\n\t\t\t]\n\t\t});\n\t\trt.child = child;\n\t\trt.expectedExit = false;\n\t\trt.startedAt = Date.now();\n\t\tclearStableTimer(rt);\n\t\trt.stableTimer = setTimeout(() => {\n\t\t\trt.consecutiveFastExits = 0;\n\t\t}, STABLE_UPTIME_MS);\n\t\tchild.stdout?.on(\"data\", (chunk) => log.writeRaw(chunk));\n\t\tchild.stderr?.on(\"data\", (chunk) => log.writeRaw(chunk));\n\t\tchild.on(\"exit\", (code) => handleChildExit(app, id, svc, rt, code));\n\t\tsvc.status = \"running\";\n\t\tif (child.pid !== void 0) svc.pid = child.pid;\n\t\tschedulePersist();\n\t\treturn { ok: true };\n\t}\n\tasync function stopService(svc, rt) {\n\t\tclearBackoffTimer(rt);\n\t\tclearStableTimer(rt);\n\t\tawait killChild(rt, TERMINATE_GRACE_MS);\n\t\tsvc.status = \"stopped\";\n\t\tdelete svc.pid;\n\t\tschedulePersist();\n\t}\n\t/**\n\t* The session-resume signal: Alchemy's no-op reconcile never fires a\n\t* deployment PUT, so nothing else restarts a service a previous session\n\t* stopped. Reuses the exact deployment-PUT start rules — same spawn\n\t* path, same supervision reset, and an explicit resume clears `held`\n\t* the same way a deployment PUT does — but from the service's already\n\t* STORED deployment spec, since no new one arrives with a start.\n\t*/\n\tasync function startService(app, id, svc) {\n\t\tif (svc.artifactHash === void 0) return;\n\t\tif (svc.status === \"running\") return;\n\t\tconst rt = getRuntime(app, id);\n\t\tclearBackoffTimer(rt);\n\t\tclearStableTimer(rt);\n\t\trt.consecutiveFastExits = 0;\n\t\tawait spawnService(app, id, svc, rt, true);\n\t}\n\tfunction json(res, status, body) {\n\t\tconst text = JSON.stringify(body);\n\t\tres.writeHead(status, { \"content-type\": \"application/json\" });\n\t\tres.end(text);\n\t}\n\tfunction text(res, status, body) {\n\t\tres.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\tres.end(body);\n\t}\n\tfunction badSegment(res, segment) {\n\t\ttext(res, 400, `invalid path segment \"${segment}\": must match /^[a-z0-9][a-z0-9-]*$/ and be at most 63 characters`);\n\t}\n\tfunction readBody(req) {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst chunks = [];\n\t\t\treq.on(\"data\", (chunk) => chunks.push(chunk));\n\t\t\treq.on(\"end\", () => resolve(Buffer.concat(chunks)));\n\t\t\treq.on(\"error\", reject);\n\t\t});\n\t}\n\tfunction serviceView(svc) {\n\t\treturn {\n\t\t\tid: svc.id,\n\t\t\taddress: svc.address,\n\t\t\tport: svc.port,\n\t\t\turl: `http://localhost:${String(svc.port)}`,\n\t\t\tstatus: svc.status,\n\t\t\t...svc.pid !== void 0 ? { pid: svc.pid } : {},\n\t\t\t...svc.lastExitCode !== void 0 ? { lastExitCode: svc.lastExitCode } : {},\n\t\t\t...svc.artifactHash !== void 0 ? { artifactHash: svc.artifactHash } : {},\n\t\t\tlogPath: svc.logPath\n\t\t};\n\t}\n\tfunction envEquals(a, b) {\n\t\tif (!a) return false;\n\t\tconst aKeys = Object.keys(a);\n\t\tconst bKeys = Object.keys(b);\n\t\tif (aKeys.length !== bKeys.length) return false;\n\t\treturn aKeys.every((k) => a[k] === b[k]);\n\t}\n\tasync function handleDeployment(req, res, app, id) {\n\t\tconst raw = await readBody(req);\n\t\tlet parsed;\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw.toString(\"utf8\"));\n\t\t} catch {\n\t\t\treturn text(res, 400, \"malformed JSON body\");\n\t\t}\n\t\tif (!isDeploymentBody(parsed)) return text(res, 400, \"malformed deployment body\");\n\t\tconst svc = await getOrCreateService(app, id);\n\t\tconst rt = getRuntime(app, id);\n\t\tconst changed = svc.artifactHash !== parsed.artifactHash || !envEquals(svc.env, parsed.env);\n\t\tif (svc.status === \"running\") {\n\t\t\tif (!changed) {\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait killChild(rt, TERMINATE_GRACE_MS);\n\t\t} else clearBackoffTimer(rt);\n\t\tsvc.address = parsed.address;\n\t\tsvc.port = parsed.port;\n\t\tclearStableTimer(rt);\n\t\trt.consecutiveFastExits = 0;\n\t\tsvc.artifactHash = parsed.artifactHash;\n\t\tsvc.env = parsed.env;\n\t\tsvc.artifactDir = parsed.artifactDir;\n\t\tschedulePersist();\n\t\tconst result = await spawnService(app, id, svc, rt, true);\n\t\tif (!result.ok) return text(res, 500, result.message ?? \"failed to start the service\");\n\t\tres.writeHead(204);\n\t\tres.end();\n\t}\n\t/** Byte offset a follow should start at to show the last `tailLines` complete lines; `<= 0` (or an empty file) starts at the current end, no backlog. */\n\tfunction startOffsetForTail(logPath, tailLines) {\n\t\tlet size = 0;\n\t\ttry {\n\t\t\tsize = fs.statSync(logPath).size;\n\t\t} catch {\n\t\t\treturn 0;\n\t\t}\n\t\tif (tailLines <= 0 || size === 0) return size;\n\t\tconst fd = fs.openSync(logPath, \"r\");\n\t\ttry {\n\t\t\tconst buf = Buffer.alloc(size);\n\t\t\tfs.readSync(fd, buf, 0, size, 0);\n\t\t\tlet seen = 0;\n\t\t\tfor (let i = size - 1; i >= 0; i -= 1) {\n\t\t\t\tif (buf[i] !== 10) continue;\n\t\t\t\tif (i === size - 1) continue;\n\t\t\t\tseen += 1;\n\t\t\t\tif (seen === tailLines) return i + 1;\n\t\t\t}\n\t\t\treturn 0;\n\t\t} finally {\n\t\t\tfs.closeSync(fd);\n\t\t}\n\t}\n\tfunction handleFollowLogs(res, logPath, tailLines) {\n\t\tfs.mkdirSync(path.dirname(logPath), { recursive: true });\n\t\tif (!fs.existsSync(logPath)) fs.closeSync(fs.openSync(logPath, \"a\"));\n\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\tlet offset = startOffsetForTail(logPath, tailLines);\n\t\tlet generation = logGeneration.get(logPath) ?? 0;\n\t\tlet stopped = false;\n\t\tlet timer;\n\t\tconst tick = () => {\n\t\t\tif (stopped) return;\n\t\t\tconst currentGeneration = logGeneration.get(logPath) ?? 0;\n\t\t\tif (currentGeneration !== generation) {\n\t\t\t\tgeneration = currentGeneration;\n\t\t\t\toffset = 0;\n\t\t\t}\n\t\t\tlet stat;\n\t\t\ttry {\n\t\t\t\tstat = fs.statSync(logPath);\n\t\t\t} catch {\n\t\t\t\tstat = void 0;\n\t\t\t}\n\t\t\tif (stat && stat.size < offset) offset = 0;\n\t\t\tif (stat && stat.size > offset) {\n\t\t\t\tconst fd = fs.openSync(logPath, \"r\");\n\t\t\t\tconst buf = Buffer.alloc(stat.size - offset);\n\t\t\t\tfs.readSync(fd, buf, 0, buf.length, offset);\n\t\t\t\tfs.closeSync(fd);\n\t\t\t\toffset = stat.size;\n\t\t\t\tres.write(buf);\n\t\t\t}\n\t\t\tif (!stopped) timer = setTimeout(tick, LOG_POLL_INTERVAL_MS);\n\t\t};\n\t\ttick();\n\t\tconst stop = () => {\n\t\t\tstopped = true;\n\t\t\tif (timer) clearTimeout(timer);\n\t\t};\n\t\tres.on(\"close\", stop);\n\t}\n\tasync function handleRequest(req, res) {\n\t\tconst url = new URL(req.url ?? \"/\", `http://127.0.0.1:${String(port)}`);\n\t\tconst method = req.method ?? \"GET\";\n\t\tconst segments = url.pathname.split(\"/\").filter((s) => s.length > 0).map((s) => decodeURIComponent(s));\n\t\tif (method === \"GET\" && segments.length === 1 && segments[0] === \"health\") return json(res, 200, { version: ownVersion });\n\t\tif (segments[0] === \"apps\" && segments.length >= 2) {\n\t\t\tconst app = segments[1];\n\t\t\tif (app === void 0 || !isValidSegment(app)) return badSegment(res, app ?? \"\");\n\t\t\tif (method === \"PUT\" && segments.length === 4 && segments[2] === \"services\") {\n\t\t\t\tconst id = segments[3];\n\t\t\t\tif (id === void 0 || !isValidSegment(id)) return badSegment(res, id ?? \"\");\n\t\t\t\tconst svc = await getOrCreateService(app, id);\n\t\t\t\treturn json(res, 200, {\n\t\t\t\t\tport: svc.port,\n\t\t\t\t\turl: `http://localhost:${String(svc.port)}`\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (method === \"PUT\" && segments.length === 5 && segments[2] === \"services\" && segments[4] === \"deployment\") {\n\t\t\t\tconst id = segments[3];\n\t\t\t\tif (id === void 0 || !isValidSegment(id)) return badSegment(res, id ?? \"\");\n\t\t\t\treturn handleDeployment(req, res, app, id);\n\t\t\t}\n\t\t\tif (method === \"GET\" && segments.length === 3 && segments[2] === \"services\") {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\treturn json(res, 200, appRec ? Object.values(appRec.services).map(serviceView) : []);\n\t\t\t}\n\t\t\tif (method === \"GET\" && segments.length === 5 && segments[2] === \"services\" && segments[4] === \"logs\") {\n\t\t\t\tconst id = segments[3];\n\t\t\t\tif (id === void 0 || !isValidSegment(id)) return badSegment(res, id ?? \"\");\n\t\t\t\tconst svc = state[app]?.services[id];\n\t\t\t\tif (!svc) return text(res, 404, `no such service \"${id}\" in app \"${app}\"`);\n\t\t\t\tif (url.searchParams.get(\"follow\") === \"1\") {\n\t\t\t\t\tconst tailParam = url.searchParams.get(\"tail\");\n\t\t\t\t\tconst tailLines = tailParam === null ? 0 : Math.max(0, Number.parseInt(tailParam, 10) || 0);\n\t\t\t\t\thandleFollowLogs(res, svc.logPath, tailLines);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst content = fs.existsSync(svc.logPath) ? fs.readFileSync(svc.logPath) : Buffer.alloc(0);\n\t\t\t\tres.writeHead(200, { \"content-type\": \"text/plain; charset=utf-8\" });\n\t\t\t\tres.end(content);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method === \"POST\" && segments.length === 3 && segments[2] === \"stop\") {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\tif (appRec) await Promise.all(Object.entries(appRec.services).map(([id, svc]) => stopService(svc, getRuntime(app, id))));\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method === \"POST\" && segments.length === 3 && segments[2] === \"start\") {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\tif (appRec) await Promise.all(Object.entries(appRec.services).map(([id, svc]) => startService(app, id, svc)));\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (method === \"DELETE\" && segments.length === 2) {\n\t\t\t\tconst appRec = state[app];\n\t\t\t\tif (appRec) {\n\t\t\t\t\tawait Promise.all(Object.entries(appRec.services).map(([id, svc]) => stopService(svc, getRuntime(app, id))));\n\t\t\t\t\tfor (const id of Object.keys(appRec.services)) {\n\t\t\t\t\t\tconst key = runtimeKey(app, id);\n\t\t\t\t\t\truntimes.get(key)?.log?.close();\n\t\t\t\t\t\truntimes.delete(key);\n\t\t\t\t\t}\n\t\t\t\t\tdelete state[app];\n\t\t\t\t\tschedulePersist();\n\t\t\t\t\tclearLockedPorts();\n\t\t\t\t}\n\t\t\t\tawait fs.promises.rm(path.join(stateDir, \"logs\", app), {\n\t\t\t\t\trecursive: true,\n\t\t\t\t\tforce: true\n\t\t\t\t});\n\t\t\t\tres.writeHead(204);\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tres.writeHead(404);\n\t\tres.end();\n\t}\n\tconst server = http.createServer((req, res) => {\n\t\thandleRequest(req, res).catch((err) => {\n\t\t\tif (!res.headersSent) res.writeHead(500, { \"content-type\": \"text/plain\" });\n\t\t\tres.end(err instanceof Error ? err.message : String(err));\n\t\t});\n\t});\n\tlet shuttingDown = false;\n\tasync function shutdown() {\n\t\tif (shuttingDown) return;\n\t\tshuttingDown = true;\n\t\tconst kills = [];\n\t\tfor (const rt of runtimes.values()) {\n\t\t\tclearBackoffTimer(rt);\n\t\t\tclearStableTimer(rt);\n\t\t\tif (rt.child) kills.push(killChild(rt, TERMINATE_GRACE_MS));\n\t\t}\n\t\tawait Promise.all(kills);\n\t\tawait stateFile.flush();\n\t\tserver.close();\n\t\tprocess.exit(0);\n\t}\n\tprocess.on(\"SIGTERM\", () => void shutdown());\n\tprocess.on(\"SIGINT\", () => void shutdown());\n\treadJsonFile(appsJsonPath, isAppsState).then((loaded) => {\n\t\tif (loaded) {\n\t\t\tfor (const appRec of Object.values(loaded)) for (const svc of Object.values(appRec.services)) if (svc.status === \"running\" || svc.status === \"backoff\") {\n\t\t\t\tsvc.status = \"stopped\";\n\t\t\t\tdelete svc.pid;\n\t\t\t}\n\t\t\tstate = loaded;\n\t\t}\n\t\tserver.listen(port, \"127.0.0.1\", () => {\n\t\t\tconsole.log(`[dev-emulators] compute-main listening on 127.0.0.1:${String(port)}`);\n\t\t});\n\t}).catch((err) => {\n\t\tconsole.error(\"compute-main: failed to load state\", err);\n\t\tprocess.exit(1);\n\t});\n}\nmain();\n//#endregion\nexport {};\n\n//# sourceMappingURL=compute-main.mjs.map"],"mappings":"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"}
|
package/dist/control.d.mts
CHANGED
|
@@ -10,7 +10,7 @@ import * as Output from "alchemy/Output";
|
|
|
10
10
|
import { Resource } from "alchemy";
|
|
11
11
|
import { Credentials } from "@distilled.cloud/prisma";
|
|
12
12
|
import { EnvironmentVariable } from "alchemy/Prisma";
|
|
13
|
-
import "effect/
|
|
13
|
+
import "effect/http/HttpClient";
|
|
14
14
|
import { ExtensionDescriptor, StateDescriptor } from "@prisma/composer/config";
|
|
15
15
|
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/index.d.mts
|
|
16
16
|
//#endregion
|
package/dist/control.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { c as paramBindingFor, l as paramName } from "./casts-DpaahrlC-Ykus3kCE.
|
|
|
2
2
|
import { a as encode, c as paramEntries, d as serializeInput, n as configKey, o as encodeParamPointer, r as decodeParamPointer, s as isParamPointerRow } from "./serializer-CE3hLPYz-DfUFvkm9.mjs";
|
|
3
3
|
import { a as provisionedEdges, n as SELF_ORIGIN, r as STREAMS_API_KEY, t as RESERVED_PROVIDER_PARAMS } from "./provisioned-edges-CPrUiJ1K--R7PIGoz.mjs";
|
|
4
4
|
import { n as requiredPackHeadOf } from "./required-pack-head-CMMJ2LaU-CfWu5JMj.mjs";
|
|
5
|
-
import { A as
|
|
5
|
+
import { A as call, C as ServiceKey, D as ManagementClient, E as isWithin, F as resolveDefaultBranchId, I as PrismaCredentials, L as fromEnv, M as collectPages, N as drivePagesAsync, O as PrismaApiError, P as layer, R as managementApiBaseUrl, S as providers, T as appAfterEnvironment, _ as resolveTargetRef, a as PRISMA_CLOUD_EXTENSION_ID, d as collectPreflightNames, f as containerDescriptor, g as resolveOrmConfig, h as prismaCloudContainerOf, i as OrmMigrationProvider, j as claimDatabaseUrlKeys, k as RESERVED_DATABASE_URL_KEYS, l as S3Credentials, m as packHeadRefHashes, n as GeneratedParamProvider, o as PgWarm, r as OrmMigration, s as PgWarmProvider, t as GeneratedParam, u as S3CredentialsProvider, v as serviceAppName, w as ServiceKeyProvider, y as targetStorageHash } from "./s3-credentials-resource-BZjtuopJ-V_3xXzMD.mjs";
|
|
6
6
|
import { r as isPostgresResourceNode } from "./orm-postgres-ChW2Ewj7-Dnas0G3L.mjs";
|
|
7
7
|
import { isParamSource } from "@prisma/composer";
|
|
8
8
|
import { blindCast } from "@prisma/composer/casts";
|
|
@@ -21,10 +21,10 @@ import * as zlib from "node:zlib";
|
|
|
21
21
|
import * as Output from "alchemy/Output";
|
|
22
22
|
import { Stack } from "alchemy";
|
|
23
23
|
import * as Prisma$1 from "alchemy/Prisma";
|
|
24
|
-
import * as HttpClientRequest from "effect/
|
|
24
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
25
25
|
import { State, makeHttpStateStore } from "alchemy/State";
|
|
26
|
-
import * as FetchHttpClient from "effect/
|
|
27
|
-
import * as Headers from "effect/
|
|
26
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
27
|
+
import * as Headers from "effect/http/Headers";
|
|
28
28
|
import { execFileSync } from "node:child_process";
|
|
29
29
|
import { readPreflightPayload } from "@prisma/composer/config";
|
|
30
30
|
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/artifact-CoKVIyRH.mjs
|
|
@@ -1185,12 +1185,17 @@ function applicationTopologyApi(options) {
|
|
|
1185
1185
|
const describe = "record this deploy's application topology";
|
|
1186
1186
|
let result;
|
|
1187
1187
|
try {
|
|
1188
|
-
result = await
|
|
1188
|
+
result = await client.PUT("/v1/projects/{projectId}/branches/{branchId}/application-topology", {
|
|
1189
1189
|
params: { path: {
|
|
1190
1190
|
projectId,
|
|
1191
1191
|
branchId
|
|
1192
1192
|
} },
|
|
1193
|
-
body:
|
|
1193
|
+
body: {
|
|
1194
|
+
contentHash: submission.contentHash,
|
|
1195
|
+
nodes: [...submission.nodes],
|
|
1196
|
+
ports: [...submission.ports],
|
|
1197
|
+
edges: [...submission.edges]
|
|
1198
|
+
},
|
|
1194
1199
|
signal: AbortSignal.timeout(REPORT_DEADLINE_MS)
|
|
1195
1200
|
});
|
|
1196
1201
|
} catch (error) {
|
|
@@ -1475,6 +1480,10 @@ function cloudApplicationOf(application) {
|
|
|
1475
1480
|
function projectIdOf(application) {
|
|
1476
1481
|
return cloudApplicationOf(application).projectId;
|
|
1477
1482
|
}
|
|
1483
|
+
/** The `logicalId` prop of a node's App, Database or Bucket: its address on every platform deploy, none in branchless dev (ADR-0051). */
|
|
1484
|
+
function logicalIdProp(application, address) {
|
|
1485
|
+
return cloudApplicationOf(application).branchless ? {} : { logicalId: address };
|
|
1486
|
+
}
|
|
1478
1487
|
/**
|
|
1479
1488
|
* The Branch a database attaches to. Upstream treats an omitted branch as
|
|
1480
1489
|
* desired-unassigned (`branchId` PATCHed back to `null` on reconcile), so a
|
|
@@ -1494,12 +1503,13 @@ function attachmentBranchIdOf(application, id) {
|
|
|
1494
1503
|
* the `name` arm. The returned `url` is direct, not pooled — PgWarm and the
|
|
1495
1504
|
* migration flows need a direct connection.
|
|
1496
1505
|
*/
|
|
1497
|
-
const stageDatabase = ({ id, application, region }) => Effect.gen(function* () {
|
|
1506
|
+
const stageDatabase = ({ id, address, application, region }) => Effect.gen(function* () {
|
|
1498
1507
|
const branchId = attachmentBranchIdOf(application, id);
|
|
1499
1508
|
const db = yield* Prisma$1.Database(`${id}-db`, {
|
|
1500
1509
|
project: projectIdOf(application),
|
|
1501
1510
|
region: region ?? "inherit",
|
|
1502
|
-
...branchId !== void 0 ? { branchId } : { name: id }
|
|
1511
|
+
...branchId !== void 0 ? { branchId } : { name: id },
|
|
1512
|
+
...logicalIdProp(application, address)
|
|
1503
1513
|
});
|
|
1504
1514
|
const conn = yield* Prisma$1.Connection(`${id}-conn`, {
|
|
1505
1515
|
database: db,
|
|
@@ -1521,13 +1531,14 @@ const stageDatabase = ({ id, application, region }) => Effect.gen(function* () {
|
|
|
1521
1531
|
* secretAccessKey) become the four S3Config outputs consumers resolve by name.
|
|
1522
1532
|
*/
|
|
1523
1533
|
function bucketDescriptor(_o) {
|
|
1524
|
-
const lowering = ({ id, application }) => Effect.gen(function* () {
|
|
1534
|
+
const lowering = ({ id, address, application }) => Effect.gen(function* () {
|
|
1525
1535
|
validateName(id, "resource name (from provision id)");
|
|
1526
|
-
const branchId = cloudApplicationOf(application)
|
|
1536
|
+
const { branchId } = cloudApplicationOf(application);
|
|
1527
1537
|
const bkt = yield* Prisma$1.Bucket(`${id}-bucket`, {
|
|
1528
1538
|
project: projectIdOf(application),
|
|
1529
1539
|
name: id,
|
|
1530
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1540
|
+
...branchId !== void 0 ? { branchId } : {},
|
|
1541
|
+
...logicalIdProp(application, address)
|
|
1531
1542
|
});
|
|
1532
1543
|
const key = yield* Prisma$1.BucketAccessKey(`${id}-key`, {
|
|
1533
1544
|
bucket: bkt.bucketId,
|
|
@@ -1583,15 +1594,16 @@ function isComputeProvisioned(value) {
|
|
|
1583
1594
|
function computeDescriptor(o) {
|
|
1584
1595
|
return {
|
|
1585
1596
|
kind: "service",
|
|
1586
|
-
provision: ({ id, application }) => Effect.gen(function* () {
|
|
1597
|
+
provision: ({ id, address, application }) => Effect.gen(function* () {
|
|
1587
1598
|
validateName(id, "service name (from provision id)");
|
|
1588
1599
|
const projectId = projectIdOf(application);
|
|
1589
|
-
const branchId = cloudApplicationOf(application)
|
|
1600
|
+
const { branchId } = cloudApplicationOf(application);
|
|
1590
1601
|
const svc = yield* Prisma$1.App(`${id}-svc`, {
|
|
1591
1602
|
project: projectId,
|
|
1592
|
-
displayName: id,
|
|
1603
|
+
displayName: serviceAppName(id),
|
|
1593
1604
|
...o().region !== void 0 ? { regionId: o().region } : {},
|
|
1594
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1605
|
+
...branchId !== void 0 ? { branchId } : {},
|
|
1606
|
+
...logicalIdProp(application, address)
|
|
1595
1607
|
});
|
|
1596
1608
|
return {
|
|
1597
1609
|
serviceId: svc.appId,
|
|
@@ -1605,6 +1617,7 @@ function computeDescriptor(o) {
|
|
|
1605
1617
|
const cls = branchId ? "preview" : "production";
|
|
1606
1618
|
const branch = branchId !== void 0 ? { branchId } : {};
|
|
1607
1619
|
const projectId = provisioned.projectId;
|
|
1620
|
+
if (node.kind !== "service") throw new Error(`prisma-cloud: cannot serialize non-service node "${address}".`);
|
|
1608
1621
|
const svc = node;
|
|
1609
1622
|
const rows = [];
|
|
1610
1623
|
for (const d of paramEntries(svc)) {
|
|
@@ -1929,10 +1942,11 @@ async function runPackPreflight(graph) {
|
|
|
1929
1942
|
* no-op, a contract or ref-invariant change re-migrates.
|
|
1930
1943
|
*/
|
|
1931
1944
|
function postgresDescriptor(o) {
|
|
1932
|
-
const lowering = ({ id, node, application, graph }) => Effect.gen(function* () {
|
|
1945
|
+
const lowering = ({ id, address, node, application, graph }) => Effect.gen(function* () {
|
|
1933
1946
|
validateName(id, "resource name (from provision id)");
|
|
1934
1947
|
const { db, url } = yield* stageDatabase({
|
|
1935
1948
|
id,
|
|
1949
|
+
address,
|
|
1936
1950
|
application,
|
|
1937
1951
|
region: o().region
|
|
1938
1952
|
});
|
|
@@ -1969,10 +1983,11 @@ function postgresDescriptor(o) {
|
|
|
1969
1983
|
* exactly once.
|
|
1970
1984
|
*/
|
|
1971
1985
|
function rawPostgresDescriptor(o) {
|
|
1972
|
-
const lowering = ({ id, application }) => Effect.gen(function* () {
|
|
1986
|
+
const lowering = ({ id, address, application }) => Effect.gen(function* () {
|
|
1973
1987
|
validateName(id, "resource name (from provision id)");
|
|
1974
1988
|
const { db, url } = yield* stageDatabase({
|
|
1975
1989
|
id,
|
|
1990
|
+
address,
|
|
1976
1991
|
application,
|
|
1977
1992
|
region: o().region
|
|
1978
1993
|
});
|