projen 0.103.26 → 0.104.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 (176) hide show
  1. package/.jsii +1087 -91
  2. package/lib/ai-instructions.js +2 -2
  3. package/lib/awscdk/auto-discover.js +6 -6
  4. package/lib/awscdk/awscdk-app-java.js +1 -1
  5. package/lib/awscdk/awscdk-app-py.js +1 -1
  6. package/lib/awscdk/awscdk-app-ts.js +1 -1
  7. package/lib/awscdk/awscdk-construct.js +1 -1
  8. package/lib/awscdk/awscdk-deps-java.js +1 -1
  9. package/lib/awscdk/awscdk-deps-js.js +1 -1
  10. package/lib/awscdk/awscdk-deps-py.js +1 -1
  11. package/lib/awscdk/awscdk-deps.js +1 -1
  12. package/lib/awscdk/cdk-config.js +3 -3
  13. package/lib/awscdk/cdk-tasks.js +1 -1
  14. package/lib/awscdk/integration-test.js +1 -1
  15. package/lib/awscdk/lambda-extension.js +1 -1
  16. package/lib/awscdk/lambda-function.js +2 -2
  17. package/lib/awscdk/private/feature-flags-v2.const.d.ts +1 -1
  18. package/lib/awscdk/private/feature-flags-v2.const.js +2 -2
  19. package/lib/build/build-workflow.js +1 -1
  20. package/lib/cdk/auto-discover-base.js +2 -2
  21. package/lib/cdk/construct-lib.js +1 -1
  22. package/lib/cdk/integration-test-base.js +1 -1
  23. package/lib/cdk/jsii-build.js +1 -1
  24. package/lib/cdk/jsii-docgen.js +1 -1
  25. package/lib/cdk/jsii-project.js +1 -1
  26. package/lib/cdk8s/auto-discover.js +2 -2
  27. package/lib/cdk8s/cdk8s-app-py.js +1 -1
  28. package/lib/cdk8s/cdk8s-app-ts.js +1 -1
  29. package/lib/cdk8s/cdk8s-construct.js +1 -1
  30. package/lib/cdk8s/cdk8s-deps-py.js +1 -1
  31. package/lib/cdk8s/cdk8s-deps.js +1 -1
  32. package/lib/cdk8s/integration-test.js +1 -1
  33. package/lib/cdktf/cdktf-construct.js +1 -1
  34. package/lib/cdktn/cdktn-app-ts.js +1 -1
  35. package/lib/cdktn/cdktn-config.js +1 -1
  36. package/lib/cdktn/cdktn-construct.js +1 -1
  37. package/lib/cdktn/cdktn-deps.js +1 -1
  38. package/lib/cdktn/cdktn-tasks.js +1 -1
  39. package/lib/circleci/circleci.js +1 -1
  40. package/lib/circleci/model.d.ts +5 -2
  41. package/lib/circleci/model.js +1 -1
  42. package/lib/component.js +2 -2
  43. package/lib/dependencies.js +1 -1
  44. package/lib/dev-env.js +1 -1
  45. package/lib/docker-compose/docker-compose-service.js +1 -1
  46. package/lib/docker-compose/docker-compose.js +1 -1
  47. package/lib/file.js +1 -1
  48. package/lib/gitattributes.js +1 -1
  49. package/lib/github/actions-provider.js +1 -1
  50. package/lib/github/actions.const.js +1 -1
  51. package/lib/github/auto-approve.d.ts +41 -1
  52. package/lib/github/auto-approve.js +66 -17
  53. package/lib/github/auto-merge.js +1 -1
  54. package/lib/github/auto-queue.js +1 -1
  55. package/lib/github/dependabot.js +1 -1
  56. package/lib/github/dependency-review.js +1 -1
  57. package/lib/github/github-credentials.js +1 -1
  58. package/lib/github/github-project.js +1 -1
  59. package/lib/github/github.js +1 -1
  60. package/lib/github/index.d.ts +1 -0
  61. package/lib/github/index.js +2 -1
  62. package/lib/github/merge-queue.js +1 -1
  63. package/lib/github/mergify.js +1 -1
  64. package/lib/github/pr-template.js +1 -1
  65. package/lib/github/pull-request-backport.js +1 -1
  66. package/lib/github/pull-request-lint.js +3 -3
  67. package/lib/github/pull-request-source.d.ts +71 -0
  68. package/lib/github/pull-request-source.js +84 -0
  69. package/lib/github/stale.js +1 -1
  70. package/lib/github/task-workflow-job.js +1 -1
  71. package/lib/github/task-workflow.js +1 -1
  72. package/lib/github/workflow-actions.js +1 -1
  73. package/lib/github/workflow-jobs.js +1 -1
  74. package/lib/github/workflow-steps.js +1 -1
  75. package/lib/github/workflows.js +1 -1
  76. package/lib/gitlab/configuration.js +2 -5
  77. package/lib/gitlab/gitlab-configuration.js +1 -1
  78. package/lib/gitlab/nested-configuration.js +1 -1
  79. package/lib/gitpod.js +1 -1
  80. package/lib/ignore-file.js +1 -1
  81. package/lib/ini.js +1 -1
  82. package/lib/java/java-project.js +1 -1
  83. package/lib/java/junit.js +1 -1
  84. package/lib/java/maven-compile.js +1 -1
  85. package/lib/java/maven-packaging.js +1 -1
  86. package/lib/java/maven-sample.js +1 -1
  87. package/lib/java/pom.js +2 -2
  88. package/lib/java/projenrc.js +1 -1
  89. package/lib/javascript/biome/biome.js +1 -1
  90. package/lib/javascript/bundler.js +1 -1
  91. package/lib/javascript/eslint.js +1 -1
  92. package/lib/javascript/index.d.ts +1 -0
  93. package/lib/javascript/index.js +2 -1
  94. package/lib/javascript/jest.js +4 -4
  95. package/lib/javascript/license-checker.js +1 -1
  96. package/lib/javascript/node-config-file.js +18 -4
  97. package/lib/javascript/node-native-test-runner.d.ts +234 -0
  98. package/lib/javascript/node-native-test-runner.js +368 -0
  99. package/lib/javascript/node-package.js +1 -1
  100. package/lib/javascript/node-project.js +3 -3
  101. package/lib/javascript/npm-config.js +1 -1
  102. package/lib/javascript/pnpm-workspace-config.js +2 -2
  103. package/lib/javascript/pnpm-workspace.js +1 -1
  104. package/lib/javascript/prettier.js +1 -1
  105. package/lib/javascript/projenrc.js +1 -1
  106. package/lib/javascript/typescript-config.js +2 -2
  107. package/lib/javascript/upgrade-dependencies.js +2 -2
  108. package/lib/javascript/yarnrc.js +1 -1
  109. package/lib/json-patch.js +1 -1
  110. package/lib/json.js +1 -1
  111. package/lib/license.js +1 -1
  112. package/lib/logger.js +1 -1
  113. package/lib/makefile.js +1 -1
  114. package/lib/object-file.js +1 -1
  115. package/lib/polaris/coverity-go.js +1 -1
  116. package/lib/polaris/coverity-java.js +1 -1
  117. package/lib/polaris/coverity-javascript.js +1 -1
  118. package/lib/polaris/coverity.js +1 -1
  119. package/lib/project-build.js +1 -1
  120. package/lib/project-tree.js +1 -1
  121. package/lib/project.js +1 -1
  122. package/lib/projects.js +1 -1
  123. package/lib/projenrc-json.js +1 -1
  124. package/lib/projenrc.js +1 -1
  125. package/lib/properties-file.js +1 -1
  126. package/lib/python/pip.js +1 -1
  127. package/lib/python/poetry.js +2 -2
  128. package/lib/python/projenrc.js +1 -1
  129. package/lib/python/pyproject-toml-file.js +1 -1
  130. package/lib/python/pytest-sample.js +1 -1
  131. package/lib/python/pytest.js +1 -1
  132. package/lib/python/python-project.js +1 -1
  133. package/lib/python/python-sample.js +1 -1
  134. package/lib/python/requirements-file.js +1 -1
  135. package/lib/python/setuppy.js +1 -1
  136. package/lib/python/setuptools.js +1 -1
  137. package/lib/python/uv-config.js +1 -1
  138. package/lib/python/uv.js +1 -1
  139. package/lib/python/venv.js +1 -1
  140. package/lib/readme.js +1 -1
  141. package/lib/release/publisher.js +1 -1
  142. package/lib/release/release-trigger.js +1 -1
  143. package/lib/release/release.js +3 -2
  144. package/lib/renovatebot.js +1 -1
  145. package/lib/run-task.cjs +6 -6
  146. package/lib/sample-file.js +2 -2
  147. package/lib/script-runner.js +1 -1
  148. package/lib/sonarqube/javascript.js +1 -1
  149. package/lib/sonarqube/rust.js +1 -1
  150. package/lib/sonarqube/sonarqube.js +1 -1
  151. package/lib/sonarqube/typescript.js +1 -1
  152. package/lib/source-code.js +1 -1
  153. package/lib/task-shell.js +1 -1
  154. package/lib/task.js +1 -1
  155. package/lib/tasks.js +1 -1
  156. package/lib/testing.js +1 -1
  157. package/lib/textfile.js +1 -1
  158. package/lib/toml.js +1 -1
  159. package/lib/typescript/projenrc-ts.js +1 -1
  160. package/lib/typescript/projenrc.js +1 -1
  161. package/lib/typescript/typescript-runner.js +1 -1
  162. package/lib/typescript/typescript-typedoc.js +1 -1
  163. package/lib/typescript/typescript.js +5 -5
  164. package/lib/version.js +2 -2
  165. package/lib/vscode/devcontainer.js +1 -1
  166. package/lib/vscode/extensions.js +1 -1
  167. package/lib/vscode/launch-config.js +1 -1
  168. package/lib/vscode/settings.js +1 -1
  169. package/lib/vscode/vscode.js +1 -1
  170. package/lib/web/next.js +3 -3
  171. package/lib/web/postcss.js +1 -1
  172. package/lib/web/react.js +3 -3
  173. package/lib/web/tailwind.js +1 -1
  174. package/lib/xmlfile.js +1 -1
  175. package/lib/yaml.js +1 -1
  176. package/package.json +6 -6
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NodeNativeTestRunner = exports.Destination = exports.NodeTestUpdateSnapshot = void 0;
4
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
+ const path_1 = require("path");
6
+ const component_1 = require("../component");
7
+ const node_config_file_1 = require("./node-config-file");
8
+ const node_project_1 = require("./node-project");
9
+ const util_1 = require("../util");
10
+ const constructs_1 = require("../util/constructs");
11
+ const DEFAULT_COVERAGE_DIR = "coverage";
12
+ const DEFAULT_TEST_REPORTS_DIR = "test-reports";
13
+ const DEFAULT_NODE_TEST_MATCH_EXTENSIONS = "cjs,mjs,js,jsx,cts,mts,ts,tsx";
14
+ /**
15
+ * Default glob patterns used to discover test files for Node's built-in test
16
+ * runner, combining Node.js' own default test file discovery with common
17
+ * Jest conventions, so that projects moving from Jest keep matching their
18
+ * existing test files.
19
+ *
20
+ * Node's test runner glob matching follows `glob(7)` and does not support
21
+ * extglobs (e.g. `@(...)`, `+(...)`, `?(...)`), so, unlike Jest's own
22
+ * defaults, each alternative is spelled out explicitly instead of relying on
23
+ * extended glob groups.
24
+ *
25
+ * @see https://nodejs.org/api/test.html#running-tests-from-the-command-line
26
+ */
27
+ const DEFAULT_NODE_TEST_MATCH = [
28
+ // Node.js' own defaults: files inside a "test" directory, or named/prefixed/suffixed "test"
29
+ `**/test/**/*.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
30
+ `**/test.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
31
+ `**/test-*.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
32
+ `**/*.test.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
33
+ `**/*-test.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
34
+ `**/*_test.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
35
+ // Jest conventions: files inside a "__tests__" directory, or named/suffixed "spec"
36
+ `**/__tests__/**/*.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
37
+ `**/spec.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
38
+ `**/*.spec.{${DEFAULT_NODE_TEST_MATCH_EXTENSIONS}}`,
39
+ ];
40
+ /**
41
+ * Whether to update snapshots in task "test" (which is executed in task
42
+ * "build" and build workflows), or create a separate task "test:update" for
43
+ * updating snapshots.
44
+ */
45
+ var NodeTestUpdateSnapshot;
46
+ (function (NodeTestUpdateSnapshot) {
47
+ /**
48
+ * Always update snapshots in "test" task.
49
+ */
50
+ NodeTestUpdateSnapshot["ALWAYS"] = "always";
51
+ /**
52
+ * Never update snapshots in "test" task and create a separate "test:update" task.
53
+ */
54
+ NodeTestUpdateSnapshot["NEVER"] = "never";
55
+ })(NodeTestUpdateSnapshot || (exports.NodeTestUpdateSnapshot = NodeTestUpdateSnapshot = {}));
56
+ /**
57
+ * Glob patterns matching the files that contain tests.
58
+ */
59
+ class TestMatch {
60
+ _patterns = new Set();
61
+ _defaultValue;
62
+ constructor(defaultValue) {
63
+ this._defaultValue = defaultValue;
64
+ }
65
+ add(pattern) {
66
+ this._patterns.add(pattern);
67
+ }
68
+ remove(pattern) {
69
+ this._patterns.delete(pattern);
70
+ }
71
+ /**
72
+ * Resolved lazily so patterns added or removed after construction are
73
+ * still reflected.
74
+ */
75
+ deferred() {
76
+ return this._patterns.size > 0
77
+ ? Array.from(this._patterns)
78
+ : this._defaultValue;
79
+ }
80
+ }
81
+ /**
82
+ * Where a reporter's output is written.
83
+ *
84
+ * @see https://nodejs.org/api/test.html#test-reporters
85
+ */
86
+ class Destination {
87
+ value;
88
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.javascript.Destination", version: "0.104.0" };
89
+ /**
90
+ * Write to standard output.
91
+ */
92
+ static STDOUT = new Destination("stdout");
93
+ /**
94
+ * Write to standard error.
95
+ */
96
+ static STDERR = new Destination("stderr");
97
+ /**
98
+ * Write to a file at the given path.
99
+ * @param path path of the file to write to
100
+ */
101
+ static file(path) {
102
+ return new Destination(path);
103
+ }
104
+ constructor(
105
+ /**
106
+ * The underlying value: `"stdout"`, `"stderr"`, or a file path.
107
+ */
108
+ value) {
109
+ this.value = value;
110
+ }
111
+ }
112
+ exports.Destination = Destination;
113
+ /**
114
+ * The set of reporters configured for a `NodeNativeTestRunner`.
115
+ *
116
+ * Provides the `test.testReporter` and `test.testReporterDestination` values
117
+ * of the generated Node.js configuration file.
118
+ */
119
+ class NodeReporters {
120
+ project;
121
+ _reporters = new Map();
122
+ constructor(project) {
123
+ this.project = project;
124
+ }
125
+ /**
126
+ * Adds a reporter, or updates its destination if one with the same name
127
+ * is already configured.
128
+ * @param name The name/kind of the reporter, e.g. `spec`, `junit`, `lcov`.
129
+ * @param destination Where the reporter's output is written.
130
+ * @default Destination.STDOUT
131
+ */
132
+ add(name, destination = Destination.STDOUT) {
133
+ this._reporters.set(name, destination);
134
+ if (destination !== Destination.STDOUT &&
135
+ destination !== Destination.STDERR) {
136
+ this.ensureDestinationDirectory(destination);
137
+ }
138
+ }
139
+ /**
140
+ * Removes a reporter, if configured.
141
+ * @param name The name/kind of the reporter to remove.
142
+ */
143
+ remove(name) {
144
+ this._reporters.delete(name);
145
+ }
146
+ /**
147
+ * Lists the configured reporters, in the order they were added.
148
+ */
149
+ list() {
150
+ return Array.from(this._reporters, ([name, destination]) => ({
151
+ name,
152
+ destination,
153
+ }));
154
+ }
155
+ /**
156
+ * Ensures the directory of a reporter's file destination exists before the
157
+ * test runner is invoked, and excludes it from the project's `.gitignore`
158
+ * and package (e.g. `.npmignore`) files.
159
+ */
160
+ ensureDestinationDirectory(destination) {
161
+ const dir = path_1.posix.dirname(destination.value);
162
+ if (dir === ".") {
163
+ return;
164
+ }
165
+ // the reporter does not create its output directory, so it must exist
166
+ // before the test runner is invoked.
167
+ this.project.testTask.prependExec(`mkdir -p ${dir}`);
168
+ const dirPattern = path_1.posix.join("/", dir, "/");
169
+ this.project.addGitIgnore(dirPattern);
170
+ this.project.addPackageIgnore(dirPattern);
171
+ }
172
+ }
173
+ /**
174
+ * Configures Node's built-in test runner (`node --test`).
175
+ *
176
+ * Owns the generated Node.js configuration file, the "test", "test:update"
177
+ * and "test:watch" tasks, and the reporters and test match patterns they use.
178
+ */
179
+ class NodeNativeTestRunner extends component_1.Component {
180
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.javascript.NodeNativeTestRunner", version: "0.104.0" };
181
+ /**
182
+ * Returns the singleton NodeNativeTestRunner component of a project or undefined
183
+ * if there is none.
184
+ */
185
+ static of(project) {
186
+ const isNodeNativeTestRunner = (c) => c instanceof NodeNativeTestRunner;
187
+ return project.components.find(isNodeNativeTestRunner);
188
+ }
189
+ project;
190
+ coverageDirectory;
191
+ updateSnapshot;
192
+ reporters;
193
+ /**
194
+ * The generated Node.js configuration file.
195
+ */
196
+ configFile;
197
+ testReportsDir = DEFAULT_TEST_REPORTS_DIR;
198
+ testMatch;
199
+ constructor(scope, options = {}) {
200
+ super(scope);
201
+ this.project = (0, constructs_1.closestProjectMustBe)(scope, node_project_1.NodeProject, new.target.name);
202
+ // Node's snapshot files are generated, not authored.
203
+ this.project.root.annotateGenerated("*.snap");
204
+ this.project.root.annotateGenerated("*.snapshot");
205
+ this.updateSnapshot =
206
+ options.updateSnapshot ?? NodeTestUpdateSnapshot.ALWAYS;
207
+ this.reporters = new NodeReporters(this.project);
208
+ const preserveDefaultReporters = options.preserveDefaultReporters ?? true;
209
+ this.testMatch = new TestMatch(DEFAULT_NODE_TEST_MATCH);
210
+ if (options.testMatch && options.testMatch.length > 0) {
211
+ options.testMatch.forEach((pattern) => this.testMatch.add(pattern));
212
+ }
213
+ const collectCoverage = options.collectCoverage ?? true;
214
+ const coverageDirectory = options.coverageDirectory ?? DEFAULT_COVERAGE_DIR;
215
+ this.coverageDirectory = collectCoverage ? coverageDirectory : undefined;
216
+ if (this.coverageDirectory) {
217
+ const coverageDirectoryPath = path_1.posix.join("/", this.coverageDirectory, "/");
218
+ this.project.addGitIgnore(coverageDirectoryPath);
219
+ this.project.addPackageIgnore(coverageDirectoryPath);
220
+ }
221
+ if (preserveDefaultReporters && collectCoverage) {
222
+ this.reporters.add("spec", Destination.STDOUT);
223
+ this.reporters.add("lcov", Destination.file(`${coverageDirectory}/lcov.info`));
224
+ this.reporters.add("junit", Destination.file(`${this.testReportsDir}/junit.xml`));
225
+ }
226
+ for (const { name, destination } of options.reporters ?? []) {
227
+ this.reporters.add(name, destination);
228
+ }
229
+ const defaultTest = {
230
+ test: true,
231
+ testGlobalSetup: options.globalSetup,
232
+ ...(collectCoverage
233
+ ? {
234
+ experimentalTestCoverage: true,
235
+ testCoverageExclude: options.coveragePathIgnorePatterns ?? [
236
+ "**/test/**",
237
+ "**/__tests__/**",
238
+ ],
239
+ }
240
+ : {}),
241
+ experimentalTestModuleMocks: options.moduleMocks,
242
+ // lazily resolved at synthesis time, so that reporters added or
243
+ // removed via `reporters` after construction are reflected in the
244
+ // generated file.
245
+ testReporter: (() => this.reporters.list().map((r) => r.name)),
246
+ testReporterDestination: (() => this.reporters.list().map((r) => r.destination.value)),
247
+ };
248
+ const test = (0, util_1.deepMerge)([defaultTest, options.testConfig ?? {}], { destructive: true });
249
+ let nodeOptions = { ...options.nodeOptions };
250
+ const extraCliOptions = options.extraCliOptions ?? [];
251
+ if (options.transformTypes ?? false) {
252
+ this.project.addDevDeps("amaro");
253
+ const imports = nodeOptions.import ?? [];
254
+ if (!imports.includes("amaro/transform")) {
255
+ imports.unshift("amaro/transform");
256
+ }
257
+ nodeOptions = {
258
+ ...nodeOptions,
259
+ enableSourceMaps: true,
260
+ import: imports,
261
+ };
262
+ }
263
+ this.configFile = new node_config_file_1.NodeConfigFile(this.project, {
264
+ filePath: options.configFilePath,
265
+ test,
266
+ nodeOptions,
267
+ });
268
+ this.project.npmignore?.addPatterns(`/${this.configFile.file.path}`);
269
+ // Test match patterns are positional arguments and must come after every
270
+ // flag: once Node sees the first positional argument it stops parsing
271
+ // flags, so any flag appended after them (e.g. `--watch`) is ignored.
272
+ const command = [
273
+ "node",
274
+ `--experimental-config-file=${this.configFile.file.path}`,
275
+ ...extraCliOptions,
276
+ ];
277
+ // `testMatch` is a live collection (`add`/`remove` can still be called
278
+ // after construction), so its resolution is deferred with `lazyExecArgs`
279
+ // rather than read eagerly here.
280
+ const testMatchArgs = () => this.testMatch.deferred();
281
+ if (this.updateSnapshot === NodeTestUpdateSnapshot.ALWAYS) {
282
+ this.project.testTask.execArgs(lazyExecArgs(() => [
283
+ ...command,
284
+ "--test-update-snapshots",
285
+ ...testMatchArgs(),
286
+ ]), { receiveArgs: true });
287
+ }
288
+ else {
289
+ const testUpdate = this.project.tasks.tryFind("test:update");
290
+ if (!testUpdate) {
291
+ this.project.addTask("test:update", {
292
+ description: "Update test snapshots",
293
+ execArgs: lazyExecArgs(() => [
294
+ ...command,
295
+ "--test-update-snapshots",
296
+ ...testMatchArgs(),
297
+ ]),
298
+ receiveArgs: true,
299
+ });
300
+ }
301
+ this.project.testTask.execArgs(lazyExecArgs(() => [...command, ...testMatchArgs()]), { receiveArgs: true });
302
+ }
303
+ const testWatch = this.project.tasks.tryFind("test:watch");
304
+ if (!testWatch) {
305
+ this.project.addTask("test:watch", {
306
+ description: "Run tests in watch mode",
307
+ execArgs: lazyExecArgs(() => [
308
+ ...command,
309
+ "--watch",
310
+ ...testMatchArgs(),
311
+ ]),
312
+ });
313
+ }
314
+ }
315
+ /**
316
+ * Adds a test match pattern.
317
+ * @param pattern glob pattern to match for tests
318
+ */
319
+ addTestMatch(pattern) {
320
+ this.testMatch.add(pattern);
321
+ }
322
+ /**
323
+ * Removes a test match pattern, if configured.
324
+ * @param pattern glob pattern to remove
325
+ */
326
+ removeTestMatch(pattern) {
327
+ this.testMatch.remove(pattern);
328
+ }
329
+ /**
330
+ * Adds a reporter, or updates its destination if one with the same name
331
+ * is already configured.
332
+ * @param name The name/kind of the reporter, e.g. `spec`, `junit`, `lcov`.
333
+ * @param destination Where the reporter's output is written.
334
+ * @default Destination.STDOUT
335
+ */
336
+ addReporter(name, destination) {
337
+ this.reporters.add(name, destination);
338
+ }
339
+ /**
340
+ * Removes a reporter, if configured.
341
+ * @param name The name/kind of the reporter to remove.
342
+ */
343
+ removeReporter(name) {
344
+ this.reporters.remove(name);
345
+ }
346
+ /**
347
+ * Lists the configured reporters, in the order they were added.
348
+ */
349
+ listReporters() {
350
+ return this.reporters.list();
351
+ }
352
+ }
353
+ exports.NodeNativeTestRunner = NodeNativeTestRunner;
354
+ /**
355
+ * Defers resolution of a `TaskStep`'s `execArgs` to synthesis time, when the
356
+ * tasks manifest is rendered.
357
+ *
358
+ * `TaskStep.execArgs` is typed as a plain `string[]`, but the manifest is
359
+ * written through the generic `resolve()` walker (see
360
+ * `ProjenTaskRunner.tasksManifest`) - the same mechanism `JsonFile`/`ObjectFile`
361
+ * use for lazy values elsewhere (e.g. `NodeReporters.list`, `TestMatch`).
362
+ * That walker calls any function it finds, so a callback deferred here runs
363
+ * once, at that point, in place of a plain array.
364
+ */
365
+ function lazyExecArgs(fn) {
366
+ return fn;
367
+ }
368
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1uYXRpdmUtdGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvamF2YXNjcmlwdC9ub2RlLW5hdGl2ZS10ZXN0LXJ1bm5lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsK0JBQTZCO0FBRTdCLDRDQUF5QztBQU16Qyx5REFBb0Q7QUFDcEQsaURBQTZDO0FBQzdDLGtDQUFvQztBQUNwQyxtREFBMEQ7QUFFMUQsTUFBTSxvQkFBb0IsR0FBRyxVQUFVLENBQUM7QUFFeEMsTUFBTSx3QkFBd0IsR0FBRyxjQUFjLENBQUM7QUFFaEQsTUFBTSxrQ0FBa0MsR0FBRywrQkFBK0IsQ0FBQztBQUUzRTs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLHVCQUF1QixHQUFhO0lBQ3hDLDRGQUE0RjtJQUM1RixpQkFBaUIsa0NBQWtDLEdBQUc7SUFDdEQsWUFBWSxrQ0FBa0MsR0FBRztJQUNqRCxjQUFjLGtDQUFrQyxHQUFHO0lBQ25ELGNBQWMsa0NBQWtDLEdBQUc7SUFDbkQsY0FBYyxrQ0FBa0MsR0FBRztJQUNuRCxjQUFjLGtDQUFrQyxHQUFHO0lBQ25ELG1GQUFtRjtJQUNuRixzQkFBc0Isa0NBQWtDLEdBQUc7SUFDM0QsWUFBWSxrQ0FBa0MsR0FBRztJQUNqRCxjQUFjLGtDQUFrQyxHQUFHO0NBQ3BELENBQUM7QUFFRjs7OztHQUlHO0FBQ0gsSUFBWSxzQkFVWDtBQVZELFdBQVksc0JBQXNCO0lBQ2hDOztPQUVHO0lBQ0gsMkNBQWlCLENBQUE7SUFFakI7O09BRUc7SUFDSCx5Q0FBZSxDQUFBO0FBQ2pCLENBQUMsRUFWVyxzQkFBc0Isc0NBQXRCLHNCQUFzQixRQVVqQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxTQUFTO0lBQ0ksU0FBUyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDOUIsYUFBYSxDQUFXO0lBRXpDLFlBQVksWUFBc0I7UUFDaEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxZQUFZLENBQUM7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IHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IFByb2plY3QgfSBmcm9tIFwiLi4vcHJvamVjdFwiO1xuaW1wb3J0IHR5cGUge1xuICBOb2RlQ29uZmlnU2NoZW1hTm9kZU9wdGlvbnMsXG4gIE5vZGVDb25maWdTY2hlbWFUZXN0LFxufSBmcm9tIFwiLi9ub2RlLWNvbmZpZ1wiO1xuaW1wb3J0IHsgTm9kZUNvbmZpZ0ZpbGUgfSBmcm9tIFwiLi9ub2RlLWNvbmZpZy1maWxlXCI7XG5pbXBvcnQgeyBOb2RlUHJvamVjdCB9IGZyb20gXCIuL25vZGUtcHJvamVjdFwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlIH0gZnJvbSBcIi4uL3V0aWxcIjtcbmltcG9ydCB7IGNsb3Nlc3RQcm9qZWN0TXVzdEJlIH0gZnJvbSBcIi4uL3V0aWwvY29uc3RydWN0c1wiO1xuXG5jb25zdCBERUZBVUxUX0NPVkVSQUdFX0RJUiA9IFwiY292ZXJhZ2VcIjtcblxuY29uc3QgREVGQVVMVF9URVNUX1JFUE9SVFNfRElSID0gXCJ0ZXN0LXJlcG9ydHNcIjtcblxuY29uc3QgREVGQVVMVF9OT0RFX1RFU1RfTUFUQ0hfRVhURU5TSU9OUyA9IFwiY2pzLG1qcyxqcyxqc3gsY3RzLG10cyx0cyx0c3hcIjtcblxuLyoqXG4gKiBEZWZhdWx0IGdsb2IgcGF0dGVybnMgdXNlZCB0byBkaXNjb3ZlciB0ZXN0IGZpbGVzIGZvciBOb2RlJ3MgYnVpbHQtaW4gdGVzdFxuICogcnVubmVyLCBjb21iaW5pbmcgTm9kZS5qcycgb3duIGRlZmF1bHQgdGVzdCBmaWxlIGRpc2NvdmVyeSB3aXRoIGNvbW1vblxuICogSmVzdCBjb252ZW50aW9ucywgc28gdGhhdCBwcm9qZWN0cyBtb3ZpbmcgZnJvbSBKZXN0IGtlZXAgbWF0Y2hpbmcgdGhlaXJcbiAqIGV4aXN0aW5nIHRlc3QgZmlsZXMuXG4gKlxuICogTm9kZSdzIHRlc3QgcnVubmVyIGdsb2IgbWF0Y2hpbmcgZm9sbG93cyBgZ2xvYig3KWAgYW5kIGRvZXMgbm90IHN1cHBvcnRcbiAqIGV4dGdsb2JzIChlLmcuIGBAKC4uLilgLCBgKyguLi4pYCwgYD8oLi4uKWApLCBzbywgdW5saWtlIEplc3QncyBvd25cbiAqIGRlZmF1bHRzLCBlYWNoIGFsdGVybmF0aXZlIGlzIHNwZWxsZWQgb3V0IGV4cGxpY2l0bHkgaW5zdGVhZCBvZiByZWx5aW5nIG9uXG4gKiBleHRlbmRlZCBnbG9iIGdyb3Vwcy5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvdGVzdC5odG1sI3J1bm5pbmctdGVzdHMtZnJvbS10aGUtY29tbWFuZC1saW5lXG4gKi9cbmNvbnN0IERFRkFVTFRfTk9ERV9URVNUX01BVENIOiBzdHJpbmdbXSA9IFtcbiAgLy8gTm9kZS5qcycgb3duIGRlZmF1bHRzOiBmaWxlcyBpbnNpZGUgYSBcInRlc3RcIiBkaXJlY3RvcnksIG9yIG5hbWVkL3ByZWZpeGVkL3N1ZmZpeGVkIFwidGVzdFwiXG4gIGAqKi90ZXN0LyoqLyoueyR7REVGQVVMVF9OT0RFX1RFU1RfTUFUQ0hfRVhURU5TSU9OU319YCxcbiAgYCoqL3Rlc3QueyR7REVGQVVMVF9OT0RFX1RFU1RfTUFUQ0hfRVhURU5TSU9OU319YCxcbiAgYCoqL3Rlc3QtKi57JHtERUZBVUxUX05PREVfVEVTVF9NQVRDSF9FWFRFTlNJT05TfX1gLFxuICBgKiovKi50ZXN0Lnske0RFRkFVTFRfTk9ERV9URVNUX01BVENIX0VYVEVOU0lPTlN9fWAsXG4gIGAqKi8qLXRlc3QueyR7REVGQVVMVF9OT0RFX1RFU1RfTUFUQ0hfRVhURU5TSU9OU319YCxcbiAgYCoqLypfdGVzdC57JHtERUZBVUxUX05PREVfVEVTVF9NQVRDSF9FWFRFTlNJT05TfX1gLFxuICAvLyBKZXN0IGNvbnZlbnRpb25zOiBmaWxlcyBpbnNpZGUgYSBcIl9fdGVzdHNfX1wiIGRpcmVjdG9yeSwgb3IgbmFtZWQvc3VmZml4ZWQgXCJzcGVjXCJcbiAgYCoqL19fdGVzdHNfXy8qKi8qLnske0RFRkFVTFRfTk9ERV9URVNUX01BVENIX0VYVEVOU0lPTlN9fWAsXG4gIGAqKi9zcGVjLnske0RFRkFVTFRfTk9ERV9URVNUX01BVENIX0VYVEVOU0lPTlN9fWAsXG4gIGAqKi8qLnNwZWMueyR7REVGQVVMVF9OT0RFX1RFU1RfTUFUQ0hfRVhURU5TSU9OU319YCxcbl07XG5cbi8qKlxuICogV2hldGhlciB0byB1cGRhdGUgc25hcHNob3RzIGluIHRhc2sgXCJ0ZXN0XCIgKHdoaWNoIGlzIGV4ZWN1dGVkIGluIHRhc2tcbiAqIFwiYnVpbGRcIiBhbmQgYnVpbGQgd29ya2Zsb3dzKSwgb3IgY3JlYXRlIGEgc2VwYXJhdGUgdGFzayBcInRlc3Q6dXBkYXRlXCIgZm9yXG4gKiB1cGRhdGluZyBzbmFwc2hvdHMuXG4gKi9cbmV4cG9ydCBlbnVtIE5vZGVUZXN0VXBkYXRlU25hcHNob3Qge1xuICAvKipcbiAgICogQWx3YXlzIHVwZGF0ZSBzbmFwc2hvdHMgaW4gXCJ0ZXN0XCIgdGFzay5cbiAgICovXG4gIEFMV0FZUyA9IFwiYWx3YXlzXCIsXG5cbiAgLyoqXG4gICAqIE5ldmVyIHVwZGF0ZSBzbmFwc2hvdHMgaW4gXCJ0ZXN0XCIgdGFzayBhbmQgY3JlYXRlIGEgc2VwYXJhdGUgXCJ0ZXN0OnVwZGF0ZVwiIHRhc2suXG4gICAqL1xuICBORVZFUiA9IFwibmV2ZXJcIixcbn1cblxuLyoqXG4gKiBHbG9iIHBhdHRlcm5zIG1hdGNoaW5nIHRoZSBmaWxlcyB0aGF0IGNvbnRhaW4gdGVzdHMuXG4gKi9cbmNsYXNzIFRlc3RNYXRjaCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3BhdHRlcm5zID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRWYWx1ZTogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IoZGVmYXVsdFZhbHVlOiBzdHJpbmdbXSkge1xuICAgIHRoaXMuX2RlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBhZGQocGF0dGVybjogc3RyaW5nKSB7XG4gICAgdGhpcy5fcGF0dGVybnMuYWRkKHBhdHRlcm4pO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZShwYXR0ZXJuOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9wYXR0ZXJucy5kZWxldGUocGF0dGVybik7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZWQgbGF6aWx5IHNvIHBhdHRlcm5zIGFkZGVkIG9yIHJlbW92ZWQgYWZ0ZXIgY29uc3RydWN0aW9uIGFyZVxuICAgKiBzdGlsbCByZWZsZWN0ZWQuXG4gICAqL1xuICBwdWJsaWMgZGVmZXJyZWQoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9wYXR0ZXJucy5zaXplID4gMFxuICAgICAgPyBBcnJheS5mcm9tKHRoaXMuX3BhdHRlcm5zKVxuICAgICAgOiB0aGlzLl9kZWZhdWx0VmFsdWU7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgUmVwb3J0ZXJLaW5kID0gXCJkb3RcIiB8IFwianVuaXRcIiB8IFwibGNvdlwiIHwgXCJzcGVjXCIgfCBcInRhcFwiO1xuXG4vKipcbiAqIFdoZXJlIGEgcmVwb3J0ZXIncyBvdXRwdXQgaXMgd3JpdHRlbi5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvdGVzdC5odG1sI3Rlc3QtcmVwb3J0ZXJzXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXN0aW5hdGlvbiB7XG4gIC8qKlxuICAgKiBXcml0ZSB0byBzdGFuZGFyZCBvdXRwdXQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNURE9VVCA9IG5ldyBEZXN0aW5hdGlvbihcInN0ZG91dFwiKTtcblxuICAvKipcbiAgICogV3JpdGUgdG8gc3RhbmRhcmQgZXJyb3IuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNUREVSUiA9IG5ldyBEZXN0aW5hdGlvbihcInN0ZGVyclwiKTtcblxuICAvKipcbiAgICogV3JpdGUgdG8gYSBmaWxlIGF0IHRoZSBnaXZlbiBwYXRoLlxuICAgKiBAcGFyYW0gcGF0aCBwYXRoIG9mIHRoZSBmaWxlIHRvIHdyaXRlIHRvXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZpbGUocGF0aDogc3RyaW5nKTogRGVzdGluYXRpb24ge1xuICAgIHJldHVybiBuZXcgRGVzdGluYXRpb24ocGF0aCk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIFRoZSB1bmRlcmx5aW5nIHZhbHVlOiBgXCJzdGRvdXRcImAsIGBcInN0ZGVyclwiYCwgb3IgYSBmaWxlIHBhdGguXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmcsXG4gICkge31cbn1cblxuLyoqXG4gKiBBIHNpbmdsZSByZXBvcnRlci9kZXN0aW5hdGlvbiBwYWlyIGZvciB0aGUgTm9kZS5qcyBuYXRpdmUgdGVzdCBydW5uZXIuXG4gKlxuICogQHNlZSBodHRwczovL25vZGVqcy5vcmcvYXBpL3Rlc3QuaHRtbCN0ZXN0LXJlcG9ydGVyc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIE5vZGVSZXBvcnRlciB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZS9raW5kIG9mIHRoZSByZXBvcnRlci5cbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IFJlcG9ydGVyS2luZDtcbiAgLyoqXG4gICAqIFdoZXJlIHRoZSByZXBvcnRlcidzIG91dHB1dCBpcyB3cml0dGVuLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvbm9kZS9ibG9iLzQyMTVjYzM1ZTI1YzQ0ZjlmNGZlYTVhNDU0MWFmYzg2MmRiN2VmMGEvdGVzdC9wYXJhbGxlbC90ZXN0LXJ1bm5lci1yZXBvcnRlcnMuanMjTDQ2LUw3N1xuICAgKiBAZGVmYXVsdCBEZXN0aW5hdGlvbi5TVERPVVRcbiAgICovXG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uOiBEZXN0aW5hdGlvbjtcbn1cblxuLyoqXG4gKiBUaGUgc2V0IG9mIHJlcG9ydGVycyBjb25maWd1cmVkIGZvciBhIGBOb2RlTmF0aXZlVGVzdFJ1bm5lcmAuXG4gKlxuICogUHJvdmlkZXMgdGhlIGB0ZXN0LnRlc3RSZXBvcnRlcmAgYW5kIGB0ZXN0LnRlc3RSZXBvcnRlckRlc3RpbmF0aW9uYCB2YWx1ZXNcbiAqIG9mIHRoZSBnZW5lcmF0ZWQgTm9kZS5qcyBjb25maWd1cmF0aW9uIGZpbGUuXG4gKi9cbmNsYXNzIE5vZGVSZXBvcnRlcnMge1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnRlcnM6IE1hcDxSZXBvcnRlcktpbmQsIERlc3RpbmF0aW9uPiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb2plY3Q6IE5vZGVQcm9qZWN0KSB7fVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcmVwb3J0ZXIsIG9yIHVwZGF0ZXMgaXRzIGRlc3RpbmF0aW9uIGlmIG9uZSB3aXRoIHRoZSBzYW1lIG5hbWVcbiAgICogaXMgYWxyZWFkeSBjb25maWd1cmVkLlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZS9raW5kIG9mIHRoZSByZXBvcnRlciwgZS5nLiBgc3BlY2AsIGBqdW5pdGAsIGBsY292YC5cbiAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFdoZXJlIHRoZSByZXBvcnRlcidzIG91dHB1dCBpcyB3cml0dGVuLlxuICAgKiBAZGVmYXVsdCBEZXN0aW5hdGlvbi5TVERPVVRcbiAgICovXG4gIHB1YmxpYyBhZGQoXG4gICAgbmFtZTogUmVwb3J0ZXJLaW5kLFxuICAgIGRlc3RpbmF0aW9uOiBEZXN0aW5hdGlvbiA9IERlc3RpbmF0aW9uLlNURE9VVCxcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0ZXJzLnNldChuYW1lLCBkZXN0aW5hdGlvbik7XG5cbiAgICBpZiAoXG4gICAgICBkZXN0aW5hdGlvbiAhPT0gRGVzdGluYXRpb24uU1RET1VUICYmXG4gICAgICBkZXN0aW5hdGlvbiAhPT0gRGVzdGluYXRpb24uU1RERVJSXG4gICAgKSB7XG4gICAgICB0aGlzLmVuc3VyZURlc3RpbmF0aW9uRGlyZWN0b3J5KGRlc3RpbmF0aW9uKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIHJlcG9ydGVyLCBpZiBjb25maWd1cmVkLlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZS9raW5kIG9mIHRoZSByZXBvcnRlciB0byByZW1vdmUuXG4gICAqL1xuICBwdWJsaWMgcmVtb3ZlKG5hbWU6IFJlcG9ydGVyS2luZCk6IHZvaWQge1xuICAgIHRoaXMuX3JlcG9ydGVycy5kZWxldGUobmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgdGhlIGNvbmZpZ3VyZWQgcmVwb3J0ZXJzLCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIGFkZGVkLlxuICAgKi9cbiAgcHVibGljIGxpc3QoKTogTm9kZVJlcG9ydGVyW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX3JlcG9ydGVycywgKFtuYW1lLCBkZXN0aW5hdGlvbl0pID0+ICh7XG4gICAgICBuYW1lLFxuICAgICAgZGVzdGluYXRpb24sXG4gICAgfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhlIGRpcmVjdG9yeSBvZiBhIHJlcG9ydGVyJ3MgZmlsZSBkZXN0aW5hdGlvbiBleGlzdHMgYmVmb3JlIHRoZVxuICAgKiB0ZXN0IHJ1bm5lciBpcyBpbnZva2VkLCBhbmQgZXhjbHVkZXMgaXQgZnJvbSB0aGUgcHJvamVjdCdzIGAuZ2l0aWdub3JlYFxuICAgKiBhbmQgcGFja2FnZSAoZS5nLiBgLm5wbWlnbm9yZWApIGZpbGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBlbnN1cmVEZXN0aW5hdGlvbkRpcmVjdG9yeShkZXN0aW5hdGlvbjogRGVzdGluYXRpb24pOiB2b2lkIHtcbiAgICBjb25zdCBkaXIgPSBwb3NpeC5kaXJuYW1lKGRlc3RpbmF0aW9uLnZhbHVlKTtcbiAgICBpZiAoZGlyID09PSBcIi5cIikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyB0aGUgcmVwb3J0ZXIgZG9lcyBub3QgY3JlYXRlIGl0cyBvdXRwdXQgZGlyZWN0b3J5LCBzbyBpdCBtdXN0IGV4aXN0XG4gICAgLy8gYmVmb3JlIHRoZSB0ZXN0IHJ1bm5lciBpcyBpbnZva2VkLlxuICAgIHRoaXMucHJvamVjdC50ZXN0VGFzay5wcmVwZW5kRXhlYyhgbWtkaXIgLXAgJHtkaXJ9YCk7XG5cbiAgICBjb25zdCBkaXJQYXR0ZXJuID0gcG9zaXguam9pbihcIi9cIiwgZGlyLCBcIi9cIik7XG4gICAgdGhpcy5wcm9qZWN0LmFkZEdpdElnbm9yZShkaXJQYXR0ZXJuKTtcbiAgICB0aGlzLnByb2plY3QuYWRkUGFja2FnZUlnbm9yZShkaXJQYXR0ZXJuKTtcbiAgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIE5vZGUuanMnIGJ1aWx0LWluIHRlc3QgcnVubmVyIChgbm9kZSAtLXRlc3RgKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOb2RlTmF0aXZlVGVzdFJ1bm5lck9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGRpcmVjdG9yeSB3aGVyZSBjb3ZlcmFnZSBmaWxlcyBhcmUgb3V0cHV0LCBpZiBjb3ZlcmFnZSBjb2xsZWN0aW9uXG4gICAqIGlzIGVuYWJsZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiY292ZXJhZ2VcIlxuICAgKi9cbiAgcmVhZG9ubHkgY292ZXJhZ2VEaXJlY3Rvcnk/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gdXBkYXRlIHNuYXBzaG90cyBpbiB0YXNrIFwidGVzdFwiICh3aGljaCBpcyBleGVjdXRlZCBpbiB0YXNrXG4gICAqIFwiYnVpbGRcIiBhbmQgYnVpbGQgd29ya2Zsb3dzKSwgb3IgY3JlYXRlIGEgc2VwYXJhdGUgdGFzayBcInRlc3Q6dXBkYXRlXCJcbiAgICogZm9yIHVwZGF0aW5nIHNuYXBzaG90cy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBTFdBWVNcbiAgICovXG4gIHJlYWRvbmx5IHVwZGF0ZVNuYXBzaG90PzogTm9kZVRlc3RVcGRhdGVTbmFwc2hvdDtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBvcHRpb25zIHRvIHBhc3MgdG8gdGhlIGBub2RlIC0tdGVzdGAgQ0xJIGludm9jYXRpb24uXG4gICAqXG4gICAqIEVhY2ggZWxlbWVudCBpcyBwYXNzZWQgYXMgYSBzaW5nbGUgYXJndW1lbnQsIGV4YWN0bHkgYXMgZ2l2ZW46IG5vIHNoZWxsXG4gICAqIHBhcnNlcyB0aGVzZSwgc28gYSBmbGFnIGFuZCBpdHMgdmFsdWUgbmVlZCBzZXBhcmF0ZSBlbGVtZW50c1xuICAgKiAoYFtcIi0tZm9vXCIsIFwiYmFyXCJdYCwgbm90IGBbXCItLWZvbyBiYXJcIl1gKS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBleHRyYSBvcHRpb25zXG4gICAqL1xuICByZWFkb25seSBleHRyYUNsaU9wdGlvbnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogUHJlc2VydmUgdGhlIGRlZmF1bHQgcmVwb3J0ZXJzIChgc3BlY2AsIGBsY292YCwgYGp1bml0YCkgd2hlbiBhZGRpdGlvbmFsXG4gICAqIHJlcG9ydGVycyBhcmUgYWRkZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHByZXNlcnZlRGVmYXVsdFJlcG9ydGVycz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgcmVwb3J0ZXJzIHRvIGNvbmZpZ3VyZSAoZS5nLiBgeyBuYW1lOiBcInRhcFwiLCBkZXN0aW5hdGlvbjpcbiAgICogRGVzdGluYXRpb24uZmlsZShcInRlc3QtcmVwb3J0cy90YXAudHh0XCIpIH1gKS5cbiAgICpcbiAgICogVGhlc2UgYXJlIGFkZGVkIG9uIHRvcCBvZiB0aGUgZGVmYXVsdCByZXBvcnRlcnMgKGBzcGVjYCwgYGxjb3ZgLCBganVuaXRgKSxcbiAgICogd2hpY2ggYXJlIGNvbnRyb2xsZWQgdmlhIGBjb2xsZWN0Q292ZXJhZ2VgLiBVc2VcbiAgICogYE5vZGVOYXRpdmVUZXN0UnVubmVyLmFkZFJlcG9ydGVyYC9gcmVtb3ZlUmVwb3J0ZXJgL2BsaXN0UmVwb3J0ZXJzYCB0b1xuICAgKiBtYW5hZ2UgcmVwb3J0ZXJzIGFmdGVyIGNvbnN0cnVjdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBhZGRpdGlvbmFsIHJlcG9ydGVyc1xuICAgKi9cbiAgcmVhZG9ubHkgcmVwb3J0ZXJzPzogTm9kZVJlcG9ydGVyW107XG5cbiAgLyoqXG4gICAqIFBhdGggdG8gdGhlIEpTT04gY29uZmlndXJhdGlvbiBmaWxlIGZvciB0aGUgdGVzdCBydW5uZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwibm9kZS5jb25maWcuanNvblwiXG4gICAqL1xuICByZWFkb25seSBjb25maWdGaWxlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogR2xvYiBwYXR0ZXJucyBtYXRjaGluZyB0aGUgZmlsZXMgdGhhdCBjb250YWluIHRlc3RzLiBCeSBkZWZhdWx0IGl0XG4gICAqIGNvbWJpbmVzIE5vZGUuanMnIG93biBkZWZhdWx0IHRlc3QgZmlsZSBkaXNjb3Zlcnkgd2l0aCBKZXN0IGNvbnZlbnRpb25zLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGNvbWJpbmVzIE5vZGUuanMnIG93biBkZWZhdWx0IHRlc3QgZmlsZSBkaXNjb3Zlcnkgd2l0aCBKZXN0IGNvbnZlbnRpb25zXG4gICAqL1xuICByZWFkb25seSB0ZXN0TWF0Y2g/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGNvdmVyYWdlIGluZm9ybWF0aW9uIHNob3VsZCBiZSBjb2xsZWN0ZWQgd2hpbGVcbiAgICogZXhlY3V0aW5nIHRoZSB0ZXN0LCB2aWEgYC0tZXhwZXJpbWVudGFsLXRlc3QtY292ZXJhZ2VgLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBjb2xsZWN0Q292ZXJhZ2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBnbG9iIHBhdHRlcm5zIHRoYXQgYXJlIG1hdGNoZWQgYWdhaW5zdCBhbGwgZmlsZSBwYXRocyBiZWZvcmVcbiAgICogZXhlY3V0aW5nIGNvdmVyYWdlIGNvbGxlY3Rpb24uIElmIGEgZmlsZSBwYXRoIG1hdGNoZXMgYW55IG9mIHRoZVxuICAgKiBwYXR0ZXJucywgY292ZXJhZ2UgaW5mb3JtYXRpb24gd2lsbCBiZSBza2lwcGVkIGZvciBpdC5cbiAgICpcbiAgICogQGRlZmF1bHQgW1wiKipcXC90ZXN0LyoqXCIsIFwiKipcXC9fX3Rlc3RzX18vKipcIl1cbiAgICovXG4gIHJlYWRvbmx5IGNvdmVyYWdlUGF0aElnbm9yZVBhdHRlcm5zPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoaXMgb3B0aW9uIGFsbG93cyB0aGUgdXNlIG9mIGEgY3VzdG9tIGdsb2JhbCBzZXR1cCBtb2R1bGUgd2hpY2hcbiAgICogZXhwb3J0cyBhIGZ1bmN0aW9uIHRoYXQgaXMgdHJpZ2dlcmVkIG9uY2UgYmVmb3JlIGFsbCB0ZXN0IHN1aXRlcy5cbiAgICogV3JpdHRlbiBhcyBgdGVzdC1nbG9iYWwtc2V0dXBgIGluIHRoZSBnZW5lcmF0ZWQgTm9kZS5qcyBjb25maWd1cmF0aW9uXG4gICAqIGZpbGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5kZWZpbmVkXG4gICAqL1xuICByZWFkb25seSBnbG9iYWxTZXR1cD86IHN0cmluZztcblxuICAvKipcbiAgICogRW5hYmxlIG1vZHVsZSBtb2NraW5nIHN1cHBvcnQgdmlhIGAtLWV4cGVyaW1lbnRhbC10ZXN0LW1vZHVsZS1tb2Nrc2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBtb2R1bGVNb2Nrcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gZW5hYmxlIHRyYW5zZm9ybWF0aW9uIG9mIFR5cGVTY3JpcHQtb25seSBzeW50YXggKGUuZy4gZW51bXMsIG5hbWVzcGFjZXMpLlxuICAgKlxuICAgKiBVc2VzIGBhbWFyb2AgKHRoZSBUeXBlU2NyaXB0IHRyYW5zZm9ybWVyIHVzZWQgaW50ZXJuYWxseSBieSBOb2RlLmpzKSBhcyBhblxuICAgKiBleHRlcm5hbCBsb2FkZXIgdmlhIGAtLWltcG9ydD1hbWFyby90cmFuc2Zvcm1gLiBBZGRzIGEgZGVwZW5kZW5jeSBvbiB0aGVcbiAgICogYGFtYXJvYCBwYWNrYWdlIGFuZCBlbmFibGVzIGAtLWVuYWJsZS1zb3VyY2UtbWFwc2AgdG8gcHJlc2VydmUgYWNjdXJhdGVcbiAgICogc3RhY2sgdHJhY2VzLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9ub2RlanMvYW1hcm9cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHRyYW5zZm9ybVR5cGVzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBlbnRyaWVzIGZvciB0aGUgYG5vZGVPcHRpb25zYCBzZWN0aW9uIG9mIHRoZSBnZW5lcmF0ZWRcbiAgICogY29uZmlndXJhdGlvbiBmaWxlIChlLmcuIGBlbmFibGVTb3VyY2VNYXBzYCwgYGRpc2FibGVXYXJuaW5nYCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYWRkaXRpb25hbCBub2RlIG9wdGlvbnNcbiAgICovXG4gIHJlYWRvbmx5IG5vZGVPcHRpb25zPzogTm9kZUNvbmZpZ1NjaGVtYU5vZGVPcHRpb25zO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGVudHJpZXMgZm9yIHRoZSBgdGVzdGAgc2VjdGlvbiBvZiB0aGUgZ2VuZXJhdGVkXG4gICAqIGNvbmZpZ3VyYXRpb24gZmlsZSAoZS5nLiBgdGVzdENvbmN1cnJlbmN5YCwgYHRlc3RUaW1lb3V0YCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYWRkaXRpb25hbCBvcHRpb25zXG4gICAqL1xuICByZWFkb25seSB0ZXN0Q29uZmlnPzogTm9kZUNvbmZpZ1NjaGVtYVRlc3Q7XG59XG5cbi8qKlxuICogQ29uZmlndXJlcyBOb2RlJ3MgYnVpbHQtaW4gdGVzdCBydW5uZXIgKGBub2RlIC0tdGVzdGApLlxuICpcbiAqIE93bnMgdGhlIGdlbmVyYXRlZCBOb2RlLmpzIGNvbmZpZ3VyYXRpb24gZmlsZSwgdGhlIFwidGVzdFwiLCBcInRlc3Q6dXBkYXRlXCJcbiAqIGFuZCBcInRlc3Q6d2F0Y2hcIiB0YXNrcywgYW5kIHRoZSByZXBvcnRlcnMgYW5kIHRlc3QgbWF0Y2ggcGF0dGVybnMgdGhleSB1c2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBOb2RlTmF0aXZlVGVzdFJ1bm5lciBleHRlbmRzIENvbXBvbmVudCB7XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBzaW5nbGV0b24gTm9kZU5hdGl2ZVRlc3RSdW5uZXIgY29tcG9uZW50IG9mIGEgcHJvamVjdCBvciB1bmRlZmluZWRcbiAgICogaWYgdGhlcmUgaXMgbm9uZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgb2YocHJvamVjdDogUHJvamVjdCk6IE5vZGVOYXRpdmVUZXN0UnVubmVyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBpc05vZGVOYXRpdmVUZXN0UnVubmVyID0gKGM6IENvbXBvbmVudCk6IGMgaXMgTm9kZU5hdGl2ZVRlc3RSdW5uZXIgPT5cbiAgICAgIGMgaW5zdGFuY2VvZiBOb2RlTmF0aXZlVGVzdFJ1bm5lcjtcbiAgICByZXR1cm4gcHJvamVjdC5jb21wb25lbnRzLmZpbmQoaXNOb2RlTmF0aXZlVGVzdFJ1bm5lcik7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgcHJvamVjdDogTm9kZVByb2plY3Q7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb3ZlcmFnZURpcmVjdG9yeT86IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHVwZGF0ZVNuYXBzaG90OiBOb2RlVGVzdFVwZGF0ZVNuYXBzaG90O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVwb3J0ZXJzOiBOb2RlUmVwb3J0ZXJzO1xuXG4gIC8qKlxuICAgKiBUaGUgZ2VuZXJhdGVkIE5vZGUuanMgY29uZmlndXJhdGlvbiBmaWxlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGNvbmZpZ0ZpbGU6IE5vZGVDb25maWdGaWxlO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdGVzdFJlcG9ydHNEaXI6IHN0cmluZyA9IERFRkFVTFRfVEVTVF9SRVBPUlRTX0RJUjtcblxuICBwcml2YXRlIHJlYWRvbmx5IHRlc3RNYXRjaDogVGVzdE1hdGNoO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBJQ29uc3RydWN0LCBvcHRpb25zOiBOb2RlTmF0aXZlVGVzdFJ1bm5lck9wdGlvbnMgPSB7fSkge1xuICAgIHN1cGVyKHNjb3BlKTtcbiAgICB0aGlzLnByb2plY3QgPSBjbG9zZXN0UHJvamVjdE11c3RCZShzY29wZSwgTm9kZVByb2plY3QsIG5ldy50YXJnZXQubmFtZSk7XG5cbiAgICAvLyBOb2RlJ3Mgc25hcHNob3QgZmlsZXMgYXJlIGdlbmVyYXRlZCwgbm90IGF1dGhvcmVkLlxuICAgIHRoaXMucHJvamVjdC5yb290LmFubm90YXRlR2VuZXJhdGVkKFwiKi5zbmFwXCIpO1xuICAgIHRoaXMucHJvamVjdC5yb290LmFubm90YXRlR2VuZXJhdGVkKFwiKi5zbmFwc2hvdFwiKTtcblxuICAgIHRoaXMudXBkYXRlU25hcHNob3QgPVxuICAgICAgb3B0aW9ucy51cGRhdGVTbmFwc2hvdCA/PyBOb2RlVGVzdFVwZGF0ZVNuYXBzaG90LkFMV0FZUztcblxuICAgIHRoaXMucmVwb3J0ZXJzID0gbmV3IE5vZGVSZXBvcnRlcnModGhpcy5wcm9qZWN0KTtcbiAgICBjb25zdCBwcmVzZXJ2ZURlZmF1bHRSZXBvcnRlcnMgPSBvcHRpb25zLnByZXNlcnZlRGVmYXVsdFJlcG9ydGVycyA/PyB0cnVlO1xuXG4gICAgdGhpcy50ZXN0TWF0Y2ggPSBuZXcgVGVzdE1hdGNoKERFRkFVTFRfTk9ERV9URVNUX01BVENIKTtcblxuICAgIGlmIChvcHRpb25zLnRlc3RNYXRjaCAmJiBvcHRpb25zLnRlc3RNYXRjaC5sZW5ndGggPiAwKSB7XG4gICAgICBvcHRpb25zLnRlc3RNYXRjaC5mb3JFYWNoKChwYXR0ZXJuKSA9PiB0aGlzLnRlc3RNYXRjaC5hZGQocGF0dGVybikpO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbGxlY3RDb3ZlcmFnZSA9IG9wdGlvbnMuY29sbGVjdENvdmVyYWdlID8/IHRydWU7XG4gICAgY29uc3QgY292ZXJhZ2VEaXJlY3RvcnkgPSBvcHRpb25zLmNvdmVyYWdlRGlyZWN0b3J5ID8/IERFRkFVTFRfQ09WRVJBR0VfRElSO1xuICAgIHRoaXMuY292ZXJhZ2VEaXJlY3RvcnkgPSBjb2xsZWN0Q292ZXJhZ2UgPyBjb3ZlcmFnZURpcmVjdG9yeSA6IHVuZGVmaW5lZDtcblxuICAgIGlmICh0aGlzLmNvdmVyYWdlRGlyZWN0b3J5KSB7XG4gICAgICBjb25zdCBjb3ZlcmFnZURpcmVjdG9yeVBhdGggPSBwb3NpeC5qb2luKFxuICAgICAgICBcIi9cIixcbiAgICAgICAgdGhpcy5jb3ZlcmFnZURpcmVjdG9yeSxcbiAgICAgICAgXCIvXCIsXG4gICAgICApO1xuICAgICAgdGhpcy5wcm9qZWN0LmFkZEdpdElnbm9yZShjb3ZlcmFnZURpcmVjdG9yeVBhdGgpO1xuICAgICAgdGhpcy5wcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoY292ZXJhZ2VEaXJlY3RvcnlQYXRoKTtcbiAgICB9XG5cbiAgICBpZiAocHJlc2VydmVEZWZhdWx0UmVwb3J0ZXJzICYmIGNvbGxlY3RDb3ZlcmFnZSkge1xuICAgICAgdGhpcy5yZXBvcnRlcnMuYWRkKFwic3BlY1wiLCBEZXN0aW5hdGlvbi5TVERPVVQpO1xuICAgICAgdGhpcy5yZXBvcnRlcnMuYWRkKFxuICAgICAgICBcImxjb3ZcIixcbiAgICAgICAgRGVzdGluYXRpb24uZmlsZShgJHtjb3ZlcmFnZURpcmVjdG9yeX0vbGNvdi5pbmZvYCksXG4gICAgICApO1xuICAgICAgdGhpcy5yZXBvcnRlcnMuYWRkKFxuICAgICAgICBcImp1bml0XCIsXG4gICAgICAgIERlc3RpbmF0aW9uLmZpbGUoYCR7dGhpcy50ZXN0UmVwb3J0c0Rpcn0vanVuaXQueG1sYCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgeyBuYW1lLCBkZXN0aW5hdGlvbiB9IG9mIG9wdGlvbnMucmVwb3J0ZXJzID8/IFtdKSB7XG4gICAgICB0aGlzLnJlcG9ydGVycy5hZGQobmFtZSwgZGVzdGluYXRpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmF1bHRUZXN0OiBOb2RlQ29uZmlnU2NoZW1hVGVzdCA9IHtcbiAgICAgIHRlc3Q6IHRydWUsXG4gICAgICB0ZXN0R2xvYmFsU2V0dXA6IG9wdGlvbnMuZ2xvYmFsU2V0dXAsXG4gICAgICAuLi4oY29sbGVjdENvdmVyYWdlXG4gICAgICAgID8ge1xuICAgICAgICAgICAgZXhwZXJpbWVudGFsVGVzdENvdmVyYWdlOiB0cnVlLFxuICAgICAgICAgICAgdGVzdENvdmVyYWdlRXhjbHVkZTogb3B0aW9ucy5jb3ZlcmFnZVBhdGhJZ25vcmVQYXR0ZXJucyA/PyBbXG4gICAgICAgICAgICAgIFwiKiovdGVzdC8qKlwiLFxuICAgICAgICAgICAgICBcIioqL19fdGVzdHNfXy8qKlwiLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgICAgZXhwZXJpbWVudGFsVGVzdE1vZHVsZU1vY2tzOiBvcHRpb25zLm1vZHVsZU1vY2tzLFxuICAgICAgLy8gbGF6aWx5IHJlc29sdmVkIGF0IHN5bnRoZXNpcyB0aW1lLCBzbyB0aGF0IHJlcG9ydGVycyBhZGRlZCBvclxuICAgICAgLy8gcmVtb3ZlZCB2aWEgYHJlcG9ydGVyc2AgYWZ0ZXIgY29uc3RydWN0aW9uIGFyZSByZWZsZWN0ZWQgaW4gdGhlXG4gICAgICAvLyBnZW5lcmF0ZWQgZmlsZS5cbiAgICAgIHRlc3RSZXBvcnRlcjogKCgpID0+IHRoaXMucmVwb3J0ZXJzLmxpc3QoKS5tYXAoKHIpID0+IHIubmFtZSkpIGFzIGFueSxcbiAgICAgIHRlc3RSZXBvcnRlckRlc3RpbmF0aW9uOiAoKCkgPT5cbiAgICAgICAgdGhpcy5yZXBvcnRlcnMubGlzdCgpLm1hcCgocikgPT4gci5kZXN0aW5hdGlvbi52YWx1ZSkpIGFzIGFueSxcbiAgICB9O1xuICAgIGNvbnN0IHRlc3Q6IE5vZGVDb25maWdTY2hlbWFUZXN0ID0gZGVlcE1lcmdlKFxuICAgICAgW2RlZmF1bHRUZXN0LCBvcHRpb25zLnRlc3RDb25maWcgPz8ge31dLFxuICAgICAgeyBkZXN0cnVjdGl2ZTogdHJ1ZSB9LFxuICAgICk7XG5cbiAgICBsZXQgbm9kZU9wdGlvbnM6IE5vZGVDb25maWdTY2hlbWFOb2RlT3B0aW9ucyA9IHsgLi4ub3B0aW9ucy5ub2RlT3B0aW9ucyB9O1xuICAgIGNvbnN0IGV4dHJhQ2xpT3B0aW9ucyA9IG9wdGlvbnMuZXh0cmFDbGlPcHRpb25zID8/IFtdO1xuXG4gICAgaWYgKG9wdGlvbnMudHJhbnNmb3JtVHlwZXMgPz8gZmFsc2UpIHtcbiAgICAgIHRoaXMucHJvamVjdC5hZGREZXZEZXBzKFwiYW1hcm9cIik7XG4gICAgICBjb25zdCBpbXBvcnRzID0gbm9kZU9wdGlvbnMuaW1wb3J0ID8/IFtdO1xuICAgICAgaWYgKCFpbXBvcnRzLmluY2x1ZGVzKFwiYW1hcm8vdHJhbnNmb3JtXCIpKSB7XG4gICAgICAgIGltcG9ydHMudW5zaGlmdChcImFtYXJvL3RyYW5zZm9ybVwiKTtcbiAgICAgIH1cbiAgICAgIG5vZGVPcHRpb25zID0ge1xuICAgICAgICAuLi5ub2RlT3B0aW9ucyxcbiAgICAgICAgZW5hYmxlU291cmNlTWFwczogdHJ1ZSxcbiAgICAgICAgaW1wb3J0OiBpbXBvcnRzLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbmZpZ0ZpbGUgPSBuZXcgTm9kZUNvbmZpZ0ZpbGUodGhpcy5wcm9qZWN0LCB7XG4gICAgICBmaWxlUGF0aDogb3B0aW9ucy5jb25maWdGaWxlUGF0aCxcbiAgICAgIHRlc3QsXG4gICAgICBub2RlT3B0aW9ucyxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QubnBtaWdub3JlPy5hZGRQYXR0ZXJucyhgLyR7dGhpcy5jb25maWdGaWxlLmZpbGUucGF0aH1gKTtcblxuICAgIC8vIFRlc3QgbWF0Y2ggcGF0dGVybnMgYXJlIHBvc2l0aW9uYWwgYXJndW1lbnRzIGFuZCBtdXN0IGNvbWUgYWZ0ZXIgZXZlcnlcbiAgICAvLyBmbGFnOiBvbmNlIE5vZGUgc2VlcyB0aGUgZmlyc3QgcG9zaXRpb25hbCBhcmd1bWVudCBpdCBzdG9wcyBwYXJzaW5nXG4gICAgLy8gZmxhZ3MsIHNvIGFueSBmbGFnIGFwcGVuZGVkIGFmdGVyIHRoZW0gKGUuZy4gYC0td2F0Y2hgKSBpcyBpZ25vcmVkLlxuICAgIGNvbnN0IGNvbW1hbmQ6IHN0cmluZ1tdID0gW1xuICAgICAgXCJub2RlXCIsXG4gICAgICBgLS1leHBlcmltZW50YWwtY29uZmlnLWZpbGU9JHt0aGlzLmNvbmZpZ0ZpbGUuZmlsZS5wYXRofWAsXG4gICAgICAuLi5leHRyYUNsaU9wdGlvbnMsXG4gICAgXTtcblxuICAgIC8vIGB0ZXN0TWF0Y2hgIGlzIGEgbGl2ZSBjb2xsZWN0aW9uIChgYWRkYC9gcmVtb3ZlYCBjYW4gc3RpbGwgYmUgY2FsbGVkXG4gICAgLy8gYWZ0ZXIgY29uc3RydWN0aW9uKSwgc28gaXRzIHJlc29sdXRpb24gaXMgZGVmZXJyZWQgd2l0aCBgbGF6eUV4ZWNBcmdzYFxuICAgIC8vIHJhdGhlciB0aGFuIHJlYWQgZWFnZXJseSBoZXJlLlxuICAgIGNvbnN0IHRlc3RNYXRjaEFyZ3MgPSAoKSA9PiB0aGlzLnRlc3RNYXRjaC5kZWZlcnJlZCgpO1xuXG4gICAgaWYgKHRoaXMudXBkYXRlU25hcHNob3QgPT09IE5vZGVUZXN0VXBkYXRlU25hcHNob3QuQUxXQVlTKSB7XG4gICAgICB0aGlzLnByb2plY3QudGVzdFRhc2suZXhlY0FyZ3MoXG4gICAgICAgIGxhenlFeGVjQXJncygoKSA9PiBbXG4gICAgICAgICAgLi4uY29tbWFuZCxcbiAgICAgICAgICBcIi0tdGVzdC11cGRhdGUtc25hcHNob3RzXCIsXG4gICAgICAgICAgLi4udGVzdE1hdGNoQXJncygpLFxuICAgICAgICBdKSxcbiAgICAgICAgeyByZWNlaXZlQXJnczogdHJ1ZSB9LFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGVzdFVwZGF0ZSA9IHRoaXMucHJvamVjdC50YXNrcy50cnlGaW5kKFwidGVzdDp1cGRhdGVcIik7XG4gICAgICBpZiAoIXRlc3RVcGRhdGUpIHtcbiAgICAgICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soXCJ0ZXN0OnVwZGF0ZVwiLCB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiVXBkYXRlIHRlc3Qgc25hcHNob3RzXCIsXG4gICAgICAgICAgZXhlY0FyZ3M6IGxhenlFeGVjQXJncygoKSA9PiBbXG4gICAgICAgICAgICAuLi5jb21tYW5kLFxuICAgICAgICAgICAgXCItLXRlc3QtdXBkYXRlLXNuYXBzaG90c1wiLFxuICAgICAgICAgICAgLi4udGVzdE1hdGNoQXJncygpLFxuICAgICAgICAgIF0pLFxuICAgICAgICAgIHJlY2VpdmVBcmdzOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5wcm9qZWN0LnRlc3RUYXNrLmV4ZWNBcmdzKFxuICAgICAgICBsYXp5RXhlY0FyZ3MoKCkgPT4gWy4uLmNvbW1hbmQsIC4uLnRlc3RNYXRjaEFyZ3MoKV0pLFxuICAgICAgICB7IHJlY2VpdmVBcmdzOiB0cnVlIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHRlc3RXYXRjaCA9IHRoaXMucHJvamVjdC50YXNrcy50cnlGaW5kKFwidGVzdDp3YXRjaFwiKTtcbiAgICBpZiAoIXRlc3RXYXRjaCkge1xuICAgICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soXCJ0ZXN0OndhdGNoXCIsIHtcbiAgICAgICAgZGVzY3JpcHRpb246IFwiUnVuIHRlc3RzIGluIHdhdGNoIG1vZGVcIixcbiAgICAgICAgZXhlY0FyZ3M6IGxhenlFeGVjQXJncygoKSA9PiBbXG4gICAgICAgICAgLi4uY29tbWFuZCxcbiAgICAgICAgICBcIi0td2F0Y2hcIixcbiAgICAgICAgICAuLi50ZXN0TWF0Y2hBcmdzKCksXG4gICAgICAgIF0pLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSB0ZXN0IG1hdGNoIHBhdHRlcm4uXG4gICAqIEBwYXJhbSBwYXR0ZXJuIGdsb2IgcGF0dGVybiB0byBtYXRjaCBmb3IgdGVzdHNcbiAgICovXG4gIHB1YmxpYyBhZGRUZXN0TWF0Y2gocGF0dGVybjogc3RyaW5nKSB7XG4gICAgdGhpcy50ZXN0TWF0Y2guYWRkKHBhdHRlcm4pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSB0ZXN0IG1hdGNoIHBhdHRlcm4sIGlmIGNvbmZpZ3VyZWQuXG4gICAqIEBwYXJhbSBwYXR0ZXJuIGdsb2IgcGF0dGVybiB0byByZW1vdmVcbiAgICovXG4gIHB1YmxpYyByZW1vdmVUZXN0TWF0Y2gocGF0dGVybjogc3RyaW5nKSB7XG4gICAgdGhpcy50ZXN0TWF0Y2gucmVtb3ZlKHBhdHRlcm4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZXBvcnRlciwgb3IgdXBkYXRlcyBpdHMgZGVzdGluYXRpb24gaWYgb25lIHdpdGggdGhlIHNhbWUgbmFtZVxuICAgKiBpcyBhbHJlYWR5IGNvbmZpZ3VyZWQuXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lL2tpbmQgb2YgdGhlIHJlcG9ydGVyLCBlLmcuIGBzcGVjYCwgYGp1bml0YCwgYGxjb3ZgLlxuICAgKiBAcGFyYW0gZGVzdGluYXRpb24gV2hlcmUgdGhlIHJlcG9ydGVyJ3Mgb3V0cHV0IGlzIHdyaXR0ZW4uXG4gICAqIEBkZWZhdWx0IERlc3RpbmF0aW9uLlNURE9VVFxuICAgKi9cbiAgcHVibGljIGFkZFJlcG9ydGVyKG5hbWU6IFJlcG9ydGVyS2luZCwgZGVzdGluYXRpb24/OiBEZXN0aW5hdGlvbikge1xuICAgIHRoaXMucmVwb3J0ZXJzLmFkZChuYW1lLCBkZXN0aW5hdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIHJlcG9ydGVyLCBpZiBjb25maWd1cmVkLlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZS9raW5kIG9mIHRoZSByZXBvcnRlciB0byByZW1vdmUuXG4gICAqL1xuICBwdWJsaWMgcmVtb3ZlUmVwb3J0ZXIobmFtZTogUmVwb3J0ZXJLaW5kKSB7XG4gICAgdGhpcy5yZXBvcnRlcnMucmVtb3ZlKG5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIHRoZSBjb25maWd1cmVkIHJlcG9ydGVycywgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBhZGRlZC5cbiAgICovXG4gIHB1YmxpYyBsaXN0UmVwb3J0ZXJzKCk6IE5vZGVSZXBvcnRlcltdIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnRlcnMubGlzdCgpO1xuICB9XG59XG5cbi8qKlxuICogRGVmZXJzIHJlc29sdXRpb24gb2YgYSBgVGFza1N0ZXBgJ3MgYGV4ZWNBcmdzYCB0byBzeW50aGVzaXMgdGltZSwgd2hlbiB0aGVcbiAqIHRhc2tzIG1hbmlmZXN0IGlzIHJlbmRlcmVkLlxuICpcbiAqIGBUYXNrU3RlcC5leGVjQXJnc2AgaXMgdHlwZWQgYXMgYSBwbGFpbiBgc3RyaW5nW11gLCBidXQgdGhlIG1hbmlmZXN0IGlzXG4gKiB3cml0dGVuIHRocm91Z2ggdGhlIGdlbmVyaWMgYHJlc29sdmUoKWAgd2Fsa2VyIChzZWVcbiAqIGBQcm9qZW5UYXNrUnVubmVyLnRhc2tzTWFuaWZlc3RgKSAtIHRoZSBzYW1lIG1lY2hhbmlzbSBgSnNvbkZpbGVgL2BPYmplY3RGaWxlYFxuICogdXNlIGZvciBsYXp5IHZhbHVlcyBlbHNld2hlcmUgKGUuZy4gYE5vZGVSZXBvcnRlcnMubGlzdGAsIGBUZXN0TWF0Y2hgKS5cbiAqIFRoYXQgd2Fsa2VyIGNhbGxzIGFueSBmdW5jdGlvbiBpdCBmaW5kcywgc28gYSBjYWxsYmFjayBkZWZlcnJlZCBoZXJlIHJ1bnNcbiAqIG9uY2UsIGF0IHRoYXQgcG9pbnQsIGluIHBsYWNlIG9mIGEgcGxhaW4gYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGxhenlFeGVjQXJncyhmbjogKCkgPT4gc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBmbiBhcyBhbnk7XG59XG4iXX0=
@@ -77,7 +77,7 @@ var CodeArtifactAuthProvider;
77
77
  * Represents the npm `package.json` file.
78
78
  */
79
79
  class NodePackage extends component_1.Component {
80
- static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.javascript.NodePackage", version: "0.103.26" };
80
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.javascript.NodePackage", version: "0.104.0" };
81
81
  /**
82
82
  * Returns the `NodePackage` instance associated with a project or `undefined` if
83
83
  * there is no NodePackage.