@geekmidas/cli 10.0.0-alpha.104 → 10.0.0-alpha.106
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/{GoDaddyProvider-dezqtUth.cjs → GoDaddyProvider-BesL1P15.cjs} +2 -2
- package/dist/{GoDaddyProvider-dezqtUth.cjs.map → GoDaddyProvider-BesL1P15.cjs.map} +1 -1
- package/dist/{GoDaddyProvider-CuPEbbjl.mjs → GoDaddyProvider-DufGBcDt.mjs} +2 -2
- package/dist/{GoDaddyProvider-CuPEbbjl.mjs.map → GoDaddyProvider-DufGBcDt.mjs.map} +1 -1
- package/dist/{LegacyStateStore-Bc8FnHEB.mjs → LegacyStateStore-1kOwqcd_.mjs} +3 -3
- package/dist/{LegacyStateStore-Bc8FnHEB.mjs.map → LegacyStateStore-1kOwqcd_.mjs.map} +1 -1
- package/dist/{LegacyStateStore-ecxYpm9-.cjs → LegacyStateStore-aFp6-7im.cjs} +3 -3
- package/dist/{LegacyStateStore-ecxYpm9-.cjs.map → LegacyStateStore-aFp6-7im.cjs.map} +1 -1
- package/dist/{LocalStateStore-wSKMDDh5.mjs → LocalStateStore-DFGsiLDy.mjs} +2 -2
- package/dist/{LocalStateStore-wSKMDDh5.mjs.map → LocalStateStore-DFGsiLDy.mjs.map} +1 -1
- package/dist/{LocalStateStore-Sf4B6kUn.cjs → LocalStateStore-Fo33UPTI.cjs} +2 -2
- package/dist/{LocalStateStore-Sf4B6kUn.cjs.map → LocalStateStore-Fo33UPTI.cjs.map} +1 -1
- package/dist/{S3StateStore-BPlVpTfg.mjs → S3StateStore-BlwEPivO.mjs} +2 -2
- package/dist/{S3StateStore-BPlVpTfg.mjs.map → S3StateStore-BlwEPivO.mjs.map} +1 -1
- package/dist/{S3StateStore-DQYjsYBl.cjs → S3StateStore-ZWXXuNQp.cjs} +2 -2
- package/dist/{S3StateStore-DQYjsYBl.cjs.map → S3StateStore-ZWXXuNQp.cjs.map} +1 -1
- package/dist/{SSMStateStore-P9OMZHkp.cjs → SSMStateStore-D5ej5j5M.cjs} +2 -2
- package/dist/{SSMStateStore-P9OMZHkp.cjs.map → SSMStateStore-D5ej5j5M.cjs.map} +1 -1
- package/dist/{SSMStateStore-De2PY12p.mjs → SSMStateStore-DG9h2iVY.mjs} +2 -2
- package/dist/{SSMStateStore-De2PY12p.mjs.map → SSMStateStore-DG9h2iVY.mjs.map} +1 -1
- package/dist/{add-Dgdsb3ox.mjs → add-1VSxmKnf.mjs} +3 -3
- package/dist/{add-Dgdsb3ox.mjs.map → add-1VSxmKnf.mjs.map} +1 -1
- package/dist/{add-C_lp7-oD.cjs → add-B9IgkvTU.cjs} +3 -3
- package/dist/{add-C_lp7-oD.cjs.map → add-B9IgkvTU.cjs.map} +1 -1
- package/dist/{appPorts-C9z9Pzn9.mjs → appPorts-BoXMwolc.mjs} +32 -6
- package/dist/appPorts-BoXMwolc.mjs.map +1 -0
- package/dist/{appPorts-Cu79hJF6.cjs → appPorts-IW-OZmRi.cjs} +37 -5
- package/dist/appPorts-IW-OZmRi.cjs.map +1 -0
- package/dist/{bundler-DBTA8gXs.cjs → bundler-BBDrSnvE.cjs} +5 -5
- package/dist/{bundler-DBTA8gXs.cjs.map → bundler-BBDrSnvE.cjs.map} +1 -1
- package/dist/{bundler-DVPoeMRa.mjs → bundler-By29I7km.mjs} +5 -5
- package/dist/{bundler-DVPoeMRa.mjs.map → bundler-By29I7km.mjs.map} +1 -1
- package/dist/{cli-D7FyFbeC.cjs → cli-Btfl8J6K.cjs} +2 -2
- package/dist/{cli-D7FyFbeC.cjs.map → cli-Btfl8J6K.cjs.map} +1 -1
- package/dist/{cli-CGXOvWRP.mjs → cli-D-ZAyAub.mjs} +2 -2
- package/dist/{cli-CGXOvWRP.mjs.map → cli-D-ZAyAub.mjs.map} +1 -1
- package/dist/{compose-B8ND6s9C.mjs → compose-C-lnkCAT.mjs} +3 -3
- package/dist/{compose-B8ND6s9C.mjs.map → compose-C-lnkCAT.mjs.map} +1 -1
- package/dist/{compose-qbPKKAMC.cjs → compose-daUOp1bm.cjs} +3 -3
- package/dist/{compose-qbPKKAMC.cjs.map → compose-daUOp1bm.cjs.map} +1 -1
- package/dist/deploy/public.cjs +6 -6
- package/dist/deploy/public.mjs +6 -6
- package/dist/{deploy-yLGEWuam.mjs → deploy-T3TwqzKf.mjs} +5 -5
- package/dist/{deploy-yLGEWuam.mjs.map → deploy-T3TwqzKf.mjs.map} +1 -1
- package/dist/{deploy-Bsxl6nyG.cjs → deploy-V43Rbboj.cjs} +5 -5
- package/dist/{deploy-Bsxl6nyG.cjs.map → deploy-V43Rbboj.cjs.map} +1 -1
- package/dist/{dns-BQrhafpk.mjs → dns-AosA2wwP.mjs} +2 -2
- package/dist/{dns-BQrhafpk.mjs.map → dns-AosA2wwP.mjs.map} +1 -1
- package/dist/{dns-BUUEztBH.cjs → dns-BfNzYlpR.cjs} +2 -2
- package/dist/{dns-BUUEztBH.cjs.map → dns-BfNzYlpR.cjs.map} +1 -1
- package/dist/{dokploy-CCnoXmGV.cjs → dokploy-COnyBUBW.cjs} +2 -2
- package/dist/{dokploy-CCnoXmGV.cjs.map → dokploy-COnyBUBW.cjs.map} +1 -1
- package/dist/{dokploy-BuIvCaE1.mjs → dokploy-CaLl5YmO.mjs} +2 -2
- package/dist/{dokploy-BuIvCaE1.mjs.map → dokploy-CaLl5YmO.mjs.map} +1 -1
- package/dist/{encryption-BFs3ItV9.mjs → encryption-BqSWtrXU.mjs} +2 -2
- package/dist/{encryption-BFs3ItV9.mjs.map → encryption-BqSWtrXU.mjs.map} +1 -1
- package/dist/{encryption-2KOlWvfq.cjs → encryption-CJdgXVFM.cjs} +2 -2
- package/dist/{encryption-2KOlWvfq.cjs.map → encryption-CJdgXVFM.cjs.map} +1 -1
- package/dist/{engine-vvr2EpTb.mjs → engine-BMM2Vy26.mjs} +3 -3
- package/dist/{engine-vvr2EpTb.mjs.map → engine-BMM2Vy26.mjs.map} +1 -1
- package/dist/{engine-Bx_ea2_k.cjs → engine-DjI9DFDW.cjs} +3 -3
- package/dist/{engine-Bx_ea2_k.cjs.map → engine-DjI9DFDW.cjs.map} +1 -1
- package/dist/{github-BM6afosB.cjs → github-MYWre3_E.cjs} +4 -4
- package/dist/{github-BM6afosB.cjs.map → github-MYWre3_E.cjs.map} +1 -1
- package/dist/{github-DuXBKTvr.mjs → github-SViQU_St.mjs} +4 -4
- package/dist/{github-DuXBKTvr.mjs.map → github-SViQU_St.mjs.map} +1 -1
- package/dist/index.cjs +50 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +50 -50
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-CQal4P1q.mjs → migrate-BNyMi8h5.mjs} +2 -2
- package/dist/{migrate-CQal4P1q.mjs.map → migrate-BNyMi8h5.mjs.map} +1 -1
- package/dist/{migrate-DXVzuw-s.cjs → migrate-CNQp-SAH.cjs} +2 -2
- package/dist/{migrate-DXVzuw-s.cjs.map → migrate-CNQp-SAH.cjs.map} +1 -1
- package/dist/{migrate-BQfq48xK.cjs → migrate-DwsOYzmN.cjs} +2 -2
- package/dist/{migrate-BQfq48xK.cjs.map → migrate-DwsOYzmN.cjs.map} +1 -1
- package/dist/{migrate-BlLFYSIx.mjs → migrate-H2vGmQ3l.mjs} +2 -2
- package/dist/{migrate-BlLFYSIx.mjs.map → migrate-H2vGmQ3l.mjs.map} +1 -1
- package/dist/{ready-DU7wvxWk.cjs → ready-BMFjxBYA.cjs} +3 -2
- package/dist/ready-BMFjxBYA.cjs.map +1 -0
- package/dist/{ready-CVNE5Pix.mjs → ready-CIt5SOtg.mjs} +3 -2
- package/dist/ready-CIt5SOtg.mjs.map +1 -0
- package/dist/{resolve-De9vfAnN.mjs → resolve-C2vVcD64.mjs} +3 -3
- package/dist/{resolve-De9vfAnN.mjs.map → resolve-C2vVcD64.mjs.map} +1 -1
- package/dist/{resolve-By_cw893.cjs → resolve-ClAnYHo-.cjs} +3 -3
- package/dist/{resolve-By_cw893.cjs.map → resolve-ClAnYHo-.cjs.map} +1 -1
- package/dist/{rollback-YCj4_q9l.mjs → rollback-BrBL9j9s.mjs} +4 -4
- package/dist/{rollback-YCj4_q9l.mjs.map → rollback-BrBL9j9s.mjs.map} +1 -1
- package/dist/{rollback-dkinZaOv.cjs → rollback-CRVwGkEl.cjs} +4 -4
- package/dist/{rollback-dkinZaOv.cjs.map → rollback-CRVwGkEl.cjs.map} +1 -1
- package/dist/{seeds-DZGuovWF.mjs → seeds-C1v4ZOro.mjs} +42 -12
- package/dist/seeds-C1v4ZOro.mjs.map +1 -0
- package/dist/{seeds-CjBwLvWY.cjs → seeds-RTQPjA4K.cjs} +41 -11
- package/dist/seeds-RTQPjA4K.cjs.map +1 -0
- package/dist/{sniffer-bo0KeZsK.mjs → sniffer-CLJ3cB3b.mjs} +6 -6
- package/dist/{sniffer-bo0KeZsK.mjs.map → sniffer-CLJ3cB3b.mjs.map} +1 -1
- package/dist/{sniffer-t0NsMNNP.cjs → sniffer-Cy1pb4hg.cjs} +6 -6
- package/dist/{sniffer-t0NsMNNP.cjs.map → sniffer-Cy1pb4hg.cjs.map} +1 -1
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.mjs +1 -1
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/package.json +15 -15
- package/dist/appPorts-C9z9Pzn9.mjs.map +0 -1
- package/dist/appPorts-Cu79hJF6.cjs.map +0 -1
- package/dist/ready-CVNE5Pix.mjs.map +0 -1
- package/dist/ready-DU7wvxWk.cjs.map +0 -1
- package/dist/seeds-CjBwLvWY.cjs.map +0 -1
- package/dist/seeds-DZGuovWF.mjs.map +0 -1
|
@@ -34,6 +34,7 @@ var appPorts_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
|
34
34
|
appTag: () => appTag,
|
|
35
35
|
assignAppPorts: () => assignAppPorts,
|
|
36
36
|
describeHolder: () => describeHolder,
|
|
37
|
+
describeMove: () => describeMove,
|
|
37
38
|
holderOf: () => holderOf,
|
|
38
39
|
savedAppPorts: () => savedAppPorts,
|
|
39
40
|
withAppPorts: () => withAppPorts
|
|
@@ -168,6 +169,10 @@ function withAppPorts(workspace, ports) {
|
|
|
168
169
|
apps
|
|
169
170
|
};
|
|
170
171
|
}
|
|
172
|
+
/** Says where an app moved from, to, and why. */
|
|
173
|
+
function describeMove({ app, from, to, holder, sibling }) {
|
|
174
|
+
return `↪️ ${app}: ${from} ${sibling ? `is ${sibling}'s` : `is held by ${describeHolder(holder)}, which is not this workspace's`} — using ${to}`;
|
|
175
|
+
}
|
|
171
176
|
/**
|
|
172
177
|
* Give each named app a local port: the one it had, or its usual one, unless
|
|
173
178
|
* another project holds it — then the next free one, which is kept.
|
|
@@ -186,9 +191,24 @@ async function assignAppPorts(workspace, names, deps) {
|
|
|
186
191
|
const ports = { ...saved };
|
|
187
192
|
const moved = [];
|
|
188
193
|
const running = [];
|
|
194
|
+
const owner = /* @__PURE__ */ new Map();
|
|
195
|
+
for (const [name, port] of Object.entries(saved)) if (!owner.has(port)) owner.set(port, name);
|
|
189
196
|
for (const name of Object.keys(wanted).sort()) {
|
|
190
197
|
const want = wanted[name];
|
|
191
198
|
ports[name] = want;
|
|
199
|
+
const sibling = owner.get(want);
|
|
200
|
+
if (sibling !== void 0 && sibling !== name) {
|
|
201
|
+
const next = await nextFree(want, taken, deps);
|
|
202
|
+
owner.set(next, name);
|
|
203
|
+
ports[name] = next;
|
|
204
|
+
moved.push({
|
|
205
|
+
app: name,
|
|
206
|
+
from: want,
|
|
207
|
+
to: next,
|
|
208
|
+
sibling
|
|
209
|
+
});
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
192
212
|
if (await deps.free(want)) continue;
|
|
193
213
|
const holder = deps.holder(want);
|
|
194
214
|
if (holder?.tag === appTag(workspace.root, name)) {
|
|
@@ -199,15 +219,14 @@ async function assignAppPorts(workspace, names, deps) {
|
|
|
199
219
|
});
|
|
200
220
|
continue;
|
|
201
221
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
taken.add(next);
|
|
222
|
+
const next = await nextFree(want, taken, deps);
|
|
223
|
+
owner.set(next, name);
|
|
205
224
|
ports[name] = next;
|
|
206
225
|
moved.push({
|
|
207
226
|
app: name,
|
|
208
227
|
from: want,
|
|
209
228
|
to: next,
|
|
210
|
-
holder
|
|
229
|
+
...holder ? { holder } : {}
|
|
211
230
|
});
|
|
212
231
|
}
|
|
213
232
|
await saveAppPorts(workspace.root, ports);
|
|
@@ -217,6 +236,13 @@ async function assignAppPorts(workspace, names, deps) {
|
|
|
217
236
|
running
|
|
218
237
|
};
|
|
219
238
|
}
|
|
239
|
+
/** The first port after `from` that no app has and nothing holds — reserved. */
|
|
240
|
+
async function nextFree(from, taken, deps) {
|
|
241
|
+
let next = from + 1;
|
|
242
|
+
while (taken.has(next) || !await deps.free(next)) next += 1;
|
|
243
|
+
taken.add(next);
|
|
244
|
+
return next;
|
|
245
|
+
}
|
|
220
246
|
//#endregion
|
|
221
247
|
Object.defineProperty(exports, "APP_TAG_ENV", {
|
|
222
248
|
enumerable: true,
|
|
@@ -248,6 +274,12 @@ Object.defineProperty(exports, "describeHolder", {
|
|
|
248
274
|
return describeHolder;
|
|
249
275
|
}
|
|
250
276
|
});
|
|
277
|
+
Object.defineProperty(exports, "describeMove", {
|
|
278
|
+
enumerable: true,
|
|
279
|
+
get: function() {
|
|
280
|
+
return describeMove;
|
|
281
|
+
}
|
|
282
|
+
});
|
|
251
283
|
Object.defineProperty(exports, "holderOf", {
|
|
252
284
|
enumerable: true,
|
|
253
285
|
get: function() {
|
|
@@ -261,4 +293,4 @@ Object.defineProperty(exports, "withAppPorts", {
|
|
|
261
293
|
}
|
|
262
294
|
});
|
|
263
295
|
|
|
264
|
-
//# sourceMappingURL=appPorts-
|
|
296
|
+
//# sourceMappingURL=appPorts-IW-OZmRi.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appPorts-IW-OZmRi.cjs","names":["resolve","execFileSync","readFileSync","readFile","join","mkdir","writeFile"],"sources":["../src/dev/appPorts.ts"],"sourcesContent":["/**\n * Which local port each app answers on — and what to do when it is taken.\n *\n * An app's port used to be fixed: 3000, 3001, … and `gkm dev` refused to start\n * if anything held one. That is right when the holder is this same app, left\n * running by a previous `gkm dev` — moving would start a second copy beside it.\n * It is wrong when the holder is another project's dev server, which also\n * defaults to 3000: two projects could not run at once, and nothing about the\n * app needs that port. A browser reaches it through the edge, whose URL carries\n * no app port, and every address a phone or a route uses is derived on each\n * start.\n *\n * So the holder is asked who it is. Every app process gkm starts is tagged with\n * {@link APP_TAG_ENV} — the workspace and the app — and children inherit it, so\n * whatever actually binds the port (`next-server`, a Metro worker, the tsx\n * server) carries it — or, when its own can't be read, one of its parents does.\n * A held port whose holder carries this app's tag is a\n * leftover, and is refused; anything else — untagged, another workspace's,\n * unreadable — is not ours, and the app moves to the next free port.\n *\n * The choice is kept in `.gkm/app-ports.json`, not recomputed: an app that\n * moved stays where it moved, so a bookmark or a phone's saved address does not\n * break the next time the other project happens to be stopped. Local only —\n * `gkm deploy` and `gkm docker` never read it.\n */\n\nimport { execFileSync } from 'node:child_process';\nimport { readFileSync } from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\n\n/** Carried by every app process gkm starts: `<workspace root>#<app>`. */\nexport const APP_TAG_ENV = 'GKM_DEV_APP';\n\nconst APP_PORTS_PATH = '.gkm/app-ports.json';\n\n/** The tag an app's processes carry. The root is encoded, so it has no spaces. */\nexport function appTag(root: string, app: string): string {\n\treturn `${encodeURIComponent(resolve(root))}#${app}`;\n}\n\n/** What listens on a port, and the tag it carries if it can be read. */\nexport interface PortHolder {\n\tpid: number;\n\tcommand?: string;\n\ttag?: string;\n}\n\n/** Says, as `command (pid N)`, what holds a port. */\nexport function describeHolder(holder: PortHolder | undefined): string {\n\tif (!holder) return 'another process';\n\treturn `${holder.command ?? 'a process'} (pid ${holder.pid})`;\n}\n\n/**\n * Who is listening on a port, read the way a person would: `lsof` for the\n * pid, then that process's environment for its tag — `/proc/<pid>/environ` on\n * Linux, `ps eww` elsewhere. Both work for the user's own processes, which is\n * every process gkm starts; one that cannot be read has no tag, so is not ours.\n */\nexport function holderOf(port: number): PortHolder | undefined {\n\tlet out: string;\n\ttry {\n\t\tout = execFileSync(\n\t\t\t'lsof',\n\t\t\t['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-Fpc'],\n\t\t\t{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] },\n\t\t);\n\t} catch {\n\t\treturn undefined;\n\t}\n\n\tconst pid = Number(out.match(/^p(\\d+)/m)?.[1]);\n\tif (!pid) return undefined;\n\tconst command = out.match(/^c(.+)$/m)?.[1];\n\tconst tag = lineageTagOf(pid);\n\n\treturn {\n\t\tpid,\n\t\t...(command ? { command } : {}),\n\t\t...(tag ? { tag } : {}),\n\t};\n}\n\n/** How far up a holder's parents to look before calling it untagged. */\nconst MAX_ANCESTORS = 8;\n\n/**\n * The tag of `pid`, or of its nearest parent that has one.\n *\n * A process can hide the tag it inherited: `next-server` renames itself, which\n * on macOS overwrites the memory `ps eww` reads its environment from, so `ps`\n * shows only its title. Its parent, the `next dev` gkm started, still carries\n * the tag. A child is only ever started by its parent, so a tagged parent makes\n * the holder this app's.\n */\nfunction lineageTagOf(pid: number): string | undefined {\n\tlet current: number | undefined = pid;\n\tfor (let depth = 0; current && current > 1; depth += 1) {\n\t\tconst tag = tagOf(current);\n\t\tif (tag || depth === MAX_ANCESTORS) return tag;\n\t\tcurrent = parentOf(current);\n\t}\n\treturn undefined;\n}\n\nfunction tagOf(pid: number): string | undefined {\n\tconst prefix = `${APP_TAG_ENV}=`;\n\ttry {\n\t\tconst entries =\n\t\t\tprocess.platform === 'linux'\n\t\t\t\t? readFileSync(`/proc/${pid}/environ`, 'utf8').split('\\0')\n\t\t\t\t: execFileSync('ps', ['eww', '-o', 'command=', '-p', String(pid)], {\n\t\t\t\t\t\tencoding: 'utf8',\n\t\t\t\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\t\t\t}).split(/\\s+/);\n\t\treturn entries\n\t\t\t.find((entry) => entry.startsWith(prefix))\n\t\t\t?.slice(prefix.length);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction parentOf(pid: number): number | undefined {\n\ttry {\n\t\tconst ppid = Number(\n\t\t\texecFileSync('ps', ['-o', 'ppid=', '-p', String(pid)], {\n\t\t\t\tencoding: 'utf8',\n\t\t\t\tstdio: ['ignore', 'pipe', 'ignore'],\n\t\t\t}).trim(),\n\t\t);\n\t\treturn ppid > 0 ? ppid : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/** The ports apps were given before, by app name. */\nexport async function savedAppPorts(\n\troot: string,\n): Promise<Record<string, number>> {\n\ttry {\n\t\treturn JSON.parse(await readFile(join(root, APP_PORTS_PATH), 'utf8'));\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nasync function saveAppPorts(\n\troot: string,\n\tports: Record<string, number>,\n): Promise<void> {\n\tawait mkdir(join(root, '.gkm'), { recursive: true });\n\tawait writeFile(\n\t\tjoin(root, APP_PORTS_PATH),\n\t\t`${JSON.stringify(ports, null, 2)}\\n`,\n\t);\n}\n\n/** The workspace, with each app on the port it was given locally. */\nexport function withAppPorts(\n\tworkspace: NormalizedWorkspace,\n\tports: Readonly<Record<string, number>>,\n): NormalizedWorkspace {\n\tconst apps = Object.fromEntries(\n\t\tObject.entries(workspace.apps).map(([name, app]) => [\n\t\t\tname,\n\t\t\tports[name] ? { ...app, port: ports[name] } : app,\n\t\t]),\n\t);\n\treturn { ...workspace, apps };\n}\n\n/** Says where an app moved from, to, and why. */\nexport function describeMove({\n\tapp,\n\tfrom,\n\tto,\n\tholder,\n\tsibling,\n}: AppMoved): string {\n\tconst why = sibling\n\t\t? `is ${sibling}'s`\n\t\t: `is held by ${describeHolder(holder)}, which is not this workspace's`;\n\treturn `↪️ ${app}: ${from} ${why} — using ${to}`;\n}\n\n/** An app this workspace already has running — left by a previous start. */\nexport interface AppRunning {\n\tapp: string;\n\tport: number;\n\tholder: PortHolder;\n}\n\n/** An app that moved, because another project or a sibling has its port. */\nexport interface AppMoved {\n\tapp: string;\n\tfrom: number;\n\tto: number;\n\t/** What holds the port, when another project's process does. */\n\tholder?: PortHolder;\n\t/** The app in this workspace the port is already given to. */\n\tsibling?: string;\n}\n\nexport interface AppPortsDeps {\n\t/** Whether a port can be bound right now. */\n\tfree: (port: number) => Promise<boolean>;\n\t/** Who holds a port. */\n\tholder: (port: number) => PortHolder | undefined;\n}\n\n/**\n * Give each named app a local port: the one it had, or its usual one, unless\n * another project holds it — then the next free one, which is kept.\n *\n * @returns every app's port, the apps that moved, and the apps this workspace\n * already has running (the caller refuses to start those).\n */\nexport async function assignAppPorts(\n\tworkspace: NormalizedWorkspace,\n\tnames: readonly string[],\n\tdeps: AppPortsDeps,\n): Promise<{\n\tports: Record<string, number>;\n\tmoved: AppMoved[];\n\trunning: AppRunning[];\n}> {\n\tconst saved = await savedAppPorts(workspace.root);\n\tconst wanted: Record<string, number> = {};\n\tfor (const name of names) {\n\t\tconst port = saved[name] ?? workspace.apps[name]?.port;\n\t\tif (port) wanted[name] = port;\n\t}\n\n\t// Every app's wanted port is reserved before any moves, so one that moves\n\t// never lands on a sibling's.\n\tconst taken = new Set([...Object.values(saved), ...Object.values(wanted)]);\n\tconst ports: Record<string, number> = { ...saved };\n\tconst moved: AppMoved[] = [];\n\tconst running: AppRunning[] = [];\n\n\t// A saved port is owned: by the app that saved it, or the first in the\n\t// file when a file saved before this rule holds one port twice. An app\n\t// moves off a port a sibling owns. Default ports are numbered across every\n\t// app, so one added later can be given a port a sibling kept from before\n\t// it existed. Two apps *configured* on one port own neither, and are left\n\t// to the conflict check, which refuses them.\n\tconst owner = new Map<number, string>();\n\tfor (const [name, port] of Object.entries(saved)) {\n\t\tif (!owner.has(port)) owner.set(port, name);\n\t}\n\n\t// Sorted, so which app moves first — and where — does not depend on order.\n\tfor (const name of Object.keys(wanted).sort()) {\n\t\tconst want = wanted[name]!;\n\t\tports[name] = want;\n\n\t\tconst sibling = owner.get(want);\n\t\tif (sibling !== undefined && sibling !== name) {\n\t\t\tconst next = await nextFree(want, taken, deps);\n\t\t\towner.set(next, name);\n\t\t\tports[name] = next;\n\t\t\tmoved.push({ app: name, from: want, to: next, sibling });\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (await deps.free(want)) continue;\n\n\t\tconst holder = deps.holder(want);\n\t\tif (holder?.tag === appTag(workspace.root, name)) {\n\t\t\trunning.push({ app: name, port: want, holder });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst next = await nextFree(want, taken, deps);\n\t\towner.set(next, name);\n\t\tports[name] = next;\n\t\tmoved.push({\n\t\t\tapp: name,\n\t\t\tfrom: want,\n\t\t\tto: next,\n\t\t\t...(holder ? { holder } : {}),\n\t\t});\n\t}\n\n\tawait saveAppPorts(workspace.root, ports);\n\treturn { ports, moved, running };\n}\n\n/** The first port after `from` that no app has and nothing holds — reserved. */\nasync function nextFree(\n\tfrom: number,\n\ttaken: Set<number>,\n\tdeps: AppPortsDeps,\n): Promise<number> {\n\tlet next = from + 1;\n\twhile (taken.has(next) || !(await deps.free(next))) next += 1;\n\ttaken.add(next);\n\treturn next;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,cAAc;AAE3B,MAAM,iBAAiB;;AAGvB,SAAgB,OAAO,MAAc,KAAqB;CACzD,OAAO,GAAG,oBAAA,GAAmBA,UAAAA,QAAAA,CAAQ,IAAI,CAAC,EAAE,GAAG;AAChD;;AAUA,SAAgB,eAAe,QAAwC;CACtE,IAAI,CAAC,QAAQ,OAAO;CACpB,OAAO,GAAG,OAAO,WAAW,YAAY,QAAQ,OAAO,IAAI;AAC5D;;;;;;;AAQA,SAAgB,SAAS,MAAsC;CAC9D,IAAI;CACJ,IAAI;EACH,OAAA,GAAMC,mBAAAA,aAAAA,CACL,QACA;GAAC;GAAO,SAAS;GAAQ;GAAgB;EAAM,GAC/C;GAAE,UAAU;GAAQ,OAAO;IAAC;IAAU;IAAQ;GAAQ;EAAE,CACzD;CACD,QAAQ;EACP;CACD;CAEA,MAAM,MAAM,OAAO,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE;CAC7C,IAAI,CAAC,KAAK,OAAO,KAAA;CACjB,MAAM,UAAU,IAAI,MAAM,UAAU,CAAC,GAAG;CACxC,MAAM,MAAM,aAAa,GAAG;CAE5B,OAAO;EACN;EACA,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;EAC7B,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;CACtB;AACD;;AAGA,MAAM,gBAAgB;;;;;;;;;;AAWtB,SAAS,aAAa,KAAiC;CACtD,IAAI,UAA8B;CAClC,KAAK,IAAI,QAAQ,GAAG,WAAW,UAAU,GAAG,SAAS,GAAG;EACvD,MAAM,MAAM,MAAM,OAAO;EACzB,IAAI,OAAO,UAAU,eAAe,OAAO;EAC3C,UAAU,SAAS,OAAO;CAC3B;AAED;AAEA,SAAS,MAAM,KAAiC;CAC/C,MAAM,SAAS,GAAG,YAAY;CAC9B,IAAI;EAQH,QANC,QAAQ,aAAa,WAAA,GAClBC,QAAAA,aAAAA,CAAa,SAAS,IAAI,WAAW,MAAM,CAAC,CAAC,MAAM,IAAI,KAAA,GACvDD,mBAAAA,aAAAA,CAAa,MAAM;GAAC;GAAO;GAAM;GAAY;GAAM,OAAO,GAAG;EAAC,GAAG;GACjE,UAAU;GACV,OAAO;IAAC;IAAU;IAAQ;GAAQ;EACnC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAA,CAEf,MAAM,UAAU,MAAM,WAAW,MAAM,CAAC,CAAC,EACxC,MAAM,OAAO,MAAM;CACvB,QAAQ;EACP;CACD;AACD;AAEA,SAAS,SAAS,KAAiC;CAClD,IAAI;EACH,MAAM,OAAO,QAAA,GACZA,mBAAAA,aAAAA,CAAa,MAAM;GAAC;GAAM;GAAS;GAAM,OAAO,GAAG;EAAC,GAAG;GACtD,UAAU;GACV,OAAO;IAAC;IAAU;IAAQ;GAAQ;EACnC,CAAC,CAAC,CAAC,KAAK,CACT;EACA,OAAO,OAAO,IAAI,OAAO,KAAA;CAC1B,QAAQ;EACP;CACD;AACD;;AAGA,eAAsB,cACrB,MACkC;CAClC,IAAI;EACH,OAAO,KAAK,MAAM,OAAA,GAAME,iBAAAA,SAAAA,EAAAA,GAASC,UAAAA,KAAAA,CAAK,MAAM,cAAc,GAAG,MAAM,CAAC;CACrE,QAAQ;EACP,OAAO,CAAC;CACT;AACD;AAEA,eAAe,aACd,MACA,OACgB;CAChB,OAAA,GAAMC,iBAAAA,MAAAA,EAAAA,GAAMD,UAAAA,KAAAA,CAAK,MAAM,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;CACnD,OAAA,GAAME,iBAAAA,UAAAA,EAAAA,GACLF,UAAAA,KAAAA,CAAK,MAAM,cAAc,GACzB,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,GACnC;AACD;;AAGA,SAAgB,aACf,WACA,OACsB;CACtB,MAAM,OAAO,OAAO,YACnB,OAAO,QAAQ,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,SAAS,CACnD,MACA,MAAM,QAAQ;EAAE,GAAG;EAAK,MAAM,MAAM;CAAM,IAAI,GAC/C,CAAC,CACF;CACA,OAAO;EAAE,GAAG;EAAW;CAAK;AAC7B;;AAGA,SAAgB,aAAa,EAC5B,KACA,MACA,IACA,QACA,WACoB;CAIpB,OAAO,OAAO,IAAI,IAAI,KAAK,GAHf,UACT,MAAM,QAAQ,MACd,cAAc,eAAe,MAAM,EAAE,iCACN,WAAW;AAC9C;;;;;;;;AAkCA,eAAsB,eACrB,WACA,OACA,MAKE;CACF,MAAM,QAAQ,MAAM,cAAc,UAAU,IAAI;CAChD,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,QAAQ,OAAO;EACzB,MAAM,OAAO,MAAM,SAAS,UAAU,KAAK,KAAK,EAAE;EAClD,IAAI,MAAM,OAAO,QAAQ;CAC1B;CAIA,MAAM,wBAAQ,IAAI,IAAI,CAAC,GAAG,OAAO,OAAO,KAAK,GAAG,GAAG,OAAO,OAAO,MAAM,CAAC,CAAC;CACzE,MAAM,QAAgC,EAAE,GAAG,MAAM;CACjD,MAAM,QAAoB,CAAC;CAC3B,MAAM,UAAwB,CAAC;CAQ/B,MAAM,wBAAQ,IAAI,IAAoB;CACtC,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,KAAK,GAC9C,IAAI,CAAC,MAAM,IAAI,IAAI,GAAG,MAAM,IAAI,MAAM,IAAI;CAI3C,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,CAAC,CAAC,KAAK,GAAG;EAC9C,MAAM,OAAO,OAAO;EACpB,MAAM,QAAQ;EAEd,MAAM,UAAU,MAAM,IAAI,IAAI;EAC9B,IAAI,YAAY,KAAA,KAAa,YAAY,MAAM;GAC9C,MAAM,OAAO,MAAM,SAAS,MAAM,OAAO,IAAI;GAC7C,MAAM,IAAI,MAAM,IAAI;GACpB,MAAM,QAAQ;GACd,MAAM,KAAK;IAAE,KAAK;IAAM,MAAM;IAAM,IAAI;IAAM;GAAQ,CAAC;GACvD;EACD;EAEA,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG;EAE3B,MAAM,SAAS,KAAK,OAAO,IAAI;EAC/B,IAAI,QAAQ,QAAQ,OAAO,UAAU,MAAM,IAAI,GAAG;GACjD,QAAQ,KAAK;IAAE,KAAK;IAAM,MAAM;IAAM;GAAO,CAAC;GAC9C;EACD;EAEA,MAAM,OAAO,MAAM,SAAS,MAAM,OAAO,IAAI;EAC7C,MAAM,IAAI,MAAM,IAAI;EACpB,MAAM,QAAQ;EACd,MAAM,KAAK;GACV,KAAK;GACL,MAAM;GACN,IAAI;GACJ,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC5B,CAAC;CACF;CAEA,MAAM,aAAa,UAAU,MAAM,KAAK;CACxC,OAAO;EAAE;EAAO;EAAO;CAAQ;AAChC;;AAGA,eAAe,SACd,MACA,OACA,MACkB;CAClB,IAAI,OAAO,OAAO;CAClB,OAAO,MAAM,IAAI,IAAI,KAAK,CAAE,MAAM,KAAK,KAAK,IAAI,GAAI,QAAQ;CAC5D,MAAM,IAAI,IAAI;CACd,OAAO;AACR"}
|
|
@@ -82,10 +82,10 @@ async function bundleServer(options) {
|
|
|
82
82
|
for (const ext of external) args.push(`--external:${ext}`);
|
|
83
83
|
let masterKey;
|
|
84
84
|
if (stage) {
|
|
85
|
-
const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await Promise.resolve().then(() => require("./seeds-
|
|
86
|
-
const { FileSecretsStore, secretsStoreFor } = await Promise.resolve().then(() => require("./seeds-
|
|
85
|
+
const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await Promise.resolve().then(() => require("./seeds-RTQPjA4K.cjs")).then((n) => n.storage_exports);
|
|
86
|
+
const { FileSecretsStore, secretsStoreFor } = await Promise.resolve().then(() => require("./seeds-RTQPjA4K.cjs")).then((n) => n.store_exports);
|
|
87
87
|
const { ConfigNotFound, loadWorkspaceSettings } = await Promise.resolve().then(() => require("./config.cjs"));
|
|
88
|
-
const { encryptSecrets, generateDefineOptions } = await Promise.resolve().then(() => require("./sniffer-
|
|
88
|
+
const { encryptSecrets, generateDefineOptions } = await Promise.resolve().then(() => require("./sniffer-Cy1pb4hg.cjs")).then((n) => n.encryption_exports);
|
|
89
89
|
const store = await loadWorkspaceSettings().then((workspace) => secretsStoreFor(workspace, stage), (error) => {
|
|
90
90
|
if (error instanceof ConfigNotFound) return new FileSecretsStore(process.cwd());
|
|
91
91
|
throw error;
|
|
@@ -133,7 +133,7 @@ async function bundleServer(options) {
|
|
|
133
133
|
const encryptedPath = (0, node_path.join)(gkmDir, "credentials.enc");
|
|
134
134
|
const ivPath = (0, node_path.join)(gkmDir, "credentials.iv");
|
|
135
135
|
if ((0, node_fs.existsSync)(encryptedPath) && (0, node_fs.existsSync)(ivPath)) {
|
|
136
|
-
const { generateDefineOptions } = await Promise.resolve().then(() => require("./sniffer-
|
|
136
|
+
const { generateDefineOptions } = await Promise.resolve().then(() => require("./sniffer-Cy1pb4hg.cjs")).then((n) => n.encryption_exports);
|
|
137
137
|
const defines = generateDefineOptions({
|
|
138
138
|
encrypted: (0, node_fs.readFileSync)(encryptedPath, "utf-8").trim(),
|
|
139
139
|
iv: (0, node_fs.readFileSync)(ivPath, "utf-8").trim(),
|
|
@@ -166,4 +166,4 @@ async function bundleServer(options) {
|
|
|
166
166
|
//#endregion
|
|
167
167
|
exports.bundleServer = bundleServer;
|
|
168
168
|
|
|
169
|
-
//# sourceMappingURL=bundler-
|
|
169
|
+
//# sourceMappingURL=bundler-BBDrSnvE.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundler-DBTA8gXs.cjs","names":["require","createRequire","join","dirname","mkdir","existsSync","readFileSync","spawnSync","writeFile"],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundler-BBDrSnvE.cjs","names":["require","createRequire","join","dirname","mkdir","existsSync","readFileSync","spawnSync","writeFile"],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAM,wBACL;;;;;;;;;;;;;AAwCD,SAAS,gBAAwB;CAChC,MAAMA,aAAAA,GAAUC,YAAAA,cAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,IAA6B;CAE7C,IAAI;EAGH,MAAM,MAAMD,UAAQ,QAAQ,sBAAsB;EAClD,QAAA,GAAOE,UAAAA,KAAAA,EAAAA,GAAKC,UAAAA,QAAAA,CAAQ,GAAG,GAAG,OAAO,SAAS;CAC3C,QAAQ;EAGP,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;AAqBA,eAAe,uBACd,YACoB;CAIpB,MAAM,2BAAW,IAAI,IAAY;CAEjC,KAAK,MAAM,aAAa,YACvB,KAAK,MAAM,QAAQ,MAAM,UAAU,eAAe,EAAE,cAAc,KAAK,CAAC,GACvE,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG,SAAS,IAAI,IAAI;CAI5C,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,KAAK;AAClC;;;;;;;;AAUA,eAAsB,aACrB,SACwB;CACxB,MAAM,EACL,YACA,WACA,QACA,WACA,UACA,OACA,eACG;CAGJ,OAAA,GAAMC,iBAAAA,MAAAA,CAAM,WAAW,EAAE,WAAW,KAAK,CAAC;CAE1C,MAAM,aAAA,GAAYF,UAAAA,KAAAA,CAAK,WAAW,QAAQ,WAAW,YAAY;CAGjE,MAAM,OAAO;EACZ,cAAc;EACd;EACA;EACA;EACA;EACA;EACA,aAAa;EACb;EACA,eAAe;CAChB;CAEA,IAAI,QAGH,KAAK,KAAK,YAAY,cAAc;CAGrC,IAAI,WACH,KAAK,KAAK,aAAa;CAIxB,KAAK,MAAM,OAAO,UACjB,KAAK,KAAK,cAAc,KAAK;CAI9B,IAAI;CAEJ,IAAI,OAAO;EACV,MAAM,EACL,qBACA,8BACA,qBACG,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,sBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,eAAA;EACV,MAAM,EAAE,kBAAkB,oBAAoB,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,sBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,aAAA;EAGpD,MAAM,EAAE,gBAAgB,0BAA0B,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,cAAA,CAAA;EACxD,MAAM,EAAE,gBAAgB,0BAA0B,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,wBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,kBAAA;EAOxD,MAAM,QAAQ,MAAM,sBAAsB,CAAC,CAAC,MAC1C,cAAc,gBAAgB,WAAW,KAAK,IAC9C,UAAU;GACV,IAAI,iBAAiB,gBACpB,OAAO,IAAI,iBAAiB,QAAQ,IAAI,CAAC;GAE1C,MAAM;EACP,CACD;EACA,IAAI,UAAU,MAAM,MAAM,KAAK,KAAK;EAEpC,IAAI,CAAC,SAAS;GAEb,QAAQ,IAAI,qCAAqC,MAAM,KAAK;GAC5D,UAAU,iBAAiB,KAAK;GAChC,MAAM,MAAM,MAAM,OAAO,OAAO;GAChC,QAAQ,IAAI,oBAAoB,MAAM,aAAa,MAAM,KAAK,EAAE;EACjE;EAGA,IAAI,cAAc,WAAW,SAAS,GAAG;GACxC,QAAQ,IAAI,kDAAkD;GAC9D,MAAM,eAAe,MAAM,uBAAuB,UAAU;GAE5D,IAAI,aAAa,SAAS,GAAG;IAC5B,MAAM,aAAa,6BAA6B,cAAc,OAAO;IAErE,IAAI,CAAC,WAAW,OAAO;KACtB,MAAM,eAAe;MACpB,4CAA4C,MAAM;MAClD;MACA,GAAG,WAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;MAC3C;MACA;MACA,0CAA0C,MAAM;MAChD,8CAA8C;MAC9C;MACA;MACA,gDAAgD;MAChD;MACA;MACA,GAAG,WAAW,SAAS,KAAK,MAC3B,WAAW,QAAQ,SAAS,CAAC,IAAI,OAAO,MAAM,OAAO,GACtD;KACD,CAAC,CAAC,KAAK,IAAI;KAEX,MAAM,IAAI,MAAM,YAAY;IAC7B;IAEA,QAAQ,IACP,WAAW,aAAa,OAAO,sCAChC;GACD;EACD;EAIA,MAAM,YAAY,eADC,oBAAoB,OACG,CAAC;EAC3C,YAAY,UAAU;EAGtB,MAAM,UAAU,sBAAsB,SAAS;EAC/C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAGhD,KAAK,KAAK,YAAY,IAAI,GAAG,OAAO;EAGrC,QAAQ,IAAI,kCAAkC,MAAM,EAAE;CACvD,OAAO;EAIN,MAAM,UAAA,GAASA,UAAAA,KAAAA,CAAK,WAAW,MAAM,IAAI;EACzC,MAAM,iBAAA,GAAgBA,UAAAA,KAAAA,CAAK,QAAQ,iBAAiB;EACpD,MAAM,UAAA,GAASA,UAAAA,KAAAA,CAAK,QAAQ,gBAAgB;EAC5C,KAAA,GAAIG,QAAAA,WAAAA,CAAW,aAAa,MAAA,GAAKA,QAAAA,WAAAA,CAAW,MAAM,GAAG;GACpD,MAAM,EAAE,0BAA0B,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,wBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,kBAAA;GACxC,MAAM,UAAU,sBAAsB;IACrC,YAAA,GAAWC,QAAAA,aAAAA,CAAa,eAAe,OAAO,CAAC,CAAC,KAAK;IACrD,KAAA,GAAIA,QAAAA,aAAAA,CAAa,QAAQ,OAAO,CAAC,CAAC,KAAK;IACvC,WAAW;GACZ,CAAC;GACD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAChD,KAAK,KAAK,YAAY,IAAI,GAAG,OAAO;GAErC,QAAQ,IAAI,0DAA0D;EACvE;CACD;CAEA,IAAI;EAEH,MAAM,CAAC,KAAK,GAAG,WAAW;EAC1B,MAAM,UAAA,GAASC,mBAAAA,UAAAA,CAAU,KAAK,SAAS;GACtC,KAAK,QAAQ,IAAI;GACjB,OAAO;GACP,OAAO,QAAQ,aAAa;EAC7B,CAAC;EAED,IAAI,OAAO,OACV,MAAM,OAAO;EAEd,IAAI,OAAO,WAAW,GACrB,MAAM,IAAI,MAAM,4BAA4B,OAAO,QAAQ;EAI5D,MAAM,EAAE,aAAa,MAAM,OAAO;EAClC,MAAM,UAAU,MAAM,SAAS,WAAW,OAAO;EACjD,IAAI,CAAC,QAAQ,WAAW,IAAI,GAC3B,OAAA,GAAMC,iBAAAA,UAAAA,CAAU,WAAW,wBAAwB,SAAS;CAE9D,SAAS,OAAO;EACf,MAAM,IAAI,MACT,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,iBACtE;CACD;CAEA,OAAO;EACN,YAAY;EACZ;CACD;AACD"}
|
|
@@ -82,10 +82,10 @@ async function bundleServer(options) {
|
|
|
82
82
|
for (const ext of external) args.push(`--external:${ext}`);
|
|
83
83
|
let masterKey;
|
|
84
84
|
if (stage) {
|
|
85
|
-
const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await import("./seeds-
|
|
86
|
-
const { FileSecretsStore, secretsStoreFor } = await import("./seeds-
|
|
85
|
+
const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await import("./seeds-C1v4ZOro.mjs").then((n) => n.Vt);
|
|
86
|
+
const { FileSecretsStore, secretsStoreFor } = await import("./seeds-C1v4ZOro.mjs").then((n) => n.Rt);
|
|
87
87
|
const { ConfigNotFound, loadWorkspaceSettings } = await import("./config.mjs");
|
|
88
|
-
const { encryptSecrets, generateDefineOptions } = await import("./sniffer-
|
|
88
|
+
const { encryptSecrets, generateDefineOptions } = await import("./sniffer-CLJ3cB3b.mjs").then((n) => n.O);
|
|
89
89
|
const store = await loadWorkspaceSettings().then((workspace) => secretsStoreFor(workspace, stage), (error) => {
|
|
90
90
|
if (error instanceof ConfigNotFound) return new FileSecretsStore(process.cwd());
|
|
91
91
|
throw error;
|
|
@@ -133,7 +133,7 @@ async function bundleServer(options) {
|
|
|
133
133
|
const encryptedPath = join(gkmDir, "credentials.enc");
|
|
134
134
|
const ivPath = join(gkmDir, "credentials.iv");
|
|
135
135
|
if (existsSync(encryptedPath) && existsSync(ivPath)) {
|
|
136
|
-
const { generateDefineOptions } = await import("./sniffer-
|
|
136
|
+
const { generateDefineOptions } = await import("./sniffer-CLJ3cB3b.mjs").then((n) => n.O);
|
|
137
137
|
const defines = generateDefineOptions({
|
|
138
138
|
encrypted: readFileSync(encryptedPath, "utf-8").trim(),
|
|
139
139
|
iv: readFileSync(ivPath, "utf-8").trim(),
|
|
@@ -166,4 +166,4 @@ async function bundleServer(options) {
|
|
|
166
166
|
//#endregion
|
|
167
167
|
export { bundleServer };
|
|
168
168
|
|
|
169
|
-
//# sourceMappingURL=bundler-
|
|
169
|
+
//# sourceMappingURL=bundler-By29I7km.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundler-DVPoeMRa.mjs","names":[],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bundler-By29I7km.mjs","names":[],"sources":["../src/build/bundler.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport type { Construct } from '@geekmidas/constructs';\n\n/**\n * Banner to inject into ESM bundle for CJS compatibility.\n * Creates a `require` function using Node's createRequire for packages\n * that internally use CommonJS require() for Node builtins.\n */\nconst ESM_CJS_COMPAT_BANNER =\n\t'import { createRequire } from \"module\"; const require = createRequire(import.meta.url);';\n\nexport interface BundleOptions {\n\t/** Entry point file (e.g., .gkm/server/server.ts) */\n\tentryPoint: string;\n\t/** Output directory for bundled files */\n\toutputDir: string;\n\t/** The bundle's file name in `outputDir`. Defaults to `server.mjs`. */\n\toutfile?: string;\n\t/** Minify the output (default: true) */\n\tminify: boolean;\n\t/** Generate sourcemaps (default: false) */\n\tsourcemap: boolean;\n\t/** Packages to exclude from bundling */\n\texternal: string[];\n\t/** Stage for secrets injection (optional) */\n\tstage?: string;\n\t/** Constructs to validate environment variables for */\n\tconstructs?: Construct[];\n}\n\nexport interface BundleResult {\n\t/** Path to the bundled output */\n\toutputPath: string;\n\t/** Ephemeral master key for deployment (only if stage was provided) */\n\tmasterKey?: string;\n}\n\n/**\n * The esbuild binary, resolved from this package rather than from PATH.\n *\n * It used to be `npx esbuild`, which is two assumptions: that esbuild is\n * installed somewhere npx can find, and that the *app's* directory is where to\n * look. Neither holds — the CLI did not depend on esbuild at all, so a deploy\n * run from an app that had not installed it failed at the bundle step with\n * `sh: esbuild: command not found`, after provisioning had already happened.\n *\n * The same fix `bin/gkm.mjs` makes for tsx: resolve from this package's own\n * `node_modules`, so the tool the CLI shells out to is the one it depends on.\n */\nfunction esbuildBinary(): string {\n\tconst require = createRequire(import.meta.url);\n\n\ttry {\n\t\t// The package root, then its bin — `require.resolve('esbuild')` gives the\n\t\t// JS entry point, which is a library rather than the CLI.\n\t\tconst pkg = require.resolve('esbuild/package.json');\n\t\treturn join(dirname(pkg), 'bin', 'esbuild');\n\t} catch {\n\t\t// Better a PATH lookup than a hard failure: a project that installed\n\t\t// esbuild itself still works.\n\t\treturn 'esbuild';\n\t}\n}\n\n/**\n * Collect the environment variables a build cannot proceed without.\n *\n * Uses the SnifferEnvironmentParser to detect which env vars each service\n * reads, and keeps only the ones it cannot do without. `markOptional` is what\n * separates them: the sniffer already knows which reads went through\n * `.optional()` or `.default()`, and asking for that distinction is the\n * difference between a build that stops and one that proceeds correctly.\n *\n * Without it, a key that is *absent by design* failed the build. A surface\n * publishes `AUTH_COOKIE_DOMAIN` only when there is a domain to widen a cookie\n * to — one host has nothing to share it with, so the derivation correctly\n * yields nothing, and Better Auth reads it as optional for exactly that\n * reason. Treating every sniffed read as required made the honest answer\n * indistinguishable from a missing secret.\n *\n * @param constructs - Array of constructs to analyze\n * @returns Deduplicated, sorted names of the required variables\n */\nasync function collectRequiredEnvVars(\n\tconstructs: Construct[],\n): Promise<string[]> {\n\t// A key read optionally by one construct and required by another stays\n\t// required: the strictest read is the one that fails at runtime, and taking\n\t// the union of the required reads is what says so.\n\tconst required = new Set<string>();\n\n\tfor (const construct of constructs) {\n\t\tfor (const name of await construct.getEnvironment({ markOptional: true })) {\n\t\t\tif (!name.endsWith('?')) required.add(name);\n\t\t}\n\t}\n\n\treturn Array.from(required).sort();\n}\n\n/**\n * Bundle the server application using esbuild.\n * Creates a fully standalone bundle with all dependencies included.\n *\n * @param options - Bundle configuration options\n * @returns Bundle result with output path and optional master key\n */\n\nexport async function bundleServer(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tentryPoint,\n\t\toutputDir,\n\t\tminify,\n\t\tsourcemap,\n\t\texternal,\n\t\tstage,\n\t\tconstructs,\n\t} = options;\n\n\t// Ensure output directory exists\n\tawait mkdir(outputDir, { recursive: true });\n\n\tconst mjsOutput = join(outputDir, options.outfile ?? 'server.mjs');\n\n\t// Build command-line arguments for esbuild\n\tconst args = [\n\t\tesbuildBinary(),\n\t\tentryPoint,\n\t\t'--bundle',\n\t\t'--platform=node',\n\t\t'--target=node22',\n\t\t'--format=esm',\n\t\t`--outfile=${mjsOutput}`,\n\t\t'--packages=bundle', // Bundle all dependencies for standalone output\n\t\t`--banner:js=${ESM_CJS_COMPAT_BANNER}`, // CJS compatibility for packages like pino\n\t];\n\n\tif (minify) {\n\t\t// Names kept: an error's class name is what a log line's `err.type` and\n\t\t// a response's `name` say, and minified they read `_6`.\n\t\targs.push('--minify', '--keep-names');\n\t}\n\n\tif (sourcemap) {\n\t\targs.push('--sourcemap');\n\t}\n\n\t// Add external packages (user-specified)\n\tfor (const ext of external) {\n\t\targs.push(`--external:${ext}`);\n\t}\n\n\t// Handle secrets injection if stage is provided\n\tlet masterKey: string | undefined;\n\n\tif (stage) {\n\t\tconst {\n\t\t\ttoEmbeddableSecrets,\n\t\t\tvalidateEnvironmentVariables,\n\t\t\tinitStageSecrets,\n\t\t} = await import('../secrets/storage');\n\t\tconst { FileSecretsStore, secretsStoreFor } = await import(\n\t\t\t'../secrets/store'\n\t\t);\n\t\tconst { ConfigNotFound, loadWorkspaceSettings } = await import('../config');\n\t\tconst { encryptSecrets, generateDefineOptions } = await import(\n\t\t\t'../secrets/encryption'\n\t\t);\n\n\t\t// The stage's own store — SSM or Secrets Manager for a deployed stage\n\t\t// kept there. Outside\n\t\t// any workspace nothing names one, so it is the file.\n\t\tconst store = await loadWorkspaceSettings().then(\n\t\t\t(workspace) => secretsStoreFor(workspace, stage),\n\t\t\t(error) => {\n\t\t\t\tif (error instanceof ConfigNotFound) {\n\t\t\t\t\treturn new FileSecretsStore(process.cwd());\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t},\n\t\t);\n\t\tlet secrets = await store.read(stage);\n\n\t\tif (!secrets) {\n\t\t\t// Auto-initialize secrets for the stage\n\t\t\tconsole.log(` Initializing secrets for stage \"${stage}\"...`);\n\t\t\tsecrets = initStageSecrets(stage);\n\t\t\tawait store.write(stage, secrets);\n\t\t\tconsole.log(` ✓ Created the \"${stage}\" secrets (${store.name})`);\n\t\t}\n\n\t\t// Validate environment variables if constructs are provided\n\t\tif (constructs && constructs.length > 0) {\n\t\t\tconsole.log(' Analyzing environment variable requirements...');\n\t\t\tconst requiredVars = await collectRequiredEnvVars(constructs);\n\n\t\t\tif (requiredVars.length > 0) {\n\t\t\t\tconst validation = validateEnvironmentVariables(requiredVars, secrets);\n\n\t\t\t\tif (!validation.valid) {\n\t\t\t\t\tconst errorMessage = [\n\t\t\t\t\t\t`Missing environment variables for stage \"${stage}\":`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t...validation.missing.map((v) => ` ❌ ${v}`),\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'To fix this, either:',\n\t\t\t\t\t\t` 1. Add the missing variables to the \"${stage}\" secrets using:`,\n\t\t\t\t\t\t` gkm secrets:set <KEY> <VALUE> --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t` 2. Or import from a JSON file:`,\n\t\t\t\t\t\t` gkm secrets:import secrets.json --stage ${stage}`,\n\t\t\t\t\t\t'',\n\t\t\t\t\t\t'Required variables:',\n\t\t\t\t\t\t...validation.required.map((v) =>\n\t\t\t\t\t\t\tvalidation.missing.includes(v) ? ` ❌ ${v}` : ` ✓ ${v}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t].join('\\n');\n\n\t\t\t\t\tthrow new Error(errorMessage);\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t` ✓ All ${requiredVars.length} required environment variables found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Convert to embeddable format and encrypt\n\t\tconst embeddable = toEmbeddableSecrets(secrets);\n\t\tconst encrypted = encryptSecrets(embeddable);\n\t\tmasterKey = encrypted.masterKey;\n\n\t\t// Add define options for build-time injection using esbuild's --define:KEY=VALUE format\n\t\tconst defines = generateDefineOptions(encrypted);\n\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t// `value` is already a JS string literal; quoting it again would\n\t\t\t// embed the quotes, and the IV would not parse as hex.\n\t\t\targs.push(`--define:${key}=${value}`);\n\t\t}\n\n\t\tconsole.log(` Secrets encrypted for stage \"${stage}\"`);\n\t} else {\n\t\t// Credentials encrypted elsewhere — an image build hands them in as a\n\t\t// BuildKit secret and writes them beside the app's `.gkm/server` — are\n\t\t// embedded as they are; whoever encrypted them holds the key.\n\t\tconst gkmDir = join(outputDir, '..', '..');\n\t\tconst encryptedPath = join(gkmDir, 'credentials.enc');\n\t\tconst ivPath = join(gkmDir, 'credentials.iv');\n\t\tif (existsSync(encryptedPath) && existsSync(ivPath)) {\n\t\t\tconst { generateDefineOptions } = await import('../secrets/encryption');\n\t\t\tconst defines = generateDefineOptions({\n\t\t\t\tencrypted: readFileSync(encryptedPath, 'utf-8').trim(),\n\t\t\t\tiv: readFileSync(ivPath, 'utf-8').trim(),\n\t\t\t\tmasterKey: '',\n\t\t\t});\n\t\t\tfor (const [key, value] of Object.entries(defines)) {\n\t\t\t\targs.push(`--define:${key}=${value}`);\n\t\t\t}\n\t\t\tconsole.log(' Embedded the encrypted credentials the build was given');\n\t\t}\n\t}\n\n\ttry {\n\t\t// Run esbuild with command-line arguments\n\t\tconst [cmd, ...cmdArgs] = args as [string, ...string[]];\n\t\tconst result = spawnSync(cmd, cmdArgs, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: 'inherit',\n\t\t\tshell: process.platform === 'win32', // Only use shell on Windows for npx resolution\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tthrow result.error;\n\t\t}\n\t\tif (result.status !== 0) {\n\t\t\tthrow new Error(`esbuild exited with code ${result.status}`);\n\t\t}\n\n\t\t// Add shebang to the bundled file\n\t\tconst { readFile } = await import('node:fs/promises');\n\t\tconst content = await readFile(mjsOutput, 'utf-8');\n\t\tif (!content.startsWith('#!')) {\n\t\t\tawait writeFile(mjsOutput, `#!/usr/bin/env node\\n${content}`);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Failed to bundle server: ${error instanceof Error ? error.message : 'Unknown error'}`,\n\t\t);\n\t}\n\n\treturn {\n\t\toutputPath: mjsOutput,\n\t\tmasterKey,\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_credentials = require("./credentials-Zqr3QQYB.cjs");
|
|
2
|
-
const require_deploy = require("./deploy-
|
|
2
|
+
const require_deploy = require("./deploy-V43Rbboj.cjs");
|
|
3
3
|
const require_index = require("./index.cjs");
|
|
4
4
|
const require_provider = require("./provider-BqpjG9QM.cjs");
|
|
5
5
|
const require_terminal = require("./terminal-D_NRPW4W.cjs");
|
|
@@ -68,4 +68,4 @@ async function deployCli(options, streams = { stdout: process.stdout }) {
|
|
|
68
68
|
//#endregion
|
|
69
69
|
exports.deployCli = deployCli;
|
|
70
70
|
|
|
71
|
-
//# sourceMappingURL=cli-
|
|
71
|
+
//# sourceMappingURL=cli-Btfl8J6K.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-
|
|
1
|
+
{"version":3,"file":"cli-Btfl8J6K.cjs","names":["targetForProvider","formatError","deploy","storedCredentials","terminalCredentials"],"sources":["../src/deploy/cli.ts"],"sourcesContent":["/**\n * `gkm deploy`: the terminal around `deploy()`. CLI layer only.\n *\n * Everything that belongs to a person at a terminal lives here and nowhere\n * below it: prompting for a missing login (and storing it), printing progress,\n * and turning the outcome into an exit code. The deploy itself is the same\n * `deploy()` a host calls.\n */\n\nimport { formatError } from '../debug';\nimport { targetForProvider } from '../target/provider';\nimport { storedCredentials } from './credentials';\nimport { deploy } from './deploy';\nimport { terminalCredentials } from './terminal';\n\nexport interface DeployCliOptions {\n\t/** The project directory: `--cwd`, else where the command was run. */\n\tcwd: string;\n\t/** `--target`: where to deploy. Defaults to `deploy.default`. */\n\ttarget?: string;\n\t/** `--provider`, deprecated: `dokploy` means `--target dokploy`. */\n\tprovider?: string;\n\tstage: string;\n\ttag?: string;\n\t/**\n\t * Print each event as one JSON object per line on stdout, instead of the\n\t * progress lines. Nothing prompts: a missing credential fails the run.\n\t */\n\tjson?: boolean;\n\t/** Plan only: create, change, build and push nothing. */\n\tdryRun?: boolean;\n\t/** On a failed release, roll back every app, not only the failed ones. */\n\tatomic?: boolean;\n\t/** `--allow-dev-services`. */\n\tallowDevServices?: boolean;\n\t/** `--skip-dns`. */\n\tskipDns?: boolean;\n\t/** `--rotate-keys`. */\n\trotateKeys?: boolean;\n\t/** `--retire-old-keys`. */\n\tretireOldKeys?: boolean;\n}\n\n/** Where the command writes. The process's own streams, outside tests. */\nexport interface DeployCliStreams {\n\tstdout: Pick<NodeJS.WriteStream, 'write'>;\n}\n\n/**\n * Run `gkm deploy` and resolve with its exit code: 0 when the run finished,\n * 1 when anything stopped it.\n */\nexport async function deployCli(\n\toptions: DeployCliOptions,\n\tstreams: DeployCliStreams = { stdout: process.stdout },\n): Promise<number> {\n\tlet target = options.target;\n\tif (options.provider !== undefined && target === undefined) {\n\t\ttry {\n\t\t\t// On stderr, so a `--json` run's stdout still carries only events.\n\t\t\ttarget = targetForProvider(options.provider, (message) =>\n\t\t\t\tconsole.warn(message),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconsole.error(formatError(error));\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst input = {\n\t\tcwd: options.cwd,\n\t\tstage: options.stage,\n\t\t...(target ? { target } : {}),\n\t\t...(options.tag ? { tag: options.tag } : {}),\n\t\t...(options.dryRun ? { dryRun: true } : {}),\n\t\t...(options.atomic ? { atomic: true } : {}),\n\t\t...(options.allowDevServices ? { allowDevServices: true } : {}),\n\t\t...(options.skipDns ? { skipDns: true } : {}),\n\t\t...(options.rotateKeys ? { rotateKeys: true } : {}),\n\t\t...(options.retireOldKeys ? { retireOldKeys: true } : {}),\n\t};\n\n\tif (options.json) {\n\t\t// stdout carries the events and nothing else: docker's own output goes\n\t\t// to stderr, and nobody is asked anything — a prompt would be written\n\t\t// into the stream a program is parsing.\n\t\tconst run = deploy({\n\t\t\t...input,\n\t\t\tcredentials: storedCredentials(),\n\t\t\tchildOutput: 'stderr',\n\t\t});\n\t\tfor await (const event of run) {\n\t\t\tstreams.stdout.write(`${JSON.stringify(event)}\\n`);\n\t\t}\n\t\treturn run.result.then(\n\t\t\t() => 0,\n\t\t\t(error) => {\n\t\t\t\tconsole.error(formatError(error));\n\t\t\t\treturn 1;\n\t\t\t},\n\t\t);\n\t}\n\n\t// The lines arrive as they are written, rather than as events read back a\n\t// tick later, so they interleave with a prompt exactly as they always did.\n\tconst run = deploy({\n\t\t...input,\n\t\tcredentials: terminalCredentials(storedCredentials()),\n\t\tlogger: {\n\t\t\tinfo: (message) => console.log(message),\n\t\t\twarn: (message) => console.warn(message),\n\t\t\terror: (message) => console.error(message),\n\t\t},\n\t});\n\n\ttry {\n\t\tawait run.result;\n\t\treturn 0;\n\t} catch (error) {\n\t\tconsole.error(formatError(error));\n\t\treturn 1;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoDA,eAAsB,UACrB,SACA,UAA4B,EAAE,QAAQ,QAAQ,OAAO,GACnC;CAClB,IAAI,SAAS,QAAQ;CACrB,IAAI,QAAQ,aAAa,KAAA,KAAa,WAAW,KAAA,GAChD,IAAI;EAEH,SAASA,iBAAAA,kBAAkB,QAAQ,WAAW,YAC7C,QAAQ,KAAK,OAAO,CACrB;CACD,SAAS,OAAO;EACf,QAAQ,MAAMC,cAAAA,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;CAGD,MAAM,QAAQ;EACb,KAAK,QAAQ;EACb,OAAO,QAAQ;EACf,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC3B,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;EAC1C,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,mBAAmB,EAAE,kBAAkB,KAAK,IAAI,CAAC;EAC7D,GAAI,QAAQ,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;EAC3C,GAAI,QAAQ,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;EACjD,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;CACxD;CAEA,IAAI,QAAQ,MAAM;EAIjB,MAAM,MAAMC,eAAAA,OAAO;GAClB,GAAG;GACH,aAAaC,oBAAAA,kBAAkB;GAC/B,aAAa;EACd,CAAC;EACD,WAAW,MAAM,SAAS,KACzB,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;EAElD,OAAO,IAAI,OAAO,WACX,IACL,UAAU;GACV,QAAQ,MAAMF,cAAAA,YAAY,KAAK,CAAC;GAChC,OAAO;EACR,CACD;CACD;CAIA,MAAM,MAAMC,eAAAA,OAAO;EAClB,GAAG;EACH,aAAaE,iBAAAA,oBAAoBD,oBAAAA,kBAAkB,CAAC;EACpD,QAAQ;GACP,OAAO,YAAY,QAAQ,IAAI,OAAO;GACtC,OAAO,YAAY,QAAQ,KAAK,OAAO;GACvC,QAAQ,YAAY,QAAQ,MAAM,OAAO;EAC1C;CACD,CAAC;CAED,IAAI;EACH,MAAM,IAAI;EACV,OAAO;CACR,SAAS,OAAO;EACf,QAAQ,MAAMF,cAAAA,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;AACD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as storedCredentials } from "./credentials-B5N5yKk6.mjs";
|
|
2
|
-
import { t as deploy } from "./deploy-
|
|
2
|
+
import { t as deploy } from "./deploy-T3TwqzKf.mjs";
|
|
3
3
|
import { i as formatError } from "./index.mjs";
|
|
4
4
|
import { n as targetForProvider } from "./provider-CEOKk8NS.mjs";
|
|
5
5
|
import { terminalCredentials } from "./terminal-CvRLxz6g.mjs";
|
|
@@ -68,4 +68,4 @@ async function deployCli(options, streams = { stdout: process.stdout }) {
|
|
|
68
68
|
//#endregion
|
|
69
69
|
export { deployCli };
|
|
70
70
|
|
|
71
|
-
//# sourceMappingURL=cli-
|
|
71
|
+
//# sourceMappingURL=cli-D-ZAyAub.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-
|
|
1
|
+
{"version":3,"file":"cli-D-ZAyAub.mjs","names":[],"sources":["../src/deploy/cli.ts"],"sourcesContent":["/**\n * `gkm deploy`: the terminal around `deploy()`. CLI layer only.\n *\n * Everything that belongs to a person at a terminal lives here and nowhere\n * below it: prompting for a missing login (and storing it), printing progress,\n * and turning the outcome into an exit code. The deploy itself is the same\n * `deploy()` a host calls.\n */\n\nimport { formatError } from '../debug';\nimport { targetForProvider } from '../target/provider';\nimport { storedCredentials } from './credentials';\nimport { deploy } from './deploy';\nimport { terminalCredentials } from './terminal';\n\nexport interface DeployCliOptions {\n\t/** The project directory: `--cwd`, else where the command was run. */\n\tcwd: string;\n\t/** `--target`: where to deploy. Defaults to `deploy.default`. */\n\ttarget?: string;\n\t/** `--provider`, deprecated: `dokploy` means `--target dokploy`. */\n\tprovider?: string;\n\tstage: string;\n\ttag?: string;\n\t/**\n\t * Print each event as one JSON object per line on stdout, instead of the\n\t * progress lines. Nothing prompts: a missing credential fails the run.\n\t */\n\tjson?: boolean;\n\t/** Plan only: create, change, build and push nothing. */\n\tdryRun?: boolean;\n\t/** On a failed release, roll back every app, not only the failed ones. */\n\tatomic?: boolean;\n\t/** `--allow-dev-services`. */\n\tallowDevServices?: boolean;\n\t/** `--skip-dns`. */\n\tskipDns?: boolean;\n\t/** `--rotate-keys`. */\n\trotateKeys?: boolean;\n\t/** `--retire-old-keys`. */\n\tretireOldKeys?: boolean;\n}\n\n/** Where the command writes. The process's own streams, outside tests. */\nexport interface DeployCliStreams {\n\tstdout: Pick<NodeJS.WriteStream, 'write'>;\n}\n\n/**\n * Run `gkm deploy` and resolve with its exit code: 0 when the run finished,\n * 1 when anything stopped it.\n */\nexport async function deployCli(\n\toptions: DeployCliOptions,\n\tstreams: DeployCliStreams = { stdout: process.stdout },\n): Promise<number> {\n\tlet target = options.target;\n\tif (options.provider !== undefined && target === undefined) {\n\t\ttry {\n\t\t\t// On stderr, so a `--json` run's stdout still carries only events.\n\t\t\ttarget = targetForProvider(options.provider, (message) =>\n\t\t\t\tconsole.warn(message),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconsole.error(formatError(error));\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\tconst input = {\n\t\tcwd: options.cwd,\n\t\tstage: options.stage,\n\t\t...(target ? { target } : {}),\n\t\t...(options.tag ? { tag: options.tag } : {}),\n\t\t...(options.dryRun ? { dryRun: true } : {}),\n\t\t...(options.atomic ? { atomic: true } : {}),\n\t\t...(options.allowDevServices ? { allowDevServices: true } : {}),\n\t\t...(options.skipDns ? { skipDns: true } : {}),\n\t\t...(options.rotateKeys ? { rotateKeys: true } : {}),\n\t\t...(options.retireOldKeys ? { retireOldKeys: true } : {}),\n\t};\n\n\tif (options.json) {\n\t\t// stdout carries the events and nothing else: docker's own output goes\n\t\t// to stderr, and nobody is asked anything — a prompt would be written\n\t\t// into the stream a program is parsing.\n\t\tconst run = deploy({\n\t\t\t...input,\n\t\t\tcredentials: storedCredentials(),\n\t\t\tchildOutput: 'stderr',\n\t\t});\n\t\tfor await (const event of run) {\n\t\t\tstreams.stdout.write(`${JSON.stringify(event)}\\n`);\n\t\t}\n\t\treturn run.result.then(\n\t\t\t() => 0,\n\t\t\t(error) => {\n\t\t\t\tconsole.error(formatError(error));\n\t\t\t\treturn 1;\n\t\t\t},\n\t\t);\n\t}\n\n\t// The lines arrive as they are written, rather than as events read back a\n\t// tick later, so they interleave with a prompt exactly as they always did.\n\tconst run = deploy({\n\t\t...input,\n\t\tcredentials: terminalCredentials(storedCredentials()),\n\t\tlogger: {\n\t\t\tinfo: (message) => console.log(message),\n\t\t\twarn: (message) => console.warn(message),\n\t\t\terror: (message) => console.error(message),\n\t\t},\n\t});\n\n\ttry {\n\t\tawait run.result;\n\t\treturn 0;\n\t} catch (error) {\n\t\tconsole.error(formatError(error));\n\t\treturn 1;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoDA,eAAsB,UACrB,SACA,UAA4B,EAAE,QAAQ,QAAQ,OAAO,GACnC;CAClB,IAAI,SAAS,QAAQ;CACrB,IAAI,QAAQ,aAAa,KAAA,KAAa,WAAW,KAAA,GAChD,IAAI;EAEH,SAAS,kBAAkB,QAAQ,WAAW,YAC7C,QAAQ,KAAK,OAAO,CACrB;CACD,SAAS,OAAO;EACf,QAAQ,MAAM,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;CAGD,MAAM,QAAQ;EACb,KAAK,QAAQ;EACb,OAAO,QAAQ;EACf,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC3B,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;EAC1C,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC;EACzC,GAAI,QAAQ,mBAAmB,EAAE,kBAAkB,KAAK,IAAI,CAAC;EAC7D,GAAI,QAAQ,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;EAC3C,GAAI,QAAQ,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;EACjD,GAAI,QAAQ,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;CACxD;CAEA,IAAI,QAAQ,MAAM;EAIjB,MAAM,MAAM,OAAO;GAClB,GAAG;GACH,aAAa,kBAAkB;GAC/B,aAAa;EACd,CAAC;EACD,WAAW,MAAM,SAAS,KACzB,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;EAElD,OAAO,IAAI,OAAO,WACX,IACL,UAAU;GACV,QAAQ,MAAM,YAAY,KAAK,CAAC;GAChC,OAAO;EACR,CACD;CACD;CAIA,MAAM,MAAM,OAAO;EAClB,GAAG;EACH,aAAa,oBAAoB,kBAAkB,CAAC;EACpD,QAAQ;GACP,OAAO,YAAY,QAAQ,IAAI,OAAO;GACtC,OAAO,YAAY,QAAQ,KAAK,OAAO;GACvC,QAAQ,YAAY,QAAQ,MAAM,OAAO;EAC1C;CACD,CAAC;CAED,IAAI;EACH,MAAM,IAAI;EACV,OAAO;CACR,SAAS,OAAO;EACf,QAAQ,MAAM,YAAY,KAAK,CAAC;EAChC,OAAO;CACR;AACD"}
|
|
@@ -2,9 +2,9 @@ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
|
2
2
|
import { t as GkmError } from "./errors-D8Gwp5kU.mjs";
|
|
3
3
|
import { a as runOutput, i as run } from "./run-BJLIerMM.mjs";
|
|
4
4
|
import { B as LOGS_PORT, I as otlpTelemetryEnv, L as resolveStageTelemetry, at as certificateFor, ft as SERVER_IPV4_KEY, ht as isReservedStageKey, it as ComposeTlsFileMissing, ot as proxyFor, z as telemetryEnv } from "./workspace-D1QbNd55.mjs";
|
|
5
|
-
import { a as serverAddressHint, h as stackBackups, i as requiredServerAddress, l as systemLookup, m as backupsService, o as stackHosts, p as backupsRoleStatements, r as isLocalHost, s as stageDns, t as HostNotPointingAtServer, u as BACKUPS_SERVICE, x as stageBackups } from "./dns-
|
|
5
|
+
import { a as serverAddressHint, h as stackBackups, i as requiredServerAddress, l as systemLookup, m as backupsService, o as stackHosts, p as backupsRoleStatements, r as isLocalHost, s as stageDns, t as HostNotPointingAtServer, u as BACKUPS_SERVICE, x as stageBackups } from "./dns-AosA2wwP.mjs";
|
|
6
6
|
import { t as defineTarget } from "./define-6poNqm5O.mjs";
|
|
7
|
-
import { $ as devServicesUsed, $t as workerUnits, An as isTelemetryKey, Bn as portKeys, Cn as withRedisPassword, Dn as planFor, Fn as EMULATOR_ACCESS_KEY_ID, Gn as LOGS_SERVICE, Gt as imageLayout, I as appDockerfile, In as hostFor, Jn as stackLogs, K as validateImageRef, Kn as logsAccess, Kt as TURBO_VERSION, Ln as DEFAULT_IMAGES, M as stageProviderNotes, Nn as telemetryOf, Pn as usesTelemetry, Qn as resolveHost, R as ensureDockerignore, Sn as stackRedis, St as composeFor, Tn as localRolePassword, Un as primaryPortKey, Wt as composeBuildPaths, Xn as NoDomainForStage, Yn as withLogsPassword, Yt as findBuildRoot, Zn as isMainFrontendApp, _ as createComposeState, _n as withGeneratedSecrets, _t as LEGACY_LOCAL_LOGIN, an as postgresStatements, at as appEnvKeys, bn as redisService, bt as pgClient, cn as loadLocalCredentials, ct as workerEnvKeys, dt as constructGlobs, en as applyBuckets, et as externalServices, it as suppliedOnly, jn as scopeTelemetryEnv, n as reportDatabaseRuns, nn as applyPostgres, o as recordDnsChanges, qn as logsService, qt as WORKER_PORT, r as reportPlannedSeeds, rn as bucketPolicies, rt as stageServiceDeclarations, s as currentActor, sn as LOCAL_RABBITMQ_USER, st as networkEnv, t as DeploySeedsFailed, tn as applyPolicies, u as DeployJournal, un as postgresSuperuser, vn as REDIS_SERVICE, vt as ensurePostgresLogin, wn as envFor, x as recordRelease, xn as runsRedis, yn as STACK_CACHE, yt as bucketClient, z as workerDockerfile, zt as initStageSecrets } from "./seeds-
|
|
7
|
+
import { $ as devServicesUsed, $t as workerUnits, An as isTelemetryKey, Bn as portKeys, Cn as withRedisPassword, Dn as planFor, Fn as EMULATOR_ACCESS_KEY_ID, Gn as LOGS_SERVICE, Gt as imageLayout, I as appDockerfile, In as hostFor, Jn as stackLogs, K as validateImageRef, Kn as logsAccess, Kt as TURBO_VERSION, Ln as DEFAULT_IMAGES, M as stageProviderNotes, Nn as telemetryOf, Pn as usesTelemetry, Qn as resolveHost, R as ensureDockerignore, Sn as stackRedis, St as composeFor, Tn as localRolePassword, Un as primaryPortKey, Wt as composeBuildPaths, Xn as NoDomainForStage, Yn as withLogsPassword, Yt as findBuildRoot, Zn as isMainFrontendApp, _ as createComposeState, _n as withGeneratedSecrets, _t as LEGACY_LOCAL_LOGIN, an as postgresStatements, at as appEnvKeys, bn as redisService, bt as pgClient, cn as loadLocalCredentials, ct as workerEnvKeys, dt as constructGlobs, en as applyBuckets, et as externalServices, it as suppliedOnly, jn as scopeTelemetryEnv, n as reportDatabaseRuns, nn as applyPostgres, o as recordDnsChanges, qn as logsService, qt as WORKER_PORT, r as reportPlannedSeeds, rn as bucketPolicies, rt as stageServiceDeclarations, s as currentActor, sn as LOCAL_RABBITMQ_USER, st as networkEnv, t as DeploySeedsFailed, tn as applyPolicies, u as DeployJournal, un as postgresSuperuser, vn as REDIS_SERVICE, vt as ensurePostgresLogin, wn as envFor, x as recordRelease, xn as runsRedis, yn as STACK_CACHE, yt as bucketClient, z as workerDockerfile, zt as initStageSecrets } from "./seeds-C1v4ZOro.mjs";
|
|
8
8
|
import { t as appKey } from "./derive-B4vDpzgP.mjs";
|
|
9
9
|
import { o as DEFAULT_EVENTS } from "./SubscriberGenerator-DHnIYwUU.mjs";
|
|
10
10
|
import { a as imageRef } from "./identity-CBXr4wNi.mjs";
|
|
@@ -3154,4 +3154,4 @@ function composeTarget(options = {}) {
|
|
|
3154
3154
|
//#endregion
|
|
3155
3155
|
export { sshTarget as _, stackOverrideFile as a, composeProject as c, stackPlan as d, EDGE_PROJECT as f, dockerHost as g, composeServer as h, ComposePushNeedsBuild as i, derivedCredentials as l, pinnedRef as m, compose_exports as n, edgeRef as o, parseDigests as p, ComposePinNeedsPull as r, removeEdgeRoutes as s, composeTarget as t, stackDir as u, dockerCompose as v, projectNetwork as y };
|
|
3156
3156
|
|
|
3157
|
-
//# sourceMappingURL=compose-
|
|
3157
|
+
//# sourceMappingURL=compose-C-lnkCAT.mjs.map
|