@qpqjs/cli 0.4.0 → 0.6.0
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/lib/commonjs/cli/runCli.js +2 -2
- package/lib/commonjs/cli/runCli.js.map +1 -1
- package/lib/commonjs/commands/checkCircular.js +2 -2
- package/lib/commonjs/commands/checkCircular.js.map +1 -1
- package/lib/commonjs/commands/goDev.js +2 -2
- package/lib/commonjs/commands/goDev.js.map +1 -1
- package/lib/commonjs/commands/goDevApi.js +6 -5
- package/lib/commonjs/commands/goDevApi.js.map +1 -1
- package/lib/commonjs/commands/goDevWeb.js +3 -3
- package/lib/commonjs/commands/goDevWeb.js.map +1 -1
- package/lib/commonjs/commands/goDocker.js +2 -2
- package/lib/commonjs/commands/goDocker.js.map +1 -1
- package/lib/commonjs/commands/hooks.js +2 -2
- package/lib/commonjs/commands/hooks.js.map +1 -1
- package/lib/commonjs/commands/migrate.js +2 -2
- package/lib/commonjs/commands/migrate.js.map +1 -1
- package/lib/commonjs/commands/prep.js +2 -2
- package/lib/commonjs/commands/prep.js.map +1 -1
- package/lib/commonjs/commands/scriptBuild.js +2 -2
- package/lib/commonjs/commands/scriptBuild.js.map +1 -1
- package/lib/commonjs/commands/scriptBuilderLayer.js +2 -2
- package/lib/commonjs/commands/scriptBuilderLayer.js.map +1 -1
- package/lib/commonjs/commands/scriptNew.js +2 -2
- package/lib/commonjs/commands/scriptNew.js.map +1 -1
- package/lib/commonjs/commands/setup.js +2 -2
- package/lib/commonjs/commands/setup.js.map +1 -1
- package/lib/commonjs/commands/synth.js +2 -2
- package/lib/commonjs/commands/synth.js.map +1 -1
- package/lib/commonjs/lib/{out.d.ts → Output.d.ts} +2 -1
- package/lib/commonjs/lib/Output.js +3 -0
- package/lib/commonjs/lib/Output.js.map +1 -0
- package/lib/commonjs/lib/clearResourcesPlan.js +2 -2
- package/lib/commonjs/lib/clearResourcesPlan.js.map +1 -1
- package/lib/commonjs/lib/createOutput.d.ts +2 -0
- package/lib/commonjs/lib/{out.js → createOutput.js} +13 -4
- package/lib/commonjs/lib/createOutput.js.map +1 -0
- package/lib/commonjs/lib/deployPrompts.js +3 -3
- package/lib/commonjs/lib/deployPrompts.js.map +1 -1
- package/lib/commonjs/lib/hooks.js +2 -2
- package/lib/commonjs/lib/hooks.js.map +1 -1
- package/lib/commonjs/lib/killChildWithEscalation.js +2 -2
- package/lib/commonjs/lib/killChildWithEscalation.js.map +1 -1
- package/lib/commonjs/lib/killStaleListeners.js +3 -3
- package/lib/commonjs/lib/killStaleListeners.js.map +1 -1
- package/lib/commonjs/lib/prompts.js +2 -2
- package/lib/commonjs/lib/prompts.js.map +1 -1
- package/lib/commonjs/lib/qpqConfigs.d.ts +1 -0
- package/lib/commonjs/lib/qpqConfigs.js +9 -4
- package/lib/commonjs/lib/qpqConfigs.js.map +1 -1
- package/lib/commonjs/lib/requireDriverCapability.js +2 -2
- package/lib/commonjs/lib/requireDriverCapability.js.map +1 -1
- package/lib/commonjs/lib/resolveAppSelection.js +3 -3
- package/lib/commonjs/lib/resolveAppSelection.js.map +1 -1
- package/lib/commonjs/lib/resolveDeployment.js +3 -3
- package/lib/commonjs/lib/resolveDeployment.js.map +1 -1
- package/lib/commonjs/lib/runCommand.js +2 -2
- package/lib/commonjs/lib/runCommand.js.map +1 -1
- package/lib/commonjs/lib/runTasks.js +2 -2
- package/lib/commonjs/lib/runTasks.js.map +1 -1
- package/lib/commonjs/lib/timing.js +2 -2
- package/lib/commonjs/lib/timing.js.map +1 -1
- package/lib/commonjs/lib/typeWatcher.js +3 -3
- package/lib/commonjs/lib/typeWatcher.js.map +1 -1
- package/lib/commonjs/lib/userScriptBuilderLayer.js +1 -1
- package/lib/commonjs/lib/userScriptBuilderLayer.js.map +1 -1
- package/lib/commonjs/platforms/aws/awsCredentials.js +2 -2
- package/lib/commonjs/platforms/aws/awsCredentials.js.map +1 -1
- package/lib/commonjs/platforms/aws/clearResources.js +4 -3
- package/lib/commonjs/platforms/aws/clearResources.js.map +1 -1
- package/lib/commonjs/platforms/aws/go.js +2 -2
- package/lib/commonjs/platforms/aws/go.js.map +1 -1
- package/lib/commonjs/platforms/aws/goDocker.js +2 -2
- package/lib/commonjs/platforms/aws/goDocker.js.map +1 -1
- package/lib/commonjs/platforms/aws/publish.js +2 -2
- package/lib/commonjs/platforms/aws/publish.js.map +1 -1
- package/lib/commonjs/platforms/aws/remote.js +2 -2
- package/lib/commonjs/platforms/aws/remote.js.map +1 -1
- package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.js +2 -2
- package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.js.map +1 -1
- package/lib/commonjs/platforms/aws/stacks.js +4 -8
- package/lib/commonjs/platforms/aws/stacks.js.map +1 -1
- package/lib/commonjs/platforms/aws/teardown.js +2 -2
- package/lib/commonjs/platforms/aws/teardown.js.map +1 -1
- package/lib/commonjs/platforms/aws/viewsSync.js +2 -2
- package/lib/commonjs/platforms/aws/viewsSync.js.map +1 -1
- package/lib/commonjs/platforms/docker/go.js +2 -2
- package/lib/commonjs/platforms/docker/go.js.map +1 -1
- package/lib/commonjs/platforms/docker/index.js +2 -2
- package/lib/commonjs/platforms/docker/index.js.map +1 -1
- package/lib/commonjs/platforms/index.js +2 -2
- package/lib/commonjs/platforms/index.js.map +1 -1
- package/lib/esm/cli/runCli.js +1 -1
- package/lib/esm/cli/runCli.js.map +1 -1
- package/lib/esm/commands/checkCircular.js +1 -1
- package/lib/esm/commands/checkCircular.js.map +1 -1
- package/lib/esm/commands/goDev.js +1 -1
- package/lib/esm/commands/goDev.js.map +1 -1
- package/lib/esm/commands/goDevApi.js +4 -4
- package/lib/esm/commands/goDevApi.js.map +1 -1
- package/lib/esm/commands/goDevWeb.js +2 -2
- package/lib/esm/commands/goDevWeb.js.map +1 -1
- package/lib/esm/commands/goDocker.js +1 -1
- package/lib/esm/commands/goDocker.js.map +1 -1
- package/lib/esm/commands/hooks.js +1 -1
- package/lib/esm/commands/hooks.js.map +1 -1
- package/lib/esm/commands/migrate.js +1 -1
- package/lib/esm/commands/migrate.js.map +1 -1
- package/lib/esm/commands/prep.js +1 -1
- package/lib/esm/commands/prep.js.map +1 -1
- package/lib/esm/commands/scriptBuild.js +1 -1
- package/lib/esm/commands/scriptBuild.js.map +1 -1
- package/lib/esm/commands/scriptBuilderLayer.js +1 -1
- package/lib/esm/commands/scriptBuilderLayer.js.map +1 -1
- package/lib/esm/commands/scriptNew.js +1 -1
- package/lib/esm/commands/scriptNew.js.map +1 -1
- package/lib/esm/commands/setup.js +1 -1
- package/lib/esm/commands/setup.js.map +1 -1
- package/lib/esm/commands/synth.js +1 -1
- package/lib/esm/commands/synth.js.map +1 -1
- package/lib/esm/lib/{out.d.ts → Output.d.ts} +2 -1
- package/lib/esm/lib/Output.js +2 -0
- package/lib/esm/lib/Output.js.map +1 -0
- package/lib/esm/lib/clearResourcesPlan.js +1 -1
- package/lib/esm/lib/clearResourcesPlan.js.map +1 -1
- package/lib/esm/lib/createOutput.d.ts +2 -0
- package/lib/esm/lib/{out.js → createOutput.js} +13 -4
- package/lib/esm/lib/createOutput.js.map +1 -0
- package/lib/esm/lib/deployPrompts.js +2 -2
- package/lib/esm/lib/deployPrompts.js.map +1 -1
- package/lib/esm/lib/hooks.js +1 -1
- package/lib/esm/lib/hooks.js.map +1 -1
- package/lib/esm/lib/killChildWithEscalation.js +1 -1
- package/lib/esm/lib/killChildWithEscalation.js.map +1 -1
- package/lib/esm/lib/killStaleListeners.js +2 -2
- package/lib/esm/lib/killStaleListeners.js.map +1 -1
- package/lib/esm/lib/prompts.js +1 -1
- package/lib/esm/lib/prompts.js.map +1 -1
- package/lib/esm/lib/qpqConfigs.d.ts +1 -0
- package/lib/esm/lib/qpqConfigs.js +7 -3
- package/lib/esm/lib/qpqConfigs.js.map +1 -1
- package/lib/esm/lib/requireDriverCapability.js +1 -1
- package/lib/esm/lib/requireDriverCapability.js.map +1 -1
- package/lib/esm/lib/resolveAppSelection.js +2 -2
- package/lib/esm/lib/resolveAppSelection.js.map +1 -1
- package/lib/esm/lib/resolveDeployment.js +2 -2
- package/lib/esm/lib/resolveDeployment.js.map +1 -1
- package/lib/esm/lib/runCommand.js +1 -1
- package/lib/esm/lib/runCommand.js.map +1 -1
- package/lib/esm/lib/runTasks.js +1 -1
- package/lib/esm/lib/runTasks.js.map +1 -1
- package/lib/esm/lib/timing.js +1 -1
- package/lib/esm/lib/timing.js.map +1 -1
- package/lib/esm/lib/typeWatcher.js +2 -2
- package/lib/esm/lib/typeWatcher.js.map +1 -1
- package/lib/esm/lib/userScriptBuilderLayer.js +1 -1
- package/lib/esm/lib/userScriptBuilderLayer.js.map +1 -1
- package/lib/esm/platforms/aws/awsCredentials.js +1 -1
- package/lib/esm/platforms/aws/awsCredentials.js.map +1 -1
- package/lib/esm/platforms/aws/clearResources.js +3 -2
- package/lib/esm/platforms/aws/clearResources.js.map +1 -1
- package/lib/esm/platforms/aws/go.js +1 -1
- package/lib/esm/platforms/aws/go.js.map +1 -1
- package/lib/esm/platforms/aws/goDocker.js +1 -1
- package/lib/esm/platforms/aws/goDocker.js.map +1 -1
- package/lib/esm/platforms/aws/publish.js +1 -1
- package/lib/esm/platforms/aws/publish.js.map +1 -1
- package/lib/esm/platforms/aws/remote.js +1 -1
- package/lib/esm/platforms/aws/remote.js.map +1 -1
- package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.js +1 -1
- package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.js.map +1 -1
- package/lib/esm/platforms/aws/stacks.js +5 -9
- package/lib/esm/platforms/aws/stacks.js.map +1 -1
- package/lib/esm/platforms/aws/teardown.js +1 -1
- package/lib/esm/platforms/aws/teardown.js.map +1 -1
- package/lib/esm/platforms/aws/viewsSync.js +1 -1
- package/lib/esm/platforms/aws/viewsSync.js.map +1 -1
- package/lib/esm/platforms/docker/go.js +1 -1
- package/lib/esm/platforms/docker/go.js.map +1 -1
- package/lib/esm/platforms/docker/index.js +1 -1
- package/lib/esm/platforms/docker/index.js.map +1 -1
- package/lib/esm/platforms/index.js +1 -1
- package/lib/esm/platforms/index.js.map +1 -1
- package/package.json +11 -11
- package/lib/commonjs/lib/out.js.map +0 -1
- package/lib/esm/lib/out.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"killStaleListeners.js","sourceRoot":"","sources":["../../../src/lib/killStaleListeners.ts"],"names":[],"mappings":"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","sourcesContent":["import { runCommandCaptureSync, sleepSync } from './runCommand';\n// Pre-start sweep shared by the dev-server commands: a previous run whose\n// wrapper died without killing its listener (closed terminal, SIGKILL) leaves\n// an orphaned process holding a dev port, and the next launch dies with\n// EADDRINUSE. Before starting, kill any listener on the given ports whose\n// command line matches `isOurs`. Anything else on the ports is left alone\n// and reported, it's not ours.\nimport { Nullable } from '@qpqjs/core';\n\nimport fs from 'fs';\nimport path from 'path';\nimport { createOutput } from './out';\n\nconst out = createOutput('kill-stale-listeners');\n\n// Matches any invocation of the qpq CLI itself, regardless of how it was\n// launched: `node node_modules/.bin/qpq ...` (the npm-script shim, which has\n// no .js extension), a direct `node .../lib/commonjs/bin/qpq.js` call, a\n// global `qpq` shebang script, etc. Checks each whitespace-separated token's\n// basename (extension stripped) rather than a fixed substring like\n// 'bin/qpq.js', which only matches the last of those forms.\nexport const isQpqCliCommand = (command: string): boolean =>\n command\n .trim()\n .split(/\\s+/)\n .some((token) => {\n const base = path.basename(token);\n const withoutExt = base.endsWith('.js') ? base.slice(0, -3) : base;\n return withoutExt === 'qpq';\n });\n\n// SIGTERM only requests termination, the caller (about to bind this same\n// process's ports itself) needs it actually gone first. A stale dev server\n// can be mid-startup when killed (still resolving config, not yet bound to\n// every port it eventually binds) and keep running for a bit past the\n// signal, going on to bind a LATER port, waiting for just the one port that\n// matched isn't enough; wait for the whole pid to disappear so it can't bind\n// anything else afterward. Poll synchronously (this whole sweep runs before\n// anything async starts) via `kill(pid, 0)`, reliable and fast here because\n// these are unrelated processes orphaned earlier, not children of this\n// one (a real child can sit as a zombie answering `kill(pid, 0)` until this\n// process's own event loop reaps it, which a tight sync loop would starve;\n// doesn't apply to a process we didn't spawn).\n//\n// The default covers the dev server's graceful shutdown (drain in-flight work,\n// then checkpoint the stores) with room to spare. Returns whether the pid\n// actually went, because a caller about to bind these ports has to escalate\n// rather than hope: giving up while the old server still holds 8080 is exactly\n// the EADDRINUSE this file exists to prevent.\nconst waitForPidGone = (pid: number, timeoutMs = 8000): boolean => {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n process.kill(pid, 0);\n } catch {\n return true; // throws once the pid no longer exists\n }\n sleepSync(50);\n }\n\n return false;\n};\n\n// Last resort for a process that ignored, or wedged during, its graceful stop.\nconst killPidHard = (pid: number): void => {\n out.warn(`Process ${pid} did not exit gracefully — sending SIGKILL.`);\n try {\n process.kill(pid, 'SIGKILL');\n } catch {\n return; // raced us and exited after all\n }\n waitForPidGone(pid, 2000);\n};\n\n// realpath'd: lsof reports the canonical path (e.g. /private/tmp on macOS,\n// where /tmp is a symlink), so comparing against a caller-supplied root\n// verbatim would false-negative whenever any component of the repo path is\n// itself a symlink (a symlinked home directory, an NFS mount, etc).\nconst getProcessCwd = (pid: number): Nullable<string> => {\n try {\n const line = runCommandCaptureSync('lsof', ['-a', '-p', String(pid), '-d', 'cwd', '-Fn'])\n .split('\\n')\n .find((l) => l.startsWith('n'));\n return line ? fs.realpathSync(line.slice(1)) : null;\n } catch {\n return null; // pid gone, or we don't have permission to inspect it\n }\n};\n\n// The sweep below must never target this process's own wrappers: launched as\n// `npx qpq go:dev:api` (or via any shell whose -c string names qpq), the\n// ancestor chain (`sh -c \"npx ... qpq ...\"`, `npm exec qpq ...`) matches\n// isQpqCliCommand and shares our cwd, so excluding just process.pid isn't\n// enough, SIGINTing an ancestor tears down our own tree. Walk ppid to the\n// top and exclude the whole chain.\nconst getOwnAncestorPids = (): Set<number> => {\n const ancestors = new Set<number>();\n let pid = process.pid;\n while (pid > 1 && !ancestors.has(pid)) {\n ancestors.add(pid);\n try {\n pid = Number(runCommandCaptureSync('ps', ['-o', 'ppid=', '-p', String(pid)]).trim());\n } catch {\n break;\n }\n }\n return ancestors;\n};\n\n// killStaleListeners only sees processes currently BOUND to one of the given\n// ports, it can't catch a still-running `qpq go:dev*` watcher whose spawned\n// dev-server child already died (a crash, or us killing just the child):\n// the watcher itself holds no port at that moment, so it's invisible to a\n// port scan, yet it's still alive and can spawn a fresh child, and bind a\n// port, moments later, racing whatever we're about to start. Close that gap\n// by finding any OTHER qpq CLI process rooted in the same repo checkout\n// (matched by cwd, not by port or command-line args, which vary by how it\n// was invoked) and killing it outright, regardless of what it currently has\n// bound. SIGINT (not SIGTERM) so goDevApiCommand/goDevWebCommand's own\n// handler runs and tears down its child cleanly rather than orphaning it.\nexport const killOtherQpqDevProcesses = (root: string): void => {\n const resolvedRoot = fs.realpathSync(root);\n const ownPids = getOwnAncestorPids();\n\n let lines: string[] = [];\n try {\n lines = runCommandCaptureSync('ps', ['-axo', 'pid=,command=']).split('\\n');\n } catch {\n return;\n }\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n const spaceIndex = trimmed.indexOf(' ');\n if (spaceIndex === -1) continue;\n\n const pid = Number(trimmed.slice(0, spaceIndex));\n const command = trimmed.slice(spaceIndex + 1).trim();\n\n if (!pid || ownPids.has(pid) || !isQpqCliCommand(command)) continue;\n if (getProcessCwd(pid) !== resolvedRoot) continue;\n\n out.log(`Killing other qpq dev process for this repo (pid ${pid}): ${command}`);\n process.kill(pid, 'SIGINT');\n if (!waitForPidGone(pid)) {\n killPidHard(pid);\n }\n }\n};\n\n// Whatever is currently listening on a port, as pid + command line. Empty when\n// the port is free, or when lsof is unavailable.\nconst getPortListeners = (port: number): { pid: number; command: string }[] => {\n let pids: number[] = [];\n try {\n pids = runCommandCaptureSync('lsof', ['-t', `-iTCP:${port}`, '-sTCP:LISTEN'])\n .split('\\n')\n .map((line) => Number(line.trim()))\n .filter(Boolean);\n } catch {\n return []; // lsof exits non-zero when nothing is listening\n }\n\n return pids.flatMap((pid) => {\n try {\n return [{ pid, command: runCommandCaptureSync('ps', ['-p', String(pid), '-o', 'command=']).trim() }];\n } catch {\n return []; // already gone\n }\n });\n};\n\n/**\n * Say what is holding these ports, without touching it.\n *\n * The other half of --keep-other-dev-servers: sparing a sibling checkout's dev\n * server means this one cannot bind, and an unexplained EADDRINUSE is a worse\n * experience than the silent kill it replaces. Naming the pid and the command\n * turns \"it just died\" into something you can act on.\n *\n * Worded as a prediction, not a fact, because it IS one: this runs before the\n * bundle step, so by the time anything binds - seconds later - the holder may\n * well have gone. Stating \"port in use\" and then starting cleanly reads like\n * the warning was wrong.\n */\nexport const reportPortHolders = (ports: number[]): void => {\n for (const port of ports) {\n for (const { pid, command } of getPortListeners(port)) {\n out.warn(`Port ${port} is currently held by pid ${pid}: ${command}`);\n out.warn(` Starting anyway. If it still holds port ${port} once this server binds, startup will fail with EADDRINUSE.`);\n }\n }\n};\n\nexport const killStaleListeners = (ports: number[], isOurs: (command: string) => boolean): void => {\n for (const port of ports) {\n for (const { pid, command } of getPortListeners(port)) {\n if (isOurs(command)) {\n out.log(`Killing stale dev server on port ${port} (pid ${pid})`);\n process.kill(pid);\n if (!waitForPidGone(pid)) {\n killPidHard(pid);\n }\n } else {\n out.warn(`Port ${port} is in use by an unrelated process (pid ${pid}: ${command}) — not killing it.`);\n }\n }\n }\n};\n"]}
|
|
1
|
+
{"version":3,"file":"killStaleListeners.js","sourceRoot":"","sources":["../../../src/lib/killStaleListeners.ts"],"names":[],"mappings":"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","sourcesContent":["// Pre-start sweep shared by the dev-server commands: a previous run whose\n// wrapper died without killing its listener (closed terminal, SIGKILL) leaves\n// an orphaned process holding a dev port, and the next launch dies with\n// EADDRINUSE. Before starting, kill any listener on the given ports whose\n// command line matches `isOurs`. Anything else on the ports is left alone\n// and reported, it's not ours.\nimport { Nullable } from '@qpqjs/core';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { createOutput } from './createOutput';\nimport { runCommandCaptureSync, sleepSync } from './runCommand';\n\nconst out = createOutput('kill-stale-listeners');\n\n// Matches any invocation of the qpq CLI itself, regardless of how it was\n// launched: `node node_modules/.bin/qpq ...` (the npm-script shim, which has\n// no .js extension), a direct `node .../lib/commonjs/bin/qpq.js` call, a\n// global `qpq` shebang script, etc. Checks each whitespace-separated token's\n// basename (extension stripped) rather than a fixed substring like\n// 'bin/qpq.js', which only matches the last of those forms.\nexport const isQpqCliCommand = (command: string): boolean =>\n command\n .trim()\n .split(/\\s+/)\n .some((token) => {\n const base = path.basename(token);\n const withoutExt = base.endsWith('.js') ? base.slice(0, -3) : base;\n return withoutExt === 'qpq';\n });\n\n// SIGTERM only requests termination, the caller (about to bind this same\n// process's ports itself) needs it actually gone first. A stale dev server\n// can be mid-startup when killed (still resolving config, not yet bound to\n// every port it eventually binds) and keep running for a bit past the\n// signal, going on to bind a LATER port, waiting for just the one port that\n// matched isn't enough; wait for the whole pid to disappear so it can't bind\n// anything else afterward. Poll synchronously (this whole sweep runs before\n// anything async starts) via `kill(pid, 0)`, reliable and fast here because\n// these are unrelated processes orphaned earlier, not children of this\n// one (a real child can sit as a zombie answering `kill(pid, 0)` until this\n// process's own event loop reaps it, which a tight sync loop would starve;\n// doesn't apply to a process we didn't spawn).\n//\n// The default covers the dev server's graceful shutdown (drain in-flight work,\n// then checkpoint the stores) with room to spare. Returns whether the pid\n// actually went, because a caller about to bind these ports has to escalate\n// rather than hope: giving up while the old server still holds 8080 is exactly\n// the EADDRINUSE this file exists to prevent.\nconst waitForPidGone = (pid: number, timeoutMs = 8000): boolean => {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n try {\n process.kill(pid, 0);\n } catch {\n return true; // throws once the pid no longer exists\n }\n sleepSync(50);\n }\n\n return false;\n};\n\n// Last resort for a process that ignored, or wedged during, its graceful stop.\nconst killPidHard = (pid: number): void => {\n out.warn(`Process ${pid} did not exit gracefully — sending SIGKILL.`);\n try {\n process.kill(pid, 'SIGKILL');\n } catch {\n return; // raced us and exited after all\n }\n waitForPidGone(pid, 2000);\n};\n\n// realpath'd: lsof reports the canonical path (e.g. /private/tmp on macOS,\n// where /tmp is a symlink), so comparing against a caller-supplied root\n// verbatim would false-negative whenever any component of the repo path is\n// itself a symlink (a symlinked home directory, an NFS mount, etc).\nconst getProcessCwd = (pid: number): Nullable<string> => {\n try {\n const line = runCommandCaptureSync('lsof', ['-a', '-p', String(pid), '-d', 'cwd', '-Fn'])\n .split('\\n')\n .find((l) => l.startsWith('n'));\n return line ? fs.realpathSync(line.slice(1)) : null;\n } catch {\n return null; // pid gone, or we don't have permission to inspect it\n }\n};\n\n// The sweep below must never target this process's own wrappers: launched as\n// `npx qpq go:dev:api` (or via any shell whose -c string names qpq), the\n// ancestor chain (`sh -c \"npx ... qpq ...\"`, `npm exec qpq ...`) matches\n// isQpqCliCommand and shares our cwd, so excluding just process.pid isn't\n// enough, SIGINTing an ancestor tears down our own tree. Walk ppid to the\n// top and exclude the whole chain.\nconst getOwnAncestorPids = (): Set<number> => {\n const ancestors = new Set<number>();\n let pid = process.pid;\n while (pid > 1 && !ancestors.has(pid)) {\n ancestors.add(pid);\n try {\n pid = Number(runCommandCaptureSync('ps', ['-o', 'ppid=', '-p', String(pid)]).trim());\n } catch {\n break;\n }\n }\n return ancestors;\n};\n\n// killStaleListeners only sees processes currently BOUND to one of the given\n// ports, it can't catch a still-running `qpq go:dev*` watcher whose spawned\n// dev-server child already died (a crash, or us killing just the child):\n// the watcher itself holds no port at that moment, so it's invisible to a\n// port scan, yet it's still alive and can spawn a fresh child, and bind a\n// port, moments later, racing whatever we're about to start. Close that gap\n// by finding any OTHER qpq CLI process rooted in the same repo checkout\n// (matched by cwd, not by port or command-line args, which vary by how it\n// was invoked) and killing it outright, regardless of what it currently has\n// bound. SIGINT (not SIGTERM) so goDevApiCommand/goDevWebCommand's own\n// handler runs and tears down its child cleanly rather than orphaning it.\nexport const killOtherQpqDevProcesses = (root: string): void => {\n const resolvedRoot = fs.realpathSync(root);\n const ownPids = getOwnAncestorPids();\n\n let lines: string[] = [];\n try {\n lines = runCommandCaptureSync('ps', ['-axo', 'pid=,command=']).split('\\n');\n } catch {\n return;\n }\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n const spaceIndex = trimmed.indexOf(' ');\n if (spaceIndex === -1) continue;\n\n const pid = Number(trimmed.slice(0, spaceIndex));\n const command = trimmed.slice(spaceIndex + 1).trim();\n\n if (!pid || ownPids.has(pid) || !isQpqCliCommand(command)) continue;\n if (getProcessCwd(pid) !== resolvedRoot) continue;\n\n out.log(`Killing other qpq dev process for this repo (pid ${pid}): ${command}`);\n process.kill(pid, 'SIGINT');\n if (!waitForPidGone(pid)) {\n killPidHard(pid);\n }\n }\n};\n\n// Whatever is currently listening on a port, as pid + command line. Empty when\n// the port is free, or when lsof is unavailable.\nconst getPortListeners = (port: number): { pid: number; command: string }[] => {\n let pids: number[] = [];\n try {\n pids = runCommandCaptureSync('lsof', ['-t', `-iTCP:${port}`, '-sTCP:LISTEN'])\n .split('\\n')\n .map((line) => Number(line.trim()))\n .filter(Boolean);\n } catch {\n return []; // lsof exits non-zero when nothing is listening\n }\n\n return pids.flatMap((pid) => {\n try {\n return [{ pid, command: runCommandCaptureSync('ps', ['-p', String(pid), '-o', 'command=']).trim() }];\n } catch {\n return []; // already gone\n }\n });\n};\n\n/**\n * Say what is holding these ports, without touching it.\n *\n * The other half of --keep-other-dev-servers: sparing a sibling checkout's dev\n * server means this one cannot bind, and an unexplained EADDRINUSE is a worse\n * experience than the silent kill it replaces. Naming the pid and the command\n * turns \"it just died\" into something you can act on.\n *\n * Worded as a prediction, not a fact, because it IS one: this runs before the\n * bundle step, so by the time anything binds - seconds later - the holder may\n * well have gone. Stating \"port in use\" and then starting cleanly reads like\n * the warning was wrong.\n */\nexport const reportPortHolders = (ports: number[]): void => {\n for (const port of ports) {\n for (const { pid, command } of getPortListeners(port)) {\n out.warn(`Port ${port} is currently held by pid ${pid}: ${command}`);\n out.warn(` Starting anyway. If it still holds port ${port} once this server binds, startup will fail with EADDRINUSE.`);\n }\n }\n};\n\nexport const killStaleListeners = (ports: number[], isOurs: (command: string) => boolean): void => {\n for (const port of ports) {\n for (const { pid, command } of getPortListeners(port)) {\n if (isOurs(command)) {\n out.log(`Killing stale dev server on port ${port} (pid ${pid})`);\n process.kill(pid);\n if (!waitForPidGone(pid)) {\n killPidHard(pid);\n }\n } else {\n out.warn(`Port ${port} is in use by an unrelated process (pid ${pid}: ${command}) — not killing it.`);\n }\n }\n }\n};\n"]}
|
package/lib/esm/lib/prompts.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createOutput } from './
|
|
1
|
+
import { createOutput } from './createOutput';
|
|
2
2
|
const out = createOutput('prompts');
|
|
3
3
|
// Present a single-choice list prompt and return the selected value.
|
|
4
4
|
// @inquirer/prompts is imported lazily so commands only pay for it when
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/lib/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/lib/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AACpC,qEAAqE;AACrE,wEAAwE;AACxE,sBAAsB;AACtB,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,OAAe,EAAE,OAAiB,EAAE,aAAsB,EAAmB,EAAE;IAChH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,wEAAwE;AACxE,6EAA6E;AAC7E,gEAAgE;AAChE,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,OAAe,EACf,OAA2E,EAC/D,EAAE;IACd,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACtC,CAAC,CAAC;AAEF,kDAAkD;AAClD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,OAAe,EAAoB,EAAE,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC;AAE/H,8EAA8E;AAC9E,2DAA2D;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,OAAe,EAAmB,EAAE;IACnE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,2FAA2F;AAC3F,qFAAqF;AACrF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAAE,MAAc,EAAoB,EAAE;IAChF,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,SAAS,MAAM,cAAc,CAAC,CAAC;IAErE,IAAI,YAAY,KAAK,MAAM,EAAE,CAAC;QAC5B,GAAG,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QAChD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,sFAAsF;AACtF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,OAAe,EACf,OAA8E,EAChE,EAAE;IAChB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACvD,OAAO,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import { createOutput } from './createOutput';\n\nconst out = createOutput('prompts');\n// Present a single-choice list prompt and return the selected value.\n// @inquirer/prompts is imported lazily so commands only pay for it when\n// actually prompting.\nexport const promptSelect = async (message: string, choices: string[], defaultChoice?: string): Promise<string> => {\n const { select } = await import('@inquirer/prompts');\n return select({ message, choices, default: defaultChoice });\n};\n\n// A single-choice list prompt over labelled values; a choice's optional\n// `short` replaces its name in the answer line once picked, and its optional\n// `description` renders under the list while it is highlighted.\nexport const promptSelectDetailed = async <T>(\n message: string,\n choices: { name: string; value: T; short?: string; description?: string }[],\n): Promise<T> => {\n const { select } = await import('@inquirer/prompts');\n return select({ message, choices });\n};\n\n// A yes/no list prompt, returning true for \"Yes\".\nexport const promptYesNo = async (message: string): Promise<boolean> => (await promptSelect(message, ['No', 'Yes'])) === 'Yes';\n\n// A free-text prompt, used where a y/n is too easy to fat-finger (destructive\n// confirmations that require typing the target name back).\nexport const promptText = async (message: string): Promise<string> => {\n const { input } = await import('@inquirer/prompts');\n return input({ message });\n};\n\n// The friction for destructive commands: the target has to be typed back exactly. Resolves\n// true when it was; prints why it stops otherwise, so callers only have to bail out.\nexport const promptTypedConfirmation = async (target: string): Promise<boolean> => {\n const confirmation = await promptText(`Type '${target}' to confirm`);\n\n if (confirmation !== target) {\n out.log('Confirmation did not match. Exiting!');\n return false;\n }\n\n return true;\n};\n\n// A multi-select checkbox prompt over labelled values; `checked` preselects a choice.\nexport const promptCheckbox = async <T>(\n message: string,\n choices: { name: string; value: T; checked?: boolean; description?: string }[],\n): Promise<T[]> => {\n const { checkbox } = await import('@inquirer/prompts');\n return checkbox({ message, choices });\n};\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type QPQConfig } from '@qpqjs/core';
|
|
2
2
|
export declare const loadServiceQpqConfig: (appName: string, service: string) => QPQConfig;
|
|
3
|
+
export declare const loadFirstServiceQpqConfig: (appName: string) => QPQConfig;
|
|
3
4
|
export declare const getAppPrefix: (appName: string) => string;
|
|
4
5
|
export declare const getServiceNamesWithFederation: (appName: string, serviceNames: string[]) => string[];
|
|
@@ -5,12 +5,16 @@ import { getRoot, getServiceNames } from './discovery';
|
|
|
5
5
|
// registered, so requiring TS works and `@scope/*` imports resolve through
|
|
6
6
|
// workspace symlinks).
|
|
7
7
|
export const loadServiceQpqConfig = (appName, service) => getWorkspaceServiceQpqConfig(getRoot(), appName, service);
|
|
8
|
-
|
|
8
|
+
// App-wide facts (the application name, the domain stack) live on every service's config alike, so the first
|
|
9
|
+
// service found stands in for the app. An app with no services has no config to read and that is an error.
|
|
10
|
+
export const loadFirstServiceQpqConfig = (appName) => {
|
|
9
11
|
const [firstService] = getServiceNames(appName);
|
|
10
|
-
if (firstService === undefined)
|
|
12
|
+
if (firstService === undefined) {
|
|
11
13
|
throw new Error(`No services found for app ${appName}`);
|
|
12
|
-
|
|
14
|
+
}
|
|
15
|
+
return loadServiceQpqConfig(appName, firstService);
|
|
13
16
|
};
|
|
17
|
+
export const getAppPrefix = (appName) => qpqCoreUtils.getApplicationName(loadFirstServiceQpqConfig(appName));
|
|
14
18
|
// The subset of the given services that opt into module-federation publishing,
|
|
15
19
|
// i.e. declare defineFederatedModuleStore(...). Federation is a config setting,
|
|
16
20
|
// not a directory convention (unlike views/ backends), so detecting it means
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qpqConfigs.js","sourceRoot":"","sources":["../../../src/lib/qpqConfigs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvD,wEAAwE;AACxE,2EAA2E;AAC3E,uBAAuB;AACvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,OAAe,EAAa,EAAE,CAAC,4BAA4B,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAE/I,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"qpqConfigs.js","sourceRoot":"","sources":["../../../src/lib/qpqConfigs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEvD,wEAAwE;AACxE,2EAA2E;AAC3E,uBAAuB;AACvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,OAAe,EAAa,EAAE,CAAC,4BAA4B,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAE/I,6GAA6G;AAC7G,2GAA2G;AAC3G,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAe,EAAa,EAAE;IACtE,MAAM,CAAC,YAAY,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,oBAAoB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,YAAY,CAAC,kBAAkB,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAC;AAE7H,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,4DAA4D;AAC5D,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,OAAe,EAAE,YAAsB,EAAY,EAAE,CACjG,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,uBAAuB,CAAC,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC","sourcesContent":["import { type QPQConfig, qpqCoreUtils } from '@qpqjs/core';\nimport { getWorkspaceServiceQpqConfig } from '@qpqjs/deploy-aws';\n\nimport { getRoot, getServiceNames } from './discovery';\n\n// Loads a service's live infrastructure.ts (qpq runs with ts-node hooks\n// registered, so requiring TS works and `@scope/*` imports resolve through\n// workspace symlinks).\nexport const loadServiceQpqConfig = (appName: string, service: string): QPQConfig => getWorkspaceServiceQpqConfig(getRoot(), appName, service);\n\n// App-wide facts (the application name, the domain stack) live on every service's config alike, so the first\n// service found stands in for the app. An app with no services has no config to read and that is an error.\nexport const loadFirstServiceQpqConfig = (appName: string): QPQConfig => {\n const [firstService] = getServiceNames(appName);\n if (firstService === undefined) {\n throw new Error(`No services found for app ${appName}`);\n }\n\n return loadServiceQpqConfig(appName, firstService);\n};\n\nexport const getAppPrefix = (appName: string): string => qpqCoreUtils.getApplicationName(loadFirstServiceQpqConfig(appName));\n\n// The subset of the given services that opt into module-federation publishing,\n// i.e. declare defineFederatedModuleStore(...). Federation is a config setting,\n// not a directory convention (unlike views/ backends), so detecting it means\n// loading each service's config, which is why this lives here and not in the\n// directory-only discovery module. Used by the deploy drivers to decide which\n// backends to publish federated remotes for after a deploy.\nexport const getServiceNamesWithFederation = (appName: string, serviceNames: string[]): string[] =>\n serviceNames.filter((service) => !!qpqCoreUtils.getFederatedModuleStore(loadServiceQpqConfig(appName, service)));\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CliError } from './CliError';
|
|
2
|
-
import { createOutput } from './
|
|
2
|
+
import { createOutput } from './createOutput';
|
|
3
3
|
const out = createOutput('require-driver-capability');
|
|
4
4
|
// Hands back a driver's optional capability, or stops the command with a message naming the
|
|
5
5
|
// platform that lacks it. The capability name doubles as the strategy name in that message.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requireDriverCapability.js","sourceRoot":"","sources":["../../../src/lib/requireDriverCapability.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"requireDriverCapability.js","sourceRoot":"","sources":["../../../src/lib/requireDriverCapability.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,MAAM,GAAG,GAAG,YAAY,CAAC,2BAA2B,CAAC,CAAC;AAMtD,4FAA4F;AAC5F,4FAA4F;AAC5F,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,OAAuB,EACvB,UAAa,EACb,OAAe,EAAE,EACkB,EAAE;IACrC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAElD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,QAAQ,CAAC,QAAQ,OAAO,CAAC,UAAU,CAAC,QAAQ,qBAAqB,UAAU,aAAa,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9H,CAAC;IAED,OAAO,cAAmD,CAAC;AAC7D,CAAC,CAAC","sourcesContent":["import { QpqPlatformDriver } from '../platforms';\nimport { CliError } from './CliError';\nimport { createOutput } from './createOutput';\nimport { CommandContext } from './resolveCommandContext';\n\nconst out = createOutput('require-driver-capability');\n\ntype OptionalCapability = {\n [K in keyof QpqPlatformDriver]-?: undefined extends QpqPlatformDriver[K] ? K : never;\n}[keyof QpqPlatformDriver];\n\n// Hands back a driver's optional capability, or stops the command with a message naming the\n// platform that lacks it. The capability name doubles as the strategy name in that message.\nexport const requireDriverCapability = <K extends OptionalCapability>(\n context: CommandContext,\n capability: K,\n hint: string = '',\n): NonNullable<QpqPlatformDriver[K]> => {\n const implementation = context.driver[capability];\n\n if (!implementation) {\n throw new CliError(`The '${context.deployment.platform}' platform has no ${capability} strategy.${hint ? ` ${hint}` : ''}`);\n }\n\n return implementation as NonNullable<QpqPlatformDriver[K]>;\n};\n"]}
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
// Commands that can meaningfully run for every app may pass allowAll to accept
|
|
11
11
|
// `--app all` (returned as the literal 'all').
|
|
12
12
|
import { getArgValue } from './args';
|
|
13
|
+
import { CliError } from './CliError';
|
|
14
|
+
import { createOutput } from './createOutput';
|
|
13
15
|
import { getAvailableApps } from './discovery';
|
|
14
16
|
import { promptSelect } from './prompts';
|
|
15
|
-
import { CliError } from './CliError';
|
|
16
|
-
import { createOutput } from './out';
|
|
17
17
|
const out = createOutput('resolve-app-selection');
|
|
18
18
|
const exitWithAppList = (requested, availableApps) => {
|
|
19
19
|
throw new CliError([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveAppSelection.js","sourceRoot":"","sources":["../../../src/lib/resolveAppSelection.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iEAAiE;AACjE,2CAA2C;AAC3C,+EAA+E;AAC/E,kFAAkF;AAClF,kDAAkD;AAClD,qCAAqC;AACrC,6DAA6D;AAC7D,6EAA6E;AAC7E,+EAA+E;AAC/E,+CAA+C;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"resolveAppSelection.js","sourceRoot":"","sources":["../../../src/lib/resolveAppSelection.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iEAAiE;AACjE,2CAA2C;AAC3C,+EAA+E;AAC/E,kFAAkF;AAClF,kDAAkD;AAClD,qCAAqC;AACrC,6DAA6D;AAC7D,6EAA6E;AAC7E,+EAA+E;AAC/E,+CAA+C;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,GAAG,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAC;AAUlD,MAAM,eAAe,GAAG,CAAC,SAA6B,EAAE,aAAuB,EAAS,EAAE;IACxF,MAAM,IAAI,QAAQ,CAChB;QACE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,gBAAgB,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,eAAe,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACzC,wDAAwD,aAAa,CAAC,CAAC,CAAC,IAAI;KAC7E,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC,CAAC;AAEF,gGAAgG;AAChG,gEAAgE;AAChE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAc,EAAE,MAAe,EAAsB,EAAE,CACzF,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAEzG,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,OAA0B,EAAmB,EAAE;IACvF,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,QAAQ,CAAC,4BAA4B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,SAAS,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpE,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,OAAO,CAAC,QAAQ,IAAI,SAAS,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QAC1D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,eAAe,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAClF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC;IAChC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxD,GAAG,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAClG,CAAC;IAED,OAAO,eAAe,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AACnD,CAAC,CAAC","sourcesContent":["// One app-selection contract for every app-facing command (prep / synth / go /\n// go:dev / go:dev:api / go:dev:web / publish). Resolution order:\n// 1. --app <name> / --app=<name> on argv\n// 2. npm_config_app (npm run x --app foo, no --)\n// 3. an env var the command already honours (QPQ_DEV_APP / DEPLOY_APP_NAME)\n// 4. exactly one app under apps/ -> auto-select\n// 5. interactive prompt (TTY only)\n// 6. otherwise: print the valid app list and exit non-zero\n// An unknown name (from any source) also prints the list and exits non-zero.\n// Commands that can meaningfully run for every app may pass allowAll to accept\n// `--app all` (returned as the literal 'all').\nimport { getArgValue } from './args';\nimport { CliError } from './CliError';\nimport { createOutput } from './createOutput';\nimport { getAvailableApps } from './discovery';\nimport { promptSelect } from './prompts';\n\nconst out = createOutput('resolve-app-selection');\n\nexport type ResolveAppOptions = {\n argv: string[];\n // Env var this command historically honours (e.g. QPQ_DEV_APP, DEPLOY_APP_NAME).\n envVar?: string;\n // Accept `--app all` and return 'all'.\n allowAll?: boolean;\n};\n\nconst exitWithAppList = (requested: string | undefined, availableApps: string[]): never => {\n throw new CliError(\n [\n ...(requested ? [`Unknown app '${requested}'.`] : []),\n `Valid apps: ${availableApps.join(', ')}`,\n `Pass one with --app <name> (e.g. qpq <command> --app ${availableApps[0]}).`,\n ].join('\\n'),\n );\n};\n\n// The app a caller named, from the sources above the auto-select and the prompt (--app, the npm\n// config flag, the command's env var); undefined when none did.\nexport const getRequestedAppName = (argv: string[], envVar?: string): string | undefined =>\n getArgValue(argv, '--app') || process.env.npm_config_app || (envVar ? process.env[envVar] : undefined);\n\nexport const resolveAppSelection = async (options: ResolveAppOptions): Promise<string> => {\n const availableApps = getAvailableApps();\n if (availableApps.length === 0) {\n throw new CliError('No apps found under apps/.');\n }\n\n const requested = getRequestedAppName(options.argv, options.envVar);\n\n if (requested) {\n if (options.allowAll && requested === 'all') return 'all';\n if (!availableApps.includes(requested)) exitWithAppList(requested, availableApps);\n return requested;\n }\n\n const [onlyApp] = availableApps;\n if (availableApps.length === 1 && onlyApp !== undefined) {\n out.log(`Using app: ${onlyApp}`);\n return onlyApp;\n }\n\n if (process.stdin.isTTY) {\n return promptSelect('Select app', options.allowAll ? [...availableApps, 'all'] : availableApps);\n }\n\n return exitWithAppList(undefined, availableApps);\n};\n"]}
|
|
@@ -2,10 +2,10 @@ import { getQpqAppDeployConfig, getQpqAppDeployConfigPath, primeDeploymentEnv }
|
|
|
2
2
|
import { QpqDeployEnvVar } from '@qpqjs/core';
|
|
3
3
|
import { getPlatformDriver } from '../platforms';
|
|
4
4
|
import { getArgValue } from './args';
|
|
5
|
+
import { CliError } from './CliError';
|
|
6
|
+
import { createOutput } from './createOutput';
|
|
5
7
|
import { getRoot } from './discovery';
|
|
6
8
|
import { promptSelect } from './prompts';
|
|
7
|
-
import { CliError } from './CliError';
|
|
8
|
-
import { createOutput } from './out';
|
|
9
9
|
const out = createOutput('resolve-deployment');
|
|
10
10
|
const DEPLOYMENT_FLAG = '--deployment';
|
|
11
11
|
// Which entry to use: the flag, then DEPLOY_NAME (set by a parent qpq command or CI: a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveDeployment.js","sourceRoot":"","sources":["../../../src/lib/resolveDeployment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAoB,eAAe,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"resolveDeployment.js","sourceRoot":"","sources":["../../../src/lib/resolveDeployment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAoB,eAAe,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,GAAG,GAAG,YAAY,CAAC,oBAAoB,CAAC,CAAC;AAE/C,MAAM,eAAe,GAAG,cAAc,CAAC;AAOvC,uFAAuF;AACvF,sFAAsF;AACtF,4DAA4D;AAC5D,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAc,EAAE,OAAe,EAAE,eAAyB,EAAmB,EAAE;IACjH,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,EAAE,eAAe,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAEhG,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,QAAQ,CAChB,uBAAuB,SAAS,QAAQ,yBAAyB,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,iBAAiB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnI,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,QAAQ,CAAC,GAAG,eAAe,CAAC;IACnC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QACzC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,IAAI,QAAQ,CAAC,gCAAgC,eAAe,wBAAwB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1H,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,IAAc,EAAE,OAAe,EAA+B,EAAE;IACtG,MAAM,EAAE,WAAW,EAAE,GAAG,qBAAqB,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IAClE,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC3F,MAAM,UAAU,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,eAAe,cAAc,eAAe,OAAO,uBAAuB,CAAC,CAAC;IAC9F,CAAC;IAED,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACxD,iBAAiB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAErF,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;AACxC,CAAC,CAAC","sourcesContent":["import { getQpqAppDeployConfig, getQpqAppDeployConfigPath, primeDeploymentEnv } from '@qpqjs/config-aws';\nimport { QpqAppDeployment, QpqDeployEnvVar } from '@qpqjs/core';\n\nimport { getPlatformDriver } from '../platforms';\nimport { getArgValue } from './args';\nimport { CliError } from './CliError';\nimport { createOutput } from './createOutput';\nimport { getRoot } from './discovery';\nimport { promptSelect } from './prompts';\n\nconst out = createOutput('resolve-deployment');\n\nconst DEPLOYMENT_FLAG = '--deployment';\n\nexport type ResolvedDeployment = {\n deploymentName: string;\n deployment: QpqAppDeployment;\n};\n\n// Which entry to use: the flag, then DEPLOY_NAME (set by a parent qpq command or CI: a\n// selector, never a value), then the sole entry, then a prompt. Headless with several\n// entries and no selection is an error rather than a guess.\nconst selectDeploymentName = async (argv: string[], appName: string, configuredNames: string[]): Promise<string> => {\n const requested = getArgValue(argv, DEPLOYMENT_FLAG) || process.env[QpqDeployEnvVar.deployName];\n\n if (requested) {\n if (!configuredNames.includes(requested)) {\n throw new CliError(\n `Unknown deployment '${requested}' in ${getQpqAppDeployConfigPath(getRoot(), appName)}. Configured: ${configuredNames.join(', ')}`,\n );\n }\n return requested;\n }\n\n const [onlyName] = configuredNames;\n if (configuredNames.length === 1 && onlyName !== undefined) {\n out.log(`Using deployment: ${onlyName}`);\n return onlyName;\n }\n\n if (process.stdin.isTTY) {\n return promptSelect('Select deployment', configuredNames);\n }\n\n throw new CliError(`No deployment selected. Pass ${DEPLOYMENT_FLAG} <name>. Configured: ${configuredNames.join(', ')}`);\n};\n\n/**\n * Selects an entry of the app's deploy.config.json and writes it into process.env\n * (identity, environment, feature, settings) before any service config is loaded.\n * The file is the source of truth: nothing in the shell overrides a value in it.\n * The platform driver validates its own settings, so an aws entry missing its\n * account or region fails here, not inside cdk.\n */\nexport const resolveDeployment = async (argv: string[], appName: string): Promise<ResolvedDeployment> => {\n const { deployments } = getQpqAppDeployConfig(getRoot(), appName);\n const deploymentName = await selectDeploymentName(argv, appName, Object.keys(deployments));\n const deployment = deployments[deploymentName];\n if (!deployment) {\n throw new Error(`Deployment [${deploymentName}] is not in ${appName}'s deploy.config.json`);\n }\n\n primeDeploymentEnv(appName, deploymentName, deployment);\n getPlatformDriver(deployment.platform).prepareDeployment(deploymentName, deployment);\n\n return { deploymentName, deployment };\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn, spawnSync } from 'child_process';
|
|
2
|
-
import { createOutput } from './
|
|
2
|
+
import { createOutput } from './createOutput';
|
|
3
3
|
const out = createOutput('run-command');
|
|
4
4
|
// Shell only on Windows (to resolve npm/aws/cdk .cmd shims). On posix, run without a shell so
|
|
5
5
|
// the already-array args are passed straight to the program and can't be re-interpreted by
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../../src/lib/runCommand.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChildProcess, spawn, spawnSync, StdioOptions } from 'child_process';\nimport type { Readable } from 'stream';\nimport { createOutput } from './out';\n\nconst out = createOutput('run-command');\n\nexport type RunCommandOptions = {\n // Extra environment variables merged over the parent process env.\n env?: Record<string, string>;\n // Working directory for the child (defaults to cwd).\n cwd?: string;\n // Echo the command before running it.\n logCommand?: boolean;\n};\n\nexport type SpawnCommandOptions = RunCommandOptions & {\n // Defaults to inheriting the parent's stdio.\n stdio?: StdioOptions;\n};\n\n// Shell only on Windows (to resolve npm/aws/cdk .cmd shims). On posix, run without a shell so\n// the already-array args are passed straight to the program and can't be re-interpreted by\n// `sh -c`, no command injection via interpolated values (stack names, CI-supplied env, etc.).\nconst useShell = process.platform === 'win32';\n\nconst toSpawnOptions = (options: SpawnCommandOptions) => ({\n shell: useShell,\n cwd: options.cwd ?? process.cwd(),\n env: { ...process.env, ...(options.env ?? {}) },\n});\n\n/**\n * Starts a long-running child (a dev server, a watcher) and hands back its handle; the caller\n * owns its lifetime. Every process the cli starts goes through here or one of the runners\n * below, so the shell and env rules are in one place.\n */\nexport const spawnCommand = (command: string, args: string[], options: SpawnCommandOptions = {}): ChildProcess =>\n spawn(\n command,\n args.filter((a) => !!a),\n { stdio: options.stdio ?? 'inherit', ...toSpawnOptions(options) },\n );\n\n/** Runs a command to completion, inheriting stdio; throws on a non-zero exit. For code that cannot await. */\nexport const runCommandSync = (command: string, args: string[], options: RunCommandOptions = {}): void => {\n const validArgs = args.filter((a) => !!a);\n const result = spawnSync(command, validArgs, { stdio: 'inherit', ...toSpawnOptions(options) });\n\n if (result.error) throw result.error;\n if (result.status) throw new Error(`${command} ${validArgs.join(' ')} exited with code ${result.status}`);\n};\n\n/**\n * Runs a command to completion and returns its stdout (stderr is dropped); throws when it\n * cannot start or exits non-zero. For the short probes (`ps`, `lsof`, `npm --version`) whose\n * output decides what the cli does next.\n */\nexport const runCommandCaptureSync = (command: string, args: string[], options: RunCommandOptions = {}): string => {\n const validArgs = args.filter((a) => !!a);\n const result = spawnSync(command, validArgs, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', ...toSpawnOptions(options) });\n\n if (result.error) throw result.error;\n if (result.status) throw new Error(`${command} ${validArgs.join(' ')} exited with code ${result.status}`);\n\n return result.stdout;\n};\n\n/** Blocks the current thread for `ms`; only for the short polls in synchronous cleanup code. */\nexport const sleepSync = (ms: number): void => {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n};\n\n// Spawn a command, inheriting stdio, resolving on success. A non-zero exit\n// REJECTS so a failed build/deploy stops the run.\nexport const runCommand = (command: string, args: string[], options: RunCommandOptions = {}): Promise<void> =>\n new Promise((resolve, reject) => {\n const validArgs = args.filter((a) => !!a);\n\n if (options.logCommand) {\n out.log(`Running command: ${command} ${validArgs.join(' ')}`);\n }\n\n const child = spawnCommand(command, validArgs, options);\n\n child.on('error', (error) => reject(error));\n\n child.on('exit', (code, signal) => {\n if (signal) return reject(new Error(`${command} was killed with signal ${signal}`));\n if (code) return reject(new Error(`${command} ${validArgs.join(' ')} exited with code ${code}`));\n return resolve();\n });\n });\n\n// Run a command for its side effect only, swallowing both its output and its\n// exit code, for best-effort cleanup steps (e.g. `docker rm -f` of a container\n// that may not exist) that must never fail the run. Without a shell there's no\n// `>/dev/null 2>&1 || true`, so quieting and non-failing happen here instead.\nexport const runCommandBestEffort = (command: string, args: string[], options: RunCommandOptions = {}): Promise<void> =>\n new Promise((resolve) => {\n const validArgs = args.filter((a) => !!a);\n\n const child = spawnCommand(command, validArgs, { ...options, stdio: 'ignore' });\n\n child.on('error', () => resolve());\n child.on('exit', () => resolve());\n });\n\nexport type RunCommandPrefixedOptions = {\n env?: Record<string, string>;\n cwd?: string;\n // ANSI color code for the prefix (see nextPrefixColor).\n color?: number;\n};\n\nconst PREFIX_COLORS = [36, 32, 33, 35, 34, 96, 92, 93, 95, 94];\nlet colorIndex = 0;\n\n// Hand each concurrent task a distinct prefix color so interleaved output is\n// scannable.\nexport const nextPrefixColor = (): number => {\n const color = PREFIX_COLORS[colorIndex % PREFIX_COLORS.length] ?? 0;\n colorIndex += 1;\n return color;\n};\n\n// Like runCommand, but pipes output and prefixes every line with a colored\n// [label], for running many commands concurrently without unreadable\n// interleaving. Rejects on non-zero exit.\nexport const runCommandPrefixed = (label: string, command: string, args: string[], options: RunCommandPrefixedOptions = {}): Promise<void> =>\n new Promise((resolve, reject) => {\n const validArgs = args.filter((a) => !!a);\n const prefix = `\\x1b[${options.color ?? 36}m[${label}]\\x1b[0m `;\n\n const child = spawnCommand(command, validArgs, { ...options, stdio: ['ignore', 'pipe', 'pipe'] });\n\n const attach = (stream: Readable, out: NodeJS.WriteStream): void => {\n let buffered = '';\n stream.on('data', (chunk: Buffer) => {\n buffered += chunk.toString();\n const lines = buffered.split('\\n');\n buffered = lines.pop() ?? '';\n lines.forEach((line) => out.write(`${prefix}${line}\\n`));\n });\n stream.on('end', () => {\n if (buffered) out.write(`${prefix}${buffered}\\n`);\n });\n };\n\n attach(child.stdout as Readable, process.stdout);\n attach(child.stderr as Readable, process.stderr);\n\n child.on('error', (error) => reject(error));\n\n child.on('exit', (code, signal) => {\n if (signal) return reject(new Error(`[${label}] ${command} was killed with signal ${signal}`));\n if (code) return reject(new Error(`[${label}] ${command} exited with code ${code}`));\n return resolve();\n });\n });\n"]}
|
|
1
|
+
{"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../../src/lib/runCommand.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChildProcess, spawn, spawnSync, StdioOptions } from 'child_process';\nimport type { Readable } from 'stream';\n\nimport { createOutput } from './createOutput';\n\nconst out = createOutput('run-command');\n\nexport type RunCommandOptions = {\n // Extra environment variables merged over the parent process env.\n env?: Record<string, string>;\n // Working directory for the child (defaults to cwd).\n cwd?: string;\n // Echo the command before running it.\n logCommand?: boolean;\n};\n\nexport type SpawnCommandOptions = RunCommandOptions & {\n // Defaults to inheriting the parent's stdio.\n stdio?: StdioOptions;\n};\n\n// Shell only on Windows (to resolve npm/aws/cdk .cmd shims). On posix, run without a shell so\n// the already-array args are passed straight to the program and can't be re-interpreted by\n// `sh -c`, no command injection via interpolated values (stack names, CI-supplied env, etc.).\nconst useShell = process.platform === 'win32';\n\nconst toSpawnOptions = (options: SpawnCommandOptions) => ({\n shell: useShell,\n cwd: options.cwd ?? process.cwd(),\n env: { ...process.env, ...(options.env ?? {}) },\n});\n\n/**\n * Starts a long-running child (a dev server, a watcher) and hands back its handle; the caller\n * owns its lifetime. Every process the cli starts goes through here or one of the runners\n * below, so the shell and env rules are in one place.\n */\nexport const spawnCommand = (command: string, args: string[], options: SpawnCommandOptions = {}): ChildProcess =>\n spawn(\n command,\n args.filter((a) => !!a),\n { stdio: options.stdio ?? 'inherit', ...toSpawnOptions(options) },\n );\n\n/** Runs a command to completion, inheriting stdio; throws on a non-zero exit. For code that cannot await. */\nexport const runCommandSync = (command: string, args: string[], options: RunCommandOptions = {}): void => {\n const validArgs = args.filter((a) => !!a);\n const result = spawnSync(command, validArgs, { stdio: 'inherit', ...toSpawnOptions(options) });\n\n if (result.error) throw result.error;\n if (result.status) throw new Error(`${command} ${validArgs.join(' ')} exited with code ${result.status}`);\n};\n\n/**\n * Runs a command to completion and returns its stdout (stderr is dropped); throws when it\n * cannot start or exits non-zero. For the short probes (`ps`, `lsof`, `npm --version`) whose\n * output decides what the cli does next.\n */\nexport const runCommandCaptureSync = (command: string, args: string[], options: RunCommandOptions = {}): string => {\n const validArgs = args.filter((a) => !!a);\n const result = spawnSync(command, validArgs, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8', ...toSpawnOptions(options) });\n\n if (result.error) throw result.error;\n if (result.status) throw new Error(`${command} ${validArgs.join(' ')} exited with code ${result.status}`);\n\n return result.stdout;\n};\n\n/** Blocks the current thread for `ms`; only for the short polls in synchronous cleanup code. */\nexport const sleepSync = (ms: number): void => {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n};\n\n// Spawn a command, inheriting stdio, resolving on success. A non-zero exit\n// REJECTS so a failed build/deploy stops the run.\nexport const runCommand = (command: string, args: string[], options: RunCommandOptions = {}): Promise<void> =>\n new Promise((resolve, reject) => {\n const validArgs = args.filter((a) => !!a);\n\n if (options.logCommand) {\n out.log(`Running command: ${command} ${validArgs.join(' ')}`);\n }\n\n const child = spawnCommand(command, validArgs, options);\n\n child.on('error', (error) => reject(error));\n\n child.on('exit', (code, signal) => {\n if (signal) return reject(new Error(`${command} was killed with signal ${signal}`));\n if (code) return reject(new Error(`${command} ${validArgs.join(' ')} exited with code ${code}`));\n return resolve();\n });\n });\n\n// Run a command for its side effect only, swallowing both its output and its\n// exit code, for best-effort cleanup steps (e.g. `docker rm -f` of a container\n// that may not exist) that must never fail the run. Without a shell there's no\n// `>/dev/null 2>&1 || true`, so quieting and non-failing happen here instead.\nexport const runCommandBestEffort = (command: string, args: string[], options: RunCommandOptions = {}): Promise<void> =>\n new Promise((resolve) => {\n const validArgs = args.filter((a) => !!a);\n\n const child = spawnCommand(command, validArgs, { ...options, stdio: 'ignore' });\n\n child.on('error', () => resolve());\n child.on('exit', () => resolve());\n });\n\nexport type RunCommandPrefixedOptions = {\n env?: Record<string, string>;\n cwd?: string;\n // ANSI color code for the prefix (see nextPrefixColor).\n color?: number;\n};\n\nconst PREFIX_COLORS = [36, 32, 33, 35, 34, 96, 92, 93, 95, 94];\nlet colorIndex = 0;\n\n// Hand each concurrent task a distinct prefix color so interleaved output is\n// scannable.\nexport const nextPrefixColor = (): number => {\n const color = PREFIX_COLORS[colorIndex % PREFIX_COLORS.length] ?? 0;\n colorIndex += 1;\n return color;\n};\n\n// Like runCommand, but pipes output and prefixes every line with a colored\n// [label], for running many commands concurrently without unreadable\n// interleaving. Rejects on non-zero exit.\nexport const runCommandPrefixed = (label: string, command: string, args: string[], options: RunCommandPrefixedOptions = {}): Promise<void> =>\n new Promise((resolve, reject) => {\n const validArgs = args.filter((a) => !!a);\n const prefix = `\\x1b[${options.color ?? 36}m[${label}]\\x1b[0m `;\n\n const child = spawnCommand(command, validArgs, { ...options, stdio: ['ignore', 'pipe', 'pipe'] });\n\n const attach = (stream: Readable, out: NodeJS.WriteStream): void => {\n let buffered = '';\n stream.on('data', (chunk: Buffer) => {\n buffered += chunk.toString();\n const lines = buffered.split('\\n');\n buffered = lines.pop() ?? '';\n lines.forEach((line) => out.write(`${prefix}${line}\\n`));\n });\n stream.on('end', () => {\n if (buffered) out.write(`${prefix}${buffered}\\n`);\n });\n };\n\n attach(child.stdout as Readable, process.stdout);\n attach(child.stderr as Readable, process.stderr);\n\n child.on('error', (error) => reject(error));\n\n child.on('exit', (code, signal) => {\n if (signal) return reject(new Error(`[${label}] ${command} was killed with signal ${signal}`));\n if (code) return reject(new Error(`[${label}] ${command} exited with code ${code}`));\n return resolve();\n });\n });\n"]}
|
package/lib/esm/lib/runTasks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createOutput } from './
|
|
1
|
+
import { createOutput } from './createOutput';
|
|
2
2
|
const out = createOutput('run-tasks');
|
|
3
3
|
// Run tasks with at most `limit` in flight; never rejects, failures come back
|
|
4
4
|
// labelled so a whole wave can finish before we report what broke.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runTasks.js","sourceRoot":"","sources":["../../../src/lib/runTasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"runTasks.js","sourceRoot":"","sources":["../../../src/lib/runTasks.ts"],"names":[],"mappings":"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","sourcesContent":["import { createOutput } from './createOutput';\n\nconst out = createOutput('run-tasks');\nexport type Task = { label: string; run: () => Promise<void> };\nexport type TaskFailure = { label: string; error: Error };\n\n// Run tasks with at most `limit` in flight; never rejects, failures come back\n// labelled so a whole wave can finish before we report what broke.\nexport const runTasks = async (tasks: Task[], limit: number): Promise<TaskFailure[]> => {\n const failures: TaskFailure[] = [];\n let nextIndex = 0;\n\n const workerCount = Math.max(1, Math.min(limit, tasks.length));\n await Promise.all(\n Array.from({ length: workerCount }, async () => {\n while (nextIndex < tasks.length) {\n const task = tasks[nextIndex];\n nextIndex += 1;\n if (!task) continue;\n try {\n await task.run();\n } catch (error) {\n failures.push({ label: task.label, error: error as Error });\n }\n }\n }),\n );\n\n return failures;\n};\n\nexport type DependencyTask = Task & {\n // Unique id other tasks reference in `deps` (e.g. a package name).\n id: string;\n // Ids of tasks that must succeed before this one starts. Ids not present in\n // the task list should be filtered out by the caller.\n deps: string[];\n};\n\n// Run tasks with at most `limit` in flight, but a task only starts once every\n// task in its `deps` has succeeded. A failure doesn't stop unrelated tasks;\n// dependents of the failed task are skipped (logged, not returned as failures,\n// the root cause already is). Never rejects. Tasks left unstartable by a\n// dependency cycle come back as failures.\nexport const runDependencyTasks = async (tasks: DependencyTask[], limit: number): Promise<TaskFailure[]> => {\n const failures: TaskFailure[] = [];\n const succeeded = new Set<string>();\n const failed = new Set<string>();\n const started = new Set<string>();\n const pipelines: Array<Promise<void>> = [];\n\n let slots = Math.max(1, limit);\n const waiting: Array<() => void> = [];\n\n const acquire = async (): Promise<void> => {\n if (slots > 0) {\n slots -= 1;\n return;\n }\n await new Promise<void>((resolve) => waiting.push(resolve));\n };\n\n const release = (): void => {\n const next = waiting.shift();\n if (next) {\n next();\n } else {\n slots += 1;\n }\n };\n\n const runOne = async (task: DependencyTask): Promise<void> => {\n await acquire();\n try {\n await task.run();\n succeeded.add(task.id);\n } catch (error) {\n failed.add(task.id);\n failures.push({ label: task.label, error: error as Error });\n } finally {\n release();\n }\n launchReady();\n };\n\n // Repeatedly sweep until stable: launching one task or cascading one skip can\n // unblock (or block) tasks earlier in the list.\n const launchReady = (): void => {\n let changed = true;\n while (changed) {\n changed = false;\n for (const task of tasks) {\n if (started.has(task.id)) continue;\n if (task.deps.some((dep) => failed.has(dep))) {\n started.add(task.id);\n failed.add(task.id); // cascade so transitive dependents skip too\n out.log(`Skipping ${task.label} (a dependency failed)`);\n changed = true;\n } else if (task.deps.every((dep) => succeeded.has(dep))) {\n started.add(task.id);\n pipelines.push(runOne(task));\n changed = true;\n }\n }\n }\n };\n\n launchReady();\n // runOne re-invokes launchReady as tasks finish, pushing newly unblocked\n // pipelines while earlier ones are being awaited; drain until it stays empty.\n while (pipelines.length > 0) {\n await Promise.all(pipelines.splice(0, pipelines.length));\n }\n\n for (const task of tasks) {\n if (!started.has(task.id)) {\n failures.push({ label: task.label, error: new Error('unstartable: dependency cycle') });\n }\n }\n\n return failures;\n};\n\nexport const assertNoFailures = (phaseName: string, failures: TaskFailure[]): void => {\n if (failures.length === 0) return;\n out.error(`\\n${phaseName} failed for:`);\n failures.forEach((failure) => out.error(` ${failure.label}: ${failure.error.message}`));\n throw new Error(`${phaseName}: ${failures.length} task(s) failed`);\n};\n"]}
|
package/lib/esm/lib/timing.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timing.js","sourceRoot":"","sources":["../../../src/lib/timing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"timing.js","sourceRoot":"","sources":["../../../src/lib/timing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEnE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAQ,EAAE;IAC/C,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAClD,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { createOutput } from './createOutput';\n\nconst out = createOutput('timing');\nexport const logTimeStart = (name: string): void => out.time(name);\n\nexport const logTimeEnd = (name: string): void => {\n out.log('When:', new Date().toLocaleTimeString());\n out.timeEnd(name);\n};\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { spawnCommand } from './runCommand';
|
|
2
1
|
import { getWorkspacePackageDirs } from '@qpqjs/deploy-rspack';
|
|
3
2
|
import fs from 'fs';
|
|
4
3
|
import path from 'path';
|
|
5
|
-
import { createOutput } from './
|
|
4
|
+
import { createOutput } from './createOutput';
|
|
5
|
+
import { spawnCommand } from './runCommand';
|
|
6
6
|
const out = createOutput('type-watcher');
|
|
7
7
|
// Routine tsc watch status lines; everything else is worth showing.
|
|
8
8
|
const routineTscPatterns = [/Starting compilation in watch mode/, /File change detected/, /Found 0 errors/];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typeWatcher.js","sourceRoot":"","sources":["../../../src/lib/typeWatcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"typeWatcher.js","sourceRoot":"","sources":["../../../src/lib/typeWatcher.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;AAEzC,oEAAoE;AACpE,MAAM,kBAAkB,GAAG,CAAC,oCAAoC,EAAE,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;AAE5G,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAE7G,uEAAuE;AACvE,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAQ,EAAE;IAC/C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,SAAS;QACX,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC,CAAC;AAEF,4EAA4E;AAC5E,4EAA4E;AAC5E,sDAAsD;AACtD,MAAM,uBAAuB,GAAG,CAAC,GAAW,EAAW,EAAE;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IACzF,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAA0B,EAAE;IACvE,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAClF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,EAAE,SAAS,EAAE,uBAAuB,EAAE,UAAU,CAAC,EAAE;QAChH,GAAG,EAAE,IAAI;QACT,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAE3C,GAAG,CAAC,GAAG,CAAC,qCAAqC,YAAY,CAAC,MAAM,gDAAgD,CAAC,CAAC;IAElH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["// Keeps workspace packages' declaration output (dist/*.d.ts) fresh while\n// `qpq go:dev` runs. The rspack dev builds bundle workspace source directly,\n// so this watcher only feeds the editor and validate-ts, which resolve\n// cross-package types through each package's built declarations.\n//\n// One `tsc -b --watch` over every workspace package that ships types; routine\n// watch chatter is dropped so only real compile errors reach the shared\n// terminal. Opt out with `--no-types`.\nimport { Nullable } from '@qpqjs/core';\nimport { getWorkspacePackageDirs } from '@qpqjs/deploy-rspack';\n\nimport { ChildProcess } from 'child_process';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { createOutput } from './createOutput';\nimport { spawnCommand } from './runCommand';\n\nconst out = createOutput('type-watcher');\n\n// Routine tsc watch status lines; everything else is worth showing.\nconst routineTscPatterns = [/Starting compilation in watch mode/, /File change detected/, /Found 0 errors/];\n\nconst isRoutineTscLine = (line: string): boolean => routineTscPatterns.some((pattern) => pattern.test(line));\n\n// Forwards non-routine tsc output line by line under a [types] prefix.\nconst forwardTscOutput = (chunk: Buffer): void => {\n for (const line of chunk.toString().split('\\n')) {\n if (line.trim().length === 0 || isRoutineTscLine(line)) {\n continue;\n }\n out.log(`[types] ${line}`);\n }\n};\n\n// A workspace package wants declaration watching when it has a tsconfig and\n// publishes types from its build output. Packages bundled by rspack (views,\n// service handlers) don't ship types and are skipped.\nconst isTypedWorkspacePackage = (dir: string): boolean => {\n if (!fs.existsSync(path.join(dir, 'tsconfig.json'))) {\n return false;\n }\n\n const packageJson = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'));\n return !!(packageJson.types || packageJson.typings);\n};\n\nexport const startTypeWatcher = (root: string): Nullable<ChildProcess> => {\n const projectDirs = getWorkspacePackageDirs(root).filter(isTypedWorkspacePackage);\n if (projectDirs.length === 0) {\n return null;\n }\n\n const relativeDirs = projectDirs.map((dir) => path.relative(root, dir));\n const child = spawnCommand('npx', ['tsc', '-b', ...relativeDirs, '--watch', '--preserveWatchOutput', '--pretty'], {\n cwd: root,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n child.stdout?.on('data', forwardTscOutput);\n child.stderr?.on('data', forwardTscOutput);\n\n out.log(`Type watcher: tsc -b --watch over ${relativeDirs.length} workspace packages (disable with --no-types).`);\n\n return child;\n};\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { runCommandCaptureSync, runCommandSync } from './runCommand';
|
|
2
1
|
import { JavascriptRuntimeArchitecture } from '@qpqjs/core';
|
|
3
2
|
import { USER_SCRIPT_BUILDER_LAYER_MODULES } from '@qpqjs/user-script';
|
|
4
3
|
import fs from 'fs';
|
|
5
4
|
import path from 'path';
|
|
5
|
+
import { runCommandCaptureSync, runCommandSync } from './runCommand';
|
|
6
6
|
const MIN_NPM_MAJOR = 9;
|
|
7
7
|
// Lambda's layer layout: /opt/nodejs/node_modules is on the function's module path.
|
|
8
8
|
const LAYER_NODE_DIR = 'nodejs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userScriptBuilderLayer.js","sourceRoot":"","sources":["../../../src/lib/userScriptBuilderLayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"userScriptBuilderLayer.js","sourceRoot":"","sources":["../../../src/lib/userScriptBuilderLayer.ts"],"names":[],"mappings":"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","sourcesContent":["import { JavascriptRuntimeArchitecture } from '@qpqjs/core';\nimport { USER_SCRIPT_BUILDER_LAYER_MODULES } from '@qpqjs/user-script';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { runCommandCaptureSync, runCommandSync } from './runCommand';\n\nconst MIN_NPM_MAJOR = 9;\n\n// Lambda's layer layout: /opt/nodejs/node_modules is on the function's module path.\nconst LAYER_NODE_DIR = 'nodejs';\n\nconst npmCpuByArchitecture: Record<JavascriptRuntimeArchitecture, 'arm64' | 'x64'> = {\n [JavascriptRuntimeArchitecture.Arm64]: 'arm64',\n [JavascriptRuntimeArchitecture.X86_64]: 'x64',\n};\n\nexport type BuilderLayerInstallOptions = {\n outDir: string;\n architecture: JavascriptRuntimeArchitecture;\n rspackVersion: string;\n};\n\n/** The npm cpu name for a lambda architecture. */\nconst getBuilderLayerCpu = (architecture: JavascriptRuntimeArchitecture): 'arm64' | 'x64' => npmCpuByArchitecture[architecture];\n\n/**\n * The npm argv that installs rspack for linux and the lambda's cpu into the layer's\n * nodejs directory. Pure, so the exact invocation is testable without running npm.\n */\nexport const getBuilderLayerInstallArgs = ({ outDir, architecture, rspackVersion }: BuilderLayerInstallOptions): string[] => [\n 'install',\n '--prefix',\n path.join(outDir, LAYER_NODE_DIR),\n '--os=linux',\n `--cpu=${getBuilderLayerCpu(architecture)}`,\n '--libc=glibc',\n '--omit=dev',\n '--no-save',\n '--no-package-lock',\n '--no-audit',\n '--no-fund',\n `@rspack/core@${rspackVersion}`,\n];\n\nconst parseMajor = (version: string): number => parseInt(version.split('.')[0] ?? '', 10);\n\nexport type BuilderLayerRunners = {\n getNpmVersion: () => string;\n runNpm: (args: string[]) => void;\n};\n\nconst defaultRunners: BuilderLayerRunners = {\n getNpmVersion: () => runCommandCaptureSync('npm', ['--version']).trim(),\n runNpm: (args) => {\n runCommandSync('npm', args);\n },\n};\n\n/**\n * Produces the user-script builder layer directory: `<outDir>/nodejs/node_modules` holding\n * rspack and its linux binding for the lambda's cpu. Empties `outDir` first and verifies\n * the binding landed. Needs npm 9 or later for the `--os`/`--cpu` flags.\n */\nexport const buildUserScriptBuilderLayer = (options: BuilderLayerInstallOptions, runners: BuilderLayerRunners = defaultRunners): string => {\n const npmVersion = runners.getNpmVersion();\n if (parseMajor(npmVersion) < MIN_NPM_MAJOR) {\n throw new Error(`script:builder-layer needs npm ${MIN_NPM_MAJOR} or later for --os/--cpu installs; found ${npmVersion}`);\n }\n\n const nodeDir = path.join(options.outDir, LAYER_NODE_DIR);\n fs.rmSync(options.outDir, { recursive: true, force: true });\n fs.mkdirSync(nodeDir, { recursive: true });\n fs.writeFileSync(path.join(nodeDir, 'package.json'), JSON.stringify({ name: 'user-script-builder-layer', private: true }, null, 2));\n\n runners.runNpm(getBuilderLayerInstallArgs(options));\n\n const bindingDir = path.join(nodeDir, 'node_modules', '@rspack', `binding-linux-${getBuilderLayerCpu(options.architecture)}-gnu`);\n if (!fs.existsSync(bindingDir)) {\n throw new Error(`script:builder-layer: expected the rspack binding at [${bindingDir}] after install; the layer would not load on lambda`);\n }\n\n const installed = USER_SCRIPT_BUILDER_LAYER_MODULES.filter((name) => fs.existsSync(path.join(nodeDir, 'node_modules', name)));\n if (installed.length !== USER_SCRIPT_BUILDER_LAYER_MODULES.length) {\n throw new Error(\n `script:builder-layer: the layer is missing ${USER_SCRIPT_BUILDER_LAYER_MODULES.filter((name) => !installed.includes(name)).join(', ')}`,\n );\n }\n\n return nodeDir;\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
|
|
2
|
-
import { createOutput } from '../../lib/
|
|
2
|
+
import { createOutput } from '../../lib/createOutput';
|
|
3
3
|
const out = createOutput('aws:aws-credentials');
|
|
4
4
|
export const isAwsCredentialsValid = async () => {
|
|
5
5
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awsCredentials.js","sourceRoot":"","sources":["../../../../src/platforms/aws/awsCredentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"awsCredentials.js","sourceRoot":"","sources":["../../../../src/platforms/aws/awsCredentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,GAAG,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAEhD,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,IAAsB,EAAE;IAChE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,WAAW;SAChF,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';\n\nimport { createOutput } from '../../lib/createOutput';\n\nconst out = createOutput('aws:aws-credentials');\n\nexport const isAwsCredentialsValid = async (): Promise<boolean> => {\n try {\n const client = new STSClient({\n region: process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1',\n });\n await client.send(new GetCallerIdentityCommand({}));\n return true;\n } catch (error) {\n out.log('Error validating AWS credentials:', error);\n return false;\n }\n};\n"]}
|
|
@@ -10,9 +10,10 @@ import { resolveStorageDriveBucketName } from '@qpqjs/actionprocessor-aws';
|
|
|
10
10
|
// same naming utils the deployed runtime uses, so what gets emptied is
|
|
11
11
|
// exactly what the app reads and writes.
|
|
12
12
|
import { awsNamingUtils, qpqConfigAwsUtils } from '@qpqjs/config-aws';
|
|
13
|
+
import { sleep } from '@qpqjs/core';
|
|
13
14
|
import { BatchWriteItemCommand, DescribeTableCommand, DynamoDBClient, ResourceNotFoundException, ScanCommand, } from '@aws-sdk/client-dynamodb';
|
|
14
15
|
import { DeleteObjectsCommand, ListObjectVersionsCommand, NoSuchBucket, S3Client } from '@aws-sdk/client-s3';
|
|
15
|
-
import { createOutput } from '../../lib/
|
|
16
|
+
import { createOutput } from '../../lib/createOutput';
|
|
16
17
|
import { loadServiceQpqConfig } from '../../lib/qpqConfigs';
|
|
17
18
|
import { isAwsCredentialsValid } from './awsCredentials';
|
|
18
19
|
const out = createOutput('aws:clear-resources');
|
|
@@ -76,7 +77,7 @@ const truncateTable = async (tableName, region) => {
|
|
|
76
77
|
requests = unprocessed;
|
|
77
78
|
if (requests.length > 0) {
|
|
78
79
|
// Throttled - back off briefly before retrying the leftovers.
|
|
79
|
-
await
|
|
80
|
+
await sleep(250);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
}
|