quidproquo-cli 0.1.18 → 0.1.20

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.
Files changed (136) hide show
  1. package/README.md +1 -0
  2. package/lib/commonjs/cli/commandRegistry.js +6 -0
  3. package/lib/commonjs/cli/commandRegistry.js.map +1 -1
  4. package/lib/commonjs/commands/goDevApi.js +54 -8
  5. package/lib/commonjs/commands/goDevApi.js.map +1 -1
  6. package/lib/commonjs/commands/goDevWeb.js +10 -2
  7. package/lib/commonjs/commands/goDevWeb.js.map +1 -1
  8. package/lib/commonjs/commands/setup.d.ts +1 -0
  9. package/lib/commonjs/commands/setup.js +102 -0
  10. package/lib/commonjs/commands/setup.js.map +1 -0
  11. package/lib/commonjs/lib/args.d.ts +1 -0
  12. package/lib/commonjs/lib/args.js +11 -1
  13. package/lib/commonjs/lib/args.js.map +1 -1
  14. package/lib/commonjs/lib/keepOtherDevServersFlag.d.ts +1 -0
  15. package/lib/commonjs/lib/keepOtherDevServersFlag.js +11 -0
  16. package/lib/commonjs/lib/keepOtherDevServersFlag.js.map +1 -0
  17. package/lib/commonjs/lib/killChildWithEscalation.d.ts +10 -0
  18. package/lib/commonjs/lib/killChildWithEscalation.js +33 -0
  19. package/lib/commonjs/lib/killChildWithEscalation.js.map +1 -0
  20. package/lib/commonjs/lib/killStaleListeners.d.ts +14 -0
  21. package/lib/commonjs/lib/killStaleListeners.js +74 -24
  22. package/lib/commonjs/lib/killStaleListeners.js.map +1 -1
  23. package/lib/commonjs/lib/prompts.d.ts +2 -0
  24. package/lib/commonjs/lib/prompts.js +1 -1
  25. package/lib/commonjs/lib/prompts.js.map +1 -1
  26. package/lib/commonjs/lib/setupStep.d.ts +16 -0
  27. package/lib/commonjs/lib/setupStep.js +3 -0
  28. package/lib/commonjs/lib/setupStep.js.map +1 -0
  29. package/lib/commonjs/platforms/aws/index.js +2 -0
  30. package/lib/commonjs/platforms/aws/index.js.map +1 -1
  31. package/lib/commonjs/platforms/aws/setup/awsSetupContext.d.ts +12 -0
  32. package/lib/commonjs/platforms/aws/setup/awsSetupContext.js +23 -0
  33. package/lib/commonjs/platforms/aws/setup/awsSetupContext.js.map +1 -0
  34. package/lib/commonjs/platforms/aws/setup/awsSetupSteps.d.ts +8 -0
  35. package/lib/commonjs/platforms/aws/setup/awsSetupSteps.js +44 -0
  36. package/lib/commonjs/platforms/aws/setup/awsSetupSteps.js.map +1 -0
  37. package/lib/commonjs/platforms/aws/setup/buildBucketNamesStep.d.ts +4 -0
  38. package/lib/commonjs/platforms/aws/setup/buildBucketNamesStep.js +77 -0
  39. package/lib/commonjs/platforms/aws/setup/buildBucketNamesStep.js.map +1 -0
  40. package/lib/commonjs/platforms/aws/setup/buildCdkBootstrapSteps.d.ts +5 -0
  41. package/lib/commonjs/platforms/aws/setup/buildCdkBootstrapSteps.js +38 -0
  42. package/lib/commonjs/platforms/aws/setup/buildCdkBootstrapSteps.js.map +1 -0
  43. package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.d.ts +4 -0
  44. package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.js +55 -0
  45. package/lib/commonjs/platforms/aws/setup/buildGithubDeployRoleStep.js.map +1 -0
  46. package/lib/commonjs/platforms/aws/setup/buildGithubOidcProviderStep.d.ts +4 -0
  47. package/lib/commonjs/platforms/aws/setup/buildGithubOidcProviderStep.js +54 -0
  48. package/lib/commonjs/platforms/aws/setup/buildGithubOidcProviderStep.js.map +1 -0
  49. package/lib/commonjs/platforms/aws/setup/buildHostedZonesStep.d.ts +4 -0
  50. package/lib/commonjs/platforms/aws/setup/buildHostedZonesStep.js +63 -0
  51. package/lib/commonjs/platforms/aws/setup/buildHostedZonesStep.js.map +1 -0
  52. package/lib/commonjs/platforms/aws/setup/buildIamCapabilityStep.d.ts +4 -0
  53. package/lib/commonjs/platforms/aws/setup/buildIamCapabilityStep.js +48 -0
  54. package/lib/commonjs/platforms/aws/setup/buildIamCapabilityStep.js.map +1 -0
  55. package/lib/commonjs/platforms/aws/setup/buildIdentityStep.d.ts +4 -0
  56. package/lib/commonjs/platforms/aws/setup/buildIdentityStep.js +39 -0
  57. package/lib/commonjs/platforms/aws/setup/buildIdentityStep.js.map +1 -0
  58. package/lib/commonjs/platforms/aws/setup/buildStackSteps.d.ts +5 -0
  59. package/lib/commonjs/platforms/aws/setup/buildStackSteps.js +32 -0
  60. package/lib/commonjs/platforms/aws/setup/buildStackSteps.js.map +1 -0
  61. package/lib/commonjs/platforms/aws/setup/describeStackStatus.d.ts +4 -0
  62. package/lib/commonjs/platforms/aws/setup/describeStackStatus.js +32 -0
  63. package/lib/commonjs/platforms/aws/setup/describeStackStatus.js.map +1 -0
  64. package/lib/commonjs/platforms/aws/setup/index.d.ts +1 -0
  65. package/lib/commonjs/platforms/aws/setup/index.js +18 -0
  66. package/lib/commonjs/platforms/aws/setup/index.js.map +1 -0
  67. package/lib/commonjs/platforms/types.d.ts +2 -0
  68. package/lib/commonjs/platforms/types.js.map +1 -1
  69. package/lib/esm/cli/commandRegistry.js +6 -0
  70. package/lib/esm/cli/commandRegistry.js.map +1 -1
  71. package/lib/esm/commands/goDevApi.js +55 -9
  72. package/lib/esm/commands/goDevApi.js.map +1 -1
  73. package/lib/esm/commands/goDevWeb.js +10 -2
  74. package/lib/esm/commands/goDevWeb.js.map +1 -1
  75. package/lib/esm/commands/setup.d.ts +1 -0
  76. package/lib/esm/commands/setup.js +88 -0
  77. package/lib/esm/commands/setup.js.map +1 -0
  78. package/lib/esm/lib/args.d.ts +1 -0
  79. package/lib/esm/lib/args.js +9 -0
  80. package/lib/esm/lib/args.js.map +1 -1
  81. package/lib/esm/lib/keepOtherDevServersFlag.d.ts +1 -0
  82. package/lib/esm/lib/keepOtherDevServersFlag.js +8 -0
  83. package/lib/esm/lib/keepOtherDevServersFlag.js.map +1 -0
  84. package/lib/esm/lib/killChildWithEscalation.d.ts +10 -0
  85. package/lib/esm/lib/killChildWithEscalation.js +29 -0
  86. package/lib/esm/lib/killChildWithEscalation.js.map +1 -0
  87. package/lib/esm/lib/killStaleListeners.d.ts +14 -0
  88. package/lib/esm/lib/killStaleListeners.js +72 -23
  89. package/lib/esm/lib/killStaleListeners.js.map +1 -1
  90. package/lib/esm/lib/prompts.d.ts +2 -0
  91. package/lib/esm/lib/prompts.js +1 -1
  92. package/lib/esm/lib/prompts.js.map +1 -1
  93. package/lib/esm/lib/setupStep.d.ts +16 -0
  94. package/lib/esm/lib/setupStep.js +2 -0
  95. package/lib/esm/lib/setupStep.js.map +1 -0
  96. package/lib/esm/platforms/aws/index.js +2 -0
  97. package/lib/esm/platforms/aws/index.js.map +1 -1
  98. package/lib/esm/platforms/aws/setup/awsSetupContext.d.ts +12 -0
  99. package/lib/esm/platforms/aws/setup/awsSetupContext.js +18 -0
  100. package/lib/esm/platforms/aws/setup/awsSetupContext.js.map +1 -0
  101. package/lib/esm/platforms/aws/setup/awsSetupSteps.d.ts +8 -0
  102. package/lib/esm/platforms/aws/setup/awsSetupSteps.js +31 -0
  103. package/lib/esm/platforms/aws/setup/awsSetupSteps.js.map +1 -0
  104. package/lib/esm/platforms/aws/setup/buildBucketNamesStep.d.ts +4 -0
  105. package/lib/esm/platforms/aws/setup/buildBucketNamesStep.js +62 -0
  106. package/lib/esm/platforms/aws/setup/buildBucketNamesStep.js.map +1 -0
  107. package/lib/esm/platforms/aws/setup/buildCdkBootstrapSteps.d.ts +5 -0
  108. package/lib/esm/platforms/aws/setup/buildCdkBootstrapSteps.js +24 -0
  109. package/lib/esm/platforms/aws/setup/buildCdkBootstrapSteps.js.map +1 -0
  110. package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.d.ts +4 -0
  111. package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.js +40 -0
  112. package/lib/esm/platforms/aws/setup/buildGithubDeployRoleStep.js.map +1 -0
  113. package/lib/esm/platforms/aws/setup/buildGithubOidcProviderStep.d.ts +4 -0
  114. package/lib/esm/platforms/aws/setup/buildGithubOidcProviderStep.js +40 -0
  115. package/lib/esm/platforms/aws/setup/buildGithubOidcProviderStep.js.map +1 -0
  116. package/lib/esm/platforms/aws/setup/buildHostedZonesStep.d.ts +4 -0
  117. package/lib/esm/platforms/aws/setup/buildHostedZonesStep.js +49 -0
  118. package/lib/esm/platforms/aws/setup/buildHostedZonesStep.js.map +1 -0
  119. package/lib/esm/platforms/aws/setup/buildIamCapabilityStep.d.ts +4 -0
  120. package/lib/esm/platforms/aws/setup/buildIamCapabilityStep.js +34 -0
  121. package/lib/esm/platforms/aws/setup/buildIamCapabilityStep.js.map +1 -0
  122. package/lib/esm/platforms/aws/setup/buildIdentityStep.d.ts +4 -0
  123. package/lib/esm/platforms/aws/setup/buildIdentityStep.js +26 -0
  124. package/lib/esm/platforms/aws/setup/buildIdentityStep.js.map +1 -0
  125. package/lib/esm/platforms/aws/setup/buildStackSteps.d.ts +5 -0
  126. package/lib/esm/platforms/aws/setup/buildStackSteps.js +17 -0
  127. package/lib/esm/platforms/aws/setup/buildStackSteps.js.map +1 -0
  128. package/lib/esm/platforms/aws/setup/describeStackStatus.d.ts +4 -0
  129. package/lib/esm/platforms/aws/setup/describeStackStatus.js +17 -0
  130. package/lib/esm/platforms/aws/setup/describeStackStatus.js.map +1 -0
  131. package/lib/esm/platforms/aws/setup/index.d.ts +1 -0
  132. package/lib/esm/platforms/aws/setup/index.js +2 -0
  133. package/lib/esm/platforms/aws/setup/index.js.map +1 -0
  134. package/lib/esm/platforms/types.d.ts +2 -0
  135. package/lib/esm/platforms/types.js.map +1 -1
  136. package/package.json +13 -10
