@aws-cdk-testing/cli-integ 2.61.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.
Files changed (165) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +16 -0
  3. package/README.md +151 -0
  4. package/bin/apply-patches +19 -0
  5. package/bin/download-and-run-old-tests +52 -0
  6. package/bin/query-github +2 -0
  7. package/bin/query-github.d.ts +1 -0
  8. package/bin/query-github.js +55 -0
  9. package/bin/run-suite +2 -0
  10. package/bin/run-suite.d.ts +1 -0
  11. package/bin/run-suite.js +126 -0
  12. package/bin/stage-distribution +2 -0
  13. package/bin/stage-distribution.d.ts +1 -0
  14. package/bin/stage-distribution.js +209 -0
  15. package/bin/test-root +2 -0
  16. package/bin/test-root.d.ts +1 -0
  17. package/bin/test-root.js +6 -0
  18. package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
  19. package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
  20. package/entrypoints/test-cli-regression.bash +83 -0
  21. package/entrypoints/test.sh +12 -0
  22. package/lib/aws.d.ts +55 -0
  23. package/lib/aws.js +243 -0
  24. package/lib/corking.d.ts +13 -0
  25. package/lib/corking.js +34 -0
  26. package/lib/files.d.ts +15 -0
  27. package/lib/files.js +80 -0
  28. package/lib/github.d.ts +4 -0
  29. package/lib/github.js +43 -0
  30. package/lib/index.d.ts +12 -0
  31. package/lib/index.js +25 -0
  32. package/lib/integ-test.d.ts +11 -0
  33. package/lib/integ-test.js +55 -0
  34. package/lib/lists.d.ts +1 -0
  35. package/lib/lists.js +12 -0
  36. package/lib/memoize.d.ts +6 -0
  37. package/lib/memoize.js +19 -0
  38. package/lib/npm.d.ts +4 -0
  39. package/lib/npm.js +15 -0
  40. package/lib/package-sources/release-source.d.ts +22 -0
  41. package/lib/package-sources/release-source.js +67 -0
  42. package/lib/package-sources/repo-source.d.ts +23 -0
  43. package/lib/package-sources/repo-source.js +92 -0
  44. package/lib/package-sources/repo-tools/npm +2 -0
  45. package/lib/package-sources/repo-tools/npm.d.ts +1 -0
  46. package/lib/package-sources/repo-tools/npm.js +42 -0
  47. package/lib/package-sources/source.d.ts +24 -0
  48. package/lib/package-sources/source.js +3 -0
  49. package/lib/package-sources/subprocess.d.ts +3 -0
  50. package/lib/package-sources/subprocess.js +18 -0
  51. package/lib/resource-pool.d.ts +54 -0
  52. package/lib/resource-pool.js +120 -0
  53. package/lib/resources.d.ts +1 -0
  54. package/lib/resources.js +6 -0
  55. package/lib/shell.d.ts +59 -0
  56. package/lib/shell.js +118 -0
  57. package/lib/staging/codeartifact.d.ts +44 -0
  58. package/lib/staging/codeartifact.js +258 -0
  59. package/lib/staging/maven.d.ts +5 -0
  60. package/lib/staging/maven.js +83 -0
  61. package/lib/staging/npm.d.ts +4 -0
  62. package/lib/staging/npm.js +56 -0
  63. package/lib/staging/nuget.d.ts +4 -0
  64. package/lib/staging/nuget.js +71 -0
  65. package/lib/staging/parallel-shell.d.ts +6 -0
  66. package/lib/staging/parallel-shell.js +46 -0
  67. package/lib/staging/pypi.d.ts +4 -0
  68. package/lib/staging/pypi.js +49 -0
  69. package/lib/staging/usage-dir.d.ts +31 -0
  70. package/lib/staging/usage-dir.js +87 -0
  71. package/lib/with-aws.d.ts +13 -0
  72. package/lib/with-aws.js +60 -0
  73. package/lib/with-cdk-app.d.ts +146 -0
  74. package/lib/with-cdk-app.js +398 -0
  75. package/lib/with-packages.d.ts +5 -0
  76. package/lib/with-packages.js +14 -0
  77. package/lib/with-sam.d.ts +33 -0
  78. package/lib/with-sam.js +240 -0
  79. package/lib/with-temporary-directory.d.ts +5 -0
  80. package/lib/with-temporary-directory.js +32 -0
  81. package/lib/xpmutex.d.ts +43 -0
  82. package/lib/xpmutex.js +207 -0
  83. package/package.json +73 -0
  84. package/resources/cdk-apps/app/app.js +463 -0
  85. package/resources/cdk-apps/app/cdk.json +7 -0
  86. package/resources/cdk-apps/app/docker/Dockerfile +2 -0
  87. package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
  88. package/resources/cdk-apps/app/lambda/index.js +4 -0
  89. package/resources/cdk-apps/app/lambda/response.json +3 -0
  90. package/resources/cdk-apps/app/nested-stack.js +49 -0
  91. package/resources/cdk-apps/cfn-include-app/.gitignore +1 -0
  92. package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
  93. package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
  94. package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
  95. package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
  96. package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
  97. package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
  98. package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
  99. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
  100. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
  101. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
  102. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
  103. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
  104. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
  105. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
  106. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
  107. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
  108. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
  109. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
  110. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
  111. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
  112. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
  113. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
  114. package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
  115. package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
  116. package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
  117. package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
  118. package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
  119. package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
  120. package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
  121. package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
  122. package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
  123. package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
  124. package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
  125. package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
  126. package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
  127. package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
  128. package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
  129. package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
  130. package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
  131. package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
  132. package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
  133. package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
  134. package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
  135. package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
  136. package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
  137. package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
  138. package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
  139. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
  140. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
  141. package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
  142. package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
  143. package/resources/integ.jest.config.js +25 -0
  144. package/skip-tests.txt +8 -0
  145. package/tests/cli-integ-tests/README.md +47 -0
  146. package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
  147. package/tests/cli-integ-tests/bootstrapping.integtest.js +271 -0
  148. package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
  149. package/tests/cli-integ-tests/cli.integtest.js +1029 -0
  150. package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
  151. package/tests/init-csharp/init-csharp.integtest.js +14 -0
  152. package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
  153. package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
  154. package/tests/init-java/init-java.integtest.d.ts +1 -0
  155. package/tests/init-java/init-java.integtest.js +14 -0
  156. package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
  157. package/tests/init-javascript/init-javascript.integtest.js +15 -0
  158. package/tests/init-python/init-python.integtest.d.ts +1 -0
  159. package/tests/init-python/init-python.integtest.js +19 -0
  160. package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
  161. package/tests/init-typescript-app/init-typescript-app.integtest.js +49 -0
  162. package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
  163. package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
  164. package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
  165. package/tests/uberpackage/uberpackage.integtest.js +11 -0
