quidproquo-cli 0.1.10 → 0.1.12

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.
@@ -38,7 +38,7 @@ const goDevCommand = (argv) => __awaiter(void 0, void 0, void 0, function* () {
38
38
  console.log('No views projects found. Running the API dev server only.');
39
39
  return;
40
40
  }
41
- yield (0, goDevWeb_1.goDevWebCommand)(argv, { plainStatusLines: true });
41
+ yield (0, goDevWeb_1.goDevWebCommand)(argv, { hideStartedStatus: true });
42
42
  });
43
43
  exports.goDevCommand = goDevCommand;
44
44
  //# sourceMappingURL=goDev.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"goDev.js","sourceRoot":"","sources":["../../../src/commands/goDev.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,uBAAuB;AACvB,uEAAuD;AAEvD,gDAA2C;AAC3C,oEAAiE;AACjE,oDAAsD;AACtD,yCAA6C;AAC7C,yCAA6C;AAEtC,MAAM,YAAY,GAAG,CAAO,IAAc,EAAiB,EAAE;IAClE,MAAM,OAAO,GAAG,MAAM,IAAA,yCAAmB,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC;IAElC,uEAAuE;IACvE,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,8BAAgB,EAAC,IAAA,mBAAO,GAAE,CAAC,CAAC;IACrF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,0EAA0E;IAC1E,kCAAkC;IAClC,MAAM,IAAA,0BAAe,EAAC,IAAI,CAAC,CAAC;IAE5B,IAAI,IAAA,sCAAW,EAAC,IAAA,mBAAO,GAAE,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,IAAA,0BAAe,EAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1D,CAAC,CAAA,CAAC;AArBW,QAAA,YAAY,gBAqBvB","sourcesContent":["// `qpq go:dev` — the whole local dev stack in one process: the API dev server\n// (go:dev:api) plus every views dev server (go:dev:web), so a single ctrl+c\n// tears it all down. A background tsc watcher keeps workspace declaration\n// output fresh for the editor (--no-types to skip it). The app is resolved\n// once here and handed to both sub-commands via QPQ_DEV_APP; their output\n// shares the terminal.\nimport { getAllViews } from 'quidproquo-deploy-rspack';\n\nimport { getRoot } from '../lib/discovery';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\nimport { startTypeWatcher } from '../lib/typeWatcher';\nimport { goDevApiCommand } from './goDevApi';\nimport { goDevWebCommand } from './goDevWeb';\n\nexport const goDevCommand = async (argv: string[]): Promise<void> => {\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n process.env.QPQ_DEV_APP = appName;\n\n // Editor/type freshness only: the rspack builds below bundle workspace\n // source directly, so the dev loop itself never waits on tsc.\n const typeWatcher = argv.includes('--no-types') ? null : startTypeWatcher(getRoot());\n if (typeWatcher) {\n process.on('exit', () => typeWatcher.kill());\n }\n\n // Kicks off the rspack watch and returns; the API server keeps running in\n // the background of this process.\n await goDevApiCommand(argv);\n\n if (getAllViews(getRoot(), appName).length === 0) {\n console.log('No views projects found. Running the API dev server only.');\n return;\n }\n\n await goDevWebCommand(argv, { plainStatusLines: true });\n};\n"]}