@@ -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 AWS_DEFAULT_ACCOUNT / 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,4FAA4F,CAAC,CAAC;QAChI,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 AWS_DEFAULT_ACCOUNT / 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 { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';
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', qpqDeployAwsCdkUtils.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', qpqDeployAwsCdkUtils.getDomainStackName(ctx.bootstrapQpqConfig), ctx.region, () => deployDomainStack(ctx.appName));
16
+ export const buildBootstrapStackStep = (ctx) => buildStackStep('bootstrap-stack', 'Bootstrap stack: WAF and app-wide resources', qpqDeployAwsCdkUtils.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,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,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,oBAAoB,CAAC,mBAAmB,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CACvH,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,oBAAoB,CAAC,kBAAkB,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAC/D,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,oBAAoB,CAAC,qBAAqB,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAClE,GAAG,CAAC,MAAM,EACV,GAAG,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CACxC,CAAC","sourcesContent":["import { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\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', qpqDeployAwsCdkUtils.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 qpqDeployAwsCdkUtils.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 qpqDeployAwsCdkUtils.getBootstrapStackName(ctx.bootstrapQpqConfig),\n ctx.region,\n () => deployBootstrapStack(ctx.appName),\n );\n"]}
@@ -0,0 +1,4 @@
1
+ import { Nullable } from 'quidproquo-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 'quidproquo-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,2 @@
1
+ export * from './awsSetupSteps';
2
+ //# sourceMappingURL=index.js.map
@@ -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"]}
@@ -1,6 +1,7 @@
1
1
  import { QpqAppDeployEnvironment } from 'quidproquo-deploy-awscdk';
2
2
  import { ClearResourcesPlan } from '../lib/clearResourcesPlan';
3
3
  import { DeployPlan, TeardownPlan } from '../lib/deployPrompts';
4
+ import { SetupStep } from '../lib/setupStep';
4
5
  export declare enum QpqDeployPlatform {
5
6
  aws = "aws",
6
7
  docker = "docker"
@@ -11,6 +12,7 @@ export interface QpqPlatformDriver {
11
12
  goDocker?: (appName: string, plan: DeployPlan) => Promise<void>;
12
13
  teardown?: (appName: string, plan: TeardownPlan) => Promise<void>;
13
14
  clearResources?: (appName: string, plan: ClearResourcesPlan) => Promise<void>;
15
+ setupSteps?: (appName: string, environment: string) => Promise<SetupStep[]>;
14
16
  publish: (appName: string, serviceNames: string[]) => Promise<void>;
15
17
  publishBuild: (appName: string, serviceNames: string[]) => Promise<void>;
16
18
  publishUpload: (appName: string, serviceNames: string[]) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/platforms/types.ts"],"names":[],"mappings":"AAKA,MAAM,CAAN,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,gCAAW,CAAA;IACX,sCAAiB,CAAA;AACnB,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,QAG5B","sourcesContent":["import { QpqAppDeployEnvironment } from 'quidproquo-deploy-awscdk';\n\nimport { ClearResourcesPlan } from '../lib/clearResourcesPlan';\nimport { DeployPlan, TeardownPlan } from '../lib/deployPrompts';\n\nexport enum QpqDeployPlatform {\n aws = 'aws',\n docker = 'docker',\n}\n\n// A deploy platform driver — everything that happens after \"what to deploy\"\n// has been decided. `qpq go` resolves the app + environment, prompts the plan,\n// then hands off here; the platform comes from the environment's entry in\n// apps/<app>/deploy.config.json (default aws), so an app can move platforms\n// with a config change instead of a different command.\nexport interface QpqPlatformDriver {\n // Prime process.env with this platform's deploy identity from the resolved\n // environment target (already-set env vars win). Service configs read these\n // vars at load time, so this runs before any infrastructure.ts is required.\n // Returns human-readable descriptions of anything still missing — deploys\n // treat that as fatal, local dev commands ignore it.\n primeDeployIdentity: (target: QpqAppDeployEnvironment | undefined) => string[];\n\n // Sequential deploy (`qpq go`).\n go: (appName: string, plan: DeployPlan) => Promise<void>;\n\n // Parallel containerized deploy (`qpq go:docker`) — optional; drivers that\n // have no docker strategy simply omit it.\n goDocker?: (appName: string, plan: DeployPlan) => Promise<void>;\n\n // Destroy the web/api/inf stacks for selected services (`qpq teardown`) —\n // optional; drivers with no teardown strategy simply omit it.\n teardown?: (appName: string, plan: TeardownPlan) => Promise<void>;\n\n // Empty the stored data of selected resources without touching the stacks\n // (`qpq clear-resources`) — optional; drivers with no strategy omit it.\n clearResources?: (appName: string, plan: ClearResourcesPlan) => Promise<void>;\n\n // Federated remote publishing (`qpq publish[:build|:upload|:deploy]`).\n publish: (appName: string, serviceNames: string[]) => Promise<void>;\n publishBuild: (appName: string, serviceNames: string[]) => Promise<void>;\n publishUpload: (appName: string, serviceNames: string[]) => Promise<void>;\n publishDeploy: (appName: string, serviceNames: string[]) => Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/platforms/types.ts"],"names":[],"mappings":"AAMA,MAAM,CAAN,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,gCAAW,CAAA;IACX,sCAAiB,CAAA;AACnB,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,QAG5B","sourcesContent":["import { QpqAppDeployEnvironment } from 'quidproquo-deploy-awscdk';\n\nimport { ClearResourcesPlan } from '../lib/clearResourcesPlan';\nimport { DeployPlan, TeardownPlan } from '../lib/deployPrompts';\nimport { SetupStep } from '../lib/setupStep';\n\nexport enum QpqDeployPlatform {\n aws = 'aws',\n docker = 'docker',\n}\n\n// A deploy platform driver — everything that happens after \"what to deploy\"\n// has been decided. `qpq go` resolves the app + environment, prompts the plan,\n// then hands off here; the platform comes from the environment's entry in\n// apps/<app>/deploy.config.json (default aws), so an app can move platforms\n// with a config change instead of a different command.\nexport interface QpqPlatformDriver {\n // Prime process.env with this platform's deploy identity from the resolved\n // environment target (already-set env vars win). Service configs read these\n // vars at load time, so this runs before any infrastructure.ts is required.\n // Returns human-readable descriptions of anything still missing — deploys\n // treat that as fatal, local dev commands ignore it.\n primeDeployIdentity: (target: QpqAppDeployEnvironment | undefined) => string[];\n\n // Sequential deploy (`qpq go`).\n go: (appName: string, plan: DeployPlan) => Promise<void>;\n\n // Parallel containerized deploy (`qpq go:docker`) — optional; drivers that\n // have no docker strategy simply omit it.\n goDocker?: (appName: string, plan: DeployPlan) => Promise<void>;\n\n // Destroy the web/api/inf stacks for selected services (`qpq teardown`) —\n // optional; drivers with no teardown strategy simply omit it.\n teardown?: (appName: string, plan: TeardownPlan) => Promise<void>;\n\n // Empty the stored data of selected resources without touching the stacks\n // (`qpq clear-resources`) — optional; drivers with no strategy omit it.\n clearResources?: (appName: string, plan: ClearResourcesPlan) => Promise<void>;\n\n // The ordered checklist that takes an empty cloud environment to a deployed\n // one (`qpq setup`) — optional; drivers with nothing to set up omit it.\n setupSteps?: (appName: string, environment: string) => Promise<SetupStep[]>;\n\n // Federated remote publishing (`qpq publish[:build|:upload|:deploy]`).\n publish: (appName: string, serviceNames: string[]) => Promise<void>;\n publishBuild: (appName: string, serviceNames: string[]) => Promise<void>;\n publishUpload: (appName: string, serviceNames: string[]) => Promise<void>;\n publishDeploy: (appName: string, serviceNames: string[]) => Promise<void>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-cli",
3
- "version": "0.1.18",
3
+ "version": "0.1.20",
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",
@@ -37,28 +37,31 @@
37
37
  },
38
38
  "homepage": "https://github.com/qpqjs/quidproquo#readme",
39
39
  "dependencies": {
40
+ "@aws-sdk/client-cloudformation": "^3.1093.0",
40
41
  "@aws-sdk/client-dynamodb": "^3.1093.0",
42
+ "@aws-sdk/client-iam": "^3.1093.0",
43
+ "@aws-sdk/client-route-53": "^3.1093.0",
41
44
  "@aws-sdk/client-s3": "^3.1093.0",
42
45
  "@aws-sdk/client-sts": "^3.1093.0",
43
46
  "@inquirer/prompts": "^8.5.2",
44
47
  "@rspack/dev-server": "^2.1.0",
45
48
  "aws-cdk": "^2.1132.1",
46
49
  "madge": "^8.0.0",
47
- "quidproquo": "0.1.18",
48
- "quidproquo-actionprocessor-awslambda": "0.1.18",
49
- "quidproquo-config-aws": "0.1.18",
50
- "quidproquo-core": "0.1.18",
51
- "quidproquo-deploy-awscdk": "0.1.18",
52
- "quidproquo-deploy-rspack": "0.1.18",
53
- "quidproquo-dev-server": "0.1.18",
54
- "quidproquo-webserver": "0.1.18",
50
+ "quidproquo": "0.1.20",
51
+ "quidproquo-actionprocessor-awslambda": "0.1.20",
52
+ "quidproquo-config-aws": "0.1.20",
53
+ "quidproquo-core": "0.1.20",
54
+ "quidproquo-deploy-awscdk": "0.1.20",
55
+ "quidproquo-deploy-rspack": "0.1.20",
56
+ "quidproquo-dev-server": "0.1.20",
57
+ "quidproquo-webserver": "0.1.20",
55
58
  "ts-node": "^10.9.1",
56
59
  "typescript": "^5.8.2"
57
60
  },
58
61
  "devDependencies": {
59
62
  "@rspack/core": "^2.1.2",
60
63
  "@types/node": "^22.13.13",
61
- "quidproquo-tsconfig": "0.1.18"
64
+ "quidproquo-tsconfig": "0.1.20"
62
65
  },
63
66
  "bin": {
64
67
  "qpq": "./lib/commonjs/bin/qpq.js"