package/lib/aws.js ADDED
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleep = exports.outputFromStack = exports.retry = exports.isBucketMissingError = exports.isStackMissingError = exports.AwsClients = void 0;
4
+ const AWS = require("aws-sdk");
5
+ class AwsClients {
6
+ constructor(region, output) {
7
+ this.region = region;
8
+ this.output = output;
9
+ this.config = {
10
+ credentials: chainableCredentials(this.region),
11
+ region: this.region,
12
+ maxRetries: 8,
13
+ retryDelayOptions: { base: 500 },
14
+ stsRegionalEndpoints: 'regional',
15
+ };
16
+ this.cloudFormation = makeAwsCaller(AWS.CloudFormation, this.config);
17
+ this.s3 = makeAwsCaller(AWS.S3, this.config);
18
+ this.ecr = makeAwsCaller(AWS.ECR, this.config);
19
+ this.sns = makeAwsCaller(AWS.SNS, this.config);
20
+ this.iam = makeAwsCaller(AWS.IAM, this.config);
21
+ this.lambda = makeAwsCaller(AWS.Lambda, this.config);
22
+ this.sts = makeAwsCaller(AWS.STS, this.config);
23
+ }
24
+ static async default(output) {
25
+ const region = process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION ?? 'us-east-1';
26
+ return AwsClients.forRegion(region, output);
27
+ }
28
+ static async forRegion(region, output) {
29
+ return new AwsClients(region, output);
30
+ }
31
+ async account() {
32
+ // Reduce # of retries, we use this as a circuit breaker for detecting no-config
33
+ return (await new AWS.STS({ ...this.config, maxRetries: 1 }).getCallerIdentity().promise()).Account;
34
+ }
35
+ async deleteStacks(...stackNames) {
36
+ if (stackNames.length === 0) {
37
+ return;
38
+ }
39
+ // We purposely do all stacks serially, because they've been ordered
40
+ // to do the bootstrap stack last.
41
+ for (const stackName of stackNames) {
42
+ await this.cloudFormation('updateTerminationProtection', {
43
+ EnableTerminationProtection: false,
44
+ StackName: stackName,
45
+ });
46
+ await this.cloudFormation('deleteStack', {
47
+ StackName: stackName,
48
+ });
49
+ await retry(this.output, `Deleting ${stackName}`, retry.forSeconds(600), async () => {
50
+ const status = await this.stackStatus(stackName);
51
+ if (status !== undefined && status.endsWith('_FAILED')) {
52
+ throw retry.abort(new Error(`'${stackName}' is in state '${status}'`));
53
+ }
54
+ if (status !== undefined) {
55
+ throw new Error(`Delete of '${stackName}' not complete yet`);
56
+ }
57
+ });
58
+ }
59
+ }
60
+ async stackStatus(stackName) {
61
+ try {
62
+ return (await this.cloudFormation('describeStacks', { StackName: stackName })).Stacks?.[0].StackStatus;
63
+ }
64
+ catch (e) {
65
+ if (isStackMissingError(e)) {
66
+ return undefined;
67
+ }
68
+ throw e;
69
+ }
70
+ }
71
+ async emptyBucket(bucketName) {
72
+ const objects = await this.s3('listObjectVersions', { Bucket: bucketName });
73
+ const deletes = [...objects.Versions || [], ...objects.DeleteMarkers || []]
74
+ .reduce((acc, obj) => {
75
+ if (typeof obj.VersionId !== 'undefined' && typeof obj.Key !== 'undefined') {
76
+ acc.push({ Key: obj.Key, VersionId: obj.VersionId });
77
+ }
78
+ else if (typeof obj.Key !== 'undefined') {
79
+ acc.push({ Key: obj.Key });
80
+ }
81
+ return acc;
82
+ }, []);
83
+ if (deletes.length === 0) {
84
+ return Promise.resolve();
85
+ }
86
+ return this.s3('deleteObjects', {
87
+ Bucket: bucketName,
88
+ Delete: {
89
+ Objects: deletes,
90
+ Quiet: false,
91
+ },
92
+ });
93
+ }
94
+ async deleteImageRepository(repositoryName) {
95
+ await this.ecr('deleteRepository', { repositoryName, force: true });
96
+ }
97
+ async deleteBucket(bucketName) {
98
+ try {
99
+ await this.emptyBucket(bucketName);
100
+ await this.s3('deleteBucket', {
101
+ Bucket: bucketName,
102
+ });
103
+ }
104
+ catch (e) {
105
+ if (isBucketMissingError(e)) {
106
+ return;
107
+ }
108
+ throw e;
109
+ }
110
+ }
111
+ }
112
+ exports.AwsClients = AwsClients;
113
+ /**
114
+ * Perform an AWS call from nothing
115
+ *
116
+ * Create the correct client, do the call and resole the promise().
117
+ */
118
+ async function awsCall(ctor, config, call, request) {
119
+ const cfn = new ctor(config);
120
+ const response = cfn[call](request);
121
+ try {
122
+ return response.promise();
123
+ }
124
+ catch (e) {
125
+ const newErr = new Error(`${call}(${JSON.stringify(request)}): ${e.message}`);
126
+ newErr.code = e.code;
127
+ throw newErr;
128
+ }
129
+ }
130
+ /**
131
+ * Factory function to invoke 'awsCall' for specific services.
132
+ *
133
+ * Not strictly necessary but calling this replaces a whole bunch of annoying generics you otherwise have to type:
134
+ *
135
+ * ```ts
136
+ * export function cloudFormation<
137
+ * C extends keyof ServiceCalls<AWS.CloudFormation>,
138
+ * >(call: C, request: First<ServiceCalls<AWS.CloudFormation>[C]>): Promise<Second<ServiceCalls<AWS.CloudFormation>[C]>> {
139
+ * return awsCall(AWS.CloudFormation, call, request);
140
+ * }
141
+ * ```
142
+ */
143
+ function makeAwsCaller(ctor, config) {
144
+ return (call, request) => {
145
+ return awsCall(ctor, config, call, request);
146
+ };
147
+ }
148
+ function isStackMissingError(e) {
149
+ return e.message.indexOf('does not exist') > -1;
150
+ }
151
+ exports.isStackMissingError = isStackMissingError;
152
+ function isBucketMissingError(e) {
153
+ return e.message.indexOf('does not exist') > -1;
154
+ }
155
+ exports.isBucketMissingError = isBucketMissingError;
156
+ /**
157
+ * Retry an async operation until a deadline is hit.
158
+ *
159
+ * Use `retry.forSeconds()` to construct a deadline relative to right now.
160
+ *
161
+ * Exceptions will cause the operation to retry. Use `retry.abort` to annotate an exception
162
+ * to stop the retry and end in a failure.
163
+ */
164
+ async function retry(output, operation, deadline, block) {
165
+ let i = 0;
166
+ output.write(`💈 ${operation}\n`);
167
+ while (true) {
168
+ try {
169
+ i++;
170
+ const ret = await block();
171
+ output.write(`💈 ${operation}: succeeded after ${i} attempts\n`);
172
+ return ret;
173
+ }
174
+ catch (e) {
175
+ if (e.abort || Date.now() > deadline.getTime()) {
176
+ throw new Error(`${operation}: did not succeed after ${i} attempts: ${e}`);
177
+ }
178
+ output.write(`⏳ ${operation} (${e.message})\n`);
179
+ await sleep(5000);
180
+ }
181
+ }
182
+ }
183
+ exports.retry = retry;
184
+ /**
185
+ * Make a deadline for the `retry` function relative to the current time.
186
+ */
187
+ retry.forSeconds = (seconds) => {
188
+ return new Date(Date.now() + seconds * 1000);
189
+ };
190
+ /**
191
+ * Annotate an error to stop the retrying
192
+ */
193
+ retry.abort = (e) => {
194
+ e.abort = true;
195
+ return e;
196
+ };
197
+ function outputFromStack(key, stack) {
198
+ return (stack.Outputs ?? []).find(o => o.OutputKey === key)?.OutputValue;
199
+ }
200
+ exports.outputFromStack = outputFromStack;
201
+ async function sleep(ms) {
202
+ return new Promise(ok => setTimeout(ok, ms));
203
+ }
204
+ exports.sleep = sleep;
205
+ function chainableCredentials(region) {
206
+ const profileName = process.env.AWS_PROFILE;
207
+ if (process.env.CODEBUILD_BUILD_ARN && profileName) {
208
+ // in codebuild we must assume the role that the cdk uses
209
+ // otherwise credentials will just be picked up by the normal sdk
210
+ // heuristics and expire after an hour.
211
+ // can't use '~' since the SDK doesn't seem to expand it...?
212
+ const configPath = `${process.env.HOME}/.aws/config`;
213
+ const ini = new AWS.IniLoader().loadFrom({
214
+ filename: configPath,
215
+ isConfig: true,
216
+ });
217
+ const profile = ini[profileName];
218
+ if (!profile) {
219
+ throw new Error(`Profile '${profileName}' does not exist in config file (${configPath})`);
220
+ }
221
+ const arn = profile.role_arn;
222
+ const externalId = profile.external_id;
223
+ if (!arn) {
224
+ throw new Error(`role_arn does not exist in profile ${profileName}`);
225
+ }
226
+ if (!externalId) {
227
+ throw new Error(`external_id does not exist in profile ${externalId}`);
228
+ }
229
+ return new AWS.ChainableTemporaryCredentials({
230
+ params: {
231
+ RoleArn: arn,
232
+ ExternalId: externalId,
233
+ RoleSessionName: 'integ-tests',
234
+ },
235
+ stsConfig: {
236
+ region,
237
+ },
238
+ masterCredentials: new AWS.ECSCredentials(),
239
+ });
240
+ }
241
+ return undefined;
242
+ }
243
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXdzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtCQUErQjtBQUUvQixNQUFhLFVBQVU7SUFvQnJCLFlBQTRCLE1BQWMsRUFBbUIsTUFBNkI7UUFBOUQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFtQixXQUFNLEdBQU4sTUFBTSxDQUF1QjtRQUN4RixJQUFJLENBQUMsTUFBTSxHQUFHO1lBQ1osV0FBVyxFQUFFLG9CQUFvQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDOUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFVBQVUsRUFBRSxDQUFDO1lBQ2IsaUJBQWlCLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFO1lBQ2hDLG9CQUFvQixFQUFFLFVBQVU7U0FDakMsQ0FBQztRQUNGLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JFLElBQUksQ0FBQyxFQUFFLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxHQUFHLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxHQUFHLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxHQUFHLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxNQUFNLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JELElBQUks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RyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztZQUN2QyxRQUFRLEVBQUUsVUFBVTtZQUNwQixRQUFRLEVBQUUsSUFBSTtTQUNmLENBQUMsQ0FBQztRQUVILE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVqQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQyxZQUFZLFdBQVcsb0NBQW9DLFVBQVUsR0FBRyxDQUFDLENBQUM7U0FDM0Y7UUFFRCxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQzdCLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUM7UUFFdkMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNSLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLFdBQVcsRUFBRSxDQUFDLENBQUM7U0FDdEU7UUFFRCxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsVUFBVSxFQUFFLENBQUMsQ0FBQztTQUN4RTtRQUVELE9BQU8sSUFBSSxHQUFHLENBQUMsNkJBQTZCLENBQUM7WUFDM0MsTUFBTSxFQUFFO2dCQUNOLE9BQU8sRUFBRSxHQUFHO2dCQUNaLFVBQVUsRUFBRSxVQUFVO2dCQUN0QixlQUFlLEVBQUUsYUFBYTthQUMvQjtZQUNELFNBQVMsRUFBRTtnQkFDVCxNQUFNO2FBQ1A7WUFDRCxpQkFBaUIsRUFBRSxJQUFJLEdBQUcsQ0FBQyxjQUFjLEVBQUU7U0FDNUMsQ0FBQyxDQUFDO0tBQ0o7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgQVdTIGZyb20gJ2F3cy1zZGsnO1xuXG5leHBvcnQgY2xhc3MgQXdzQ2xpZW50cyB7XG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZGVmYXVsdChvdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbSkge1xuICAgIGNvbnN0IHJlZ2lvbiA9IHByb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OID8/ICd1cy1lYXN0LTEnO1xuICAgIHJldHVybiBBd3NDbGllbnRzLmZvclJlZ2lvbihyZWdpb24sIG91dHB1dCk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIGZvclJlZ2lvbihyZWdpb246IHN0cmluZywgb3V0cHV0OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0pIHtcbiAgICByZXR1cm4gbmV3IEF3c0NsaWVudHMocmVnaW9uLCBvdXRwdXQpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IGFueTtcblxuICBwdWJsaWMgcmVhZG9ubHkgY2xvdWRGb3JtYXRpb246IEF3c0NhbGxlcjxBV1MuQ2xvdWRGb3JtYXRpb24+O1xuICBwdWJsaWMgcmVhZG9ubHkgczM6IEF3c0NhbGxlcjxBV1MuUzM+O1xuICBwdWJsaWMgcmVhZG9ubHkgZWNyOiBBd3NDYWxsZXI8QVdTLkVDUj47XG4gIHB1YmxpYyByZWFkb25seSBzbnM6IEF3c0NhbGxlcjxBV1MuU05TPjtcbiAgcHVibGljIHJlYWRvbmx5IGlhbTogQXdzQ2FsbGVyPEFXUy5JQU0+O1xuICBwdWJsaWMgcmVhZG9ubHkgbGFtYmRhOiBBd3NDYWxsZXI8QVdTLkxhbWJkYT47XG4gIHB1YmxpYyByZWFkb25seSBzdHM6IEF3c0NhbGxlcjxBV1MuU1RTPjtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmcsIHByaXZhdGUgcmVhZG9ubHkgb3V0cHV0OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0pIHtcbiAgICB0aGlzLmNvbmZpZyA9IHtcbiAgICAgIGNyZWRlbnRpYWxzOiBjaGFpbmFibGVDcmVkZW50aWFscyh0aGlzLnJlZ2lvbiksXG4gICAgICByZWdpb246IHRoaXMucmVnaW9uLFxuICAgICAgbWF4UmV0cmllczogOCxcbiAgICAgIHJldHJ5RGVsYXlPcHRpb25zOiB7IGJhc2U6IDUwMCB9LFxuICAgICAgc3RzUmVnaW9uYWxFbmRwb2ludHM6ICdyZWdpb25hbCcsXG4gICAgfTtcbiAgICB0aGlzLmNsb3VkRm9ybWF0aW9uID0gbWFrZUF3c0NhbGxlcihBV1MuQ2xvdWRGb3JtYXRpb24sIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnMzID0gbWFrZUF3c0NhbGxlcihBV1MuUzMsIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmVjciA9IG1ha2VBd3NDYWxsZXIoQVdTLkVDUiwgdGhpcy5jb25maWcpO1xuICAgIHRoaXMuc25zID0gbWFrZUF3c0NhbGxlcihBV1MuU05TLCB0aGlzLmNvbmZpZyk7XG4gICAgdGhpcy5pYW0gPSBtYWtlQXdzQ2FsbGVyKEFXUy5JQU0sIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmxhbWJkYSA9IG1ha2VBd3NDYWxsZXIoQVdTLkxhbWJkYSwgdGhpcy5jb25maWcpO1xuICAgIHRoaXMuc3RzID0gbWFrZUF3c0NhbGxlcihBV1MuU1RTLCB0aGlzLmNvbmZpZyk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgYWNjb3VudCgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIC8vIFJlZHVjZSAjIG9mIHJldHJpZXMsIHdlIHVzZSB0aGlzIGFzIGEgY2lyY3VpdCBicmVha2VyIGZvciBkZXRlY3Rpbmcgbm8tY29uZmlnXG4gICAgcmV0dXJuIChhd2FpdCBuZXcgQVdTLlNUUyh7IC4uLnRoaXMuY29uZmlnLCBtYXhSZXRyaWVzOiAxIH0pLmdldENhbGxlcklkZW50aXR5KCkucHJvbWlzZSgpKS5BY2NvdW50ITtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWxldGVTdGFja3MoLi4uc3RhY2tOYW1lczogc3RyaW5nW10pIHtcbiAgICBpZiAoc3RhY2tOYW1lcy5sZW5ndGggPT09IDApIHsgcmV0dXJuOyB9XG5cbiAgICAvLyBXZSBwdXJwb3NlbHkgZG8gYWxsIHN0YWNrcyBzZXJpYWxseSwgYmVjYXVzZSB0aGV5J3ZlIGJlZW4gb3JkZXJlZFxuICAgIC8vIHRvIGRvIHRoZSBib290c3RyYXAgc3RhY2sgbGFzdC5cbiAgICBmb3IgKGNvbnN0IHN0YWNrTmFtZSBvZiBzdGFja05hbWVzKSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3VkRm9ybWF0aW9uKCd1cGRhdGVUZXJtaW5hdGlvblByb3RlY3Rpb24nLCB7XG4gICAgICAgIEVuYWJsZVRlcm1pbmF0aW9uUHJvdGVjdGlvbjogZmFsc2UsXG4gICAgICAgIFN0YWNrTmFtZTogc3RhY2tOYW1lLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCB0aGlzLmNsb3VkRm9ybWF0aW9uKCdkZWxldGVTdGFjaycsIHtcbiAgICAgICAgU3RhY2tOYW1lOiBzdGFja05hbWUsXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgcmV0cnkodGhpcy5vdXRwdXQsIGBEZWxldGluZyAke3N0YWNrTmFtZX1gLCByZXRyeS5mb3JTZWNvbmRzKDYwMCksIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgdGhpcy5zdGFja1N0YXR1cyhzdGFja05hbWUpO1xuICAgICAgICBpZiAoc3RhdHVzICE9PSB1bmRlZmluZWQgJiYgc3RhdHVzLmVuZHNXaXRoKCdfRkFJTEVEJykpIHtcbiAgICAgICAgICB0aHJvdyByZXRyeS5hYm9ydChuZXcgRXJyb3IoYCcke3N0YWNrTmFtZX0nIGlzIGluIHN0YXRlICcke3N0YXR1c30nYCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0dXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRGVsZXRlIG9mICcke3N0YWNrTmFtZX0nIG5vdCBjb21wbGV0ZSB5ZXRgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHN0YWNrU3RhdHVzKHN0YWNrTmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIChhd2FpdCB0aGlzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBzdGFja05hbWUgfSkpLlN0YWNrcz8uWzBdLlN0YWNrU3RhdHVzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChpc1N0YWNrTWlzc2luZ0Vycm9yKGUpKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGVtcHR5QnVja2V0KGJ1Y2tldE5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IG9iamVjdHMgPSBhd2FpdCB0aGlzLnMzKCdsaXN0T2JqZWN0VmVyc2lvbnMnLCB7IEJ1Y2tldDogYnVja2V0TmFtZSB9KTtcbiAgICBjb25zdCBkZWxldGVzID0gWy4uLm9iamVjdHMuVmVyc2lvbnMgfHwgW10sIC4uLm9iamVjdHMuRGVsZXRlTWFya2VycyB8fCBbXV1cbiAgICAgIC5yZWR1Y2UoKGFjYywgb2JqKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqLlZlcnNpb25JZCAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG9iai5LZXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgYWNjLnB1c2goeyBLZXk6IG9iai5LZXksIFZlcnNpb25JZDogb2JqLlZlcnNpb25JZCB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygb2JqLktleSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBhY2MucHVzaCh7IEtleTogb2JqLktleSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgW10gYXMgQVdTLlMzLk9iamVjdElkZW50aWZpZXJMaXN0KTtcbiAgICBpZiAoZGVsZXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuczMoJ2RlbGV0ZU9iamVjdHMnLCB7XG4gICAgICBCdWNrZXQ6IGJ1Y2tldE5hbWUsXG4gICAgICBEZWxldGU6IHtcbiAgICAgICAgT2JqZWN0czogZGVsZXRlcyxcbiAgICAgICAgUXVpZXQ6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWxldGVJbWFnZVJlcG9zaXRvcnkocmVwb3NpdG9yeU5hbWU6IHN0cmluZykge1xuICAgIGF3YWl0IHRoaXMuZWNyKCdkZWxldGVSZXBvc2l0b3J5JywgeyByZXBvc2l0b3J5TmFtZSwgZm9yY2U6IHRydWUgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVsZXRlQnVja2V0KGJ1Y2tldE5hbWU6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVtcHR5QnVja2V0KGJ1Y2tldE5hbWUpO1xuICAgICAgYXdhaXQgdGhpcy5zMygnZGVsZXRlQnVja2V0Jywge1xuICAgICAgICBCdWNrZXQ6IGJ1Y2tldE5hbWUsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoaXNCdWNrZXRNaXNzaW5nRXJyb3IoZSkpIHsgcmV0dXJuOyB9XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFBlcmZvcm0gYW4gQVdTIGNhbGwgZnJvbSBub3RoaW5nXG4gKlxuICogQ3JlYXRlIHRoZSBjb3JyZWN0IGNsaWVudCwgZG8gdGhlIGNhbGwgYW5kIHJlc29sZSB0aGUgcHJvbWlzZSgpLlxuICovXG5hc3luYyBmdW5jdGlvbiBhd3NDYWxsPFxuICBBIGV4dGVuZHMgQVdTLlNlcnZpY2UsXG4gIEIgZXh0ZW5kcyBrZXlvZiBTZXJ2aWNlQ2FsbHM8QT4sXG4+KGN0b3I6IG5ldyAoY29uZmlnOiBhbnkpID0+IEEsIGNvbmZpZzogYW55LCBjYWxsOiBCLCByZXF1ZXN0OiBGaXJzdDxTZXJ2aWNlQ2FsbHM8QT5bQl0+KTogUHJvbWlzZTxTZWNvbmQ8U2VydmljZUNhbGxzPEE+W0JdPj4ge1xuICBjb25zdCBjZm4gPSBuZXcgY3Rvcihjb25maWcpO1xuICBjb25zdCByZXNwb25zZSA9IGNmbltjYWxsXShyZXF1ZXN0KTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcmVzcG9uc2UucHJvbWlzZSgpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc3QgbmV3RXJyID0gbmV3IEVycm9yKGAke2NhbGx9KCR7SlNPTi5zdHJpbmdpZnkocmVxdWVzdCl9KTogJHtlLm1lc3NhZ2V9YCk7XG4gICAgKG5ld0VyciBhcyBhbnkpLmNvZGUgPSBlLmNvZGU7XG4gICAgdGhyb3cgbmV3RXJyO1xuICB9XG59XG5cbnR5cGUgQXdzQ2FsbGVyPEE+ID0gPEIgZXh0ZW5kcyBrZXlvZiBTZXJ2aWNlQ2FsbHM8QT4+KGNhbGw6IEIsIHJlcXVlc3Q6IEZpcnN0PFNlcnZpY2VDYWxsczxBPltCXT4pID0+IFByb21pc2U8U2Vjb25kPFNlcnZpY2VDYWxsczxBPltCXT4+O1xuXG4vKipcbiAqIEZhY3RvcnkgZnVuY3Rpb24gdG8gaW52b2tlICdhd3NDYWxsJyBmb3Igc3BlY2lmaWMgc2VydmljZXMuXG4gKlxuICogTm90IHN0cmljdGx5IG5lY2Vzc2FyeSBidXQgY2FsbGluZyB0aGlzIHJlcGxhY2VzIGEgd2hvbGUgYnVuY2ggb2YgYW5ub3lpbmcgZ2VuZXJpY3MgeW91IG90aGVyd2lzZSBoYXZlIHRvIHR5cGU6XG4gKlxuICogYGBgdHNcbiAqIGV4cG9ydCBmdW5jdGlvbiBjbG91ZEZvcm1hdGlvbjxcbiAqICAgQyBleHRlbmRzIGtleW9mIFNlcnZpY2VDYWxsczxBV1MuQ2xvdWRGb3JtYXRpb24+LFxuICogPihjYWxsOiBDLCByZXF1ZXN0OiBGaXJzdDxTZXJ2aWNlQ2FsbHM8QVdTLkNsb3VkRm9ybWF0aW9uPltDXT4pOiBQcm9taXNlPFNlY29uZDxTZXJ2aWNlQ2FsbHM8QVdTLkNsb3VkRm9ybWF0aW9uPltDXT4+IHtcbiAqICAgcmV0dXJuIGF3c0NhbGwoQVdTLkNsb3VkRm9ybWF0aW9uLCBjYWxsLCByZXF1ZXN0KTtcbiAqIH1cbiAqIGBgYFxuICovXG5mdW5jdGlvbiBtYWtlQXdzQ2FsbGVyPEEgZXh0ZW5kcyBBV1MuU2VydmljZT4oY3RvcjogbmV3IChjb25maWc6IGFueSkgPT4gQSwgY29uZmlnOiBhbnkpOiBBd3NDYWxsZXI8QT4ge1xuICByZXR1cm4gPEIgZXh0ZW5kcyBrZXlvZiBTZXJ2aWNlQ2FsbHM8QT4+KGNhbGw6IEIsIHJlcXVlc3Q6IEZpcnN0PFNlcnZpY2VDYWxsczxBPltCXT4pOiBQcm9taXNlPFNlY29uZDxTZXJ2aWNlQ2FsbHM8QT5bQl0+PiA9PiB7XG4gICAgcmV0dXJuIGF3c0NhbGwoY3RvciwgY29uZmlnLCBjYWxsLCByZXF1ZXN0KTtcbiAgfTtcbn1cblxudHlwZSBTZXJ2aWNlQ2FsbHM8VD4gPSBOb05heU5ldmVyPFNpbXBsaWZpZWRTZXJ2aWNlPFQ+Pjtcbi8vIE1hcCBldmVyIG1lbWJlciBpbiB0aGUgdHlwZSB0byB0aGUgaW1wb3J0YW50IEFXUyBjYWxsIG92ZXJsb2FkLCBvciB0byAnbmV2ZXInXG50eXBlIFNpbXBsaWZpZWRTZXJ2aWNlPFQ+ID0ge1trIGluIGtleW9mIFRdOiBBd3NDYWxsSU88VFtrXT59O1xuLy8gUmVtb3ZlIGFsbCAnbmV2ZXInIHR5cGVzIGZyb20gYW4gb2JqZWN0IHR5cGVcbnR5cGUgTm9OYXlOZXZlcjxUPiA9IFBpY2s8VCwge1trIGluIGtleW9mIFRdOiBUW2tdIGV4dGVuZHMgbmV2ZXIgPyBuZXZlciA6IGsgfVtrZXlvZiBUXT47XG5cbi8vIEJlY2F1c2Ugb2YgdGhlIG92ZXJsb2FkcyBhbiBBV1MgaGFuZGxlciB0eXBlIGxvb2tzIGxpa2UgdGhpczpcbi8vXG4vLyAgIHtcbi8vICAgICAgKHBhcmFtczogSU5QVVRTVFJVQ1QsIGNhbGxiYWNrPzogKChlcnI6IEFXU0Vycm9yLCBkYXRhOiB7fSkgPT4gdm9pZCkgfCB1bmRlZmluZWQpOiBSZXF1ZXN0PE9VVFBVVCwgLi4uPjtcbi8vICAgICAgKGNhbGxiYWNrPzogKChlcnI6IEFXUy5BV1NFcnJvciwgZGF0YToge30pID0+IHZvaWQpIHwgdW5kZWZpbmVkKTogQVdTLlJlcXVlc3Q8Li4uPjtcbi8vICAgfVxuLy9cbi8vIEdldCB0aGUgZmlyc3Qgb3ZlcmxvYWQgYW5kIGV4dHJhY3QgdGhlIGlucHV0IGFuZCBvdXRwdXQgc3RydWN0IHR5cGVzXG50eXBlIEF3c0NhbGxJTzxUPiA9XG4gIFQgZXh0ZW5kcyB7XG4gICAgKGFyZ3M6IGluZmVyIElOUFVULCBjYWxsYmFjaz86ICgoZXJyOiBBV1MuQVdTRXJyb3IsIGRhdGE6IGFueSkgPT4gdm9pZCkgfCB1bmRlZmluZWQpOiBBV1MuUmVxdWVzdDxpbmZlciBPVVRQVVQsIEFXUy5BV1NFcnJvcj47XG4gICAgKGNhbGxiYWNrPzogKChlcnI6IEFXUy5BV1NFcnJvciwgZGF0YToge30pID0+IHZvaWQpIHwgdW5kZWZpbmVkKTogQVdTLlJlcXVlc3Q8YW55LCBhbnk+O1xuICB9ID8gW0lOUFVULCBPVVRQVVRdIDogbmV2ZXI7XG5cbnR5cGUgRmlyc3Q8VD4gPSBUIGV4dGVuZHMgW2FueSwgYW55XSA/IFRbMF0gOiBuZXZlcjtcbnR5cGUgU2Vjb25kPFQ+ID0gVCBleHRlbmRzIFthbnksIGFueV0gPyBUWzFdIDogbmV2ZXI7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU3RhY2tNaXNzaW5nRXJyb3IoZTogRXJyb3IpIHtcbiAgcmV0dXJuIGUubWVzc2FnZS5pbmRleE9mKCdkb2VzIG5vdCBleGlzdCcpID4gLTE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0J1Y2tldE1pc3NpbmdFcnJvcihlOiBFcnJvcikge1xuICByZXR1cm4gZS5tZXNzYWdlLmluZGV4T2YoJ2RvZXMgbm90IGV4aXN0JykgPiAtMTtcbn1cblxuLyoqXG4gKiBSZXRyeSBhbiBhc3luYyBvcGVyYXRpb24gdW50aWwgYSBkZWFkbGluZSBpcyBoaXQuXG4gKlxuICogVXNlIGByZXRyeS5mb3JTZWNvbmRzKClgIHRvIGNvbnN0cnVjdCBhIGRlYWRsaW5lIHJlbGF0aXZlIHRvIHJpZ2h0IG5vdy5cbiAqXG4gKiBFeGNlcHRpb25zIHdpbGwgY2F1c2UgdGhlIG9wZXJhdGlvbiB0byByZXRyeS4gVXNlIGByZXRyeS5hYm9ydGAgdG8gYW5ub3RhdGUgYW4gZXhjZXB0aW9uXG4gKiB0byBzdG9wIHRoZSByZXRyeSBhbmQgZW5kIGluIGEgZmFpbHVyZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJldHJ5PEE+KG91dHB1dDogTm9kZUpTLldyaXRhYmxlU3RyZWFtLCBvcGVyYXRpb246IHN0cmluZywgZGVhZGxpbmU6IERhdGUsIGJsb2NrOiAoKSA9PiBQcm9taXNlPEE+KTogUHJvbWlzZTxBPiB7XG4gIGxldCBpID0gMDtcbiAgb3V0cHV0LndyaXRlKGDwn5KIICR7b3BlcmF0aW9ufVxcbmApO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICBpKys7XG4gICAgICBjb25zdCByZXQgPSBhd2FpdCBibG9jaygpO1xuICAgICAgb3V0cHV0LndyaXRlKGDwn5KIICR7b3BlcmF0aW9ufTogc3VjY2VlZGVkIGFmdGVyICR7aX0gYXR0ZW1wdHNcXG5gKTtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUuYWJvcnQgfHwgRGF0ZS5ub3coKSA+IGRlYWRsaW5lLmdldFRpbWUoICkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke29wZXJhdGlvbn06IGRpZCBub3Qgc3VjY2VlZCBhZnRlciAke2l9IGF0dGVtcHRzOiAke2V9YCk7XG4gICAgICB9XG4gICAgICBvdXRwdXQud3JpdGUoYOKPsyAke29wZXJhdGlvbn0gKCR7ZS5tZXNzYWdlfSlcXG5gKTtcbiAgICAgIGF3YWl0IHNsZWVwKDUwMDApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1ha2UgYSBkZWFkbGluZSBmb3IgdGhlIGByZXRyeWAgZnVuY3Rpb24gcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgdGltZS5cbiAqL1xucmV0cnkuZm9yU2Vjb25kcyA9IChzZWNvbmRzOiBudW1iZXIpOiBEYXRlID0+IHtcbiAgcmV0dXJuIG5ldyBEYXRlKERhdGUubm93KCkgKyBzZWNvbmRzICogMTAwMCk7XG59O1xuXG4vKipcbiAqIEFubm90YXRlIGFuIGVycm9yIHRvIHN0b3AgdGhlIHJldHJ5aW5nXG4gKi9cbnJldHJ5LmFib3J0ID0gKGU6IEVycm9yKTogRXJyb3IgPT4ge1xuICAoZSBhcyBhbnkpLmFib3J0ID0gdHJ1ZTtcbiAgcmV0dXJuIGU7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gb3V0cHV0RnJvbVN0YWNrKGtleTogc3RyaW5nLCBzdGFjazogQVdTLkNsb3VkRm9ybWF0aW9uLlN0YWNrKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIChzdGFjay5PdXRwdXRzID8/IFtdKS5maW5kKG8gPT4gby5PdXRwdXRLZXkgPT09IGtleSk/Lk91dHB1dFZhbHVlO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcikge1xuICByZXR1cm4gbmV3IFByb21pc2Uob2sgPT4gc2V0VGltZW91dChvaywgbXMpKTtcbn1cblxuZnVuY3Rpb24gY2hhaW5hYmxlQ3JlZGVudGlhbHMocmVnaW9uOiBzdHJpbmcpOiBBV1MuQ3JlZGVudGlhbHMgfCB1bmRlZmluZWQge1xuXG4gIGNvbnN0IHByb2ZpbGVOYW1lID0gcHJvY2Vzcy5lbnYuQVdTX1BST0ZJTEU7XG4gIGlmIChwcm9jZXNzLmVudi5DT0RFQlVJTERfQlVJTERfQVJOICYmIHByb2ZpbGVOYW1lKSB7XG5cbiAgICAvLyBpbiBjb2RlYnVpbGQgd2UgbXVzdCBhc3N1bWUgdGhlIHJvbGUgdGhhdCB0aGUgY2RrIHVzZXNcbiAgICAvLyBvdGhlcndpc2UgY3JlZGVudGlhbHMgd2lsbCBqdXN0IGJlIHBpY2tlZCB1cCBieSB0aGUgbm9ybWFsIHNka1xuICAgIC8vIGhldXJpc3RpY3MgYW5kIGV4cGlyZSBhZnRlciBhbiBob3VyLlxuXG4gICAgLy8gY2FuJ3QgdXNlICd+JyBzaW5jZSB0aGUgU0RLIGRvZXNuJ3Qgc2VlbSB0byBleHBhbmQgaXQuLi4/XG4gICAgY29uc3QgY29uZmlnUGF0aCA9IGAke3Byb2Nlc3MuZW52LkhPTUV9Ly5hd3MvY29uZmlnYDtcbiAgICBjb25zdCBpbmkgPSBuZXcgQVdTLkluaUxvYWRlcigpLmxvYWRGcm9tKHtcbiAgICAgIGZpbGVuYW1lOiBjb25maWdQYXRoLFxuICAgICAgaXNDb25maWc6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBwcm9maWxlID0gaW5pW3Byb2ZpbGVOYW1lXTtcblxuICAgIGlmICghcHJvZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm9maWxlICcke3Byb2ZpbGVOYW1lfScgZG9lcyBub3QgZXhpc3QgaW4gY29uZmlnIGZpbGUgKCR7Y29uZmlnUGF0aH0pYCk7XG4gICAgfVxuXG4gICAgY29uc3QgYXJuID0gcHJvZmlsZS5yb2xlX2FybjtcbiAgICBjb25zdCBleHRlcm5hbElkID0gcHJvZmlsZS5leHRlcm5hbF9pZDtcblxuICAgIGlmICghYXJuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHJvbGVfYXJuIGRvZXMgbm90IGV4aXN0IGluIHByb2ZpbGUgJHtwcm9maWxlTmFtZX1gKTtcbiAgICB9XG5cbiAgICBpZiAoIWV4dGVybmFsSWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgZXh0ZXJuYWxfaWQgZG9lcyBub3QgZXhpc3QgaW4gcHJvZmlsZSAke2V4dGVybmFsSWR9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBV1MuQ2hhaW5hYmxlVGVtcG9yYXJ5Q3JlZGVudGlhbHMoe1xuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIFJvbGVBcm46IGFybixcbiAgICAgICAgRXh0ZXJuYWxJZDogZXh0ZXJuYWxJZCxcbiAgICAgICAgUm9sZVNlc3Npb25OYW1lOiAnaW50ZWctdGVzdHMnLFxuICAgICAgfSxcbiAgICAgIHN0c0NvbmZpZzoge1xuICAgICAgICByZWdpb24sXG4gICAgICB9LFxuICAgICAgbWFzdGVyQ3JlZGVudGlhbHM6IG5ldyBBV1MuRUNTQ3JlZGVudGlhbHMoKSxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59Il19
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ /**
3
+ * Routines for corking stdout and stderr
4
+ */
5
+ import * as stream from 'stream';
6
+ export declare class MemoryStream extends stream.Writable {
7
+ private parts;
8
+ _write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void;
9
+ buffer(): Buffer;
10
+ clear(): void;
11
+ flushTo(strm: NodeJS.WritableStream): Promise<unknown>;
12
+ toString(): string;
13
+ }
package/lib/corking.js ADDED
@@ -0,0 +1,34 @@
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
+ }
29
+ toString() {
30
+ return this.buffer().toString();
31
+ }
32
+ }
33
+ exports.MemoryStream = MemoryStream;
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ya2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNvcmtpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7O0dBRUc7QUFDSCxpQ0FBaUM7QUFFakMsTUFBYSxZQUFhLFNBQVEsTUFBTSxDQUFDLFFBQVE7SUFBakQ7O1FBQ1UsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7SUF5QnRDLENBQUM7SUF2QlEsTUFBTSxDQUFDLEtBQWEsRUFBRSxTQUFpQixFQUFFLFFBQXdDO1FBQ3RGLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLFFBQVEsRUFBRSxDQUFDO0lBQ2IsQ0FBQztJQUVNLE1BQU07UUFDWCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTSxLQUFLO1FBQ1YsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVNLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBMkI7UUFDOUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1osT0FBTyxJQUFJLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDbEQ7SUFDSCxDQUFDO0lBRU0sUUFBUTtRQUNiLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xDLENBQUM7Q0FDRjtBQTFCRCxvQ0EwQkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJvdXRpbmVzIGZvciBjb3JraW5nIHN0ZG91dCBhbmQgc3RkZXJyXG4gKi9cbmltcG9ydCAqIGFzIHN0cmVhbSBmcm9tICdzdHJlYW0nO1xuXG5leHBvcnQgY2xhc3MgTWVtb3J5U3RyZWFtIGV4dGVuZHMgc3RyZWFtLldyaXRhYmxlIHtcbiAgcHJpdmF0ZSBwYXJ0cyA9IG5ldyBBcnJheTxCdWZmZXI+KCk7XG5cbiAgcHVibGljIF93cml0ZShjaHVuazogQnVmZmVyLCBfZW5jb2Rpbmc6IHN0cmluZywgY2FsbGJhY2s6IChlcnJvcj86IEVycm9yIHwgbnVsbCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMucGFydHMucHVzaChjaHVuayk7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBidWZmZXIoKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQodGhpcy5wYXJ0cyk7XG4gIH1cblxuICBwdWJsaWMgY2xlYXIoKSB7XG4gICAgdGhpcy5wYXJ0cy5zcGxpY2UoMCwgdGhpcy5wYXJ0cy5sZW5ndGgpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGZsdXNoVG8oc3RybTogTm9kZUpTLldyaXRhYmxlU3RyZWFtKSB7XG4gICAgY29uc3QgZmx1c2hlZCA9IHN0cm0ud3JpdGUodGhpcy5idWZmZXIoKSk7XG4gICAgaWYgKCFmbHVzaGVkKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2Uob2sgPT4gc3RybS5vbmNlKCdkcmFpbicsIG9rKSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmJ1ZmZlcigpLnRvU3RyaW5nKCk7XG4gIH1cbn1cbiJdfQ==
package/lib/files.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export declare function rmFile(filename: string): Promise<void>;
2
+ export declare function addToFile(filename: string, line: string): Promise<void>;
3
+ export declare function writeFile(filename: string, contents: string): Promise<void>;
4
+ export declare function copyDirectoryContents(dir: string, target: string): Promise<void>;
5
+ export declare function findUp(name: string, directory?: string): string | undefined;
6
+ /**
7
+ * Docker-safe home directory
8
+ */
9
+ export declare function homeDir(): string;
10
+ export declare function loadLines(filename: string): Promise<string[]>;
11
+ export declare function writeLines(filename: string, lines: string[]): Promise<void>;
12
+ /**
13
+ * Update a spaceless ini file in place
14
+ */
15
+ export declare function updateIniKey(lines: string[], key: string, value: string): void;
package/lib/files.js ADDED
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateIniKey = exports.writeLines = exports.loadLines = exports.homeDir = exports.findUp = exports.copyDirectoryContents = exports.writeFile = exports.addToFile = exports.rmFile = void 0;
4
+ const os = require("os");
5
+ const path = require("path");
6
+ const fs = require("fs-extra");
7
+ async function rmFile(filename) {
8
+ if (await fs.pathExists(filename)) {
9
+ await fs.unlink(filename);
10
+ }
11
+ }
12
+ exports.rmFile = rmFile;
13
+ async function addToFile(filename, line) {
14
+ let contents = await fs.pathExists(filename) ? await fs.readFile(filename, { encoding: 'utf-8' }) : '';
15
+ if (!contents.endsWith('\n')) {
16
+ contents += '\n';
17
+ }
18
+ contents += line + '\n';
19
+ await writeFile(filename, contents);
20
+ }
21
+ exports.addToFile = addToFile;
22
+ async function writeFile(filename, contents) {
23
+ await fs.mkdirp(path.dirname(filename));
24
+ await fs.writeFile(filename, contents, { encoding: 'utf-8' });
25
+ }
26
+ exports.writeFile = writeFile;
27
+ async function copyDirectoryContents(dir, target) {
28
+ for (const file of await fs.readdir(path.join(dir), { encoding: 'utf-8' })) {
29
+ await fs.copyFile(path.join(dir, file), path.join(target, file));
30
+ }
31
+ }
32
+ exports.copyDirectoryContents = copyDirectoryContents;
33
+ function findUp(name, directory = process.cwd()) {
34
+ const absoluteDirectory = path.resolve(directory);
35
+ const file = path.join(directory, name);
36
+ if (fs.existsSync(file)) {
37
+ return file;
38
+ }
39
+ const { root } = path.parse(absoluteDirectory);
40
+ if (absoluteDirectory == root) {
41
+ return undefined;
42
+ }
43
+ return findUp(name, path.dirname(absoluteDirectory));
44
+ }
45
+ exports.findUp = findUp;
46
+ /**
47
+ * Docker-safe home directory
48
+ */
49
+ function homeDir() {
50
+ return os.userInfo().homedir ?? os.homedir();
51
+ }
52
+ exports.homeDir = homeDir;
53
+ async function loadLines(filename) {
54
+ return await fs.pathExists(filename) ? (await fs.readFile(filename, { encoding: 'utf-8' })).trim().split('\n') : [];
55
+ }
56
+ exports.loadLines = loadLines;
57
+ async function writeLines(filename, lines) {
58
+ // Must end in a newline or our bash script won't read it properly
59
+ await fs.writeFile(filename, lines.join('\n') + '\n', { encoding: 'utf-8' });
60
+ }
61
+ exports.writeLines = writeLines;
62
+ /**
63
+ * Update a spaceless ini file in place
64
+ */
65
+ function updateIniKey(lines, key, value) {
66
+ const prefix = `${key}=`;
67
+ let found = false;
68
+ for (let i = 0; i < lines.length; i++) {
69
+ if (lines[i].startsWith(prefix)) {
70
+ lines[i] = prefix + value;
71
+ found = true;
72
+ break;
73
+ }
74
+ }
75
+ if (!found) {
76
+ lines.push(prefix + value);
77
+ }
78
+ }
79
+ exports.updateIniKey = updateIniKey;
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmaWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLCtCQUErQjtBQUV4QixLQUFLLFVBQVUsTUFBTSxDQUFDLFFBQWdCO0lBQzNDLElBQUksTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ2pDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztLQUMzQjtBQUNILENBQUM7QUFKRCx3QkFJQztBQUVNLEtBQUssVUFBVSxTQUFTLENBQUMsUUFBZ0IsRUFBRSxJQUFZO0lBQzVELElBQUksUUFBUSxHQUFHLE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDdkcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDNUIsUUFBUSxJQUFJLElBQUksQ0FBQztLQUNsQjtJQUNELFFBQVEsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBRXhCLE1BQU0sU0FBUyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUN0QyxDQUFDO0FBUkQsOEJBUUM7QUFFTSxLQUFLLFVBQVUsU0FBUyxDQUFDLFFBQWdCLEVBQUUsUUFBZ0I7SUFDaEUsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUN4QyxNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBQ2hFLENBQUM7QUFIRCw4QkFHQztB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QUM7S0FDNUI7QUFDSCxDQUFDO0FBYkQsb0NBYUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcm1GaWxlKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgaWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMoZmlsZW5hbWUpKSB7XG4gICAgYXdhaXQgZnMudW5saW5rKGZpbGVuYW1lKTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWRkVG9GaWxlKGZpbGVuYW1lOiBzdHJpbmcsIGxpbmU6IHN0cmluZykge1xuICBsZXQgY29udGVudHMgPSBhd2FpdCBmcy5wYXRoRXhpc3RzKGZpbGVuYW1lKSA/IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGVuYW1lLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pIDogJyc7XG4gIGlmICghY29udGVudHMuZW5kc1dpdGgoJ1xcbicpKSB7XG4gICAgY29udGVudHMgKz0gJ1xcbic7XG4gIH1cbiAgY29udGVudHMgKz0gbGluZSArICdcXG4nO1xuXG4gIGF3YWl0IHdyaXRlRmlsZShmaWxlbmFtZSwgY29udGVudHMpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcsIGNvbnRlbnRzOiBzdHJpbmcpIHtcbiAgYXdhaXQgZnMubWtkaXJwKHBhdGguZGlybmFtZShmaWxlbmFtZSkpO1xuICBhd2FpdCBmcy53cml0ZUZpbGUoZmlsZW5hbWUsIGNvbnRlbnRzLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29weURpcmVjdG9yeUNvbnRlbnRzKGRpcjogc3RyaW5nLCB0YXJnZXQ6IHN0cmluZykge1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgYXdhaXQgZnMucmVhZGRpcihwYXRoLmpvaW4oZGlyKSwgeyBlbmNvZGluZzogJ3V0Zi04JyB9KSkge1xuICAgIGF3YWl0IGZzLmNvcHlGaWxlKHBhdGguam9pbihkaXIsIGZpbGUpLCBwYXRoLmpvaW4odGFyZ2V0LCBmaWxlKSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRVcChuYW1lOiBzdHJpbmcsIGRpcmVjdG9yeTogc3RyaW5nID0gcHJvY2Vzcy5jd2QoKSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGFic29sdXRlRGlyZWN0b3J5ID0gcGF0aC5yZXNvbHZlKGRpcmVjdG9yeSk7XG5cbiAgY29uc3QgZmlsZSA9IHBhdGguam9pbihkaXJlY3RvcnksIG5hbWUpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhmaWxlKSkge1xuICAgIHJldHVybiBmaWxlO1xuICB9XG5cbiAgY29uc3QgeyByb290IH0gPSBwYXRoLnBhcnNlKGFic29sdXRlRGlyZWN0b3J5KTtcbiAgaWYgKGFic29sdXRlRGlyZWN0b3J5ID09IHJvb3QpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmV0dXJuIGZpbmRVcChuYW1lLCBwYXRoLmRpcm5hbWUoYWJzb2x1dGVEaXJlY3RvcnkpKTtcbn1cblxuXG4vKipcbiAqIERvY2tlci1zYWZlIGhvbWUgZGlyZWN0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBob21lRGlyKCkge1xuICByZXR1cm4gb3MudXNlckluZm8oKS5ob21lZGlyID8/IG9zLmhvbWVkaXIoKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRMaW5lcyhmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICByZXR1cm4gYXdhaXQgZnMucGF0aEV4aXN0cyhmaWxlbmFtZSkgPyAoYXdhaXQgZnMucmVhZEZpbGUoZmlsZW5hbWUsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSkpLnRyaW0oKS5zcGxpdCgnXFxuJykgOiBbXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlTGluZXMoZmlsZW5hbWU6IHN0cmluZywgbGluZXM6IHN0cmluZ1tdKSB7XG4gIC8vIE11c3QgZW5kIGluIGEgbmV3bGluZSBvciBvdXIgYmFzaCBzY3JpcHQgd29uJ3QgcmVhZCBpdCBwcm9wZXJseVxuICBhd2FpdCBmcy53cml0ZUZpbGUoZmlsZW5hbWUsIGxpbmVzLmpvaW4oJ1xcbicpICsgJ1xcbicsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG59XG5cbi8qKlxuICogVXBkYXRlIGEgc3BhY2VsZXNzIGluaSBmaWxlIGluIHBsYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVJbmlLZXkobGluZXM6IHN0cmluZ1tdLCBrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZykge1xuICBjb25zdCBwcmVmaXggPSBgJHtrZXl9PWA7XG4gIGxldCBmb3VuZCA9IGZhbHNlO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGxpbmVzW2ldLnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgbGluZXNbaV0gPSBwcmVmaXggKyB2YWx1ZTtcbiAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoIWZvdW5kKSB7XG4gICAgbGluZXMucHVzaChwcmVmaXggKyB2YWx1ZSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,4 @@
1
+ export declare function fetchPreviousVersion(token: string, options?: {
2
+ priorTo?: string;
3
+ majorVersion?: string;
4
+ }): Promise<string>;
package/lib/github.js ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchPreviousVersion = void 0;
4
+ const rest_1 = require("@octokit/rest");
5
+ const semver = require("semver");
6
+ async function fetchPreviousVersion(token, options) {
7
+ const github = new rest_1.Octokit({ auth: token });
8
+ const releases = await github.repos.listReleases({
9
+ owner: 'aws',
10
+ repo: 'aws-cdk',
11
+ });
12
+ // this returns a list in descending order, newest releases first
13
+ // opts for same major version where possible, falling back otherwise
14
+ // to previous major versions.
15
+ let previousMVRelease = undefined;
16
+ for (const release of releases.data) {
17
+ const version = release.name?.replace('v', '');
18
+ if (!version) {
19
+ continue;
20
+ }
21
+ // Any old version is fine
22
+ if (!options?.majorVersion && !options?.priorTo) {
23
+ return version;
24
+ }
25
+ if (options?.majorVersion && `${semver.major(version)}` === options.majorVersion) {
26
+ return version;
27
+ }
28
+ if (options?.priorTo && semver.lt(version, options?.priorTo) && semver.major(version) === semver.major(options.priorTo)) {
29
+ return version;
30
+ }
31
+ // Otherwise return the most recent version that didn't match any
32
+ if (!previousMVRelease) {
33
+ previousMVRelease = version;
34
+ }
35
+ }
36
+ if (previousMVRelease) {
37
+ return previousMVRelease;
38
+ }
39
+ throw new Error(`Unable to find previous version given ${JSON.stringify(options)}`);
40
+ }
41
+ exports.fetchPreviousVersion = fetchPreviousVersion;
42
+ ;
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0aHViLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZ2l0aHViLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHdDQUF3QztBQUN4QyxpQ0FBaUM7QUFFMUIsS0FBSyxVQUFVLG9CQUFvQixDQUFDLEtBQWEsRUFBRSxPQUd6RDtJQUNDLE1BQU0sTUFBTSxHQUFHLElBQUksY0FBTyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDNUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQztRQUMvQyxLQUFLLEVBQUUsS0FBSztRQUNaLElBQUksRUFBRSxTQUFTO0tBQ2hCLENBQUMsQ0FBQztJQUVILGlFQUFpRTtJQUNqRSxxRUFBcUU7SUFDckUsOEJBQThCO0lBQzlCLElBQUksaUJBQWlCLEdBQUcsU0FBUyxDQUFDO0lBQ2xDLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxDQUFDLElBQUksRUFBRTtRQUNuQyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUFFLFNBQVM7U0FBRTtRQUUzQiwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxZQUFZLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFO1lBQy9DLE9BQU8sT0FBTyxDQUFDO1NBQ2hCO1FBRUQsSUFBSSxPQUFPLEVBQUUsWUFBWSxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLE9BQU8sQ0FBQyxZQUFZLEVBQUU7WUFDaEYsT0FBTyxPQUFPLENBQUM7U0FDaEI7UUFFRCxJQUFJLE9BQU8sRUFBRSxPQUFPLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDdkgsT0FBTyxPQUFPLENBQUM7U0FDaEI7UUFFRCxpRUFBaUU7UUFDakUsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3RCLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztTQUM3QjtLQUNGO0lBQ0QsSUFBSSxpQkFBaUIsRUFBRTtRQUFFLE9BQU8saUJBQWlCLENBQUM7S0FBRTtJQUVwRCxNQUFNLElBQUksS0FBSyxDQUFDLHlDQUF5QyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN0RixDQUFDO0FBdkNELG9EQXVDQztBQUFBLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPY3Rva2l0IH0gZnJvbSAnQG9jdG9raXQvcmVzdCc7XG5pbXBvcnQgKiBhcyBzZW12ZXIgZnJvbSAnc2VtdmVyJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoUHJldmlvdXNWZXJzaW9uKHRva2VuOiBzdHJpbmcsIG9wdGlvbnM/OiB7XG4gIHByaW9yVG8/OiBzdHJpbmcsXG4gIG1ham9yVmVyc2lvbj86IHN0cmluZyxcbn0pIHtcbiAgY29uc3QgZ2l0aHViID0gbmV3IE9jdG9raXQoeyBhdXRoOiB0b2tlbiB9KTtcbiAgY29uc3QgcmVsZWFzZXMgPSBhd2FpdCBnaXRodWIucmVwb3MubGlzdFJlbGVhc2VzKHtcbiAgICBvd25lcjogJ2F3cycsXG4gICAgcmVwbzogJ2F3cy1jZGsnLFxuICB9KTtcblxuICAvLyB0aGlzIHJldHVybnMgYSBsaXN0IGluIGRlc2NlbmRpbmcgb3JkZXIsIG5ld2VzdCByZWxlYXNlcyBmaXJzdFxuICAvLyBvcHRzIGZvciBzYW1lIG1ham9yIHZlcnNpb24gd2hlcmUgcG9zc2libGUsIGZhbGxpbmcgYmFjayBvdGhlcndpc2VcbiAgLy8gdG8gcHJldmlvdXMgbWFqb3IgdmVyc2lvbnMuXG4gIGxldCBwcmV2aW91c01WUmVsZWFzZSA9IHVuZGVmaW5lZDtcbiAgZm9yIChjb25zdCByZWxlYXNlIG9mIHJlbGVhc2VzLmRhdGEpIHtcbiAgICBjb25zdCB2ZXJzaW9uID0gcmVsZWFzZS5uYW1lPy5yZXBsYWNlKCd2JywgJycpO1xuICAgIGlmICghdmVyc2lvbikgeyBjb250aW51ZTsgfVxuXG4gICAgLy8gQW55IG9sZCB2ZXJzaW9uIGlzIGZpbmVcbiAgICBpZiAoIW9wdGlvbnM/Lm1ham9yVmVyc2lvbiAmJiAhb3B0aW9ucz8ucHJpb3JUbykge1xuICAgICAgcmV0dXJuIHZlcnNpb247XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/Lm1ham9yVmVyc2lvbiAmJiBgJHtzZW12ZXIubWFqb3IodmVyc2lvbil9YCA9PT0gb3B0aW9ucy5tYWpvclZlcnNpb24pIHtcbiAgICAgIHJldHVybiB2ZXJzaW9uO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zPy5wcmlvclRvICYmIHNlbXZlci5sdCh2ZXJzaW9uLCBvcHRpb25zPy5wcmlvclRvKSAmJiBzZW12ZXIubWFqb3IodmVyc2lvbikgPT09IHNlbXZlci5tYWpvcihvcHRpb25zLnByaW9yVG8pKSB7XG4gICAgICByZXR1cm4gdmVyc2lvbjtcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UgcmV0dXJuIHRoZSBtb3N0IHJlY2VudCB2ZXJzaW9uIHRoYXQgZGlkbid0IG1hdGNoIGFueVxuICAgIGlmICghcHJldmlvdXNNVlJlbGVhc2UpIHtcbiAgICAgIHByZXZpb3VzTVZSZWxlYXNlID0gdmVyc2lvbjtcbiAgICB9XG4gIH1cbiAgaWYgKHByZXZpb3VzTVZSZWxlYXNlKSB7IHJldHVybiBwcmV2aW91c01WUmVsZWFzZTsgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgcHJldmlvdXMgdmVyc2lvbiBnaXZlbiAke0pTT04uc3RyaW5naWZ5KG9wdGlvbnMpfWApO1xufTsiXX0=
package/lib/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export * from './aws';
2
+ export * from './corking';
3
+ export * from './integ-test';
4
+ export * from './memoize';
5
+ export * from './resource-pool';
6
+ export * from './with-sam';
7
+ export * from './shell';
8
+ export * from './with-aws';
9
+ export * from './with-cdk-app';
10
+ export * from './with-packages';
11
+ export * from './with-temporary-directory';
12
+ export * from './resources';
package/lib/index.js ADDED
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./aws"), exports);
14
+ __exportStar(require("./corking"), exports);
15
+ __exportStar(require("./integ-test"), exports);
16
+ __exportStar(require("./memoize"), exports);
17
+ __exportStar(require("./resource-pool"), exports);
18
+ __exportStar(require("./with-sam"), exports);
19
+ __exportStar(require("./shell"), exports);
20
+ __exportStar(require("./with-aws"), exports);
21
+ __exportStar(require("./with-cdk-app"), exports);
22
+ __exportStar(require("./with-packages"), exports);
23
+ __exportStar(require("./with-temporary-directory"), exports);
24
+ __exportStar(require("./resources"), exports);
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSx3Q0FBc0I7QUFDdEIsNENBQTBCO0FBQzFCLCtDQUE2QjtBQUM3Qiw0Q0FBMEI7QUFDMUIsa0RBQWdDO0FBQ2hDLDZDQUEyQjtBQUMzQiwwQ0FBd0I7QUFDeEIsNkNBQTJCO0FBQzNCLGlEQUErQjtBQUMvQixrREFBZ0M7QUFDaEMsNkRBQTJDO0FBQzNDLDhDQUE0QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXdzJztcbmV4cG9ydCAqIGZyb20gJy4vY29ya2luZyc7XG5leHBvcnQgKiBmcm9tICcuL2ludGVnLXRlc3QnO1xuZXhwb3J0ICogZnJvbSAnLi9tZW1vaXplJztcbmV4cG9ydCAqIGZyb20gJy4vcmVzb3VyY2UtcG9vbCc7XG5leHBvcnQgKiBmcm9tICcuL3dpdGgtc2FtJztcbmV4cG9ydCAqIGZyb20gJy4vc2hlbGwnO1xuZXhwb3J0ICogZnJvbSAnLi93aXRoLWF3cyc7XG5leHBvcnQgKiBmcm9tICcuL3dpdGgtY2RrLWFwcCc7XG5leHBvcnQgKiBmcm9tICcuL3dpdGgtcGFja2FnZXMnO1xuZXhwb3J0ICogZnJvbSAnLi93aXRoLXRlbXBvcmFyeS1kaXJlY3RvcnknO1xuZXhwb3J0ICogZnJvbSAnLi9yZXNvdXJjZXMnOyJdfQ==
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ export interface TestContext {
3
+ readonly randomString: string;
4
+ readonly output: NodeJS.WritableStream;
5
+ log(s: string): void;
6
+ }
7
+ /**
8
+ * A wrapper for jest's 'test' which takes regression-disabled tests into account and prints a banner
9
+ */
10
+ export declare function integTest(name: string, callback: (context: TestContext) => Promise<void>, timeoutMillis?: number): void;
11
+ export declare function randomString(): string;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.randomString = exports.integTest = void 0;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const corking_1 = require("./corking");
7
+ const SKIP_TESTS = fs.readFileSync(path.join(__dirname, '..', 'skip-tests.txt'), { encoding: 'utf-8' }).split('\n');
8
+ ;
9
+ /**
10
+ * A wrapper for jest's 'test' which takes regression-disabled tests into account and prints a banner
11
+ */
12
+ function integTest(name, callback, timeoutMillis) {
13
+ // Integ tests can run concurrently, and are responsible for blocking
14
+ // themselves if they cannot. Because `test.concurrent` executes the test
15
+ // code immediately, regardles of any `--testNamePattern`, this cannot be the
16
+ // default: test filtering simply does not work with `test.concurrent`.
17
+ // Instead, we make it opt-in only for the pipeline where we don't do any
18
+ // selection, but execute all tests unconditionally.
19
+ const testKind = process.env.JEST_TEST_CONCURRENT === 'true' ? test.concurrent : test;
20
+ const runner = shouldSkip(name) ? testKind.skip : testKind;
21
+ runner(name, async () => {
22
+ const output = new corking_1.MemoryStream();
23
+ output.write('================================================================\n');
24
+ output.write(`${name}\n`);
25
+ output.write('================================================================\n');
26
+ try {
27
+ return await callback({
28
+ output,
29
+ randomString: randomString(),
30
+ log(s) {
31
+ output.write(`${s}\n`);
32
+ },
33
+ });
34
+ }
35
+ catch (e) {
36
+ output.write(e.message);
37
+ output.write(e.stack);
38
+ // Print output only if the test fails. Use 'console.log' so the output is buffered by
39
+ // jest and prints without a stack trace (if verbose: false).
40
+ // eslint-disable-next-line no-console
41
+ console.log(output.buffer().toString());
42
+ throw e;
43
+ }
44
+ }, timeoutMillis);
45
+ }
46
+ exports.integTest = integTest;
47
+ function shouldSkip(testName) {
48
+ return SKIP_TESTS.includes(testName);
49
+ }
50
+ function randomString() {
51
+ // Crazy
52
+ return Math.random().toString(36).replace(/[^a-z0-9]+/g, '');
53
+ }
54
+ exports.randomString = randomString;
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWctdGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImludGVnLXRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix1Q0FBeUM7QUFFekMsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztBQU1uSCxDQUFDO0FBRUY7O0dBRUc7QUFDSCxTQUFnQixTQUFTLENBQ3ZCLElBQVksRUFDWixRQUFpRCxFQUNqRCxhQUFzQjtJQUd0QixxRUFBcUU7SUFDckUsMEVBQTBFO0lBQzFFLDZFQUE2RTtJQUM3RSx1RUFBdUU7SUFDdkUseUVBQXlFO0lBQ3pFLG9EQUFvRDtJQUNwRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3RGLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0lBRTNELE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxzQkFBWSxFQUFFLENBQUM7UUFFbEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvRUFBb0UsQ0FBQyxDQUFDO1FBQ25GLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQzFCLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0VBQW9FLENBQUMsQ0FBQztRQUVuRixJQUFJO1lBQ0YsT0FBTyxNQUFNLFFBQVEsQ0FBQztnQkFDcEIsTUFBTTtnQkFDTixZQUFZLEVBQUUsWUFBWSxFQUFFO2dCQUM1QixHQUFHLENBQUMsQ0FBUztvQkFDWCxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDekIsQ0FBQzthQUNGLENBQUMsQ0FBQztTQUNKO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDVixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0QixzRkFBc0Y7WUFDdEYsNkRBQTZEO1lBQzdELHNDQUFzQztZQUN0QyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxDQUFDO1NBQ1Q7SUFDSCxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDcEIsQ0FBQztBQXhDRCw4QkF3Q0M7QUFFRCxTQUFTLFVBQVUsQ0FBQyxRQUFnQjtJQUNsQyxPQUFPLFVBQVUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDdkMsQ0FBQztBQUVELFNBQWdCLFlBQVk7SUFDMUIsUUFBUTtJQUNSLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFIRCxvQ0FHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBNZW1vcnlTdHJlYW0gfSBmcm9tICcuL2NvcmtpbmcnO1xuXG5jb25zdCBTS0lQX1RFU1RTID0gZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihfX2Rpcm5hbWUsICcuLicsICdza2lwLXRlc3RzLnR4dCcpLCB7IGVuY29kaW5nOiAndXRmLTgnIH0pLnNwbGl0KCdcXG4nKTtcblxuZXhwb3J0IGludGVyZmFjZSBUZXN0Q29udGV4dCB7XG4gIHJlYWRvbmx5IHJhbmRvbVN0cmluZzogc3RyaW5nO1xuICByZWFkb25seSBvdXRwdXQ6IE5vZGVKUy5Xcml0YWJsZVN0cmVhbTtcbiAgbG9nKHM6IHN0cmluZyk6IHZvaWQ7XG59O1xuXG4vKipcbiAqIEEgd3JhcHBlciBmb3IgamVzdCdzICd0ZXN0JyB3aGljaCB0YWtlcyByZWdyZXNzaW9uLWRpc2FibGVkIHRlc3RzIGludG8gYWNjb3VudCBhbmQgcHJpbnRzIGEgYmFubmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRlZ1Rlc3QoXG4gIG5hbWU6IHN0cmluZyxcbiAgY2FsbGJhY2s6IChjb250ZXh0OiBUZXN0Q29udGV4dCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgdGltZW91dE1pbGxpcz86IG51bWJlcixcbikge1xuXG4gIC8vIEludGVnIHRlc3RzIGNhbiBydW4gY29uY3VycmVudGx5LCBhbmQgYXJlIHJlc3BvbnNpYmxlIGZvciBibG9ja2luZ1xuICAvLyB0aGVtc2VsdmVzIGlmIHRoZXkgY2Fubm90LiAgQmVjYXVzZSBgdGVzdC5jb25jdXJyZW50YCBleGVjdXRlcyB0aGUgdGVzdFxuICAvLyBjb2RlIGltbWVkaWF0ZWx5LCByZWdhcmRsZXMgb2YgYW55IGAtLXRlc3ROYW1lUGF0dGVybmAsIHRoaXMgY2Fubm90IGJlIHRoZVxuICAvLyBkZWZhdWx0OiB0ZXN0IGZpbHRlcmluZyBzaW1wbHkgZG9lcyBub3Qgd29yayB3aXRoIGB0ZXN0LmNvbmN1cnJlbnRgLlxuICAvLyBJbnN0ZWFkLCB3ZSBtYWtlIGl0IG9wdC1pbiBvbmx5IGZvciB0aGUgcGlwZWxpbmUgd2hlcmUgd2UgZG9uJ3QgZG8gYW55XG4gIC8vIHNlbGVjdGlvbiwgYnV0IGV4ZWN1dGUgYWxsIHRlc3RzIHVuY29uZGl0aW9uYWxseS5cbiAgY29uc3QgdGVzdEtpbmQgPSBwcm9jZXNzLmVudi5KRVNUX1RFU1RfQ09OQ1VSUkVOVCA9PT0gJ3RydWUnID8gdGVzdC5jb25jdXJyZW50IDogdGVzdDtcbiAgY29uc3QgcnVubmVyID0gc2hvdWxkU2tpcChuYW1lKSA/IHRlc3RLaW5kLnNraXAgOiB0ZXN0S2luZDtcblxuICBydW5uZXIobmFtZSwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG91dHB1dCA9IG5ldyBNZW1vcnlTdHJlYW0oKTtcblxuICAgIG91dHB1dC53cml0ZSgnPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbicpO1xuICAgIG91dHB1dC53cml0ZShgJHtuYW1lfVxcbmApO1xuICAgIG91dHB1dC53cml0ZSgnPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxcbicpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBjYWxsYmFjayh7XG4gICAgICAgIG91dHB1dCxcbiAgICAgICAgcmFuZG9tU3RyaW5nOiByYW5kb21TdHJpbmcoKSxcbiAgICAgICAgbG9nKHM6IHN0cmluZykge1xuICAgICAgICAgIG91dHB1dC53cml0ZShgJHtzfVxcbmApO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgb3V0cHV0LndyaXRlKGUubWVzc2FnZSk7XG4gICAgICBvdXRwdXQud3JpdGUoZS5zdGFjayk7XG4gICAgICAvLyBQcmludCBvdXRwdXQgb25seSBpZiB0aGUgdGVzdCBmYWlscy4gVXNlICdjb25zb2xlLmxvZycgc28gdGhlIG91dHB1dCBpcyBidWZmZXJlZCBieVxuICAgICAgLy8gamVzdCBhbmQgcHJpbnRzIHdpdGhvdXQgYSBzdGFjayB0cmFjZSAoaWYgdmVyYm9zZTogZmFsc2UpLlxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUubG9nKG91dHB1dC5idWZmZXIoKS50b1N0cmluZygpKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9LCB0aW1lb3V0TWlsbGlzKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkU2tpcCh0ZXN0TmFtZTogc3RyaW5nKSB7XG4gIHJldHVybiBTS0lQX1RFU1RTLmluY2x1ZGVzKHRlc3ROYW1lKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZygpIHtcbiAgLy8gQ3JhenlcbiAgcmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnJlcGxhY2UoL1teYS16MC05XSsvZywgJycpO1xufSJdfQ==
package/lib/lists.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare function chunk<A>(n: number, xs: A[]): A[][];
package/lib/lists.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chunk = void 0;
4
+ function chunk(n, xs) {
5
+ const ret = new Array();
6
+ for (let i = 0; i < xs.length; i += n) {
7
+ ret.push(xs.slice(i, i + n));
8
+ }
9
+ return ret;
10
+ }
11
+ exports.chunk = chunk;
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJsaXN0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxTQUFnQixLQUFLLENBQUksQ0FBUyxFQUFFLEVBQU87SUFDekMsTUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLEVBQU8sQ0FBQztJQUU3QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ3JDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDOUI7SUFFRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFSRCxzQkFRQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBjaHVuazxBPihuOiBudW1iZXIsIHhzOiBBW10pOiBBW11bXSB7XG4gIGNvbnN0IHJldCA9IG5ldyBBcnJheTxBW10+KCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkgKz0gbikge1xuICAgIHJldC5wdXNoKHhzLnNsaWNlKGksIGkgKyBuKSk7XG4gIH1cblxuICByZXR1cm4gcmV0O1xufSJdfQ==
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Return a memoized version of an function with 0 arguments.
3
+ *
4
+ * Async-safe.
5
+ */
6
+ export declare function memoize0<A>(fn: () => Promise<A>): () => Promise<A>;