1
+ {"version":3,"file":"goDev.js","sourceRoot":"","sources":["../../../src/commands/goDev.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,uBAAuB;AACvB,uEAAuD;AAEvD,gDAA2C;AAC3C,oEAAiE;AACjE,oDAAsD;AACtD,yCAA6C;AAC7C,yCAA6C;AAEtC,MAAM,YAAY,GAAG,CAAO,IAAc,EAAiB,EAAE;IAClE,MAAM,OAAO,GAAG,MAAM,IAAA,yCAAmB,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC;IAElC,uEAAuE;IACvE,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,8BAAgB,EAAC,IAAA,mBAAO,GAAE,CAAC,CAAC;IACrF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,0EAA0E;IAC1E,kCAAkC;IAClC,MAAM,IAAA,0BAAe,EAAC,IAAI,CAAC,CAAC;IAE5B,IAAI,IAAA,sCAAW,EAAC,IAAA,mBAAO,GAAE,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,IAAA,0BAAe,EAAC,IAAI,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAA,CAAC;AArBW,QAAA,YAAY,gBAqBvB","sourcesContent":["// `qpq go:dev` — the whole local dev stack in one process: the API dev server\n// (go:dev:api) plus every views dev server (go:dev:web), so a single ctrl+c\n// tears it all down. A background tsc watcher keeps workspace declaration\n// output fresh for the editor (--no-types to skip it). The app is resolved\n// once here and handed to both sub-commands via QPQ_DEV_APP; their output\n// shares the terminal.\nimport { getAllViews } from 'quidproquo-deploy-rspack';\n\nimport { getRoot } from '../lib/discovery';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\nimport { startTypeWatcher } from '../lib/typeWatcher';\nimport { goDevApiCommand } from './goDevApi';\nimport { goDevWebCommand } from './goDevWeb';\n\nexport const goDevCommand = async (argv: string[]): Promise<void> => {\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n process.env.QPQ_DEV_APP = appName;\n\n // Editor/type freshness only: the rspack builds below bundle workspace\n // source directly, so the dev loop itself never waits on tsc.\n const typeWatcher = argv.includes('--no-types') ? null : startTypeWatcher(getRoot());\n if (typeWatcher) {\n process.on('exit', () => typeWatcher.kill());\n }\n\n // Kicks off the rspack watch and returns; the API server keeps running in\n // the background of this process.\n await goDevApiCommand(argv);\n\n if (getAllViews(getRoot(), appName).length === 0) {\n console.log('No views projects found. Running the API dev server only.');\n return;\n }\n\n await goDevWebCommand(argv, { hideStartedStatus: true });\n};\n"]}
@@ -1,4 +1,4 @@
1
1
  export type GoDevWebOptions = {
2
- plainStatusLines?: boolean;
2
+ hideStartedStatus?: boolean;
3
3
  };
4
4
  export declare const goDevWebCommand: (argv: string[], options?: GoDevWebOptions) => Promise<void>;
@@ -76,7 +76,7 @@ const goDevWebCommand = (argv_1, ...args_2) => __awaiter(void 0, [argv_1, ...arg
76
76
  };
77
77
  const markStarted = (index) => {
78
78
  const v = views[index];
79
- if (!process.stdout.isTTY || options.plainStatusLines) {
79
+ if (!process.stdout.isTTY) {
80
80
  logBelowList(` ${v.service} started`);
81
81
  return;
82
82
  }
@@ -115,7 +115,10 @@ const goDevWebCommand = (argv_1, ...args_2) => __awaiter(void 0, [argv_1, ...arg
115
115
  shutdown(1);
116
116
  return;
117
117
  }
118
- pollUntilStarted(index);
118
+ // markStarted is the only consumer of the ready signal, so there is
119
+ // nothing to poll for when the status is hidden.
120
+ if (!options.hideStartedStatus)
121
+ pollUntilStarted(index);
119
122
  }
120
123
  process.on('SIGINT', () => shutdown(0));
121
124
  process.on('SIGTERM', () => shutdown(0));
@@ -1 +1 @@
1
- {"version":3,"file":"goDevWeb.js","sourceRoot":"","sources":["../../../src/commands/goDevWeb.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:dev:web` — boots every views microfrontend's Rspack dev server\n// in-process (shell is the MF host app, plus all remotes on their own ports).\n// Everything is served dynamically; remotes resolve at runtime via\n// mf-manifest.json on localhost ports. Programmatic — no per-views\n// rspack.config.ts or npm serve script needed.\n//\n// Usage:\n// qpq go:dev:web\n// qpq go:dev:web --only shell,design\n// qpq go:dev:web --app <name>\nimport { getAllViews, getViewsRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport http from 'http';\nimport { rspack } from '@rspack/core';\nimport { RspackDevServer } from '@rspack/dev-server';\n\nimport { getArgValue } from '../lib/args';\nimport { primeDeployEnvFromConfig } from '../lib/deployEnv';\nimport { getRoot } from '../lib/discovery';\nimport { isQpqCliCommand, killStaleListeners } from '../lib/killStaleListeners';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\n\nexport type GoDevWebOptions = {\n // The in-place \"(started)\" chip rewrite assumes this command owns the\n // terminal; when stdout is shared with the API dev server (combined\n // `qpq go:dev`) the cursor math breaks, so fall back to plain lines.\n plainStatusLines?: boolean;\n};\n\nexport const goDevWebCommand = async (argv: string[], options: GoDevWebOptions = {}): Promise<void> => {\n const root = getRoot();\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n\n process.env.LOCAL_DEV_SERVER = 'true';\n process.env.NODE_ENV = 'development';\n primeDeployEnvFromConfig(appName);\n\n const only = getArgValue(argv, '--only')\n ?.split(',')\n .map((s) => s.trim());\n\n let views = getAllViews(root, appName);\n if (only) views = views.filter((v) => only.includes(v.service));\n if (views.length === 0) {\n console.error('No views projects found.');\n process.exit(1);\n }\n\n killStaleListeners(\n views.map((v) => v.port),\n isQpqCliCommand,\n );\n\n // Every RspackDevServer.start() registers its own SIGINT/SIGTERM handler on\n // process — with a dozen views servers in one process that trips node's\n // default 10-listener warning. Size the limit to the fleet.\n process.setMaxListeners(Math.max(process.getMaxListeners(), views.length * 2 + 10));\n\n // Service names are padded to a common width so the \"(started)\" chips align.\n const serviceColumnWidth = Math.max(...views.map((v) => v.service.length));\n\n console.log(`Starting ${views.length} views dev servers for [${appName}]:`);\n for (const v of views) console.log(` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)}`);\n\n const servers: RspackDevServer[] = [];\n let shuttingDown = false;\n\n const shutdown = (code: number): void => {\n if (shuttingDown) return;\n shuttingDown = true;\n Promise.allSettled(servers.map((server) => server.stop())).then(() => process.exit(code));\n };\n\n // The URL list above gets a yellow \"(started)\" chip appended in place as\n // each dev server begins answering HTTP. The in-place rewrite moves the\n // cursor up past everything printed since the list, so every line printed\n // below it MUST go through logBelowList to keep the offset accurate.\n let linesBelowList = 0;\n\n const logBelowList = (line: string): void => {\n console.log(line);\n linesBelowList += 1;\n };\n\n const markStarted = (index: number): void => {\n const v = views[index];\n if (!process.stdout.isTTY || options.plainStatusLines) {\n logBelowList(` ${v.service} started`);\n return;\n }\n const line = ` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)} \\x1b[33m(started)\\x1b[0m`;\n const up = linesBelowList + (views.length - index);\n process.stdout.write(`\\x1b[${up}F\\x1b[2K${line}\\x1b[${up}E`);\n };\n\n const pollUntilStarted = (index: number): void => {\n const attempt = (): void => {\n if (shuttingDown) return;\n const req = http.get(\n {\n host: 'localhost',\n port: views[index].port,\n path: '/',\n timeout: 1000,\n },\n (res) => {\n res.resume();\n markStarted(index);\n },\n );\n req.on('error', () => setTimeout(attempt, 500));\n req.on('timeout', () => req.destroy());\n };\n attempt();\n };\n\n for (const [index, view] of views.entries()) {\n const config = getViewsRspackConfig(view.viewsDir);\n const compiler = rspack(config);\n const server = new RspackDevServer(config.devServer || { port: view.port }, compiler);\n servers.push(server);\n\n try {\n await server.start();\n } catch (e) {\n logBelowList(` [${view.service}] failed to start: ${(e as Error).message} — shutting down all views servers.`);\n shutdown(1);\n return;\n }\n\n pollUntilStarted(index);\n }\n\n process.on('SIGINT', () => shutdown(0));\n process.on('SIGTERM', () => shutdown(0));\n};\n"]}
1
+ {"version":3,"file":"goDevWeb.js","sourceRoot":"","sources":["../../../src/commands/goDevWeb.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:dev:web` — boots every views microfrontend's Rspack dev server\n// in-process (shell is the MF host app, plus all remotes on their own ports).\n// Everything is served dynamically; remotes resolve at runtime via\n// mf-manifest.json on localhost ports. Programmatic — no per-views\n// rspack.config.ts or npm serve script needed.\n//\n// Usage:\n// qpq go:dev:web\n// qpq go:dev:web --only shell,design\n// qpq go:dev:web --app <name>\nimport { getAllViews, getViewsRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport http from 'http';\nimport { rspack } from '@rspack/core';\nimport { RspackDevServer } from '@rspack/dev-server';\n\nimport { getArgValue } from '../lib/args';\nimport { primeDeployEnvFromConfig } from '../lib/deployEnv';\nimport { getRoot } from '../lib/discovery';\nimport { isQpqCliCommand, killStaleListeners } from '../lib/killStaleListeners';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\n\nexport type GoDevWebOptions = {\n // The in-place \"(started)\" chip rewrite assumes this command owns the\n // terminal; when stdout is shared with the API dev server (combined\n // `qpq go:dev`) the cursor math breaks. The plain-line fallback is just a\n // wall of \" auth started\" noise interleaved with the API output, so drop\n // the ready status altogether there.\n hideStartedStatus?: boolean;\n};\n\nexport const goDevWebCommand = async (argv: string[], options: GoDevWebOptions = {}): Promise<void> => {\n const root = getRoot();\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n\n process.env.LOCAL_DEV_SERVER = 'true';\n process.env.NODE_ENV = 'development';\n primeDeployEnvFromConfig(appName);\n\n const only = getArgValue(argv, '--only')\n ?.split(',')\n .map((s) => s.trim());\n\n let views = getAllViews(root, appName);\n if (only) views = views.filter((v) => only.includes(v.service));\n if (views.length === 0) {\n console.error('No views projects found.');\n process.exit(1);\n }\n\n killStaleListeners(\n views.map((v) => v.port),\n isQpqCliCommand,\n );\n\n // Every RspackDevServer.start() registers its own SIGINT/SIGTERM handler on\n // process — with a dozen views servers in one process that trips node's\n // default 10-listener warning. Size the limit to the fleet.\n process.setMaxListeners(Math.max(process.getMaxListeners(), views.length * 2 + 10));\n\n // Service names are padded to a common width so the \"(started)\" chips align.\n const serviceColumnWidth = Math.max(...views.map((v) => v.service.length));\n\n console.log(`Starting ${views.length} views dev servers for [${appName}]:`);\n for (const v of views) console.log(` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)}`);\n\n const servers: RspackDevServer[] = [];\n let shuttingDown = false;\n\n const shutdown = (code: number): void => {\n if (shuttingDown) return;\n shuttingDown = true;\n Promise.allSettled(servers.map((server) => server.stop())).then(() => process.exit(code));\n };\n\n // The URL list above gets a yellow \"(started)\" chip appended in place as\n // each dev server begins answering HTTP. The in-place rewrite moves the\n // cursor up past everything printed since the list, so every line printed\n // below it MUST go through logBelowList to keep the offset accurate.\n let linesBelowList = 0;\n\n const logBelowList = (line: string): void => {\n console.log(line);\n linesBelowList += 1;\n };\n\n const markStarted = (index: number): void => {\n const v = views[index];\n if (!process.stdout.isTTY) {\n logBelowList(` ${v.service} started`);\n return;\n }\n const line = ` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)} \\x1b[33m(started)\\x1b[0m`;\n const up = linesBelowList + (views.length - index);\n process.stdout.write(`\\x1b[${up}F\\x1b[2K${line}\\x1b[${up}E`);\n };\n\n const pollUntilStarted = (index: number): void => {\n const attempt = (): void => {\n if (shuttingDown) return;\n const req = http.get(\n {\n host: 'localhost',\n port: views[index].port,\n path: '/',\n timeout: 1000,\n },\n (res) => {\n res.resume();\n markStarted(index);\n },\n );\n req.on('error', () => setTimeout(attempt, 500));\n req.on('timeout', () => req.destroy());\n };\n attempt();\n };\n\n for (const [index, view] of views.entries()) {\n const config = getViewsRspackConfig(view.viewsDir);\n const compiler = rspack(config);\n const server = new RspackDevServer(config.devServer || { port: view.port }, compiler);\n servers.push(server);\n\n try {\n await server.start();\n } catch (e) {\n logBelowList(` [${view.service}] failed to start: ${(e as Error).message} — shutting down all views servers.`);\n shutdown(1);\n return;\n }\n\n // markStarted is the only consumer of the ready signal, so there is\n // nothing to poll for when the status is hidden.\n if (!options.hideStartedStatus) pollUntilStarted(index);\n }\n\n process.on('SIGINT', () => shutdown(0));\n process.on('SIGTERM', () => shutdown(0));\n};\n"]}
@@ -119,10 +119,13 @@ const dockerDeployStack = (color, appName, serviceName, stackType, stackName) =>
119
119
  // Sync one service's pre-built views to S3 in a throwaway aws-cli container
120
120
  // named <service>-views. The official image's entrypoint is `aws`. Multiple
121
121
  // destinations (shell → website root + views prefix) run sequentially within
122
- // the service, reusing the container name.
122
+ // the service, reusing the container name. Mirrors the host-side syncViewsToS3
123
+ // cache policy: hashed assets immutable, the fixed-name entry points re-uploaded
124
+ // with no-cache every deploy (see NO_CACHE_FILES).
123
125
  const dockerSyncViews = (color, appName, serviceName) => __awaiter(void 0, void 0, void 0, function* () {
124
126
  const containerName = `${serviceName}-views`;
125
- for (const destination of (0, viewsSync_1.getViewsS3Destinations)(appName, serviceName)) {
127
+ const distDir = (0, views_1.getViewsDistDir)(appName, serviceName);
128
+ const runAwsCli = (awsArgs) => __awaiter(void 0, void 0, void 0, function* () {
126
129
  yield removeContainer(containerName);
127
130
  yield (0, runCommand_1.runCommandPrefixed)(`views:${serviceName}`, 'docker', [
128
131
  'run',
@@ -130,14 +133,28 @@ const dockerSyncViews = (color, appName, serviceName) => __awaiter(void 0, void
130
133
  '--name',
131
134
  containerName,
132
135
  '-v',
133
- `${(0, views_1.getViewsDistDir)(appName, serviceName)}:/views:ro`,
136
+ `${distDir}:/views:ro`,
134
137
  ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),
135
138
  AWS_CLI_IMAGE,
139
+ ...awsArgs,
140
+ ], { color });
141
+ });
142
+ for (const destination of (0, viewsSync_1.getViewsS3Destinations)(appName, serviceName)) {
143
+ yield runAwsCli([
136
144
  's3',
137
145
  'sync',
138
146
  '/views',
139
147
  destination,
140
- ], { color });
148
+ '--cache-control',
149
+ 'public,max-age=31536000,immutable',
150
+ ...viewsSync_1.NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
151
+ ]);
152
+ for (const file of viewsSync_1.NO_CACHE_FILES) {
153
+ if (!fs_1.default.existsSync(path_1.default.join(distDir, file))) {
154
+ continue;
155
+ }
156
+ yield runAwsCli(['s3', 'cp', `/views/${file}`, `${destination}/${file}`, '--cache-control', 'no-cache']);
157
+ }
141
158
  }
142
159
  });
143
160
  // Publish one service's already-built federated remote to S3 in a throwaway
@@ -1 +1 @@
1
- {"version":3,"file":"goDocker.js","sourceRoot":"","sources":["../../../../src/platforms/aws/goDocker.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:docker` — asks the same questions as `qpq go`, then deploys in\n// parallel via docker instead of sequentially:\n//\n// 1. Build everything locally first: QPQ config synth, rspack API bundles,\n// rspack view bundles, rspack federated-remote bundles, and one\n// self-contained CDK cloud assembly per service\n// (`cdk synth --output dist/qpq/cdk-docker/<app>/<service>`).\n// 2. Wave 1 (inf): one docker container per service deploys its inf stack,\n// all concurrently. Containers run only the CDK CLI against the mounted\n// pre-synthesized assembly — the workspace (and its npm-linked\n// quidproquo packages) never needs to exist inside the image.\n// 3. Wave 2 (api + web): once every inf stack is done, api and web stacks\n// for all services deploy concurrently (they depend only on inf, not on\n// each other).\n// 4. Views: the already-built bundles are synced to S3, one aws-cli\n// container per service, all concurrently.\n// 5. Publish: the already-built federated remotes (backends that opt in with\n// defineFederatedModuleStore(...)) are synced to S3 and their manifests\n// flipped, one aws-cli container per service, all concurrently.\n//\n// domain/bootstrap menu options deploy host-side exactly like `qpq go` —\n// a single stack gains nothing from docker.\n//\n// Requires the same env as `go` plus a running docker daemon. Knobs:\n// GO_DOCKER_BUILD_CONCURRENCY (default 4 — local builds are CPU-bound) and\n// GO_DOCKER_DEPLOY_CONCURRENCY (default unlimited — deploys just wait on\n// CloudFormation).\nimport { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\nimport { getServiceRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { synthCommand } from '../../commands/synth';\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runRspack } from '../../lib/rspackRun';\nimport { nextPrefixColor, runCommand, runCommandBestEffort, runCommandPrefixed } from '../../lib/runCommand';\nimport { assertNoFailures, runTasks } from '../../lib/runTasks';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { getCdkAppCommand, getDockerDir } from './cdkApp';\nimport { buildRemote, resolvePublishTarget } from './remote';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';\nimport { getViewsS3Destinations } from './viewsSync';\n\nconst IMAGE_TAG = 'qpq-cdk-deployer';\nconst AWS_CLI_IMAGE = 'amazon/aws-cli';\n\nconst BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;\nconst DEPLOY_CONCURRENCY = Number(process.env.GO_DOCKER_DEPLOY_CONCURRENCY) || Infinity;\n\n// Credentials/region reach the containers via `docker run -e NAME` (value\n// inherited from this process's env, never on the docker command line).\nconst AWS_ENV_PASSTHROUGH = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n 'AWS_DEFAULT_ACCOUNT',\n];\n\nconst assemblyDir = (appName: string, serviceName: string): string => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);\n\n// A container left behind by an interrupted run would block reusing its name.\n// Clear it first, best-effort: a missing container (exit 1) must not fail the\n// deploy. Was a `docker rm -f … >/dev/null 2>&1 ;` prefix on the run command,\n// but that only worked under `shell: true`; as a separate call it's shell-free.\nconst removeContainer = (containerName: string): Promise<void> => runCommandBestEffort('docker', ['rm', '-f', containerName]);\n\nconst assertDockerRunning = async (): Promise<void> => {\n try {\n await runCommand('docker', ['info', '--format', 'docker daemon ok — server {{.ServerVersion}}']);\n } catch {\n throw new Error('Docker daemon is not running (start Docker Desktop and retry).');\n }\n};\n\nconst buildDeployerImage = async (): Promise<void> => {\n // Pin the image's CDK CLI to the CLI's own aws-cdk version so it can always\n // read the assembly schema the host synthesized.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cdkVersion = require('aws-cdk/package.json').version as string;\n console.log(`Building deployer image [${IMAGE_TAG}] (aws-cdk ${cdkVersion})`);\n await runCommand('docker', ['build', '-t', IMAGE_TAG, '--build-arg', `CDK_VERSION=${cdkVersion}`, getDockerDir()]);\n};\n\n// Deploy one stack from a pre-synthesized assembly in a throwaway container\n// named <service>-<stackType> (e.g. mini-web) so `docker ps` reads cleanly.\n// The assembly mounts read-only and is copied container-local first — the CDK\n// CLI writes lock files next to the assembly it reads, and the copy keeps\n// parallel api/web deploys of the same service fully isolated.\nconst dockerDeployStack = async (\n color: number,\n appName: string,\n serviceName: string,\n stackType: 'inf' | 'api' | 'web',\n stackName: string,\n): Promise<void> => {\n const containerName = `${serviceName}-${stackType}`;\n await removeContainer(containerName);\n await runCommandPrefixed(\n `${stackType}:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${assemblyDir(appName, serviceName)}:/assembly:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n IMAGE_TAG,\n 'bash',\n '-c',\n `cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events`,\n ],\n { color },\n );\n};\n\n// Sync one service's pre-built views to S3 in a throwaway aws-cli container\n// named <service>-views. The official image's entrypoint is `aws`. Multiple\n// destinations (shell → website root + views prefix) run sequentially within\n// the service, reusing the container name.\nconst dockerSyncViews = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const containerName = `${serviceName}-views`;\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `views:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${getViewsDistDir(appName, serviceName)}:/views:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n 's3',\n 'sync',\n '/views',\n destination,\n ],\n { color },\n );\n }\n};\n\n// Publish one service's already-built federated remote to S3 in a throwaway\n// aws-cli container named <service>-publish. The version dir (everything the\n// manifest references) syncs first, then the manifest.json is copied last —\n// same ordering guarantee as the host-side publish, so a reading lambda never\n// sees a manifest whose files aren't all present yet. resolvePublishTarget reads\n// the manifest hash + resolved bucket/prefix from the buildRemote output.\nconst dockerPublishRemote = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const { publishPath, manifestHash, bucketName, servicePrefix } = resolvePublishTarget(appName, serviceName);\n const containerName = `${serviceName}-publish`;\n\n // /publish is the service-remote-published dir; the hashed version subdir and\n // manifest.json both live directly under it.\n const s3Operations: string[][] = [\n ['s3', 'sync', `/publish/${manifestHash}`, `s3://${bucketName}/${servicePrefix}/${manifestHash}`],\n ['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],\n ];\n\n for (const s3Operation of s3Operations) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `publish:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${publishPath}:/publish:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...s3Operation,\n ],\n { color },\n );\n }\n};\n\nexport const awsGoDocker = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n if (plan.kind === 'account') {\n await deployAccountStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n if (plan.kind === 'bootstrap') {\n if (plan.includeDomain) {\n await deployDomainStack(plan.appName);\n }\n await deployBootstrapStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n const { services, stacks } = plan;\n\n const allStacks = stacks === 'all';\n const needInf = allStacks || stacks === 'inf';\n const needApi = allStacks || stacks === 'api';\n const needWeb = allStacks || stacks === 'web';\n const needViews = allStacks || stacks === 'views';\n const needCdkDeploys = needInf || needApi || needWeb;\n\n const viewServices = needViews ? services.filter((s) => getServiceNamesWithViews(appName).includes(s)) : [];\n\n console.log('\\n\\nRunning dockerized deploy\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n // Federated publish needs the api stack (needApi ⇒ needCdkDeploys), so any\n // docker preflight it requires is already covered by these two checks.\n if (needCdkDeploys || viewServices.length > 0) {\n await assertDockerRunning();\n }\n if (needCdkDeploys) {\n await buildDeployerImage();\n }\n\n // ---- Phase 1: build everything locally ----\n console.log('\\n=== Phase 1: local builds ===\\n');\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. npm runs\n // the workspaces in topological order; tsc -b is incremental, so this is\n // seconds when nothing changed.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // Synth QPQ configs (shell's config resolves the view bucket names).\n // In-process (no subprocess per service) — it's just config loads + JSON writes.\n const qpqSynthServices = [...new Set([...services, ...(needViews ? ['shell'] : [])])];\n for (const service of qpqSynthServices) {\n await synthCommand([service, '--app', appName]);\n }\n\n // Federated remotes are the backend story code, so republish them whenever the\n // api stack was (re)deployed. Skips services without defineFederatedModuleStore(...).\n // Detected here (after the workspace build) because it loads each service's config.\n const federatedServices = needApi ? getServiceNamesWithFederation(appName, services) : [];\n\n // The aws-cli image backs both the views sync (phase 4) and the federated\n // publish (phase 5) waves. Pull once now so those waves don't race N containers\n // into pulling the same image. Docker is already confirmed running above.\n if (viewServices.length > 0 || federatedServices.length > 0) {\n await runCommand('docker', ['pull', AWS_CLI_IMAGE]);\n }\n\n if (stacks !== 'views') {\n assertNoFailures(\n 'API bundling',\n await runTasks(\n services.map((service) => ({\n label: `bundle-api:${service}`,\n run: async () => {\n console.log(`Bundling api: [${service}]`);\n const qpqConfig = loadServiceQpqConfig(appName, service);\n await runRspack(getServiceRspackConfig(qpqConfig, path.join(getServiceDirectory(appName, service), 'service')));\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n assertNoFailures(\n 'Views bundling',\n await runTasks(\n viewServices.map((service) => ({\n label: `bundle-views:${service}`,\n run: async () => {\n console.log(`Bundling views: [${service}]`);\n await bundleViews(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n // Build the federated remotes locally now (rspack needs the workspace), so the\n // publish wave only has to sync the already-built output — mirroring how views\n // are bundled here and synced later.\n assertNoFailures(\n 'Remote bundling',\n await runTasks(\n federatedServices.map((service) => ({\n label: `bundle-remote:${service}`,\n run: async () => {\n console.log(`Bundling federated remote: [${service}]`);\n await buildRemote(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n if (needCdkDeploys) {\n // One self-contained cloud assembly per service (all its stacks + staged\n // assets) — separate --output dirs so synths can run in parallel and\n // containers never share mutable state.\n assertNoFailures(\n 'CDK synth',\n await runTasks(\n services.map((service) => ({\n label: `cdk-synth:${service}`,\n run: async () => {\n const outputDir = assemblyDir(appName, service);\n fs.rmSync(outputDir, { recursive: true, force: true });\n await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app', getCdkAppCommand(), '--output', outputDir], {\n cwd: getRoot(),\n env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },\n color: nextPrefixColor(),\n });\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n // Stack names come from each service's live config, resolved once up front.\n const stackNames = new Map(\n services.map((service) => {\n const qpqConfig = loadServiceQpqConfig(appName, service);\n return [\n service,\n {\n inf: qpqDeployAwsCdkUtils.getInfStackName(qpqConfig),\n api: qpqDeployAwsCdkUtils.getApiStackName(qpqConfig),\n web: qpqDeployAwsCdkUtils.getWebStackName(qpqConfig),\n },\n ];\n }),\n );\n\n // ---- Phase 2: inf stacks, one container per service, all concurrent ----\n if (needInf) {\n console.log('\\n=== Phase 2: deploy inf stacks (docker) ===\\n');\n logTimeStart('infWave');\n assertNoFailures(\n 'Inf deploy',\n await runTasks(\n services.map((service) => ({\n label: `inf:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, 'inf', stackNames.get(service)!.inf),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('infWave');\n }\n\n // ---- Phase 3: api + web stacks, all concurrent ----\n if (needApi || needWeb) {\n console.log('\\n=== Phase 3: deploy api + web stacks (docker) ===\\n');\n logTimeStart('apiWebWave');\n assertNoFailures(\n 'Api/Web deploy',\n await runTasks(\n (['api', 'web'] as const)\n .filter((stackType) => (stackType === 'api' ? needApi : needWeb))\n .flatMap((stackType) =>\n services.map((service) => ({\n label: `${stackType}:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, stackType, stackNames.get(service)![stackType]),\n })),\n ),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('apiWebWave');\n }\n\n // ---- Phase 4: sync the pre-built views to S3, all concurrent ----\n if (viewServices.length > 0) {\n console.log('\\n=== Phase 4: sync views to S3 (docker) ===\\n');\n logTimeStart('viewsWave');\n assertNoFailures(\n 'Views sync',\n await runTasks(\n viewServices.map((service) => ({\n label: `views:${service}`,\n run: () => dockerSyncViews(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('viewsWave');\n }\n\n // ---- Phase 5: publish the pre-built federated remotes to S3, all concurrent ----\n if (federatedServices.length > 0) {\n console.log('\\n=== Phase 5: publish federated remotes to S3 (docker) ===\\n');\n logTimeStart('publishWave');\n assertNoFailures(\n 'Federated publish',\n await runTasks(\n federatedServices.map((service) => ({\n label: `publish:${service}`,\n run: () => dockerPublishRemote(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('publishWave');\n }\n\n logTimeEnd('totalTime');\n};\n"]}
1
+ {"version":3,"file":"goDocker.js","sourceRoot":"","sources":["../../../../src/platforms/aws/goDocker.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:docker` — asks the same questions as `qpq go`, then deploys in\n// parallel via docker instead of sequentially:\n//\n// 1. Build everything locally first: QPQ config synth, rspack API bundles,\n// rspack view bundles, rspack federated-remote bundles, and one\n// self-contained CDK cloud assembly per service\n// (`cdk synth --output dist/qpq/cdk-docker/<app>/<service>`).\n// 2. Wave 1 (inf): one docker container per service deploys its inf stack,\n// all concurrently. Containers run only the CDK CLI against the mounted\n// pre-synthesized assembly — the workspace (and its npm-linked\n// quidproquo packages) never needs to exist inside the image.\n// 3. Wave 2 (api + web): once every inf stack is done, api and web stacks\n// for all services deploy concurrently (they depend only on inf, not on\n// each other).\n// 4. Views: the already-built bundles are synced to S3, one aws-cli\n// container per service, all concurrently.\n// 5. Publish: the already-built federated remotes (backends that opt in with\n// defineFederatedModuleStore(...)) are synced to S3 and their manifests\n// flipped, one aws-cli container per service, all concurrently.\n//\n// domain/bootstrap menu options deploy host-side exactly like `qpq go` —\n// a single stack gains nothing from docker.\n//\n// Requires the same env as `go` plus a running docker daemon. Knobs:\n// GO_DOCKER_BUILD_CONCURRENCY (default 4 — local builds are CPU-bound) and\n// GO_DOCKER_DEPLOY_CONCURRENCY (default unlimited — deploys just wait on\n// CloudFormation).\nimport { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\nimport { getServiceRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { synthCommand } from '../../commands/synth';\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runRspack } from '../../lib/rspackRun';\nimport { nextPrefixColor, runCommand, runCommandBestEffort, runCommandPrefixed } from '../../lib/runCommand';\nimport { assertNoFailures, runTasks } from '../../lib/runTasks';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { getCdkAppCommand, getDockerDir } from './cdkApp';\nimport { buildRemote, resolvePublishTarget } from './remote';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';\nimport { getViewsS3Destinations, NO_CACHE_FILES } from './viewsSync';\n\nconst IMAGE_TAG = 'qpq-cdk-deployer';\nconst AWS_CLI_IMAGE = 'amazon/aws-cli';\n\nconst BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;\nconst DEPLOY_CONCURRENCY = Number(process.env.GO_DOCKER_DEPLOY_CONCURRENCY) || Infinity;\n\n// Credentials/region reach the containers via `docker run -e NAME` (value\n// inherited from this process's env, never on the docker command line).\nconst AWS_ENV_PASSTHROUGH = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n 'AWS_DEFAULT_ACCOUNT',\n];\n\nconst assemblyDir = (appName: string, serviceName: string): string => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);\n\n// A container left behind by an interrupted run would block reusing its name.\n// Clear it first, best-effort: a missing container (exit 1) must not fail the\n// deploy. Was a `docker rm -f … >/dev/null 2>&1 ;` prefix on the run command,\n// but that only worked under `shell: true`; as a separate call it's shell-free.\nconst removeContainer = (containerName: string): Promise<void> => runCommandBestEffort('docker', ['rm', '-f', containerName]);\n\nconst assertDockerRunning = async (): Promise<void> => {\n try {\n await runCommand('docker', ['info', '--format', 'docker daemon ok — server {{.ServerVersion}}']);\n } catch {\n throw new Error('Docker daemon is not running (start Docker Desktop and retry).');\n }\n};\n\nconst buildDeployerImage = async (): Promise<void> => {\n // Pin the image's CDK CLI to the CLI's own aws-cdk version so it can always\n // read the assembly schema the host synthesized.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cdkVersion = require('aws-cdk/package.json').version as string;\n console.log(`Building deployer image [${IMAGE_TAG}] (aws-cdk ${cdkVersion})`);\n await runCommand('docker', ['build', '-t', IMAGE_TAG, '--build-arg', `CDK_VERSION=${cdkVersion}`, getDockerDir()]);\n};\n\n// Deploy one stack from a pre-synthesized assembly in a throwaway container\n// named <service>-<stackType> (e.g. mini-web) so `docker ps` reads cleanly.\n// The assembly mounts read-only and is copied container-local first — the CDK\n// CLI writes lock files next to the assembly it reads, and the copy keeps\n// parallel api/web deploys of the same service fully isolated.\nconst dockerDeployStack = async (\n color: number,\n appName: string,\n serviceName: string,\n stackType: 'inf' | 'api' | 'web',\n stackName: string,\n): Promise<void> => {\n const containerName = `${serviceName}-${stackType}`;\n await removeContainer(containerName);\n await runCommandPrefixed(\n `${stackType}:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${assemblyDir(appName, serviceName)}:/assembly:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n IMAGE_TAG,\n 'bash',\n '-c',\n `cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events`,\n ],\n { color },\n );\n};\n\n// Sync one service's pre-built views to S3 in a throwaway aws-cli container\n// named <service>-views. The official image's entrypoint is `aws`. Multiple\n// destinations (shell → website root + views prefix) run sequentially within\n// the service, reusing the container name. Mirrors the host-side syncViewsToS3\n// cache policy: hashed assets immutable, the fixed-name entry points re-uploaded\n// with no-cache every deploy (see NO_CACHE_FILES).\nconst dockerSyncViews = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const containerName = `${serviceName}-views`;\n const distDir = getViewsDistDir(appName, serviceName);\n\n const runAwsCli = async (awsArgs: string[]): Promise<void> => {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `views:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${distDir}:/views:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...awsArgs,\n ],\n { color },\n );\n };\n\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n await runAwsCli([\n 's3',\n 'sync',\n '/views',\n destination,\n '--cache-control',\n 'public,max-age=31536000,immutable',\n ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),\n ]);\n\n for (const file of NO_CACHE_FILES) {\n if (!fs.existsSync(path.join(distDir, file))) {\n continue;\n }\n\n await runAwsCli(['s3', 'cp', `/views/${file}`, `${destination}/${file}`, '--cache-control', 'no-cache']);\n }\n }\n};\n\n// Publish one service's already-built federated remote to S3 in a throwaway\n// aws-cli container named <service>-publish. The version dir (everything the\n// manifest references) syncs first, then the manifest.json is copied last —\n// same ordering guarantee as the host-side publish, so a reading lambda never\n// sees a manifest whose files aren't all present yet. resolvePublishTarget reads\n// the manifest hash + resolved bucket/prefix from the buildRemote output.\nconst dockerPublishRemote = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const { publishPath, manifestHash, bucketName, servicePrefix } = resolvePublishTarget(appName, serviceName);\n const containerName = `${serviceName}-publish`;\n\n // /publish is the service-remote-published dir; the hashed version subdir and\n // manifest.json both live directly under it.\n const s3Operations: string[][] = [\n ['s3', 'sync', `/publish/${manifestHash}`, `s3://${bucketName}/${servicePrefix}/${manifestHash}`],\n ['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],\n ];\n\n for (const s3Operation of s3Operations) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `publish:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${publishPath}:/publish:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...s3Operation,\n ],\n { color },\n );\n }\n};\n\nexport const awsGoDocker = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n if (plan.kind === 'account') {\n await deployAccountStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n if (plan.kind === 'bootstrap') {\n if (plan.includeDomain) {\n await deployDomainStack(plan.appName);\n }\n await deployBootstrapStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n const { services, stacks } = plan;\n\n const allStacks = stacks === 'all';\n const needInf = allStacks || stacks === 'inf';\n const needApi = allStacks || stacks === 'api';\n const needWeb = allStacks || stacks === 'web';\n const needViews = allStacks || stacks === 'views';\n const needCdkDeploys = needInf || needApi || needWeb;\n\n const viewServices = needViews ? services.filter((s) => getServiceNamesWithViews(appName).includes(s)) : [];\n\n console.log('\\n\\nRunning dockerized deploy\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n // Federated publish needs the api stack (needApi ⇒ needCdkDeploys), so any\n // docker preflight it requires is already covered by these two checks.\n if (needCdkDeploys || viewServices.length > 0) {\n await assertDockerRunning();\n }\n if (needCdkDeploys) {\n await buildDeployerImage();\n }\n\n // ---- Phase 1: build everything locally ----\n console.log('\\n=== Phase 1: local builds ===\\n');\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. npm runs\n // the workspaces in topological order; tsc -b is incremental, so this is\n // seconds when nothing changed.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // Synth QPQ configs (shell's config resolves the view bucket names).\n // In-process (no subprocess per service) — it's just config loads + JSON writes.\n const qpqSynthServices = [...new Set([...services, ...(needViews ? ['shell'] : [])])];\n for (const service of qpqSynthServices) {\n await synthCommand([service, '--app', appName]);\n }\n\n // Federated remotes are the backend story code, so republish them whenever the\n // api stack was (re)deployed. Skips services without defineFederatedModuleStore(...).\n // Detected here (after the workspace build) because it loads each service's config.\n const federatedServices = needApi ? getServiceNamesWithFederation(appName, services) : [];\n\n // The aws-cli image backs both the views sync (phase 4) and the federated\n // publish (phase 5) waves. Pull once now so those waves don't race N containers\n // into pulling the same image. Docker is already confirmed running above.\n if (viewServices.length > 0 || federatedServices.length > 0) {\n await runCommand('docker', ['pull', AWS_CLI_IMAGE]);\n }\n\n if (stacks !== 'views') {\n assertNoFailures(\n 'API bundling',\n await runTasks(\n services.map((service) => ({\n label: `bundle-api:${service}`,\n run: async () => {\n console.log(`Bundling api: [${service}]`);\n const qpqConfig = loadServiceQpqConfig(appName, service);\n await runRspack(getServiceRspackConfig(qpqConfig, path.join(getServiceDirectory(appName, service), 'service')));\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n assertNoFailures(\n 'Views bundling',\n await runTasks(\n viewServices.map((service) => ({\n label: `bundle-views:${service}`,\n run: async () => {\n console.log(`Bundling views: [${service}]`);\n await bundleViews(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n // Build the federated remotes locally now (rspack needs the workspace), so the\n // publish wave only has to sync the already-built output — mirroring how views\n // are bundled here and synced later.\n assertNoFailures(\n 'Remote bundling',\n await runTasks(\n federatedServices.map((service) => ({\n label: `bundle-remote:${service}`,\n run: async () => {\n console.log(`Bundling federated remote: [${service}]`);\n await buildRemote(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n if (needCdkDeploys) {\n // One self-contained cloud assembly per service (all its stacks + staged\n // assets) — separate --output dirs so synths can run in parallel and\n // containers never share mutable state.\n assertNoFailures(\n 'CDK synth',\n await runTasks(\n services.map((service) => ({\n label: `cdk-synth:${service}`,\n run: async () => {\n const outputDir = assemblyDir(appName, service);\n fs.rmSync(outputDir, { recursive: true, force: true });\n await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app', getCdkAppCommand(), '--output', outputDir], {\n cwd: getRoot(),\n env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },\n color: nextPrefixColor(),\n });\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n // Stack names come from each service's live config, resolved once up front.\n const stackNames = new Map(\n services.map((service) => {\n const qpqConfig = loadServiceQpqConfig(appName, service);\n return [\n service,\n {\n inf: qpqDeployAwsCdkUtils.getInfStackName(qpqConfig),\n api: qpqDeployAwsCdkUtils.getApiStackName(qpqConfig),\n web: qpqDeployAwsCdkUtils.getWebStackName(qpqConfig),\n },\n ];\n }),\n );\n\n // ---- Phase 2: inf stacks, one container per service, all concurrent ----\n if (needInf) {\n console.log('\\n=== Phase 2: deploy inf stacks (docker) ===\\n');\n logTimeStart('infWave');\n assertNoFailures(\n 'Inf deploy',\n await runTasks(\n services.map((service) => ({\n label: `inf:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, 'inf', stackNames.get(service)!.inf),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('infWave');\n }\n\n // ---- Phase 3: api + web stacks, all concurrent ----\n if (needApi || needWeb) {\n console.log('\\n=== Phase 3: deploy api + web stacks (docker) ===\\n');\n logTimeStart('apiWebWave');\n assertNoFailures(\n 'Api/Web deploy',\n await runTasks(\n (['api', 'web'] as const)\n .filter((stackType) => (stackType === 'api' ? needApi : needWeb))\n .flatMap((stackType) =>\n services.map((service) => ({\n label: `${stackType}:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, stackType, stackNames.get(service)![stackType]),\n })),\n ),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('apiWebWave');\n }\n\n // ---- Phase 4: sync the pre-built views to S3, all concurrent ----\n if (viewServices.length > 0) {\n console.log('\\n=== Phase 4: sync views to S3 (docker) ===\\n');\n logTimeStart('viewsWave');\n assertNoFailures(\n 'Views sync',\n await runTasks(\n viewServices.map((service) => ({\n label: `views:${service}`,\n run: () => dockerSyncViews(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('viewsWave');\n }\n\n // ---- Phase 5: publish the pre-built federated remotes to S3, all concurrent ----\n if (federatedServices.length > 0) {\n console.log('\\n=== Phase 5: publish federated remotes to S3 (docker) ===\\n');\n logTimeStart('publishWave');\n assertNoFailures(\n 'Federated publish',\n await runTasks(\n federatedServices.map((service) => ({\n label: `publish:${service}`,\n run: () => dockerPublishRemote(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('publishWave');\n }\n\n logTimeEnd('totalTime');\n};\n"]}
@@ -1,2 +1,3 @@
1
+ export declare const NO_CACHE_FILES: string[];
1
2
  export declare const getViewsS3Destinations: (appName: string, serviceName: string) => string[];
2
3
  export declare const syncViewsToS3: (appName: string, serviceName: string) => Promise<void>;
@@ -8,16 +8,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.syncViewsToS3 = exports.getViewsS3Destinations = void 0;
15
+ exports.syncViewsToS3 = exports.getViewsS3Destinations = exports.NO_CACHE_FILES = void 0;
13
16
  // Views upload to S3. Bucket names resolve from the shell service's config.
14
17
  // shell is the module-federation host: its bundle is the root website, so it
15
18
  // syncs to the 'website' bucket root AND to its prefix in the shared 'views'
16
19
  // bucket (where every other service's views live).
17
20
  const quidproquo_actionprocessor_awslambda_1 = require("quidproquo-actionprocessor-awslambda");
21
+ const fs_1 = __importDefault(require("fs"));
22
+ const path_1 = __importDefault(require("path"));
18
23
  const qpqConfigs_1 = require("../../lib/qpqConfigs");
19
24
  const runCommand_1 = require("../../lib/runCommand");
20
25
  const views_1 = require("../../lib/views");
26
+ // The mutable entry points: fixed names whose CONTENT changes every deploy. They
27
+ // must never be cached without revalidation — a browser holding a stale
28
+ // mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle
29
+ // (the module-reload hot-swap and plain page refreshes both depend on these being
30
+ // fresh). Everything else in a views dist is content-hashed and safely immutable.
31
+ exports.NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];
21
32
  const getViewsS3Destinations = (appName, serviceName) => {
22
33
  const shellConfig = (0, qpqConfigs_1.loadServiceQpqConfig)(appName, 'shell');
23
34
  const viewsBucketName = quidproquo_actionprocessor_awslambda_1.awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);
@@ -30,9 +41,27 @@ const getViewsS3Destinations = (appName, serviceName) => {
30
41
  };
31
42
  exports.getViewsS3Destinations = getViewsS3Destinations;
32
43
  const syncViewsToS3 = (appName, serviceName) => __awaiter(void 0, void 0, void 0, function* () {
44
+ const distDir = (0, views_1.getViewsDistDir)(appName, serviceName);
33
45
  for (const destination of (0, exports.getViewsS3Destinations)(appName, serviceName)) {
34
46
  console.log(`Copying [${serviceName}] views to [${destination}]`);
35
- yield (0, runCommand_1.runCommand)('aws', ['s3', 'sync', (0, views_1.getViewsDistDir)(appName, serviceName), destination]);
47
+ // Content-hashed assets: cache forever.
48
+ yield (0, runCommand_1.runCommand)('aws', [
49
+ 's3',
50
+ 'sync',
51
+ distDir,
52
+ destination,
53
+ '--cache-control',
54
+ 'public,max-age=31536000,immutable',
55
+ ...exports.NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
56
+ ]);
57
+ // Entry points: cp (not sync) so the no-cache header is (re)applied on every
58
+ // deploy even when a body happens to be byte-identical.
59
+ for (const file of exports.NO_CACHE_FILES) {
60
+ if (!fs_1.default.existsSync(path_1.default.join(distDir, file))) {
61
+ continue;
62
+ }
63
+ yield (0, runCommand_1.runCommand)('aws', ['s3', 'cp', path_1.default.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);
64
+ }
36
65
  }
37
66
  });
38
67
  exports.syncViewsToS3 = syncViewsToS3;
@@ -1 +1 @@
1
- {"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,mDAAmD;AACnD,+FAAsE;AAEtE,qDAA4D;AAC5D,qDAAkD;AAClD,2CAAkD;AAE3C,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAY,EAAE;IACvF,MAAM,WAAW,GAAG,IAAA,iCAAoB,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,qDAAc,CAAC,sCAAsC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,YAAY,GAAG,CAAC,QAAQ,eAAe,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,qDAAc,CAAC,sCAAsC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,YAAY,CAAC,IAAI,CAAC,QAAQ,iBAAiB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAZW,QAAA,sBAAsB,0BAYjC;AAEK,MAAM,aAAa,GAAG,CAAO,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACzF,KAAK,MAAM,WAAW,IAAI,IAAA,8BAAsB,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,eAAe,WAAW,GAAG,CAAC,CAAC;QAClE,MAAM,IAAA,uBAAU,EAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAA,uBAAe,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC,CAAA,CAAC;AALW,QAAA,aAAa,iBAKxB","sourcesContent":["// Views upload to S3. Bucket names resolve from the shell service's config.\n// shell is the module-federation host: its bundle is the root website, so it\n// syncs to the 'website' bucket root AND to its prefix in the shared 'views'\n// bucket (where every other service's views live).\nimport { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';\n\nimport { loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runCommand } from '../../lib/runCommand';\nimport { getViewsDistDir } from '../../lib/views';\n\nexport const getViewsS3Destinations = (appName: string, serviceName: string): string[] => {\n const shellConfig = loadServiceQpqConfig(appName, 'shell');\n const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);\n\n const destinations = [`s3://${viewsBucketName}/${serviceName}`];\n\n if (serviceName === 'shell') {\n const websiteBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('website', shellConfig);\n destinations.push(`s3://${websiteBucketName}`);\n }\n\n return destinations;\n};\n\nexport const syncViewsToS3 = async (appName: string, serviceName: string): Promise<void> => {\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n console.log(`Copying [${serviceName}] views to [${destination}]`);\n await runCommand('aws', ['s3', 'sync', getViewsDistDir(appName, serviceName), destination]);\n }\n};\n"]}
1
+ {"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,mDAAmD;AACnD,+FAAsE;AAEtE,4CAAoB;AACpB,gDAAwB;AAExB,qDAA4D;AAC5D,qDAAkD;AAClD,2CAAkD;AAElD,iFAAiF;AACjF,wEAAwE;AACxE,gFAAgF;AAChF,kFAAkF;AAClF,kFAAkF;AACrE,QAAA,cAAc,GAAG,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAE3F,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAY,EAAE;IACvF,MAAM,WAAW,GAAG,IAAA,iCAAoB,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,qDAAc,CAAC,sCAAsC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,YAAY,GAAG,CAAC,QAAQ,eAAe,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,qDAAc,CAAC,sCAAsC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,YAAY,CAAC,IAAI,CAAC,QAAQ,iBAAiB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAZW,QAAA,sBAAsB,0BAYjC;AAEK,MAAM,aAAa,GAAG,CAAO,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACzF,MAAM,OAAO,GAAG,IAAA,uBAAe,EAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEtD,KAAK,MAAM,WAAW,IAAI,IAAA,8BAAsB,EAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,eAAe,WAAW,GAAG,CAAC,CAAC;QAElE,wCAAwC;QACxC,MAAM,IAAA,uBAAU,EAAC,KAAK,EAAE;YACtB,IAAI;YACJ,MAAM;YACN,OAAO;YACP,WAAW;YACX,iBAAiB;YACjB,mCAAmC;YACnC,GAAG,sBAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;SACzD,CAAC,CAAC;QAEH,6EAA6E;QAC7E,wDAAwD;QACxD,KAAK,MAAM,IAAI,IAAI,sBAAc,EAAE,CAAC;YAClC,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;gBAC7C,SAAS;YACX,CAAC;YAED,MAAM,IAAA,uBAAU,EAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,WAAW,IAAI,IAAI,EAAE,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC;QAC3H,CAAC;IACH,CAAC;AACH,CAAC,CAAA,CAAC;AA3BW,QAAA,aAAa,iBA2BxB","sourcesContent":["// Views upload to S3. Bucket names resolve from the shell service's config.\n// shell is the module-federation host: its bundle is the root website, so it\n// syncs to the 'website' bucket root AND to its prefix in the shared 'views'\n// bucket (where every other service's views live).\nimport { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runCommand } from '../../lib/runCommand';\nimport { getViewsDistDir } from '../../lib/views';\n\n// The mutable entry points: fixed names whose CONTENT changes every deploy. They\n// must never be cached without revalidation — a browser holding a stale\n// mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle\n// (the module-reload hot-swap and plain page refreshes both depend on these being\n// fresh). Everything else in a views dist is content-hashed and safely immutable.\nexport const NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];\n\nexport const getViewsS3Destinations = (appName: string, serviceName: string): string[] => {\n const shellConfig = loadServiceQpqConfig(appName, 'shell');\n const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);\n\n const destinations = [`s3://${viewsBucketName}/${serviceName}`];\n\n if (serviceName === 'shell') {\n const websiteBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('website', shellConfig);\n destinations.push(`s3://${websiteBucketName}`);\n }\n\n return destinations;\n};\n\nexport const syncViewsToS3 = async (appName: string, serviceName: string): Promise<void> => {\n const distDir = getViewsDistDir(appName, serviceName);\n\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n console.log(`Copying [${serviceName}] views to [${destination}]`);\n\n // Content-hashed assets: cache forever.\n await runCommand('aws', [\n 's3',\n 'sync',\n distDir,\n destination,\n '--cache-control',\n 'public,max-age=31536000,immutable',\n ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),\n ]);\n\n // Entry points: cp (not sync) so the no-cache header is (re)applied on every\n // deploy even when a body happens to be byte-identical.\n for (const file of NO_CACHE_FILES) {\n if (!fs.existsSync(path.join(distDir, file))) {\n continue;\n }\n\n await runCommand('aws', ['s3', 'cp', path.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);\n }\n }\n};\n"]}
@@ -26,6 +26,6 @@ export const goDevCommand = async (argv) => {
26
26
  console.log('No views projects found. Running the API dev server only.');
27
27
  return;
28
28
  }
29
- await goDevWebCommand(argv, { plainStatusLines: true });
29
+ await goDevWebCommand(argv, { hideStartedStatus: true });
30
30
  };
31
31
  //# sourceMappingURL=goDev.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"goDev.js","sourceRoot":"","sources":["../../../src/commands/goDev.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,uBAAuB;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,IAAc,EAAiB,EAAE;IAClE,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC;IAElC,uEAAuE;IACvE,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;IACrF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,0EAA0E;IAC1E,kCAAkC;IAClC,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAE5B,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1D,CAAC,CAAC","sourcesContent":["// `qpq go:dev` — the whole local dev stack in one process: the API dev server\n// (go:dev:api) plus every views dev server (go:dev:web), so a single ctrl+c\n// tears it all down. A background tsc watcher keeps workspace declaration\n// output fresh for the editor (--no-types to skip it). The app is resolved\n// once here and handed to both sub-commands via QPQ_DEV_APP; their output\n// shares the terminal.\nimport { getAllViews } from 'quidproquo-deploy-rspack';\n\nimport { getRoot } from '../lib/discovery';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\nimport { startTypeWatcher } from '../lib/typeWatcher';\nimport { goDevApiCommand } from './goDevApi';\nimport { goDevWebCommand } from './goDevWeb';\n\nexport const goDevCommand = async (argv: string[]): Promise<void> => {\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n process.env.QPQ_DEV_APP = appName;\n\n // Editor/type freshness only: the rspack builds below bundle workspace\n // source directly, so the dev loop itself never waits on tsc.\n const typeWatcher = argv.includes('--no-types') ? null : startTypeWatcher(getRoot());\n if (typeWatcher) {\n process.on('exit', () => typeWatcher.kill());\n }\n\n // Kicks off the rspack watch and returns; the API server keeps running in\n // the background of this process.\n await goDevApiCommand(argv);\n\n if (getAllViews(getRoot(), appName).length === 0) {\n console.log('No views projects found. Running the API dev server only.');\n return;\n }\n\n await goDevWebCommand(argv, { plainStatusLines: true });\n};\n"]}
1
+ {"version":3,"file":"goDev.js","sourceRoot":"","sources":["../../../src/commands/goDev.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,uBAAuB;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,IAAc,EAAiB,EAAE;IAClE,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,OAAO,CAAC;IAElC,uEAAuE;IACvE,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;IACrF,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,0EAA0E;IAC1E,kCAAkC;IAClC,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAE5B,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC,CAAC","sourcesContent":["// `qpq go:dev` — the whole local dev stack in one process: the API dev server\n// (go:dev:api) plus every views dev server (go:dev:web), so a single ctrl+c\n// tears it all down. A background tsc watcher keeps workspace declaration\n// output fresh for the editor (--no-types to skip it). The app is resolved\n// once here and handed to both sub-commands via QPQ_DEV_APP; their output\n// shares the terminal.\nimport { getAllViews } from 'quidproquo-deploy-rspack';\n\nimport { getRoot } from '../lib/discovery';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\nimport { startTypeWatcher } from '../lib/typeWatcher';\nimport { goDevApiCommand } from './goDevApi';\nimport { goDevWebCommand } from './goDevWeb';\n\nexport const goDevCommand = async (argv: string[]): Promise<void> => {\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n process.env.QPQ_DEV_APP = appName;\n\n // Editor/type freshness only: the rspack builds below bundle workspace\n // source directly, so the dev loop itself never waits on tsc.\n const typeWatcher = argv.includes('--no-types') ? null : startTypeWatcher(getRoot());\n if (typeWatcher) {\n process.on('exit', () => typeWatcher.kill());\n }\n\n // Kicks off the rspack watch and returns; the API server keeps running in\n // the background of this process.\n await goDevApiCommand(argv);\n\n if (getAllViews(getRoot(), appName).length === 0) {\n console.log('No views projects found. Running the API dev server only.');\n return;\n }\n\n await goDevWebCommand(argv, { hideStartedStatus: true });\n};\n"]}
@@ -1,4 +1,4 @@
1
1
  export type GoDevWebOptions = {
2
- plainStatusLines?: boolean;
2
+ hideStartedStatus?: boolean;
3
3
  };
4
4
  export declare const goDevWebCommand: (argv: string[], options?: GoDevWebOptions) => Promise<void>;
@@ -62,7 +62,7 @@ export const goDevWebCommand = async (argv, options = {}) => {
62
62
  };
63
63
  const markStarted = (index) => {
64
64
  const v = views[index];
65
- if (!process.stdout.isTTY || options.plainStatusLines) {
65
+ if (!process.stdout.isTTY) {
66
66
  logBelowList(` ${v.service} started`);
67
67
  return;
68
68
  }
@@ -101,7 +101,10 @@ export const goDevWebCommand = async (argv, options = {}) => {
101
101
  shutdown(1);
102
102
  return;
103
103
  }
104
- pollUntilStarted(index);
104
+ // markStarted is the only consumer of the ready signal, so there is
105
+ // nothing to poll for when the status is hidden.
106
+ if (!options.hideStartedStatus)
107
+ pollUntilStarted(index);
105
108
  }
106
109
  process.on('SIGINT', () => shutdown(0));
107
110
  process.on('SIGTERM', () => shutdown(0));
@@ -1 +1 @@
1
- {"version":3,"file":"goDevWeb.js","sourceRoot":"","sources":["../../../src/commands/goDevWeb.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:dev:web` — boots every views microfrontend's Rspack dev server\n// in-process (shell is the MF host app, plus all remotes on their own ports).\n// Everything is served dynamically; remotes resolve at runtime via\n// mf-manifest.json on localhost ports. Programmatic — no per-views\n// rspack.config.ts or npm serve script needed.\n//\n// Usage:\n// qpq go:dev:web\n// qpq go:dev:web --only shell,design\n// qpq go:dev:web --app <name>\nimport { getAllViews, getViewsRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport http from 'http';\nimport { rspack } from '@rspack/core';\nimport { RspackDevServer } from '@rspack/dev-server';\n\nimport { getArgValue } from '../lib/args';\nimport { primeDeployEnvFromConfig } from '../lib/deployEnv';\nimport { getRoot } from '../lib/discovery';\nimport { isQpqCliCommand, killStaleListeners } from '../lib/killStaleListeners';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\n\nexport type GoDevWebOptions = {\n // The in-place \"(started)\" chip rewrite assumes this command owns the\n // terminal; when stdout is shared with the API dev server (combined\n // `qpq go:dev`) the cursor math breaks, so fall back to plain lines.\n plainStatusLines?: boolean;\n};\n\nexport const goDevWebCommand = async (argv: string[], options: GoDevWebOptions = {}): Promise<void> => {\n const root = getRoot();\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n\n process.env.LOCAL_DEV_SERVER = 'true';\n process.env.NODE_ENV = 'development';\n primeDeployEnvFromConfig(appName);\n\n const only = getArgValue(argv, '--only')\n ?.split(',')\n .map((s) => s.trim());\n\n let views = getAllViews(root, appName);\n if (only) views = views.filter((v) => only.includes(v.service));\n if (views.length === 0) {\n console.error('No views projects found.');\n process.exit(1);\n }\n\n killStaleListeners(\n views.map((v) => v.port),\n isQpqCliCommand,\n );\n\n // Every RspackDevServer.start() registers its own SIGINT/SIGTERM handler on\n // process — with a dozen views servers in one process that trips node's\n // default 10-listener warning. Size the limit to the fleet.\n process.setMaxListeners(Math.max(process.getMaxListeners(), views.length * 2 + 10));\n\n // Service names are padded to a common width so the \"(started)\" chips align.\n const serviceColumnWidth = Math.max(...views.map((v) => v.service.length));\n\n console.log(`Starting ${views.length} views dev servers for [${appName}]:`);\n for (const v of views) console.log(` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)}`);\n\n const servers: RspackDevServer[] = [];\n let shuttingDown = false;\n\n const shutdown = (code: number): void => {\n if (shuttingDown) return;\n shuttingDown = true;\n Promise.allSettled(servers.map((server) => server.stop())).then(() => process.exit(code));\n };\n\n // The URL list above gets a yellow \"(started)\" chip appended in place as\n // each dev server begins answering HTTP. The in-place rewrite moves the\n // cursor up past everything printed since the list, so every line printed\n // below it MUST go through logBelowList to keep the offset accurate.\n let linesBelowList = 0;\n\n const logBelowList = (line: string): void => {\n console.log(line);\n linesBelowList += 1;\n };\n\n const markStarted = (index: number): void => {\n const v = views[index];\n if (!process.stdout.isTTY || options.plainStatusLines) {\n logBelowList(` ${v.service} started`);\n return;\n }\n const line = ` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)} \\x1b[33m(started)\\x1b[0m`;\n const up = linesBelowList + (views.length - index);\n process.stdout.write(`\\x1b[${up}F\\x1b[2K${line}\\x1b[${up}E`);\n };\n\n const pollUntilStarted = (index: number): void => {\n const attempt = (): void => {\n if (shuttingDown) return;\n const req = http.get(\n {\n host: 'localhost',\n port: views[index].port,\n path: '/',\n timeout: 1000,\n },\n (res) => {\n res.resume();\n markStarted(index);\n },\n );\n req.on('error', () => setTimeout(attempt, 500));\n req.on('timeout', () => req.destroy());\n };\n attempt();\n };\n\n for (const [index, view] of views.entries()) {\n const config = getViewsRspackConfig(view.viewsDir);\n const compiler = rspack(config);\n const server = new RspackDevServer(config.devServer || { port: view.port }, compiler);\n servers.push(server);\n\n try {\n await server.start();\n } catch (e) {\n logBelowList(` [${view.service}] failed to start: ${(e as Error).message} — shutting down all views servers.`);\n shutdown(1);\n return;\n }\n\n pollUntilStarted(index);\n }\n\n process.on('SIGINT', () => shutdown(0));\n process.on('SIGTERM', () => shutdown(0));\n};\n"]}
1
+ {"version":3,"file":"goDevWeb.js","sourceRoot":"","sources":["../../../src/commands/goDevWeb.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:dev:web` — boots every views microfrontend's Rspack dev server\n// in-process (shell is the MF host app, plus all remotes on their own ports).\n// Everything is served dynamically; remotes resolve at runtime via\n// mf-manifest.json on localhost ports. Programmatic — no per-views\n// rspack.config.ts or npm serve script needed.\n//\n// Usage:\n// qpq go:dev:web\n// qpq go:dev:web --only shell,design\n// qpq go:dev:web --app <name>\nimport { getAllViews, getViewsRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport http from 'http';\nimport { rspack } from '@rspack/core';\nimport { RspackDevServer } from '@rspack/dev-server';\n\nimport { getArgValue } from '../lib/args';\nimport { primeDeployEnvFromConfig } from '../lib/deployEnv';\nimport { getRoot } from '../lib/discovery';\nimport { isQpqCliCommand, killStaleListeners } from '../lib/killStaleListeners';\nimport { resolveAppSelection } from '../lib/resolveAppSelection';\n\nexport type GoDevWebOptions = {\n // The in-place \"(started)\" chip rewrite assumes this command owns the\n // terminal; when stdout is shared with the API dev server (combined\n // `qpq go:dev`) the cursor math breaks. The plain-line fallback is just a\n // wall of \" auth started\" noise interleaved with the API output, so drop\n // the ready status altogether there.\n hideStartedStatus?: boolean;\n};\n\nexport const goDevWebCommand = async (argv: string[], options: GoDevWebOptions = {}): Promise<void> => {\n const root = getRoot();\n const appName = await resolveAppSelection({ argv, envVar: 'QPQ_DEV_APP' });\n\n process.env.LOCAL_DEV_SERVER = 'true';\n process.env.NODE_ENV = 'development';\n primeDeployEnvFromConfig(appName);\n\n const only = getArgValue(argv, '--only')\n ?.split(',')\n .map((s) => s.trim());\n\n let views = getAllViews(root, appName);\n if (only) views = views.filter((v) => only.includes(v.service));\n if (views.length === 0) {\n console.error('No views projects found.');\n process.exit(1);\n }\n\n killStaleListeners(\n views.map((v) => v.port),\n isQpqCliCommand,\n );\n\n // Every RspackDevServer.start() registers its own SIGINT/SIGTERM handler on\n // process — with a dozen views servers in one process that trips node's\n // default 10-listener warning. Size the limit to the fleet.\n process.setMaxListeners(Math.max(process.getMaxListeners(), views.length * 2 + 10));\n\n // Service names are padded to a common width so the \"(started)\" chips align.\n const serviceColumnWidth = Math.max(...views.map((v) => v.service.length));\n\n console.log(`Starting ${views.length} views dev servers for [${appName}]:`);\n for (const v of views) console.log(` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)}`);\n\n const servers: RspackDevServer[] = [];\n let shuttingDown = false;\n\n const shutdown = (code: number): void => {\n if (shuttingDown) return;\n shuttingDown = true;\n Promise.allSettled(servers.map((server) => server.stop())).then(() => process.exit(code));\n };\n\n // The URL list above gets a yellow \"(started)\" chip appended in place as\n // each dev server begins answering HTTP. The in-place rewrite moves the\n // cursor up past everything printed since the list, so every line printed\n // below it MUST go through logBelowList to keep the offset accurate.\n let linesBelowList = 0;\n\n const logBelowList = (line: string): void => {\n console.log(line);\n linesBelowList += 1;\n };\n\n const markStarted = (index: number): void => {\n const v = views[index];\n if (!process.stdout.isTTY) {\n logBelowList(` ${v.service} started`);\n return;\n }\n const line = ` http://localhost:${v.port} ${v.service.padEnd(serviceColumnWidth)} \\x1b[33m(started)\\x1b[0m`;\n const up = linesBelowList + (views.length - index);\n process.stdout.write(`\\x1b[${up}F\\x1b[2K${line}\\x1b[${up}E`);\n };\n\n const pollUntilStarted = (index: number): void => {\n const attempt = (): void => {\n if (shuttingDown) return;\n const req = http.get(\n {\n host: 'localhost',\n port: views[index].port,\n path: '/',\n timeout: 1000,\n },\n (res) => {\n res.resume();\n markStarted(index);\n },\n );\n req.on('error', () => setTimeout(attempt, 500));\n req.on('timeout', () => req.destroy());\n };\n attempt();\n };\n\n for (const [index, view] of views.entries()) {\n const config = getViewsRspackConfig(view.viewsDir);\n const compiler = rspack(config);\n const server = new RspackDevServer(config.devServer || { port: view.port }, compiler);\n servers.push(server);\n\n try {\n await server.start();\n } catch (e) {\n logBelowList(` [${view.service}] failed to start: ${(e as Error).message} — shutting down all views servers.`);\n shutdown(1);\n return;\n }\n\n // markStarted is the only consumer of the ready signal, so there is\n // nothing to poll for when the status is hidden.\n if (!options.hideStartedStatus) pollUntilStarted(index);\n }\n\n process.on('SIGINT', () => shutdown(0));\n process.on('SIGTERM', () => shutdown(0));\n};\n"]}
@@ -42,7 +42,7 @@ import { isAwsCredentialsValid } from './awsCredentials';
42
42
  import { getCdkAppCommand, getDockerDir } from './cdkApp';
43
43
  import { buildRemote, resolvePublishTarget } from './remote';
44
44
  import { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';
45
- import { getViewsS3Destinations } from './viewsSync';
45
+ import { getViewsS3Destinations, NO_CACHE_FILES } from './viewsSync';
46
46
  const IMAGE_TAG = 'qpq-cdk-deployer';
47
47
  const AWS_CLI_IMAGE = 'amazon/aws-cli';
48
48
  const BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;
@@ -104,10 +104,13 @@ const dockerDeployStack = async (color, appName, serviceName, stackType, stackNa
104
104
  // Sync one service's pre-built views to S3 in a throwaway aws-cli container
105
105
  // named <service>-views. The official image's entrypoint is `aws`. Multiple
106
106
  // destinations (shell → website root + views prefix) run sequentially within
107
- // the service, reusing the container name.
107
+ // the service, reusing the container name. Mirrors the host-side syncViewsToS3
108
+ // cache policy: hashed assets immutable, the fixed-name entry points re-uploaded
109
+ // with no-cache every deploy (see NO_CACHE_FILES).
108
110
  const dockerSyncViews = async (color, appName, serviceName) => {
109
111
  const containerName = `${serviceName}-views`;
110
- for (const destination of getViewsS3Destinations(appName, serviceName)) {
112
+ const distDir = getViewsDistDir(appName, serviceName);
113
+ const runAwsCli = async (awsArgs) => {
111
114
  await removeContainer(containerName);
112
115
  await runCommandPrefixed(`views:${serviceName}`, 'docker', [
113
116
  'run',
@@ -115,14 +118,28 @@ const dockerSyncViews = async (color, appName, serviceName) => {
115
118
  '--name',
116
119
  containerName,
117
120
  '-v',
118
- `${getViewsDistDir(appName, serviceName)}:/views:ro`,
121
+ `${distDir}:/views:ro`,
119
122
  ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),
120
123
  AWS_CLI_IMAGE,
124
+ ...awsArgs,
125
+ ], { color });
126
+ };
127
+ for (const destination of getViewsS3Destinations(appName, serviceName)) {
128
+ await runAwsCli([
121
129
  's3',
122
130
  'sync',
123
131
  '/views',
124
132
  destination,
125
- ], { color });
133
+ '--cache-control',
134
+ 'public,max-age=31536000,immutable',
135
+ ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
136
+ ]);
137
+ for (const file of NO_CACHE_FILES) {
138
+ if (!fs.existsSync(path.join(distDir, file))) {
139
+ continue;
140
+ }
141
+ await runAwsCli(['s3', 'cp', `/views/${file}`, `${destination}/${file}`, '--cache-control', 'no-cache']);
142
+ }
126
143
  }
127
144
  };
128
145
  // Publish one service's already-built federated remote to S3 in a throwaway
@@ -1 +1 @@
1
- {"version":3,"file":"goDocker.js","sourceRoot":"","sources":["../../../../src/platforms/aws/goDocker.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,+CAA+C;AAC/C,EAAE;AACF,6EAA6E;AAC7E,qEAAqE;AACrE,qDAAqD;AACrD,mEAAmE;AACnE,6EAA6E;AAC7E,6EAA6E;AAC7E,oEAAoE;AACpE,mEAAmE;AACnE,4EAA4E;AAC5E,6EAA6E;AAC7E,oBAAoB;AACpB,sEAAsE;AACtE,gDAAgD;AAChD,+EAA+E;AAC/E,6EAA6E;AAC7E,qEAAqE;AACrE,EAAE;AACF,yEAAyE;AACzE,4CAA4C;AAC5C,EAAE;AACF,qEAAqE;AACrE,2EAA2E;AAC3E,yEAAyE;AACzE,mBAAmB;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC7G,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,SAAS,GAAG,kBAAkB,CAAC;AACrC,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAEvC,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;AAC/E,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,IAAI,QAAQ,CAAC;AAExF,0EAA0E;AAC1E,wEAAwE;AACxE,MAAM,mBAAmB,GAAG;IAC1B,mBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,YAAY;IACZ,oBAAoB;IACpB,qBAAqB;CACtB,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAE9I,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAC9E,gFAAgF;AAChF,MAAM,eAAe,GAAG,CAAC,aAAqB,EAAiB,EAAE,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AAE9H,MAAM,mBAAmB,GAAG,KAAK,IAAmB,EAAE;IACpD,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,8CAA8C,CAAC,CAAC,CAAC;IACnG,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,KAAK,IAAmB,EAAE;IACnD,4EAA4E;IAC5E,iDAAiD;IACjD,iEAAiE;IACjE,MAAM,UAAU,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,OAAiB,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,cAAc,UAAU,GAAG,CAAC,CAAC;IAC9E,MAAM,UAAU,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,UAAU,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AACrH,CAAC,CAAC;AAEF,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,+DAA+D;AAC/D,MAAM,iBAAiB,GAAG,KAAK,EAC7B,KAAa,EACb,OAAe,EACf,WAAmB,EACnB,SAAgC,EAChC,SAAiB,EACF,EAAE;IACjB,MAAM,aAAa,GAAG,GAAG,WAAW,IAAI,SAAS,EAAE,CAAC;IACpD,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;IACrC,MAAM,kBAAkB,CACtB,GAAG,SAAS,IAAI,WAAW,EAAE,EAC7B,QAAQ,EACR;QACE,KAAK;QACL,MAAM;QACN,QAAQ;QACR,aAAa;QACb,IAAI;QACJ,GAAG,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,eAAe;QACnD,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtD,SAAS;QACT,MAAM;QACN,IAAI;QACJ,gDAAgD,SAAS,kEAAkE;KAC5H,EACD,EAAE,KAAK,EAAE,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,2CAA2C;AAC3C,MAAM,eAAe,GAAG,KAAK,EAAE,KAAa,EAAE,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACnG,MAAM,aAAa,GAAG,GAAG,WAAW,QAAQ,CAAC;IAC7C,KAAK,MAAM,WAAW,IAAI,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACrC,MAAM,kBAAkB,CACtB,SAAS,WAAW,EAAE,EACtB,QAAQ,EACR;YACE,KAAK;YACL,MAAM;YACN,QAAQ;YACR,aAAa;YACb,IAAI;YACJ,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,YAAY;YACpD,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACtD,aAAa;YACb,IAAI;YACJ,MAAM;YACN,QAAQ;YACR,WAAW;SACZ,EACD,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,iFAAiF;AACjF,0EAA0E;AAC1E,MAAM,mBAAmB,GAAG,KAAK,EAAE,KAAa,EAAE,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACvG,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC5G,MAAM,aAAa,GAAG,GAAG,WAAW,UAAU,CAAC;IAE/C,8EAA8E;IAC9E,6CAA6C;IAC7C,MAAM,YAAY,GAAe;QAC/B,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,YAAY,EAAE,EAAE,QAAQ,UAAU,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;QACjG,CAAC,IAAI,EAAE,IAAI,EAAE,wBAAwB,EAAE,QAAQ,UAAU,IAAI,aAAa,gBAAgB,CAAC;KAC5F,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACrC,MAAM,kBAAkB,CACtB,WAAW,WAAW,EAAE,EACxB,QAAQ,EACR;YACE,KAAK;YACL,MAAM;YACN,QAAQ;YACR,aAAa;YACb,IAAI;YACJ,GAAG,WAAW,cAAc;YAC5B,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACtD,aAAa;YACb,GAAG,WAAW;SACf,EACD,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,OAAe,EAAE,IAAgB,EAAiB,EAAE;IACpF,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,IAAI,CAAC,MAAM,qBAAqB,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IAED,YAAY,CAAC,WAAW,CAAC,CAAC;IAE1B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,UAAU,CAAC,WAAW,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,UAAU,CAAC,WAAW,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAElC,MAAM,SAAS,GAAG,MAAM,KAAK,KAAK,CAAC;IACnC,MAAM,OAAO,GAAG,SAAS,IAAI,MAAM,KAAK,KAAK,CAAC;IAC9C,MAAM,OAAO,GAAG,SAAS,IAAI,MAAM,KAAK,KAAK,CAAC;IAC9C,MAAM,OAAO,GAAG,SAAS,IAAI,MAAM,KAAK,KAAK,CAAC;IAC9C,MAAM,SAAS,GAAG,SAAS,IAAI,MAAM,KAAK,OAAO,CAAC;IAClD,MAAM,cAAc,GAAG,OAAO,IAAI,OAAO,IAAI,OAAO,CAAC;IAErD,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5G,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjC,2EAA2E;IAC3E,uEAAuE;IACvE,IAAI,cAAc,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,mBAAmB,EAAE,CAAC;IAC9B,CAAC;IACD,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,kBAAkB,EAAE,CAAC;IAC7B,CAAC;IAED,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IAEjD,MAAM,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEvC,4EAA4E;IAC5E,6EAA6E;IAC7E,yEAAyE;IACzE,gCAAgC;IAChC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC;IAE1E,qEAAqE;IACrE,iFAAiF;IACjF,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,MAAM,YAAY,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,+EAA+E;IAC/E,sFAAsF;IACtF,oFAAoF;IACpF,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE1F,0EAA0E;IAC1E,gFAAgF;IAChF,0EAA0E;IAC1E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,gBAAgB,CACd,cAAc,EACd,MAAM,QAAQ,CACZ,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACzB,KAAK,EAAE,cAAc,OAAO,EAAE;YAC9B,GAAG,EAAE,KAAK,IAAI,EAAE;gBACd,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,GAAG,CAAC,CAAC;gBAC1C,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBACzD,MAAM,SAAS,CAAC,sBAAsB,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YAClH,CAAC;SACF,CAAC,CAAC,EACH,iBAAiB,CAClB,CACF,CAAC;IACJ,CAAC;IAED,gBAAgB,CACd,gBAAgB,EAChB,MAAM,QAAQ,CACZ,YAAY,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC7B,KAAK,EAAE,gBAAgB,OAAO,EAAE;QAChC,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,GAAG,CAAC,CAAC;YAC5C,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;KACF,CAAC,CAAC,EACH,iBAAiB,CAClB,CACF,CAAC;IAEF,+EAA+E;IAC/E,+EAA+E;IAC/E,qCAAqC;IACrC,gBAAgB,CACd,iBAAiB,EACjB,MAAM,QAAQ,CACZ,iBAAiB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClC,KAAK,EAAE,iBAAiB,OAAO,EAAE;QACjC,GAAG,EAAE,KAAK,IAAI,EAAE;YACd,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,GAAG,CAAC,CAAC;YACvD,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;KACF,CAAC,CAAC,EACH,iBAAiB,CAClB,CACF,CAAC;IAEF,IAAI,cAAc,EAAE,CAAC;QACnB,yEAAyE;QACzE,qEAAqE;QACrE,wCAAwC;QACxC,gBAAgB,CACd,WAAW,EACX,MAAM,QAAQ,CACZ,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACzB,KAAK,EAAE,aAAa,OAAO,EAAE;YAC7B,GAAG,EAAE,KAAK,IAAI,EAAE;gBACd,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAChD,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACvD,MAAM,kBAAkB,CAAC,aAAa,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE;oBACvI,GAAG,EAAE,OAAO,EAAE;oBACd,GAAG,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE;oBAC/D,KAAK,EAAE,eAAe,EAAE;iBACzB,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC,EACH,iBAAiB,CAClB,CACF,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACvB,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzD,OAAO;YACL,OAAO;YACP;gBACE,GAAG,EAAE,oBAAoB,CAAC,eAAe,CAAC,SAAS,CAAC;gBACpD,GAAG,EAAE,oBAAoB,CAAC,eAAe,CAAC,SAAS,CAAC;gBACpD,GAAG,EAAE,oBAAoB,CAAC,eAAe,CAAC,SAAS,CAAC;aACrD;SACF,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,2EAA2E;IAC3E,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QAC/D,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,gBAAgB,CACd,YAAY,EACZ,MAAM,QAAQ,CACZ,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACzB,KAAK,EAAE,OAAO,OAAO,EAAE;YACvB,GAAG,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC;SACvG,CAAC,CAAC,EACH,kBAAkB,CACnB,CACF,CAAC;QACF,UAAU,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IAED,sDAAsD;IACtD,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QACrE,YAAY,CAAC,YAAY,CAAC,CAAC;QAC3B,gBAAgB,CACd,gBAAgB,EAChB,MAAM,QAAQ,CACX,CAAC,KAAK,EAAE,KAAK,CAAW;aACtB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;aAChE,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CACrB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACzB,KAAK,EAAE,GAAG,SAAS,IAAI,OAAO,EAAE;YAChC,GAAG,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,SAAS,CAAC,CAAC;SAClH,CAAC,CAAC,CACJ,EACH,kBAAkB,CACnB,CACF,CAAC;QACF,UAAU,CAAC,YAAY,CAAC,CAAC;IAC3B,CAAC;IAED,oEAAoE;IACpE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,YAAY,CAAC,WAAW,CAAC,CAAC;QAC1B,gBAAgB,CACd,YAAY,EACZ,MAAM,QAAQ,CACZ,YAAY,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC7B,KAAK,EAAE,SAAS,OAAO,EAAE;YACzB,GAAG,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC;SAChE,CAAC,CAAC,EACH,kBAAkB,CACnB,CACF,CAAC;QACF,UAAU,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;IAED,mFAAmF;IACnF,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC,CAAC;QAC7E,YAAY,CAAC,aAAa,CAAC,CAAC;QAC5B,gBAAgB,CACd,mBAAmB,EACnB,MAAM,QAAQ,CACZ,iBAAiB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAClC,KAAK,EAAE,WAAW,OAAO,EAAE;YAC3B,GAAG,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC;SACpE,CAAC,CAAC,EACH,kBAAkB,CACnB,CACF,CAAC;QACF,UAAU,CAAC,aAAa,CAAC,CAAC;IAC5B,CAAC;IAED,UAAU,CAAC,WAAW,CAAC,CAAC;AAC1B,CAAC,CAAC","sourcesContent":["// `qpq go:docker` — asks the same questions as `qpq go`, then deploys in\n// parallel via docker instead of sequentially:\n//\n// 1. Build everything locally first: QPQ config synth, rspack API bundles,\n// rspack view bundles, rspack federated-remote bundles, and one\n// self-contained CDK cloud assembly per service\n// (`cdk synth --output dist/qpq/cdk-docker/<app>/<service>`).\n// 2. Wave 1 (inf): one docker container per service deploys its inf stack,\n// all concurrently. Containers run only the CDK CLI against the mounted\n// pre-synthesized assembly — the workspace (and its npm-linked\n// quidproquo packages) never needs to exist inside the image.\n// 3. Wave 2 (api + web): once every inf stack is done, api and web stacks\n// for all services deploy concurrently (they depend only on inf, not on\n// each other).\n// 4. Views: the already-built bundles are synced to S3, one aws-cli\n// container per service, all concurrently.\n// 5. Publish: the already-built federated remotes (backends that opt in with\n// defineFederatedModuleStore(...)) are synced to S3 and their manifests\n// flipped, one aws-cli container per service, all concurrently.\n//\n// domain/bootstrap menu options deploy host-side exactly like `qpq go` —\n// a single stack gains nothing from docker.\n//\n// Requires the same env as `go` plus a running docker daemon. Knobs:\n// GO_DOCKER_BUILD_CONCURRENCY (default 4 — local builds are CPU-bound) and\n// GO_DOCKER_DEPLOY_CONCURRENCY (default unlimited — deploys just wait on\n// CloudFormation).\nimport { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\nimport { getServiceRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { synthCommand } from '../../commands/synth';\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runRspack } from '../../lib/rspackRun';\nimport { nextPrefixColor, runCommand, runCommandBestEffort, runCommandPrefixed } from '../../lib/runCommand';\nimport { assertNoFailures, runTasks } from '../../lib/runTasks';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { getCdkAppCommand, getDockerDir } from './cdkApp';\nimport { buildRemote, resolvePublishTarget } from './remote';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';\nimport { getViewsS3Destinations } from './viewsSync';\n\nconst IMAGE_TAG = 'qpq-cdk-deployer';\nconst AWS_CLI_IMAGE = 'amazon/aws-cli';\n\nconst BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;\nconst DEPLOY_CONCURRENCY = Number(process.env.GO_DOCKER_DEPLOY_CONCURRENCY) || Infinity;\n\n// Credentials/region reach the containers via `docker run -e NAME` (value\n// inherited from this process's env, never on the docker command line).\nconst AWS_ENV_PASSTHROUGH = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n 'AWS_DEFAULT_ACCOUNT',\n];\n\nconst assemblyDir = (appName: string, serviceName: string): string => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);\n\n// A container left behind by an interrupted run would block reusing its name.\n// Clear it first, best-effort: a missing container (exit 1) must not fail the\n// deploy. Was a `docker rm -f … >/dev/null 2>&1 ;` prefix on the run command,\n// but that only worked under `shell: true`; as a separate call it's shell-free.\nconst removeContainer = (containerName: string): Promise<void> => runCommandBestEffort('docker', ['rm', '-f', containerName]);\n\nconst assertDockerRunning = async (): Promise<void> => {\n try {\n await runCommand('docker', ['info', '--format', 'docker daemon ok — server {{.ServerVersion}}']);\n } catch {\n throw new Error('Docker daemon is not running (start Docker Desktop and retry).');\n }\n};\n\nconst buildDeployerImage = async (): Promise<void> => {\n // Pin the image's CDK CLI to the CLI's own aws-cdk version so it can always\n // read the assembly schema the host synthesized.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cdkVersion = require('aws-cdk/package.json').version as string;\n console.log(`Building deployer image [${IMAGE_TAG}] (aws-cdk ${cdkVersion})`);\n await runCommand('docker', ['build', '-t', IMAGE_TAG, '--build-arg', `CDK_VERSION=${cdkVersion}`, getDockerDir()]);\n};\n\n// Deploy one stack from a pre-synthesized assembly in a throwaway container\n// named <service>-<stackType> (e.g. mini-web) so `docker ps` reads cleanly.\n// The assembly mounts read-only and is copied container-local first — the CDK\n// CLI writes lock files next to the assembly it reads, and the copy keeps\n// parallel api/web deploys of the same service fully isolated.\nconst dockerDeployStack = async (\n color: number,\n appName: string,\n serviceName: string,\n stackType: 'inf' | 'api' | 'web',\n stackName: string,\n): Promise<void> => {\n const containerName = `${serviceName}-${stackType}`;\n await removeContainer(containerName);\n await runCommandPrefixed(\n `${stackType}:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${assemblyDir(appName, serviceName)}:/assembly:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n IMAGE_TAG,\n 'bash',\n '-c',\n `cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events`,\n ],\n { color },\n );\n};\n\n// Sync one service's pre-built views to S3 in a throwaway aws-cli container\n// named <service>-views. The official image's entrypoint is `aws`. Multiple\n// destinations (shell → website root + views prefix) run sequentially within\n// the service, reusing the container name.\nconst dockerSyncViews = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const containerName = `${serviceName}-views`;\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `views:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${getViewsDistDir(appName, serviceName)}:/views:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n 's3',\n 'sync',\n '/views',\n destination,\n ],\n { color },\n );\n }\n};\n\n// Publish one service's already-built federated remote to S3 in a throwaway\n// aws-cli container named <service>-publish. The version dir (everything the\n// manifest references) syncs first, then the manifest.json is copied last —\n// same ordering guarantee as the host-side publish, so a reading lambda never\n// sees a manifest whose files aren't all present yet. resolvePublishTarget reads\n// the manifest hash + resolved bucket/prefix from the buildRemote output.\nconst dockerPublishRemote = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const { publishPath, manifestHash, bucketName, servicePrefix } = resolvePublishTarget(appName, serviceName);\n const containerName = `${serviceName}-publish`;\n\n // /publish is the service-remote-published dir; the hashed version subdir and\n // manifest.json both live directly under it.\n const s3Operations: string[][] = [\n ['s3', 'sync', `/publish/${manifestHash}`, `s3://${bucketName}/${servicePrefix}/${manifestHash}`],\n ['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],\n ];\n\n for (const s3Operation of s3Operations) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `publish:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${publishPath}:/publish:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...s3Operation,\n ],\n { color },\n );\n }\n};\n\nexport const awsGoDocker = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n if (plan.kind === 'account') {\n await deployAccountStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n if (plan.kind === 'bootstrap') {\n if (plan.includeDomain) {\n await deployDomainStack(plan.appName);\n }\n await deployBootstrapStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n const { services, stacks } = plan;\n\n const allStacks = stacks === 'all';\n const needInf = allStacks || stacks === 'inf';\n const needApi = allStacks || stacks === 'api';\n const needWeb = allStacks || stacks === 'web';\n const needViews = allStacks || stacks === 'views';\n const needCdkDeploys = needInf || needApi || needWeb;\n\n const viewServices = needViews ? services.filter((s) => getServiceNamesWithViews(appName).includes(s)) : [];\n\n console.log('\\n\\nRunning dockerized deploy\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n // Federated publish needs the api stack (needApi ⇒ needCdkDeploys), so any\n // docker preflight it requires is already covered by these two checks.\n if (needCdkDeploys || viewServices.length > 0) {\n await assertDockerRunning();\n }\n if (needCdkDeploys) {\n await buildDeployerImage();\n }\n\n // ---- Phase 1: build everything locally ----\n console.log('\\n=== Phase 1: local builds ===\\n');\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. npm runs\n // the workspaces in topological order; tsc -b is incremental, so this is\n // seconds when nothing changed.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // Synth QPQ configs (shell's config resolves the view bucket names).\n // In-process (no subprocess per service) — it's just config loads + JSON writes.\n const qpqSynthServices = [...new Set([...services, ...(needViews ? ['shell'] : [])])];\n for (const service of qpqSynthServices) {\n await synthCommand([service, '--app', appName]);\n }\n\n // Federated remotes are the backend story code, so republish them whenever the\n // api stack was (re)deployed. Skips services without defineFederatedModuleStore(...).\n // Detected here (after the workspace build) because it loads each service's config.\n const federatedServices = needApi ? getServiceNamesWithFederation(appName, services) : [];\n\n // The aws-cli image backs both the views sync (phase 4) and the federated\n // publish (phase 5) waves. Pull once now so those waves don't race N containers\n // into pulling the same image. Docker is already confirmed running above.\n if (viewServices.length > 0 || federatedServices.length > 0) {\n await runCommand('docker', ['pull', AWS_CLI_IMAGE]);\n }\n\n if (stacks !== 'views') {\n assertNoFailures(\n 'API bundling',\n await runTasks(\n services.map((service) => ({\n label: `bundle-api:${service}`,\n run: async () => {\n console.log(`Bundling api: [${service}]`);\n const qpqConfig = loadServiceQpqConfig(appName, service);\n await runRspack(getServiceRspackConfig(qpqConfig, path.join(getServiceDirectory(appName, service), 'service')));\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n assertNoFailures(\n 'Views bundling',\n await runTasks(\n viewServices.map((service) => ({\n label: `bundle-views:${service}`,\n run: async () => {\n console.log(`Bundling views: [${service}]`);\n await bundleViews(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n // Build the federated remotes locally now (rspack needs the workspace), so the\n // publish wave only has to sync the already-built output — mirroring how views\n // are bundled here and synced later.\n assertNoFailures(\n 'Remote bundling',\n await runTasks(\n federatedServices.map((service) => ({\n label: `bundle-remote:${service}`,\n run: async () => {\n console.log(`Bundling federated remote: [${service}]`);\n await buildRemote(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n if (needCdkDeploys) {\n // One self-contained cloud assembly per service (all its stacks + staged\n // assets) — separate --output dirs so synths can run in parallel and\n // containers never share mutable state.\n assertNoFailures(\n 'CDK synth',\n await runTasks(\n services.map((service) => ({\n label: `cdk-synth:${service}`,\n run: async () => {\n const outputDir = assemblyDir(appName, service);\n fs.rmSync(outputDir, { recursive: true, force: true });\n await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app', getCdkAppCommand(), '--output', outputDir], {\n cwd: getRoot(),\n env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },\n color: nextPrefixColor(),\n });\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n // Stack names come from each service's live config, resolved once up front.\n const stackNames = new Map(\n services.map((service) => {\n const qpqConfig = loadServiceQpqConfig(appName, service);\n return [\n service,\n {\n inf: qpqDeployAwsCdkUtils.getInfStackName(qpqConfig),\n api: qpqDeployAwsCdkUtils.getApiStackName(qpqConfig),\n web: qpqDeployAwsCdkUtils.getWebStackName(qpqConfig),\n },\n ];\n }),\n );\n\n // ---- Phase 2: inf stacks, one container per service, all concurrent ----\n if (needInf) {\n console.log('\\n=== Phase 2: deploy inf stacks (docker) ===\\n');\n logTimeStart('infWave');\n assertNoFailures(\n 'Inf deploy',\n await runTasks(\n services.map((service) => ({\n label: `inf:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, 'inf', stackNames.get(service)!.inf),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('infWave');\n }\n\n // ---- Phase 3: api + web stacks, all concurrent ----\n if (needApi || needWeb) {\n console.log('\\n=== Phase 3: deploy api + web stacks (docker) ===\\n');\n logTimeStart('apiWebWave');\n assertNoFailures(\n 'Api/Web deploy',\n await runTasks(\n (['api', 'web'] as const)\n .filter((stackType) => (stackType === 'api' ? needApi : needWeb))\n .flatMap((stackType) =>\n services.map((service) => ({\n label: `${stackType}:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, stackType, stackNames.get(service)![stackType]),\n })),\n ),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('apiWebWave');\n }\n\n // ---- Phase 4: sync the pre-built views to S3, all concurrent ----\n if (viewServices.length > 0) {\n console.log('\\n=== Phase 4: sync views to S3 (docker) ===\\n');\n logTimeStart('viewsWave');\n assertNoFailures(\n 'Views sync',\n await runTasks(\n viewServices.map((service) => ({\n label: `views:${service}`,\n run: () => dockerSyncViews(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('viewsWave');\n }\n\n // ---- Phase 5: publish the pre-built federated remotes to S3, all concurrent ----\n if (federatedServices.length > 0) {\n console.log('\\n=== Phase 5: publish federated remotes to S3 (docker) ===\\n');\n logTimeStart('publishWave');\n assertNoFailures(\n 'Federated publish',\n await runTasks(\n federatedServices.map((service) => ({\n label: `publish:${service}`,\n run: () => dockerPublishRemote(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('publishWave');\n }\n\n logTimeEnd('totalTime');\n};\n"]}
1
+ {"version":3,"file":"goDocker.js","sourceRoot":"","sources":["../../../../src/platforms/aws/goDocker.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:docker` — asks the same questions as `qpq go`, then deploys in\n// parallel via docker instead of sequentially:\n//\n// 1. Build everything locally first: QPQ config synth, rspack API bundles,\n// rspack view bundles, rspack federated-remote bundles, and one\n// self-contained CDK cloud assembly per service\n// (`cdk synth --output dist/qpq/cdk-docker/<app>/<service>`).\n// 2. Wave 1 (inf): one docker container per service deploys its inf stack,\n// all concurrently. Containers run only the CDK CLI against the mounted\n// pre-synthesized assembly — the workspace (and its npm-linked\n// quidproquo packages) never needs to exist inside the image.\n// 3. Wave 2 (api + web): once every inf stack is done, api and web stacks\n// for all services deploy concurrently (they depend only on inf, not on\n// each other).\n// 4. Views: the already-built bundles are synced to S3, one aws-cli\n// container per service, all concurrently.\n// 5. Publish: the already-built federated remotes (backends that opt in with\n// defineFederatedModuleStore(...)) are synced to S3 and their manifests\n// flipped, one aws-cli container per service, all concurrently.\n//\n// domain/bootstrap menu options deploy host-side exactly like `qpq go` —\n// a single stack gains nothing from docker.\n//\n// Requires the same env as `go` plus a running docker daemon. Knobs:\n// GO_DOCKER_BUILD_CONCURRENCY (default 4 — local builds are CPU-bound) and\n// GO_DOCKER_DEPLOY_CONCURRENCY (default unlimited — deploys just wait on\n// CloudFormation).\nimport { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\nimport { getServiceRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { synthCommand } from '../../commands/synth';\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runRspack } from '../../lib/rspackRun';\nimport { nextPrefixColor, runCommand, runCommandBestEffort, runCommandPrefixed } from '../../lib/runCommand';\nimport { assertNoFailures, runTasks } from '../../lib/runTasks';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { getCdkAppCommand, getDockerDir } from './cdkApp';\nimport { buildRemote, resolvePublishTarget } from './remote';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';\nimport { getViewsS3Destinations, NO_CACHE_FILES } from './viewsSync';\n\nconst IMAGE_TAG = 'qpq-cdk-deployer';\nconst AWS_CLI_IMAGE = 'amazon/aws-cli';\n\nconst BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;\nconst DEPLOY_CONCURRENCY = Number(process.env.GO_DOCKER_DEPLOY_CONCURRENCY) || Infinity;\n\n// Credentials/region reach the containers via `docker run -e NAME` (value\n// inherited from this process's env, never on the docker command line).\nconst AWS_ENV_PASSTHROUGH = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n 'AWS_DEFAULT_ACCOUNT',\n];\n\nconst assemblyDir = (appName: string, serviceName: string): string => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);\n\n// A container left behind by an interrupted run would block reusing its name.\n// Clear it first, best-effort: a missing container (exit 1) must not fail the\n// deploy. Was a `docker rm -f … >/dev/null 2>&1 ;` prefix on the run command,\n// but that only worked under `shell: true`; as a separate call it's shell-free.\nconst removeContainer = (containerName: string): Promise<void> => runCommandBestEffort('docker', ['rm', '-f', containerName]);\n\nconst assertDockerRunning = async (): Promise<void> => {\n try {\n await runCommand('docker', ['info', '--format', 'docker daemon ok — server {{.ServerVersion}}']);\n } catch {\n throw new Error('Docker daemon is not running (start Docker Desktop and retry).');\n }\n};\n\nconst buildDeployerImage = async (): Promise<void> => {\n // Pin the image's CDK CLI to the CLI's own aws-cdk version so it can always\n // read the assembly schema the host synthesized.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cdkVersion = require('aws-cdk/package.json').version as string;\n console.log(`Building deployer image [${IMAGE_TAG}] (aws-cdk ${cdkVersion})`);\n await runCommand('docker', ['build', '-t', IMAGE_TAG, '--build-arg', `CDK_VERSION=${cdkVersion}`, getDockerDir()]);\n};\n\n// Deploy one stack from a pre-synthesized assembly in a throwaway container\n// named <service>-<stackType> (e.g. mini-web) so `docker ps` reads cleanly.\n// The assembly mounts read-only and is copied container-local first — the CDK\n// CLI writes lock files next to the assembly it reads, and the copy keeps\n// parallel api/web deploys of the same service fully isolated.\nconst dockerDeployStack = async (\n color: number,\n appName: string,\n serviceName: string,\n stackType: 'inf' | 'api' | 'web',\n stackName: string,\n): Promise<void> => {\n const containerName = `${serviceName}-${stackType}`;\n await removeContainer(containerName);\n await runCommandPrefixed(\n `${stackType}:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${assemblyDir(appName, serviceName)}:/assembly:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n IMAGE_TAG,\n 'bash',\n '-c',\n `cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events`,\n ],\n { color },\n );\n};\n\n// Sync one service's pre-built views to S3 in a throwaway aws-cli container\n// named <service>-views. The official image's entrypoint is `aws`. Multiple\n// destinations (shell → website root + views prefix) run sequentially within\n// the service, reusing the container name. Mirrors the host-side syncViewsToS3\n// cache policy: hashed assets immutable, the fixed-name entry points re-uploaded\n// with no-cache every deploy (see NO_CACHE_FILES).\nconst dockerSyncViews = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const containerName = `${serviceName}-views`;\n const distDir = getViewsDistDir(appName, serviceName);\n\n const runAwsCli = async (awsArgs: string[]): Promise<void> => {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `views:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${distDir}:/views:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...awsArgs,\n ],\n { color },\n );\n };\n\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n await runAwsCli([\n 's3',\n 'sync',\n '/views',\n destination,\n '--cache-control',\n 'public,max-age=31536000,immutable',\n ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),\n ]);\n\n for (const file of NO_CACHE_FILES) {\n if (!fs.existsSync(path.join(distDir, file))) {\n continue;\n }\n\n await runAwsCli(['s3', 'cp', `/views/${file}`, `${destination}/${file}`, '--cache-control', 'no-cache']);\n }\n }\n};\n\n// Publish one service's already-built federated remote to S3 in a throwaway\n// aws-cli container named <service>-publish. The version dir (everything the\n// manifest references) syncs first, then the manifest.json is copied last —\n// same ordering guarantee as the host-side publish, so a reading lambda never\n// sees a manifest whose files aren't all present yet. resolvePublishTarget reads\n// the manifest hash + resolved bucket/prefix from the buildRemote output.\nconst dockerPublishRemote = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const { publishPath, manifestHash, bucketName, servicePrefix } = resolvePublishTarget(appName, serviceName);\n const containerName = `${serviceName}-publish`;\n\n // /publish is the service-remote-published dir; the hashed version subdir and\n // manifest.json both live directly under it.\n const s3Operations: string[][] = [\n ['s3', 'sync', `/publish/${manifestHash}`, `s3://${bucketName}/${servicePrefix}/${manifestHash}`],\n ['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],\n ];\n\n for (const s3Operation of s3Operations) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `publish:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${publishPath}:/publish:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...s3Operation,\n ],\n { color },\n );\n }\n};\n\nexport const awsGoDocker = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n if (plan.kind === 'account') {\n await deployAccountStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n if (plan.kind === 'bootstrap') {\n if (plan.includeDomain) {\n await deployDomainStack(plan.appName);\n }\n await deployBootstrapStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n const { services, stacks } = plan;\n\n const allStacks = stacks === 'all';\n const needInf = allStacks || stacks === 'inf';\n const needApi = allStacks || stacks === 'api';\n const needWeb = allStacks || stacks === 'web';\n const needViews = allStacks || stacks === 'views';\n const needCdkDeploys = needInf || needApi || needWeb;\n\n const viewServices = needViews ? services.filter((s) => getServiceNamesWithViews(appName).includes(s)) : [];\n\n console.log('\\n\\nRunning dockerized deploy\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n // Federated publish needs the api stack (needApi ⇒ needCdkDeploys), so any\n // docker preflight it requires is already covered by these two checks.\n if (needCdkDeploys || viewServices.length > 0) {\n await assertDockerRunning();\n }\n if (needCdkDeploys) {\n await buildDeployerImage();\n }\n\n // ---- Phase 1: build everything locally ----\n console.log('\\n=== Phase 1: local builds ===\\n');\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. npm runs\n // the workspaces in topological order; tsc -b is incremental, so this is\n // seconds when nothing changed.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // Synth QPQ configs (shell's config resolves the view bucket names).\n // In-process (no subprocess per service) — it's just config loads + JSON writes.\n const qpqSynthServices = [...new Set([...services, ...(needViews ? ['shell'] : [])])];\n for (const service of qpqSynthServices) {\n await synthCommand([service, '--app', appName]);\n }\n\n // Federated remotes are the backend story code, so republish them whenever the\n // api stack was (re)deployed. Skips services without defineFederatedModuleStore(...).\n // Detected here (after the workspace build) because it loads each service's config.\n const federatedServices = needApi ? getServiceNamesWithFederation(appName, services) : [];\n\n // The aws-cli image backs both the views sync (phase 4) and the federated\n // publish (phase 5) waves. Pull once now so those waves don't race N containers\n // into pulling the same image. Docker is already confirmed running above.\n if (viewServices.length > 0 || federatedServices.length > 0) {\n await runCommand('docker', ['pull', AWS_CLI_IMAGE]);\n }\n\n if (stacks !== 'views') {\n assertNoFailures(\n 'API bundling',\n await runTasks(\n services.map((service) => ({\n label: `bundle-api:${service}`,\n run: async () => {\n console.log(`Bundling api: [${service}]`);\n const qpqConfig = loadServiceQpqConfig(appName, service);\n await runRspack(getServiceRspackConfig(qpqConfig, path.join(getServiceDirectory(appName, service), 'service')));\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n assertNoFailures(\n 'Views bundling',\n await runTasks(\n viewServices.map((service) => ({\n label: `bundle-views:${service}`,\n run: async () => {\n console.log(`Bundling views: [${service}]`);\n await bundleViews(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n // Build the federated remotes locally now (rspack needs the workspace), so the\n // publish wave only has to sync the already-built output — mirroring how views\n // are bundled here and synced later.\n assertNoFailures(\n 'Remote bundling',\n await runTasks(\n federatedServices.map((service) => ({\n label: `bundle-remote:${service}`,\n run: async () => {\n console.log(`Bundling federated remote: [${service}]`);\n await buildRemote(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n if (needCdkDeploys) {\n // One self-contained cloud assembly per service (all its stacks + staged\n // assets) — separate --output dirs so synths can run in parallel and\n // containers never share mutable state.\n assertNoFailures(\n 'CDK synth',\n await runTasks(\n services.map((service) => ({\n label: `cdk-synth:${service}`,\n run: async () => {\n const outputDir = assemblyDir(appName, service);\n fs.rmSync(outputDir, { recursive: true, force: true });\n await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app', getCdkAppCommand(), '--output', outputDir], {\n cwd: getRoot(),\n env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },\n color: nextPrefixColor(),\n });\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n // Stack names come from each service's live config, resolved once up front.\n const stackNames = new Map(\n services.map((service) => {\n const qpqConfig = loadServiceQpqConfig(appName, service);\n return [\n service,\n {\n inf: qpqDeployAwsCdkUtils.getInfStackName(qpqConfig),\n api: qpqDeployAwsCdkUtils.getApiStackName(qpqConfig),\n web: qpqDeployAwsCdkUtils.getWebStackName(qpqConfig),\n },\n ];\n }),\n );\n\n // ---- Phase 2: inf stacks, one container per service, all concurrent ----\n if (needInf) {\n console.log('\\n=== Phase 2: deploy inf stacks (docker) ===\\n');\n logTimeStart('infWave');\n assertNoFailures(\n 'Inf deploy',\n await runTasks(\n services.map((service) => ({\n label: `inf:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, 'inf', stackNames.get(service)!.inf),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('infWave');\n }\n\n // ---- Phase 3: api + web stacks, all concurrent ----\n if (needApi || needWeb) {\n console.log('\\n=== Phase 3: deploy api + web stacks (docker) ===\\n');\n logTimeStart('apiWebWave');\n assertNoFailures(\n 'Api/Web deploy',\n await runTasks(\n (['api', 'web'] as const)\n .filter((stackType) => (stackType === 'api' ? needApi : needWeb))\n .flatMap((stackType) =>\n services.map((service) => ({\n label: `${stackType}:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, stackType, stackNames.get(service)![stackType]),\n })),\n ),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('apiWebWave');\n }\n\n // ---- Phase 4: sync the pre-built views to S3, all concurrent ----\n if (viewServices.length > 0) {\n console.log('\\n=== Phase 4: sync views to S3 (docker) ===\\n');\n logTimeStart('viewsWave');\n assertNoFailures(\n 'Views sync',\n await runTasks(\n viewServices.map((service) => ({\n label: `views:${service}`,\n run: () => dockerSyncViews(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('viewsWave');\n }\n\n // ---- Phase 5: publish the pre-built federated remotes to S3, all concurrent ----\n if (federatedServices.length > 0) {\n console.log('\\n=== Phase 5: publish federated remotes to S3 (docker) ===\\n');\n logTimeStart('publishWave');\n assertNoFailures(\n 'Federated publish',\n await runTasks(\n federatedServices.map((service) => ({\n label: `publish:${service}`,\n run: () => dockerPublishRemote(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('publishWave');\n }\n\n logTimeEnd('totalTime');\n};\n"]}
@@ -1,2 +1,3 @@
1
+ export declare const NO_CACHE_FILES: string[];
1
2
  export declare const getViewsS3Destinations: (appName: string, serviceName: string) => string[];
2
3
  export declare const syncViewsToS3: (appName: string, serviceName: string) => Promise<void>;
@@ -3,9 +3,17 @@
3
3
  // syncs to the 'website' bucket root AND to its prefix in the shared 'views'
4
4
  // bucket (where every other service's views live).
5
5
  import { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';
6
+ import fs from 'fs';
7
+ import path from 'path';
6
8
  import { loadServiceQpqConfig } from '../../lib/qpqConfigs';
7
9
  import { runCommand } from '../../lib/runCommand';
8
10
  import { getViewsDistDir } from '../../lib/views';
11
+ // The mutable entry points: fixed names whose CONTENT changes every deploy. They
12
+ // must never be cached without revalidation — a browser holding a stale
13
+ // mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle
14
+ // (the module-reload hot-swap and plain page refreshes both depend on these being
15
+ // fresh). Everything else in a views dist is content-hashed and safely immutable.
16
+ export const NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];
9
17
  export const getViewsS3Destinations = (appName, serviceName) => {
10
18
  const shellConfig = loadServiceQpqConfig(appName, 'shell');
11
19
  const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);
@@ -17,9 +25,27 @@ export const getViewsS3Destinations = (appName, serviceName) => {
17
25
  return destinations;
18
26
  };
19
27
  export const syncViewsToS3 = async (appName, serviceName) => {
28
+ const distDir = getViewsDistDir(appName, serviceName);
20
29
  for (const destination of getViewsS3Destinations(appName, serviceName)) {
21
30
  console.log(`Copying [${serviceName}] views to [${destination}]`);
22
- await runCommand('aws', ['s3', 'sync', getViewsDistDir(appName, serviceName), destination]);
31
+ // Content-hashed assets: cache forever.
32
+ await runCommand('aws', [
33
+ 's3',
34
+ 'sync',
35
+ distDir,
36
+ destination,
37
+ '--cache-control',
38
+ 'public,max-age=31536000,immutable',
39
+ ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
40
+ ]);
41
+ // Entry points: cp (not sync) so the no-cache header is (re)applied on every
42
+ // deploy even when a body happens to be byte-identical.
43
+ for (const file of NO_CACHE_FILES) {
44
+ if (!fs.existsSync(path.join(distDir, file))) {
45
+ continue;
46
+ }
47
+ await runCommand('aws', ['s3', 'cp', path.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);
48
+ }
23
49
  }
24
50
  };
25
51
  //# sourceMappingURL=viewsSync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,mDAAmD;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAY,EAAE;IACvF,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,cAAc,CAAC,sCAAsC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,YAAY,GAAG,CAAC,QAAQ,eAAe,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,cAAc,CAAC,sCAAsC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,YAAY,CAAC,IAAI,CAAC,QAAQ,iBAAiB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACzF,KAAK,MAAM,WAAW,IAAI,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,eAAe,WAAW,GAAG,CAAC,CAAC;QAClE,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC,CAAC","sourcesContent":["// Views upload to S3. Bucket names resolve from the shell service's config.\n// shell is the module-federation host: its bundle is the root website, so it\n// syncs to the 'website' bucket root AND to its prefix in the shared 'views'\n// bucket (where every other service's views live).\nimport { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';\n\nimport { loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runCommand } from '../../lib/runCommand';\nimport { getViewsDistDir } from '../../lib/views';\n\nexport const getViewsS3Destinations = (appName: string, serviceName: string): string[] => {\n const shellConfig = loadServiceQpqConfig(appName, 'shell');\n const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);\n\n const destinations = [`s3://${viewsBucketName}/${serviceName}`];\n\n if (serviceName === 'shell') {\n const websiteBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('website', shellConfig);\n destinations.push(`s3://${websiteBucketName}`);\n }\n\n return destinations;\n};\n\nexport const syncViewsToS3 = async (appName: string, serviceName: string): Promise<void> => {\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n console.log(`Copying [${serviceName}] views to [${destination}]`);\n await runCommand('aws', ['s3', 'sync', getViewsDistDir(appName, serviceName), destination]);\n }\n};\n"]}
1
+ {"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,mDAAmD;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,iFAAiF;AACjF,wEAAwE;AACxE,gFAAgF;AAChF,kFAAkF;AAClF,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAElG,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAY,EAAE;IACvF,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,cAAc,CAAC,sCAAsC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,YAAY,GAAG,CAAC,QAAQ,eAAe,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,cAAc,CAAC,sCAAsC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,YAAY,CAAC,IAAI,CAAC,QAAQ,iBAAiB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACzF,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEtD,KAAK,MAAM,WAAW,IAAI,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,eAAe,WAAW,GAAG,CAAC,CAAC;QAElE,wCAAwC;QACxC,MAAM,UAAU,CAAC,KAAK,EAAE;YACtB,IAAI;YACJ,MAAM;YACN,OAAO;YACP,WAAW;YACX,iBAAiB;YACjB,mCAAmC;YACnC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;SACzD,CAAC,CAAC;QAEH,6EAA6E;QAC7E,wDAAwD;QACxD,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;gBAC7C,SAAS;YACX,CAAC;YAED,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,WAAW,IAAI,IAAI,EAAE,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC;QAC3H,CAAC;IACH,CAAC;AACH,CAAC,CAAC","sourcesContent":["// Views upload to S3. Bucket names resolve from the shell service's config.\n// shell is the module-federation host: its bundle is the root website, so it\n// syncs to the 'website' bucket root AND to its prefix in the shared 'views'\n// bucket (where every other service's views live).\nimport { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runCommand } from '../../lib/runCommand';\nimport { getViewsDistDir } from '../../lib/views';\n\n// The mutable entry points: fixed names whose CONTENT changes every deploy. They\n// must never be cached without revalidation — a browser holding a stale\n// mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle\n// (the module-reload hot-swap and plain page refreshes both depend on these being\n// fresh). Everything else in a views dist is content-hashed and safely immutable.\nexport const NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];\n\nexport const getViewsS3Destinations = (appName: string, serviceName: string): string[] => {\n const shellConfig = loadServiceQpqConfig(appName, 'shell');\n const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);\n\n const destinations = [`s3://${viewsBucketName}/${serviceName}`];\n\n if (serviceName === 'shell') {\n const websiteBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('website', shellConfig);\n destinations.push(`s3://${websiteBucketName}`);\n }\n\n return destinations;\n};\n\nexport const syncViewsToS3 = async (appName: string, serviceName: string): Promise<void> => {\n const distDir = getViewsDistDir(appName, serviceName);\n\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n console.log(`Copying [${serviceName}] views to [${destination}]`);\n\n // Content-hashed assets: cache forever.\n await runCommand('aws', [\n 's3',\n 'sync',\n distDir,\n destination,\n '--cache-control',\n 'public,max-age=31536000,immutable',\n ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),\n ]);\n\n // Entry points: cp (not sync) so the no-cache header is (re)applied on every\n // deploy even when a body happens to be byte-identical.\n for (const file of NO_CACHE_FILES) {\n if (!fs.existsSync(path.join(distDir, file))) {\n continue;\n }\n\n await runCommand('aws', ['s3', 'cp', path.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);\n }\n }\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-cli",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "The qpq CLI — build, dev and deploy orchestration for QPQ apps",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -34,28 +34,28 @@
34
34
  },
35
35
  "homepage": "https://github.com/joe-coady/quidproquo#readme",
36
36
  "dependencies": {
37
- "@aws-sdk/client-dynamodb": "^3.621.0",
38
- "@aws-sdk/client-s3": "^3.621.0",
39
- "@aws-sdk/client-sts": "^3.621.0",
37
+ "@aws-sdk/client-dynamodb": "^3.1093.0",
38
+ "@aws-sdk/client-s3": "^3.1093.0",
39
+ "@aws-sdk/client-sts": "^3.1093.0",
40
40
  "@inquirer/prompts": "^8.5.2",
41
41
  "@rspack/dev-server": "^2.1.0",
42
- "aws-cdk": "^2.1128.1",
42
+ "aws-cdk": "^2.1132.1",
43
43
  "madge": "^8.0.0",
44
- "quidproquo": "0.1.10",
45
- "quidproquo-actionprocessor-awslambda": "0.1.10",
46
- "quidproquo-config-aws": "0.1.10",
47
- "quidproquo-core": "0.1.10",
48
- "quidproquo-deploy-awscdk": "0.1.10",
49
- "quidproquo-deploy-rspack": "0.1.10",
50
- "quidproquo-dev-server": "0.1.10",
51
- "quidproquo-webserver": "0.1.10",
44
+ "quidproquo": "0.1.12",
45
+ "quidproquo-actionprocessor-awslambda": "0.1.12",
46
+ "quidproquo-config-aws": "0.1.12",
47
+ "quidproquo-core": "0.1.12",
48
+ "quidproquo-deploy-awscdk": "0.1.12",
49
+ "quidproquo-deploy-rspack": "0.1.12",
50
+ "quidproquo-dev-server": "0.1.12",
51
+ "quidproquo-webserver": "0.1.12",
52
52
  "ts-node": "^10.9.1",
53
53
  "typescript": "^5.8.2"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@rspack/core": "^2.1.2",
57
57
  "@types/node": "^22.13.13",
58
- "quidproquo-tsconfig": "0.1.10"
58
+ "quidproquo-tsconfig": "0.1.12"
59
59
  },
60
60
  "bin": {
61
61
  "qpq": "./lib/commonjs/bin/qpq.js"