quidproquo-cli 0.1.5
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/README.md +3 -0
- package/docker/cdk-deployer/Dockerfile +13 -0
- package/docker/dev-server/Dockerfile +48 -0
- package/lib/commonjs/bin/qpq.d.ts +2 -0
- package/lib/commonjs/bin/qpq.js +6 -0
- package/lib/commonjs/bin/qpq.js.map +1 -0
- package/lib/commonjs/bin/qpqCdkApp.d.ts +1 -0
- package/lib/commonjs/bin/qpqCdkApp.js +8 -0
- package/lib/commonjs/bin/qpqCdkApp.js.map +1 -0
- package/lib/commonjs/cli/index.d.ts +1 -0
- package/lib/commonjs/cli/index.js +18 -0
- package/lib/commonjs/cli/index.js.map +1 -0
- package/lib/commonjs/cli/runCli.d.ts +1 -0
- package/lib/commonjs/cli/runCli.js +80 -0
- package/lib/commonjs/cli/runCli.js.map +1 -0
- package/lib/commonjs/commands/go.d.ts +1 -0
- package/lib/commonjs/commands/go.js +28 -0
- package/lib/commonjs/commands/go.js.map +1 -0
- package/lib/commonjs/commands/goDev.d.ts +1 -0
- package/lib/commonjs/commands/goDev.js +143 -0
- package/lib/commonjs/commands/goDev.js.map +1 -0
- package/lib/commonjs/commands/goDevWeb.d.ts +1 -0
- package/lib/commonjs/commands/goDevWeb.js +122 -0
- package/lib/commonjs/commands/goDevWeb.js.map +1 -0
- package/lib/commonjs/commands/goDocker.d.ts +1 -0
- package/lib/commonjs/commands/goDocker.js +32 -0
- package/lib/commonjs/commands/goDocker.js.map +1 -0
- package/lib/commonjs/commands/hooks.d.ts +1 -0
- package/lib/commonjs/commands/hooks.js +26 -0
- package/lib/commonjs/commands/hooks.js.map +1 -0
- package/lib/commonjs/commands/prep.d.ts +1 -0
- package/lib/commonjs/commands/prep.js +28 -0
- package/lib/commonjs/commands/prep.js.map +1 -0
- package/lib/commonjs/commands/publish.d.ts +4 -0
- package/lib/commonjs/commands/publish.js +54 -0
- package/lib/commonjs/commands/publish.js.map +1 -0
- package/lib/commonjs/commands/synth.d.ts +1 -0
- package/lib/commonjs/commands/synth.js +79 -0
- package/lib/commonjs/commands/synth.js.map +1 -0
- package/lib/commonjs/commands/teardown.d.ts +1 -0
- package/lib/commonjs/commands/teardown.js +33 -0
- package/lib/commonjs/commands/teardown.js.map +1 -0
- package/lib/commonjs/index.d.ts +1 -0
- package/lib/commonjs/index.js +18 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/lib/args.d.ts +2 -0
- package/lib/commonjs/lib/args.js +21 -0
- package/lib/commonjs/lib/args.js.map +1 -0
- package/lib/commonjs/lib/deployEnv.d.ts +6 -0
- package/lib/commonjs/lib/deployEnv.js +76 -0
- package/lib/commonjs/lib/deployEnv.js.map +1 -0
- package/lib/commonjs/lib/deployPrompts.d.ts +25 -0
- package/lib/commonjs/lib/deployPrompts.js +83 -0
- package/lib/commonjs/lib/deployPrompts.js.map +1 -0
- package/lib/commonjs/lib/devServerEntry.d.ts +1 -0
- package/lib/commonjs/lib/devServerEntry.js +53 -0
- package/lib/commonjs/lib/devServerEntry.js.map +1 -0
- package/lib/commonjs/lib/discovery.d.ts +10 -0
- package/lib/commonjs/lib/discovery.js +56 -0
- package/lib/commonjs/lib/discovery.js.map +1 -0
- package/lib/commonjs/lib/hooks.d.ts +2 -0
- package/lib/commonjs/lib/hooks.js +45 -0
- package/lib/commonjs/lib/hooks.js.map +1 -0
- package/lib/commonjs/lib/packageRoot.d.ts +1 -0
- package/lib/commonjs/lib/packageRoot.js +21 -0
- package/lib/commonjs/lib/packageRoot.js.map +1 -0
- package/lib/commonjs/lib/prompts.d.ts +3 -0
- package/lib/commonjs/lib/prompts.js +64 -0
- package/lib/commonjs/lib/prompts.js.map +1 -0
- package/lib/commonjs/lib/qpqConfigs.d.ts +3 -0
- package/lib/commonjs/lib/qpqConfigs.js +19 -0
- package/lib/commonjs/lib/qpqConfigs.js.map +1 -0
- package/lib/commonjs/lib/resolveAppSelection.d.ts +6 -0
- package/lib/commonjs/lib/resolveAppSelection.js +58 -0
- package/lib/commonjs/lib/resolveAppSelection.js.map +1 -0
- package/lib/commonjs/lib/rspackRun.d.ts +2 -0
- package/lib/commonjs/lib/rspackRun.js +23 -0
- package/lib/commonjs/lib/rspackRun.js.map +1 -0
- package/lib/commonjs/lib/runCommand.d.ts +13 -0
- package/lib/commonjs/lib/runCommand.js +78 -0
- package/lib/commonjs/lib/runCommand.js.map +1 -0
- package/lib/commonjs/lib/runTasks.d.ts +10 -0
- package/lib/commonjs/lib/runTasks.js +42 -0
- package/lib/commonjs/lib/runTasks.js.map +1 -0
- package/lib/commonjs/lib/timing.d.ts +2 -0
- package/lib/commonjs/lib/timing.js +11 -0
- package/lib/commonjs/lib/timing.js.map +1 -0
- package/lib/commonjs/lib/views.d.ts +2 -0
- package/lib/commonjs/lib/views.js +32 -0
- package/lib/commonjs/lib/views.js.map +1 -0
- package/lib/commonjs/platforms/aws/awsCredentials.d.ts +1 -0
- package/lib/commonjs/platforms/aws/awsCredentials.js +28 -0
- package/lib/commonjs/platforms/aws/awsCredentials.js.map +1 -0
- package/lib/commonjs/platforms/aws/cdkApp.d.ts +2 -0
- package/lib/commonjs/platforms/aws/cdkApp.js +19 -0
- package/lib/commonjs/platforms/aws/cdkApp.js.map +1 -0
- package/lib/commonjs/platforms/aws/go.d.ts +2 -0
- package/lib/commonjs/platforms/aws/go.js +116 -0
- package/lib/commonjs/platforms/aws/go.js.map +1 -0
- package/lib/commonjs/platforms/aws/goDocker.d.ts +2 -0
- package/lib/commonjs/platforms/aws/goDocker.js +287 -0
- package/lib/commonjs/platforms/aws/goDocker.js.map +1 -0
- package/lib/commonjs/platforms/aws/identity.d.ts +2 -0
- package/lib/commonjs/platforms/aws/identity.js +26 -0
- package/lib/commonjs/platforms/aws/identity.js.map +1 -0
- package/lib/commonjs/platforms/aws/index.d.ts +2 -0
- package/lib/commonjs/platforms/aws/index.js +19 -0
- package/lib/commonjs/platforms/aws/index.js.map +1 -0
- package/lib/commonjs/platforms/aws/publish.d.ts +4 -0
- package/lib/commonjs/platforms/aws/publish.js +66 -0
- package/lib/commonjs/platforms/aws/publish.js.map +1 -0
- package/lib/commonjs/platforms/aws/remote.d.ts +11 -0
- package/lib/commonjs/platforms/aws/remote.js +106 -0
- package/lib/commonjs/platforms/aws/remote.js.map +1 -0
- package/lib/commonjs/platforms/aws/stacks.d.ts +7 -0
- package/lib/commonjs/platforms/aws/stacks.js +91 -0
- package/lib/commonjs/platforms/aws/stacks.js.map +1 -0
- package/lib/commonjs/platforms/aws/teardown.d.ts +2 -0
- package/lib/commonjs/platforms/aws/teardown.js +59 -0
- package/lib/commonjs/platforms/aws/teardown.js.map +1 -0
- package/lib/commonjs/platforms/aws/viewsSync.d.ts +2 -0
- package/lib/commonjs/platforms/aws/viewsSync.js +39 -0
- package/lib/commonjs/platforms/aws/viewsSync.js.map +1 -0
- package/lib/commonjs/platforms/docker/go.d.ts +2 -0
- package/lib/commonjs/platforms/docker/go.js +160 -0
- package/lib/commonjs/platforms/docker/go.js.map +1 -0
- package/lib/commonjs/platforms/docker/index.d.ts +2 -0
- package/lib/commonjs/platforms/docker/index.js +27 -0
- package/lib/commonjs/platforms/docker/index.js.map +1 -0
- package/lib/commonjs/platforms/index.d.ts +4 -0
- package/lib/commonjs/platforms/index.js +39 -0
- package/lib/commonjs/platforms/index.js.map +1 -0
- package/lib/commonjs/platforms/types.d.ts +16 -0
- package/lib/commonjs/platforms/types.js +9 -0
- package/lib/commonjs/platforms/types.js.map +1 -0
- package/lib/esm/bin/qpq.d.ts +2 -0
- package/lib/esm/bin/qpq.js +4 -0
- package/lib/esm/bin/qpq.js.map +1 -0
- package/lib/esm/bin/qpqCdkApp.d.ts +1 -0
- package/lib/esm/bin/qpqCdkApp.js +6 -0
- package/lib/esm/bin/qpqCdkApp.js.map +1 -0
- package/lib/esm/cli/index.d.ts +1 -0
- package/lib/esm/cli/index.js +2 -0
- package/lib/esm/cli/index.js.map +1 -0
- package/lib/esm/cli/runCli.d.ts +1 -0
- package/lib/esm/cli/runCli.js +67 -0
- package/lib/esm/cli/runCli.js.map +1 -0
- package/lib/esm/commands/go.d.ts +1 -0
- package/lib/esm/commands/go.js +15 -0
- package/lib/esm/commands/go.js.map +1 -0
- package/lib/esm/commands/goDev.d.ts +1 -0
- package/lib/esm/commands/goDev.js +127 -0
- package/lib/esm/commands/goDev.js.map +1 -0
- package/lib/esm/commands/goDevWeb.d.ts +1 -0
- package/lib/esm/commands/goDevWeb.js +107 -0
- package/lib/esm/commands/goDevWeb.js.map +1 -0
- package/lib/esm/commands/goDocker.d.ts +1 -0
- package/lib/esm/commands/goDocker.js +19 -0
- package/lib/esm/commands/goDocker.js.map +1 -0
- package/lib/esm/commands/hooks.d.ts +1 -0
- package/lib/esm/commands/hooks.js +13 -0
- package/lib/esm/commands/hooks.js.map +1 -0
- package/lib/esm/commands/prep.d.ts +1 -0
- package/lib/esm/commands/prep.js +15 -0
- package/lib/esm/commands/prep.js.map +1 -0
- package/lib/esm/commands/publish.d.ts +4 -0
- package/lib/esm/commands/publish.js +38 -0
- package/lib/esm/commands/publish.js.map +1 -0
- package/lib/esm/commands/synth.d.ts +1 -0
- package/lib/esm/commands/synth.js +63 -0
- package/lib/esm/commands/synth.js.map +1 -0
- package/lib/esm/commands/teardown.d.ts +1 -0
- package/lib/esm/commands/teardown.js +20 -0
- package/lib/esm/commands/teardown.js.map +1 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/lib/args.d.ts +2 -0
- package/lib/esm/lib/args.js +16 -0
- package/lib/esm/lib/args.js.map +1 -0
- package/lib/esm/lib/deployEnv.d.ts +6 -0
- package/lib/esm/lib/deployEnv.js +60 -0
- package/lib/esm/lib/deployEnv.js.map +1 -0
- package/lib/esm/lib/deployPrompts.d.ts +25 -0
- package/lib/esm/lib/deployPrompts.js +69 -0
- package/lib/esm/lib/deployPrompts.js.map +1 -0
- package/lib/esm/lib/devServerEntry.d.ts +1 -0
- package/lib/esm/lib/devServerEntry.js +46 -0
- package/lib/esm/lib/devServerEntry.js.map +1 -0
- package/lib/esm/lib/discovery.d.ts +10 -0
- package/lib/esm/lib/discovery.js +40 -0
- package/lib/esm/lib/discovery.js.map +1 -0
- package/lib/esm/lib/hooks.d.ts +2 -0
- package/lib/esm/lib/hooks.js +27 -0
- package/lib/esm/lib/hooks.js.map +1 -0
- package/lib/esm/lib/packageRoot.d.ts +1 -0
- package/lib/esm/lib/packageRoot.js +14 -0
- package/lib/esm/lib/packageRoot.js.map +1 -0
- package/lib/esm/lib/prompts.d.ts +3 -0
- package/lib/esm/lib/prompts.js +16 -0
- package/lib/esm/lib/prompts.js.map +1 -0
- package/lib/esm/lib/qpqConfigs.d.ts +3 -0
- package/lib/esm/lib/qpqConfigs.js +14 -0
- package/lib/esm/lib/qpqConfigs.js.map +1 -0
- package/lib/esm/lib/resolveAppSelection.d.ts +6 -0
- package/lib/esm/lib/resolveAppSelection.js +45 -0
- package/lib/esm/lib/resolveAppSelection.js.map +1 -0
- package/lib/esm/lib/rspackRun.d.ts +2 -0
- package/lib/esm/lib/rspackRun.js +19 -0
- package/lib/esm/lib/rspackRun.js.map +1 -0
- package/lib/esm/lib/runCommand.d.ts +13 -0
- package/lib/esm/lib/runCommand.js +69 -0
- package/lib/esm/lib/runCommand.js.map +1 -0
- package/lib/esm/lib/runTasks.d.ts +10 -0
- package/lib/esm/lib/runTasks.js +28 -0
- package/lib/esm/lib/runTasks.js.map +1 -0
- package/lib/esm/lib/timing.d.ts +2 -0
- package/lib/esm/lib/timing.js +6 -0
- package/lib/esm/lib/timing.js.map +1 -0
- package/lib/esm/lib/views.d.ts +2 -0
- package/lib/esm/lib/views.js +15 -0
- package/lib/esm/lib/views.js.map +1 -0
- package/lib/esm/platforms/aws/awsCredentials.d.ts +1 -0
- package/lib/esm/platforms/aws/awsCredentials.js +15 -0
- package/lib/esm/platforms/aws/awsCredentials.js.map +1 -0
- package/lib/esm/platforms/aws/cdkApp.d.ts +2 -0
- package/lib/esm/platforms/aws/cdkApp.js +11 -0
- package/lib/esm/platforms/aws/cdkApp.js.map +1 -0
- package/lib/esm/platforms/aws/go.d.ts +2 -0
- package/lib/esm/platforms/aws/go.js +100 -0
- package/lib/esm/platforms/aws/go.js.map +1 -0
- package/lib/esm/platforms/aws/goDocker.d.ts +2 -0
- package/lib/esm/platforms/aws/goDocker.js +271 -0
- package/lib/esm/platforms/aws/goDocker.js.map +1 -0
- package/lib/esm/platforms/aws/identity.d.ts +2 -0
- package/lib/esm/platforms/aws/identity.js +22 -0
- package/lib/esm/platforms/aws/identity.js.map +1 -0
- package/lib/esm/platforms/aws/index.d.ts +2 -0
- package/lib/esm/platforms/aws/index.js +16 -0
- package/lib/esm/platforms/aws/index.js.map +1 -0
- package/lib/esm/platforms/aws/publish.d.ts +4 -0
- package/lib/esm/platforms/aws/publish.js +50 -0
- package/lib/esm/platforms/aws/publish.js.map +1 -0
- package/lib/esm/platforms/aws/remote.d.ts +11 -0
- package/lib/esm/platforms/aws/remote.js +90 -0
- package/lib/esm/platforms/aws/remote.js.map +1 -0
- package/lib/esm/platforms/aws/stacks.d.ts +7 -0
- package/lib/esm/platforms/aws/stacks.js +69 -0
- package/lib/esm/platforms/aws/stacks.js.map +1 -0
- package/lib/esm/platforms/aws/teardown.d.ts +2 -0
- package/lib/esm/platforms/aws/teardown.js +46 -0
- package/lib/esm/platforms/aws/teardown.js.map +1 -0
- package/lib/esm/platforms/aws/viewsSync.d.ts +2 -0
- package/lib/esm/platforms/aws/viewsSync.js +25 -0
- package/lib/esm/platforms/aws/viewsSync.js.map +1 -0
- package/lib/esm/platforms/docker/go.d.ts +2 -0
- package/lib/esm/platforms/docker/go.js +143 -0
- package/lib/esm/platforms/docker/go.js.map +1 -0
- package/lib/esm/platforms/docker/index.d.ts +2 -0
- package/lib/esm/platforms/docker/index.js +15 -0
- package/lib/esm/platforms/docker/index.js.map +1 -0
- package/lib/esm/platforms/index.d.ts +4 -0
- package/lib/esm/platforms/index.js +20 -0
- package/lib/esm/platforms/index.js.map +1 -0
- package/lib/esm/platforms/types.d.ts +16 -0
- package/lib/esm/platforms/types.js +6 -0
- package/lib/esm/platforms/types.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.dockerGo = void 0;
|
|
16
|
+
// Docker platform deploy (`qpq go` with platform 'docker') — proof-of-concept
|
|
17
|
+
// self-hosting: bakes the QPQ dev server (a full local platform emulation)
|
|
18
|
+
// plus every service of the app and its pre-built views into one docker image.
|
|
19
|
+
//
|
|
20
|
+
// 1. Build workspace packages, then the dev-server bundle (all services).
|
|
21
|
+
// 2. Build every views microfrontend with a same-origin module-federation
|
|
22
|
+
// remote base (/views/<svc>), mirroring the AWS website/views layout.
|
|
23
|
+
// 3. Assemble an image context under dist/qpq/docker-image/<app>/ — server
|
|
24
|
+
// bundle, web root, a workspaces-stripped package.json for runtime deps,
|
|
25
|
+
// and the locally-built quidproquo packages as a vendor overlay.
|
|
26
|
+
// 4. docker build, then print the run command.
|
|
27
|
+
//
|
|
28
|
+
// Not production-grade (single process, sqlite, in-memory queues) — it's the
|
|
29
|
+
// whole product on one box with one command.
|
|
30
|
+
const quidproquo_deploy_rspack_1 = require("quidproquo-deploy-rspack");
|
|
31
|
+
const fs_1 = __importDefault(require("fs"));
|
|
32
|
+
const path_1 = __importDefault(require("path"));
|
|
33
|
+
const devServerEntry_1 = require("../../lib/devServerEntry");
|
|
34
|
+
const discovery_1 = require("../../lib/discovery");
|
|
35
|
+
const hooks_1 = require("../../lib/hooks");
|
|
36
|
+
const packageRoot_1 = require("../../lib/packageRoot");
|
|
37
|
+
const rspackRun_1 = require("../../lib/rspackRun");
|
|
38
|
+
const runCommand_1 = require("../../lib/runCommand");
|
|
39
|
+
const timing_1 = require("../../lib/timing");
|
|
40
|
+
const views_1 = require("../../lib/views");
|
|
41
|
+
const getImageContextDir = (root, appName) => path_1.default.join(root, 'dist', 'qpq', 'docker-image', appName);
|
|
42
|
+
// The consumer root package.json, stripped to what the image's npm install
|
|
43
|
+
// needs: runtime dependencies (+ overrides). Workspaces/scripts/devDeps are
|
|
44
|
+
// host-only concerns — the workspace packages themselves are bundled into the
|
|
45
|
+
// server bundle from source.
|
|
46
|
+
//
|
|
47
|
+
// quidproquo deps declared as file: refs (a consumer living beside the qpq
|
|
48
|
+
// monorepo) point outside the image context, where npm install would leave
|
|
49
|
+
// dangling symlinks — rewrite them to the vendored copies inside the context.
|
|
50
|
+
const writeImagePackageJson = (root, contextDir) => {
|
|
51
|
+
var _a, _b;
|
|
52
|
+
const rootPackageJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(root, 'package.json'), 'utf8'));
|
|
53
|
+
const dependencies = Object.assign({}, ((_a = rootPackageJson.dependencies) !== null && _a !== void 0 ? _a : {}));
|
|
54
|
+
for (const [name, version] of Object.entries(dependencies)) {
|
|
55
|
+
if (name.startsWith('quidproquo') && version.startsWith('file:')) {
|
|
56
|
+
dependencies[name] = `file:./vendor/${name}`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const imagePackageJson = {
|
|
60
|
+
name: `${rootPackageJson.name}-qpq-docker`,
|
|
61
|
+
version: (_b = rootPackageJson.version) !== null && _b !== void 0 ? _b : '0.0.0',
|
|
62
|
+
private: true,
|
|
63
|
+
dependencies,
|
|
64
|
+
overrides: rootPackageJson.overrides,
|
|
65
|
+
};
|
|
66
|
+
fs_1.default.writeFileSync(path_1.default.join(contextDir, 'package.json'), JSON.stringify(imagePackageJson, null, 2) + '\n');
|
|
67
|
+
};
|
|
68
|
+
// Copy the locally-built quidproquo packages (which may be npm-linked
|
|
69
|
+
// checkouts newer than the registry) into vendor/ so the image runs the same
|
|
70
|
+
// qpq code the bundle was built against. Follows the node_modules symlinks;
|
|
71
|
+
// lib/config only — no node_modules, no src.
|
|
72
|
+
const vendorQuidproquoPackages = (root, contextDir) => {
|
|
73
|
+
const nodeModules = path_1.default.join(root, 'node_modules');
|
|
74
|
+
const vendorDir = path_1.default.join(contextDir, 'vendor');
|
|
75
|
+
let vendored = 0;
|
|
76
|
+
for (const name of fs_1.default.readdirSync(nodeModules)) {
|
|
77
|
+
if (!name.startsWith('quidproquo'))
|
|
78
|
+
continue;
|
|
79
|
+
const packageDir = fs_1.default.realpathSync(path_1.default.join(nodeModules, name));
|
|
80
|
+
const targetDir = path_1.default.join(vendorDir, name);
|
|
81
|
+
fs_1.default.mkdirSync(targetDir, { recursive: true });
|
|
82
|
+
fs_1.default.copyFileSync(path_1.default.join(packageDir, 'package.json'), path_1.default.join(targetDir, 'package.json'));
|
|
83
|
+
for (const sub of ['lib', 'config']) {
|
|
84
|
+
const subDir = path_1.default.join(packageDir, sub);
|
|
85
|
+
if (fs_1.default.existsSync(subDir)) {
|
|
86
|
+
fs_1.default.cpSync(subDir, path_1.default.join(targetDir, sub), { recursive: true, dereference: true });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
vendored += 1;
|
|
90
|
+
}
|
|
91
|
+
return vendored;
|
|
92
|
+
};
|
|
93
|
+
const dockerGo = (appName, plan) => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
+
if (plan.kind === 'cancelled') {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (plan.kind === 'account' || plan.kind === 'bootstrap') {
|
|
98
|
+
console.log(`Nothing to do — the docker platform has no ${plan.kind} stacks.`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const root = (0, discovery_1.getRoot)();
|
|
102
|
+
const imageTag = `qpq-${appName}:${process.env.ENVIRONMENT}`;
|
|
103
|
+
// The dev server hosts every service of the app, so per-service/stack
|
|
104
|
+
// selections don't apply — the image is always the whole app.
|
|
105
|
+
console.log(`\n\nBuilding docker image [${imageTag}] — the whole app deploys as one image\n\n`);
|
|
106
|
+
(0, timing_1.logTimeStart)('totalTime');
|
|
107
|
+
yield (0, hooks_1.runAppHook)(appName, 'predeploy');
|
|
108
|
+
// Workspace packages resolve through their built dist/ (package.json main),
|
|
109
|
+
// so bundles would ship stale code unless every lib is tsc'd first.
|
|
110
|
+
console.log('Building workspace packages');
|
|
111
|
+
yield (0, runCommand_1.runCommand)('npm', ['run', 'build', '--workspaces', '--if-present']);
|
|
112
|
+
// ---- Server bundle: the dev server + every service, one main.js ----
|
|
113
|
+
console.log('Bundling server (dev server + all services)');
|
|
114
|
+
const qpqConfigs = (0, quidproquo_deploy_rspack_1.getAppServiceQpqConfigs)(root, appName);
|
|
115
|
+
const entry = (0, devServerEntry_1.writeDevServerEntry)(root, appName);
|
|
116
|
+
yield (0, rspackRun_1.runRspack)((0, quidproquo_deploy_rspack_1.getDevServerRspackConfig)({ root, entry, qpqConfigs }));
|
|
117
|
+
// ---- Views: production builds with same-origin federation remotes ----
|
|
118
|
+
process.env.QPQ_VIEWS_REMOTE_BASE = '/views';
|
|
119
|
+
const viewServices = (0, discovery_1.getServiceNamesWithViews)(appName);
|
|
120
|
+
for (const serviceName of viewServices) {
|
|
121
|
+
console.log(`Bundling views: [${serviceName}]`);
|
|
122
|
+
yield (0, views_1.bundleViews)(appName, serviceName);
|
|
123
|
+
}
|
|
124
|
+
delete process.env.QPQ_VIEWS_REMOTE_BASE;
|
|
125
|
+
// ---- Assemble the image context ----
|
|
126
|
+
console.log('Assembling image context');
|
|
127
|
+
const contextDir = getImageContextDir(root, appName);
|
|
128
|
+
fs_1.default.rmSync(contextDir, { recursive: true, force: true });
|
|
129
|
+
fs_1.default.mkdirSync(contextDir, { recursive: true });
|
|
130
|
+
fs_1.default.copyFileSync(path_1.default.join((0, packageRoot_1.getOwnPackageRoot)(), 'docker', 'dev-server', 'Dockerfile'), path_1.default.join(contextDir, 'Dockerfile'));
|
|
131
|
+
writeImagePackageJson(root, contextDir);
|
|
132
|
+
const vendored = vendorQuidproquoPackages(root, contextDir);
|
|
133
|
+
console.log(`Vendored ${vendored} quidproquo packages`);
|
|
134
|
+
fs_1.default.cpSync(path_1.default.join(root, 'dist', 'qpq', 'dev-server'), path_1.default.join(contextDir, 'server'), { recursive: true });
|
|
135
|
+
// Web root mirrors the AWS buckets: shell at website/, every views build
|
|
136
|
+
// (shell included) under views/<svc>/.
|
|
137
|
+
for (const serviceName of viewServices) {
|
|
138
|
+
const viewsDist = (0, views_1.getViewsDistDir)(appName, serviceName);
|
|
139
|
+
fs_1.default.cpSync(viewsDist, path_1.default.join(contextDir, 'web', 'views', serviceName), { recursive: true });
|
|
140
|
+
if (serviceName === 'shell') {
|
|
141
|
+
fs_1.default.cpSync(viewsDist, path_1.default.join(contextDir, 'web', 'website'), { recursive: true });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// ---- Build the image ----
|
|
145
|
+
console.log('Building docker image');
|
|
146
|
+
yield (0, runCommand_1.runCommand)('docker', ['build', '-t', imageTag, contextDir]);
|
|
147
|
+
(0, timing_1.logTimeEnd)('totalTime');
|
|
148
|
+
console.log(`
|
|
149
|
+
Done. Run it with:
|
|
150
|
+
|
|
151
|
+
docker run --rm -p 80:8080 -p 8080:8080 -p 8888:8888 -p 3001:3001 \\
|
|
152
|
+
-v qpq-${appName}-data:/app/.qpq-runtime \\
|
|
153
|
+
${imageTag}
|
|
154
|
+
|
|
155
|
+
Then open http://localhost
|
|
156
|
+
(80 serves the shell; 8080 stays mapped because the app's url resolvers call localhost:8080 for apis)
|
|
157
|
+
`);
|
|
158
|
+
});
|
|
159
|
+
exports.dockerGo = dockerGo;
|
|
160
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../../../src/platforms/docker/go.ts"],"names":[],"mappings":"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","sourcesContent":["// Docker platform deploy (`qpq go` with platform 'docker') — proof-of-concept\n// self-hosting: bakes the QPQ dev server (a full local platform emulation)\n// plus every service of the app and its pre-built views into one docker image.\n//\n// 1. Build workspace packages, then the dev-server bundle (all services).\n// 2. Build every views microfrontend with a same-origin module-federation\n// remote base (/views/<svc>), mirroring the AWS website/views layout.\n// 3. Assemble an image context under dist/qpq/docker-image/<app>/ — server\n// bundle, web root, a workspaces-stripped package.json for runtime deps,\n// and the locally-built quidproquo packages as a vendor overlay.\n// 4. docker build, then print the run command.\n//\n// Not production-grade (single process, sqlite, in-memory queues) — it's the\n// whole product on one box with one command.\nimport { getAppServiceQpqConfigs, getDevServerRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { writeDevServerEntry } from '../../lib/devServerEntry';\nimport { getRoot, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getOwnPackageRoot } from '../../lib/packageRoot';\nimport { runRspack } from '../../lib/rspackRun';\nimport { runCommand } from '../../lib/runCommand';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\n\nconst getImageContextDir = (root: string, appName: string): string => path.join(root, 'dist', 'qpq', 'docker-image', appName);\n\n// The consumer root package.json, stripped to what the image's npm install\n// needs: runtime dependencies (+ overrides). Workspaces/scripts/devDeps are\n// host-only concerns — the workspace packages themselves are bundled into the\n// server bundle from source.\n//\n// quidproquo deps declared as file: refs (a consumer living beside the qpq\n// monorepo) point outside the image context, where npm install would leave\n// dangling symlinks — rewrite them to the vendored copies inside the context.\nconst writeImagePackageJson = (root: string, contextDir: string): void => {\n const rootPackageJson = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));\n\n const dependencies: Record<string, string> = { ...(rootPackageJson.dependencies ?? {}) };\n for (const [name, version] of Object.entries(dependencies)) {\n if (name.startsWith('quidproquo') && version.startsWith('file:')) {\n dependencies[name] = `file:./vendor/${name}`;\n }\n }\n\n const imagePackageJson = {\n name: `${rootPackageJson.name}-qpq-docker`,\n version: rootPackageJson.version ?? '0.0.0',\n private: true,\n dependencies,\n overrides: rootPackageJson.overrides,\n };\n\n fs.writeFileSync(path.join(contextDir, 'package.json'), JSON.stringify(imagePackageJson, null, 2) + '\\n');\n};\n\n// Copy the locally-built quidproquo packages (which may be npm-linked\n// checkouts newer than the registry) into vendor/ so the image runs the same\n// qpq code the bundle was built against. Follows the node_modules symlinks;\n// lib/config only — no node_modules, no src.\nconst vendorQuidproquoPackages = (root: string, contextDir: string): number => {\n const nodeModules = path.join(root, 'node_modules');\n const vendorDir = path.join(contextDir, 'vendor');\n let vendored = 0;\n\n for (const name of fs.readdirSync(nodeModules)) {\n if (!name.startsWith('quidproquo')) continue;\n\n const packageDir = fs.realpathSync(path.join(nodeModules, name));\n const targetDir = path.join(vendorDir, name);\n fs.mkdirSync(targetDir, { recursive: true });\n\n fs.copyFileSync(path.join(packageDir, 'package.json'), path.join(targetDir, 'package.json'));\n for (const sub of ['lib', 'config']) {\n const subDir = path.join(packageDir, sub);\n if (fs.existsSync(subDir)) {\n fs.cpSync(subDir, path.join(targetDir, sub), { recursive: true, dereference: true });\n }\n }\n vendored += 1;\n }\n\n return vendored;\n};\n\nexport const dockerGo = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if (plan.kind === 'account' || plan.kind === 'bootstrap') {\n console.log(`Nothing to do — the docker platform has no ${plan.kind} stacks.`);\n return;\n }\n\n const root = getRoot();\n const imageTag = `qpq-${appName}:${process.env.ENVIRONMENT}`;\n\n // The dev server hosts every service of the app, so per-service/stack\n // selections don't apply — the image is always the whole app.\n console.log(`\\n\\nBuilding docker image [${imageTag}] — the whole app deploys as one image\\n\\n`);\n\n logTimeStart('totalTime');\n\n await runAppHook(appName, 'predeploy');\n\n // Workspace packages resolve through their built dist/ (package.json main),\n // so bundles would ship stale code unless every lib is tsc'd first.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // ---- Server bundle: the dev server + every service, one main.js ----\n console.log('Bundling server (dev server + all services)');\n const qpqConfigs = getAppServiceQpqConfigs(root, appName);\n const entry = writeDevServerEntry(root, appName);\n await runRspack(getDevServerRspackConfig({ root, entry, qpqConfigs }));\n\n // ---- Views: production builds with same-origin federation remotes ----\n process.env.QPQ_VIEWS_REMOTE_BASE = '/views';\n const viewServices = getServiceNamesWithViews(appName);\n for (const serviceName of viewServices) {\n console.log(`Bundling views: [${serviceName}]`);\n await bundleViews(appName, serviceName);\n }\n delete process.env.QPQ_VIEWS_REMOTE_BASE;\n\n // ---- Assemble the image context ----\n console.log('Assembling image context');\n const contextDir = getImageContextDir(root, appName);\n fs.rmSync(contextDir, { recursive: true, force: true });\n fs.mkdirSync(contextDir, { recursive: true });\n\n fs.copyFileSync(path.join(getOwnPackageRoot(), 'docker', 'dev-server', 'Dockerfile'), path.join(contextDir, 'Dockerfile'));\n writeImagePackageJson(root, contextDir);\n\n const vendored = vendorQuidproquoPackages(root, contextDir);\n console.log(`Vendored ${vendored} quidproquo packages`);\n\n fs.cpSync(path.join(root, 'dist', 'qpq', 'dev-server'), path.join(contextDir, 'server'), { recursive: true });\n\n // Web root mirrors the AWS buckets: shell at website/, every views build\n // (shell included) under views/<svc>/.\n for (const serviceName of viewServices) {\n const viewsDist = getViewsDistDir(appName, serviceName);\n fs.cpSync(viewsDist, path.join(contextDir, 'web', 'views', serviceName), { recursive: true });\n if (serviceName === 'shell') {\n fs.cpSync(viewsDist, path.join(contextDir, 'web', 'website'), { recursive: true });\n }\n }\n\n // ---- Build the image ----\n console.log('Building docker image');\n await runCommand('docker', ['build', '-t', imageTag, contextDir]);\n\n logTimeEnd('totalTime');\n\n console.log(`\nDone. Run it with:\n\n docker run --rm -p 80:8080 -p 8080:8080 -p 8888:8888 -p 3001:3001 \\\\\n -v qpq-${appName}-data:/app/.qpq-runtime \\\\\n ${imageTag}\n\nThen open http://localhost\n(80 serves the shell; 8080 stays mapped because the app's url resolvers call localhost:8080 for apis)\n`);\n};\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.dockerPlatformDriver = void 0;
|
|
13
|
+
const go_1 = require("./go");
|
|
14
|
+
const publishNotSupported = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
console.error('The docker platform has no federated code store — story code is baked into the image. Rebuild with qpq go instead.');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
exports.dockerPlatformDriver = {
|
|
19
|
+
// The docker platform needs no deploy identity — everything runs in-image.
|
|
20
|
+
primeDeployIdentity: () => [],
|
|
21
|
+
go: go_1.dockerGo,
|
|
22
|
+
publish: publishNotSupported,
|
|
23
|
+
publishBuild: publishNotSupported,
|
|
24
|
+
publishUpload: publishNotSupported,
|
|
25
|
+
publishDeploy: publishNotSupported,
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/platforms/docker/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,6BAAgC;AAEhC,MAAM,mBAAmB,GAAG,GAAwB,EAAE;IACpD,OAAO,CAAC,KAAK,CAAC,oHAAoH,CAAC,CAAC;IACpI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAA,CAAC;AAEW,QAAA,oBAAoB,GAAsB;IACrD,2EAA2E;IAC3E,mBAAmB,EAAE,GAAG,EAAE,CAAC,EAAE;IAE7B,EAAE,EAAE,aAAQ;IAEZ,OAAO,EAAE,mBAAmB;IAC5B,YAAY,EAAE,mBAAmB;IACjC,aAAa,EAAE,mBAAmB;IAClC,aAAa,EAAE,mBAAmB;CACnC,CAAC","sourcesContent":["import { QpqPlatformDriver } from '../types';\nimport { dockerGo } from './go';\n\nconst publishNotSupported = async (): Promise<void> => {\n console.error('The docker platform has no federated code store — story code is baked into the image. Rebuild with qpq go instead.');\n process.exit(1);\n};\n\nexport const dockerPlatformDriver: QpqPlatformDriver = {\n // The docker platform needs no deploy identity — everything runs in-image.\n primeDeployIdentity: () => [],\n\n go: dockerGo,\n\n publish: publishNotSupported,\n publishBuild: publishNotSupported,\n publishUpload: publishNotSupported,\n publishDeploy: publishNotSupported,\n};\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.getPlatformDriver = exports.findPlatformDriver = void 0;
|
|
18
|
+
const aws_1 = require("./aws");
|
|
19
|
+
const docker_1 = require("./docker");
|
|
20
|
+
const types_1 = require("./types");
|
|
21
|
+
const platformDrivers = {
|
|
22
|
+
[types_1.QpqDeployPlatform.aws]: aws_1.awsPlatformDriver,
|
|
23
|
+
[types_1.QpqDeployPlatform.docker]: docker_1.dockerPlatformDriver,
|
|
24
|
+
};
|
|
25
|
+
// Lenient lookup for best-effort paths (local dev priming) — undefined when
|
|
26
|
+
// the platform isn't known, never exits.
|
|
27
|
+
const findPlatformDriver = (platform) => platformDrivers[platform];
|
|
28
|
+
exports.findPlatformDriver = findPlatformDriver;
|
|
29
|
+
const getPlatformDriver = (platform) => {
|
|
30
|
+
const driver = (0, exports.findPlatformDriver)(platform);
|
|
31
|
+
if (!driver) {
|
|
32
|
+
console.error(`Unknown deploy platform '${platform}'. Supported platforms: ${Object.keys(platformDrivers).join(', ')}`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
return driver;
|
|
36
|
+
};
|
|
37
|
+
exports.getPlatformDriver = getPlatformDriver;
|
|
38
|
+
__exportStar(require("./types"), exports);
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/platforms/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+BAA0C;AAC1C,qCAAgD;AAChD,mCAA+D;AAE/D,MAAM,eAAe,GAAsC;IACzD,CAAC,yBAAiB,CAAC,GAAG,CAAC,EAAE,uBAAiB;IAC1C,CAAC,yBAAiB,CAAC,MAAM,CAAC,EAAE,6BAAoB;CACjD,CAAC;AAEF,4EAA4E;AAC5E,yCAAyC;AAClC,MAAM,kBAAkB,GAAG,CAAC,QAAgB,EAAiC,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;AAApG,QAAA,kBAAkB,sBAAkF;AAE1G,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAqB,EAAE;IACvE,MAAM,MAAM,GAAG,IAAA,0BAAkB,EAAC,QAAQ,CAAC,CAAC;IAE5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,4BAA4B,QAAQ,2BAA2B,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AATW,QAAA,iBAAiB,qBAS5B;AAEF,0CAAwB","sourcesContent":["import { awsPlatformDriver } from './aws';\nimport { dockerPlatformDriver } from './docker';\nimport { QpqDeployPlatform, QpqPlatformDriver } from './types';\n\nconst platformDrivers: Record<string, QpqPlatformDriver> = {\n [QpqDeployPlatform.aws]: awsPlatformDriver,\n [QpqDeployPlatform.docker]: dockerPlatformDriver,\n};\n\n// Lenient lookup for best-effort paths (local dev priming) — undefined when\n// the platform isn't known, never exits.\nexport const findPlatformDriver = (platform: string): QpqPlatformDriver | undefined => platformDrivers[platform];\n\nexport const getPlatformDriver = (platform: string): QpqPlatformDriver => {\n const driver = findPlatformDriver(platform);\n\n if (!driver) {\n console.error(`Unknown deploy platform '${platform}'. Supported platforms: ${Object.keys(platformDrivers).join(', ')}`);\n process.exit(1);\n }\n\n return driver;\n};\n\nexport * from './types';\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { QpqAppDeployEnvironment } from 'quidproquo-deploy-awscdk';
|
|
2
|
+
import { DeployPlan, TeardownPlan } from '../lib/deployPrompts';
|
|
3
|
+
export declare enum QpqDeployPlatform {
|
|
4
|
+
aws = "aws",
|
|
5
|
+
docker = "docker"
|
|
6
|
+
}
|
|
7
|
+
export interface QpqPlatformDriver {
|
|
8
|
+
primeDeployIdentity: (target: QpqAppDeployEnvironment | undefined) => string[];
|
|
9
|
+
go: (appName: string, plan: DeployPlan) => Promise<void>;
|
|
10
|
+
goDocker?: (appName: string, plan: DeployPlan) => Promise<void>;
|
|
11
|
+
teardown?: (appName: string, plan: TeardownPlan) => Promise<void>;
|
|
12
|
+
publish: (appName: string, serviceNames: string[]) => Promise<void>;
|
|
13
|
+
publishBuild: (appName: string, serviceNames: string[]) => Promise<void>;
|
|
14
|
+
publishUpload: (appName: string, serviceNames: string[]) => Promise<void>;
|
|
15
|
+
publishDeploy: (appName: string, serviceNames: string[]) => Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QpqDeployPlatform = void 0;
|
|
4
|
+
var QpqDeployPlatform;
|
|
5
|
+
(function (QpqDeployPlatform) {
|
|
6
|
+
QpqDeployPlatform["aws"] = "aws";
|
|
7
|
+
QpqDeployPlatform["docker"] = "docker";
|
|
8
|
+
})(QpqDeployPlatform || (exports.QpqDeployPlatform = QpqDeployPlatform = {}));
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/platforms/types.ts"],"names":[],"mappings":";;;AAIA,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,gCAAW,CAAA;IACX,sCAAiB,CAAA;AACnB,CAAC,EAHW,iBAAiB,iCAAjB,iBAAiB,QAG5B","sourcesContent":["import { QpqAppDeployEnvironment } from 'quidproquo-deploy-awscdk';\n\nimport { DeployPlan, TeardownPlan } from '../lib/deployPrompts';\n\nexport enum QpqDeployPlatform {\n aws = 'aws',\n docker = 'docker',\n}\n\n// A deploy platform driver — everything that happens after \"what to deploy\"\n// has been decided. `qpq go` resolves the app + environment, prompts the plan,\n// then hands off here; the platform comes from the environment's entry in\n// apps/<app>/deploy.config.json (default aws), so an app can move platforms\n// with a config change instead of a different command.\nexport interface QpqPlatformDriver {\n // Prime process.env with this platform's deploy identity from the resolved\n // environment target (already-set env vars win). Service configs read these\n // vars at load time, so this runs before any infrastructure.ts is required.\n // Returns human-readable descriptions of anything still missing — deploys\n // treat that as fatal, local dev commands ignore it.\n primeDeployIdentity: (target: QpqAppDeployEnvironment | undefined) => string[];\n\n // Sequential deploy (`qpq go`).\n go: (appName: string, plan: DeployPlan) => Promise<void>;\n\n // Parallel containerized deploy (`qpq go:docker`) — optional; drivers that\n // have no docker strategy simply omit it.\n goDocker?: (appName: string, plan: DeployPlan) => Promise<void>;\n\n // Destroy the web/api/inf stacks for selected services (`qpq teardown`) —\n // optional; drivers with no teardown strategy simply omit it.\n teardown?: (appName: string, plan: TeardownPlan) => Promise<void>;\n\n // Federated remote publishing (`qpq publish[:build|:upload|:deploy]`).\n publish: (appName: string, serviceNames: string[]) => Promise<void>;\n publishBuild: (appName: string, serviceNames: string[]) => Promise<void>;\n publishUpload: (appName: string, serviceNames: string[]) => Promise<void>;\n publishDeploy: (appName: string, serviceNames: string[]) => Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qpq.js","sourceRoot":"","sources":["../../../src/bin/qpq.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { runCli } from '../cli';\n\nrunCli(process.argv.slice(2));\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// The CDK app command (`cdk ... --app "node -r ts-node/register/transpile-only <this file>"`).
|
|
2
|
+
// Runs under ts-node hooks so per-app TS config fragments and service
|
|
3
|
+
// infrastructure.ts files can be required directly.
|
|
4
|
+
import { createWorkspaceQpqCdkApp } from 'quidproquo-deploy-awscdk';
|
|
5
|
+
createWorkspaceQpqCdkApp();
|
|
6
|
+
//# sourceMappingURL=qpqCdkApp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qpqCdkApp.js","sourceRoot":"","sources":["../../../src/bin/qpqCdkApp.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,sEAAsE;AACtE,oDAAoD;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,wBAAwB,EAAE,CAAC","sourcesContent":["// The CDK app command (`cdk ... --app \"node -r ts-node/register/transpile-only <this file>\"`).\n// Runs under ts-node hooks so per-app TS config fragments and service\n// infrastructure.ts files can be required directly.\nimport { createWorkspaceQpqCdkApp } from 'quidproquo-deploy-awscdk';\n\ncreateWorkspaceQpqCdkApp();\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './runCli';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC","sourcesContent":["export * from './runCli';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const runCli: (argv: string[]) => Promise<void>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const usage = `qpq — build, dev and deploy orchestration for QPQ apps
|
|
2
|
+
|
|
3
|
+
Usage: qpq <command> [--app <name>] [--env <name>] [--platform <name>]
|
|
4
|
+
|
|
5
|
+
Commands:
|
|
6
|
+
go Deploy services (interactive; platform from deploy.config.json, default aws)
|
|
7
|
+
go:docker Same as go, but deploys in parallel via docker
|
|
8
|
+
go:dev Run the local dev server (hot reload)
|
|
9
|
+
go:dev:web Run every views microfrontend dev server
|
|
10
|
+
teardown Destroy web/api/inf stacks for selected services (interactive)
|
|
11
|
+
synth [service] Synth QPQ configs to dist/apps/<app>/infrastructure
|
|
12
|
+
prep Regenerate apps/<app>/tsconfig.federated.json
|
|
13
|
+
publish Build + upload + deploy federated remotes
|
|
14
|
+
publish:build Build federated remotes locally
|
|
15
|
+
publish:upload Upload built version dirs (nothing goes live)
|
|
16
|
+
publish:deploy Flip manifests to the uploaded versions
|
|
17
|
+
hooks <name> Run qpq:<name> in every app that defines it
|
|
18
|
+
`;
|
|
19
|
+
// Service infrastructure.ts files (and app config fragments) are TypeScript —
|
|
20
|
+
// register ts-node's transpile-only require hook so the CLI can require them
|
|
21
|
+
// directly, using the consumer root's tsconfig.json ts-node settings.
|
|
22
|
+
const registerTsNode = () => {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
24
|
+
require('ts-node').register({ transpileOnly: true });
|
|
25
|
+
};
|
|
26
|
+
export const runCli = async (argv) => {
|
|
27
|
+
const [command, ...commandArgv] = argv;
|
|
28
|
+
if (!command || command === 'help' || command === '--help') {
|
|
29
|
+
console.log(usage);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
registerTsNode();
|
|
33
|
+
// Commands are required lazily so a simple `qpq help` doesn't pay for the
|
|
34
|
+
// whole toolchain, and so ts-node is registered before any command module
|
|
35
|
+
// (or anything it requires) loads.
|
|
36
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
37
|
+
const commands = {
|
|
38
|
+
go: (a) => require('../commands/go').goCommand(a),
|
|
39
|
+
'go:docker': (a) => require('../commands/goDocker').goDockerCommand(a),
|
|
40
|
+
'go:dev': (a) => require('../commands/goDev').goDevCommand(a),
|
|
41
|
+
'go:dev:web': (a) => require('../commands/goDevWeb').goDevWebCommand(a),
|
|
42
|
+
teardown: (a) => require('../commands/teardown').teardownCommand(a),
|
|
43
|
+
synth: (a) => require('../commands/synth').synthCommand(a),
|
|
44
|
+
prep: (a) => require('../commands/prep').prepCommand(a),
|
|
45
|
+
publish: (a) => require('../commands/publish').publishCommand(a),
|
|
46
|
+
'publish:build': (a) => require('../commands/publish').publishBuildCommand(a),
|
|
47
|
+
'publish:upload': (a) => require('../commands/publish').publishUploadCommand(a),
|
|
48
|
+
'publish:deploy': (a) => require('../commands/publish').publishDeployCommand(a),
|
|
49
|
+
hooks: (a) => require('../commands/hooks').hooksCommand(a),
|
|
50
|
+
};
|
|
51
|
+
/* eslint-enable @typescript-eslint/no-require-imports */
|
|
52
|
+
const run = commands[command];
|
|
53
|
+
if (!run) {
|
|
54
|
+
console.error(`Unknown command: ${command}`);
|
|
55
|
+
console.log(usage);
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await run(commandArgv);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(`qpq ${command} failed:`, error);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=runCli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runCli.js","sourceRoot":"","sources":["../../../src/cli/runCli.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;CAiBb,CAAC;AAEF,8EAA8E;AAC9E,6EAA6E;AAC7E,sEAAsE;AACtE,MAAM,cAAc,GAAG,GAAS,EAAE;IAChC,iEAAiE;IACjE,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,IAAc,EAAiB,EAAE;IAC5D,MAAM,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,GAAG,IAAI,CAAC;IAEvC,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,cAAc,EAAE,CAAC;IAEjB,0EAA0E;IAC1E,0EAA0E;IAC1E,mCAAmC;IACnC,0DAA0D;IAC1D,MAAM,QAAQ,GAA6D;QACzE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACjD,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACtE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QAC7D,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACvE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACnE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QAC1D,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QACvD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;QAChE,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7E,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC/E,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAC/E,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;KAC3D,CAAC;IACF,yDAAyD;IAEzD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,WAAW,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,OAAO,OAAO,UAAU,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC","sourcesContent":["const usage = `qpq — build, dev and deploy orchestration for QPQ apps\n\nUsage: qpq <command> [--app <name>] [--env <name>] [--platform <name>]\n\nCommands:\n go Deploy services (interactive; platform from deploy.config.json, default aws)\n go:docker Same as go, but deploys in parallel via docker\n go:dev Run the local dev server (hot reload)\n go:dev:web Run every views microfrontend dev server\n teardown Destroy web/api/inf stacks for selected services (interactive)\n synth [service] Synth QPQ configs to dist/apps/<app>/infrastructure\n prep Regenerate apps/<app>/tsconfig.federated.json\n publish Build + upload + deploy federated remotes\n publish:build Build federated remotes locally\n publish:upload Upload built version dirs (nothing goes live)\n publish:deploy Flip manifests to the uploaded versions\n hooks <name> Run qpq:<name> in every app that defines it\n`;\n\n// Service infrastructure.ts files (and app config fragments) are TypeScript —\n// register ts-node's transpile-only require hook so the CLI can require them\n// directly, using the consumer root's tsconfig.json ts-node settings.\nconst registerTsNode = (): void => {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n require('ts-node').register({ transpileOnly: true });\n};\n\nexport const runCli = async (argv: string[]): Promise<void> => {\n const [command, ...commandArgv] = argv;\n\n if (!command || command === 'help' || command === '--help') {\n console.log(usage);\n return;\n }\n\n registerTsNode();\n\n // Commands are required lazily so a simple `qpq help` doesn't pay for the\n // whole toolchain, and so ts-node is registered before any command module\n // (or anything it requires) loads.\n /* eslint-disable @typescript-eslint/no-require-imports */\n const commands: Record<string, (commandArgv: string[]) => Promise<void>> = {\n go: (a) => require('../commands/go').goCommand(a),\n 'go:docker': (a) => require('../commands/goDocker').goDockerCommand(a),\n 'go:dev': (a) => require('../commands/goDev').goDevCommand(a),\n 'go:dev:web': (a) => require('../commands/goDevWeb').goDevWebCommand(a),\n teardown: (a) => require('../commands/teardown').teardownCommand(a),\n synth: (a) => require('../commands/synth').synthCommand(a),\n prep: (a) => require('../commands/prep').prepCommand(a),\n publish: (a) => require('../commands/publish').publishCommand(a),\n 'publish:build': (a) => require('../commands/publish').publishBuildCommand(a),\n 'publish:upload': (a) => require('../commands/publish').publishUploadCommand(a),\n 'publish:deploy': (a) => require('../commands/publish').publishDeployCommand(a),\n hooks: (a) => require('../commands/hooks').hooksCommand(a),\n };\n /* eslint-enable @typescript-eslint/no-require-imports */\n\n const run = commands[command];\n\n if (!run) {\n console.error(`Unknown command: ${command}`);\n console.log(usage);\n process.exitCode = 1;\n return;\n }\n\n try {\n await run(commandArgv);\n } catch (error) {\n console.error(`qpq ${command} failed:`, error);\n process.exitCode = 1;\n }\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const goCommand: (argv: string[]) => Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// `qpq go` — interactive deploy. Resolves the app + environment (which names
|
|
2
|
+
// the deploy platform in apps/<app>/deploy.config.json, default aws), asks the
|
|
3
|
+
// deploy plan, then hands off to the platform driver.
|
|
4
|
+
import { resolveDeployEnvironment } from '../lib/deployEnv';
|
|
5
|
+
import { promptDeployPlan } from '../lib/deployPrompts';
|
|
6
|
+
import { resolveAppSelection } from '../lib/resolveAppSelection';
|
|
7
|
+
import { getPlatformDriver } from '../platforms';
|
|
8
|
+
export const goCommand = async (argv) => {
|
|
9
|
+
const appName = await resolveAppSelection({ argv, envVar: 'DEPLOY_APP_NAME' });
|
|
10
|
+
const { platform } = await resolveDeployEnvironment(argv, appName);
|
|
11
|
+
const driver = getPlatformDriver(platform);
|
|
12
|
+
const plan = await promptDeployPlan(appName);
|
|
13
|
+
await driver.go(appName, plan);
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=go.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go.js","sourceRoot":"","sources":["../../../src/commands/go.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,+EAA+E;AAC/E,sDAAsD;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAc,EAAiB,EAAE;IAC/D,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC/E,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAE3C,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE7C,MAAM,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC,CAAC","sourcesContent":["// `qpq go` — interactive deploy. Resolves the app + environment (which names\n// the deploy platform in apps/<app>/deploy.config.json, default aws), asks the\n// deploy plan, then hands off to the platform driver.\nimport { resolveDeployEnvironment } from '../lib/deployEnv';\nimport { promptDeployPlan } from '../lib/deployPrompts';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\nimport { getPlatformDriver } from '../platforms';\n\nexport const goCommand = async (argv: string[]): Promise<void> => {\n const appName = await resolveAppSelection({ argv, envVar: 'DEPLOY_APP_NAME' });\n const { platform } = await resolveDeployEnvironment(argv, appName);\n const driver = getPlatformDriver(platform);\n\n const plan = await promptDeployPlan(appName);\n\n await driver.go(appName, plan);\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const goDevCommand: (argv: string[]) => Promise<void>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// `qpq go:dev` — boots the QPQ local dev server. Resolves the app, generates
|
|
2
|
+
// the dev-server entry, builds the rspack config, then runs rspack in watch
|
|
3
|
+
// mode, restarting the server process on every successful rebuild.
|
|
4
|
+
//
|
|
5
|
+
// The one thing NOT hot-reloaded is the qpq configs themselves: each service's
|
|
6
|
+
// infrastructure.ts is evaluated once at launch and baked into the
|
|
7
|
+
// `quidproquo-dynamic-loader` virtual module — config changes need a full
|
|
8
|
+
// `go:dev` restart.
|
|
9
|
+
import { getAppServiceQpqConfigs, getDevServerRspackConfig } from 'quidproquo-deploy-rspack';
|
|
10
|
+
import { execSync, spawn } from 'child_process';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { rspack } from '@rspack/core';
|
|
13
|
+
import { primeDeployEnvFromConfig } from '../lib/deployEnv';
|
|
14
|
+
import { writeDevServerEntry } from '../lib/devServerEntry';
|
|
15
|
+
import { getRoot } from '../lib/discovery';
|
|
16
|
+
import { resolveAppSelection } from '../lib/resolveAppSelection';
|
|
17
|
+
// 8080/8888 are set in the generated entry; 3001 is the quidproquo-dev-server
|
|
18
|
+
// file-storage (secure URL) default port.
|
|
19
|
+
const DEV_SERVER_PORTS = [8080, 8888, 3001];
|
|
20
|
+
const DEV_SERVER_BUNDLE_PATH = path.join('dist', 'qpq', 'dev-server', 'main.js');
|
|
21
|
+
// Pre-start sweep: a previous `go:dev` whose wrapper died without killing its
|
|
22
|
+
// child (closed terminal, SIGKILL) leaves an orphaned server process holding
|
|
23
|
+
// the dev ports, and the next launch dies with EADDRINUSE. Before starting,
|
|
24
|
+
// kill any listener on those ports that is running the dev-server bundle.
|
|
25
|
+
// Anything else on the ports is left alone and reported — it's not ours.
|
|
26
|
+
const killStaleDevServers = () => {
|
|
27
|
+
for (const port of DEV_SERVER_PORTS) {
|
|
28
|
+
let pids = [];
|
|
29
|
+
try {
|
|
30
|
+
pids = execSync(`lsof -t -iTCP:${port} -sTCP:LISTEN`, {
|
|
31
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
32
|
+
})
|
|
33
|
+
.toString()
|
|
34
|
+
.split('\n')
|
|
35
|
+
.map((line) => Number(line.trim()))
|
|
36
|
+
.filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
continue; // lsof exits non-zero when nothing is listening
|
|
40
|
+
}
|
|
41
|
+
for (const pid of pids) {
|
|
42
|
+
let command = '';
|
|
43
|
+
try {
|
|
44
|
+
command = execSync(`ps -p ${pid} -o command=`).toString().trim();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
continue; // already gone
|
|
48
|
+
}
|
|
49
|
+
if (command.includes(DEV_SERVER_BUNDLE_PATH)) {
|
|
50
|
+
console.log(`Killing stale dev server on port ${port} (pid ${pid})`);
|
|
51
|
+
process.kill(pid);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.warn(`Port ${port} is in use by an unrelated process (pid ${pid}: ${command}) — not killing it.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export const goDevCommand = async (argv) => {
|
|
60
|
+
const root = getRoot();
|
|
61
|
+
const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });
|
|
62
|
+
process.env.QPQ_DEV_APP = appName;
|
|
63
|
+
primeDeployEnvFromConfig(appName);
|
|
64
|
+
console.log(`Dev server for app [${appName}]`);
|
|
65
|
+
killStaleDevServers();
|
|
66
|
+
const qpqConfigs = getAppServiceQpqConfigs(root, appName);
|
|
67
|
+
const entry = writeDevServerEntry(root, appName);
|
|
68
|
+
const rspackConfig = getDevServerRspackConfig({ root, entry, qpqConfigs });
|
|
69
|
+
const bundlePath = path.join(root, DEV_SERVER_BUNDLE_PATH);
|
|
70
|
+
const env = { ...process.env, QPQ_DEV_APP: appName };
|
|
71
|
+
// The long-lived server process (HTTP 8080 / WS 8888), restarted per rebuild.
|
|
72
|
+
let child = null;
|
|
73
|
+
let restartQueued = false;
|
|
74
|
+
const startServer = () => {
|
|
75
|
+
child = spawn('node', [bundlePath], { stdio: 'inherit', env });
|
|
76
|
+
child.on('exit', (code) => {
|
|
77
|
+
child = null;
|
|
78
|
+
if (!restartQueued) {
|
|
79
|
+
// Crashed (or exited) on its own — leave it down; the next successful
|
|
80
|
+
// rebuild (i.e. the next file save) brings it back up.
|
|
81
|
+
console.log(`Dev server exited with code ${code}. Save a file to restart it.`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
const restartServer = () => {
|
|
86
|
+
if (restartQueued)
|
|
87
|
+
return;
|
|
88
|
+
if (!child) {
|
|
89
|
+
startServer();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
restartQueued = true;
|
|
93
|
+
child.once('exit', () => {
|
|
94
|
+
restartQueued = false;
|
|
95
|
+
startServer();
|
|
96
|
+
});
|
|
97
|
+
child.kill();
|
|
98
|
+
};
|
|
99
|
+
console.log('Bundling dev server (watch mode)...');
|
|
100
|
+
let lastHash;
|
|
101
|
+
const compiler = rspack(rspackConfig);
|
|
102
|
+
compiler.watch({ aggregateTimeout: 200 }, (err, stats) => {
|
|
103
|
+
if (err) {
|
|
104
|
+
console.error(err);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (stats?.hasErrors()) {
|
|
108
|
+
console.error(stats.toString({ colors: true, chunks: false, modules: false }));
|
|
109
|
+
console.log('Build failed — dev server not restarted. Fix the error and save again.');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// Skip no-op rebuilds (e.g. the virtual-module-triggered second compile at
|
|
113
|
+
// startup): only restart when the output actually changed.
|
|
114
|
+
if (stats?.hash === lastHash && child) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
lastHash = stats?.hash;
|
|
118
|
+
console.log(child ? 'Rebuilt. Restarting dev server...' : 'Dev server bundled. Starting...');
|
|
119
|
+
restartServer();
|
|
120
|
+
});
|
|
121
|
+
process.on('SIGINT', () => {
|
|
122
|
+
restartQueued = true; // suppress the crash log / rebuild-restart on our own kill
|
|
123
|
+
child?.kill();
|
|
124
|
+
compiler.close(() => process.exit(0));
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=goDev.js.map
|