@qpqjs/cli 0.0.0-stage → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -2
- package/docker/cdk-deployer/Dockerfile +13 -0
- package/docker/dev-server/Dockerfile +47 -0
- package/lib/commonjs/bin/qpq.d.ts +2 -0
- package/lib/commonjs/bin/qpq.js +6 -0
- package/lib/commonjs/bin/qpq.js.map +1 -0
- package/lib/commonjs/bin/qpqCdkApp.d.ts +1 -0
- package/lib/commonjs/bin/qpqCdkApp.js +8 -0
- package/lib/commonjs/bin/qpqCdkApp.js.map +1 -0
- package/lib/commonjs/cli/commandMenu.d.ts +2 -0
- package/lib/commonjs/cli/commandMenu.js +81 -0
- package/lib/commonjs/cli/commandMenu.js.map +1 -0
- package/lib/commonjs/cli/commandRegistry.d.ts +10 -0
- package/lib/commonjs/cli/commandRegistry.js +177 -0
- package/lib/commonjs/cli/commandRegistry.js.map +1 -0
- package/lib/commonjs/cli/index.d.ts +1 -0
- package/lib/commonjs/cli/index.js +18 -0
- package/lib/commonjs/cli/index.js.map +1 -0
- package/lib/commonjs/cli/runCli.d.ts +1 -0
- package/lib/commonjs/cli/runCli.js +86 -0
- package/lib/commonjs/cli/runCli.js.map +1 -0
- package/lib/commonjs/commands/checkCircular.d.ts +1 -0
- package/lib/commonjs/commands/checkCircular.js +70 -0
- package/lib/commonjs/commands/checkCircular.js.map +1 -0
- package/lib/commonjs/commands/clearResources.d.ts +1 -0
- package/lib/commonjs/commands/clearResources.js +36 -0
- package/lib/commonjs/commands/clearResources.js.map +1 -0
- package/lib/commonjs/commands/go.d.ts +1 -0
- package/lib/commonjs/commands/go.js +30 -0
- package/lib/commonjs/commands/go.js.map +1 -0
- package/lib/commonjs/commands/goDev.d.ts +1 -0
- package/lib/commonjs/commands/goDev.js +46 -0
- package/lib/commonjs/commands/goDev.js.map +1 -0
- package/lib/commonjs/commands/goDevApi.d.ts +1 -0
- package/lib/commonjs/commands/goDevApi.js +158 -0
- package/lib/commonjs/commands/goDevApi.js.map +1 -0
- package/lib/commonjs/commands/goDevWeb.d.ts +4 -0
- package/lib/commonjs/commands/goDevWeb.js +144 -0
- package/lib/commonjs/commands/goDevWeb.js.map +1 -0
- package/lib/commonjs/commands/goDocker.d.ts +1 -0
- package/lib/commonjs/commands/goDocker.js +43 -0
- package/lib/commonjs/commands/goDocker.js.map +1 -0
- package/lib/commonjs/commands/hooks.d.ts +1 -0
- package/lib/commonjs/commands/hooks.js +39 -0
- package/lib/commonjs/commands/hooks.js.map +1 -0
- package/lib/commonjs/commands/migrate.d.ts +1 -0
- package/lib/commonjs/commands/migrate.js +70 -0
- package/lib/commonjs/commands/migrate.js.map +1 -0
- package/lib/commonjs/commands/prep.d.ts +1 -0
- package/lib/commonjs/commands/prep.js +28 -0
- package/lib/commonjs/commands/prep.js.map +1 -0
- package/lib/commonjs/commands/publish.d.ts +4 -0
- package/lib/commonjs/commands/publish.js +54 -0
- package/lib/commonjs/commands/publish.js.map +1 -0
- package/lib/commonjs/commands/scriptBuild.d.ts +1 -0
- package/lib/commonjs/commands/scriptBuild.js +46 -0
- package/lib/commonjs/commands/scriptBuild.js.map +1 -0
- package/lib/commonjs/commands/scriptBuilderLayer.d.ts +1 -0
- package/lib/commonjs/commands/scriptBuilderLayer.js +48 -0
- package/lib/commonjs/commands/scriptBuilderLayer.js.map +1 -0
- package/lib/commonjs/commands/scriptNew.d.ts +1 -0
- package/lib/commonjs/commands/scriptNew.js +35 -0
- package/lib/commonjs/commands/scriptNew.js.map +1 -0
- package/lib/commonjs/commands/setup.d.ts +1 -0
- package/lib/commonjs/commands/setup.js +102 -0
- package/lib/commonjs/commands/setup.js.map +1 -0
- package/lib/commonjs/commands/synth.d.ts +1 -0
- package/lib/commonjs/commands/synth.js +89 -0
- package/lib/commonjs/commands/synth.js.map +1 -0
- package/lib/commonjs/commands/teardown.d.ts +1 -0
- package/lib/commonjs/commands/teardown.js +33 -0
- package/lib/commonjs/commands/teardown.js.map +1 -0
- package/lib/commonjs/index.d.ts +1 -0
- package/lib/commonjs/index.js +18 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/lib/args.d.ts +3 -0
- package/lib/commonjs/lib/args.js +31 -0
- package/lib/commonjs/lib/args.js.map +1 -0
- package/lib/commonjs/lib/circularImports.d.ts +3 -0
- package/lib/commonjs/lib/circularImports.js +79 -0
- package/lib/commonjs/lib/circularImports.js.map +1 -0
- package/lib/commonjs/lib/clearResourcesPlan.d.ts +15 -0
- package/lib/commonjs/lib/clearResourcesPlan.js +79 -0
- package/lib/commonjs/lib/clearResourcesPlan.js.map +1 -0
- package/lib/commonjs/lib/deployPrompts.d.ts +26 -0
- package/lib/commonjs/lib/deployPrompts.js +118 -0
- package/lib/commonjs/lib/deployPrompts.js.map +1 -0
- package/lib/commonjs/lib/devServerEntry.d.ts +22 -0
- package/lib/commonjs/lib/devServerEntry.js +135 -0
- package/lib/commonjs/lib/devServerEntry.js.map +1 -0
- package/lib/commonjs/lib/devServerPorts.d.ts +13 -0
- package/lib/commonjs/lib/devServerPorts.js +36 -0
- package/lib/commonjs/lib/devServerPorts.js.map +1 -0
- package/lib/commonjs/lib/discovery.d.ts +10 -0
- package/lib/commonjs/lib/discovery.js +56 -0
- package/lib/commonjs/lib/discovery.js.map +1 -0
- package/lib/commonjs/lib/getDefaultHookJobs.d.ts +2 -0
- package/lib/commonjs/lib/getDefaultHookJobs.js +11 -0
- package/lib/commonjs/lib/getDefaultHookJobs.js.map +1 -0
- package/lib/commonjs/lib/getDeployTargetLabel.d.ts +2 -0
- package/lib/commonjs/lib/getDeployTargetLabel.js +12 -0
- package/lib/commonjs/lib/getDeployTargetLabel.js.map +1 -0
- package/lib/commonjs/lib/goDockerMode.d.ts +6 -0
- package/lib/commonjs/lib/goDockerMode.js +23 -0
- package/lib/commonjs/lib/goDockerMode.js.map +1 -0
- package/lib/commonjs/lib/hooks.d.ts +9 -0
- package/lib/commonjs/lib/hooks.js +178 -0
- package/lib/commonjs/lib/hooks.js.map +1 -0
- package/lib/commonjs/lib/keepOtherDevServersFlag.d.ts +1 -0
- package/lib/commonjs/lib/keepOtherDevServersFlag.js +11 -0
- package/lib/commonjs/lib/keepOtherDevServersFlag.js.map +1 -0
- package/lib/commonjs/lib/killChildWithEscalation.d.ts +10 -0
- package/lib/commonjs/lib/killChildWithEscalation.js +33 -0
- package/lib/commonjs/lib/killChildWithEscalation.js.map +1 -0
- package/lib/commonjs/lib/killStaleListeners.d.ts +17 -0
- package/lib/commonjs/lib/killStaleListeners.js +220 -0
- package/lib/commonjs/lib/killStaleListeners.js.map +1 -0
- package/lib/commonjs/lib/packageRoot.d.ts +1 -0
- package/lib/commonjs/lib/packageRoot.js +21 -0
- package/lib/commonjs/lib/packageRoot.js.map +1 -0
- package/lib/commonjs/lib/prompts.d.ts +15 -0
- package/lib/commonjs/lib/prompts.js +78 -0
- package/lib/commonjs/lib/prompts.js.map +1 -0
- package/lib/commonjs/lib/qpqConfigs.d.ts +4 -0
- package/lib/commonjs/lib/qpqConfigs.js +27 -0
- package/lib/commonjs/lib/qpqConfigs.js.map +1 -0
- package/lib/commonjs/lib/resolveAppSelection.d.ts +6 -0
- package/lib/commonjs/lib/resolveAppSelection.js +58 -0
- package/lib/commonjs/lib/resolveAppSelection.js.map +1 -0
- package/lib/commonjs/lib/resolveDeployment.d.ts +14 -0
- package/lib/commonjs/lib/resolveDeployment.js +58 -0
- package/lib/commonjs/lib/resolveDeployment.js.map +1 -0
- package/lib/commonjs/lib/runCommand.d.ts +14 -0
- package/lib/commonjs/lib/runCommand.js +103 -0
- package/lib/commonjs/lib/runCommand.js.map +1 -0
- package/lib/commonjs/lib/runTasks.d.ts +15 -0
- package/lib/commonjs/lib/runTasks.js +123 -0
- package/lib/commonjs/lib/runTasks.js.map +1 -0
- package/lib/commonjs/lib/setupStep.d.ts +16 -0
- package/lib/commonjs/lib/setupStep.js +3 -0
- package/lib/commonjs/lib/setupStep.js.map +1 -0
- package/lib/commonjs/lib/timing.d.ts +2 -0
- package/lib/commonjs/lib/timing.js +11 -0
- package/lib/commonjs/lib/timing.js.map +1 -0
- package/lib/commonjs/lib/typeWatcher.d.ts +2 -0
- package/lib/commonjs/lib/typeWatcher.js +59 -0
- package/lib/commonjs/lib/typeWatcher.js.map +1 -0
- package/lib/commonjs/lib/userScriptBuilderLayer.d.ts +23 -0
- package/lib/commonjs/lib/userScriptBuilderLayer.js +74 -0
- package/lib/commonjs/lib/userScriptBuilderLayer.js.map +1 -0
- package/lib/commonjs/lib/userScriptTemplate.d.ts +6 -0
- package/lib/commonjs/lib/userScriptTemplate.js +47 -0
- package/lib/commonjs/lib/userScriptTemplate.js.map +1 -0
- package/lib/commonjs/lib/views.d.ts +2 -0
- package/lib/commonjs/lib/views.js +31 -0
- package/lib/commonjs/lib/views.js.map +1 -0
- package/lib/commonjs/lib/webAddressingEnv.d.ts +7 -0
- package/lib/commonjs/lib/webAddressingEnv.js +16 -0
- package/lib/commonjs/lib/webAddressingEnv.js.map +1 -0
- package/lib/commonjs/platforms/aws/awsCredentials.d.ts +1 -0
- package/lib/commonjs/platforms/aws/awsCredentials.js +28 -0
- package/lib/commonjs/platforms/aws/awsCredentials.js.map +1 -0
- package/lib/commonjs/platforms/aws/cdkApp.d.ts +3 -0
- package/lib/commonjs/platforms/aws/cdkApp.js +31 -0
- package/lib/commonjs/platforms/aws/cdkApp.js.map +1 -0
- package/lib/commonjs/platforms/aws/clearResources.d.ts +2 -0
- package/lib/commonjs/platforms/aws/clearResources.js +167 -0
- package/lib/commonjs/platforms/aws/clearResources.js.map +1 -0
- package/lib/commonjs/platforms/aws/go.d.ts +2 -0
- package/lib/commonjs/platforms/aws/go.js +131 -0
- package/lib/commonjs/platforms/aws/go.js.map +1 -0
- package/lib/commonjs/platforms/aws/goDocker.d.ts +3 -0
- package/lib/commonjs/platforms/aws/goDocker.js +457 -0
- package/lib/commonjs/platforms/aws/goDocker.js.map +1 -0
- package/lib/commonjs/platforms/aws/goDockerManifest.d.ts +44 -0
- package/lib/commonjs/platforms/aws/goDockerManifest.js +38 -0
- package/lib/commonjs/platforms/aws/goDockerManifest.js.map +1 -0
- package/lib/commonjs/platforms/aws/index.d.ts +2 -0
- package/lib/commonjs/platforms/aws/index.js +23 -0
- package/lib/commonjs/platforms/aws/index.js.map +1 -0
- package/lib/commonjs/platforms/aws/prepareDeployment.d.ts +3 -0
- package/lib/commonjs/platforms/aws/prepareDeployment.js +10 -0
- package/lib/commonjs/platforms/aws/prepareDeployment.js.map +1 -0
- package/lib/commonjs/platforms/aws/publish.d.ts +4 -0
- package/lib/commonjs/platforms/aws/publish.js +66 -0
- package/lib/commonjs/platforms/aws/publish.js.map +1 -0
- package/lib/commonjs/platforms/aws/remote.d.ts +11 -0
- package/lib/commonjs/platforms/aws/remote.js +105 -0
- package/lib/commonjs/platforms/aws/remote.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/awsSetupContext.d.ts +12 -0
- package/lib/commonjs/platforms/aws/setup/awsSetupContext.js +20 -0
- package/lib/commonjs/platforms/aws/setup/awsSetupContext.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/awsSetupSteps.d.ts +8 -0
- package/lib/commonjs/platforms/aws/setup/awsSetupSteps.js +44 -0
- package/lib/commonjs/platforms/aws/setup/awsSetupSteps.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildBucketNamesStep.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/buildBucketNamesStep.js +77 -0
- package/lib/commonjs/platforms/aws/setup/buildBucketNamesStep.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildCdkBootstrapSteps.d.ts +5 -0
- package/lib/commonjs/platforms/aws/setup/buildCdkBootstrapSteps.js +38 -0
- package/lib/commonjs/platforms/aws/setup/buildCdkBootstrapSteps.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.js +55 -0
- package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildGithubOidcProviderStep.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/buildGithubOidcProviderStep.js +54 -0
- package/lib/commonjs/platforms/aws/setup/buildGithubOidcProviderStep.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildHostedZonesStep.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/buildHostedZonesStep.js +63 -0
- package/lib/commonjs/platforms/aws/setup/buildHostedZonesStep.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildIamCapabilityStep.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/buildIamCapabilityStep.js +48 -0
- package/lib/commonjs/platforms/aws/setup/buildIamCapabilityStep.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildIdentityStep.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/buildIdentityStep.js +39 -0
- package/lib/commonjs/platforms/aws/setup/buildIdentityStep.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/buildStackSteps.d.ts +5 -0
- package/lib/commonjs/platforms/aws/setup/buildStackSteps.js +32 -0
- package/lib/commonjs/platforms/aws/setup/buildStackSteps.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/describeStackStatus.d.ts +4 -0
- package/lib/commonjs/platforms/aws/setup/describeStackStatus.js +32 -0
- package/lib/commonjs/platforms/aws/setup/describeStackStatus.js.map +1 -0
- package/lib/commonjs/platforms/aws/setup/index.d.ts +1 -0
- package/lib/commonjs/platforms/aws/setup/index.js +18 -0
- package/lib/commonjs/platforms/aws/setup/index.js.map +1 -0
- package/lib/commonjs/platforms/aws/stacks.d.ts +7 -0
- package/lib/commonjs/platforms/aws/stacks.js +94 -0
- package/lib/commonjs/platforms/aws/stacks.js.map +1 -0
- package/lib/commonjs/platforms/aws/teardown.d.ts +2 -0
- package/lib/commonjs/platforms/aws/teardown.js +59 -0
- package/lib/commonjs/platforms/aws/teardown.js.map +1 -0
- package/lib/commonjs/platforms/aws/viewsSync.d.ts +3 -0
- package/lib/commonjs/platforms/aws/viewsSync.js +77 -0
- package/lib/commonjs/platforms/aws/viewsSync.js.map +1 -0
- package/lib/commonjs/platforms/docker/QpqDockerPlatformSettings.d.ts +10 -0
- package/lib/commonjs/platforms/docker/QpqDockerPlatformSettings.js +3 -0
- package/lib/commonjs/platforms/docker/QpqDockerPlatformSettings.js.map +1 -0
- package/lib/commonjs/platforms/docker/getContainerPorts.d.ts +4 -0
- package/lib/commonjs/platforms/docker/getContainerPorts.js +12 -0
- package/lib/commonjs/platforms/docker/getContainerPorts.js.map +1 -0
- package/lib/commonjs/platforms/docker/getDefaultPortMappings.d.ts +3 -0
- package/lib/commonjs/platforms/docker/getDefaultPortMappings.js +10 -0
- package/lib/commonjs/platforms/docker/getDefaultPortMappings.js.map +1 -0
- package/lib/commonjs/platforms/docker/getDockerPlatformSettings.d.ts +14 -0
- package/lib/commonjs/platforms/docker/getDockerPlatformSettings.js +39 -0
- package/lib/commonjs/platforms/docker/getDockerPlatformSettings.js.map +1 -0
- package/lib/commonjs/platforms/docker/getImageName.d.ts +6 -0
- package/lib/commonjs/platforms/docker/getImageName.js +10 -0
- package/lib/commonjs/platforms/docker/getImageName.js.map +1 -0
- package/lib/commonjs/platforms/docker/go.d.ts +2 -0
- package/lib/commonjs/platforms/docker/go.js +261 -0
- package/lib/commonjs/platforms/docker/go.js.map +1 -0
- package/lib/commonjs/platforms/docker/index.d.ts +2 -0
- package/lib/commonjs/platforms/docker/index.js +43 -0
- package/lib/commonjs/platforms/docker/index.js.map +1 -0
- package/lib/commonjs/platforms/docker/parseMounts.d.ts +7 -0
- package/lib/commonjs/platforms/docker/parseMounts.js +27 -0
- package/lib/commonjs/platforms/docker/parseMounts.js.map +1 -0
- package/lib/commonjs/platforms/docker/parsePortMappings.d.ts +8 -0
- package/lib/commonjs/platforms/docker/parsePortMappings.js +26 -0
- package/lib/commonjs/platforms/docker/parsePortMappings.js.map +1 -0
- package/lib/commonjs/platforms/docker/resolvePortMappings.d.ts +8 -0
- package/lib/commonjs/platforms/docker/resolvePortMappings.js +23 -0
- package/lib/commonjs/platforms/docker/resolvePortMappings.js.map +1 -0
- package/lib/commonjs/platforms/docker/writeComposeFile.d.ts +20 -0
- package/lib/commonjs/platforms/docker/writeComposeFile.js +44 -0
- package/lib/commonjs/platforms/docker/writeComposeFile.js.map +1 -0
- package/lib/commonjs/platforms/index.d.ts +3 -0
- package/lib/commonjs/platforms/index.js +35 -0
- package/lib/commonjs/platforms/index.js.map +1 -0
- package/lib/commonjs/platforms/types.d.ts +21 -0
- package/lib/commonjs/platforms/types.js +9 -0
- package/lib/commonjs/platforms/types.js.map +1 -0
- package/lib/esm/bin/qpq.d.ts +2 -0
- package/lib/esm/bin/qpq.js +4 -0
- package/lib/esm/bin/qpq.js.map +1 -0
- package/lib/esm/bin/qpqCdkApp.d.ts +1 -0
- package/lib/esm/bin/qpqCdkApp.js +6 -0
- package/lib/esm/bin/qpqCdkApp.js.map +1 -0
- package/lib/esm/cli/commandMenu.d.ts +2 -0
- package/lib/esm/cli/commandMenu.js +67 -0
- package/lib/esm/cli/commandMenu.js.map +1 -0
- package/lib/esm/cli/commandRegistry.d.ts +10 -0
- package/lib/esm/cli/commandRegistry.js +161 -0
- package/lib/esm/cli/commandRegistry.js.map +1 -0
- package/lib/esm/cli/index.d.ts +1 -0
- package/lib/esm/cli/index.js +2 -0
- package/lib/esm/cli/index.js.map +1 -0
- package/lib/esm/cli/runCli.d.ts +1 -0
- package/lib/esm/cli/runCli.js +73 -0
- package/lib/esm/cli/runCli.js.map +1 -0
- package/lib/esm/commands/checkCircular.d.ts +1 -0
- package/lib/esm/commands/checkCircular.js +55 -0
- package/lib/esm/commands/checkCircular.js.map +1 -0
- package/lib/esm/commands/clearResources.d.ts +1 -0
- package/lib/esm/commands/clearResources.js +23 -0
- package/lib/esm/commands/clearResources.js.map +1 -0
- package/lib/esm/commands/go.d.ts +1 -0
- package/lib/esm/commands/go.js +16 -0
- package/lib/esm/commands/go.js.map +1 -0
- package/lib/esm/commands/goDev.d.ts +1 -0
- package/lib/esm/commands/goDev.js +33 -0
- package/lib/esm/commands/goDev.js.map +1 -0
- package/lib/esm/commands/goDevApi.d.ts +1 -0
- package/lib/esm/commands/goDevApi.js +142 -0
- package/lib/esm/commands/goDevApi.js.map +1 -0
- package/lib/esm/commands/goDevWeb.d.ts +4 -0
- package/lib/esm/commands/goDevWeb.js +129 -0
- package/lib/esm/commands/goDevWeb.js.map +1 -0
- package/lib/esm/commands/goDocker.d.ts +1 -0
- package/lib/esm/commands/goDocker.js +29 -0
- package/lib/esm/commands/goDocker.js.map +1 -0
- package/lib/esm/commands/hooks.d.ts +1 -0
- package/lib/esm/commands/hooks.js +26 -0
- package/lib/esm/commands/hooks.js.map +1 -0
- package/lib/esm/commands/migrate.d.ts +1 -0
- package/lib/esm/commands/migrate.js +57 -0
- package/lib/esm/commands/migrate.js.map +1 -0
- package/lib/esm/commands/prep.d.ts +1 -0
- package/lib/esm/commands/prep.js +15 -0
- package/lib/esm/commands/prep.js.map +1 -0
- package/lib/esm/commands/publish.d.ts +4 -0
- package/lib/esm/commands/publish.js +38 -0
- package/lib/esm/commands/publish.js.map +1 -0
- package/lib/esm/commands/scriptBuild.d.ts +1 -0
- package/lib/esm/commands/scriptBuild.js +29 -0
- package/lib/esm/commands/scriptBuild.js.map +1 -0
- package/lib/esm/commands/scriptBuilderLayer.d.ts +1 -0
- package/lib/esm/commands/scriptBuilderLayer.js +34 -0
- package/lib/esm/commands/scriptBuilderLayer.js.map +1 -0
- package/lib/esm/commands/scriptNew.d.ts +1 -0
- package/lib/esm/commands/scriptNew.js +19 -0
- package/lib/esm/commands/scriptNew.js.map +1 -0
- package/lib/esm/commands/setup.d.ts +1 -0
- package/lib/esm/commands/setup.js +88 -0
- package/lib/esm/commands/setup.js.map +1 -0
- package/lib/esm/commands/synth.d.ts +1 -0
- package/lib/esm/commands/synth.js +73 -0
- package/lib/esm/commands/synth.js.map +1 -0
- package/lib/esm/commands/teardown.d.ts +1 -0
- package/lib/esm/commands/teardown.js +20 -0
- package/lib/esm/commands/teardown.js.map +1 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +2 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/lib/args.d.ts +3 -0
- package/lib/esm/lib/args.js +25 -0
- package/lib/esm/lib/args.js.map +1 -0
- package/lib/esm/lib/circularImports.d.ts +3 -0
- package/lib/esm/lib/circularImports.js +61 -0
- package/lib/esm/lib/circularImports.js.map +1 -0
- package/lib/esm/lib/clearResourcesPlan.d.ts +15 -0
- package/lib/esm/lib/clearResourcesPlan.js +65 -0
- package/lib/esm/lib/clearResourcesPlan.js.map +1 -0
- package/lib/esm/lib/deployPrompts.d.ts +26 -0
- package/lib/esm/lib/deployPrompts.js +103 -0
- package/lib/esm/lib/deployPrompts.js.map +1 -0
- package/lib/esm/lib/devServerEntry.d.ts +22 -0
- package/lib/esm/lib/devServerEntry.js +127 -0
- package/lib/esm/lib/devServerEntry.js.map +1 -0
- package/lib/esm/lib/devServerPorts.d.ts +13 -0
- package/lib/esm/lib/devServerPorts.js +27 -0
- package/lib/esm/lib/devServerPorts.js.map +1 -0
- package/lib/esm/lib/discovery.d.ts +10 -0
- package/lib/esm/lib/discovery.js +40 -0
- package/lib/esm/lib/discovery.js.map +1 -0
- package/lib/esm/lib/getDefaultHookJobs.d.ts +2 -0
- package/lib/esm/lib/getDefaultHookJobs.js +4 -0
- package/lib/esm/lib/getDefaultHookJobs.js.map +1 -0
- package/lib/esm/lib/getDeployTargetLabel.d.ts +2 -0
- package/lib/esm/lib/getDeployTargetLabel.js +8 -0
- package/lib/esm/lib/getDeployTargetLabel.js.map +1 -0
- package/lib/esm/lib/goDockerMode.d.ts +6 -0
- package/lib/esm/lib/goDockerMode.js +19 -0
- package/lib/esm/lib/goDockerMode.js.map +1 -0
- package/lib/esm/lib/hooks.d.ts +9 -0
- package/lib/esm/lib/hooks.js +154 -0
- package/lib/esm/lib/hooks.js.map +1 -0
- package/lib/esm/lib/keepOtherDevServersFlag.d.ts +1 -0
- package/lib/esm/lib/keepOtherDevServersFlag.js +8 -0
- package/lib/esm/lib/keepOtherDevServersFlag.js.map +1 -0
- package/lib/esm/lib/killChildWithEscalation.d.ts +10 -0
- package/lib/esm/lib/killChildWithEscalation.js +29 -0
- package/lib/esm/lib/killChildWithEscalation.js.map +1 -0
- package/lib/esm/lib/killStaleListeners.d.ts +17 -0
- package/lib/esm/lib/killStaleListeners.js +210 -0
- package/lib/esm/lib/killStaleListeners.js.map +1 -0
- package/lib/esm/lib/packageRoot.d.ts +1 -0
- package/lib/esm/lib/packageRoot.js +14 -0
- package/lib/esm/lib/packageRoot.js.map +1 -0
- package/lib/esm/lib/prompts.d.ts +15 -0
- package/lib/esm/lib/prompts.js +28 -0
- package/lib/esm/lib/prompts.js.map +1 -0
- package/lib/esm/lib/qpqConfigs.d.ts +4 -0
- package/lib/esm/lib/qpqConfigs.js +21 -0
- package/lib/esm/lib/qpqConfigs.js.map +1 -0
- package/lib/esm/lib/resolveAppSelection.d.ts +6 -0
- package/lib/esm/lib/resolveAppSelection.js +45 -0
- package/lib/esm/lib/resolveAppSelection.js.map +1 -0
- package/lib/esm/lib/resolveDeployment.d.ts +14 -0
- package/lib/esm/lib/resolveDeployment.js +45 -0
- package/lib/esm/lib/resolveDeployment.js.map +1 -0
- package/lib/esm/lib/runCommand.d.ts +14 -0
- package/lib/esm/lib/runCommand.js +92 -0
- package/lib/esm/lib/runCommand.js.map +1 -0
- package/lib/esm/lib/runTasks.d.ts +15 -0
- package/lib/esm/lib/runTasks.js +108 -0
- package/lib/esm/lib/runTasks.js.map +1 -0
- package/lib/esm/lib/setupStep.d.ts +16 -0
- package/lib/esm/lib/setupStep.js +2 -0
- package/lib/esm/lib/setupStep.js.map +1 -0
- package/lib/esm/lib/timing.d.ts +2 -0
- package/lib/esm/lib/timing.js +6 -0
- package/lib/esm/lib/timing.js.map +1 -0
- package/lib/esm/lib/typeWatcher.d.ts +2 -0
- package/lib/esm/lib/typeWatcher.js +51 -0
- package/lib/esm/lib/typeWatcher.js.map +1 -0
- package/lib/esm/lib/userScriptBuilderLayer.d.ts +23 -0
- package/lib/esm/lib/userScriptBuilderLayer.js +65 -0
- package/lib/esm/lib/userScriptBuilderLayer.js.map +1 -0
- package/lib/esm/lib/userScriptTemplate.d.ts +6 -0
- package/lib/esm/lib/userScriptTemplate.js +39 -0
- package/lib/esm/lib/userScriptTemplate.js.map +1 -0
- package/lib/esm/lib/views.d.ts +2 -0
- package/lib/esm/lib/views.js +14 -0
- package/lib/esm/lib/views.js.map +1 -0
- package/lib/esm/lib/webAddressingEnv.d.ts +7 -0
- package/lib/esm/lib/webAddressingEnv.js +11 -0
- package/lib/esm/lib/webAddressingEnv.js.map +1 -0
- package/lib/esm/platforms/aws/awsCredentials.d.ts +1 -0
- package/lib/esm/platforms/aws/awsCredentials.js +15 -0
- package/lib/esm/platforms/aws/awsCredentials.js.map +1 -0
- package/lib/esm/platforms/aws/cdkApp.d.ts +3 -0
- package/lib/esm/platforms/aws/cdkApp.js +22 -0
- package/lib/esm/platforms/aws/cdkApp.js.map +1 -0
- package/lib/esm/platforms/aws/clearResources.d.ts +2 -0
- package/lib/esm/platforms/aws/clearResources.js +151 -0
- package/lib/esm/platforms/aws/clearResources.js.map +1 -0
- package/lib/esm/platforms/aws/go.d.ts +2 -0
- package/lib/esm/platforms/aws/go.js +115 -0
- package/lib/esm/platforms/aws/go.js.map +1 -0
- package/lib/esm/platforms/aws/goDocker.d.ts +3 -0
- package/lib/esm/platforms/aws/goDocker.js +441 -0
- package/lib/esm/platforms/aws/goDocker.js.map +1 -0
- package/lib/esm/platforms/aws/goDockerManifest.d.ts +44 -0
- package/lib/esm/platforms/aws/goDockerManifest.js +26 -0
- package/lib/esm/platforms/aws/goDockerManifest.js.map +1 -0
- package/lib/esm/platforms/aws/index.d.ts +2 -0
- package/lib/esm/platforms/aws/index.js +20 -0
- package/lib/esm/platforms/aws/index.js.map +1 -0
- package/lib/esm/platforms/aws/prepareDeployment.d.ts +3 -0
- package/lib/esm/platforms/aws/prepareDeployment.js +6 -0
- package/lib/esm/platforms/aws/prepareDeployment.js.map +1 -0
- package/lib/esm/platforms/aws/publish.d.ts +4 -0
- package/lib/esm/platforms/aws/publish.js +50 -0
- package/lib/esm/platforms/aws/publish.js.map +1 -0
- package/lib/esm/platforms/aws/remote.d.ts +11 -0
- package/lib/esm/platforms/aws/remote.js +89 -0
- package/lib/esm/platforms/aws/remote.js.map +1 -0
- package/lib/esm/platforms/aws/setup/awsSetupContext.d.ts +12 -0
- package/lib/esm/platforms/aws/setup/awsSetupContext.js +16 -0
- package/lib/esm/platforms/aws/setup/awsSetupContext.js.map +1 -0
- package/lib/esm/platforms/aws/setup/awsSetupSteps.d.ts +8 -0
- package/lib/esm/platforms/aws/setup/awsSetupSteps.js +31 -0
- package/lib/esm/platforms/aws/setup/awsSetupSteps.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildBucketNamesStep.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/buildBucketNamesStep.js +62 -0
- package/lib/esm/platforms/aws/setup/buildBucketNamesStep.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildCdkBootstrapSteps.d.ts +5 -0
- package/lib/esm/platforms/aws/setup/buildCdkBootstrapSteps.js +24 -0
- package/lib/esm/platforms/aws/setup/buildCdkBootstrapSteps.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.js +40 -0
- package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildGithubOidcProviderStep.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/buildGithubOidcProviderStep.js +40 -0
- package/lib/esm/platforms/aws/setup/buildGithubOidcProviderStep.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildHostedZonesStep.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/buildHostedZonesStep.js +49 -0
- package/lib/esm/platforms/aws/setup/buildHostedZonesStep.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildIamCapabilityStep.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/buildIamCapabilityStep.js +34 -0
- package/lib/esm/platforms/aws/setup/buildIamCapabilityStep.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildIdentityStep.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/buildIdentityStep.js +26 -0
- package/lib/esm/platforms/aws/setup/buildIdentityStep.js.map +1 -0
- package/lib/esm/platforms/aws/setup/buildStackSteps.d.ts +5 -0
- package/lib/esm/platforms/aws/setup/buildStackSteps.js +17 -0
- package/lib/esm/platforms/aws/setup/buildStackSteps.js.map +1 -0
- package/lib/esm/platforms/aws/setup/describeStackStatus.d.ts +4 -0
- package/lib/esm/platforms/aws/setup/describeStackStatus.js +17 -0
- package/lib/esm/platforms/aws/setup/describeStackStatus.js.map +1 -0
- package/lib/esm/platforms/aws/setup/index.d.ts +1 -0
- package/lib/esm/platforms/aws/setup/index.js +2 -0
- package/lib/esm/platforms/aws/setup/index.js.map +1 -0
- package/lib/esm/platforms/aws/stacks.d.ts +7 -0
- package/lib/esm/platforms/aws/stacks.js +72 -0
- package/lib/esm/platforms/aws/stacks.js.map +1 -0
- package/lib/esm/platforms/aws/teardown.d.ts +2 -0
- package/lib/esm/platforms/aws/teardown.js +46 -0
- package/lib/esm/platforms/aws/teardown.js.map +1 -0
- package/lib/esm/platforms/aws/viewsSync.d.ts +3 -0
- package/lib/esm/platforms/aws/viewsSync.js +60 -0
- package/lib/esm/platforms/aws/viewsSync.js.map +1 -0
- package/lib/esm/platforms/docker/QpqDockerPlatformSettings.d.ts +10 -0
- package/lib/esm/platforms/docker/QpqDockerPlatformSettings.js +2 -0
- package/lib/esm/platforms/docker/QpqDockerPlatformSettings.js.map +1 -0
- package/lib/esm/platforms/docker/getContainerPorts.d.ts +4 -0
- package/lib/esm/platforms/docker/getContainerPorts.js +8 -0
- package/lib/esm/platforms/docker/getContainerPorts.js.map +1 -0
- package/lib/esm/platforms/docker/getDefaultPortMappings.d.ts +3 -0
- package/lib/esm/platforms/docker/getDefaultPortMappings.js +6 -0
- package/lib/esm/platforms/docker/getDefaultPortMappings.js.map +1 -0
- package/lib/esm/platforms/docker/getDockerPlatformSettings.d.ts +14 -0
- package/lib/esm/platforms/docker/getDockerPlatformSettings.js +34 -0
- package/lib/esm/platforms/docker/getDockerPlatformSettings.js.map +1 -0
- package/lib/esm/platforms/docker/getImageName.d.ts +6 -0
- package/lib/esm/platforms/docker/getImageName.js +6 -0
- package/lib/esm/platforms/docker/getImageName.js.map +1 -0
- package/lib/esm/platforms/docker/go.d.ts +2 -0
- package/lib/esm/platforms/docker/go.js +242 -0
- package/lib/esm/platforms/docker/go.js.map +1 -0
- package/lib/esm/platforms/docker/index.d.ts +2 -0
- package/lib/esm/platforms/docker/index.js +31 -0
- package/lib/esm/platforms/docker/index.js.map +1 -0
- package/lib/esm/platforms/docker/parseMounts.d.ts +7 -0
- package/lib/esm/platforms/docker/parseMounts.js +23 -0
- package/lib/esm/platforms/docker/parseMounts.js.map +1 -0
- package/lib/esm/platforms/docker/parsePortMappings.d.ts +8 -0
- package/lib/esm/platforms/docker/parsePortMappings.js +21 -0
- package/lib/esm/platforms/docker/parsePortMappings.js.map +1 -0
- package/lib/esm/platforms/docker/resolvePortMappings.d.ts +8 -0
- package/lib/esm/platforms/docker/resolvePortMappings.js +18 -0
- package/lib/esm/platforms/docker/resolvePortMappings.js.map +1 -0
- package/lib/esm/platforms/docker/writeComposeFile.d.ts +20 -0
- package/lib/esm/platforms/docker/writeComposeFile.js +37 -0
- package/lib/esm/platforms/docker/writeComposeFile.js.map +1 -0
- package/lib/esm/platforms/index.d.ts +3 -0
- package/lib/esm/platforms/index.js +17 -0
- package/lib/esm/platforms/index.js.map +1 -0
- package/lib/esm/platforms/types.d.ts +21 -0
- package/lib/esm/platforms/types.js +6 -0
- package/lib/esm/platforms/types.js.map +1 -0
- package/package.json +71 -3
- package/templates/user-script/README.md +28 -0
- package/templates/user-script/gitignore +2 -0
- package/templates/user-script/package.json +16 -0
- package/templates/user-script/src/main.ts +15 -0
- package/templates/user-script/tsconfig.json +12 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';
|
|
2
|
+
import { qpqWebServerUtils } from '@qpqjs/webserver';
|
|
3
|
+
import { ListHostedZonesByNameCommand, Route53Client } from '@aws-sdk/client-route-53';
|
|
4
|
+
// The zones the environment writes records into: one per root, chosen the way the
|
|
5
|
+
// CDK chooses them (each root's site root under the app's resolver, or the root).
|
|
6
|
+
const getRequiredZones = (ctx) => {
|
|
7
|
+
const config = ctx.bootstrapQpqConfig;
|
|
8
|
+
return [
|
|
9
|
+
...new Set(qpqWebServerUtils
|
|
10
|
+
.getRootDomains(config)
|
|
11
|
+
.map((rootDomain) => qpqDeployAwsUtils.resolveHostedZoneForHost(config, qpqDeployAwsUtils.resolveDeployHostForRoot(config, rootDomain, {})))),
|
|
12
|
+
];
|
|
13
|
+
};
|
|
14
|
+
const zoneExists = async (client, zoneName) => {
|
|
15
|
+
const { HostedZones } = await client.send(new ListHostedZonesByNameCommand({ DNSName: zoneName, MaxItems: 1 }));
|
|
16
|
+
return (HostedZones ?? []).some((zone) => zone.Name === `${zoneName}.` && !zone.Config?.PrivateZone);
|
|
17
|
+
};
|
|
18
|
+
const checkHostedZones = async (ctx) => {
|
|
19
|
+
const required = getRequiredZones(ctx);
|
|
20
|
+
if (required.length === 0) {
|
|
21
|
+
return { done: true, detail: 'no domains declared' };
|
|
22
|
+
}
|
|
23
|
+
const client = new Route53Client({ region: ctx.region });
|
|
24
|
+
const missing = [];
|
|
25
|
+
for (const zoneName of required) {
|
|
26
|
+
if (!(await zoneExists(client, zoneName))) {
|
|
27
|
+
missing.push(zoneName);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return missing.length === 0
|
|
31
|
+
? { done: true, detail: required.join(', ') }
|
|
32
|
+
: {
|
|
33
|
+
done: false,
|
|
34
|
+
detail: `missing ${missing.join(', ')}: create each as a public hosted zone here and delegate it (NS record) from its parent zone`,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/** Check-only: the Route53 zones the deploy will write records into exist in this account. */
|
|
38
|
+
export const buildHostedZonesStep = (ctx) => ({
|
|
39
|
+
id: 'hosted-zones',
|
|
40
|
+
name: 'Route53 hosted zones',
|
|
41
|
+
check: () => checkHostedZones(ctx),
|
|
42
|
+
run: async () => {
|
|
43
|
+
const result = await checkHostedZones(ctx);
|
|
44
|
+
if (!result.done) {
|
|
45
|
+
throw new Error(result.detail ?? 'hosted zones missing');
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=buildHostedZonesStep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildHostedZonesStep.js","sourceRoot":"","sources":["../../../../../src/platforms/aws/setup/buildHostedZonesStep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,4BAA4B,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAKvF,kFAAkF;AAClF,kFAAkF;AAClF,MAAM,gBAAgB,GAAG,CAAC,GAAoB,EAAY,EAAE;IAC1D,MAAM,MAAM,GAAG,GAAG,CAAC,kBAAkB,CAAC;IACtC,OAAO;QACL,GAAG,IAAI,GAAG,CACR,iBAAiB;aACd,cAAc,CAAC,MAAM,CAAC;aACtB,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,MAAM,EAAE,iBAAiB,CAAC,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAC/I;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,KAAK,EAAE,MAAqB,EAAE,QAAgB,EAAoB,EAAE;IACrF,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,4BAA4B,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAChH,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACvG,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAoB,EAA6B,EAAE;IACjF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC7C,CAAC,CAAC;YACE,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,WAAW,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,6FAA6F;SACnI,CAAC;AACR,CAAC,CAAC;AAEF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAoB,EAAa,EAAE,CAAC,CAAC;IACxE,EAAE,EAAE,cAAc;IAClB,IAAI,EAAE,sBAAsB;IAC5B,KAAK,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC;IAClC,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,sBAAsB,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';\nimport { qpqWebServerUtils } from '@qpqjs/webserver';\n\nimport { ListHostedZonesByNameCommand, Route53Client } from '@aws-sdk/client-route-53';\n\nimport { SetupCheckResult, SetupStep } from '../../../lib/setupStep';\nimport { AwsSetupContext } from './awsSetupContext';\n\n// The zones the environment writes records into: one per root, chosen the way the\n// CDK chooses them (each root's site root under the app's resolver, or the root).\nconst getRequiredZones = (ctx: AwsSetupContext): string[] => {\n const config = ctx.bootstrapQpqConfig;\n return [\n ...new Set(\n qpqWebServerUtils\n .getRootDomains(config)\n .map((rootDomain) => qpqDeployAwsUtils.resolveHostedZoneForHost(config, qpqDeployAwsUtils.resolveDeployHostForRoot(config, rootDomain, {}))),\n ),\n ];\n};\n\nconst zoneExists = async (client: Route53Client, zoneName: string): Promise<boolean> => {\n const { HostedZones } = await client.send(new ListHostedZonesByNameCommand({ DNSName: zoneName, MaxItems: 1 }));\n return (HostedZones ?? []).some((zone) => zone.Name === `${zoneName}.` && !zone.Config?.PrivateZone);\n};\n\nconst checkHostedZones = async (ctx: AwsSetupContext): Promise<SetupCheckResult> => {\n const required = getRequiredZones(ctx);\n if (required.length === 0) {\n return { done: true, detail: 'no domains declared' };\n }\n\n const client = new Route53Client({ region: ctx.region });\n const missing: string[] = [];\n for (const zoneName of required) {\n if (!(await zoneExists(client, zoneName))) {\n missing.push(zoneName);\n }\n }\n\n return missing.length === 0\n ? { done: true, detail: required.join(', ') }\n : {\n done: false,\n detail: `missing ${missing.join(', ')}: create each as a public hosted zone here and delegate it (NS record) from its parent zone`,\n };\n};\n\n/** Check-only: the Route53 zones the deploy will write records into exist in this account. */\nexport const buildHostedZonesStep = (ctx: AwsSetupContext): SetupStep => ({\n id: 'hosted-zones',\n name: 'Route53 hosted zones',\n check: () => checkHostedZones(ctx),\n run: async () => {\n const result = await checkHostedZones(ctx);\n if (!result.done) {\n throw new Error(result.detail ?? 'hosted zones missing');\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { GetRoleCommand, IAMClient } from '@aws-sdk/client-iam';
|
|
2
|
+
// CDK bootstrap and every deploy create IAM roles. PowerUserAccess fails on the
|
|
3
|
+
// first iam:GetRole for a cdk-* role, so probe exactly that: a NoSuchEntity
|
|
4
|
+
// answer means the permission is there, AccessDenied means it is not.
|
|
5
|
+
const checkIamCapability = async (ctx) => {
|
|
6
|
+
const roleName = `cdk-hnb659fds-cfn-exec-role-${ctx.accountId}-${ctx.region}`;
|
|
7
|
+
try {
|
|
8
|
+
await new IAMClient({ region: ctx.region }).send(new GetRoleCommand({ RoleName: roleName }));
|
|
9
|
+
return { done: true, detail: 'iam:GetRole allowed' };
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
const name = error instanceof Error ? error.name : '';
|
|
13
|
+
if (name === 'NoSuchEntityException') {
|
|
14
|
+
return { done: true, detail: 'iam:GetRole allowed' };
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
done: false,
|
|
18
|
+
detail: `iam:GetRole denied (${name}); the permission set needs IAM rights (AdministratorAccess or a custom set adding iam:*)`,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/** Check-only: the credentials can manage IAM, which every CDK deploy needs. */
|
|
23
|
+
export const buildIamCapabilityStep = (ctx) => ({
|
|
24
|
+
id: 'iam',
|
|
25
|
+
name: 'IAM rights on the credentials',
|
|
26
|
+
check: () => checkIamCapability(ctx),
|
|
27
|
+
run: async () => {
|
|
28
|
+
const result = await checkIamCapability(ctx);
|
|
29
|
+
if (!result.done) {
|
|
30
|
+
throw new Error(result.detail ?? 'IAM rights missing');
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=buildIamCapabilityStep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildIamCapabilityStep.js","sourceRoot":"","sources":["../../../../../src/platforms/aws/setup/buildIamCapabilityStep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAKhE,gFAAgF;AAChF,4EAA4E;AAC5E,sEAAsE;AACtE,MAAM,kBAAkB,GAAG,KAAK,EAAE,GAAoB,EAA6B,EAAE;IACnF,MAAM,QAAQ,GAAG,+BAA+B,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;IAC9E,IAAI,CAAC;QACH,MAAM,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC7F,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;YACrC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QACvD,CAAC;QACD,OAAO;YACL,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,uBAAuB,IAAI,2FAA2F;SAC/H,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAoB,EAAa,EAAE,CAAC,CAAC;IAC1E,EAAE,EAAE,KAAK;IACT,IAAI,EAAE,+BAA+B;IACrC,KAAK,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC;IACpC,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,oBAAoB,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { GetRoleCommand, IAMClient } from '@aws-sdk/client-iam';\n\nimport { SetupCheckResult, SetupStep } from '../../../lib/setupStep';\nimport { AwsSetupContext } from './awsSetupContext';\n\n// CDK bootstrap and every deploy create IAM roles. PowerUserAccess fails on the\n// first iam:GetRole for a cdk-* role, so probe exactly that: a NoSuchEntity\n// answer means the permission is there, AccessDenied means it is not.\nconst checkIamCapability = async (ctx: AwsSetupContext): Promise<SetupCheckResult> => {\n const roleName = `cdk-hnb659fds-cfn-exec-role-${ctx.accountId}-${ctx.region}`;\n try {\n await new IAMClient({ region: ctx.region }).send(new GetRoleCommand({ RoleName: roleName }));\n return { done: true, detail: 'iam:GetRole allowed' };\n } catch (error) {\n const name = error instanceof Error ? error.name : '';\n if (name === 'NoSuchEntityException') {\n return { done: true, detail: 'iam:GetRole allowed' };\n }\n return {\n done: false,\n detail: `iam:GetRole denied (${name}); the permission set needs IAM rights (AdministratorAccess or a custom set adding iam:*)`,\n };\n }\n};\n\n/** Check-only: the credentials can manage IAM, which every CDK deploy needs. */\nexport const buildIamCapabilityStep = (ctx: AwsSetupContext): SetupStep => ({\n id: 'iam',\n name: 'IAM rights on the credentials',\n check: () => checkIamCapability(ctx),\n run: async () => {\n const result = await checkIamCapability(ctx);\n if (!result.done) {\n throw new Error(result.detail ?? 'IAM rights missing');\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { SetupStep } from '../../../lib/setupStep';
|
|
2
|
+
import { AwsSetupContext } from './awsSetupContext';
|
|
3
|
+
/** Check-only: the active credentials belong to the environment's account. Catches a stale .env or SSO profile. */
|
|
4
|
+
export declare const buildIdentityStep: (ctx: AwsSetupContext) => SetupStep;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
|
|
2
|
+
const checkIdentity = async (ctx) => {
|
|
3
|
+
try {
|
|
4
|
+
const { Account, Arn } = await new STSClient({ region: ctx.region }).send(new GetCallerIdentityCommand({}));
|
|
5
|
+
if (Account !== ctx.accountId) {
|
|
6
|
+
return { done: false, detail: `credentials are for account ${Account}, environment '${ctx.environment}' deploys to ${ctx.accountId}` };
|
|
7
|
+
}
|
|
8
|
+
return { done: true, detail: `${Arn}` };
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
return { done: false, detail: `no valid credentials: ${error instanceof Error ? error.message : String(error)}` };
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/** Check-only: the active credentials belong to the environment's account. Catches a stale .env or SSO profile. */
|
|
15
|
+
export const buildIdentityStep = (ctx) => ({
|
|
16
|
+
id: 'identity',
|
|
17
|
+
name: `Credentials for account ${ctx.accountId}`,
|
|
18
|
+
check: () => checkIdentity(ctx),
|
|
19
|
+
run: async () => {
|
|
20
|
+
const result = await checkIdentity(ctx);
|
|
21
|
+
if (!result.done) {
|
|
22
|
+
throw new Error(`${result.detail}. Log in to the right account (or fix the deployment in deploy.config.json) and rerun.`);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=buildIdentityStep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildIdentityStep.js","sourceRoot":"","sources":["../../../../../src/platforms/aws/setup/buildIdentityStep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAK1E,MAAM,aAAa,GAAG,KAAK,EAAE,GAAoB,EAA6B,EAAE;IAC9E,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5G,IAAI,OAAO,KAAK,GAAG,CAAC,SAAS,EAAE,CAAC;YAC9B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,OAAO,kBAAkB,GAAG,CAAC,WAAW,gBAAgB,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC;QACzI,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IACpH,CAAC;AACH,CAAC,CAAC;AAEF,mHAAmH;AACnH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,GAAoB,EAAa,EAAE,CAAC,CAAC;IACrE,EAAE,EAAE,UAAU;IACd,IAAI,EAAE,2BAA2B,GAAG,CAAC,SAAS,EAAE;IAChD,KAAK,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC;IAC/B,GAAG,EAAE,KAAK,IAAI,EAAE;QACd,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,wFAAwF,CAAC,CAAC;QAC5H,CAAC;IACH,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';\n\nimport { SetupCheckResult, SetupStep } from '../../../lib/setupStep';\nimport { AwsSetupContext } from './awsSetupContext';\n\nconst checkIdentity = async (ctx: AwsSetupContext): Promise<SetupCheckResult> => {\n try {\n const { Account, Arn } = await new STSClient({ region: ctx.region }).send(new GetCallerIdentityCommand({}));\n if (Account !== ctx.accountId) {\n return { done: false, detail: `credentials are for account ${Account}, environment '${ctx.environment}' deploys to ${ctx.accountId}` };\n }\n return { done: true, detail: `${Arn}` };\n } catch (error) {\n return { done: false, detail: `no valid credentials: ${error instanceof Error ? error.message : String(error)}` };\n }\n};\n\n/** Check-only: the active credentials belong to the environment's account. Catches a stale .env or SSO profile. */\nexport const buildIdentityStep = (ctx: AwsSetupContext): SetupStep => ({\n id: 'identity',\n name: `Credentials for account ${ctx.accountId}`,\n check: () => checkIdentity(ctx),\n run: async () => {\n const result = await checkIdentity(ctx);\n if (!result.done) {\n throw new Error(`${result.detail}. Log in to the right account (or fix the deployment in deploy.config.json) and rerun.`);\n }\n },\n});\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SetupStep } from '../../../lib/setupStep';
|
|
2
|
+
import { AwsSetupContext } from './awsSetupContext';
|
|
3
|
+
export declare const buildAccountStackStep: (ctx: AwsSetupContext) => SetupStep;
|
|
4
|
+
export declare const buildDomainStackStep: (ctx: AwsSetupContext) => SetupStep;
|
|
5
|
+
export declare const buildBootstrapStackStep: (ctx: AwsSetupContext) => SetupStep;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';
|
|
2
|
+
import { deployAccountStack, deployBootstrapStack, deployDomainStack } from '../stacks';
|
|
3
|
+
import { describeStackStatus, isStackHealthy } from './describeStackStatus';
|
|
4
|
+
const buildStackStep = (id, name, stackName, region, run) => ({
|
|
5
|
+
id,
|
|
6
|
+
name: `${name} (${stackName})`,
|
|
7
|
+
check: async () => {
|
|
8
|
+
const status = await describeStackStatus(stackName, region);
|
|
9
|
+
return status === null ? { done: false, detail: 'not deployed' } : { done: isStackHealthy(status), detail: status };
|
|
10
|
+
},
|
|
11
|
+
run,
|
|
12
|
+
});
|
|
13
|
+
export const buildAccountStackStep = (ctx) => buildStackStep('account-stack', 'Account guardrails stack', qpqDeployAwsUtils.getAccountStackName(), ctx.region, () => deployAccountStack(ctx.appName));
|
|
14
|
+
// The domain stack deploys its cert stacks as dependencies, so one step covers certificates too.
|
|
15
|
+
export const buildDomainStackStep = (ctx) => buildStackStep('domain-stack', 'Domain stack: certificates + api domains', qpqDeployAwsUtils.getDomainStackName(ctx.bootstrapQpqConfig), ctx.region, () => deployDomainStack(ctx.appName));
|
|
16
|
+
export const buildBootstrapStackStep = (ctx) => buildStackStep('bootstrap-stack', 'Bootstrap stack: WAF and app-wide resources', qpqDeployAwsUtils.getBootstrapStackName(ctx.bootstrapQpqConfig), ctx.region, () => deployBootstrapStack(ctx.appName));
|
|
17
|
+
//# sourceMappingURL=buildStackSteps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildStackSteps.js","sourceRoot":"","sources":["../../../../../src/platforms/aws/setup/buildStackSteps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAExF,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5E,MAAM,cAAc,GAAG,CAAC,EAAU,EAAE,IAAY,EAAE,SAAiB,EAAE,MAAc,EAAE,GAAwB,EAAa,EAAE,CAAC,CAAC;IAC5H,EAAE;IACF,IAAI,EAAE,GAAG,IAAI,KAAK,SAAS,GAAG;IAC9B,KAAK,EAAE,KAAK,IAAI,EAAE;QAChB,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC5D,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACtH,CAAC;IACD,GAAG;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAoB,EAAa,EAAE,CACvE,cAAc,CAAC,eAAe,EAAE,0BAA0B,EAAE,iBAAiB,CAAC,mBAAmB,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CACpH,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAChC,CAAC;AAEJ,iGAAiG;AACjG,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAoB,EAAa,EAAE,CACtE,cAAc,CACZ,cAAc,EACd,0CAA0C,EAC1C,iBAAiB,CAAC,kBAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAC5D,GAAG,CAAC,MAAM,EACV,GAAG,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CACrC,CAAC;AAEJ,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAoB,EAAa,EAAE,CACzE,cAAc,CACZ,iBAAiB,EACjB,6CAA6C,EAC7C,iBAAiB,CAAC,qBAAqB,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAC/D,GAAG,CAAC,MAAM,EACV,GAAG,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CACxC,CAAC","sourcesContent":["import { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';\n\nimport { SetupStep } from '../../../lib/setupStep';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from '../stacks';\nimport { AwsSetupContext } from './awsSetupContext';\nimport { describeStackStatus, isStackHealthy } from './describeStackStatus';\n\nconst buildStackStep = (id: string, name: string, stackName: string, region: string, run: () => Promise<void>): SetupStep => ({\n id,\n name: `${name} (${stackName})`,\n check: async () => {\n const status = await describeStackStatus(stackName, region);\n return status === null ? { done: false, detail: 'not deployed' } : { done: isStackHealthy(status), detail: status };\n },\n run,\n});\n\nexport const buildAccountStackStep = (ctx: AwsSetupContext): SetupStep =>\n buildStackStep('account-stack', 'Account guardrails stack', qpqDeployAwsUtils.getAccountStackName(), ctx.region, () =>\n deployAccountStack(ctx.appName),\n );\n\n// The domain stack deploys its cert stacks as dependencies, so one step covers certificates too.\nexport const buildDomainStackStep = (ctx: AwsSetupContext): SetupStep =>\n buildStackStep(\n 'domain-stack',\n 'Domain stack: certificates + api domains',\n qpqDeployAwsUtils.getDomainStackName(ctx.bootstrapQpqConfig),\n ctx.region,\n () => deployDomainStack(ctx.appName),\n );\n\nexport const buildBootstrapStackStep = (ctx: AwsSetupContext): SetupStep =>\n buildStackStep(\n 'bootstrap-stack',\n 'Bootstrap stack: WAF and app-wide resources',\n qpqDeployAwsUtils.getBootstrapStackName(ctx.bootstrapQpqConfig),\n ctx.region,\n () => deployBootstrapStack(ctx.appName),\n );\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Nullable } from '@qpqjs/core';
|
|
2
|
+
/** A stack's status, or null when it does not exist. */
|
|
3
|
+
export declare const describeStackStatus: (stackName: string, region: string) => Promise<Nullable<string>>;
|
|
4
|
+
export declare const isStackHealthy: (status: Nullable<string>) => boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CloudFormationClient, DescribeStacksCommand } from '@aws-sdk/client-cloudformation';
|
|
2
|
+
/** A stack's status, or null when it does not exist. */
|
|
3
|
+
export const describeStackStatus = async (stackName, region) => {
|
|
4
|
+
try {
|
|
5
|
+
const { Stacks } = await new CloudFormationClient({ region }).send(new DescribeStacksCommand({ StackName: stackName }));
|
|
6
|
+
return Stacks?.[0]?.StackStatus ?? null;
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
if (error instanceof Error && /does not exist/.test(error.message)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const healthyStatuses = ['CREATE_COMPLETE', 'UPDATE_COMPLETE', 'IMPORT_COMPLETE'];
|
|
16
|
+
export const isStackHealthy = (status) => status !== null && healthyStatuses.includes(status);
|
|
17
|
+
//# sourceMappingURL=describeStackStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describeStackStatus.js","sourceRoot":"","sources":["../../../../../src/platforms/aws/setup/describeStackStatus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE7F,wDAAwD;AACxD,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,SAAiB,EAAE,MAAc,EAA6B,EAAE;IACxG,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QACxH,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,IAAI,CAAC;IAC1C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACnE,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AAElF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAwB,EAAW,EAAE,CAAC,MAAM,KAAK,IAAI,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC","sourcesContent":["import { Nullable } from '@qpqjs/core';\n\nimport { CloudFormationClient, DescribeStacksCommand } from '@aws-sdk/client-cloudformation';\n\n/** A stack's status, or null when it does not exist. */\nexport const describeStackStatus = async (stackName: string, region: string): Promise<Nullable<string>> => {\n try {\n const { Stacks } = await new CloudFormationClient({ region }).send(new DescribeStacksCommand({ StackName: stackName }));\n return Stacks?.[0]?.StackStatus ?? null;\n } catch (error) {\n if (error instanceof Error && /does not exist/.test(error.message)) {\n return null;\n }\n throw error;\n }\n};\n\nconst healthyStatuses = ['CREATE_COMPLETE', 'UPDATE_COMPLETE', 'IMPORT_COMPLETE'];\n\nexport const isStackHealthy = (status: Nullable<string>): boolean => status !== null && healthyStatuses.includes(status);\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './awsSetupSteps';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/platforms/aws/setup/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './awsSetupSteps';\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const deployStack: (stackName: string, env?: Record<string, string>) => Promise<void>;
|
|
2
|
+
export declare const deployServiceStack: (serviceName: string, stackName: string, appName: string) => Promise<void>;
|
|
3
|
+
export declare const destroyStack: (stackName: string, env?: Record<string, string>) => Promise<void>;
|
|
4
|
+
export declare const destroyServiceStack: (serviceName: string, stackName: string, appName: string) => Promise<void>;
|
|
5
|
+
export declare const deployDomainStack: (appName: string) => Promise<void>;
|
|
6
|
+
export declare const deployAccountStack: (appName: string) => Promise<void>;
|
|
7
|
+
export declare const deployBootstrapStack: (appName: string) => Promise<void>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Host-side `cdk deploy` helpers. No cdk.json anywhere: the CDK app command is
|
|
2
|
+
// passed via --app and runs @qpqjs/deploy-aws's generic workspace app
|
|
3
|
+
// (bin/qpq-cdk-app.js) under ts-node hooks. The child inherits the primed
|
|
4
|
+
// deployment env (DEPLOY_APP_NAME / DEPLOY_NAME and everything resolveDeployment
|
|
5
|
+
// set); only the per-invocation service is added here.
|
|
6
|
+
import { QpqDeployEnvVar } from '@qpqjs/core';
|
|
7
|
+
import { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { getRoot, getServiceNames } from '../../lib/discovery';
|
|
10
|
+
import { getAppPrefix, loadServiceQpqConfig } from '../../lib/qpqConfigs';
|
|
11
|
+
import { runCommand } from '../../lib/runCommand';
|
|
12
|
+
import { logTimeEnd, logTimeStart } from '../../lib/timing';
|
|
13
|
+
import { getCdkAppCommand } from './cdkApp';
|
|
14
|
+
export const deployStack = async (stackName, env = {}) => {
|
|
15
|
+
logTimeStart(stackName);
|
|
16
|
+
await runCommand('npx', ['cdk', 'deploy', stackName, '--require-approval', 'never', '--app', `'${getCdkAppCommand()}'`, '--output', path.join('dist', 'qpq', 'cdk.out')], {
|
|
17
|
+
cwd: getRoot(),
|
|
18
|
+
env,
|
|
19
|
+
});
|
|
20
|
+
logTimeEnd(stackName);
|
|
21
|
+
};
|
|
22
|
+
export const deployServiceStack = (serviceName, stackName, appName) => deployStack(stackName, {
|
|
23
|
+
DEPLOY_SERVICE_NAME: serviceName,
|
|
24
|
+
DEPLOY_APP_NAME: appName,
|
|
25
|
+
});
|
|
26
|
+
// `cdk destroy` still synths the app to find the stack, so it runs the same
|
|
27
|
+
// generic workspace app with the same DEPLOY_* env as deploys — meaning the
|
|
28
|
+
// service bundles under dist/ must exist for asset resolution to succeed.
|
|
29
|
+
export const destroyStack = async (stackName, env = {}) => {
|
|
30
|
+
logTimeStart(stackName);
|
|
31
|
+
await runCommand('npx', ['cdk', 'destroy', stackName, '--force', '--app', `'${getCdkAppCommand()}'`, '--output', path.join('dist', 'qpq', 'cdk.out')], {
|
|
32
|
+
cwd: getRoot(),
|
|
33
|
+
env,
|
|
34
|
+
});
|
|
35
|
+
logTimeEnd(stackName);
|
|
36
|
+
};
|
|
37
|
+
export const destroyServiceStack = (serviceName, stackName, appName) => destroyStack(stackName, {
|
|
38
|
+
DEPLOY_SERVICE_NAME: serviceName,
|
|
39
|
+
DEPLOY_APP_NAME: appName,
|
|
40
|
+
});
|
|
41
|
+
export const deployDomainStack = async (appName) => {
|
|
42
|
+
const qpqConfig = loadServiceQpqConfig(appName, getServiceNames(appName)[0]);
|
|
43
|
+
const stackName = qpqDeployAwsUtils.getDomainStackName(qpqConfig);
|
|
44
|
+
console.log('Deploy Domain: ', stackName);
|
|
45
|
+
await deployStack(stackName, {
|
|
46
|
+
DEPLOY_SERVICE_NAME: '',
|
|
47
|
+
DEPLOY_APP_NAME: appName,
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
// Account-level guardrails stack - statically named (one per AWS account,
|
|
51
|
+
// app-agnostic), so no config load is needed to know the name. Callers decide
|
|
52
|
+
// whether an actor deploy should include it (bootstrap skips it; the explicit
|
|
53
|
+
// 'account' menu option always deploys).
|
|
54
|
+
export const deployAccountStack = async (appName) => {
|
|
55
|
+
const stackName = qpqDeployAwsUtils.getAccountStackName();
|
|
56
|
+
console.log('Deploy Account: ', stackName);
|
|
57
|
+
await deployStack(stackName, {
|
|
58
|
+
DEPLOY_SERVICE_NAME: '',
|
|
59
|
+
DEPLOY_APP_NAME: appName,
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
export const deployBootstrapStack = async (appName) => {
|
|
63
|
+
const appPrefix = getAppPrefix(appName);
|
|
64
|
+
const environment = process.env[QpqDeployEnvVar.environment];
|
|
65
|
+
const feature = process.env[QpqDeployEnvVar.featureName];
|
|
66
|
+
const stackName = feature ? `${appPrefix}-${environment}-${feature}-bs` : `${appPrefix}-${environment}-bs`;
|
|
67
|
+
await deployStack(stackName, {
|
|
68
|
+
DEPLOY_SERVICE_NAME: '',
|
|
69
|
+
DEPLOY_APP_NAME: appName,
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=stacks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stacks.js","sourceRoot":"","sources":["../../../../src/platforms/aws/stacks.ts"],"names":[],"mappings":"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","sourcesContent":["// Host-side `cdk deploy` helpers. No cdk.json anywhere: the CDK app command is\n// passed via --app and runs @qpqjs/deploy-aws's generic workspace app\n// (bin/qpq-cdk-app.js) under ts-node hooks. The child inherits the primed\n// deployment env (DEPLOY_APP_NAME / DEPLOY_NAME and everything resolveDeployment\n// set); only the per-invocation service is added here.\nimport { QpqDeployEnvVar } from '@qpqjs/core';\nimport { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';\n\nimport path from 'path';\n\nimport { getRoot, getServiceNames } from '../../lib/discovery';\nimport { getAppPrefix, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runCommand } from '../../lib/runCommand';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { getCdkAppCommand } from './cdkApp';\n\nexport const deployStack = async (stackName: string, env: Record<string, string> = {}): Promise<void> => {\n logTimeStart(stackName);\n await runCommand(\n 'npx',\n ['cdk', 'deploy', stackName, '--require-approval', 'never', '--app', `'${getCdkAppCommand()}'`, '--output', path.join('dist', 'qpq', 'cdk.out')],\n {\n cwd: getRoot(),\n env,\n },\n );\n logTimeEnd(stackName);\n};\n\nexport const deployServiceStack = (serviceName: string, stackName: string, appName: string): Promise<void> =>\n deployStack(stackName, {\n DEPLOY_SERVICE_NAME: serviceName,\n DEPLOY_APP_NAME: appName,\n });\n\n// `cdk destroy` still synths the app to find the stack, so it runs the same\n// generic workspace app with the same DEPLOY_* env as deploys — meaning the\n// service bundles under dist/ must exist for asset resolution to succeed.\nexport const destroyStack = async (stackName: string, env: Record<string, string> = {}): Promise<void> => {\n logTimeStart(stackName);\n await runCommand(\n 'npx',\n ['cdk', 'destroy', stackName, '--force', '--app', `'${getCdkAppCommand()}'`, '--output', path.join('dist', 'qpq', 'cdk.out')],\n {\n cwd: getRoot(),\n env,\n },\n );\n logTimeEnd(stackName);\n};\n\nexport const destroyServiceStack = (serviceName: string, stackName: string, appName: string): Promise<void> =>\n destroyStack(stackName, {\n DEPLOY_SERVICE_NAME: serviceName,\n DEPLOY_APP_NAME: appName,\n });\n\nexport const deployDomainStack = async (appName: string): Promise<void> => {\n const qpqConfig = loadServiceQpqConfig(appName, getServiceNames(appName)[0]);\n const stackName = qpqDeployAwsUtils.getDomainStackName(qpqConfig);\n console.log('Deploy Domain: ', stackName);\n await deployStack(stackName, {\n DEPLOY_SERVICE_NAME: '',\n DEPLOY_APP_NAME: appName,\n });\n};\n\n// Account-level guardrails stack - statically named (one per AWS account,\n// app-agnostic), so no config load is needed to know the name. Callers decide\n// whether an actor deploy should include it (bootstrap skips it; the explicit\n// 'account' menu option always deploys).\nexport const deployAccountStack = async (appName: string): Promise<void> => {\n const stackName = qpqDeployAwsUtils.getAccountStackName();\n console.log('Deploy Account: ', stackName);\n await deployStack(stackName, {\n DEPLOY_SERVICE_NAME: '',\n DEPLOY_APP_NAME: appName,\n });\n};\n\nexport const deployBootstrapStack = async (appName: string): Promise<void> => {\n const appPrefix = getAppPrefix(appName);\n const environment = process.env[QpqDeployEnvVar.environment];\n const feature = process.env[QpqDeployEnvVar.featureName];\n const stackName = feature ? `${appPrefix}-${environment}-${feature}-bs` : `${appPrefix}-${environment}-bs`;\n await deployStack(stackName, {\n DEPLOY_SERVICE_NAME: '',\n DEPLOY_APP_NAME: appName,\n });\n};\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// AWS sequential teardown (`qpq teardown`) — the stack phases of `qpq go` in
|
|
2
|
+
// reverse. Per phase it destroys every selected service's web, then api, then
|
|
3
|
+
// inf CDK stacks. Phases don't cross-reference each other's CFN outputs
|
|
4
|
+
// (values flow through SSM), so this order is prudence, not a hard dependency.
|
|
5
|
+
// Bootstrap, domain and account stacks are deliberately out of scope — they
|
|
6
|
+
// outlive any one service and are torn down by hand if ever.
|
|
7
|
+
import { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';
|
|
8
|
+
import { synthCommand } from '../../commands/synth';
|
|
9
|
+
import { loadServiceQpqConfig } from '../../lib/qpqConfigs';
|
|
10
|
+
import { logTimeEnd, logTimeStart } from '../../lib/timing';
|
|
11
|
+
import { isAwsCredentialsValid } from './awsCredentials';
|
|
12
|
+
import { destroyServiceStack } from './stacks';
|
|
13
|
+
const teardownPhases = [
|
|
14
|
+
{ label: 'Web', getStackName: qpqDeployAwsUtils.getWebStackName },
|
|
15
|
+
{ label: 'Api', getStackName: qpqDeployAwsUtils.getApiStackName },
|
|
16
|
+
{ label: 'Inf', getStackName: qpqDeployAwsUtils.getInfStackName },
|
|
17
|
+
];
|
|
18
|
+
export const awsTeardown = async (appName, plan) => {
|
|
19
|
+
if (plan.kind === 'cancelled') {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const { services } = plan;
|
|
23
|
+
console.log('\n\nRunning automated teardown\n\n');
|
|
24
|
+
console.log('Executing for services');
|
|
25
|
+
console.log(services.join(', '));
|
|
26
|
+
if ((await isAwsCredentialsValid()) === false) {
|
|
27
|
+
console.log('Credentials are expired or invalid.');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
logTimeStart('totalTime');
|
|
31
|
+
// The stack-name utils and the cdk app both read the synthed QPQ configs.
|
|
32
|
+
await services.reduce(async (cur, service) => {
|
|
33
|
+
await cur;
|
|
34
|
+
await synthCommand([service, '--app', appName]);
|
|
35
|
+
}, Promise.resolve());
|
|
36
|
+
for (const { label, getStackName } of teardownPhases) {
|
|
37
|
+
await services.reduce(async (cur, service) => {
|
|
38
|
+
await cur;
|
|
39
|
+
const qpqConfigForService = loadServiceQpqConfig(appName, service);
|
|
40
|
+
console.log(`Destroy ${label}: `, service);
|
|
41
|
+
await destroyServiceStack(service, getStackName(qpqConfigForService), appName);
|
|
42
|
+
}, Promise.resolve());
|
|
43
|
+
}
|
|
44
|
+
logTimeEnd('totalTime');
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=teardown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teardown.js","sourceRoot":"","sources":["../../../../src/platforms/aws/teardown.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,wEAAwE;AACxE,+EAA+E;AAC/E,4EAA4E;AAC5E,6DAA6D;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,MAAM,cAAc,GAAG;IACrB,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,CAAC,eAAe,EAAE;IACjE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,CAAC,eAAe,EAAE;IACjE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,CAAC,eAAe,EAAE;CAClE,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,OAAe,EAAE,IAAkB,EAAiB,EAAE;IACtF,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE1B,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjC,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,0EAA0E;IAC1E,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;QAC3C,MAAM,GAAG,CAAC;QACV,MAAM,YAAY,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEtB,KAAK,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,cAAc,EAAE,CAAC;QACrD,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;YAC3C,MAAM,GAAG,CAAC;YACV,MAAM,mBAAmB,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3C,MAAM,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,CAAC;QACjF,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,UAAU,CAAC,WAAW,CAAC,CAAC;AAC1B,CAAC,CAAC","sourcesContent":["// AWS sequential teardown (`qpq teardown`) — the stack phases of `qpq go` in\n// reverse. Per phase it destroys every selected service's web, then api, then\n// inf CDK stacks. Phases don't cross-reference each other's CFN outputs\n// (values flow through SSM), so this order is prudence, not a hard dependency.\n// Bootstrap, domain and account stacks are deliberately out of scope — they\n// outlive any one service and are torn down by hand if ever.\nimport { qpqDeployAwsUtils } from '@qpqjs/deploy-aws';\n\nimport { synthCommand } from '../../commands/synth';\nimport { TeardownPlan } from '../../lib/deployPrompts';\nimport { loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { destroyServiceStack } from './stacks';\n\nconst teardownPhases = [\n { label: 'Web', getStackName: qpqDeployAwsUtils.getWebStackName },\n { label: 'Api', getStackName: qpqDeployAwsUtils.getApiStackName },\n { label: 'Inf', getStackName: qpqDeployAwsUtils.getInfStackName },\n];\n\nexport const awsTeardown = async (appName: string, plan: TeardownPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n const { services } = plan;\n\n console.log('\\n\\nRunning automated teardown\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n // The stack-name utils and the cdk app both read the synthed QPQ configs.\n await services.reduce(async (cur, service) => {\n await cur;\n await synthCommand([service, '--app', appName]);\n }, Promise.resolve());\n\n for (const { label, getStackName } of teardownPhases) {\n await services.reduce(async (cur, service) => {\n await cur;\n const qpqConfigForService = loadServiceQpqConfig(appName, service);\n console.log(`Destroy ${label}: `, service);\n await destroyServiceStack(service, getStackName(qpqConfigForService), appName);\n }, Promise.resolve());\n }\n\n logTimeEnd('totalTime');\n};\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Views upload to S3. Every service's views go to its prefix in the shared
|
|
2
|
+
// 'views' bucket (owned by shell). A service can also be a standalone host on
|
|
3
|
+
// its own domain: each of its web entries marked `storageDrive.syncServiceViews`
|
|
4
|
+
// gets the bundle at its drive's root. shell is the root website, which predates
|
|
5
|
+
// that flag, so it keeps its 'website' bucket root when it declares none.
|
|
6
|
+
import { awsNamingUtils } from '@qpqjs/actionprocessor-aws';
|
|
7
|
+
import { qpqWebServerUtils } from '@qpqjs/webserver';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { loadServiceQpqConfig } from '../../lib/qpqConfigs';
|
|
11
|
+
import { runCommand } from '../../lib/runCommand';
|
|
12
|
+
import { getViewsDistDir } from '../../lib/views';
|
|
13
|
+
// The mutable entry points: fixed names whose CONTENT changes every deploy. They
|
|
14
|
+
// must never be cached without revalidation — a browser holding a stale
|
|
15
|
+
// mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle
|
|
16
|
+
// (the module-reload hot-swap and plain page refreshes both depend on these being
|
|
17
|
+
// fresh). Everything else in a views dist is content-hashed and safely immutable.
|
|
18
|
+
export const NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];
|
|
19
|
+
export const getViewsS3Destinations = (appName, serviceName) => {
|
|
20
|
+
const shellConfig = loadServiceQpqConfig(appName, 'shell');
|
|
21
|
+
const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);
|
|
22
|
+
const destinations = [`s3://${viewsBucketName}/${serviceName}`];
|
|
23
|
+
const serviceConfig = serviceName === 'shell' ? shellConfig : loadServiceQpqConfig(appName, serviceName);
|
|
24
|
+
const hostDrives = qpqWebServerUtils
|
|
25
|
+
.getWebEntryConfigs(serviceConfig)
|
|
26
|
+
.filter((webEntry) => webEntry.storageDrive.syncServiceViews && webEntry.storageDrive.sourceStorageDrive)
|
|
27
|
+
.map((webEntry) => webEntry.storageDrive.sourceStorageDrive);
|
|
28
|
+
if (serviceName === 'shell' && hostDrives.length === 0) {
|
|
29
|
+
hostDrives.push('website');
|
|
30
|
+
}
|
|
31
|
+
for (const drive of hostDrives) {
|
|
32
|
+
destinations.push(`s3://${awsNamingUtils.getConfigRuntimeResourceNameFromConfig(drive, serviceConfig)}`);
|
|
33
|
+
}
|
|
34
|
+
return destinations;
|
|
35
|
+
};
|
|
36
|
+
export const syncViewsToS3 = async (appName, serviceName) => {
|
|
37
|
+
const distDir = getViewsDistDir(appName, serviceName);
|
|
38
|
+
for (const destination of getViewsS3Destinations(appName, serviceName)) {
|
|
39
|
+
console.log(`Copying [${serviceName}] views to [${destination}]`);
|
|
40
|
+
// Content-hashed assets: cache forever.
|
|
41
|
+
await runCommand('aws', [
|
|
42
|
+
's3',
|
|
43
|
+
'sync',
|
|
44
|
+
distDir,
|
|
45
|
+
destination,
|
|
46
|
+
'--cache-control',
|
|
47
|
+
'public,max-age=31536000,immutable',
|
|
48
|
+
...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
|
|
49
|
+
]);
|
|
50
|
+
// Entry points: cp (not sync) so the no-cache header is (re)applied on every
|
|
51
|
+
// deploy even when a body happens to be byte-identical.
|
|
52
|
+
for (const file of NO_CACHE_FILES) {
|
|
53
|
+
if (!fs.existsSync(path.join(distDir, file))) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
await runCommand('aws', ['s3', 'cp', path.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=viewsSync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":"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","sourcesContent":["// Views upload to S3. Every service's views go to its prefix in the shared\n// 'views' bucket (owned by shell). A service can also be a standalone host on\n// its own domain: each of its web entries marked `storageDrive.syncServiceViews`\n// gets the bundle at its drive's root. shell is the root website, which predates\n// that flag, so it keeps its 'website' bucket root when it declares none.\nimport { awsNamingUtils } from '@qpqjs/actionprocessor-aws';\nimport { qpqWebServerUtils } from '@qpqjs/webserver';\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 const serviceConfig = serviceName === 'shell' ? shellConfig : loadServiceQpqConfig(appName, serviceName);\n const hostDrives = qpqWebServerUtils\n .getWebEntryConfigs(serviceConfig)\n .filter((webEntry) => webEntry.storageDrive.syncServiceViews && webEntry.storageDrive.sourceStorageDrive)\n .map((webEntry) => webEntry.storageDrive.sourceStorageDrive!);\n\n if (serviceName === 'shell' && hostDrives.length === 0) {\n hostDrives.push('website');\n }\n\n for (const drive of hostDrives) {\n destinations.push(`s3://${awsNamingUtils.getConfigRuntimeResourceNameFromConfig(drive, serviceConfig)}`);\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"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The docker entry's `platformSettings`: how the image is named, built and mapped onto a host. */
|
|
2
|
+
export type QpqDockerPlatformSettings = {
|
|
3
|
+
portMappings?: string;
|
|
4
|
+
registry?: string;
|
|
5
|
+
arch?: string;
|
|
6
|
+
tag?: string;
|
|
7
|
+
publicHost?: string;
|
|
8
|
+
dataPath?: string;
|
|
9
|
+
mounts?: string;
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QpqDockerPlatformSettings.js","sourceRoot":"","sources":["../../../../src/platforms/docker/QpqDockerPlatformSettings.ts"],"names":[],"mappings":"","sourcesContent":["/** The docker entry's `platformSettings`: how the image is named, built and mapped onto a host. */\nexport type QpqDockerPlatformSettings = {\n // Comma-separated docker `host:container` pairs, e.g. \"80:8080, 8888:8888, 3090:3090\". Container\n // ports are 8080 (api + site), 8888 (websockets), 3001 (file storage), plus the port of every\n // web entry listed in a service's defineDevServerOptions. Default: 80 to the site and every\n // container port to itself. The host side is baked into the frontend, so a host must map the\n // same ports.\n portMappings?: string;\n\n // Registry to push the image to, e.g. \"192.168.8.88:5000\" or \"ghcr.io/me\". Without it the image\n // only lands in the local docker store.\n registry?: string;\n\n // Target platform for the image, e.g. \"linux/amd64\" for an x86 host built from an arm Mac.\n // Default: the building machine's own.\n arch?: string;\n\n // Image tag. Default: the deployment's environment.\n tag?: string;\n\n // The address browsers reach the host on, e.g. \"192.168.8.88\" or \"unraid.local\". Secure file\n // upload/download urls are absolute and point here. Default: localhost.\n publicHost?: string;\n\n // Host directory for the app's state (key-value stores, file storage), e.g.\n // \"/mnt/user/appdata/qpq-myapp\". Default: a docker named volume.\n dataPath?: string;\n\n // Comma-separated host folders to mount into the container, as docker `host:container` pairs\n // with both absolute, optionally ending \":ro\" for read-only, e.g.\n // \"/mnt/user/media/downloads:/mnt/user/media/downloads, /mnt/user/tv:/tv:ro\". For apps that\n // read or write files on the host outside their own state. Default: none.\n mounts?: string;\n};\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { WebEntryHost } from '@qpqjs/dev-server';
|
|
2
|
+
import { ResolvedDevServerPorts } from '../../lib/devServerPorts';
|
|
3
|
+
/** Every port the image listens on: the app's dev-server ports plus one per hosted web entry. */
|
|
4
|
+
export declare const getContainerPorts: (devServerPorts: ResolvedDevServerPorts, hosts: WebEntryHost[]) => number[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Every port the image listens on: the app's dev-server ports plus one per hosted web entry. */
|
|
2
|
+
export const getContainerPorts = (devServerPorts, hosts) => [
|
|
3
|
+
devServerPorts.api,
|
|
4
|
+
devServerPorts.webSocket,
|
|
5
|
+
devServerPorts.fileStorage,
|
|
6
|
+
...hosts.map((host) => host.port),
|
|
7
|
+
];
|
|
8
|
+
//# sourceMappingURL=getContainerPorts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getContainerPorts.js","sourceRoot":"","sources":["../../../../src/platforms/docker/getContainerPorts.ts"],"names":[],"mappings":"AAIA,iGAAiG;AACjG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,cAAsC,EAAE,KAAqB,EAAY,EAAE,CAAC;IAC5G,cAAc,CAAC,GAAG;IAClB,cAAc,CAAC,SAAS;IACxB,cAAc,CAAC,WAAW;IAC1B,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;CAClC,CAAC","sourcesContent":["import { WebEntryHost } from '@qpqjs/dev-server';\n\nimport { ResolvedDevServerPorts } from '../../lib/devServerPorts';\n\n/** Every port the image listens on: the app's dev-server ports plus one per hosted web entry. */\nexport const getContainerPorts = (devServerPorts: ResolvedDevServerPorts, hosts: WebEntryHost[]): number[] => [\n devServerPorts.api,\n devServerPorts.webSocket,\n devServerPorts.fileStorage,\n ...hosts.map((host) => host.port),\n];\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { PortMapping } from './parsePortMappings';
|
|
2
|
+
/** Each container port on the same host port, plus 80 for the site, when the deployment sets no `portMappings`. */
|
|
3
|
+
export declare const getDefaultPortMappings: (apiPort: number, containerPorts: number[]) => PortMapping[];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Each container port on the same host port, plus 80 for the site, when the deployment sets no `portMappings`. */
|
|
2
|
+
export const getDefaultPortMappings = (apiPort, containerPorts) => [
|
|
3
|
+
{ host: 80, container: apiPort },
|
|
4
|
+
...containerPorts.map((port) => ({ host: port, container: port })),
|
|
5
|
+
];
|
|
6
|
+
//# sourceMappingURL=getDefaultPortMappings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDefaultPortMappings.js","sourceRoot":"","sources":["../../../../src/platforms/docker/getDefaultPortMappings.ts"],"names":[],"mappings":"AAEA,mHAAmH;AACnH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,cAAwB,EAAiB,EAAE,CAAC;IAClG,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE;IAChC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;CACnE,CAAC","sourcesContent":["import { PortMapping } from './parsePortMappings';\n\n/** Each container port on the same host port, plus 80 for the site, when the deployment sets no `portMappings`. */\nexport const getDefaultPortMappings = (apiPort: number, containerPorts: number[]): PortMapping[] => [\n { host: 80, container: apiPort },\n ...containerPorts.map((port) => ({ host: port, container: port })),\n];\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { QpqAppDeployment } from '@qpqjs/core';
|
|
2
|
+
import { Mount } from './parseMounts';
|
|
3
|
+
import { PortMapping } from './parsePortMappings';
|
|
4
|
+
export type ParsedDockerPlatformSettings = {
|
|
5
|
+
portMappings?: PortMapping[];
|
|
6
|
+
registry?: string;
|
|
7
|
+
arch?: string;
|
|
8
|
+
tag: string;
|
|
9
|
+
publicHost?: string;
|
|
10
|
+
dataPath?: string;
|
|
11
|
+
mounts?: Mount[];
|
|
12
|
+
};
|
|
13
|
+
/** The docker entry's platform settings, parsed; throws for a malformed value, naming the deployment. */
|
|
14
|
+
export declare const getDockerPlatformSettings: (deploymentName: string, deployment: QpqAppDeployment) => ParsedDockerPlatformSettings;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parseMounts } from './parseMounts';
|
|
2
|
+
import { parsePortMappings } from './parsePortMappings';
|
|
3
|
+
const asOptionalString = (deploymentName, name, value) => {
|
|
4
|
+
if (value === undefined) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
8
|
+
throw new Error(`Invalid docker deployment '${deploymentName}': platformSettings.${name} must be a non-empty string`);
|
|
9
|
+
}
|
|
10
|
+
return value.trim().replace(/\/+$/, '');
|
|
11
|
+
};
|
|
12
|
+
/** The docker entry's platform settings, parsed; throws for a malformed value, naming the deployment. */
|
|
13
|
+
export const getDockerPlatformSettings = (deploymentName, deployment) => {
|
|
14
|
+
const settings = deployment.platformSettings ?? {};
|
|
15
|
+
let portMappings;
|
|
16
|
+
let mounts;
|
|
17
|
+
try {
|
|
18
|
+
portMappings = settings.portMappings === undefined ? undefined : parsePortMappings(settings.portMappings);
|
|
19
|
+
mounts = settings.mounts === undefined ? undefined : parseMounts(settings.mounts);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error(`Invalid docker deployment '${deploymentName}': ${error instanceof Error ? error.message : String(error)}`);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
portMappings,
|
|
26
|
+
registry: asOptionalString(deploymentName, 'registry', settings.registry),
|
|
27
|
+
arch: asOptionalString(deploymentName, 'arch', settings.arch),
|
|
28
|
+
tag: asOptionalString(deploymentName, 'tag', settings.tag) ?? deployment.environment,
|
|
29
|
+
publicHost: asOptionalString(deploymentName, 'publicHost', settings.publicHost),
|
|
30
|
+
dataPath: asOptionalString(deploymentName, 'dataPath', settings.dataPath),
|
|
31
|
+
mounts,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=getDockerPlatformSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDockerPlatformSettings.js","sourceRoot":"","sources":["../../../../src/platforms/docker/getDockerPlatformSettings.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,WAAW,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAe,MAAM,qBAAqB,CAAC;AAcrE,MAAM,gBAAgB,GAAG,CAAC,cAAsB,EAAE,IAAY,EAAE,KAAc,EAAsB,EAAE;IACpG,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,8BAA8B,cAAc,uBAAuB,IAAI,6BAA6B,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,yGAAyG;AACzG,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,cAAsB,EAAE,UAA4B,EAAgC,EAAE;IAC9H,MAAM,QAAQ,GAAG,UAAU,CAAC,gBAAgB,IAAI,EAAE,CAAC;IAEnD,IAAI,YAAuC,CAAC;IAC5C,IAAI,MAA2B,CAAC;IAChC,IAAI,CAAC;QACH,YAAY,GAAG,QAAQ,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC1G,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,8BAA8B,cAAc,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9H,CAAC;IAED,OAAO;QACL,YAAY;QACZ,QAAQ,EAAE,gBAAgB,CAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC;QACzE,IAAI,EAAE,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;QAC7D,GAAG,EAAE,gBAAgB,CAAC,cAAc,EAAE,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,WAAW;QACpF,UAAU,EAAE,gBAAgB,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,UAAU,CAAC;QAC/E,QAAQ,EAAE,gBAAgB,CAAC,cAAc,EAAE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC;QACzE,MAAM;KACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { QpqAppDeployment } from '@qpqjs/core';\n\nimport { Mount, parseMounts } from './parseMounts';\nimport { parsePortMappings, PortMapping } from './parsePortMappings';\n\nexport type ParsedDockerPlatformSettings = {\n // Absent when the deployment sets no `portMappings`; the defaults depend on the app's config.\n portMappings?: PortMapping[];\n registry?: string;\n arch?: string;\n tag: string;\n publicHost?: string;\n dataPath?: string;\n // Absent when the deployment mounts nothing beyond its state directory.\n mounts?: Mount[];\n};\n\nconst asOptionalString = (deploymentName: string, name: string, value: unknown): string | undefined => {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`Invalid docker deployment '${deploymentName}': platformSettings.${name} must be a non-empty string`);\n }\n return value.trim().replace(/\\/+$/, '');\n};\n\n/** The docker entry's platform settings, parsed; throws for a malformed value, naming the deployment. */\nexport const getDockerPlatformSettings = (deploymentName: string, deployment: QpqAppDeployment): ParsedDockerPlatformSettings => {\n const settings = deployment.platformSettings ?? {};\n\n let portMappings: PortMapping[] | undefined;\n let mounts: Mount[] | undefined;\n try {\n portMappings = settings.portMappings === undefined ? undefined : parsePortMappings(settings.portMappings);\n mounts = settings.mounts === undefined ? undefined : parseMounts(settings.mounts);\n } catch (error) {\n throw new Error(`Invalid docker deployment '${deploymentName}': ${error instanceof Error ? error.message : String(error)}`);\n }\n\n return {\n portMappings,\n registry: asOptionalString(deploymentName, 'registry', settings.registry),\n arch: asOptionalString(deploymentName, 'arch', settings.arch),\n tag: asOptionalString(deploymentName, 'tag', settings.tag) ?? deployment.environment,\n publicHost: asOptionalString(deploymentName, 'publicHost', settings.publicHost),\n dataPath: asOptionalString(deploymentName, 'dataPath', settings.dataPath),\n mounts,\n };\n};\n"]}
|