@aws-cdk-testing/cli-integ 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +9 -0
- package/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +205 -0
- package/bin/apply-patches +22 -0
- package/bin/download-and-run-old-tests +52 -0
- package/bin/query-github +2 -0
- package/bin/query-github.d.ts +1 -0
- package/bin/query-github.js +54 -0
- package/bin/query-github.ts +56 -0
- package/bin/run-suite +2 -0
- package/bin/run-suite.d.ts +1 -0
- package/bin/run-suite.js +131 -0
- package/bin/run-suite.ts +140 -0
- package/bin/stage-distribution +2 -0
- package/bin/stage-distribution.d.ts +1 -0
- package/bin/stage-distribution.js +217 -0
- package/bin/stage-distribution.ts +267 -0
- package/bin/test-root +2 -0
- package/bin/test-root.d.ts +1 -0
- package/bin/test-root.js +6 -0
- package/bin/test-root.ts +3 -0
- package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
- package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
- package/entrypoints/test-cli-regression.bash +83 -0
- package/entrypoints/test.sh +12 -0
- package/lib/aws.d.ts +51 -0
- package/lib/aws.js +206 -0
- package/lib/aws.ts +263 -0
- package/lib/corking.d.ts +12 -0
- package/lib/corking.js +35 -0
- package/lib/corking.ts +33 -0
- package/lib/eventually.d.ts +20 -0
- package/lib/eventually.js +34 -0
- package/lib/eventually.ts +42 -0
- package/lib/files.d.ts +15 -0
- package/lib/files.js +80 -0
- package/lib/files.ts +80 -0
- package/lib/github.d.ts +4 -0
- package/lib/github.js +43 -0
- package/lib/github.ts +43 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +30 -0
- package/lib/index.ts +13 -0
- package/lib/integ-test.d.ts +10 -0
- package/lib/integ-test.js +70 -0
- package/lib/integ-test.ts +81 -0
- package/lib/lists.d.ts +1 -0
- package/lib/lists.js +11 -0
- package/lib/lists.ts +9 -0
- package/lib/memoize.d.ts +6 -0
- package/lib/memoize.js +18 -0
- package/lib/memoize.ts +14 -0
- package/lib/npm.d.ts +8 -0
- package/lib/npm.js +38 -0
- package/lib/npm.ts +41 -0
- package/lib/package-sources/release-source.d.ts +23 -0
- package/lib/package-sources/release-source.js +71 -0
- package/lib/package-sources/release-source.ts +81 -0
- package/lib/package-sources/repo-source.d.ts +30 -0
- package/lib/package-sources/repo-source.js +97 -0
- package/lib/package-sources/repo-source.ts +111 -0
- package/lib/package-sources/repo-tools/npm +2 -0
- package/lib/package-sources/repo-tools/npm.d.ts +1 -0
- package/lib/package-sources/repo-tools/npm.js +43 -0
- package/lib/package-sources/repo-tools/npm.ts +48 -0
- package/lib/package-sources/source.d.ts +28 -0
- package/lib/package-sources/source.js +3 -0
- package/lib/package-sources/source.ts +35 -0
- package/lib/package-sources/subprocess.d.ts +3 -0
- package/lib/package-sources/subprocess.js +17 -0
- package/lib/package-sources/subprocess.ts +15 -0
- package/lib/resource-pool.d.ts +50 -0
- package/lib/resource-pool.js +117 -0
- package/lib/resource-pool.ts +140 -0
- package/lib/resources.d.ts +1 -0
- package/lib/resources.js +6 -0
- package/lib/resources.ts +4 -0
- package/lib/shell.d.ts +56 -0
- package/lib/shell.js +123 -0
- package/lib/shell.ts +168 -0
- package/lib/staging/codeartifact.d.ts +44 -0
- package/lib/staging/codeartifact.js +281 -0
- package/lib/staging/codeartifact.ts +387 -0
- package/lib/staging/maven.d.ts +5 -0
- package/lib/staging/maven.js +91 -0
- package/lib/staging/maven.ts +95 -0
- package/lib/staging/npm.d.ts +4 -0
- package/lib/staging/npm.js +55 -0
- package/lib/staging/npm.ts +62 -0
- package/lib/staging/nuget.d.ts +4 -0
- package/lib/staging/nuget.js +69 -0
- package/lib/staging/nuget.ts +75 -0
- package/lib/staging/parallel-shell.d.ts +5 -0
- package/lib/staging/parallel-shell.js +45 -0
- package/lib/staging/parallel-shell.ts +51 -0
- package/lib/staging/pypi.d.ts +4 -0
- package/lib/staging/pypi.js +48 -0
- package/lib/staging/pypi.ts +50 -0
- package/lib/staging/usage-dir.d.ts +31 -0
- package/lib/staging/usage-dir.js +87 -0
- package/lib/staging/usage-dir.ts +99 -0
- package/lib/with-aws.d.ts +14 -0
- package/lib/with-aws.js +60 -0
- package/lib/with-aws.ts +67 -0
- package/lib/with-cdk-app.d.ts +210 -0
- package/lib/with-cdk-app.js +539 -0
- package/lib/with-cdk-app.ts +742 -0
- package/lib/with-cli-lib.d.ts +17 -0
- package/lib/with-cli-lib.js +123 -0
- package/lib/with-cli-lib.ts +134 -0
- package/lib/with-packages.d.ts +5 -0
- package/lib/with-packages.js +13 -0
- package/lib/with-packages.ts +15 -0
- package/lib/with-sam.d.ts +33 -0
- package/lib/with-sam.js +258 -0
- package/lib/with-sam.ts +288 -0
- package/lib/with-temporary-directory.d.ts +5 -0
- package/lib/with-temporary-directory.js +31 -0
- package/lib/with-temporary-directory.ts +35 -0
- package/lib/with-timeout.d.ts +19 -0
- package/lib/with-timeout.js +34 -0
- package/lib/with-timeout.ts +33 -0
- package/lib/xpmutex.d.ts +43 -0
- package/lib/xpmutex.js +207 -0
- package/lib/xpmutex.ts +218 -0
- package/package.json +111 -0
- package/resources/bootstrap-templates/session-tags.all-roles-deny-all.yaml +703 -0
- package/resources/bootstrap-templates/session-tags.deploy-role-deny-sqs.yaml +700 -0
- package/resources/cdk-apps/app/app.js +926 -0
- package/resources/cdk-apps/app/appsync.hotswap.graphql +3 -0
- package/resources/cdk-apps/app/cdk.json +7 -0
- package/resources/cdk-apps/app/docker/Dockerfile +2 -0
- package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
- package/resources/cdk-apps/app/lambda/index.js +4 -0
- package/resources/cdk-apps/app/lambda/response.json +3 -0
- package/resources/cdk-apps/app/nested-stack.js +65 -0
- package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
- package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
- package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
- package/resources/cdk-apps/rollback-test-app/app.js +110 -0
- package/resources/cdk-apps/rollback-test-app/cdk.json +7 -0
- package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
- package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
- package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
- package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
- package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
- package/resources/cdk-apps/simple-app/app.js +26 -0
- package/resources/cdk-apps/simple-app/cdk.json +7 -0
- package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
- package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
- package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
- package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
- package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
- package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
- package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
- package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
- package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
- package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
- package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
- package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
- package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
- package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
- package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
- package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
- package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
- package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
- package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
- package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
- package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
- package/resources/cli-regression-patches/v2.130.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.130.0/node_modules/@aws-cdk-testing/cli-integ/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
- package/resources/cli-regression-patches/v2.130.0/node_modules/@aws-cdk-testing/cli-integ/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
- package/resources/cli-regression-patches/v2.130.0/skip-tests.txt +5 -0
- package/resources/cli-regression-patches/v2.132.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.132.0/skip-tests.txt +4 -0
- package/resources/cli-regression-patches/v2.142.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.142.0/skip-tests.txt +4 -0
- package/resources/cli-regression-patches/v2.160.0/skip-tests.txt +2 -0
- package/resources/cli-regression-patches/v2.161.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.161.0/skip-tests.txt +5 -0
- package/resources/cli-regression-patches/v2.166.0/NOTES.md +1 -0
- package/resources/cli-regression-patches/v2.166.0/skip-tests.txt +2 -0
- package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
- package/resources/cloud-assemblies/0.36.0/cdk.out +1 -0
- package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/cdk.out +1 -0
- package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
- package/resources/integ.jest.config.js +25 -0
- package/resources/templates/sqs-template.json +36 -0
- package/skip-tests.txt +8 -0
- package/tests/cli-integ-tests/README.md +47 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.js +412 -0
- package/tests/cli-integ-tests/bootstrapping.integtest.ts +493 -0
- package/tests/cli-integ-tests/cli-lib.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/cli-lib.integtest.js +62 -0
- package/tests/cli-integ-tests/cli-lib.integtest.ts +90 -0
- package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/cli.integtest.js +2104 -0
- package/tests/cli-integ-tests/cli.integtest.ts +2874 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.d.ts +1 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.js +314 -0
- package/tests/cli-integ-tests/garbage-collection.integtest.ts +392 -0
- package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
- package/tests/init-csharp/init-csharp.integtest.js +14 -0
- package/tests/init-csharp/init-csharp.integtest.ts +15 -0
- package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
- package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
- package/tests/init-fsharp/init-fsharp.integtest.ts +15 -0
- package/tests/init-go/init-go.integtest.d.ts +1 -0
- package/tests/init-go/init-go.integtest.js +21 -0
- package/tests/init-go/init-go.integtest.ts +23 -0
- package/tests/init-java/init-java.integtest.d.ts +1 -0
- package/tests/init-java/init-java.integtest.js +14 -0
- package/tests/init-java/init-java.integtest.ts +14 -0
- package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
- package/tests/init-javascript/init-javascript.integtest.js +53 -0
- package/tests/init-javascript/init-javascript.integtest.ts +59 -0
- package/tests/init-python/init-python.integtest.d.ts +1 -0
- package/tests/init-python/init-python.integtest.js +19 -0
- package/tests/init-python/init-python.integtest.ts +20 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.js +54 -0
- package/tests/init-typescript-app/init-typescript-app.integtest.ts +66 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
- package/tests/init-typescript-lib/init-typescript-lib.integtest.ts +13 -0
- package/tests/tool-integrations/amplify.integtest.d.ts +1 -0
- package/tests/tool-integrations/amplify.integtest.js +39 -0
- package/tests/tool-integrations/amplify.integtest.ts +43 -0
- package/tests/tool-integrations/with-tool-context.d.ts +9 -0
- package/tests/tool-integrations/with-tool-context.js +13 -0
- package/tests/tool-integrations/with-tool-context.ts +14 -0
- package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
- package/tests/uberpackage/uberpackage.integtest.js +11 -0
- package/tests/uberpackage/uberpackage.integtest.ts +11 -0
package/lib/aws.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AwsClients = void 0;
|
|
4
|
+
exports.isStackMissingError = isStackMissingError;
|
|
5
|
+
exports.isBucketMissingError = isBucketMissingError;
|
|
6
|
+
exports.retry = retry;
|
|
7
|
+
exports.outputFromStack = outputFromStack;
|
|
8
|
+
exports.sleep = sleep;
|
|
9
|
+
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
|
|
10
|
+
const client_ecr_1 = require("@aws-sdk/client-ecr");
|
|
11
|
+
const client_ecs_1 = require("@aws-sdk/client-ecs");
|
|
12
|
+
const client_iam_1 = require("@aws-sdk/client-iam");
|
|
13
|
+
const client_lambda_1 = require("@aws-sdk/client-lambda");
|
|
14
|
+
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
15
|
+
const client_sns_1 = require("@aws-sdk/client-sns");
|
|
16
|
+
const client_sso_1 = require("@aws-sdk/client-sso");
|
|
17
|
+
const client_sts_1 = require("@aws-sdk/client-sts");
|
|
18
|
+
const credential_providers_1 = require("@aws-sdk/credential-providers");
|
|
19
|
+
const util_retry_1 = require("@smithy/util-retry");
|
|
20
|
+
class AwsClients {
|
|
21
|
+
static async default(output) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
const region = (_b = (_a = process.env.AWS_REGION) !== null && _a !== void 0 ? _a : process.env.AWS_DEFAULT_REGION) !== null && _b !== void 0 ? _b : 'us-east-1';
|
|
24
|
+
return AwsClients.forRegion(region, output);
|
|
25
|
+
}
|
|
26
|
+
static async forRegion(region, output) {
|
|
27
|
+
return new AwsClients(region, output);
|
|
28
|
+
}
|
|
29
|
+
constructor(region, output) {
|
|
30
|
+
this.region = region;
|
|
31
|
+
this.output = output;
|
|
32
|
+
this.config = {
|
|
33
|
+
credentials: chainableCredentials(this.region),
|
|
34
|
+
region: this.region,
|
|
35
|
+
retryStrategy: new util_retry_1.ConfiguredRetryStrategy(9, (attempt) => attempt ** 500),
|
|
36
|
+
};
|
|
37
|
+
this.cloudFormation = new client_cloudformation_1.CloudFormationClient(this.config);
|
|
38
|
+
this.s3 = new client_s3_1.S3Client(this.config);
|
|
39
|
+
this.ecr = new client_ecr_1.ECRClient(this.config);
|
|
40
|
+
this.ecs = new client_ecs_1.ECSClient(this.config);
|
|
41
|
+
this.sso = new client_sso_1.SSOClient(this.config);
|
|
42
|
+
this.sns = new client_sns_1.SNSClient(this.config);
|
|
43
|
+
this.iam = new client_iam_1.IAMClient(this.config);
|
|
44
|
+
this.lambda = new client_lambda_1.LambdaClient(this.config);
|
|
45
|
+
this.sts = new client_sts_1.STSClient(this.config);
|
|
46
|
+
}
|
|
47
|
+
async account() {
|
|
48
|
+
// Reduce # of retries, we use this as a circuit breaker for detecting no-config
|
|
49
|
+
const stsClient = new client_sts_1.STSClient({
|
|
50
|
+
credentials: this.config.credentials,
|
|
51
|
+
region: this.config.region,
|
|
52
|
+
maxAttempts: 2,
|
|
53
|
+
});
|
|
54
|
+
return (await stsClient.send(new client_sts_1.GetCallerIdentityCommand({}))).Account;
|
|
55
|
+
}
|
|
56
|
+
async deleteStacks(...stackNames) {
|
|
57
|
+
if (stackNames.length === 0) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// We purposely do all stacks serially, because they've been ordered
|
|
61
|
+
// to do the bootstrap stack last.
|
|
62
|
+
for (const stackName of stackNames) {
|
|
63
|
+
await this.cloudFormation.send(new client_cloudformation_1.UpdateTerminationProtectionCommand({
|
|
64
|
+
EnableTerminationProtection: false,
|
|
65
|
+
StackName: stackName,
|
|
66
|
+
}));
|
|
67
|
+
await this.cloudFormation.send(new client_cloudformation_1.DeleteStackCommand({
|
|
68
|
+
StackName: stackName,
|
|
69
|
+
}));
|
|
70
|
+
await retry(this.output, `Deleting ${stackName}`, retry.forSeconds(600), async () => {
|
|
71
|
+
const status = await this.stackStatus(stackName);
|
|
72
|
+
if (status !== undefined && status.endsWith('_FAILED')) {
|
|
73
|
+
throw retry.abort(new Error(`'${stackName}' is in state '${status}'`));
|
|
74
|
+
}
|
|
75
|
+
if (status !== undefined) {
|
|
76
|
+
throw new Error(`Delete of '${stackName}' not complete yet, status: '${status}'`);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async stackStatus(stackName) {
|
|
82
|
+
var _a;
|
|
83
|
+
try {
|
|
84
|
+
return (_a = (await this.cloudFormation.send(new client_cloudformation_1.DescribeStacksCommand({
|
|
85
|
+
StackName: stackName,
|
|
86
|
+
}))).Stacks) === null || _a === void 0 ? void 0 : _a[0].StackStatus;
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
if (isStackMissingError(e)) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
throw e;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async emptyBucket(bucketName, options) {
|
|
96
|
+
const objects = await this.s3.send(new client_s3_1.ListObjectVersionsCommand({
|
|
97
|
+
Bucket: bucketName,
|
|
98
|
+
}));
|
|
99
|
+
const deletes = [...(objects.Versions || []), ...(objects.DeleteMarkers || [])].reduce((acc, obj) => {
|
|
100
|
+
if (typeof obj.VersionId !== 'undefined' && typeof obj.Key !== 'undefined') {
|
|
101
|
+
acc.push({ Key: obj.Key, VersionId: obj.VersionId });
|
|
102
|
+
}
|
|
103
|
+
else if (typeof obj.Key !== 'undefined') {
|
|
104
|
+
acc.push({ Key: obj.Key });
|
|
105
|
+
}
|
|
106
|
+
return acc;
|
|
107
|
+
}, []);
|
|
108
|
+
if (deletes.length === 0) {
|
|
109
|
+
return Promise.resolve();
|
|
110
|
+
}
|
|
111
|
+
return this.s3.send(new client_s3_1.DeleteObjectsCommand({
|
|
112
|
+
Bucket: bucketName,
|
|
113
|
+
Delete: {
|
|
114
|
+
Objects: deletes,
|
|
115
|
+
Quiet: false,
|
|
116
|
+
},
|
|
117
|
+
BypassGovernanceRetention: (options === null || options === void 0 ? void 0 : options.bypassGovernance) ? true : undefined,
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
async deleteImageRepository(repositoryName) {
|
|
121
|
+
await this.ecr.send(new client_ecr_1.DeleteRepositoryCommand({
|
|
122
|
+
repositoryName: repositoryName,
|
|
123
|
+
force: true,
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
async deleteBucket(bucketName) {
|
|
127
|
+
try {
|
|
128
|
+
await this.emptyBucket(bucketName);
|
|
129
|
+
await this.s3.send(new client_s3_1.DeleteBucketCommand({
|
|
130
|
+
Bucket: bucketName,
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
if (isBucketMissingError(e)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
throw e;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
exports.AwsClients = AwsClients;
|
|
142
|
+
function isStackMissingError(e) {
|
|
143
|
+
return e.message.indexOf('does not exist') > -1;
|
|
144
|
+
}
|
|
145
|
+
function isBucketMissingError(e) {
|
|
146
|
+
return e.message.indexOf('does not exist') > -1;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Retry an async operation until a deadline is hit.
|
|
150
|
+
*
|
|
151
|
+
* Use `retry.forSeconds()` to construct a deadline relative to right now.
|
|
152
|
+
*
|
|
153
|
+
* Exceptions will cause the operation to retry. Use `retry.abort` to annotate an exception
|
|
154
|
+
* to stop the retry and end in a failure.
|
|
155
|
+
*/
|
|
156
|
+
async function retry(output, operation, deadline, block) {
|
|
157
|
+
let i = 0;
|
|
158
|
+
output.write(`💈 ${operation}\n`);
|
|
159
|
+
while (true) {
|
|
160
|
+
try {
|
|
161
|
+
i++;
|
|
162
|
+
const ret = await block();
|
|
163
|
+
output.write(`💈 ${operation}: succeeded after ${i} attempts\n`);
|
|
164
|
+
return ret;
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
if (e.abort || Date.now() > deadline.getTime()) {
|
|
168
|
+
throw new Error(`${operation}: did not succeed after ${i} attempts: ${e}`);
|
|
169
|
+
}
|
|
170
|
+
output.write(`⏳ ${operation} (${e.message})\n`);
|
|
171
|
+
await sleep(5000);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Make a deadline for the `retry` function relative to the current time.
|
|
177
|
+
*/
|
|
178
|
+
retry.forSeconds = (seconds) => {
|
|
179
|
+
return new Date(Date.now() + seconds * 1000);
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Annotate an error to stop the retrying
|
|
183
|
+
*/
|
|
184
|
+
retry.abort = (e) => {
|
|
185
|
+
e.abort = true;
|
|
186
|
+
return e;
|
|
187
|
+
};
|
|
188
|
+
function outputFromStack(key, stack) {
|
|
189
|
+
var _a, _b;
|
|
190
|
+
return (_b = ((_a = stack.Outputs) !== null && _a !== void 0 ? _a : []).find((o) => o.OutputKey === key)) === null || _b === void 0 ? void 0 : _b.OutputValue;
|
|
191
|
+
}
|
|
192
|
+
async function sleep(ms) {
|
|
193
|
+
return new Promise((ok) => setTimeout(ok, ms));
|
|
194
|
+
}
|
|
195
|
+
function chainableCredentials(region) {
|
|
196
|
+
if (process.env.CODEBUILD_BUILD_ARN && process.env.AWS_PROFILE) {
|
|
197
|
+
// in codebuild we must assume the role that the cdk uses
|
|
198
|
+
// otherwise credentials will just be picked up by the normal sdk
|
|
199
|
+
// heuristics and expire after an hour.
|
|
200
|
+
return (0, credential_providers_1.fromIni)({
|
|
201
|
+
clientConfig: { region },
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXdzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTRMQSxrREFFQztBQUVELG9EQUVDO0FBVUQsc0JBc0JDO0FBaUJELDBDQUVDO0FBRUQsc0JBRUM7QUF6UEQsMEVBTXdDO0FBQ3hDLG9EQUF5RTtBQUN6RSxvREFBZ0Q7QUFDaEQsb0RBQWdEO0FBQ2hELDBEQUFzRDtBQUN0RCxrREFNNEI7QUFDNUIsb0RBQWdEO0FBQ2hELG9EQUFnRDtBQUNoRCxvREFBMEU7QUFDMUUsd0VBQXdEO0FBRXhELG1EQUE2RDtBQU83RCxNQUFhLFVBQVU7SUFDZCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUE2Qjs7UUFDdkQsTUFBTSxNQUFNLEdBQUcsTUFBQSxNQUFBLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxtQ0FBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixtQ0FBSSxXQUFXLENBQUM7UUFDdkYsT0FBTyxVQUFVLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBYyxFQUFFLE1BQTZCO1FBQ3pFLE9BQU8sSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFjRCxZQUE0QixNQUFjLEVBQW1CLE1BQTZCO1FBQTlELFdBQU0sR0FBTixNQUFNLENBQVE7UUFBbUIsV0FBTSxHQUFOLE1BQU0sQ0FBdUI7UUFDeEYsSUFBSSxDQUFDLE1BQU0sR0FBRztZQUNaLFdBQVcsRUFBRSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1lBQzlDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixhQUFhLEVBQUUsSUFBSSxvQ0FBdUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFlLEVBQUUsRUFBRSxDQUFDLE9BQU8sSUFBSSxH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UUFDakUsdUNBQXVDO1FBQ3ZDLE9BQU8sSUFBQSw4QkFBTyxFQUFDO1lBQ2IsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFO1NBQ3pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gIERlbGV0ZVN0YWNrQ29tbWFuZCxcbiAgRGVzY3JpYmVTdGFja3NDb21tYW5kLFxuICBVcGRhdGVUZXJtaW5hdGlvblByb3RlY3Rpb25Db21tYW5kLFxuICB0eXBlIFN0YWNrLFxufSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgRGVsZXRlUmVwb3NpdG9yeUNvbW1hbmQsIEVDUkNsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1lY3InO1xuaW1wb3J0IHsgRUNTQ2xpZW50IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWVjcyc7XG5pbXBvcnQgeyBJQU1DbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtaWFtJztcbmltcG9ydCB7IExhbWJkYUNsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1sYW1iZGEnO1xuaW1wb3J0IHtcbiAgUzNDbGllbnQsXG4gIERlbGV0ZU9iamVjdHNDb21tYW5kLFxuICBMaXN0T2JqZWN0VmVyc2lvbnNDb21tYW5kLFxuICB0eXBlIE9iamVjdElkZW50aWZpZXIsXG4gIERlbGV0ZUJ1Y2tldENvbW1hbmQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zMyc7XG5pbXBvcnQgeyBTTlNDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtc25zJztcbmltcG9ydCB7IFNTT0NsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zc28nO1xuaW1wb3J0IHsgU1RTQ2xpZW50LCBHZXRDYWxsZXJJZGVudGl0eUNvbW1hbmQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtc3RzJztcbmltcG9ydCB7IGZyb21JbmkgfSBmcm9tICdAYXdzLXNkay9jcmVkZW50aWFsLXByb3ZpZGVycyc7XG5pbXBvcnQgdHlwZSB7IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyIH0gZnJvbSAnQHNtaXRoeS90eXBlcyc7XG5pbXBvcnQgeyBDb25maWd1cmVkUmV0cnlTdHJhdGVneSB9IGZyb20gJ0BzbWl0aHkvdXRpbC1yZXRyeSc7XG5pbnRlcmZhY2UgQ2xpZW50Q29uZmlnIHtcbiAgcmVhZG9ubHkgY3JlZGVudGlhbHM/OiBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlcjtcbiAgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJldHJ5U3RyYXRlZ3k6IENvbmZpZ3VyZWRSZXRyeVN0cmF0ZWd5O1xufVxuXG5leHBvcnQgY2xhc3MgQXdzQ2xpZW50cyB7XG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZGVmYXVsdChvdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkge1xuICAgIGNvbnN0IHJlZ2lvbiA9IHByb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OID8/ICd1cy1lYXN0LTEnO1xuICAgIHJldHVybiBBd3NDbGllbnRzLmZvclJlZ2lvbihyZWdpb24sIG91dHB1dCk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZvclJlZ2lvbihyZWdpb246IHN0cmluZywgb3V0cHV0OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0pIHtcbiAgICByZXR1cm4gbmV3IEF3c0NsaWVudHMocmVnaW9uLCBvdXRwdXQpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IENsaWVudENvbmZpZztcblxuICBwdWJsaWMgcmVhZG9ubHkgY2xvdWRGb3JtYXRpb246IENsb3VkRm9ybWF0aW9uQ2xpZW50O1xuICBwdWJsaWMgcmVhZG9ubHkgczM6IFMzQ2xpZW50O1xuICBwdWJsaWMgcmVhZG9ubHkgZWNyOiBFQ1JDbGllbnQ7XG4gIHB1YmxpYyByZWFkb25seSBlY3M6IEVDU0NsaWVudDtcbiAgcHVibGljIHJlYWRvbmx5IHNzbzogU1NPQ2xpZW50O1xuICBwdWJsaWMgcmVhZG9ubHkgc25zOiBTTlNDbGllbnQ7XG4gIHB1YmxpYyByZWFkb25seSBpYW06IElBTUNsaWVudDtcbiAgcHVibGljIHJlYWRvbmx5IGxhbWJkYTogTGFtYmRhQ2xpZW50O1xuICBwdWJsaWMgcmVhZG9ubHkgc3RzOiBTVFNDbGllbnQ7XG5cbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHJlZ2lvbjogc3RyaW5nLCBwcml2YXRlIHJlYWRvbmx5IG91dHB1dDogTm9kZUpTLldyaXRhYmxlU3RyZWFtKSB7XG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICBjcmVkZW50aWFsczogY2hhaW5hYmxlQ3JlZGVudGlhbHModGhpcy5yZWdpb24pLFxuICAgICAgcmVnaW9uOiB0aGlzLnJlZ2lvbixcbiAgICAgIHJldHJ5U3RyYXRlZ3k6IG5ldyBDb25maWd1cmVkUmV0cnlTdHJhdGVneSg5LCAoYXR0ZW1wdDogbnVtYmVyKSA9PiBhdHRlbXB0ICoqIDUwMCksXG4gICAgfTtcbiAgICB0aGlzLmNsb3VkRm9ybWF0aW9uID0gbmV3IENsb3VkRm9ybWF0aW9uQ2xpZW50KHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnMzID0gbmV3IFMzQ2xpZW50KHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmVjciA9IG5ldyBFQ1JDbGllbnQodGhpcy5jb25maWcpO1xuICAgIHRoaXMuZWNzID0gbmV3IEVDU0NsaWVudCh0aGlzLmNvbmZpZyk7XG4gICAgdGhpcy5zc28gPSBuZXcgU1NPQ2xpZW50KHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnNucyA9IG5ldyBTTlNDbGllbnQodGhpcy5jb25maWcpO1xuICAgIHRoaXMuaWFtID0gbmV3IElBTUNsaWVudCh0aGlzLmNvbmZpZyk7XG4gICAgdGhpcy5sYW1iZGEgPSBuZXcgTGFtYmRhQ2xpZW50KHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnN0cyA9IG5ldyBTVFNDbGllbnQodGhpcy5jb25maWcpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGFjY291bnQoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICAvLyBSZWR1Y2UgIyBvZiByZXRyaWVzLCB3ZSB1c2UgdGhpcyBhcyBhIGNpcmN1aXQgYnJlYWtlciBmb3IgZGV0ZWN0aW5nIG5vLWNvbmZpZ1xuICAgIGNvbnN0IHN0c0NsaWVudCA9IG5ldyBTVFNDbGllbnQoe1xuICAgICAgY3JlZGVudGlhbHM6IHRoaXMuY29uZmlnLmNyZWRlbnRpYWxzLFxuICAgICAgcmVnaW9uOiB0aGlzLmNvbmZpZy5yZWdpb24sXG4gICAgICBtYXhBdHRlbXB0czogMixcbiAgICB9KTtcblxuICAgIHJldHVybiAoYXdhaXQgc3RzQ2xpZW50LnNlbmQobmV3IEdldENhbGxlcklkZW50aXR5Q29tbWFuZCh7fSkpKS5BY2NvdW50ITtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWxldGVTdGFja3MoLi4uc3RhY2tOYW1lczogc3RyaW5nW10pIHtcbiAgICBpZiAoc3RhY2tOYW1lcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXZSBwdXJwb3NlbHkgZG8gYWxsIHN0YWNrcyBzZXJpYWxseSwgYmVjYXVzZSB0aGV5J3ZlIGJlZW4gb3JkZXJlZFxuICAgIC8vIHRvIGRvIHRoZSBib290c3RyYXAgc3RhY2sgbGFzdC5cbiAgICBmb3IgKGNvbnN0IHN0YWNrTmFtZSBvZiBzdGFja05hbWVzKSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3VkRm9ybWF0aW9uLnNlbmQoXG4gICAgICAgIG5ldyBVcGRhdGVUZXJtaW5hdGlvblByb3RlY3Rpb25Db21tYW5kKHtcbiAgICAgICAgICBFbmFibGVUZXJtaW5hdGlvblByb3RlY3Rpb246IGZhbHNlLFxuICAgICAgICAgIFN0YWNrTmFtZTogc3RhY2tOYW1lLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmNsb3VkRm9ybWF0aW9uLnNlbmQoXG4gICAgICAgIG5ldyBEZWxldGVTdGFja0NvbW1hbmQoe1xuICAgICAgICAgIFN0YWNrTmFtZTogc3RhY2tOYW1lLFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIGF3YWl0IHJldHJ5KHRoaXMub3V0cHV0LCBgRGVsZXRpbmcgJHtzdGFja05hbWV9YCwgcmV0cnkuZm9yU2Vjb25kcyg2MDApLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IHRoaXMuc3RhY2tTdGF0dXMoc3RhY2tOYW1lKTtcbiAgICAgICAgaWYgKHN0YXR1cyAhPT0gdW5kZWZpbmVkICYmIHN0YXR1cy5lbmRzV2l0aCgnX0ZBSUxFRCcpKSB7XG4gICAgICAgICAgdGhyb3cgcmV0cnkuYWJvcnQobmV3IEVycm9yKGAnJHtzdGFja05hbWV9JyBpcyBpbiBzdGF0ZSAnJHtzdGF0dXN9J2ApKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhdHVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERlbGV0ZSBvZiAnJHtzdGFja05hbWV9JyBub3QgY29tcGxldGUgeWV0LCBzdGF0dXM6ICcke3N0YXR1c30nYCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzdGFja1N0YXR1cyhzdGFja05hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAoXG4gICAgICAgIGF3YWl0IHRoaXMuY2xvdWRGb3JtYXRpb24uc2VuZChcbiAgICAgICAgICBuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHtcbiAgICAgICAgICAgIFN0YWNrTmFtZTogc3RhY2tOYW1lLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICApLlN0YWNrcz8uWzBdLlN0YWNrU3RhdHVzO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGlzU3RhY2tNaXNzaW5nRXJyb3IoZSkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGVtcHR5QnVja2V0KGJ1Y2tldE5hbWU6IHN0cmluZywgb3B0aW9ucz86IHsgYnlwYXNzR292ZXJuYW5jZT86IGJvb2xlYW4gfSkge1xuICAgIGNvbnN0IG9iamVjdHMgPSBhd2FpdCB0aGlzLnMzLnNlbmQoXG4gICAgICBuZXcgTGlzdE9iamVjdFZlcnNpb25zQ29tbWFuZCh7XG4gICAgICAgIEJ1Y2tldDogYnVja2V0TmFtZSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBkZWxldGVzID0gWy4uLihvYmplY3RzLlZlcnNpb25zIHx8IFtdKSwgLi4uKG9iamVjdHMuRGVsZXRlTWFya2VycyB8fCBbXSldLnJlZHVjZSgoYWNjLCBvYmopID0+IHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqLlZlcnNpb25JZCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9iai5LZXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGFjYy5wdXNoKHsgS2V5OiBvYmouS2V5LCBWZXJzaW9uSWQ6IG9iai5WZXJzaW9uSWQgfSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmouS2V5ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBhY2MucHVzaCh7IEtleTogb2JqLktleSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10gYXMgT2JqZWN0SWRlbnRpZmllcltdKTtcblxuICAgIGlmIChkZWxldGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnMzLnNlbmQoXG4gICAgICBuZXcgRGVsZXRlT2JqZWN0c0NvbW1hbmQoe1xuICAgICAgICBCdWNrZXQ6IGJ1Y2tldE5hbWUsXG4gICAgICAgIERlbGV0ZToge1xuICAgICAgICAgIE9iamVjdHM6IGRlbGV0ZXMsXG4gICAgICAgICAgUXVpZXQ6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBCeXBhc3NHb3Zlcm5hbmNlUmV0ZW50aW9uOiBvcHRpb25zPy5ieXBhc3NHb3Zlcm5hbmNlID8gdHJ1ZSA6IHVuZGVmaW5lZCxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVsZXRlSW1hZ2VSZXBvc2l0b3J5KHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcpIHtcbiAgICBhd2FpdCB0aGlzLmVjci5zZW5kKFxuICAgICAgbmV3IERlbGV0ZVJlcG9zaXRvcnlDb21tYW5kKHtcbiAgICAgICAgcmVwb3NpdG9yeU5hbWU6IHJlcG9zaXRvcnlOYW1lLFxuICAgICAgICBmb3JjZTogdHJ1ZSxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVsZXRlQnVja2V0KGJ1Y2tldE5hbWU6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVtcHR5QnVja2V0KGJ1Y2tldE5hbWUpO1xuXG4gICAgICBhd2FpdCB0aGlzLnMzLnNlbmQoXG4gICAgICAgIG5ldyBEZWxldGVCdWNrZXRDb21tYW5kKHtcbiAgICAgICAgICBCdWNrZXQ6IGJ1Y2tldE5hbWUsXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmIChpc0J1Y2tldE1pc3NpbmdFcnJvcihlKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTdGFja01pc3NpbmdFcnJvcihlOiBFcnJvcikge1xuICByZXR1cm4gZS5tZXNzYWdlLmluZGV4T2YoJ2RvZXMgbm90IGV4aXN0JykgPiAtMTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQnVja2V0TWlzc2luZ0Vycm9yKGU6IEVycm9yKSB7XG4gIHJldHVybiBlLm1lc3NhZ2UuaW5kZXhPZignZG9lcyBub3QgZXhpc3QnKSA+IC0xO1xufVxuXG4vKipcbiAqIFJldHJ5IGFuIGFzeW5jIG9wZXJhdGlvbiB1bnRpbCBhIGRlYWRsaW5lIGlzIGhpdC5cbiAqXG4gKiBVc2UgYHJldHJ5LmZvclNlY29uZHMoKWAgdG8gY29uc3RydWN0IGEgZGVhZGxpbmUgcmVsYXRpdmUgdG8gcmlnaHQgbm93LlxuICpcbiAqIEV4Y2VwdGlvbnMgd2lsbCBjYXVzZSB0aGUgb3BlcmF0aW9uIHRvIHJldHJ5LiBVc2UgYHJldHJ5LmFib3J0YCB0byBhbm5vdGF0ZSBhbiBleGNlcHRpb25cbiAqIHRvIHN0b3AgdGhlIHJldHJ5IGFuZCBlbmQgaW4gYSBmYWlsdXJlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmV0cnk8QT4oXG4gIG91dHB1dDogTm9kZUpTLldyaXRhYmxlU3RyZWFtLFxuICBvcGVyYXRpb246IHN0cmluZyxcbiAgZGVhZGxpbmU6IERhdGUsXG4gIGJsb2NrOiAoKSA9PiBQcm9taXNlPEE+LFxuKTogUHJvbWlzZTxBPiB7XG4gIGxldCBpID0gMDtcbiAgb3V0cHV0LndyaXRlKGDwn5KIICR7b3BlcmF0aW9ufVxcbmApO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICBpKys7XG4gICAgICBjb25zdCByZXQgPSBhd2FpdCBibG9jaygpO1xuICAgICAgb3V0cHV0LndyaXRlKGDwn5KIICR7b3BlcmF0aW9ufTogc3VjY2VlZGVkIGFmdGVyICR7aX0gYXR0ZW1wdHNcXG5gKTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoZS5hYm9ydCB8fCBEYXRlLm5vdygpID4gZGVhZGxpbmUuZ2V0VGltZSgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtvcGVyYXRpb259OiBkaWQgbm90IHN1Y2NlZWQgYWZ0ZXIgJHtpfSBhdHRlbXB0czogJHtlfWApO1xuICAgICAgfVxuICAgICAgb3V0cHV0LndyaXRlKGDij7MgJHtvcGVyYXRpb259ICgke2UubWVzc2FnZX0pXFxuYCk7XG4gICAgICBhd2FpdCBzbGVlcCg1MDAwKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYWtlIGEgZGVhZGxpbmUgZm9yIHRoZSBgcmV0cnlgIGZ1bmN0aW9uIHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHRpbWUuXG4gKi9cbnJldHJ5LmZvclNlY29uZHMgPSAoc2Vjb25kczogbnVtYmVyKTogRGF0ZSA9PiB7XG4gIHJldHVybiBuZXcgRGF0ZShEYXRlLm5vdygpICsgc2Vjb25kcyAqIDEwMDApO1xufTtcblxuLyoqXG4gKiBBbm5vdGF0ZSBhbiBlcnJvciB0byBzdG9wIHRoZSByZXRyeWluZ1xuICovXG5yZXRyeS5hYm9ydCA9IChlOiBFcnJvcik6IEVycm9yID0+IHtcbiAgKGUgYXMgYW55KS5hYm9ydCA9IHRydWU7XG4gIHJldHVybiBlO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG91dHB1dEZyb21TdGFjayhrZXk6IHN0cmluZywgc3RhY2s6IFN0YWNrKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChzdGFjay5PdXRwdXRzID8/IFtdKS5maW5kKChvKSA9PiBvLk91dHB1dEtleSA9PT0ga2V5KT8uT3V0cHV0VmFsdWU7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59XG5cbmZ1bmN0aW9uIGNoYWluYWJsZUNyZWRlbnRpYWxzKHJlZ2lvbjogc3RyaW5nKTogQXdzQ3JlZGVudGlhbElkZW50aXR5UHJvdmlkZXIgfCB1bmRlZmluZWQge1xuICBpZiAocHJvY2Vzcy5lbnYuQ09ERUJVSUxEX0JVSUxEX0FSTiAmJiBwcm9jZXNzLmVudi5BV1NfUFJPRklMRSkge1xuICAgIC8vIGluIGNvZGVidWlsZCB3ZSBtdXN0IGFzc3VtZSB0aGUgcm9sZSB0aGF0IHRoZSBjZGsgdXNlc1xuICAgIC8vIG90aGVyd2lzZSBjcmVkZW50aWFscyB3aWxsIGp1c3QgYmUgcGlja2VkIHVwIGJ5IHRoZSBub3JtYWwgc2RrXG4gICAgLy8gaGV1cmlzdGljcyBhbmQgZXhwaXJlIGFmdGVyIGFuIGhvdXIuXG4gICAgcmV0dXJuIGZyb21Jbmkoe1xuICAgICAgY2xpZW50Q29uZmlnOiB7IHJlZ2lvbiB9LFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiJdfQ==
|
package/lib/aws.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CloudFormationClient,
|
|
3
|
+
DeleteStackCommand,
|
|
4
|
+
DescribeStacksCommand,
|
|
5
|
+
UpdateTerminationProtectionCommand,
|
|
6
|
+
type Stack,
|
|
7
|
+
} from '@aws-sdk/client-cloudformation';
|
|
8
|
+
import { DeleteRepositoryCommand, ECRClient } from '@aws-sdk/client-ecr';
|
|
9
|
+
import { ECSClient } from '@aws-sdk/client-ecs';
|
|
10
|
+
import { IAMClient } from '@aws-sdk/client-iam';
|
|
11
|
+
import { LambdaClient } from '@aws-sdk/client-lambda';
|
|
12
|
+
import {
|
|
13
|
+
S3Client,
|
|
14
|
+
DeleteObjectsCommand,
|
|
15
|
+
ListObjectVersionsCommand,
|
|
16
|
+
type ObjectIdentifier,
|
|
17
|
+
DeleteBucketCommand,
|
|
18
|
+
} from '@aws-sdk/client-s3';
|
|
19
|
+
import { SNSClient } from '@aws-sdk/client-sns';
|
|
20
|
+
import { SSOClient } from '@aws-sdk/client-sso';
|
|
21
|
+
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
|
|
22
|
+
import { fromIni } from '@aws-sdk/credential-providers';
|
|
23
|
+
import type { AwsCredentialIdentityProvider } from '@smithy/types';
|
|
24
|
+
import { ConfiguredRetryStrategy } from '@smithy/util-retry';
|
|
25
|
+
interface ClientConfig {
|
|
26
|
+
readonly credentials?: AwsCredentialIdentityProvider;
|
|
27
|
+
readonly region: string;
|
|
28
|
+
readonly retryStrategy: ConfiguredRetryStrategy;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class AwsClients {
|
|
32
|
+
public static async default(output: NodeJS.WritableStream) {
|
|
33
|
+
const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1';
|
|
34
|
+
return AwsClients.forRegion(region, output);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public static async forRegion(region: string, output: NodeJS.WritableStream) {
|
|
38
|
+
return new AwsClients(region, output);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private readonly config: ClientConfig;
|
|
42
|
+
|
|
43
|
+
public readonly cloudFormation: CloudFormationClient;
|
|
44
|
+
public readonly s3: S3Client;
|
|
45
|
+
public readonly ecr: ECRClient;
|
|
46
|
+
public readonly ecs: ECSClient;
|
|
47
|
+
public readonly sso: SSOClient;
|
|
48
|
+
public readonly sns: SNSClient;
|
|
49
|
+
public readonly iam: IAMClient;
|
|
50
|
+
public readonly lambda: LambdaClient;
|
|
51
|
+
public readonly sts: STSClient;
|
|
52
|
+
|
|
53
|
+
constructor(public readonly region: string, private readonly output: NodeJS.WritableStream) {
|
|
54
|
+
this.config = {
|
|
55
|
+
credentials: chainableCredentials(this.region),
|
|
56
|
+
region: this.region,
|
|
57
|
+
retryStrategy: new ConfiguredRetryStrategy(9, (attempt: number) => attempt ** 500),
|
|
58
|
+
};
|
|
59
|
+
this.cloudFormation = new CloudFormationClient(this.config);
|
|
60
|
+
this.s3 = new S3Client(this.config);
|
|
61
|
+
this.ecr = new ECRClient(this.config);
|
|
62
|
+
this.ecs = new ECSClient(this.config);
|
|
63
|
+
this.sso = new SSOClient(this.config);
|
|
64
|
+
this.sns = new SNSClient(this.config);
|
|
65
|
+
this.iam = new IAMClient(this.config);
|
|
66
|
+
this.lambda = new LambdaClient(this.config);
|
|
67
|
+
this.sts = new STSClient(this.config);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public async account(): Promise<string> {
|
|
71
|
+
// Reduce # of retries, we use this as a circuit breaker for detecting no-config
|
|
72
|
+
const stsClient = new STSClient({
|
|
73
|
+
credentials: this.config.credentials,
|
|
74
|
+
region: this.config.region,
|
|
75
|
+
maxAttempts: 2,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return (await stsClient.send(new GetCallerIdentityCommand({}))).Account!;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public async deleteStacks(...stackNames: string[]) {
|
|
82
|
+
if (stackNames.length === 0) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// We purposely do all stacks serially, because they've been ordered
|
|
87
|
+
// to do the bootstrap stack last.
|
|
88
|
+
for (const stackName of stackNames) {
|
|
89
|
+
await this.cloudFormation.send(
|
|
90
|
+
new UpdateTerminationProtectionCommand({
|
|
91
|
+
EnableTerminationProtection: false,
|
|
92
|
+
StackName: stackName,
|
|
93
|
+
}),
|
|
94
|
+
);
|
|
95
|
+
await this.cloudFormation.send(
|
|
96
|
+
new DeleteStackCommand({
|
|
97
|
+
StackName: stackName,
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
await retry(this.output, `Deleting ${stackName}`, retry.forSeconds(600), async () => {
|
|
102
|
+
const status = await this.stackStatus(stackName);
|
|
103
|
+
if (status !== undefined && status.endsWith('_FAILED')) {
|
|
104
|
+
throw retry.abort(new Error(`'${stackName}' is in state '${status}'`));
|
|
105
|
+
}
|
|
106
|
+
if (status !== undefined) {
|
|
107
|
+
throw new Error(`Delete of '${stackName}' not complete yet, status: '${status}'`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public async stackStatus(stackName: string): Promise<string | undefined> {
|
|
114
|
+
try {
|
|
115
|
+
return (
|
|
116
|
+
await this.cloudFormation.send(
|
|
117
|
+
new DescribeStacksCommand({
|
|
118
|
+
StackName: stackName,
|
|
119
|
+
}),
|
|
120
|
+
)
|
|
121
|
+
).Stacks?.[0].StackStatus;
|
|
122
|
+
} catch (e: any) {
|
|
123
|
+
if (isStackMissingError(e)) {
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
throw e;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public async emptyBucket(bucketName: string, options?: { bypassGovernance?: boolean }) {
|
|
131
|
+
const objects = await this.s3.send(
|
|
132
|
+
new ListObjectVersionsCommand({
|
|
133
|
+
Bucket: bucketName,
|
|
134
|
+
}),
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const deletes = [...(objects.Versions || []), ...(objects.DeleteMarkers || [])].reduce((acc, obj) => {
|
|
138
|
+
if (typeof obj.VersionId !== 'undefined' && typeof obj.Key !== 'undefined') {
|
|
139
|
+
acc.push({ Key: obj.Key, VersionId: obj.VersionId });
|
|
140
|
+
} else if (typeof obj.Key !== 'undefined') {
|
|
141
|
+
acc.push({ Key: obj.Key });
|
|
142
|
+
}
|
|
143
|
+
return acc;
|
|
144
|
+
}, [] as ObjectIdentifier[]);
|
|
145
|
+
|
|
146
|
+
if (deletes.length === 0) {
|
|
147
|
+
return Promise.resolve();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return this.s3.send(
|
|
151
|
+
new DeleteObjectsCommand({
|
|
152
|
+
Bucket: bucketName,
|
|
153
|
+
Delete: {
|
|
154
|
+
Objects: deletes,
|
|
155
|
+
Quiet: false,
|
|
156
|
+
},
|
|
157
|
+
BypassGovernanceRetention: options?.bypassGovernance ? true : undefined,
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public async deleteImageRepository(repositoryName: string) {
|
|
163
|
+
await this.ecr.send(
|
|
164
|
+
new DeleteRepositoryCommand({
|
|
165
|
+
repositoryName: repositoryName,
|
|
166
|
+
force: true,
|
|
167
|
+
}),
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public async deleteBucket(bucketName: string) {
|
|
172
|
+
try {
|
|
173
|
+
await this.emptyBucket(bucketName);
|
|
174
|
+
|
|
175
|
+
await this.s3.send(
|
|
176
|
+
new DeleteBucketCommand({
|
|
177
|
+
Bucket: bucketName,
|
|
178
|
+
}),
|
|
179
|
+
);
|
|
180
|
+
} catch (e: any) {
|
|
181
|
+
if (isBucketMissingError(e)) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
throw e;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function isStackMissingError(e: Error) {
|
|
190
|
+
return e.message.indexOf('does not exist') > -1;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export function isBucketMissingError(e: Error) {
|
|
194
|
+
return e.message.indexOf('does not exist') > -1;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Retry an async operation until a deadline is hit.
|
|
199
|
+
*
|
|
200
|
+
* Use `retry.forSeconds()` to construct a deadline relative to right now.
|
|
201
|
+
*
|
|
202
|
+
* Exceptions will cause the operation to retry. Use `retry.abort` to annotate an exception
|
|
203
|
+
* to stop the retry and end in a failure.
|
|
204
|
+
*/
|
|
205
|
+
export async function retry<A>(
|
|
206
|
+
output: NodeJS.WritableStream,
|
|
207
|
+
operation: string,
|
|
208
|
+
deadline: Date,
|
|
209
|
+
block: () => Promise<A>,
|
|
210
|
+
): Promise<A> {
|
|
211
|
+
let i = 0;
|
|
212
|
+
output.write(`💈 ${operation}\n`);
|
|
213
|
+
while (true) {
|
|
214
|
+
try {
|
|
215
|
+
i++;
|
|
216
|
+
const ret = await block();
|
|
217
|
+
output.write(`💈 ${operation}: succeeded after ${i} attempts\n`);
|
|
218
|
+
return ret;
|
|
219
|
+
} catch (e: any) {
|
|
220
|
+
if (e.abort || Date.now() > deadline.getTime()) {
|
|
221
|
+
throw new Error(`${operation}: did not succeed after ${i} attempts: ${e}`);
|
|
222
|
+
}
|
|
223
|
+
output.write(`⏳ ${operation} (${e.message})\n`);
|
|
224
|
+
await sleep(5000);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Make a deadline for the `retry` function relative to the current time.
|
|
231
|
+
*/
|
|
232
|
+
retry.forSeconds = (seconds: number): Date => {
|
|
233
|
+
return new Date(Date.now() + seconds * 1000);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Annotate an error to stop the retrying
|
|
238
|
+
*/
|
|
239
|
+
retry.abort = (e: Error): Error => {
|
|
240
|
+
(e as any).abort = true;
|
|
241
|
+
return e;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export function outputFromStack(key: string, stack: Stack): string | undefined {
|
|
245
|
+
return (stack.Outputs ?? []).find((o) => o.OutputKey === key)?.OutputValue;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export async function sleep(ms: number) {
|
|
249
|
+
return new Promise((ok) => setTimeout(ok, ms));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function chainableCredentials(region: string): AwsCredentialIdentityProvider | undefined {
|
|
253
|
+
if (process.env.CODEBUILD_BUILD_ARN && process.env.AWS_PROFILE) {
|
|
254
|
+
// in codebuild we must assume the role that the cdk uses
|
|
255
|
+
// otherwise credentials will just be picked up by the normal sdk
|
|
256
|
+
// heuristics and expire after an hour.
|
|
257
|
+
return fromIni({
|
|
258
|
+
clientConfig: { region },
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
package/lib/corking.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routines for corking stdout and stderr
|
|
3
|
+
*/
|
|
4
|
+
import * as stream from 'stream';
|
|
5
|
+
export declare class MemoryStream extends stream.Writable {
|
|
6
|
+
private parts;
|
|
7
|
+
_write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void;
|
|
8
|
+
buffer(): Buffer;
|
|
9
|
+
clear(): void;
|
|
10
|
+
flushTo(strm: NodeJS.WritableStream): Promise<void>;
|
|
11
|
+
toString(): string;
|
|
12
|
+
}
|
package/lib/corking.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoryStream = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Routines for corking stdout and stderr
|
|
6
|
+
*/
|
|
7
|
+
const stream = require("stream");
|
|
8
|
+
class MemoryStream extends stream.Writable {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(...arguments);
|
|
11
|
+
this.parts = new Array();
|
|
12
|
+
}
|
|
13
|
+
_write(chunk, _encoding, callback) {
|
|
14
|
+
this.parts.push(chunk);
|
|
15
|
+
callback();
|
|
16
|
+
}
|
|
17
|
+
buffer() {
|
|
18
|
+
return Buffer.concat(this.parts);
|
|
19
|
+
}
|
|
20
|
+
clear() {
|
|
21
|
+
this.parts.splice(0, this.parts.length);
|
|
22
|
+
}
|
|
23
|
+
async flushTo(strm) {
|
|
24
|
+
const flushed = strm.write(this.buffer());
|
|
25
|
+
if (!flushed) {
|
|
26
|
+
return new Promise(ok => strm.once('drain', ok));
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
toString() {
|
|
31
|
+
return this.buffer().toString();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.MemoryStream = MemoryStream;
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ya2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvcmtpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7O0dBRUc7QUFDSCxpQ0FBaUM7QUFFakMsTUFBYSxZQUFhLFNBQVEsTUFBTSxDQUFDLFFBQVE7SUFBakQ7O1FBQ1UsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7SUEwQnRDLENBQUM7SUF4QlEsTUFBTSxDQUFDLEtBQWEsRUFBRSxTQUFpQixFQUFFLFFBQXdDO1FBQ3RGLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLFFBQVEsRUFBRSxDQUFDO0lBQ2IsQ0FBQztJQUVNLE1BQU07UUFDWCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTSxLQUFLO1FBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVNLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBMkI7UUFDOUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDYixPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsT0FBTztJQUNULENBQUM7SUFFTSxRQUFRO1FBQ2IsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDbEMsQ0FBQztDQUNGO0FBM0JELG9DQTJCQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUm91dGluZXMgZm9yIGNvcmtpbmcgc3Rkb3V0IGFuZCBzdGRlcnJcbiAqL1xuaW1wb3J0ICogYXMgc3RyZWFtIGZyb20gJ3N0cmVhbSc7XG5cbmV4cG9ydCBjbGFzcyBNZW1vcnlTdHJlYW0gZXh0ZW5kcyBzdHJlYW0uV3JpdGFibGUge1xuICBwcml2YXRlIHBhcnRzID0gbmV3IEFycmF5PEJ1ZmZlcj4oKTtcblxuICBwdWJsaWMgX3dyaXRlKGNodW5rOiBCdWZmZXIsIF9lbmNvZGluZzogc3RyaW5nLCBjYWxsYmFjazogKGVycm9yPzogRXJyb3IgfCBudWxsKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5wYXJ0cy5wdXNoKGNodW5rKTtcbiAgICBjYWxsYmFjaygpO1xuICB9XG5cbiAgcHVibGljIGJ1ZmZlcigpIHtcbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdCh0aGlzLnBhcnRzKTtcbiAgfVxuXG4gIHB1YmxpYyBjbGVhcigpIHtcbiAgICB0aGlzLnBhcnRzLnNwbGljZSgwLCB0aGlzLnBhcnRzLmxlbmd0aCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZmx1c2hUbyhzdHJtOiBOb2RlSlMuV3JpdGFibGVTdHJlYW0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBmbHVzaGVkID0gc3RybS53cml0ZSh0aGlzLmJ1ZmZlcigpKTtcbiAgICBpZiAoIWZsdXNoZWQpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShvayA9PiBzdHJtLm9uY2UoJ2RyYWluJywgb2spKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHVibGljIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmJ1ZmZlcigpLnRvU3RyaW5nKCk7XG4gIH1cbn1cbiJdfQ==
|
package/lib/corking.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routines for corking stdout and stderr
|
|
3
|
+
*/
|
|
4
|
+
import * as stream from 'stream';
|
|
5
|
+
|
|
6
|
+
export class MemoryStream extends stream.Writable {
|
|
7
|
+
private parts = new Array<Buffer>();
|
|
8
|
+
|
|
9
|
+
public _write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {
|
|
10
|
+
this.parts.push(chunk);
|
|
11
|
+
callback();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public buffer() {
|
|
15
|
+
return Buffer.concat(this.parts);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public clear() {
|
|
19
|
+
this.parts.splice(0, this.parts.length);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public async flushTo(strm: NodeJS.WritableStream): Promise<void> {
|
|
23
|
+
const flushed = strm.write(this.buffer());
|
|
24
|
+
if (!flushed) {
|
|
25
|
+
return new Promise(ok => strm.once('drain', ok));
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public toString() {
|
|
31
|
+
return this.buffer().toString();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param maxAttempts the maximum number of attempts
|
|
3
|
+
* @param interval interval in milliseconds to observe between attempts
|
|
4
|
+
*/
|
|
5
|
+
export type EventuallyOptions = {
|
|
6
|
+
maxAttempts?: number;
|
|
7
|
+
interval?: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Runs a function on an interval until the maximum number of attempts has
|
|
11
|
+
* been reached.
|
|
12
|
+
*
|
|
13
|
+
* Default interval = 1000 milliseconds
|
|
14
|
+
* Default maxAttempts = 10
|
|
15
|
+
*
|
|
16
|
+
* @param fn function to run
|
|
17
|
+
* @param options EventuallyOptions
|
|
18
|
+
*/
|
|
19
|
+
declare const eventually: <T>(call: () => Promise<T>, options?: EventuallyOptions) => Promise<T>;
|
|
20
|
+
export default eventually;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
4
|
+
const DEFAULT_INTERVAL = 1000;
|
|
5
|
+
const DEFAULT_MAX_ATTEMPTS = 10;
|
|
6
|
+
/**
|
|
7
|
+
* Runs a function on an interval until the maximum number of attempts has
|
|
8
|
+
* been reached.
|
|
9
|
+
*
|
|
10
|
+
* Default interval = 1000 milliseconds
|
|
11
|
+
* Default maxAttempts = 10
|
|
12
|
+
*
|
|
13
|
+
* @param fn function to run
|
|
14
|
+
* @param options EventuallyOptions
|
|
15
|
+
*/
|
|
16
|
+
const eventually = async (call, options) => {
|
|
17
|
+
const opts = {
|
|
18
|
+
interval: (options === null || options === void 0 ? void 0 : options.interval) ? options.interval : DEFAULT_INTERVAL,
|
|
19
|
+
maxAttempts: (options === null || options === void 0 ? void 0 : options.maxAttempts) ? options.maxAttempts : DEFAULT_MAX_ATTEMPTS,
|
|
20
|
+
};
|
|
21
|
+
while (opts.maxAttempts-- >= 0) {
|
|
22
|
+
try {
|
|
23
|
+
return await call();
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
if (opts.maxAttempts <= 0)
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
await wait(opts.interval);
|
|
30
|
+
}
|
|
31
|
+
throw new Error('An unexpected error has occurred.');
|
|
32
|
+
};
|
|
33
|
+
exports.default = eventually;
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnR1YWxseS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImV2ZW50dWFsbHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFTQSxNQUFNLElBQUksR0FBRyxDQUFDLEVBQVUsRUFBaUIsRUFBRSxDQUFDLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDOUYsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7QUFDOUIsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLENBQUM7QUFFaEM7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLEdBQUcsS0FBSyxFQUFLLElBQXNCLEVBQUUsT0FBMkIsRUFBYyxFQUFFO0lBQzlGLE1BQU0sSUFBSSxHQUFHO1FBQ1gsUUFBUSxFQUFFLENBQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLFFBQVEsRUFBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCO1FBQ2pFLFdBQVcsRUFBRSxDQUFBLE9BQU8sYUFBUCxPQUFPLHVCQUFQLE9BQU8sQ0FBRSxXQUFXLEVBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtLQUMvRSxDQUFDO0lBRUYsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ3RCLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUM7Z0JBQUUsTUFBTSxHQUFHLENBQUM7UUFDdkMsQ0FBQztRQUNELE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO0FBQ3ZELENBQUMsQ0FBQztBQUVGLGtCQUFlLFVBQVUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHBhcmFtIG1heEF0dGVtcHRzIHRoZSBtYXhpbXVtIG51bWJlciBvZiBhdHRlbXB0c1xuICogQHBhcmFtIGludGVydmFsIGludGVydmFsIGluIG1pbGxpc2Vjb25kcyB0byBvYnNlcnZlIGJldHdlZW4gYXR0ZW1wdHNcbiAqL1xuZXhwb3J0IHR5cGUgRXZlbnR1YWxseU9wdGlvbnMgPSB7XG4gIG1heEF0dGVtcHRzPzogbnVtYmVyO1xuICBpbnRlcnZhbD86IG51bWJlcjtcbn07XG5cbmNvbnN0IHdhaXQgPSAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbmNvbnN0IERFRkFVTFRfSU5URVJWQUwgPSAxMDAwO1xuY29uc3QgREVGQVVMVF9NQVhfQVRURU1QVFMgPSAxMDtcblxuLyoqXG4gKiBSdW5zIGEgZnVuY3Rpb24gb24gYW4gaW50ZXJ2YWwgdW50aWwgdGhlIG1heGltdW0gbnVtYmVyIG9mIGF0dGVtcHRzIGhhc1xuICogYmVlbiByZWFjaGVkLlxuICpcbiAqIERlZmF1bHQgaW50ZXJ2YWwgPSAxMDAwIG1pbGxpc2Vjb25kc1xuICogRGVmYXVsdCBtYXhBdHRlbXB0cyA9IDEwXG4gKlxuICogQHBhcmFtIGZuIGZ1bmN0aW9uIHRvIHJ1blxuICogQHBhcmFtIG9wdGlvbnMgRXZlbnR1YWxseU9wdGlvbnNcbiAqL1xuY29uc3QgZXZlbnR1YWxseSA9IGFzeW5jIDxUPihjYWxsOiAoKSA9PiBQcm9taXNlPFQ+LCBvcHRpb25zPzogRXZlbnR1YWxseU9wdGlvbnMpOiBQcm9taXNlPFQ+ID0+IHtcbiAgY29uc3Qgb3B0cyA9IHtcbiAgICBpbnRlcnZhbDogb3B0aW9ucz8uaW50ZXJ2YWwgPyBvcHRpb25zLmludGVydmFsIDogREVGQVVMVF9JTlRFUlZBTCxcbiAgICBtYXhBdHRlbXB0czogb3B0aW9ucz8ubWF4QXR0ZW1wdHMgPyBvcHRpb25zLm1heEF0dGVtcHRzIDogREVGQVVMVF9NQVhfQVRURU1QVFMsXG4gIH07XG5cbiAgd2hpbGUgKG9wdHMubWF4QXR0ZW1wdHMtLSA+PSAwKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAob3B0cy5tYXhBdHRlbXB0cyA8PSAwKSB0aHJvdyBlcnI7XG4gICAgfVxuICAgIGF3YWl0IHdhaXQob3B0cy5pbnRlcnZhbCk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ0FuIHVuZXhwZWN0ZWQgZXJyb3IgaGFzIG9jY3VycmVkLicpO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgZXZlbnR1YWxseTtcbiJdfQ==
|