@workflow/builders 5.0.0-beta.4 → 5.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/apply-swc-transform.d.ts +7 -2
- package/dist/apply-swc-transform.d.ts.map +1 -1
- package/dist/apply-swc-transform.js +10 -4
- package/dist/base-builder-logging.test.d.ts +2 -0
- package/dist/base-builder-logging.test.d.ts.map +1 -0
- package/dist/base-builder-logging.test.js +99 -0
- package/dist/base-builder.d.ts +132 -13
- package/dist/base-builder.d.ts.map +1 -1
- package/dist/base-builder.js +788 -92
- package/dist/build-queue.js +1 -1
- package/dist/config-helpers.d.ts +4 -1
- package/dist/config-helpers.d.ts.map +1 -1
- package/dist/config-helpers.js +63 -1
- package/dist/config-helpers.test.d.ts +2 -0
- package/dist/config-helpers.test.d.ts.map +1 -0
- package/dist/config-helpers.test.js +17 -0
- package/dist/constants.d.ts +66 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +106 -19
- package/dist/constants.test.d.ts +2 -0
- package/dist/constants.test.d.ts.map +1 -0
- package/dist/constants.test.js +90 -0
- package/dist/discover-entries-esbuild-plugin.d.ts +3 -1
- package/dist/discover-entries-esbuild-plugin.d.ts.map +1 -1
- package/dist/discover-entries-esbuild-plugin.js +24 -4
- package/dist/discover-entries-esbuild-plugin.test.js +1 -1
- package/dist/esbuild-tsconfig.js +1 -1
- package/dist/esbuild-tsconfig.test.js +1 -1
- package/dist/external-package-warning.test.d.ts +2 -0
- package/dist/external-package-warning.test.d.ts.map +1 -0
- package/dist/external-package-warning.test.js +219 -0
- package/dist/fast-discovery.d.ts +29 -0
- package/dist/fast-discovery.d.ts.map +1 -0
- package/dist/fast-discovery.js +771 -0
- package/dist/fast-discovery.test.d.ts +2 -0
- package/dist/fast-discovery.test.d.ts.map +1 -0
- package/dist/fast-discovery.test.js +453 -0
- package/dist/get-input-files.test.js +34 -2
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/module-specifier.d.ts +20 -2
- package/dist/module-specifier.d.ts.map +1 -1
- package/dist/module-specifier.js +92 -17
- package/dist/module-specifier.test.js +45 -3
- package/dist/node-module-esbuild-plugin.d.ts.map +1 -1
- package/dist/node-module-esbuild-plugin.js +73 -23
- package/dist/node-module-esbuild-plugin.test.js +97 -1
- package/dist/optional-otel-api.d.ts +14 -0
- package/dist/optional-otel-api.d.ts.map +1 -0
- package/dist/optional-otel-api.js +14 -0
- package/dist/optional-typescript-alias.d.ts +2 -0
- package/dist/optional-typescript-alias.d.ts.map +1 -0
- package/dist/optional-typescript-alias.js +3 -0
- package/dist/optional-typescript.d.ts +3 -0
- package/dist/optional-typescript.d.ts.map +1 -0
- package/dist/optional-typescript.js +9 -0
- package/dist/optional-ws-native.d.ts +30 -0
- package/dist/optional-ws-native.d.ts.map +1 -0
- package/dist/optional-ws-native.js +33 -0
- package/dist/pseudo-package-esbuild-plugin.js +1 -1
- package/dist/pseudo-package-esbuild-plugin.test.js +1 -1
- package/dist/request-converter.js +1 -1
- package/dist/resolve-sourcemap.test.d.ts +2 -0
- package/dist/resolve-sourcemap.test.d.ts.map +1 -0
- package/dist/resolve-sourcemap.test.js +194 -0
- package/dist/serde-checker.js +1 -1
- package/dist/standalone.d.ts +0 -3
- package/dist/standalone.d.ts.map +1 -1
- package/dist/standalone.js +17 -41
- package/dist/step-source-registration.test.d.ts +2 -0
- package/dist/step-source-registration.test.d.ts.map +1 -0
- package/dist/step-source-registration.test.js +82 -0
- package/dist/swc-esbuild-plugin.d.ts +26 -0
- package/dist/swc-esbuild-plugin.d.ts.map +1 -1
- package/dist/swc-esbuild-plugin.js +124 -14
- package/dist/swc-esbuild-plugin.test.js +475 -6
- package/dist/transform-utils.d.ts.map +1 -1
- package/dist/transform-utils.js +45 -6
- package/dist/transform-utils.test.js +78 -6
- package/dist/types.d.ts +73 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/vercel-build-output-api.d.ts +0 -2
- package/dist/vercel-build-output-api.d.ts.map +1 -1
- package/dist/vercel-build-output-api.js +37 -60
- package/dist/workflow-alias.js +1 -1
- package/dist/workflow-alias.test.js +2 -2
- package/dist/workflows-extractor.js +8 -3
- package/dist/workflows-extractor.test.d.ts +2 -0
- package/dist/workflows-extractor.test.d.ts.map +1 -0
- package/dist/workflows-extractor.test.js +70 -0
- package/package.json +8 -7
- package/dist/apply-swc-transform.js.map +0 -1
- package/dist/base-builder.js.map +0 -1
- package/dist/build-queue.js.map +0 -1
- package/dist/config-helpers.js.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/discover-entries-esbuild-plugin.js.map +0 -1
- package/dist/discover-entries-esbuild-plugin.test.js.map +0 -1
- package/dist/esbuild-tsconfig.js.map +0 -1
- package/dist/esbuild-tsconfig.test.js.map +0 -1
- package/dist/get-input-files.test.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/module-specifier.js.map +0 -1
- package/dist/module-specifier.test.js.map +0 -1
- package/dist/node-module-esbuild-plugin.js.map +0 -1
- package/dist/node-module-esbuild-plugin.test.js.map +0 -1
- package/dist/pseudo-package-esbuild-plugin.js.map +0 -1
- package/dist/pseudo-package-esbuild-plugin.test.js.map +0 -1
- package/dist/request-converter.js.map +0 -1
- package/dist/serde-checker.js.map +0 -1
- package/dist/standalone.js.map +0 -1
- package/dist/swc-esbuild-plugin.js.map +0 -1
- package/dist/swc-esbuild-plugin.test.js.map +0 -1
- package/dist/transform-utils.js.map +0 -1
- package/dist/transform-utils.test.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/vercel-build-output-api.js.map +0 -1
- package/dist/workflow-alias.js.map +0 -1
- package/dist/workflow-alias.test.js.map +0 -1
- package/dist/workflows-extractor.js.map +0 -1
package/dist/standalone.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { rm } from 'node:fs/promises';
|
|
1
2
|
import { BaseBuilder } from './base-builder.js';
|
|
2
3
|
export class StandaloneBuilder extends BaseBuilder {
|
|
3
4
|
constructor(config) {
|
|
@@ -7,21 +8,25 @@ export class StandaloneBuilder extends BaseBuilder {
|
|
|
7
8
|
});
|
|
8
9
|
}
|
|
9
10
|
async build() {
|
|
11
|
+
// Existing standalone output may still contain the retired step route.
|
|
12
|
+
await rm(this.resolvePath('.well-known/workflow/v1/step.mjs'), {
|
|
13
|
+
force: true,
|
|
14
|
+
});
|
|
10
15
|
const inputFiles = await this.getInputFiles();
|
|
11
16
|
const tsconfigPath = await this.findTsConfigPath();
|
|
12
|
-
const
|
|
17
|
+
const stepsBundlePath = this.resolvePath(this.config.stepsBundlePath);
|
|
18
|
+
const workflowBundlePath = this.resolvePath(this.config.workflowsBundlePath);
|
|
19
|
+
await this.ensureDirectory(stepsBundlePath);
|
|
20
|
+
await this.ensureDirectory(workflowBundlePath);
|
|
21
|
+
this.logBaseBuilderInfo('Creating combined bundle');
|
|
22
|
+
const { manifest } = await this.createCombinedBundle({
|
|
13
23
|
inputFiles,
|
|
24
|
+
stepsOutfile: stepsBundlePath,
|
|
25
|
+
flowOutfile: workflowBundlePath,
|
|
14
26
|
tsconfigPath,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const workflowsManifest = await this.buildWorkflowsBundle(options);
|
|
27
|
+
bundleFinalOutput: true,
|
|
28
|
+
});
|
|
18
29
|
await this.buildWebhookFunction();
|
|
19
|
-
// Merge manifests from both bundles
|
|
20
|
-
// Steps bundle discovers classes from default export conditions
|
|
21
|
-
// Workflow bundle discovers classes from 'workflow' export conditions
|
|
22
|
-
const manifest = this.mergeManifests(stepsManifest, workflowsManifest);
|
|
23
|
-
// Build unified manifest from workflow bundle
|
|
24
|
-
const workflowBundlePath = this.resolvePath(this.config.workflowsBundlePath);
|
|
25
30
|
const manifestDir = this.resolvePath('.well-known/workflow/v1');
|
|
26
31
|
await this.createManifest({
|
|
27
32
|
workflowBundlePath,
|
|
@@ -30,37 +35,8 @@ export class StandaloneBuilder extends BaseBuilder {
|
|
|
30
35
|
});
|
|
31
36
|
await this.createClientLibrary();
|
|
32
37
|
}
|
|
33
|
-
mergeManifests(stepsManifest, workflowsManifest) {
|
|
34
|
-
return {
|
|
35
|
-
steps: { ...stepsManifest.steps, ...workflowsManifest.steps },
|
|
36
|
-
workflows: { ...stepsManifest.workflows, ...workflowsManifest.workflows },
|
|
37
|
-
classes: { ...stepsManifest.classes, ...workflowsManifest.classes },
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
async buildStepsBundle({ inputFiles, tsconfigPath, }) {
|
|
41
|
-
console.log('Creating steps bundle at', this.config.stepsBundlePath);
|
|
42
|
-
const stepsBundlePath = this.resolvePath(this.config.stepsBundlePath);
|
|
43
|
-
await this.ensureDirectory(stepsBundlePath);
|
|
44
|
-
const { manifest } = await this.createStepsBundle({
|
|
45
|
-
outfile: stepsBundlePath,
|
|
46
|
-
inputFiles,
|
|
47
|
-
tsconfigPath,
|
|
48
|
-
});
|
|
49
|
-
return manifest;
|
|
50
|
-
}
|
|
51
|
-
async buildWorkflowsBundle({ inputFiles, tsconfigPath, }) {
|
|
52
|
-
console.log('Creating workflows bundle at', this.config.workflowsBundlePath);
|
|
53
|
-
const workflowBundlePath = this.resolvePath(this.config.workflowsBundlePath);
|
|
54
|
-
await this.ensureDirectory(workflowBundlePath);
|
|
55
|
-
const { manifest } = await this.createWorkflowsBundle({
|
|
56
|
-
outfile: workflowBundlePath,
|
|
57
|
-
inputFiles,
|
|
58
|
-
tsconfigPath,
|
|
59
|
-
});
|
|
60
|
-
return manifest;
|
|
61
|
-
}
|
|
62
38
|
async buildWebhookFunction() {
|
|
63
|
-
|
|
39
|
+
this.logBaseBuilderInfo('Creating webhook bundle at', this.config.webhookBundlePath);
|
|
64
40
|
const webhookBundlePath = this.resolvePath(this.config.webhookBundlePath);
|
|
65
41
|
await this.ensureDirectory(webhookBundlePath);
|
|
66
42
|
await this.createWebhookBundle({
|
|
@@ -68,4 +44,4 @@ export class StandaloneBuilder extends BaseBuilder {
|
|
|
68
44
|
});
|
|
69
45
|
}
|
|
70
46
|
}
|
|
71
|
-
//# sourceMappingURL=
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhbG9uZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zdGFuZGFsb25lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHaEQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLFdBQVc7SUFDaEQsWUFBWSxNQUFzQjtRQUNoQyxLQUFLLENBQUM7WUFDSixHQUFHLE1BQU07WUFDVCxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUM7U0FDWixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUs7UUFDVCx1RUFBdUU7UUFDdkUsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxrQ0FBa0MsQ0FBQyxFQUFFO1lBQzdELEtBQUssRUFBRSxJQUFJO1NBQ1osQ0FBQyxDQUFDO1FBRUgsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDOUMsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUVuRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdEUsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUN6QyxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUNoQyxDQUFDO1FBQ0YsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBRS9DLElBQUksQ0FBQyxrQkFBa0IsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBRXBELE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztZQUNuRCxVQUFVO1lBQ1YsWUFBWSxFQUFFLGVBQWU7WUFDN0IsV0FBVyxFQUFFLGtCQUFrQjtZQUMvQixZQUFZO1lBQ1osaUJBQWlCLEVBQUUsSUFBSTtTQUN4QixDQUFDLENBQUM7UUFFSCxNQUFNLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBRWxDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUNoRSxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUM7WUFDeEIsa0JBQWtCO1lBQ2xCLFdBQVc7WUFDWCxRQUFRO1NBQ1QsQ0FBQyxDQUFDO1FBRUgsTUFBTSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBRU8sS0FBSyxDQUFDLG9CQUFvQjtRQUNoQyxJQUFJLENBQUMsa0JBQWtCLENBQ3JCLDRCQUE0QixFQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUM5QixDQUFDO1FBRUYsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUMxRSxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUU5QyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztZQUM3QixPQUFPLEVBQUUsaUJBQWlCO1NBQzNCLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJtIH0gZnJvbSAnbm9kZTpmcy9wcm9taXNlcyc7XG5pbXBvcnQgeyBCYXNlQnVpbGRlciB9IGZyb20gJy4vYmFzZS1idWlsZGVyLmpzJztcbmltcG9ydCB0eXBlIHsgV29ya2Zsb3dDb25maWcgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIFN0YW5kYWxvbmVCdWlsZGVyIGV4dGVuZHMgQmFzZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFdvcmtmbG93Q29uZmlnKSB7XG4gICAgc3VwZXIoe1xuICAgICAgLi4uY29uZmlnLFxuICAgICAgZGlyczogWycuJ10sXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBidWlsZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBFeGlzdGluZyBzdGFuZGFsb25lIG91dHB1dCBtYXkgc3RpbGwgY29udGFpbiB0aGUgcmV0aXJlZCBzdGVwIHJvdXRlLlxuICAgIGF3YWl0IHJtKHRoaXMucmVzb2x2ZVBhdGgoJy53ZWxsLWtub3duL3dvcmtmbG93L3YxL3N0ZXAubWpzJyksIHtcbiAgICAgIGZvcmNlOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW5wdXRGaWxlcyA9IGF3YWl0IHRoaXMuZ2V0SW5wdXRGaWxlcygpO1xuICAgIGNvbnN0IHRzY29uZmlnUGF0aCA9IGF3YWl0IHRoaXMuZmluZFRzQ29uZmlnUGF0aCgpO1xuXG4gICAgY29uc3Qgc3RlcHNCdW5kbGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aCh0aGlzLmNvbmZpZy5zdGVwc0J1bmRsZVBhdGgpO1xuICAgIGNvbnN0IHdvcmtmbG93QnVuZGxlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGgoXG4gICAgICB0aGlzLmNvbmZpZy53b3JrZmxvd3NCdW5kbGVQYXRoXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZURpcmVjdG9yeShzdGVwc0J1bmRsZVBhdGgpO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlRGlyZWN0b3J5KHdvcmtmbG93QnVuZGxlUGF0aCk7XG5cbiAgICB0aGlzLmxvZ0Jhc2VCdWlsZGVySW5mbygnQ3JlYXRpbmcgY29tYmluZWQgYnVuZGxlJyk7XG5cbiAgICBjb25zdCB7IG1hbmlmZXN0IH0gPSBhd2FpdCB0aGlzLmNyZWF0ZUNvbWJpbmVkQnVuZGxlKHtcbiAgICAgIGlucHV0RmlsZXMsXG4gICAgICBzdGVwc091dGZpbGU6IHN0ZXBzQnVuZGxlUGF0aCxcbiAgICAgIGZsb3dPdXRmaWxlOiB3b3JrZmxvd0J1bmRsZVBhdGgsXG4gICAgICB0c2NvbmZpZ1BhdGgsXG4gICAgICBidW5kbGVGaW5hbE91dHB1dDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIGF3YWl0IHRoaXMuYnVpbGRXZWJob29rRnVuY3Rpb24oKTtcblxuICAgIGNvbnN0IG1hbmlmZXN0RGlyID0gdGhpcy5yZXNvbHZlUGF0aCgnLndlbGwta25vd24vd29ya2Zsb3cvdjEnKTtcbiAgICBhd2FpdCB0aGlzLmNyZWF0ZU1hbmlmZXN0KHtcbiAgICAgIHdvcmtmbG93QnVuZGxlUGF0aCxcbiAgICAgIG1hbmlmZXN0RGlyLFxuICAgICAgbWFuaWZlc3QsXG4gICAgfSk7XG5cbiAgICBhd2FpdCB0aGlzLmNyZWF0ZUNsaWVudExpYnJhcnkoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYnVpbGRXZWJob29rRnVuY3Rpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5sb2dCYXNlQnVpbGRlckluZm8oXG4gICAgICAnQ3JlYXRpbmcgd2ViaG9vayBidW5kbGUgYXQnLFxuICAgICAgdGhpcy5jb25maWcud2ViaG9va0J1bmRsZVBhdGhcbiAgICApO1xuXG4gICAgY29uc3Qgd2ViaG9va0J1bmRsZVBhdGggPSB0aGlzLnJlc29sdmVQYXRoKHRoaXMuY29uZmlnLndlYmhvb2tCdW5kbGVQYXRoKTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZURpcmVjdG9yeSh3ZWJob29rQnVuZGxlUGF0aCk7XG5cbiAgICBhd2FpdCB0aGlzLmNyZWF0ZVdlYmhvb2tCdW5kbGUoe1xuICAgICAgb3V0ZmlsZTogd2ViaG9va0J1bmRsZVBhdGgsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-source-registration.test.d.ts","sourceRoot":"","sources":["../src/step-source-registration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
+
import { BaseBuilder } from './base-builder.js';
|
|
6
|
+
class TestBuilder extends BaseBuilder {
|
|
7
|
+
async build() {
|
|
8
|
+
// no-op
|
|
9
|
+
}
|
|
10
|
+
createSourceStepRegistrations(inputFiles, outfile, discoveredEntries) {
|
|
11
|
+
return this.createStepsBundle({
|
|
12
|
+
inputFiles,
|
|
13
|
+
outfile,
|
|
14
|
+
externalizeNonSteps: true,
|
|
15
|
+
bundleTransitiveLocalStepDependencies: false,
|
|
16
|
+
sourceStepRegistrationImports: true,
|
|
17
|
+
discoveredEntries,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const realTmpdir = realpathSync(tmpdir());
|
|
22
|
+
function writeFile(path, contents) {
|
|
23
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
24
|
+
writeFileSync(path, contents, 'utf-8');
|
|
25
|
+
}
|
|
26
|
+
function createBuilder(workingDir) {
|
|
27
|
+
const config = {
|
|
28
|
+
buildTarget: 'standalone',
|
|
29
|
+
workingDir,
|
|
30
|
+
dirs: ['.'],
|
|
31
|
+
stepsBundlePath: join(workingDir, '.workflow', 'steps.js'),
|
|
32
|
+
workflowsBundlePath: join(workingDir, '.workflow', 'workflows.js'),
|
|
33
|
+
webhookBundlePath: join(workingDir, '.workflow', 'webhook.js'),
|
|
34
|
+
};
|
|
35
|
+
return new TestBuilder(config);
|
|
36
|
+
}
|
|
37
|
+
describe('step source registration', () => {
|
|
38
|
+
let testRoot;
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
testRoot = mkdtempSync(join(realTmpdir, 'workflow-step-registration-'));
|
|
41
|
+
writeFile(join(testRoot, 'node_modules', 'workflow', 'package.json'), JSON.stringify({ name: 'workflow', version: '1.0.0' }));
|
|
42
|
+
writeFile(join(testRoot, 'node_modules', 'workflow', 'internal', 'builtins.js'), 'export const __builtins = true;\n');
|
|
43
|
+
});
|
|
44
|
+
afterEach(() => {
|
|
45
|
+
rmSync(testRoot, { recursive: true, force: true });
|
|
46
|
+
});
|
|
47
|
+
it('imports serde-only files for step context class registration', async () => {
|
|
48
|
+
const entryFile = join(testRoot, 'src', 'entry.ts');
|
|
49
|
+
const stepFile = join(testRoot, 'src', 'step.ts');
|
|
50
|
+
const serdeFile = join(testRoot, 'src', 'serde.ts');
|
|
51
|
+
const outfile = join(testRoot, '.workflow', 'steps.js');
|
|
52
|
+
mkdirSync(dirname(outfile), { recursive: true });
|
|
53
|
+
writeFile(entryFile, `export { runStep } from './step';\n`);
|
|
54
|
+
writeFile(stepFile, `export async function runStep() {
|
|
55
|
+
'use step';
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
58
|
+
`);
|
|
59
|
+
writeFile(serdeFile, `export class Value {
|
|
60
|
+
static classId = 'Value';
|
|
61
|
+
static [Symbol.for('workflow-serialize')](value: Value) {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
static [Symbol.for('workflow-deserialize')](value: Value) {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
`);
|
|
69
|
+
const discoveredEntries = {
|
|
70
|
+
discoveredSteps: new Set([stepFile]),
|
|
71
|
+
discoveredWorkflows: new Set(),
|
|
72
|
+
discoveredSerdeFiles: new Set([serdeFile]),
|
|
73
|
+
};
|
|
74
|
+
const { manifest } = await createBuilder(testRoot).createSourceStepRegistrations([entryFile], outfile, discoveredEntries);
|
|
75
|
+
const generated = readFileSync(outfile, 'utf-8');
|
|
76
|
+
expect(generated).toContain('import "workflow/internal/builtins";');
|
|
77
|
+
expect(generated).toContain('import "../src/step.ts";');
|
|
78
|
+
expect(generated).toContain('import "../src/serde.ts";');
|
|
79
|
+
expect(Object.keys(manifest.classes ?? {})).toContain('src/serde.ts');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1zb3VyY2UtcmVnaXN0cmF0aW9uLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3RlcC1zb3VyY2UtcmVnaXN0cmF0aW9uLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxXQUFXLEVBQ1gsWUFBWSxFQUNaLFlBQVksRUFDWixNQUFNLEVBQ04sYUFBYSxHQUNkLE1BQU0sU0FBUyxDQUFDO0FBQ2pCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDakMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDMUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDckUsT0FBTyxFQUFFLFdBQVcsRUFBMEIsTUFBTSxtQkFBbUIsQ0FBQztBQUd4RSxNQUFNLFdBQVksU0FBUSxXQUFXO0lBQ25DLEtBQUssQ0FBQyxLQUFLO1FBQ1QsUUFBUTtJQUNWLENBQUM7SUFFTSw2QkFBNkIsQ0FDbEMsVUFBb0IsRUFDcEIsT0FBZSxFQUNmLGlCQUFvQztRQUVwQyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztZQUM1QixVQUFVO1lBQ1YsT0FBTztZQUNQLG1CQUFtQixFQUFFLElBQUk7WUFDekIscUNBQXFDLEVBQUUsS0FBSztZQUM1Qyw2QkFBNkIsRUFBRSxJQUFJO1lBQ25DLGlCQUFpQjtTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFFRCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUUxQyxTQUFTLFNBQVMsQ0FBQyxJQUFZLEVBQUUsUUFBZ0I7SUFDL0MsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lB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RSxPQUFPLENBQUMsQ0FBQztRQUVqRCxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBUyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDcEUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFNBQVMsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3hELE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLENBQUMsMkJBQTJCLENBQUMsQ0FBQztRQUN6RCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3hFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBta2RpclN5bmMsXG4gIG1rZHRlbXBTeW5jLFxuICByZWFkRmlsZVN5bmMsXG4gIHJlYWxwYXRoU3luYyxcbiAgcm1TeW5jLFxuICB3cml0ZUZpbGVTeW5jLFxufSBmcm9tICdub2RlOmZzJztcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gJ25vZGU6b3MnO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQgeyBhZnRlckVhY2gsIGJlZm9yZUVhY2gsIGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSAndml0ZXN0JztcbmltcG9ydCB7IEJhc2VCdWlsZGVyLCB0eXBlIERpc2NvdmVyZWRFbnRyaWVzIH0gZnJvbSAnLi9iYXNlLWJ1aWxkZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBTdGFuZGFsb25lQ29uZmlnIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmNsYXNzIFRlc3RCdWlsZGVyIGV4dGVuZHMgQmFzZUJ1aWxkZXIge1xuICBhc3luYyBidWlsZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBuby1vcFxuICB9XG5cbiAgcHVibGljIGNyZWF0ZVNvdXJjZVN0ZXBSZWdpc3RyYXRpb25zKFxuICAgIGlucHV0RmlsZXM6IHN0cmluZ1tdLFxuICAgIG91dGZpbGU6IHN0cmluZyxcbiAgICBkaXNjb3ZlcmVkRW50cmllczogRGlzY292ZXJlZEVudHJpZXNcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlU3RlcHNCdW5kbGUoe1xuICAgICAgaW5wdXRGaWxlcyxcbiAgICAgIG91dGZpbGUsXG4gICAgICBleHRlcm5hbGl6ZU5vblN0ZXBzOiB0cnVlLFxuICAgICAgYnVuZGxlVHJhbnNpdGl2ZUxvY2FsU3RlcERlcGVuZGVuY2llczogZmFsc2UsXG4gICAgICBzb3VyY2VTdGVwUmVnaXN0cmF0aW9uSW1wb3J0czogdHJ1ZSxcbiAgICAgIGRpc2NvdmVyZWRFbnRyaWVzLFxuICAgIH0pO1xuICB9XG59XG5cbmNvbnN0IHJlYWxUbXBkaXIgPSByZWFscGF0aFN5bmModG1wZGlyKCkpO1xuXG5mdW5jdGlvbiB3cml0ZUZpbGUocGF0aDogc3RyaW5nLCBjb250ZW50czogc3RyaW5nKTogdm9pZCB7XG4gIG1rZGlyU3luYyhkaXJuYW1lKHBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgd3JpdGVGaWxlU3luYyhwYXRoLCBjb250ZW50cywgJ3V0Zi04Jyk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1aWxkZXIod29ya2luZ0Rpcjogc3RyaW5nKTogVGVzdEJ1aWxkZXIge1xuICBjb25zdCBjb25maWc6IFN0YW5kYWxvbmVDb25maWcgPSB7XG4gICAgYnVpbGRUYXJnZXQ6ICdzdGFuZGFsb25lJyxcbiAgICB3b3JraW5nRGlyLFxuICAgIGRpcnM6IFsnLiddLFxuICAgIHN0ZXBzQnVuZGxlUGF0aDogam9pbih3b3JraW5nRGlyLCAnLndvcmtmbG93JywgJ3N0ZXBzLmpzJyksXG4gICAgd29ya2Zsb3dzQnVuZGxlUGF0aDogam9pbih3b3JraW5nRGlyLCAnLndvcmtmbG93JywgJ3dvcmtmbG93cy5qcycpLFxuICAgIHdlYmhvb2tCdW5kbGVQYXRoOiBqb2luKHdvcmtpbmdEaXIsICcud29ya2Zsb3cnLCAnd2ViaG9vay5qcycpLFxuICB9O1xuICByZXR1cm4gbmV3IFRlc3RCdWlsZGVyKGNvbmZpZyk7XG59XG5cbmRlc2NyaWJlKCdzdGVwIHNvdXJjZSByZWdpc3RyYXRpb24nLCAoKSA9PiB7XG4gIGxldCB0ZXN0Um9vdDogc3RyaW5nO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIHRlc3RSb290ID0gbWtkdGVtcFN5bmMoam9pbihyZWFsVG1wZGlyLCAnd29ya2Zsb3ctc3RlcC1yZWdpc3RyYXRpb24tJykpO1xuICAgIHdyaXRlRmlsZShcbiAgICAgIGpvaW4odGVzdFJvb3QsICdub2RlX21vZHVsZXMnLCAnd29ya2Zsb3cnLCAncGFja2FnZS5qc29uJyksXG4gICAgICBKU09OLnN0cmluZ2lmeSh7IG5hbWU6ICd3b3JrZmxvdycsIHZlcnNpb246ICcxLjAuMCcgfSlcbiAgICApO1xuICAgIHdyaXRlRmlsZShcbiAgICAgIGpvaW4odGVzdFJvb3QsICdub2RlX21vZHVsZXMnLCAnd29ya2Zsb3cnLCAnaW50ZXJuYWwnLCAnYnVpbHRpbnMuanMnKSxcbiAgICAgICdleHBvcnQgY29uc3QgX19idWlsdGlucyA9IHRydWU7XFxuJ1xuICAgICk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgcm1TeW5jKHRlc3RSb290LCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gIH0pO1xuXG4gIGl0KCdpbXBvcnRzIHNlcmRlLW9ubHkgZmlsZXMgZm9yIHN0ZXAgY29udGV4dCBjbGFzcyByZWdpc3RyYXRpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZW50cnlGaWxlID0gam9pbih0ZXN0Um9vdCwgJ3NyYycsICdlbnRyeS50cycpO1xuICAgIGNvbnN0IHN0ZXBGaWxlID0gam9pbih0ZXN0Um9vdCwgJ3NyYycsICdzdGVwLnRzJyk7XG4gICAgY29uc3Qgc2VyZGVGaWxlID0gam9pbih0ZXN0Um9vdCwgJ3NyYycsICdzZXJkZS50cycpO1xuICAgIGNvbnN0IG91dGZpbGUgPSBqb2luKHRlc3RSb290LCAnLndvcmtmbG93JywgJ3N0ZXBzLmpzJyk7XG5cbiAgICBta2RpclN5bmMoZGlybmFtZShvdXRmaWxlKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgd3JpdGVGaWxlKGVudHJ5RmlsZSwgYGV4cG9ydCB7IHJ1blN0ZXAgfSBmcm9tICcuL3N0ZXAnO1xcbmApO1xuICAgIHdyaXRlRmlsZShcbiAgICAgIHN0ZXBGaWxlLFxuICAgICAgYGV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5TdGVwKCkge1xuICAndXNlIHN0ZXAnO1xuICByZXR1cm4gMTtcbn1cbmBcbiAgICApO1xuICAgIHdyaXRlRmlsZShcbiAgICAgIHNlcmRlRmlsZSxcbiAgICAgIGBleHBvcnQgY2xhc3MgVmFsdWUge1xuICBzdGF0aWMgY2xhc3NJZCA9ICdWYWx1ZSc7XG4gIHN0YXRpYyBbU3ltYm9sLmZvcignd29ya2Zsb3ctc2VyaWFsaXplJyldKHZhbHVlOiBWYWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBzdGF0aWMgW1N5bWJvbC5mb3IoJ3dvcmtmbG93LWRlc2VyaWFsaXplJyldKHZhbHVlOiBWYWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuYFxuICAgICk7XG5cbiAgICBjb25zdCBkaXNjb3ZlcmVkRW50cmllczogRGlzY292ZXJlZEVudHJpZXMgPSB7XG4gICAgICBkaXNjb3ZlcmVkU3RlcHM6IG5ldyBTZXQoW3N0ZXBGaWxlXSksXG4gICAgICBkaXNjb3ZlcmVkV29ya2Zsb3dzOiBuZXcgU2V0KCksXG4gICAgICBkaXNjb3ZlcmVkU2VyZGVGaWxlczogbmV3IFNldChbc2VyZGVGaWxlXSksXG4gICAgfTtcblxuICAgIGNvbnN0IHsgbWFuaWZlc3QgfSA9IGF3YWl0IGNyZWF0ZUJ1aWxkZXIoXG4gICAgICB0ZXN0Um9vdFxuICAgICkuY3JlYXRlU291cmNlU3RlcFJlZ2lzdHJhdGlvbnMoW2VudHJ5RmlsZV0sIG91dGZpbGUsIGRpc2NvdmVyZWRFbnRyaWVzKTtcbiAgICBjb25zdCBnZW5lcmF0ZWQgPSByZWFkRmlsZVN5bmMob3V0ZmlsZSwgJ3V0Zi04Jyk7XG5cbiAgICBleHBlY3QoZ2VuZXJhdGVkKS50b0NvbnRhaW4oJ2ltcG9ydCBcIndvcmtmbG93L2ludGVybmFsL2J1aWx0aW5zXCI7Jyk7XG4gICAgZXhwZWN0KGdlbmVyYXRlZCkudG9Db250YWluKCdpbXBvcnQgXCIuLi9zcmMvc3RlcC50c1wiOycpO1xuICAgIGV4cGVjdChnZW5lcmF0ZWQpLnRvQ29udGFpbignaW1wb3J0IFwiLi4vc3JjL3NlcmRlLnRzXCI7Jyk7XG4gICAgZXhwZWN0KE9iamVjdC5rZXlzKG1hbmlmZXN0LmNsYXNzZXMgPz8ge30pKS50b0NvbnRhaW4oJ3NyYy9zZXJkZS50cycpO1xuICB9KTtcbn0pO1xuIl19
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import type { Plugin } from 'esbuild';
|
|
2
2
|
import { type WorkflowManifest } from './apply-swc-transform.js';
|
|
3
|
+
export interface WorkflowTransformResult {
|
|
4
|
+
readonly mode: 'step' | 'workflow';
|
|
5
|
+
readonly filename: string;
|
|
6
|
+
readonly absolutePath: string;
|
|
7
|
+
readonly source: string;
|
|
8
|
+
readonly code: string;
|
|
9
|
+
readonly workflowManifest: WorkflowManifest;
|
|
10
|
+
}
|
|
11
|
+
export type WorkflowAfterTransformHook = (result: WorkflowTransformResult) => void | Promise<void>;
|
|
3
12
|
export interface SwcPluginOptions {
|
|
4
13
|
mode: 'step' | 'workflow';
|
|
5
14
|
entriesToBundle?: string[];
|
|
6
15
|
outdir?: string;
|
|
7
16
|
projectRoot?: string;
|
|
17
|
+
moduleSpecifierRoot?: string;
|
|
8
18
|
workflowManifest?: WorkflowManifest;
|
|
19
|
+
/**
|
|
20
|
+
* Optional observer invoked after a transform's manifest entries have been
|
|
21
|
+
* accepted. A file may be observed multiple times across modes, bundles, and
|
|
22
|
+
* watch rebuilds. The observer is awaited, cannot replace the generated code,
|
|
23
|
+
* and aborts the build if it throws.
|
|
24
|
+
*/
|
|
25
|
+
onAfterTransform?: WorkflowAfterTransformHook;
|
|
9
26
|
/**
|
|
10
27
|
* Rewrite TypeScript extensions (.ts, .tsx, .mts, .cts) to their JS
|
|
11
28
|
* equivalents (.js, .mjs, .cjs) in externalized import paths.
|
|
@@ -18,6 +35,15 @@ export interface SwcPluginOptions {
|
|
|
18
35
|
* breaks them because the .js file doesn't exist on disk.
|
|
19
36
|
*/
|
|
20
37
|
rewriteTsExtensions?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Bundle project-local files that are transitively imported by step entries.
|
|
40
|
+
*
|
|
41
|
+
* Keep this disabled when a downstream bundler consumes the generated step
|
|
42
|
+
* bundle because that bundler can resolve the externalized local imports.
|
|
43
|
+
* Enable it for direct runtime loading, where Node imports the generated step
|
|
44
|
+
* bundle from disk without a later bundling pass.
|
|
45
|
+
*/
|
|
46
|
+
bundleTransitiveLocalStepDependencies?: boolean;
|
|
21
47
|
/**
|
|
22
48
|
* Absolute file paths of discovered workflow/step/serde entries whose
|
|
23
49
|
* imports must be treated as side-effectful.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swc-esbuild-plugin.d.ts","sourceRoot":"","sources":["../src/swc-esbuild-plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"swc-esbuild-plugin.d.ts","sourceRoot":"","sources":["../src/swc-esbuild-plugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAQlC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;CAC7C;AAED,MAAM,MAAM,0BAA0B,GAAG,CACvC,MAAM,EAAE,uBAAuB,KAC5B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,0BAA0B,CAAC;IAC9C;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;OAOG;IACH,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAkHD,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CA6XjE"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { relative } from 'node:path';
|
|
3
3
|
import { promisify } from 'node:util';
|
|
4
|
+
import { WorkflowBuildError } from '@workflow/errors';
|
|
4
5
|
import enhancedResolveOrig from 'enhanced-resolve';
|
|
5
6
|
import { applySwcTransform, } from './apply-swc-transform.js';
|
|
6
7
|
import { jsTsRegex, parentHasChild, } from './discover-entries-esbuild-plugin.js';
|
|
8
|
+
import { resolveModuleSpecifier } from './module-specifier.js';
|
|
7
9
|
import { resolveWorkflowAliasRelativePath } from './workflow-alias.js';
|
|
8
10
|
const NODE_RESOLVE_OPTIONS = {
|
|
9
11
|
dependencyType: 'commonjs',
|
|
@@ -39,10 +41,59 @@ const NODE_ESM_RESOLVE_OPTIONS = {
|
|
|
39
41
|
dependencyType: 'esm',
|
|
40
42
|
conditionNames: ['node', 'import'],
|
|
41
43
|
};
|
|
44
|
+
function normalizePath(path) {
|
|
45
|
+
return path.replace(/\\/g, '/');
|
|
46
|
+
}
|
|
47
|
+
function formatIdLocation(location) {
|
|
48
|
+
return `${location.filePath}#${location.name}`;
|
|
49
|
+
}
|
|
50
|
+
function assertUniqueManifestIds(entriesByFile, ids, getId, label) {
|
|
51
|
+
const entriesByFileList = Object.entries(entriesByFile || {});
|
|
52
|
+
for (const [filePath, entries] of entriesByFileList) {
|
|
53
|
+
for (const [name, data] of Object.entries(entries)) {
|
|
54
|
+
const id = getId(data);
|
|
55
|
+
const existing = ids.get(id);
|
|
56
|
+
const current = { filePath, name };
|
|
57
|
+
if (existing &&
|
|
58
|
+
(existing.filePath !== current.filePath ||
|
|
59
|
+
existing.name !== current.name)) {
|
|
60
|
+
const idName = label === 'step' ? 'workflow step ID' : 'workflow ID';
|
|
61
|
+
const functionName = `${label} function`;
|
|
62
|
+
const capitalizedLabel = label === 'step' ? 'Step' : 'Workflow';
|
|
63
|
+
throw new WorkflowBuildError(`Duplicate ${idName} "${id}" generated for ${formatIdLocation(existing)} and ${formatIdLocation(current)}.`, {
|
|
64
|
+
hint: `${capitalizedLabel} IDs must be unique across a build. ` +
|
|
65
|
+
`If you own one of the colliding files, rename the ${functionName} or export ` +
|
|
66
|
+
`the package file through a unique package subpath. If the collision is in a ` +
|
|
67
|
+
`transitive dependency you don't control, file an issue with the upstream ` +
|
|
68
|
+
`package or pin to a non-colliding version.`,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
ids.set(id, current);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function mergeWorkflowManifest(target, incoming, stepIds, workflowIds) {
|
|
76
|
+
assertUniqueManifestIds(incoming.steps, stepIds, (data) => data.stepId, 'step');
|
|
77
|
+
assertUniqueManifestIds(incoming.workflows, workflowIds, (data) => data.workflowId, 'workflow');
|
|
78
|
+
target.workflows = Object.assign(target.workflows || {}, incoming.workflows);
|
|
79
|
+
target.steps = Object.assign(target.steps || {}, incoming.steps);
|
|
80
|
+
target.classes = Object.assign(target.classes || {}, incoming.classes);
|
|
81
|
+
}
|
|
42
82
|
export function createSwcPlugin(options) {
|
|
43
83
|
return {
|
|
44
84
|
name: 'swc-workflow-plugin',
|
|
45
85
|
setup(build) {
|
|
86
|
+
let stepIdsForCurrentBuild = new Map();
|
|
87
|
+
let workflowIdsForCurrentBuild = new Map();
|
|
88
|
+
build.onStart(() => {
|
|
89
|
+
stepIdsForCurrentBuild = new Map();
|
|
90
|
+
workflowIdsForCurrentBuild = new Map();
|
|
91
|
+
if (options.workflowManifest) {
|
|
92
|
+
delete options.workflowManifest.steps;
|
|
93
|
+
delete options.workflowManifest.workflows;
|
|
94
|
+
delete options.workflowManifest.classes;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
46
97
|
// everything is external unless explicitly configured
|
|
47
98
|
// to be bundled
|
|
48
99
|
const cjsResolver = promisify(enhancedResolveOrig.create(NODE_RESOLVE_OPTIONS));
|
|
@@ -75,17 +126,33 @@ export function createSwcPlugin(options) {
|
|
|
75
126
|
const specifier = args.path;
|
|
76
127
|
const specifierIsPath = specifier.startsWith('.') || specifier.startsWith('/');
|
|
77
128
|
let resolvedPath;
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
|
|
129
|
+
// Path-style specifiers (./foo, ../foo, /abs/path) externalize as
|
|
130
|
+
// relative paths from `outdir`. Bare specifiers (npm packages)
|
|
131
|
+
// externalize as-is so Node can resolve them at runtime.
|
|
132
|
+
const shouldMakeRelative = specifierIsPath;
|
|
81
133
|
if (specifierIsPath) {
|
|
82
134
|
resolvedPath = await enhancedResolve(args.resolveDir, specifier);
|
|
83
135
|
}
|
|
84
136
|
else {
|
|
85
137
|
// Resolve from project root so nested deps aren't externalized
|
|
86
138
|
resolvedPath = await enhancedResolve(build.initialOptions.absWorkingDir || process.cwd(), specifier).catch(() => undefined); // swallow so esbuild fallback below can try
|
|
87
|
-
// Fall back to esbuild for aliases/tsconfig paths
|
|
88
|
-
//
|
|
139
|
+
// Fall back to esbuild for aliases/tsconfig paths.
|
|
140
|
+
//
|
|
141
|
+
// If the specifier resolves to a project-local file via an
|
|
142
|
+
// alias/path mapping (e.g. tsconfig `paths`, esbuild `alias`,
|
|
143
|
+
// self-referencing package names like `@my-pkg/lib/foo`), we
|
|
144
|
+
// bundle it inline rather than externalizing.
|
|
145
|
+
//
|
|
146
|
+
// Externalizing such files is unsafe: we'd emit a relative
|
|
147
|
+
// import to the original source on disk, but that source can
|
|
148
|
+
// contain further alias imports. At runtime, Node's ESM loader
|
|
149
|
+
// doesn't know about tsconfig paths or build-time aliases, so
|
|
150
|
+
// those transitive imports throw `ERR_MODULE_NOT_FOUND` /
|
|
151
|
+
// `Package subpath ... is not defined by "exports"`.
|
|
152
|
+
//
|
|
153
|
+
// Bundling inline ensures alias-based imports are resolved at
|
|
154
|
+
// build time (where the alias map is known) and the runtime
|
|
155
|
+
// never sees an unresolvable specifier.
|
|
89
156
|
if (!resolvedPath) {
|
|
90
157
|
const esbuildResult = await build.resolve(specifier, {
|
|
91
158
|
resolveDir: args.resolveDir,
|
|
@@ -99,15 +166,34 @@ export function createSwcPlugin(options) {
|
|
|
99
166
|
.replace(/\\/g, '/')
|
|
100
167
|
.includes('/node_modules/');
|
|
101
168
|
if (isProjectLocalFile) {
|
|
102
|
-
|
|
103
|
-
|
|
169
|
+
// Let esbuild bundle this aliased project-local file inline
|
|
170
|
+
// (return null to defer to esbuild's normal pipeline). The
|
|
171
|
+
// SWC `onLoad` handler will still process it.
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
else if (options.entriesToBundle &&
|
|
175
|
+
esbuildResult.path?.endsWith('.node')) {
|
|
176
|
+
return {
|
|
177
|
+
external: true,
|
|
178
|
+
path: specifier,
|
|
179
|
+
};
|
|
104
180
|
}
|
|
105
181
|
}
|
|
106
182
|
}
|
|
107
183
|
if (!resolvedPath)
|
|
108
184
|
return null;
|
|
109
185
|
// Normalize to forward slashes for cross-platform comparison
|
|
110
|
-
const normalizedResolvedPath = resolvedPath
|
|
186
|
+
const normalizedResolvedPath = normalizePath(resolvedPath);
|
|
187
|
+
const workingDir = build.initialOptions.absWorkingDir || process.cwd();
|
|
188
|
+
const projectRoot = options.projectRoot || workingDir;
|
|
189
|
+
const moduleSpecifierRoot = options.moduleSpecifierRoot || projectRoot;
|
|
190
|
+
if (options.entriesToBundle &&
|
|
191
|
+
normalizedResolvedPath.endsWith('.node')) {
|
|
192
|
+
return {
|
|
193
|
+
external: true,
|
|
194
|
+
path: specifier,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
111
197
|
// Check if this module is a discovered entry whose SWC-transformed
|
|
112
198
|
// code contains side effects (workflow/step/class registration).
|
|
113
199
|
// Override the package.json "sideEffects": false so esbuild does not
|
|
@@ -128,6 +214,17 @@ export function createSwcPlugin(options) {
|
|
|
128
214
|
shouldBundle = true;
|
|
129
215
|
break;
|
|
130
216
|
}
|
|
217
|
+
// Bundle project-local source files that are imported by a
|
|
218
|
+
// step/serde entry so direct runtime loaders do not see raw TS
|
|
219
|
+
// extensionless imports. Keep package dependencies external
|
|
220
|
+
// unless they are themselves in entriesToBundle or are parents
|
|
221
|
+
// of a discovered workflow/step/serde file via the check above.
|
|
222
|
+
if (options.bundleTransitiveLocalStepDependencies &&
|
|
223
|
+
isProjectLocalFile(normalizedResolvedPath, moduleSpecifierRoot) &&
|
|
224
|
+
parentHasChild(normalizedEntry, normalizedResolvedPath)) {
|
|
225
|
+
shouldBundle = true;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
131
228
|
}
|
|
132
229
|
if (shouldBundle) {
|
|
133
230
|
// Let esbuild bundle this entry, but override sideEffects if needed.
|
|
@@ -201,6 +298,7 @@ export function createSwcPlugin(options) {
|
|
|
201
298
|
// The filename parameter is used to generate workflowId/stepId, so it must be relative
|
|
202
299
|
const workingDir = build.initialOptions.absWorkingDir || process.cwd();
|
|
203
300
|
const projectRoot = options.projectRoot || workingDir;
|
|
301
|
+
const moduleSpecifierRoot = options.moduleSpecifierRoot || projectRoot;
|
|
204
302
|
// Normalize paths: convert backslashes to forward slashes and remove trailing slashes
|
|
205
303
|
const normalizedWorkingDir = workingDir
|
|
206
304
|
.replace(/\\/g, '/')
|
|
@@ -212,7 +310,7 @@ export function createSwcPlugin(options) {
|
|
|
212
310
|
const lowerWd = normalizedWorkingDir.toLowerCase();
|
|
213
311
|
const lowerPath = normalizedPath.toLowerCase();
|
|
214
312
|
let relativeFilepath;
|
|
215
|
-
if (lowerPath.startsWith(lowerWd
|
|
313
|
+
if (lowerPath.startsWith(`${lowerWd}/`)) {
|
|
216
314
|
// File is under working directory - manually calculate relative path
|
|
217
315
|
// This ensures we get a relative path even with drive letter casing issues
|
|
218
316
|
relativeFilepath = normalizedPath.substring(normalizedWorkingDir.length + 1);
|
|
@@ -247,13 +345,19 @@ export function createSwcPlugin(options) {
|
|
|
247
345
|
relativeFilepath = normalizedPath.split('/').pop() || 'unknown.ts';
|
|
248
346
|
}
|
|
249
347
|
const { code: transformedCode, workflowManifest } = await applySwcTransform(relativeFilepath, normalizedSource, options.mode, args.path, // Pass absolute path for module specifier resolution
|
|
250
|
-
projectRoot);
|
|
348
|
+
projectRoot, moduleSpecifierRoot);
|
|
251
349
|
if (!options.workflowManifest) {
|
|
252
350
|
options.workflowManifest = {};
|
|
253
351
|
}
|
|
254
|
-
options.workflowManifest
|
|
255
|
-
options.
|
|
256
|
-
|
|
352
|
+
mergeWorkflowManifest(options.workflowManifest, workflowManifest, stepIdsForCurrentBuild, workflowIdsForCurrentBuild);
|
|
353
|
+
await options.onAfterTransform?.({
|
|
354
|
+
mode: options.mode,
|
|
355
|
+
filename: relativeFilepath,
|
|
356
|
+
absolutePath: args.path,
|
|
357
|
+
source: normalizedSource,
|
|
358
|
+
code: transformedCode,
|
|
359
|
+
workflowManifest,
|
|
360
|
+
});
|
|
257
361
|
return {
|
|
258
362
|
contents: transformedCode,
|
|
259
363
|
loader,
|
|
@@ -275,4 +379,10 @@ export function createSwcPlugin(options) {
|
|
|
275
379
|
},
|
|
276
380
|
};
|
|
277
381
|
}
|
|
278
|
-
|
|
382
|
+
function isProjectLocalFile(filePath, projectRoot) {
|
|
383
|
+
if (normalizePath(filePath).includes('/node_modules/')) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
return (resolveModuleSpecifier(filePath, projectRoot).moduleSpecifier === undefined);
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3djLWVzYnVpbGQtcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3N3Yy1lc2J1aWxkLXBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNyQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3RELE9BQU8sbUJBQW1CLE1BQU0sa0JBQWtCLENBQUM7QUFFbkQsT0FBTyxFQUNMLGlCQUFpQixHQUVsQixNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsY0FBYyxHQUNmLE1BQU0sc0NBQXNDLENBQUM7QUFDOUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUE4RHZFLE1BQU0sb0JBQW9CLEdBQUc7SUFDM0IsY0FBYyxFQUFFLFVBQVU7SUFDMUIsT0FBTyxFQUFFLENBQUMsY0FBYyxDQUFDO0lBQ3pCLGFBQWEsRUFBRSxDQUFDLFNBQVMsQ0FBQztJQUMxQixhQUFhLEVBQUUsQ0FBQyxTQUFTLENBQUM7SUFDMUIsY0FBYyxFQUFFLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQztJQUNuQyxnQkFBZ0IsRUFBRSxDQUFDLGNBQWMsQ0FBQztJQUNsQyxVQUFVLEVBQUU7UUFDVixLQUFLO1FBQ0wsTUFBTTtRQUNOLE1BQU07UUFDTixNQUFNO1FBQ04sTUFBTTtRQUNOLE1BQU07UUFDTixLQUFLO1FBQ0wsTUFBTTtRQUNOLE9BQU87UUFDUCxPQUFPO0tBQ1I7SUFDRCxpQkFBaUIsRUFBRSxLQUFLO0lBQ3hCLFFBQVEsRUFBRSxJQUFJO0lBQ2Qs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bEQ7eUJBQ0Y7cUJBQ0YsQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGtCQUFrQixDQUFDLFFBQWdCLEVBQUUsV0FBbUI7SUFDL0QsSUFBSSxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztRQUN2RCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxPQUFPLENBQ0wsc0JBQXNCLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDLGVBQWUsS0FBSyxTQUFTLENBQzVFLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IHJlbGF0aXZlIH0gZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IHByb21pc2lmeSB9IGZyb20gJ25vZGU6dXRpbCc7XG5pbXBvcnQgeyBXb3JrZmxvd0J1aWxkRXJyb3IgfSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCBlbmhhbmNlZFJlc29sdmVPcmlnIGZyb20gJ2VuaGFuY2VkLXJlc29sdmUnO1xuaW1wb3J0IHR5cGUgeyBQbHVnaW4gfSBmcm9tICdlc2J1aWxkJztcbmltcG9ydCB7XG4gIGFwcGx5U3djVHJhbnNmb3JtLFxuICB0eXBlIFdvcmtmbG93TWFuaWZlc3QsXG59IGZyb20gJy4vYXBwbHktc3djLXRyYW5zZm9ybS5qcyc7XG5pbXBvcnQge1xuICBqc1RzUmVnZXgsXG4gIHBhcmVudEhhc0NoaWxkLFxufSBmcm9tICcuL2Rpc2NvdmVyLWVudHJpZXMtZXNidWlsZC1wbHVnaW4uanMnO1xuaW1wb3J0IHsgcmVzb2x2ZU1vZHVsZVNwZWNpZmllciB9IGZyb20gJy4vbW9kdWxlLXNwZWNpZmllci5qcyc7XG5pbXBvcnQgeyByZXNvbHZlV29ya2Zsb3dBbGlhc1JlbGF0aXZlUGF0aCB9IGZyb20gJy4vd29ya2Zsb3ctYWxpYXMuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtmbG93VHJhbnNmb3JtUmVzdWx0IHtcbiAgcmVhZG9ubHkgbW9kZTogJ3N0ZXAnIHwgJ3dvcmtmbG93JztcbiAgcmVhZG9ubHkgZmlsZW5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgYWJzb2x1dGVQYXRoOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNvdXJjZTogc3RyaW5nO1xuICByZWFkb25seSBjb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdvcmtmbG93TWFuaWZlc3Q6IFdvcmtmbG93TWFuaWZlc3Q7XG59XG5cbmV4cG9ydCB0eXBlIFdvcmtmbG93QWZ0ZXJUcmFuc2Zvcm1Ib29rID0gKFxuICByZXN1bHQ6IFdvcmtmbG93VHJhbnNmb3JtUmVzdWx0XG4pID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuXG5leHBvcnQgaW50ZXJmYWNlIFN3Y1BsdWdpbk9wdGlvbnMge1xuICBtb2RlOiAnc3RlcCcgfCAnd29ya2Zsb3cnO1xuICBlbnRyaWVzVG9CdW5kbGU/OiBzdHJpbmdbXTtcbiAgb3V0ZGlyPzogc3RyaW5nO1xuICBwcm9qZWN0Um9vdD86IHN0cmluZztcbiAgbW9kdWxlU3BlY2lmaWVyUm9vdD86IHN0cmluZztcbiAgd29ya2Zsb3dNYW5pZmVzdD86IFdvcmtmbG93TWFuaWZlc3Q7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBvYnNlcnZlciBpbnZva2VkIGFmdGVyIGEgdHJhbnNmb3JtJ3MgbWFuaWZlc3QgZW50cmllcyBoYXZlIGJlZW5cbiAgICogYWNjZXB0ZWQuIEEgZmlsZSBtYXkgYmUgb2JzZXJ2ZWQgbXVsdGlwbGUgdGltZXMgYWNyb3NzIG1vZGVzLCBidW5kbGVzLCBhbmRcbiAgICogd2F0Y2ggcmVidWlsZHMuIFRoZSBvYnNlcnZlciBpcyBhd2FpdGVkLCBjYW5ub3QgcmVwbGFjZSB0aGUgZ2VuZXJhdGVkIGNvZGUsXG4gICAqIGFuZCBhYm9ydHMgdGhlIGJ1aWxkIGlmIGl0IHRocm93cy5cbiAgICovXG4gIG9uQWZ0ZXJUcmFuc2Zvcm0/OiBXb3JrZmxvd0FmdGVyVHJhbnNmb3JtSG9vaztcbiAgLyoqXG4gICAqIFJld3JpdGUgVHlwZVNjcmlwdCBleHRlbnNpb25zICgudHMsIC50c3gsIC5tdHMsIC5jdHMpIHRvIHRoZWlyIEpTXG4gICAqIGVxdWl2YWxlbnRzICguanMsIC5tanMsIC5janMpIGluIGV4dGVybmFsaXplZCBpbXBvcnQgcGF0aHMuXG4gICAqXG4gICAqIEVuYWJsZSB0aGlzIHdoZW4gdGhlIG91dHB1dCBidW5kbGUgaXMgY29uc3VtZWQgZGlyZWN0bHkgYnkgTm9kZSdzIG5hdGl2ZVxuICAgKiBFU00gbG9hZGVyIChlLmcuIHZpdGVzdCksIHdoaWNoIGNhbm5vdCByZXNvbHZlIC50cyBleHRlbnNpb25zLlxuICAgKlxuICAgKiBMZWF2ZSBkaXNhYmxlZCAoZGVmYXVsdCkgd2hlbiBhIGRvd25zdHJlYW0gYnVuZGxlciAod2VicGFjaywgVml0ZSwgZXRjLilcbiAgICogaGFuZGxlcyByZXNvbHV0aW9uIOKAlCB0aG9zZSB0b29scyByZXNvbHZlIC50cyBuYXRpdmVseSBhbmQgcmV3cml0aW5nXG4gICAqIGJyZWFrcyB0aGVtIGJlY2F1c2UgdGhlIC5qcyBmaWxlIGRvZXNuJ3QgZXhpc3Qgb24gZGlzay5cbiAgICovXG4gIHJld3JpdGVUc0V4dGVuc2lvbnM/OiBib29sZWFuO1xuICAvKipcbiAgICogQnVuZGxlIHByb2plY3QtbG9jYWwgZmlsZXMgdGhhdCBhcmUgdHJhbnNpdGl2ZWx5IGltcG9ydGVkIGJ5IHN0ZXAgZW50cmllcy5cbiAgICpcbiAgICogS2VlcCB0aGlzIGRpc2FibGVkIHdoZW4gYSBkb3duc3RyZWFtIGJ1bmRsZXIgY29uc3VtZXMgdGhlIGdlbmVyYXRlZCBzdGVwXG4gICAqIGJ1bmRsZSBiZWNhdXNlIHRoYXQgYnVuZGxlciBjYW4gcmVzb2x2ZSB0aGUgZXh0ZXJuYWxpemVkIGxvY2FsIGltcG9ydHMuXG4gICAqIEVuYWJsZSBpdCBmb3IgZGlyZWN0IHJ1bnRpbWUgbG9hZGluZywgd2hlcmUgTm9kZSBpbXBvcnRzIHRoZSBnZW5lcmF0ZWQgc3RlcFxuICAgKiBidW5kbGUgZnJvbSBkaXNrIHdpdGhvdXQgYSBsYXRlciBidW5kbGluZyBwYXNzLlxuICAgKi9cbiAgYnVuZGxlVHJhbnNpdGl2ZUxvY2FsU3RlcERlcGVuZGVuY2llcz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBmaWxlIHBhdGhzIG9mIGRpc2NvdmVyZWQgd29ya2Zsb3cvc3RlcC9zZXJkZSBlbnRyaWVzIHdob3NlXG4gICAqIGltcG9ydHMgbXVzdCBiZSB0cmVhdGVkIGFzIHNpZGUtZWZmZWN0ZnVsLlxuICAgKlxuICAgKiBUaGUgU1dDIGNvbXBpbGVyIHRyYW5zZm9ybSBpbmplY3RzIHJlZ2lzdHJhdGlvbiBjYWxscyAod29ya2Zsb3cgSURzLFxuICAgKiBzdGVwIElEcywgY2xhc3Mgc2VyaWFsaXphdGlvbiwgZXRjLikgaW50byB0aGVzZSBmaWxlcy4gV2l0aG91dCB0aGlzXG4gICAqIG92ZXJyaWRlLCBlc2J1aWxkIGhvbm91cnMgYFwic2lkZUVmZmVjdHNcIjogZmFsc2VgIGZyb20gdGhlIHBhY2thZ2Unc1xuICAgKiBgcGFja2FnZS5qc29uYCBhbmQgc2lsZW50bHkgZHJvcHMgYmFyZSBpbXBvcnRzIG9mIHRoZXNlIG1vZHVsZXMuXG4gICAqL1xuICBzaWRlRWZmZWN0RW50cmllcz86IHN0cmluZ1tdO1xufVxuXG5jb25zdCBOT0RFX1JFU09MVkVfT1BUSU9OUyA9IHtcbiAgZGVwZW5kZW5jeVR5cGU6ICdjb21tb25qcycsXG4gIG1vZHVsZXM6IFsnbm9kZV9tb2R1bGVzJ10sXG4gIGV4cG9ydHNGaWVsZHM6IFsnZXhwb3J0cyddLFxuICBpbXBvcnRzRmllbGRzOiBbJ2ltcG9ydHMnXSxcbiAgY29uZGl0aW9uTmFtZXM6IFsnbm9kZScsICdyZXF1aXJlJ10sXG4gIGRlc2NyaXB0aW9uRmlsZXM6IFsncGFja2FnZS5qc29uJ10sXG4gIGV4dGVuc2lvbnM6IFtcbiAgICAnLnRzJyxcbiAgICAnLnRzeCcsXG4gICAgJy5tdHMnLFxuICAgICcuY3RzJyxcbiAgICAnLmNqcycsXG4gICAgJy5tanMnLFxuICAgICcuanMnLFxuICAgICcuanN4JyxcbiAgICAnLmpzb24nLFxuICAgICcubm9kZScsXG4gIF0sXG4gIGVuZm9yY2VFeHRlbnNpb25zOiBmYWxzZSxcbiAgc3ltbGlua3M6IHRydWUsXG4gIG1haW5GaWVsZHM6IFsnbWFpbiddLFxuICBtYWluRmlsZXM6IFsnaW5kZXgnXSxcbiAgcm9vdHM6IFtdLFxuICBmdWxseVNwZWNpZmllZDogZmFsc2UsXG4gIHByZWZlclJlbGF0aXZlOiBmYWxzZSxcbiAgcHJlZmVyQWJzb2x1dGU6IGZhbHNlLFxuICByZXN0cmljdGlvbnM6IFtdLFxufTtcblxuY29uc3QgTk9ERV9FU01fUkVTT0xWRV9PUFRJT05TID0ge1xuICAuLi5OT0RFX1JFU09MVkVfT1BUSU9OUyxcbiAgZGVwZW5kZW5jeVR5cGU6ICdlc20nLFxuICBjb25kaXRpb25OYW1lczogWydub2RlJywgJ2ltcG9ydCddLFxufTtcblxuZnVuY3Rpb24gbm9ybWFsaXplUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG59XG5cbnR5cGUgSWRMb2NhdGlvbiA9IHtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xufTtcblxuZnVuY3Rpb24gZm9ybWF0SWRMb2NhdGlvbihsb2NhdGlvbjogSWRMb2NhdGlvbik6IHN0cmluZyB7XG4gIHJldHVybiBgJHtsb2NhdGlvbi5maWxlUGF0aH0jJHtsb2NhdGlvbi5uYW1lfWA7XG59XG5cbmZ1bmN0aW9uIGFzc2VydFVuaXF1ZU1hbmlmZXN0SWRzKFxuICBlbnRyaWVzQnlGaWxlOiBXb3JrZmxvd01hbmlmZXN0WydzdGVwcyddIHwgV29ya2Zsb3dNYW5pZmVzdFsnd29ya2Zsb3dzJ10sXG4gIGlkczogTWFwPHN0cmluZywgSWRMb2NhdGlvbj4sXG4gIGdldElkOiAoZGF0YTogeyBzdGVwSWQ6IHN0cmluZyB9IHwgeyB3b3JrZmxvd0lkOiBzdHJpbmcgfSkgPT4gc3RyaW5nLFxuICBsYWJlbDogJ3N0ZXAnIHwgJ3dvcmtmbG93J1xuKTogdm9pZCB7XG4gIGNvbnN0IGVudHJpZXNCeUZpbGVMaXN0ID0gT2JqZWN0LmVudHJpZXMoZW50cmllc0J5RmlsZSB8fCB7fSkgYXMgQXJyYXk8XG4gICAgW3N0cmluZywgUmVjb3JkPHN0cmluZywgeyBzdGVwSWQ6IHN0cmluZyB9IHwgeyB3b3JrZmxvd0lkOiBzdHJpbmcgfT5dXG4gID47XG4gIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBlbnRyaWVzXSBvZiBlbnRyaWVzQnlGaWxlTGlzdCkge1xuICAgIGZvciAoY29uc3QgW25hbWUsIGRhdGFdIG9mIE9iamVjdC5lbnRyaWVzKGVudHJpZXMpKSB7XG4gICAgICBjb25zdCBpZCA9IGdldElkKGRhdGEpO1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBpZHMuZ2V0KGlkKTtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSB7IGZpbGVQYXRoLCBuYW1lIH07XG4gICAgICBpZiAoXG4gICAgICAgIGV4aXN0aW5nICYmXG4gICAgICAgIChleGlzdGluZy5maWxlUGF0aCAhPT0gY3VycmVudC5maWxlUGF0aCB8fFxuICAgICAgICAgIGV4aXN0aW5nLm5hbWUgIT09IGN1cnJlbnQubmFtZSlcbiAgICAgICkge1xuICAgICAgICBjb25zdCBpZE5hbWUgPSBsYWJlbCA9PT0gJ3N0ZXAnID8gJ3dvcmtmbG93IHN0ZXAgSUQnIDogJ3dvcmtmbG93IElEJztcbiAgICAgICAgY29uc3QgZnVuY3Rpb25OYW1lID0gYCR7bGFiZWx9IGZ1bmN0aW9uYDtcbiAgICAgICAgY29uc3QgY2FwaXRhbGl6ZWRMYWJlbCA9IGxhYmVsID09PSAnc3RlcCcgPyAnU3RlcCcgOiAnV29ya2Zsb3cnO1xuICAgICAgICB0aHJvdyBuZXcgV29ya2Zsb3dCdWlsZEVycm9yKFxuICAgICAgICAgIGBEdXBsaWNhdGUgJHtpZE5hbWV9IFwiJHtpZH1cIiBnZW5lcmF0ZWQgZm9yICR7Zm9ybWF0SWRMb2NhdGlvbihleGlzdGluZyl9IGFuZCAke2Zvcm1hdElkTG9jYXRpb24oY3VycmVudCl9LmAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgaGludDpcbiAgICAgICAgICAgICAgYCR7Y2FwaXRhbGl6ZWRMYWJlbH0gSURzIG11c3QgYmUgdW5pcXVlIGFjcm9zcyBhIGJ1aWxkLiBgICtcbiAgICAgICAgICAgICAgYElmIHlvdSBvd24gb25lIG9mIHRoZSBjb2xsaWRpbmcgZmlsZXMsIHJlbmFtZSB0aGUgJHtmdW5jdGlvbk5hbWV9IG9yIGV4cG9ydCBgICtcbiAgICAgICAgICAgICAgYHRoZSBwYWNrYWdlIGZpbGUgdGhyb3VnaCBhIHVuaXF1ZSBwYWNrYWdlIHN1YnBhdGguIElmIHRoZSBjb2xsaXNpb24gaXMgaW4gYSBgICtcbiAgICAgICAgICAgICAgYHRyYW5zaXRpdmUgZGVwZW5kZW5jeSB5b3UgZG9uJ3QgY29udHJvbCwgZmlsZSBhbiBpc3N1ZSB3aXRoIHRoZSB1cHN0cmVhbSBgICtcbiAgICAgICAgICAgICAgYHBhY2thZ2Ugb3IgcGluIHRvIGEgbm9uLWNvbGxpZGluZyB2ZXJzaW9uLmAsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWRzLnNldChpZCwgY3VycmVudCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG1lcmdlV29ya2Zsb3dNYW5pZmVzdChcbiAgdGFyZ2V0OiBXb3JrZmxvd01hbmlmZXN0LFxuICBpbmNvbWluZzogV29ya2Zsb3dNYW5pZmVzdCxcbiAgc3RlcElkczogTWFwPHN0cmluZywgSWRMb2NhdGlvbj4sXG4gIHdvcmtmbG93SWRzOiBNYXA8c3RyaW5nLCBJZExvY2F0aW9uPlxuKTogdm9pZCB7XG4gIGFzc2VydFVuaXF1ZU1hbmlmZXN0SWRzKFxuICAgIGluY29taW5nLnN0ZXBzLFxuICAgIHN0ZXBJZHMsXG4gICAgKGRhdGEpID0+IChkYXRhIGFzIHsgc3RlcElkOiBzdHJpbmcgfSkuc3RlcElkLFxuICAgICdzdGVwJ1xuICApO1xuICBhc3NlcnRVbmlxdWVNYW5pZmVzdElkcyhcbiAgICBpbmNvbWluZy53b3JrZmxvd3MsXG4gICAgd29ya2Zsb3dJZHMsXG4gICAgKGRhdGEpID0+IChkYXRhIGFzIHsgd29ya2Zsb3dJZDogc3RyaW5nIH0pLndvcmtmbG93SWQsXG4gICAgJ3dvcmtmbG93J1xuICApO1xuXG4gIHRhcmdldC53b3JrZmxvd3MgPSBPYmplY3QuYXNzaWduKHRhcmdldC53b3JrZmxvd3MgfHwge30sIGluY29taW5nLndvcmtmbG93cyk7XG4gIHRhcmdldC5zdGVwcyA9IE9iamVjdC5hc3NpZ24odGFyZ2V0LnN0ZXBzIHx8IHt9LCBpbmNvbWluZy5zdGVwcyk7XG4gIHRhcmdldC5jbGFzc2VzID0gT2JqZWN0LmFzc2lnbih0YXJnZXQuY2xhc3NlcyB8fCB7fSwgaW5jb21pbmcuY2xhc3Nlcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTd2NQbHVnaW4ob3B0aW9uczogU3djUGx1Z2luT3B0aW9ucyk6IFBsdWdpbiB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogJ3N3Yy13b3JrZmxvdy1wbHVnaW4nLFxuICAgIHNldHVwKGJ1aWxkKSB7XG4gICAgICBsZXQgc3RlcElkc0ZvckN1cnJlbnRCdWlsZCA9IG5ldyBNYXA8c3RyaW5nLCBJZExvY2F0aW9uPigpO1xuICAgICAgbGV0IHdvcmtmbG93SWRzRm9yQ3VycmVudEJ1aWxkID0gbmV3IE1hcDxzdHJpbmcsIElkTG9jYXRpb24+KCk7XG5cbiAgICAgIGJ1aWxkLm9uU3RhcnQoKCkgPT4ge1xuICAgICAgICBzdGVwSWRzRm9yQ3VycmVudEJ1aWxkID0gbmV3IE1hcCgpO1xuICAgICAgICB3b3JrZmxvd0lkc0ZvckN1cnJlbnRCdWlsZCA9IG5ldyBNYXAoKTtcbiAgICAgICAgaWYgKG9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdCkge1xuICAgICAgICAgIGRlbGV0ZSBvcHRpb25zLndvcmtmbG93TWFuaWZlc3Quc3RlcHM7XG4gICAgICAgICAgZGVsZXRlIG9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdC53b3JrZmxvd3M7XG4gICAgICAgICAgZGVsZXRlIG9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdC5jbGFzc2VzO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gZXZlcnl0aGluZyBpcyBleHRlcm5hbCB1bmxlc3MgZXhwbGljaXRseSBjb25maWd1cmVkXG4gICAgICAvLyB0byBiZSBidW5kbGVkXG4gICAgICBjb25zdCBjanNSZXNvbHZlciA9IHByb21pc2lmeShcbiAgICAgICAgZW5oYW5jZWRSZXNvbHZlT3JpZy5jcmVhdGUoTk9ERV9SRVNPTFZFX09QVElPTlMpXG4gICAgICApO1xuICAgICAgY29uc3QgZXNtUmVzb2x2ZXIgPSBwcm9taXNpZnkoXG4gICAgICAgIGVuaGFuY2VkUmVzb2x2ZU9yaWcuY3JlYXRlKE5PREVfRVNNX1JFU09MVkVfT1BUSU9OUylcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGVuaGFuY2VkUmVzb2x2ZSA9IGFzeW5jIChjb250ZXh0OiBzdHJpbmcsIHBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBhd2FpdCBlc21SZXNvbHZlcihjb250ZXh0LCBwYXRoKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiBjanNSZXNvbHZlcihjb250ZXh0LCBwYXRoKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gUHJlLWNvbXB1dGUgdGhlIG5vcm1hbGl6ZWQgc2lkZS1lZmZlY3QgZW50cmllcyBzZXQgZm9yIE8oMSkgbG9va3Vwcy5cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTaWRlRWZmZWN0RW50cmllcyA9IG5ldyBTZXQoXG4gICAgICAgIG9wdGlvbnMuc2lkZUVmZmVjdEVudHJpZXM/Lm1hcCgoZSkgPT4gZS5yZXBsYWNlKC9cXFxcL2csICcvJykpXG4gICAgICApO1xuXG4gICAgICBidWlsZC5vblJlc29sdmUoeyBmaWx0ZXI6IC8uKi8gfSwgYXN5bmMgKGFyZ3MpID0+IHtcbiAgICAgICAgaWYgKGFyZ3MucGx1Z2luRGF0YT8uc2tpcFN3Y1BsdWdpbikgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFvcHRpb25zLmVudHJpZXNUb0J1bmRsZSAmJlxuICAgICAgICAgIG5vcm1hbGl6ZWRTaWRlRWZmZWN0RW50cmllcy5zaXplID09PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2hlbiBvbmx5IHNpZGVFZmZlY3RFbnRyaWVzIGlzIHNldCAobm8gZW50cmllc1RvQnVuZGxlKSwgd2Ugb25seVxuICAgICAgICAvLyBuZWVkIHRvIG92ZXJyaWRlIHNpZGVFZmZlY3RzIGZvciB0b3AtbGV2ZWwgYmFyZSBpbXBvcnRzIOKAlCB0eXBpY2FsbHlcbiAgICAgICAgLy8gZnJvbSB0aGUgdmlydHVhbCBlbnRyeS4gU2tpcCByZXNvbHV0aW9uIGZvciB0cmFuc2l0aXZlIGltcG9ydHNcbiAgICAgICAgLy8gKGR5bmFtaWMgaW1wb3J0cywgcmVxdWlyZXMsIGV0Yy4pIHRvIGF2b2lkIHVubmVjZXNzYXJ5IG92ZXJoZWFkLlxuICAgICAgICBpZiAoIW9wdGlvbnMuZW50cmllc1RvQnVuZGxlICYmIGFyZ3Mua2luZCAhPT0gJ2ltcG9ydC1zdGF0ZW1lbnQnKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHNwZWNpZmllciA9IGFyZ3MucGF0aDtcbiAgICAgICAgICBjb25zdCBzcGVjaWZpZXJJc1BhdGggPVxuICAgICAgICAgICAgc3BlY2lmaWVyLnN0YXJ0c1dpdGgoJy4nKSB8fCBzcGVjaWZpZXIuc3RhcnRzV2l0aCgnLycpO1xuXG4gICAgICAgICAgbGV0IHJlc29sdmVkUGF0aDogc3RyaW5nIHwgZmFsc2UgfCB1bmRlZmluZWQ7XG4gICAgICAgICAgLy8gUGF0aC1zdHlsZSBzcGVjaWZpZXJzICguL2ZvbywgLi4vZm9vLCAvYWJzL3BhdGgpIGV4dGVybmFsaXplIGFzXG4gICAgICAgICAgLy8gcmVsYXRpdmUgcGF0aHMgZnJvbSBgb3V0ZGlyYC4gQmFyZSBzcGVjaWZpZXJzIChucG0gcGFja2FnZXMpXG4gICAgICAgICAgLy8gZXh0ZXJuYWxpemUgYXMtaXMgc28gTm9kZSBjYW4gcmVzb2x2ZSB0aGVtIGF0IHJ1bnRpbWUuXG4gICAgICAgICAgY29uc3Qgc2hvdWxkTWFrZVJlbGF0aXZlID0gc3BlY2lmaWVySXNQYXRoO1xuXG4gICAgICAgICAgaWYgKHNwZWNpZmllcklzUGF0aCkge1xuICAgICAgICAgICAgcmVzb2x2ZWRQYXRoID0gYXdhaXQgZW5oYW5jZWRSZXNvbHZlKGFyZ3MucmVzb2x2ZURpciwgc3BlY2lmaWVyKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gUmVzb2x2ZSBmcm9tIHByb2plY3Qgcm9vdCBzbyBuZXN0ZWQgZGVwcyBhcmVuJ3QgZXh0ZXJuYWxpemVkXG4gICAgICAgICAgICByZXNvbHZlZFBhdGggPSBhd2FpdCBlbmhhbmNlZFJlc29sdmUoXG4gICAgICAgICAgICAgIGJ1aWxkLmluaXRpYWxPcHRpb25zLmFic1dvcmtpbmdEaXIgfHwgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICAgICAgc3BlY2lmaWVyXG4gICAgICAgICAgICApLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7IC8vIHN3YWxsb3cgc28gZXNidWlsZCBmYWxsYmFjayBiZWxvdyBjYW4gdHJ5XG5cbiAgICAgICAgICAgIC8vIEZhbGwgYmFjayB0byBlc2J1aWxkIGZvciBhbGlhc2VzL3RzY29uZmlnIHBhdGhzLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIElmIHRoZSBzcGVjaWZpZXIgcmVzb2x2ZXMgdG8gYSBwcm9qZWN0LWxvY2FsIGZpbGUgdmlhIGFuXG4gICAgICAgICAgICAvLyBhbGlhcy9wYXRoIG1hcHBpbmcgKGUuZy4gdHNjb25maWcgYHBhdGhzYCwgZXNidWlsZCBgYWxpYXNgLFxuICAgICAgICAgICAgLy8gc2VsZi1yZWZlcmVuY2luZyBwYWNrYWdlIG5hbWVzIGxpa2UgYEBteS1wa2cvbGliL2Zvb2ApLCB3ZVxuICAgICAgICAgICAgLy8gYnVuZGxlIGl0IGlubGluZSByYXRoZXIgdGhhbiBleHRlcm5hbGl6aW5nLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEV4dGVybmFsaXppbmcgc3VjaCBmaWxlcyBpcyB1bnNhZmU6IHdlJ2QgZW1pdCBhIHJlbGF0aXZlXG4gICAgICAgICAgICAvLyBpbXBvcnQgdG8gdGhlIG9yaWdpbmFsIHNvdXJjZSBvbiBkaXNrLCBidXQgdGhhdCBzb3VyY2UgY2FuXG4gICAgICAgICAgICAvLyBjb250YWluIGZ1cnRoZXIgYWxpYXMgaW1wb3J0cy4gQXQgcnVudGltZSwgTm9kZSdzIEVTTSBsb2FkZXJcbiAgICAgICAgICAgIC8vIGRvZXNuJ3Qga25vdyBhYm91dCB0c2NvbmZpZyBwYXRocyBvciBidWlsZC10aW1lIGFsaWFzZXMsIHNvXG4gICAgICAgICAgICAvLyB0aG9zZSB0cmFuc2l0aXZlIGltcG9ydHMgdGhyb3cgYEVSUl9NT0RVTEVfTk9UX0ZPVU5EYCAvXG4gICAgICAgICAgICAvLyBgUGFja2FnZSBzdWJwYXRoIC4uLiBpcyBub3QgZGVmaW5lZCBieSBcImV4cG9ydHNcImAuXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gQnVuZGxpbmcgaW5saW5lIGVuc3VyZXMgYWxpYXMtYmFzZWQgaW1wb3J0cyBhcmUgcmVzb2x2ZWQgYXRcbiAgICAgICAgICAgIC8vIGJ1aWxkIHRpbWUgKHdoZXJlIHRoZSBhbGlhcyBtYXAgaXMga25vd24pIGFuZCB0aGUgcnVudGltZVxuICAgICAgICAgICAgLy8gbmV2ZXIgc2VlcyBhbiB1bnJlc29sdmFibGUgc3BlY2lmaWVyLlxuICAgICAgICAgICAgaWYgKCFyZXNvbHZlZFBhdGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXNidWlsZFJlc3VsdCA9IGF3YWl0IGJ1aWxkLnJlc29sdmUoc3BlY2lmaWVyLCB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZURpcjogYXJncy5yZXNvbHZlRGlyLFxuICAgICAgICAgICAgICAgIGtpbmQ6IGFyZ3Mua2luZCxcbiAgICAgICAgICAgICAgICBwbHVnaW5EYXRhOiB7IHNraXBTd2NQbHVnaW46IHRydWUgfSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGNvbnN0IGRpZFJlc29sdmUgPVxuICAgICAgICAgICAgICAgICEhZXNidWlsZFJlc3VsdC5wYXRoICYmICFlc2J1aWxkUmVzdWx0LmVycm9ycy5sZW5ndGg7XG4gICAgICAgICAgICAgIGNvbnN0IGlzUHJvamVjdExvY2FsRmlsZSA9XG4gICAgICAgICAgICAgICAgZGlkUmVzb2x2ZSAmJlxuICAgICAgICAgICAgICAgICFlc2J1aWxkUmVzdWx0LmV4dGVybmFsICYmXG4gICAgICAgICAgICAgICAgIWVzYnVpbGRSZXN1bHQucGF0aFxuICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFwvZywgJy8nKVxuICAgICAgICAgICAgICAgICAgLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpO1xuICAgICAgICAgICAgICBpZiAoaXNQcm9qZWN0TG9jYWxGaWxlKSB7XG4gICAgICAgICAgICAgICAgLy8gTGV0IGVzYnVpbGQgYnVuZGxlIHRoaXMgYWxpYXNlZCBwcm9qZWN0LWxvY2FsIGZpbGUgaW5saW5lXG4gICAgICAgICAgICAgICAgLy8gKHJldHVybiBudWxsIHRvIGRlZmVyIHRvIGVzYnVpbGQncyBub3JtYWwgcGlwZWxpbmUpLiBUaGVcbiAgICAgICAgICAgICAgICAvLyBTV0MgYG9uTG9hZGAgaGFuZGxlciB3aWxsIHN0aWxsIHByb2Nlc3MgaXQuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5lbnRyaWVzVG9CdW5kbGUgJiZcbiAgICAgICAgICAgICAgICBlc2J1aWxkUmVzdWx0LnBhdGg/LmVuZHNXaXRoKCcubm9kZScpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBleHRlcm5hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHNwZWNpZmllcixcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFyZXNvbHZlZFBhdGgpIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgLy8gTm9ybWFsaXplIHRvIGZvcndhcmQgc2xhc2hlcyBmb3IgY3Jvc3MtcGxhdGZvcm0gY29tcGFyaXNvblxuICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGggPSBub3JtYWxpemVQYXRoKHJlc29sdmVkUGF0aCk7XG4gICAgICAgICAgY29uc3Qgd29ya2luZ0RpciA9XG4gICAgICAgICAgICBidWlsZC5pbml0aWFsT3B0aW9ucy5hYnNXb3JraW5nRGlyIHx8IHByb2Nlc3MuY3dkKCk7XG4gICAgICAgICAgY29uc3QgcHJvamVjdFJvb3QgPSBvcHRpb25zLnByb2plY3RSb290IHx8IHdvcmtpbmdEaXI7XG4gICAgICAgICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyUm9vdCA9XG4gICAgICAgICAgICBvcHRpb25zLm1vZHVsZVNwZWNpZmllclJvb3QgfHwgcHJvamVjdFJvb3Q7XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBvcHRpb25zLmVudHJpZXNUb0J1bmRsZSAmJlxuICAgICAgICAgICAgbm9ybWFsaXplZFJlc29sdmVkUGF0aC5lbmRzV2l0aCgnLm5vZGUnKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZXh0ZXJuYWw6IHRydWUsXG4gICAgICAgICAgICAgIHBhdGg6IHNwZWNpZmllcixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBtb2R1bGUgaXMgYSBkaXNjb3ZlcmVkIGVudHJ5IHdob3NlIFNXQy10cmFuc2Zvcm1lZFxuICAgICAgICAgIC8vIGNvZGUgY29udGFpbnMgc2lkZSBlZmZlY3RzICh3b3JrZmxvdy9zdGVwL2NsYXNzIHJlZ2lzdHJhdGlvbikuXG4gICAgICAgICAgLy8gT3ZlcnJpZGUgdGhlIHBhY2thZ2UuanNvbiBcInNpZGVFZmZlY3RzXCI6IGZhbHNlIHNvIGVzYnVpbGQgZG9lcyBub3RcbiAgICAgICAgICAvLyBkcm9wIGJhcmUgaW1wb3J0cyBvZiB0aGVzZSBtb2R1bGVzLlxuICAgICAgICAgIGNvbnN0IGhhc1NpZGVFZmZlY3RzID0gbm9ybWFsaXplZFNpZGVFZmZlY3RFbnRyaWVzLmhhcyhcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGhcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKG9wdGlvbnMuZW50cmllc1RvQnVuZGxlKSB7XG4gICAgICAgICAgICBsZXQgc2hvdWxkQnVuZGxlID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGVudHJ5VG9CdW5kbGUgb2Ygb3B0aW9ucy5lbnRyaWVzVG9CdW5kbGUpIHtcbiAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZEVudHJ5ID0gZW50cnlUb0J1bmRsZS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG5cbiAgICAgICAgICAgICAgaWYgKG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGggPT09IG5vcm1hbGl6ZWRFbnRyeSkge1xuICAgICAgICAgICAgICAgIHNob3VsZEJ1bmRsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBpZiB0aGUgY3VycmVudCBlbnRyeSBpbXBvcnRzIGEgY2hpbGQgdGhhdCBuZWVkc1xuICAgICAgICAgICAgICAvLyB0byBiZSBidW5kbGVkIHRoZW4gaXQgbmVlZHMgdG8gYWxzbyBiZSBidW5kbGVkIHNvXG4gICAgICAgICAgICAgIC8vIHRoYXQgdGhlIGNoaWxkIGNhbiBoYXZlIG91ciB0cmFuc2Zvcm0gYXBwbGllZFxuICAgICAgICAgICAgICBpZiAocGFyZW50SGFzQ2hpbGQobm9ybWFsaXplZFJlc29sdmVkUGF0aCwgbm9ybWFsaXplZEVudHJ5KSkge1xuICAgICAgICAgICAgICAgIHNob3VsZEJ1bmRsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBCdW5kbGUgcHJvamVjdC1sb2NhbCBzb3VyY2UgZmlsZXMgdGhhdCBhcmUgaW1wb3J0ZWQgYnkgYVxuICAgICAgICAgICAgICAvLyBzdGVwL3NlcmRlIGVudHJ5IHNvIGRpcmVjdCBydW50aW1lIGxvYWRlcnMgZG8gbm90IHNlZSByYXcgVFNcbiAgICAgICAgICAgICAgLy8gZXh0ZW5zaW9ubGVzcyBpbXBvcnRzLiBLZWVwIHBhY2thZ2UgZGVwZW5kZW5jaWVzIGV4dGVybmFsXG4gICAgICAgICAgICAgIC8vIHVubGVzcyB0aGV5IGFyZSB0aGVtc2VsdmVzIGluIGVudHJpZXNUb0J1bmRsZSBvciBhcmUgcGFyZW50c1xuICAgICAgICAgICAgICAvLyBvZiBhIGRpc2NvdmVyZWQgd29ya2Zsb3cvc3RlcC9zZXJkZSBmaWxlIHZpYSB0aGUgY2hlY2sgYWJvdmUuXG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBvcHRpb25zLmJ1bmRsZVRyYW5zaXRpdmVMb2NhbFN0ZXBEZXBlbmRlbmNpZXMgJiZcbiAgICAgICAgICAgICAgICBpc1Byb2plY3RMb2NhbEZpbGUoXG4gICAgICAgICAgICAgICAgICBub3JtYWxpemVkUmVzb2x2ZWRQYXRoLFxuICAgICAgICAgICAgICAgICAgbW9kdWxlU3BlY2lmaWVyUm9vdFxuICAgICAgICAgICAgICAgICkgJiZcbiAgICAgICAgICAgICAgICBwYXJlbnRIYXNDaGlsZChub3JtYWxpemVkRW50cnksIG5vcm1hbGl6ZWRSZXNvbHZlZFBhdGgpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHNob3VsZEJ1bmRsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHNob3VsZEJ1bmRsZSkge1xuICAgICAgICAgICAgICAvLyBMZXQgZXNidWlsZCBidW5kbGUgdGhpcyBlbnRyeSwgYnV0IG92ZXJyaWRlIHNpZGVFZmZlY3RzIGlmIG5lZWRlZC5cbiAgICAgICAgICAgICAgLy8gV2UgbXVzdCByZXR1cm4gdGhlIHJlc29sdmVkIGBwYXRoYCBhbG9uZ3NpZGUgYHNpZGVFZmZlY3RzYCBiZWNhdXNlXG4gICAgICAgICAgICAgIC8vIHJldHVybmluZyBvbmx5IGB7IHNpZGVFZmZlY3RzOiB0cnVlIH1gIHdpdGhvdXQgYSBwYXRoIGNhdXNlcyBlc2J1aWxkXG4gICAgICAgICAgICAgIC8vIHRvIGZhbGwgdGhyb3VnaCB0byBpdHMgb3duIHJlc29sdmVyLCB3aGljaCByZS1yZWFkcyB0aGUgcGFja2FnZS5qc29uXG4gICAgICAgICAgICAgIC8vIGFuZCBhcHBsaWVzIGBcInNpZGVFZmZlY3RzXCI6IGZhbHNlYCBmcm9tIHRoZXJlLlxuICAgICAgICAgICAgICByZXR1cm4gaGFzU2lkZUVmZmVjdHNcbiAgICAgICAgICAgICAgICA/IHsgcGF0aDogcmVzb2x2ZWRQYXRoLCBzaWRlRWZmZWN0czogdHJ1ZSB9XG4gICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZXh0ZXJuYWxQYXRoOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAoc2hvdWxkTWFrZVJlbGF0aXZlKSB7XG4gICAgICAgICAgICAgIC8vIFdoZW4gdGhlIHJlc29sdmVkIGZpbGUgbGl2ZXMgaW5zaWRlIG5vZGVfbW9kdWxlcywgbGV0XG4gICAgICAgICAgICAgIC8vIGVzYnVpbGQgYnVuZGxlIGl0IHJhdGhlciB0aGFuIGV4dGVybmFsaXppbmcgd2l0aCBhIGRlZXBseVxuICAgICAgICAgICAgICAvLyBuZXN0ZWQgcmVsYXRpdmUgcGF0aC4gRG93bnN0cmVhbSBidW5kbGVycyAoUm9sbHVwL1ZpdGUpXG4gICAgICAgICAgICAgIC8vIGNhbid0IHJld3JpdGUgb3BhcXVlIGBfX3JlcXVpcmUoKWAgY2FsbHMgaW4gQ0pTIHNoaW1zLCBzb1xuICAgICAgICAgICAgICAvLyByZWxhdGl2ZSBwYXRocyBjb21wdXRlZCBmb3IgYG91dGRpcmAgYnJlYWsgb25jZSB0aGUgb3V0cHV0XG4gICAgICAgICAgICAgIC8vIGlzIHJlYnVuZGxlZCB0byBhIGRpZmZlcmVudCBkaXJlY3RvcnkuXG4gICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUmVzb2x2ZWRQYXRoLmluY2x1ZGVzKCcvbm9kZV9tb2R1bGVzLycpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7IC8vIGxldCBlc2J1aWxkIGJ1bmRsZSBpdFxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgZXh0ZXJuYWxQYXRoID0gcmVsYXRpdmUoXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5vdXRkaXIgfHwgcHJvY2Vzcy5jd2QoKSxcbiAgICAgICAgICAgICAgICByZXNvbHZlZFBhdGhcbiAgICAgICAgICAgICAgKS5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG5cbiAgICAgICAgICAgICAgaWYgKG9wdGlvbnMucmV3cml0ZVRzRXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgICAgIC8vIFJld3JpdGUgVHlwZVNjcmlwdCBleHRlbnNpb25zIHRvIHRoZWlyIEpTIGVxdWl2YWxlbnRzIHNvIHRoZVxuICAgICAgICAgICAgICAgIC8vIGV4dGVybmFsaXplZCBpbXBvcnQgaXMgbG9hZGFibGUgYnkgTm9kZSdzIG5hdGl2ZSBFU00gbG9hZGVyLlxuICAgICAgICAgICAgICAgIGV4dGVybmFsUGF0aCA9IGV4dGVybmFsUGF0aFxuICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcLnRzeD8kLywgJy5qcycpXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFwubXRzJC8sICcubWpzJylcbiAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXC5jdHMkLywgJy5janMnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZXh0ZXJuYWxQYXRoID0gc3BlY2lmaWVyO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBleHRlcm5hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgcGF0aDogZXh0ZXJuYWxQYXRoLFxuICAgICAgICAgICAgICBzaWRlRWZmZWN0czogaGFzU2lkZUVmZmVjdHMgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBObyBlbnRyaWVzVG9CdW5kbGUg4oCUIG9ubHkgb3ZlcnJpZGUgc2lkZUVmZmVjdHMgd2hlbiBuZWVkZWQuXG4gICAgICAgICAgLy8gV2UgbXVzdCByZXR1cm4gdGhlIHJlc29sdmVkIGBwYXRoYCBhbG9uZ3NpZGUgYHNpZGVFZmZlY3RzYCBiZWNhdXNlXG4gICAgICAgICAgLy8gcmV0dXJuaW5nIG9ubHkgYHsgc2lkZUVmZmVjdHM6IHRydWUgfWAgd2l0aG91dCBhIHBhdGggY2F1c2VzIGVzYnVpbGRcbiAgICAgICAgICAvLyB0byBmYWxsIHRocm91Z2ggdG8gaXRzIG93biByZXNvbHZlciwgd2hpY2ggcmUtcmVhZHMgdGhlIHBhY2thZ2UuanNvblxuICAgICAgICAgIC8vIGFuZCBhcHBsaWVzIGBcInNpZGVFZmZlY3RzXCI6IGZhbHNlYCBmcm9tIHRoZXJlLlxuICAgICAgICAgIHJldHVybiBoYXNTaWRlRWZmZWN0c1xuICAgICAgICAgICAgPyB7IHBhdGg6IHJlc29sdmVkUGF0aCwgc2lkZUVmZmVjdHM6IHRydWUgfVxuICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICB9IGNhdGNoIChfKSB7fVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBIYW5kbGUgVHlwZVNjcmlwdCBhbmQgSmF2YVNjcmlwdCBmaWxlc1xuICAgICAgYnVpbGQub25Mb2FkKHsgZmlsdGVyOiBqc1RzUmVnZXggfSwgYXN5bmMgKGFyZ3MpID0+IHtcbiAgICAgICAgLy8gRGV0ZXJtaW5lIGlmIHRoaXMgaXMgYSBUeXBlU2NyaXB0IGZpbGVcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGxvYWRlciBiYXNlZCBvbiB0aGUgb3V0cHV0XG4gICAgICAgICAgbGV0IGxvYWRlcjogJ2pzJyB8ICdqc3gnIHwgJ3RzeCcgPSAnanMnO1xuICAgICAgICAgIGlmIChhcmdzLnBhdGguZW5kc1dpdGgoJy5qc3gnKSkge1xuICAgICAgICAgICAgbG9hZGVyID0gJ2pzeCc7XG4gICAgICAgICAgfSBlbHNlIGlmIChhcmdzLnBhdGguZW5kc1dpdGgoJy50c3gnKSkge1xuICAgICAgICAgICAgbG9hZGVyID0gJ3RzeCc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHJlYWRGaWxlKGFyZ3MucGF0aCwgJ3V0ZjgnKTtcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkU291cmNlID0gc291cmNlXG4gICAgICAgICAgICAucmVwbGFjZSgvcmVxdWlyZVxcKFxccyooWydcIl0pc2VydmVyLW9ubHlcXDFcXHMqXFwpL2csICd2b2lkIDAnKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3JlcXVpcmVcXChcXHMqKFsnXCJdKWNsaWVudC1vbmx5XFwxXFxzKlxcKS9nLCAndm9pZCAwJyk7XG5cbiAgICAgICAgICAvLyBDYWxjdWxhdGUgcmVsYXRpdmUgcGF0aCBmb3IgU1dDIHBsdWdpblxuICAgICAgICAgIC8vIFRoZSBmaWxlbmFtZSBwYXJhbWV0ZXIgaXMgdXNlZCB0byBnZW5lcmF0ZSB3b3JrZmxvd0lkL3N0ZXBJZCwgc28gaXQgbXVzdCBiZSByZWxhdGl2ZVxuICAgICAgICAgIGNvbnN0IHdvcmtpbmdEaXIgPVxuICAgICAgICAgICAgYnVpbGQuaW5pdGlhbE9wdGlvbnMuYWJzV29ya2luZ0RpciB8fCBwcm9jZXNzLmN3ZCgpO1xuICAgICAgICAgIGNvbnN0IHByb2plY3RSb290ID0gb3B0aW9ucy5wcm9qZWN0Um9vdCB8fCB3b3JraW5nRGlyO1xuICAgICAgICAgIGNvbnN0IG1vZHVsZVNwZWNpZmllclJvb3QgPVxuICAgICAgICAgICAgb3B0aW9ucy5tb2R1bGVTcGVjaWZpZXJSb290IHx8IHByb2plY3RSb290O1xuICAgICAgICAgIC8vIE5vcm1hbGl6ZSBwYXRoczogY29udmVydCBiYWNrc2xhc2hlcyB0byBmb3J3YXJkIHNsYXNoZXMgYW5kIHJlbW92ZSB0cmFpbGluZyBzbGFzaGVzXG4gICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFdvcmtpbmdEaXIgPSB3b3JraW5nRGlyXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxcXC9nLCAnLycpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFwvJC8sICcnKTtcbiAgICAgICAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IGFyZ3MucGF0aC5yZXBsYWNlKC9cXFxcL2csICcvJyk7XG5cbiAgICAgICAgICAvLyBXaW5kb3dzIGZpeDogQWx3YXlzIGRvIGNhc2UtaW5zZW5zaXRpdmUgcGF0aCBjb21wYXJpc29uIGFzIHRoZSBQUklNQVJZIGxvZ2ljXG4gICAgICAgICAgLy8gdG8gd29yayBhcm91bmQgbm9kZTpwYXRoLnJlbGF0aXZlKCkgbm90IHJlY29nbml6aW5nIHBhdGhzIHdpdGggZGlmZmVyZW50IGRyaXZlXG4gICAgICAgICAgLy8gbGV0dGVyIGNhc2luZyAoZS5nLiwgRDogdnMgZDopIGFzIGJlaW5nIGluIHRoZSBzYW1lIHRyZWVcbiAgICAgICAgICBjb25zdCBsb3dlcldkID0gbm9ybWFsaXplZFdvcmtpbmdEaXIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICBjb25zdCBsb3dlclBhdGggPSBub3JtYWxpemVkUGF0aC50b0xvd2VyQ2FzZSgpO1xuXG4gICAgICAgICAgbGV0IHJlbGF0aXZlRmlsZXBhdGg6IHN0cmluZztcbiAgICAgICAgICBpZiAobG93ZXJQYXRoLnN0YXJ0c1dpdGgoYCR7bG93ZXJXZH0vYCkpIHtcbiAgICAgICAgICAgIC8vIEZpbGUgaXMgdW5kZXIgd29ya2luZyBkaXJlY3RvcnkgLSBtYW51YWxseSBjYWxjdWxhdGUgcmVsYXRpdmUgcGF0aFxuICAgICAgICAgICAgLy8gVGhpcyBlbnN1cmVzIHdlIGdldCBhIHJlbGF0aXZlIHBhdGggZXZlbiB3aXRoIGRyaXZlIGxldHRlciBjYXNpbmcgaXNzdWVzXG4gICAgICAgICAgICByZWxhdGl2ZUZpbGVwYXRoID0gbm9ybWFsaXplZFBhdGguc3Vic3RyaW5nKFxuICAgICAgICAgICAgICBub3JtYWxpemVkV29ya2luZ0Rpci5sZW5ndGggKyAxXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAobG93ZXJQYXRoID09PSBsb3dlcldkKSB7XG4gICAgICAgICAgICAvLyBGaWxlIElTIHRoZSB3b3JraW5nIGRpcmVjdG9yeVxuICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aCA9ICcuJztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gRmlsZSBpcyBvdXRzaWRlIHdvcmtpbmcgZGlyZWN0b3J5IC0gdXNlIHJlbGF0aXZlKCkgYW5kIHN0cmlwIC4uLyBwcmVmaXhlcyBpZiBuZWVkZWRcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZXBhdGggPSByZWxhdGl2ZShcbiAgICAgICAgICAgICAgbm9ybWFsaXplZFdvcmtpbmdEaXIsXG4gICAgICAgICAgICAgIG5vcm1hbGl6ZWRQYXRoXG4gICAgICAgICAgICApLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAgICAgICAgICAgLy8gSGFuZGxlIGZpbGVzIGRpc2NvdmVyZWQgb3V0c2lkZSB0aGUgd29ya2luZyBkaXJlY3RvcnlcbiAgICAgICAgICAgIC8vIFRoZXNlIGNvbWUgYmFjayBhcyAuLi9wYXRoL3RvL2ZpbGUsIGJ1dCB3ZSB3YW50IGp1c3QgcGF0aC90by9maWxlXG4gICAgICAgICAgICBpZiAocmVsYXRpdmVGaWxlcGF0aC5zdGFydHNXaXRoKCcuLi8nKSkge1xuICAgICAgICAgICAgICBjb25zdCBhbGlhc2VkUmVsYXRpdmVQYXRoID1cbiAgICAgICAgICAgICAgICBhd2FpdCByZXNvbHZlV29ya2Zsb3dBbGlhc1JlbGF0aXZlUGF0aChhcmdzLnBhdGgsIHdvcmtpbmdEaXIpO1xuICAgICAgICAgICAgICBpZiAoYWxpYXNlZFJlbGF0aXZlUGF0aCkge1xuICAgICAgICAgICAgICAgIHJlbGF0aXZlRmlsZXBhdGggPSBhbGlhc2VkUmVsYXRpdmVQYXRoO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlbGF0aXZlRmlsZXBhdGggPSByZWxhdGl2ZUZpbGVwYXRoXG4gICAgICAgICAgICAgICAgICAuc3BsaXQoJy8nKVxuICAgICAgICAgICAgICAgICAgLmZpbHRlcigocGFydCkgPT4gcGFydCAhPT0gJy4uJylcbiAgICAgICAgICAgICAgICAgIC5qb2luKCcvJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBGaW5hbCBzYWZldHkgY2hlY2sgLSBlbnN1cmUgd2UgbmV2ZXIgcGFzcyBhbiBhYnNvbHV0ZSBwYXRoIHRvIFNXQ1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHJlbGF0aXZlRmlsZXBhdGguaW5jbHVkZXMoJzonKSB8fFxuICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aC5zdGFydHNXaXRoKCcvJylcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0IGlmIGl0IGRvZXMsIHVzZSBqdXN0IHRoZSBmaWxlbmFtZSBhcyBsYXN0IHJlc29ydFxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICAgYFtFUlJPUl0gcmVsYXRpdmVGaWxlcGF0aCBpcyBzdGlsbCBhYnNvbHV0ZTogJHtyZWxhdGl2ZUZpbGVwYXRofWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZWxhdGl2ZUZpbGVwYXRoID0gbm9ybWFsaXplZFBhdGguc3BsaXQoJy8nKS5wb3AoKSB8fCAndW5rbm93bi50cyc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgeyBjb2RlOiB0cmFuc2Zvcm1lZENvZGUsIHdvcmtmbG93TWFuaWZlc3QgfSA9XG4gICAgICAgICAgICBhd2FpdCBhcHBseVN3Y1RyYW5zZm9ybShcbiAgICAgICAgICAgICAgcmVsYXRpdmVGaWxlcGF0aCxcbiAgICAgICAgICAgICAgbm9ybWFsaXplZFNvdXJjZSxcbiAgICAgICAgICAgICAgb3B0aW9ucy5tb2RlLFxuICAgICAgICAgICAgICBhcmdzLnBhdGgsIC8vIFBhc3MgYWJzb2x1dGUgcGF0aCBmb3IgbW9kdWxlIHNwZWNpZmllciByZXNvbHV0aW9uXG4gICAgICAgICAgICAgIHByb2plY3RSb290LFxuICAgICAgICAgICAgICBtb2R1bGVTcGVjaWZpZXJSb290XG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKCFvcHRpb25zLndvcmtmbG93TWFuaWZlc3QpIHtcbiAgICAgICAgICAgIG9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdCA9IHt9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIG1lcmdlV29ya2Zsb3dNYW5pZmVzdChcbiAgICAgICAgICAgIG9wdGlvbnMud29ya2Zsb3dNYW5pZmVzdCxcbiAgICAgICAgICAgIHdvcmtmbG93TWFuaWZlc3QsXG4gICAgICAgICAgICBzdGVwSWRzRm9yQ3VycmVudEJ1aWxkLFxuICAgICAgICAgICAgd29ya2Zsb3dJZHNGb3JDdXJyZW50QnVpbGRcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgYXdhaXQgb3B0aW9ucy5vbkFmdGVyVHJhbnNmb3JtPy4oe1xuICAgICAgICAgICAgbW9kZTogb3B0aW9ucy5tb2RlLFxuICAgICAgICAgICAgZmlsZW5hbWU6IHJlbGF0aXZlRmlsZXBhdGgsXG4gICAgICAgICAgICBhYnNvbHV0ZVBhdGg6IGFyZ3MucGF0aCxcbiAgICAgICAgICAgIHNvdXJjZTogbm9ybWFsaXplZFNvdXJjZSxcbiAgICAgICAgICAgIGNvZGU6IHRyYW5zZm9ybWVkQ29kZSxcbiAgICAgICAgICAgIHdvcmtmbG93TWFuaWZlc3QsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGVudHM6IHRyYW5zZm9ybWVkQ29kZSxcbiAgICAgICAgICAgIGxvYWRlcixcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgIGDinYwgU1dDIHRyYW5zZm9ybSBlcnJvciBpbiAke2FyZ3MucGF0aH06YCxcbiAgICAgICAgICAgIGVycm9yTWVzc2FnZVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVycm9yczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGV4dDogYFNXQyB0cmFuc2Zvcm0gZmFpbGVkOiAke2Vycm9yTWVzc2FnZX1gLFxuICAgICAgICAgICAgICAgIGxvY2F0aW9uOiB7IGZpbGU6IGFyZ3MucGF0aCwgbGluZTogMCwgY29sdW1uOiAwIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzUHJvamVjdExvY2FsRmlsZShmaWxlUGF0aDogc3RyaW5nLCBwcm9qZWN0Um9vdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChub3JtYWxpemVQYXRoKGZpbGVQYXRoKS5pbmNsdWRlcygnL25vZGVfbW9kdWxlcy8nKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgcmVzb2x2ZU1vZHVsZVNwZWNpZmllcihmaWxlUGF0aCwgcHJvamVjdFJvb3QpLm1vZHVsZVNwZWNpZmllciA9PT0gdW5kZWZpbmVkXG4gICk7XG59XG4iXX0=
|