@cdktn/provider-generator 0.24.0-pre.9 → 0.24.0-pre.91
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/.spec.swcrc +22 -0
- package/LICENSE +355 -0
- package/README.md +1 -1
- package/build/__tests__/edge-provider-schema/builder.d.ts +9 -3
- package/build/__tests__/edge-provider-schema/builder.js +6 -3
- package/build/__tests__/edge-provider-schema/cli.js +8 -3
- package/build/__tests__/edge-provider-schema/index.js +119 -1
- package/build/__tests__/provider.test.js +4 -1
- package/build/get/__tests__/generator/ephemeral-resources.test.d.ts +2 -0
- package/build/get/__tests__/generator/ephemeral-resources.test.js +49 -0
- package/build/get/__tests__/generator/module-generator.test.js +12 -12
- package/build/get/__tests__/generator/provider-functions.test.d.ts +2 -0
- package/build/get/__tests__/generator/provider-functions.test.js +176 -0
- package/build/get/__tests__/generator/provider-source-matching.test.d.ts +2 -0
- package/build/get/__tests__/generator/provider-source-matching.test.js +45 -0
- package/build/get/__tests__/generator/provider.test.js +9 -1
- package/build/get/__tests__/generator/supported-stored-classes.test.d.ts +2 -0
- package/build/get/__tests__/generator/supported-stored-classes.test.js +137 -0
- package/build/get/__tests__/generator/types.test.js +44 -1
- package/build/get/__tests__/generator/write-only.test.d.ts +2 -0
- package/build/get/__tests__/generator/write-only.test.js +65 -0
- package/build/get/__tests__/target-versions.test.d.ts +2 -0
- package/build/get/__tests__/target-versions.test.js +171 -0
- package/build/get/constructs-maker.d.ts +8 -1
- package/build/get/constructs-maker.js +46 -10
- package/build/get/generator/emitter/attributes-emitter.d.ts +13 -2
- package/build/get/generator/emitter/attributes-emitter.js +71 -5
- package/build/get/generator/emitter/index.d.ts +1 -0
- package/build/get/generator/emitter/index.js +2 -1
- package/build/get/generator/emitter/provider-functions-emitter.d.ts +11 -0
- package/build/get/generator/emitter/provider-functions-emitter.js +94 -0
- package/build/get/generator/emitter/resource-emitter.d.ts +5 -1
- package/build/get/generator/emitter/resource-emitter.js +83 -7
- package/build/get/generator/emitter/struct-emitter.js +10 -10
- package/build/get/generator/models/attribute-model.d.ts +4 -0
- package/build/get/generator/models/attribute-model.js +50 -4
- package/build/get/generator/models/attribute-type-model.d.ts +24 -0
- package/build/get/generator/models/attribute-type-model.js +91 -5
- package/build/get/generator/models/index.d.ts +1 -0
- package/build/get/generator/models/index.js +2 -1
- package/build/get/generator/models/provider-function-model.d.ts +102 -0
- package/build/get/generator/models/provider-function-model.js +667 -0
- package/build/get/generator/models/resource-model.d.ts +3 -0
- package/build/get/generator/models/resource-model.js +13 -4
- package/build/get/generator/models/struct.d.ts +2 -0
- package/build/get/generator/models/struct.js +6 -2
- package/build/get/generator/models/supported-stored-classes.d.ts +5 -0
- package/build/get/generator/models/supported-stored-classes.js +86 -0
- package/build/get/generator/module-generator.js +3 -3
- package/build/get/generator/provider-generator.d.ts +2 -0
- package/build/get/generator/provider-generator.js +41 -6
- package/build/get/generator/resource-parser.js +3 -1
- package/jest.config.js +16 -9
- package/package.json +28 -27
- package/package.sh +1 -1
- package/src/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +4 -0
- package/src/__tests__/__snapshots__/provider.test.ts.snap +2828 -2828
- package/src/__tests__/edge-provider-schema/builder.ts +201 -0
- package/src/__tests__/edge-provider-schema/cli.ts +51 -0
- package/src/__tests__/edge-provider-schema/index.ts +284 -0
- package/src/__tests__/edge-provider-schema.test.ts +24 -0
- package/src/__tests__/provider.test.ts +183 -0
- package/src/get/__tests__/constructs-maker.test.ts +118 -0
- package/src/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +5 -5
- package/src/get/__tests__/generator/__snapshots__/ephemeral-resources.test.ts.snap +524 -0
- package/src/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +3310 -3310
- package/src/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +355 -355
- package/src/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +8 -8
- package/src/get/__tests__/generator/__snapshots__/provider-functions.test.ts.snap +444 -0
- package/src/get/__tests__/generator/__snapshots__/provider.test.ts.snap +8 -8
- package/src/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +126 -126
- package/src/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +17 -17
- package/src/get/__tests__/generator/__snapshots__/types.test.ts.snap +201 -52
- package/src/get/__tests__/generator/__snapshots__/write-only.test.ts.snap +262 -0
- package/src/get/__tests__/generator/complex-computed-types.test.ts +28 -0
- package/src/get/__tests__/generator/deep-nested-attributes.test.ts +56 -0
- package/src/get/__tests__/generator/description-escaping.test.ts +84 -0
- package/src/get/__tests__/generator/empty-provider-resources.test.ts +26 -0
- package/src/get/__tests__/generator/ephemeral-resources.test.ts +46 -0
- package/src/get/__tests__/generator/export-sharding.test.ts +169 -0
- package/src/get/__tests__/generator/fixtures/deeply-nested-collections.test.fixture.json +129 -0
- package/src/get/__tests__/generator/fixtures/ephemeral-resources.test.fixture.json +160 -0
- package/src/get/__tests__/generator/fixtures/provider-functions-collision.test.fixture.json +31 -0
- package/src/get/__tests__/generator/fixtures/provider-functions-synthetic.test.fixture.json +192 -0
- package/src/get/__tests__/generator/fixtures/provider-functions.test.fixture.json +170 -0
- package/src/get/__tests__/generator/fixtures/write-only.test.fixture.json +58 -0
- package/src/get/__tests__/generator/import-style.test.ts +129 -0
- package/src/get/__tests__/generator/module-generator.test.ts +528 -0
- package/src/get/__tests__/generator/nested-types.test.ts +54 -0
- package/src/get/__tests__/generator/provider-functions.test.ts +262 -0
- package/src/get/__tests__/generator/provider-source-matching.test.ts +84 -0
- package/src/get/__tests__/generator/provider.test.ts +59 -0
- package/src/get/__tests__/generator/resource-types.test.ts +118 -0
- package/src/get/__tests__/generator/skipped-attributes.test.ts +72 -0
- package/src/get/__tests__/generator/supported-stored-classes.test.ts +147 -0
- package/src/get/__tests__/generator/types.test.ts +686 -0
- package/src/get/__tests__/generator/versions-file.test.ts +72 -0
- package/src/get/__tests__/generator/write-only.test.ts +71 -0
- package/src/get/__tests__/target-versions.test.ts +206 -0
- package/src/get/__tests__/util.ts +75 -0
- package/src/get/constructs-maker.ts +885 -0
- package/src/get/generator/custom-defaults.ts +493 -0
- package/src/get/generator/emitter/attributes-emitter.ts +316 -0
- package/src/get/generator/emitter/index.ts +6 -0
- package/src/get/generator/emitter/provider-functions-emitter.ts +117 -0
- package/src/get/generator/emitter/resource-emitter.ts +330 -0
- package/src/get/generator/emitter/struct-emitter.ts +683 -0
- package/src/get/generator/loop-detection.ts +81 -0
- package/src/get/generator/models/attribute-model.ts +273 -0
- package/src/get/generator/models/attribute-type-model.ts +560 -0
- package/src/get/generator/models/index.ts +8 -0
- package/src/get/generator/models/provider-function-model.ts +872 -0
- package/src/get/generator/models/resource-model.ts +183 -0
- package/src/get/generator/models/scope.ts +54 -0
- package/src/get/generator/models/struct.ts +124 -0
- package/src/get/generator/models/supported-stored-classes.ts +88 -0
- package/src/get/generator/module-generator.ts +234 -0
- package/src/get/generator/provider-generator.ts +428 -0
- package/src/get/generator/resource-parser.ts +764 -0
- package/src/get/generator/sanitized-comments.ts +49 -0
- package/src/get/generator/skipped-attributes.ts +27 -0
- package/src/index.ts +40 -0
- package/src/util.ts +26 -0
- package/tsconfig.json +1 -2
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
// Copyright (c) HashiCorp, Inc
|
|
27
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
28
|
+
const fs = __importStar(require("fs"));
|
|
29
|
+
const path = __importStar(require("path"));
|
|
30
|
+
const provider_generator_1 = require("../../generator/provider-generator");
|
|
31
|
+
const provider_function_model_1 = require("../../generator/models/provider-function-model");
|
|
32
|
+
const codemaker_1 = require("codemaker");
|
|
33
|
+
const util_1 = require("../util");
|
|
34
|
+
const tmp = (0, util_1.createTmpHelper)();
|
|
35
|
+
test("generate provider functions for the time provider (real terraform 1.15.6 schema fragment)", async () => {
|
|
36
|
+
const code = new codemaker_1.CodeMaker();
|
|
37
|
+
const workdir = tmp("provider-functions.test");
|
|
38
|
+
const spec = JSON.parse(fs.readFileSync(path.join(__dirname, "fixtures", "provider-functions.test.fixture.json"), "utf-8"));
|
|
39
|
+
new provider_generator_1.TerraformProviderGenerator(code, spec).generateAll();
|
|
40
|
+
await code.save(workdir);
|
|
41
|
+
const providerFunctionsOutput = fs.readFileSync(path.join(workdir, "providers/time/provider-functions/index.ts"), "utf-8");
|
|
42
|
+
expect(providerFunctionsOutput).toMatchSnapshot("time-provider-functions");
|
|
43
|
+
const providerOutput = fs.readFileSync(path.join(workdir, "providers/time/provider/index.ts"), "utf-8");
|
|
44
|
+
expect(providerOutput).toMatchSnapshot("time-provider");
|
|
45
|
+
const providerIndex = fs.readFileSync(path.join(workdir, "providers/time/index.ts"), "utf-8");
|
|
46
|
+
expect(providerIndex).toMatchSnapshot("provider-index");
|
|
47
|
+
const providerLazyIndex = fs.readFileSync(path.join(workdir, "providers/time/lazy-index.ts"), "utf-8");
|
|
48
|
+
expect(providerLazyIndex).toMatchSnapshot("provider-lazy-index");
|
|
49
|
+
});
|
|
50
|
+
describe("generate provider functions covering variadic parameters, primitive/list returns, and a 'default' parameter name", () => {
|
|
51
|
+
let providerFunctionsOutput;
|
|
52
|
+
let providerIndex;
|
|
53
|
+
let providerLazyIndex;
|
|
54
|
+
beforeAll(async () => {
|
|
55
|
+
const code = new codemaker_1.CodeMaker();
|
|
56
|
+
const workdir = tmp("provider-functions-synthetic.test");
|
|
57
|
+
const spec = JSON.parse(fs.readFileSync(path.join(__dirname, "fixtures", "provider-functions-synthetic.test.fixture.json"), "utf-8"));
|
|
58
|
+
new provider_generator_1.TerraformProviderGenerator(code, spec).generateAll();
|
|
59
|
+
await code.save(workdir);
|
|
60
|
+
providerFunctionsOutput = fs.readFileSync(path.join(workdir, "providers/example/provider-functions/index.ts"), "utf-8");
|
|
61
|
+
providerIndex = fs.readFileSync(path.join(workdir, "providers/example/index.ts"), "utf-8");
|
|
62
|
+
providerLazyIndex = fs.readFileSync(path.join(workdir, "providers/example/lazy-index.ts"), "utf-8");
|
|
63
|
+
});
|
|
64
|
+
test("matches the snapshot", () => {
|
|
65
|
+
expect(providerFunctionsOutput).toMatchSnapshot("example-provider-functions");
|
|
66
|
+
expect(providerIndex).toMatchSnapshot("provider-index");
|
|
67
|
+
expect(providerLazyIndex).toMatchSnapshot("provider-lazy-index");
|
|
68
|
+
});
|
|
69
|
+
test("nested collection docstrings use the compact recursive Array/Set notation", () => {
|
|
70
|
+
// list(set(string)): notation carries the structure; a plain Terraform
|
|
71
|
+
// list needs no prose note.
|
|
72
|
+
expect(providerFunctionsOutput).toContain("@param {Array<Set<string>>} nameGroups");
|
|
73
|
+
expect(providerFunctionsOutput).toContain("@returns {Array<Set<string>>}");
|
|
74
|
+
// set(list(string)): Set<...> notation plus the set-semantics prose note
|
|
75
|
+
// (the jsii type is still an array - the note keeps a reader from
|
|
76
|
+
// literally passing a JS Set).
|
|
77
|
+
expect(providerFunctionsOutput).toContain("@param {Set<Array<string>>} nameLists - Terraform set; ordering is not guaranteed and duplicate values are removed.");
|
|
78
|
+
expect(providerFunctionsOutput).toContain("@returns {Set<Array<string>>} Terraform set; ordering is not guaranteed and duplicate values are removed.");
|
|
79
|
+
});
|
|
80
|
+
// This package has no TypeScript-compiling harness
|
|
81
|
+
// for generated output (no fixture/test anywhere generates a snippet and
|
|
82
|
+
// feeds it through `tsc`/`ts.transpileModule`, and `cdktn` itself isn't a
|
|
83
|
+
// dependency of this package to typecheck against), so these are
|
|
84
|
+
// structural assertions on the emitted declaration text rather than an
|
|
85
|
+
// actual compile - see also the runtime-level proof in
|
|
86
|
+
// packages/cdktn/test/provider-functions.test.ts, which exercises the
|
|
87
|
+
// same union/token mechanics these signatures rely on.
|
|
88
|
+
describe("composition: a function's return type is directly assignable to another function's parameter of the 'same' Terraform type", () => {
|
|
89
|
+
test("flagsForSeed()'s set(bool) return type (cdktn.IResolvable) is one of the exact union members flagSet()'s set(bool) parameter declares", () => {
|
|
90
|
+
expect(providerFunctionsOutput).toContain("public flagsForSeed(seed: string): cdktn.IResolvable {");
|
|
91
|
+
expect(providerFunctionsOutput).toContain("public flagSet(flags: Array<boolean | cdktn.IResolvable> | cdktn.IResolvable): cdktn.IResolvable {");
|
|
92
|
+
});
|
|
93
|
+
test("defaultTags()'s map(string) return type is textually identical to tagMap()'s map(string) parameter type", () => {
|
|
94
|
+
expect(providerFunctionsOutput).toContain("public defaultTags(prefix: string): { [key: string]: string } {");
|
|
95
|
+
expect(providerFunctionsOutput).toContain("public tagMap(tags: { [key: string]: string }): string {");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
test("a list(bool) parameter (not just set(bool)) also accepts a whole-collection token", () => {
|
|
99
|
+
expect(providerFunctionsOutput).toContain("public flagsOrdered(flags: Array<boolean | cdktn.IResolvable> | cdktn.IResolvable): cdktn.IResolvable {");
|
|
100
|
+
});
|
|
101
|
+
test("a list(object) parameter widens to any[] | cdktn.IResolvable (whole-collection token accepted)", () => {
|
|
102
|
+
expect(providerFunctionsOutput).toContain("public describeConfigs(configs: any[] | cdktn.IResolvable): string {");
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
test("buildProviderFunctionsModel throws when two function names collapse to the same generated method name", () => {
|
|
106
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
107
|
+
foo_bar: { return_type: "string", parameters: [] },
|
|
108
|
+
foo__bar: { return_type: "string", parameters: [] },
|
|
109
|
+
})).toThrow(/foo_bar/);
|
|
110
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
111
|
+
foo_bar: { return_type: "string", parameters: [] },
|
|
112
|
+
foo__bar: { return_type: "string", parameters: [] },
|
|
113
|
+
})).toThrow(/foo__bar/);
|
|
114
|
+
});
|
|
115
|
+
test("buildProviderFunctionsModel throws when two parameter names collapse within one function", () => {
|
|
116
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
117
|
+
my_function: {
|
|
118
|
+
return_type: "string",
|
|
119
|
+
parameters: [
|
|
120
|
+
{ name: "some_value", type: "string" },
|
|
121
|
+
{ name: "some__value", type: "string" },
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
})).toThrow(/some_value/);
|
|
125
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
126
|
+
my_function: {
|
|
127
|
+
return_type: "string",
|
|
128
|
+
parameters: [
|
|
129
|
+
{ name: "some_value", type: "string" },
|
|
130
|
+
{ name: "some__value", type: "string" },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
})).toThrow(/some__value/);
|
|
134
|
+
});
|
|
135
|
+
// Both of these assert the model-level throw happens before any file is
|
|
136
|
+
// generated: buildProviderFunctionsModel is called directly, with no
|
|
137
|
+
// CodeMaker/generator involved, so there is no emission step to reach.
|
|
138
|
+
test("buildProviderFunctionsModel throws when a function name sanitizes to 'constructor'", () => {
|
|
139
|
+
// The nested signature literal is cast to `FunctionSignature` (rather than
|
|
140
|
+
// relying on contextual typing from the surrounding index signature)
|
|
141
|
+
// because TypeScript special-cases a property literally named
|
|
142
|
+
// "constructor" - contextually typing it against `Function` (from
|
|
143
|
+
// `Object.prototype`) instead of the index signature's `FunctionSignature`,
|
|
144
|
+
// and spuriously flagging `return_type: "string"` as an error. See
|
|
145
|
+
// https://github.com/microsoft/TypeScript/issues/40776.
|
|
146
|
+
const signature = {
|
|
147
|
+
return_type: "string",
|
|
148
|
+
parameters: [],
|
|
149
|
+
};
|
|
150
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
151
|
+
constructor: signature,
|
|
152
|
+
})).toThrow(/constructor/);
|
|
153
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
154
|
+
constructor: signature,
|
|
155
|
+
})).toThrow(/example/);
|
|
156
|
+
});
|
|
157
|
+
test("buildProviderFunctionsModel throws when a function name sanitizes to 'providerLocalName'", () => {
|
|
158
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
159
|
+
provider_local_name: { return_type: "string", parameters: [] },
|
|
160
|
+
})).toThrow(/provider_local_name/);
|
|
161
|
+
expect(() => (0, provider_function_model_1.buildProviderFunctionsModel)("example", {
|
|
162
|
+
provider_local_name: { return_type: "string", parameters: [] },
|
|
163
|
+
})).toThrow(/providerLocalName/);
|
|
164
|
+
});
|
|
165
|
+
test("assertNoFunctionsGetterCollision throws when the provider's own config schema would generate a 'functions' property", () => {
|
|
166
|
+
expect(() => (0, provider_function_model_1.assertNoFunctionsGetterCollision)("example", ["alias", "functions"])).toThrow(/"functions"/);
|
|
167
|
+
});
|
|
168
|
+
test("assertNoFunctionsGetterCollision does not throw when there is no colliding attribute", () => {
|
|
169
|
+
expect(() => (0, provider_function_model_1.assertNoFunctionsGetterCollision)("example", ["alias"])).not.toThrow();
|
|
170
|
+
});
|
|
171
|
+
test("generation throws when a provider's config attribute collides with the generated 'functions' getter", async () => {
|
|
172
|
+
const code = new codemaker_1.CodeMaker();
|
|
173
|
+
const spec = JSON.parse(fs.readFileSync(path.join(__dirname, "fixtures", "provider-functions-collision.test.fixture.json"), "utf-8"));
|
|
174
|
+
expect(() => new provider_generator_1.TerraformProviderGenerator(code, spec).generateAll()).toThrow(/"functions"/);
|
|
175
|
+
});
|
|
176
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXItZnVuY3Rpb25zLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZ2V0L19fdGVzdHNfXy9nZW5lcmF0b3IvcHJvdmlkZXItZnVuY3Rpb25zLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtCQUErQjtBQUMvQixtQ0FBbUM7QUFDbkMsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUM3QiwyRUFBZ0Y7QUFDaEYsNEZBR3dEO0FBQ3hELHlDQUFzQztBQUV0QyxrQ0FBMEM7QUFFMUMsTUFBTSxHQUFHLEdBQUcsSUFBQSxzQkFBZSxHQUFFLENBQUM7QUFFOUIsSUFBSSxDQUFDLDJGQUEyRixFQUFFLEtBQUssSUFBSSxFQUFFO0lBQzNHLE1BQU0sSUFBSSxHQUFHLElBQUkscUJBQVMsRUFBRSxDQUFDO0lBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQ3JCLEVBQUUsQ0FBQyxZQUFZLENBQ2IsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLHNDQUFzQyxDQUFDLEVBQ3hFLE9BQU8sQ0FDUixDQUNGLENBQUM7SUFDRixJQUFJLCtDQUEwQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN6RCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFekIsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSw0Q0FBNEMsQ0FBQyxFQUNoRSxPQUFPLENBQ1IsQ0FBQztJQUNGLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLGVBQWUsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBRTNFLE1BQU0sY0FB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QUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgVGVycmFmb3JtUHJvdmlkZXJHZW5lcmF0b3IgfSBmcm9tIFwiLi4vLi4vZ2VuZXJhdG9yL3Byb3ZpZGVyLWdlbmVyYXRvclwiO1xuaW1wb3J0IHtcbiAgYXNzZXJ0Tm9GdW5jdGlvbnNHZXR0ZXJDb2xsaXNpb24sXG4gIGJ1aWxkUHJvdmlkZXJGdW5jdGlvbnNNb2RlbCxcbn0gZnJvbSBcIi4uLy4uL2dlbmVyYXRvci9tb2RlbHMvcHJvdmlkZXItZnVuY3Rpb24tbW9kZWxcIjtcbmltcG9ydCB7IENvZGVNYWtlciB9IGZyb20gXCJjb2RlbWFrZXJcIjtcbmltcG9ydCB7IEZ1bmN0aW9uU2lnbmF0dXJlIH0gZnJvbSBcIkBjZGt0bi9jb21tb25zXCI7XG5pbXBvcnQgeyBjcmVhdGVUbXBIZWxwZXIgfSBmcm9tIFwiLi4vdXRpbFwiO1xuXG5jb25zdCB0bXAgPSBjcmVhdGVUbXBIZWxwZXIoKTtcblxudGVzdChcImdlbmVyYXRlIHByb3ZpZGVyIGZ1bmN0aW9ucyBmb3IgdGhlIHRpbWUgcHJvdmlkZXIgKHJlYWwgdGVycmFmb3JtIDEuMTUuNiBzY2hlbWEgZnJhZ21lbnQpXCIsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgY29kZSA9IG5ldyBDb2RlTWFrZXIoKTtcbiAgY29uc3Qgd29ya2RpciA9IHRtcChcInByb3ZpZGVyLWZ1bmN0aW9ucy50ZXN0XCIpO1xuICBjb25zdCBzcGVjID0gSlNPTi5wYXJzZShcbiAgICBmcy5yZWFkRmlsZVN5bmMoXG4gICAgICBwYXRoLmpvaW4oX19kaXJuYW1lLCBcImZpeHR1cmVzXCIsIFwicHJvdmlkZXItZnVuY3Rpb25zLnRlc3QuZml4dHVyZS5qc29uXCIpLFxuICAgICAgXCJ1dGYtOFwiLFxuICAgICksXG4gICk7XG4gIG5ldyBUZXJyYWZvcm1Qcm92aWRlckdlbmVyYXRvcihjb2RlLCBzcGVjKS5nZW5lcmF0ZUFsbCgpO1xuICBhd2FpdCBjb2RlLnNhdmUod29ya2Rpcik7XG5cbiAgY29uc3QgcHJvdmlkZXJGdW5jdGlvbnNPdXRwdXQgPSBmcy5yZWFkRmlsZVN5bmMoXG4gICAgcGF0aC5qb2luKHdvcmtkaXIsIFwicHJvdmlkZXJzL3RpbWUvcHJvdmlkZXItZnVuY3Rpb25zL2luZGV4LnRzXCIpLFxuICAgIFwidXRmLThcIixcbiAgKTtcbiAgZXhwZWN0KHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0KS50b01hdGNoU25hcHNob3QoXCJ0aW1lLXByb3ZpZGVyLWZ1bmN0aW9uc1wiKTtcblxuICBjb25zdCBwcm92aWRlck91dHB1dCA9IGZzLnJlYWRGaWxlU3luYyhcbiAgICBwYXRoLmpvaW4od29ya2RpciwgXCJwcm92aWRlcnMvdGltZS9wcm92aWRlci9pbmRleC50c1wiKSxcbiAgICBcInV0Zi04XCIsXG4gICk7XG4gIGV4cGVjdChwcm92aWRlck91dHB1dCkudG9NYXRjaFNuYXBzaG90KFwidGltZS1wcm92aWRlclwiKTtcblxuICBjb25zdCBwcm92aWRlckluZGV4ID0gZnMucmVhZEZpbGVTeW5jKFxuICAgIHBhdGguam9pbih3b3JrZGlyLCBcInByb3ZpZGVycy90aW1lL2luZGV4LnRzXCIpLFxuICAgIFwidXRmLThcIixcbiAgKTtcbiAgZXhwZWN0KHByb3ZpZGVySW5kZXgpLnRvTWF0Y2hTbmFwc2hvdChcInByb3ZpZGVyLWluZGV4XCIpO1xuXG4gIGNvbnN0IHByb3ZpZGVyTGF6eUluZGV4ID0gZnMucmVhZEZpbGVTeW5jKFxuICAgIHBhdGguam9pbih3b3JrZGlyLCBcInByb3ZpZGVycy90aW1lL2xhenktaW5kZXgudHNcIiksXG4gICAgXCJ1dGYtOFwiLFxuICApO1xuICBleHBlY3QocHJvdmlkZXJMYXp5SW5kZXgpLnRvTWF0Y2hTbmFwc2hvdChcInByb3ZpZGVyLWxhenktaW5kZXhcIik7XG59KTtcblxuZGVzY3JpYmUoXCJnZW5lcmF0ZSBwcm92aWRlciBmdW5jdGlvbnMgY292ZXJpbmcgdmFyaWFkaWMgcGFyYW1ldGVycywgcHJpbWl0aXZlL2xpc3QgcmV0dXJucywgYW5kIGEgJ2RlZmF1bHQnIHBhcmFtZXRlciBuYW1lXCIsICgpID0+IHtcbiAgbGV0IHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0OiBzdHJpbmc7XG4gIGxldCBwcm92aWRlckluZGV4OiBzdHJpbmc7XG4gIGxldCBwcm92aWRlckxhenlJbmRleDogc3RyaW5nO1xuXG4gIGJlZm9yZUFsbChhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY29kZSA9IG5ldyBDb2RlTWFrZXIoKTtcbiAgICBjb25zdCB3b3JrZGlyID0gdG1wKFwicHJvdmlkZXItZnVuY3Rpb25zLXN5bnRoZXRpYy50ZXN0XCIpO1xuICAgIGNvbnN0IHNwZWMgPSBKU09OLnBhcnNlKFxuICAgICAgZnMucmVhZEZpbGVTeW5jKFxuICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgX19kaXJuYW1lLFxuICAgICAgICAgIFwiZml4dHVyZXNcIixcbiAgICAgICAgICBcInByb3ZpZGVyLWZ1bmN0aW9ucy1zeW50aGV0aWMudGVzdC5maXh0dXJlLmpzb25cIixcbiAgICAgICAgKSxcbiAgICAgICAgXCJ1dGYtOFwiLFxuICAgICAgKSxcbiAgICApO1xuICAgIG5ldyBUZXJyYWZvcm1Qcm92aWRlckdlbmVyYXRvcihjb2RlLCBzcGVjKS5nZW5lcmF0ZUFsbCgpO1xuICAgIGF3YWl0IGNvZGUuc2F2ZSh3b3JrZGlyKTtcblxuICAgIHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0ID0gZnMucmVhZEZpbGVTeW5jKFxuICAgICAgcGF0aC5qb2luKHdvcmtkaXIsIFwicHJvdmlkZXJzL2V4YW1wbGUvcHJvdmlkZXItZnVuY3Rpb25zL2luZGV4LnRzXCIpLFxuICAgICAgXCJ1dGYtOFwiLFxuICAgICk7XG4gICAgcHJvdmlkZXJJbmRleCA9IGZzLnJlYWRGaWxlU3luYyhcbiAgICAgIHBhdGguam9pbih3b3JrZGlyLCBcInByb3ZpZGVycy9leGFtcGxlL2luZGV4LnRzXCIpLFxuICAgICAgXCJ1dGYtOFwiLFxuICAgICk7XG4gICAgcHJvdmlkZXJMYXp5SW5kZXggPSBmcy5yZWFkRmlsZVN5bmMoXG4gICAgICBwYXRoLmpvaW4od29ya2RpciwgXCJwcm92aWRlcnMvZXhhbXBsZS9sYXp5LWluZGV4LnRzXCIpLFxuICAgICAgXCJ1dGYtOFwiLFxuICAgICk7XG4gIH0pO1xuXG4gIHRlc3QoXCJtYXRjaGVzIHRoZSBzbmFwc2hvdFwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0KS50b01hdGNoU25hcHNob3QoXG4gICAgICBcImV4YW1wbGUtcHJvdmlkZXItZnVuY3Rpb25zXCIsXG4gICAgKTtcbiAgICBleHBlY3QocHJvdmlkZXJJbmRleCkudG9NYXRjaFNuYXBzaG90KFwicHJvdmlkZXItaW5kZXhcIik7XG4gICAgZXhwZWN0KHByb3ZpZGVyTGF6eUluZGV4KS50b01hdGNoU25hcHNob3QoXCJwcm92aWRlci1sYXp5LWluZGV4XCIpO1xuICB9KTtcblxuICB0ZXN0KFwibmVzdGVkIGNvbGxlY3Rpb24gZG9jc3RyaW5ncyB1c2UgdGhlIGNvbXBhY3QgcmVjdXJzaXZlIEFycmF5L1NldCBub3RhdGlvblwiLCAoKSA9PiB7XG4gICAgLy8gbGlzdChzZXQoc3RyaW5nKSk6IG5vdGF0aW9uIGNhcnJpZXMgdGhlIHN0cnVjdHVyZTsgYSBwbGFpbiBUZXJyYWZvcm1cbiAgICAvLyBsaXN0IG5lZWRzIG5vIHByb3NlIG5vdGUuXG4gICAgZXhwZWN0KHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0KS50b0NvbnRhaW4oXG4gICAgICBcIkBwYXJhbSB7QXJyYXk8U2V0PHN0cmluZz4+fSBuYW1lR3JvdXBzXCIsXG4gICAgKTtcbiAgICBleHBlY3QocHJvdmlkZXJGdW5jdGlvbnNPdXRwdXQpLnRvQ29udGFpbihcIkByZXR1cm5zIHtBcnJheTxTZXQ8c3RyaW5nPj59XCIpO1xuICAgIC8vIHNldChsaXN0KHN0cmluZykpOiBTZXQ8Li4uPiBub3RhdGlvbiBwbHVzIHRoZSBzZXQtc2VtYW50aWNzIHByb3NlIG5vdGVcbiAgICAvLyAodGhlIGpzaWkgdHlwZSBpcyBzdGlsbCBhbiBhcnJheSAtIHRoZSBub3RlIGtlZXBzIGEgcmVhZGVyIGZyb21cbiAgICAvLyBsaXRlcmFsbHkgcGFzc2luZyBhIEpTIFNldCkuXG4gICAgZXhwZWN0KHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0KS50b0NvbnRhaW4oXG4gICAgICBcIkBwYXJhbSB7U2V0PEFycmF5PHN0cmluZz4+fSBuYW1lTGlzdHMgLSBUZXJyYWZvcm0gc2V0OyBvcmRlcmluZyBpcyBub3QgZ3VhcmFudGVlZCBhbmQgZHVwbGljYXRlIHZhbHVlcyBhcmUgcmVtb3ZlZC5cIixcbiAgICApO1xuICAgIGV4cGVjdChwcm92aWRlckZ1bmN0aW9uc091dHB1dCkudG9Db250YWluKFxuICAgICAgXCJAcmV0dXJucyB7U2V0PEFycmF5PHN0cmluZz4+fSBUZXJyYWZvcm0gc2V0OyBvcmRlcmluZyBpcyBub3QgZ3VhcmFudGVlZCBhbmQgZHVwbGljYXRlIHZhbHVlcyBhcmUgcmVtb3ZlZC5cIixcbiAgICApO1xuICB9KTtcblxuICAvLyBUaGlzIHBhY2thZ2UgaGFzIG5vIFR5cGVTY3JpcHQtY29tcGlsaW5nIGhhcm5lc3NcbiAgLy8gZm9yIGdlbmVyYXRlZCBvdXRwdXQgKG5vIGZpeHR1cmUvdGVzdCBhbnl3aGVyZSBnZW5lcmF0ZXMgYSBzbmlwcGV0IGFuZFxuICAvLyBmZWVkcyBpdCB0aHJvdWdoIGB0c2NgL2B0cy50cmFuc3BpbGVNb2R1bGVgLCBhbmQgYGNka3RuYCBpdHNlbGYgaXNuJ3QgYVxuICAvLyBkZXBlbmRlbmN5IG9mIHRoaXMgcGFja2FnZSB0byB0eXBlY2hlY2sgYWdhaW5zdCksIHNvIHRoZXNlIGFyZVxuICAvLyBzdHJ1Y3R1cmFsIGFzc2VydGlvbnMgb24gdGhlIGVtaXR0ZWQgZGVjbGFyYXRpb24gdGV4dCByYXRoZXIgdGhhbiBhblxuICAvLyBhY3R1YWwgY29tcGlsZSAtIHNlZSBhbHNvIHRoZSBydW50aW1lLWxldmVsIHByb29mIGluXG4gIC8vIHBhY2thZ2VzL2Nka3RuL3Rlc3QvcHJvdmlkZXItZnVuY3Rpb25zLnRlc3QudHMsIHdoaWNoIGV4ZXJjaXNlcyB0aGVcbiAgLy8gc2FtZSB1bmlvbi90b2tlbiBtZWNoYW5pY3MgdGhlc2Ugc2lnbmF0dXJlcyByZWx5IG9uLlxuICBkZXNjcmliZShcImNvbXBvc2l0aW9uOiBhIGZ1bmN0aW9uJ3MgcmV0dXJuIHR5cGUgaXMgZGlyZWN0bHkgYXNzaWduYWJsZSB0byBhbm90aGVyIGZ1bmN0aW9uJ3MgcGFyYW1ldGVyIG9mIHRoZSAnc2FtZScgVGVycmFmb3JtIHR5cGVcIiwgKCkgPT4ge1xuICAgIHRlc3QoXCJmbGFnc0ZvclNlZWQoKSdzIHNldChib29sKSByZXR1cm4gdHlwZSAoY2RrdG4uSVJlc29sdmFibGUpIGlzIG9uZSBvZiB0aGUgZXhhY3QgdW5pb24gbWVtYmVycyBmbGFnU2V0KCkncyBzZXQoYm9vbCkgcGFyYW1ldGVyIGRlY2xhcmVzXCIsICgpID0+IHtcbiAgICAgIGV4cGVjdChwcm92aWRlckZ1bmN0aW9uc091dHB1dCkudG9Db250YWluKFxuICAgICAgICBcInB1YmxpYyBmbGFnc0ZvclNlZWQoc2VlZDogc3RyaW5nKTogY2RrdG4uSVJlc29sdmFibGUge1wiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChwcm92aWRlckZ1bmN0aW9uc091dHB1dCkudG9Db250YWluKFxuICAgICAgICBcInB1YmxpYyBmbGFnU2V0KGZsYWdzOiBBcnJheTxib29sZWFuIHwgY2RrdG4uSVJlc29sdmFibGU+IHwgY2RrdG4uSVJlc29sdmFibGUpOiBjZGt0bi5JUmVzb2x2YWJsZSB7XCIsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdChcImRlZmF1bHRUYWdzKCkncyBtYXAoc3RyaW5nKSByZXR1cm4gdHlwZSBpcyB0ZXh0dWFsbHkgaWRlbnRpY2FsIHRvIHRhZ01hcCgpJ3MgbWFwKHN0cmluZykgcGFyYW1ldGVyIHR5cGVcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0KS50b0NvbnRhaW4oXG4gICAgICAgIFwicHVibGljIGRlZmF1bHRUYWdzKHByZWZpeDogc3RyaW5nKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHByb3ZpZGVyRnVuY3Rpb25zT3V0cHV0KS50b0NvbnRhaW4oXG4gICAgICAgIFwicHVibGljIHRhZ01hcCh0YWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogc3RyaW5nIHtcIixcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoXCJhIGxpc3QoYm9vbCkgcGFyYW1ldGVyIChub3QganVzdCBzZXQoYm9vbCkpIGFsc28gYWNjZXB0cyBhIHdob2xlLWNvbGxlY3Rpb24gdG9rZW5cIiwgKCkgPT4ge1xuICAgIGV4cGVjdChwcm92aWRlckZ1bmN0aW9uc091dHB1dCkudG9Db250YWluKFxuICAgICAgXCJwdWJsaWMgZmxhZ3NPcmRlcmVkKGZsYWdzOiBBcnJheTxib29sZWFuIHwgY2RrdG4uSVJlc29sdmFibGU+IHwgY2RrdG4uSVJlc29sdmFibGUpOiBjZGt0bi5JUmVzb2x2YWJsZSB7XCIsXG4gICAgKTtcbiAgfSk7XG5cbiAgdGVzdChcImEgbGlzdChvYmplY3QpIHBhcmFtZXRlciB3aWRlbnMgdG8gYW55W10gfCBjZGt0bi5JUmVzb2x2YWJsZSAod2hvbGUtY29sbGVjdGlvbiB0b2tlbiBhY2NlcHRlZClcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChwcm92aWRlckZ1bmN0aW9uc091dHB1dCkudG9Db250YWluKFxuICAgICAgXCJwdWJsaWMgZGVzY3JpYmVDb25maWdzKGNvbmZpZ3M6IGFueVtdIHwgY2RrdG4uSVJlc29sdmFibGUpOiBzdHJpbmcge1wiLFxuICAgICk7XG4gIH0pO1xufSk7XG5cbnRlc3QoXCJidWlsZFByb3ZpZGVyRnVuY3Rpb25zTW9kZWwgdGhyb3dzIHdoZW4gdHdvIGZ1bmN0aW9uIG5hbWVzIGNvbGxhcHNlIHRvIHRoZSBzYW1lIGdlbmVyYXRlZCBtZXRob2QgbmFtZVwiLCAoKSA9PiB7XG4gIGV4cGVjdCgoKSA9PlxuICAgIGJ1aWxkUHJvdmlkZXJGdW5jdGlvbnNNb2RlbChcImV4YW1wbGVcIiwge1xuICAgICAgZm9vX2JhcjogeyByZXR1cm5fdHlwZTogXCJzdHJpbmdcIiwgcGFyYW1ldGVyczogW10gfSxcbiAgICAgIGZvb19fYmFyOiB7IHJldHVybl90eXBlOiBcInN0cmluZ1wiLCBwYXJhbWV0ZXJzOiBbXSB9LFxuICAgIH0pLFxuICApLnRvVGhyb3coL2Zvb19iYXIvKTtcbiAgZXhwZWN0KCgpID0+XG4gICAgYnVpbGRQcm92aWRlckZ1bmN0aW9uc01vZGVsKFwiZXhhbXBsZVwiLCB7XG4gICAgICBmb29fYmFyOiB7IHJldHVybl90eXBlOiBcInN0cmluZ1wiLCBwYXJhbWV0ZXJzOiBbXSB9LFxuICAgICAgZm9vX19iYXI6IHsgcmV0dXJuX3R5cGU6IFwic3RyaW5nXCIsIHBhcmFtZXRlcnM6IFtdIH0sXG4gICAgfSksXG4gICkudG9UaHJvdygvZm9vX19iYXIvKTtcbn0pO1xuXG50ZXN0KFwiYnVpbGRQcm92aWRlckZ1bmN0aW9uc01vZGVsIHRocm93cyB3aGVuIHR3byBwYXJhbWV0ZXIgbmFtZXMgY29sbGFwc2Ugd2l0aGluIG9uZSBmdW5jdGlvblwiLCAoKSA9PiB7XG4gIGV4cGVjdCgoKSA9PlxuICAgIGJ1aWxkUHJvdmlkZXJGdW5jdGlvbnNNb2RlbChcImV4YW1wbGVcIiwge1xuICAgICAgbXlfZnVuY3Rpb246IHtcbiAgICAgICAgcmV0dXJuX3R5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgIHBhcmFtZXRlcnM6IFtcbiAgICAgICAgICB7IG5hbWU6IFwic29tZV92YWx1ZVwiLCB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgeyBuYW1lOiBcInNvbWVfX3ZhbHVlXCIsIHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfSksXG4gICkudG9UaHJvdygvc29tZV92YWx1ZS8pO1xuICBleHBlY3QoKCkgPT5cbiAgICBidWlsZFByb3ZpZGVyRnVuY3Rpb25zTW9kZWwoXCJleGFtcGxlXCIsIHtcbiAgICAgIG15X2Z1bmN0aW9uOiB7XG4gICAgICAgIHJldHVybl90eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBwYXJhbWV0ZXJzOiBbXG4gICAgICAgICAgeyBuYW1lOiBcInNvbWVfdmFsdWVcIiwgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgIHsgbmFtZTogXCJzb21lX192YWx1ZVwiLCB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0pLFxuICApLnRvVGhyb3coL3NvbWVfX3ZhbHVlLyk7XG59KTtcblxuLy8gQm90aCBvZiB0aGVzZSBhc3NlcnQgdGhlIG1vZGVsLWxldmVsIHRocm93IGhhcHBlbnMgYmVmb3JlIGFueSBmaWxlIGlzXG4vLyBnZW5lcmF0ZWQ6IGJ1aWxkUHJvdmlkZXJGdW5jdGlvbnNNb2RlbCBpcyBjYWxsZWQgZGlyZWN0bHksIHdpdGggbm9cbi8vIENvZGVNYWtlci9nZW5lcmF0b3IgaW52b2x2ZWQsIHNvIHRoZXJlIGlzIG5vIGVtaXNzaW9uIHN0ZXAgdG8gcmVhY2guXG50ZXN0KFwiYnVpbGRQcm92aWRlckZ1bmN0aW9uc01vZGVsIHRocm93cyB3aGVuIGEgZnVuY3Rpb24gbmFtZSBzYW5pdGl6ZXMgdG8gJ2NvbnN0cnVjdG9yJ1wiLCAoKSA9PiB7XG4gIC8vIFRoZSBuZXN0ZWQgc2lnbmF0dXJlIGxpdGVyYWwgaXMgY2FzdCB0byBgRnVuY3Rpb25TaWduYXR1cmVgIChyYXRoZXIgdGhhblxuICAvLyByZWx5aW5nIG9uIGNvbnRleHR1YWwgdHlwaW5nIGZyb20gdGhlIHN1cnJvdW5kaW5nIGluZGV4IHNpZ25hdHVyZSlcbiAgLy8gYmVjYXVzZSBUeXBlU2NyaXB0IHNwZWNpYWwtY2FzZXMgYSBwcm9wZXJ0eSBsaXRlcmFsbHkgbmFtZWRcbiAgLy8gXCJjb25zdHJ1Y3RvclwiIC0gY29udGV4dHVhbGx5IHR5cGluZyBpdCBhZ2FpbnN0IGBGdW5jdGlvbmAgKGZyb21cbiAgLy8gYE9iamVjdC5wcm90b3R5cGVgKSBpbnN0ZWFkIG9mIHRoZSBpbmRleCBzaWduYXR1cmUncyBgRnVuY3Rpb25TaWduYXR1cmVgLFxuICAvLyBhbmQgc3B1cmlvdXNseSBmbGFnZ2luZyBgcmV0dXJuX3R5cGU6IFwic3RyaW5nXCJgIGFzIGFuIGVycm9yLiBTZWVcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2lzc3Vlcy80MDc3Ni5cbiAgY29uc3Qgc2lnbmF0dXJlOiBGdW5jdGlvblNpZ25hdHVyZSA9IHtcbiAgICByZXR1cm5fdHlwZTogXCJzdHJpbmdcIixcbiAgICBwYXJhbWV0ZXJzOiBbXSxcbiAgfTtcbiAgZXhwZWN0KCgpID0+XG4gICAgYnVpbGRQcm92aWRlckZ1bmN0aW9uc01vZGVsKFwiZXhhbXBsZVwiLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjogc2lnbmF0dXJlLFxuICAgIH0pLFxuICApLnRvVGhyb3coL2NvbnN0cnVjdG9yLyk7XG4gIGV4cGVjdCgoKSA9PlxuICAgIGJ1aWxkUHJvdmlkZXJGdW5jdGlvbnNNb2RlbChcImV4YW1wbGVcIiwge1xuICAgICAgY29uc3RydWN0b3I6IHNpZ25hdHVyZSxcbiAgICB9KSxcbiAgKS50b1Rocm93KC9leGFtcGxlLyk7XG59KTtcblxudGVzdChcImJ1aWxkUHJvdmlkZXJGdW5jdGlvbnNNb2RlbCB0aHJvd3Mgd2hlbiBhIGZ1bmN0aW9uIG5hbWUgc2FuaXRpemVzIHRvICdwcm92aWRlckxvY2FsTmFtZSdcIiwgKCkgPT4ge1xuICBleHBlY3QoKCkgPT5cbiAgICBidWlsZFByb3ZpZGVyRnVuY3Rpb25zTW9kZWwoXCJleGFtcGxlXCIsIHtcbiAgICAgIHByb3ZpZGVyX2xvY2FsX25hbWU6IHsgcmV0dXJuX3R5cGU6IFwic3RyaW5nXCIsIHBhcmFtZXRlcnM6IFtdIH0sXG4gICAgfSksXG4gICkudG9UaHJvdygvcHJvdmlkZXJfbG9jYWxfbmFtZS8pO1xuICBleHBlY3QoKCkgPT5cbiAgICBidWlsZFByb3ZpZGVyRnVuY3Rpb25zTW9kZWwoXCJleGFtcGxlXCIsIHtcbiAgICAgIHByb3ZpZGVyX2xvY2FsX25hbWU6IHsgcmV0dXJuX3R5cGU6IFwic3RyaW5nXCIsIHBhcmFtZXRlcnM6IFtdIH0sXG4gICAgfSksXG4gICkudG9UaHJvdygvcHJvdmlkZXJMb2NhbE5hbWUvKTtcbn0pO1xuXG50ZXN0KFwiYXNzZXJ0Tm9GdW5jdGlvbnNHZXR0ZXJDb2xsaXNpb24gdGhyb3dzIHdoZW4gdGhlIHByb3ZpZGVyJ3Mgb3duIGNvbmZpZyBzY2hlbWEgd291bGQgZ2VuZXJhdGUgYSAnZnVuY3Rpb25zJyBwcm9wZXJ0eVwiLCAoKSA9PiB7XG4gIGV4cGVjdCgoKSA9PlxuICAgIGFzc2VydE5vRnVuY3Rpb25zR2V0dGVyQ29sbGlzaW9uKFwiZXhhbXBsZVwiLCBbXCJhbGlhc1wiLCBcImZ1bmN0aW9uc1wiXSksXG4gICkudG9UaHJvdygvXCJmdW5jdGlvbnNcIi8pO1xufSk7XG5cbnRlc3QoXCJhc3NlcnROb0Z1bmN0aW9uc0dldHRlckNvbGxpc2lvbiBkb2VzIG5vdCB0aHJvdyB3aGVuIHRoZXJlIGlzIG5vIGNvbGxpZGluZyBhdHRyaWJ1dGVcIiwgKCkgPT4ge1xuICBleHBlY3QoKCkgPT5cbiAgICBhc3NlcnROb0Z1bmN0aW9uc0dldHRlckNvbGxpc2lvbihcImV4YW1wbGVcIiwgW1wiYWxpYXNcIl0pLFxuICApLm5vdC50b1Rocm93KCk7XG59KTtcblxudGVzdChcImdlbmVyYXRpb24gdGhyb3dzIHdoZW4gYSBwcm92aWRlcidzIGNvbmZpZyBhdHRyaWJ1dGUgY29sbGlkZXMgd2l0aCB0aGUgZ2VuZXJhdGVkICdmdW5jdGlvbnMnIGdldHRlclwiLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNvZGUgPSBuZXcgQ29kZU1ha2VyKCk7XG4gIGNvbnN0IHNwZWMgPSBKU09OLnBhcnNlKFxuICAgIGZzLnJlYWRGaWxlU3luYyhcbiAgICAgIHBhdGguam9pbihcbiAgICAgICAgX19kaXJuYW1lLFxuICAgICAgICBcImZpeHR1cmVzXCIsXG4gICAgICAgIFwicHJvdmlkZXItZnVuY3Rpb25zLWNvbGxpc2lvbi50ZXN0LmZpeHR1cmUuanNvblwiLFxuICAgICAgKSxcbiAgICAgIFwidXRmLThcIixcbiAgICApLFxuICApO1xuICBleHBlY3QoKCkgPT5cbiAgICBuZXcgVGVycmFmb3JtUHJvdmlkZXJHZW5lcmF0b3IoY29kZSwgc3BlYykuZ2VuZXJhdGVBbGwoKSxcbiAgKS50b1Rocm93KC9cImZ1bmN0aW9uc1wiLyk7XG59KTtcbiJdfQ==
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Copyright (c) HashiCorp, Inc
|
|
4
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
5
|
+
const commons_1 = require("@cdktn/commons");
|
|
6
|
+
const codemaker_1 = require("codemaker");
|
|
7
|
+
const provider_generator_1 = require("../../generator/provider-generator");
|
|
8
|
+
// Builds a minimal provider schema keyed by a single FQPN. The provider body is
|
|
9
|
+
// intentionally empty (like the empty-provider-resources fixture) since these
|
|
10
|
+
// tests only exercise the schema-key <-> target-source matching logic.
|
|
11
|
+
const schemaWithKey = (fqpn) => ({
|
|
12
|
+
provider_schemas: {
|
|
13
|
+
[fqpn]: { resource_schemas: null },
|
|
14
|
+
},
|
|
15
|
+
provider_versions: {
|
|
16
|
+
[fqpn]: "1.84.0",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
const targetForSource = (source) => new commons_1.ConstructsMakerProviderTarget(new commons_1.TerraformProviderConstraint(`${source}@1.84.0`), commons_1.Language.TYPESCRIPT);
|
|
20
|
+
const generateFor = (schemaKey, source) => {
|
|
21
|
+
const generator = new provider_generator_1.TerraformProviderGenerator(new codemaker_1.CodeMaker(), schemaWithKey(schemaKey));
|
|
22
|
+
generator.generate(targetForSource(source));
|
|
23
|
+
return generator;
|
|
24
|
+
};
|
|
25
|
+
describe("provider source matching against schema keys", () => {
|
|
26
|
+
it("matches a shorthand source against an OpenTofu registry schema key", () => {
|
|
27
|
+
// Regression test for #216: `tofu providers schema` returns keys under
|
|
28
|
+
// registry.opentofu.org, so a shorthand source must not assume
|
|
29
|
+
// registry.terraform.io.
|
|
30
|
+
const generator = generateFor("registry.opentofu.org/hashicorp/awscc", "hashicorp/awscc");
|
|
31
|
+
expect(Object.keys(generator.versions)).toContain("registry.opentofu.org/hashicorp/awscc");
|
|
32
|
+
});
|
|
33
|
+
it("matches a shorthand source against a Terraform registry schema key", () => {
|
|
34
|
+
const generator = generateFor("registry.terraform.io/hashicorp/awscc", "hashicorp/awscc");
|
|
35
|
+
expect(Object.keys(generator.versions)).toContain("registry.terraform.io/hashicorp/awscc");
|
|
36
|
+
});
|
|
37
|
+
it("keeps an explicit hostname strict and does not cross registries", () => {
|
|
38
|
+
expect(() => generateFor("registry.opentofu.org/hashicorp/awscc", "registry.terraform.io/hashicorp/awscc")).toThrow(/Could not find provider with constraint/);
|
|
39
|
+
});
|
|
40
|
+
it("matches an explicit hostname when it agrees with the schema key", () => {
|
|
41
|
+
const generator = generateFor("registry.opentofu.org/hashicorp/awscc", "registry.opentofu.org/hashicorp/awscc");
|
|
42
|
+
expect(Object.keys(generator.versions)).toContain("registry.opentofu.org/hashicorp/awscc");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXItc291cmNlLW1hdGNoaW5nLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZ2V0L19fdGVzdHNfXy9nZW5lcmF0b3IvcHJvdmlkZXItc291cmNlLW1hdGNoaW5nLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLDRDQUt3QjtBQUN4Qix5Q0FBc0M7QUFDdEMsMkVBQWdGO0FBRWhGLGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUUsdUVBQXVFO0FBQ3ZFLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBWSxFQUFrQixFQUFFLENBQUMsQ0FBQztJQUN2RCxnQkFBZ0IsRUFBRTtRQUNoQixDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxFQUFTO0tBQzFDO0lBQ0QsaUJBQWlCLEVBQUU7UUFDakIsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRO0tBQ2pCO0NBQ0YsQ0FBQyxDQUFDO0FBRUgsTUFBTSxlQUFlLEdBQUcsQ0FBQyxNQUFjLEVBQUUsRUFBRSxDQUN6QyxJQUFJLHVDQUE2QixDQUMvQixJQUFJLHFDQUEyQixDQUFDLEdBQUcsTUFBTSxTQUFTLENBQUMsRUFDbkQsa0JBQVEsQ0FBQyxVQUFVLENBQ3BCLENBQUM7QUFFSixNQUFNLFdBQVcsR0FBRyxDQUFDLFNBQWlCLEVBQUUsTUFBYyxFQUFFLEVBQUU7SUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSwrQ0FBMEIsQ0FDOUMsSUFBSSxxQkFBUyxFQUFFLEVBQ2YsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUN6QixDQUFDO0lBQ0YsU0FBUyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUM1QyxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDLENBQUM7QUFFRixRQUFRLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO0lBQzVELEVBQUUsQ0FBQyxvRUFBb0UsRUFBRSxHQUFHLEVBQUU7UUFDNUUsdUVBQXVFO1FBQ3ZFLCtEQUErRDtRQUMvRCx5QkFBeUI7UUFDekIsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUMzQix1Q0FBdUMsRUFDdkMsaUJBQWlCLENBQ2xCLENBQUM7UUFFRixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQy9DLHVDQUF1QyxDQUN4QyxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsb0VBQW9FLEVBQUUsR0FBRyxFQUFFO1FBQzVFLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FDM0IsdUNBQXVDLEVBQ3ZDLGlCQUFpQixDQUNsQixDQUFDO1FBRUYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUMvQyx1Q0FBdUMsQ0FDeEMsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlFQUFpRSxFQUFFLEdBQUcsRUFBRTtRQUN6RSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQ1YsV0FBVyxDQUNULHVDQUF1QyxFQUN2Qyx1Q0FBdUMsQ0FDeEMsQ0FDRixDQUFDLE9BQU8sQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO0lBQ3ZELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlFQUFpRSxFQUFFLEdBQUcsRUFBRTtRQUN6RSxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQzNCLHVDQUF1QyxFQUN2Qyx1Q0FBdUMsQ0FDeEMsQ0FBQztRQUVGLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FDL0MsdUNBQXVDLENBQ3hDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCB7XG4gIENvbnN0cnVjdHNNYWtlclByb3ZpZGVyVGFyZ2V0LFxuICBMYW5ndWFnZSxcbiAgUHJvdmlkZXJTY2hlbWEsXG4gIFRlcnJhZm9ybVByb3ZpZGVyQ29uc3RyYWludCxcbn0gZnJvbSBcIkBjZGt0bi9jb21tb25zXCI7XG5pbXBvcnQgeyBDb2RlTWFrZXIgfSBmcm9tIFwiY29kZW1ha2VyXCI7XG5pbXBvcnQgeyBUZXJyYWZvcm1Qcm92aWRlckdlbmVyYXRvciB9IGZyb20gXCIuLi8uLi9nZW5lcmF0b3IvcHJvdmlkZXItZ2VuZXJhdG9yXCI7XG5cbi8vIEJ1aWxkcyBhIG1pbmltYWwgcHJvdmlkZXIgc2NoZW1hIGtleWVkIGJ5IGEgc2luZ2xlIEZRUE4uIFRoZSBwcm92aWRlciBib2R5IGlzXG4vLyBpbnRlbnRpb25hbGx5IGVtcHR5IChsaWtlIHRoZSBlbXB0eS1wcm92aWRlci1yZXNvdXJjZXMgZml4dHVyZSkgc2luY2UgdGhlc2Vcbi8vIHRlc3RzIG9ubHkgZXhlcmNpc2UgdGhlIHNjaGVtYS1rZXkgPC0+IHRhcmdldC1zb3VyY2UgbWF0Y2hpbmcgbG9naWMuXG5jb25zdCBzY2hlbWFXaXRoS2V5ID0gKGZxcG46IHN0cmluZyk6IFByb3ZpZGVyU2NoZW1hID0+ICh7XG4gIHByb3ZpZGVyX3NjaGVtYXM6IHtcbiAgICBbZnFwbl06IHsgcmVzb3VyY2Vfc2NoZW1hczogbnVsbCB9IGFzIGFueSxcbiAgfSxcbiAgcHJvdmlkZXJfdmVyc2lvbnM6IHtcbiAgICBbZnFwbl06IFwiMS44NC4wXCIsXG4gIH0sXG59KTtcblxuY29uc3QgdGFyZ2V0Rm9yU291cmNlID0gKHNvdXJjZTogc3RyaW5nKSA9PlxuICBuZXcgQ29uc3RydWN0c01ha2VyUHJvdmlkZXJUYXJnZXQoXG4gICAgbmV3IFRlcnJhZm9ybVByb3ZpZGVyQ29uc3RyYWludChgJHtzb3VyY2V9QDEuODQuMGApLFxuICAgIExhbmd1YWdlLlRZUEVTQ1JJUFQsXG4gICk7XG5cbmNvbnN0IGdlbmVyYXRlRm9yID0gKHNjaGVtYUtleTogc3RyaW5nLCBzb3VyY2U6IHN0cmluZykgPT4ge1xuICBjb25zdCBnZW5lcmF0b3IgPSBuZXcgVGVycmFmb3JtUHJvdmlkZXJHZW5lcmF0b3IoXG4gICAgbmV3IENvZGVNYWtlcigpLFxuICAgIHNjaGVtYVdpdGhLZXkoc2NoZW1hS2V5KSxcbiAgKTtcbiAgZ2VuZXJhdG9yLmdlbmVyYXRlKHRhcmdldEZvclNvdXJjZShzb3VyY2UpKTtcbiAgcmV0dXJuIGdlbmVyYXRvcjtcbn07XG5cbmRlc2NyaWJlKFwicHJvdmlkZXIgc291cmNlIG1hdGNoaW5nIGFnYWluc3Qgc2NoZW1hIGtleXNcIiwgKCkgPT4ge1xuICBpdChcIm1hdGNoZXMgYSBzaG9ydGhhbmQgc291cmNlIGFnYWluc3QgYW4gT3BlblRvZnUgcmVnaXN0cnkgc2NoZW1hIGtleVwiLCAoKSA9PiB7XG4gICAgLy8gUmVncmVzc2lvbiB0ZXN0IGZvciAjMjE2OiBgdG9mdSBwcm92aWRlcnMgc2NoZW1hYCByZXR1cm5zIGtleXMgdW5kZXJcbiAgICAvLyByZWdpc3RyeS5vcGVudG9mdS5vcmcsIHNvIGEgc2hvcnRoYW5kIHNvdXJjZSBtdXN0IG5vdCBhc3N1bWVcbiAgICAvLyByZWdpc3RyeS50ZXJyYWZvcm0uaW8uXG4gICAgY29uc3QgZ2VuZXJhdG9yID0gZ2VuZXJhdGVGb3IoXG4gICAgICBcInJlZ2lzdHJ5Lm9wZW50b2Z1Lm9yZy9oYXNoaWNvcnAvYXdzY2NcIixcbiAgICAgIFwiaGFzaGljb3JwL2F3c2NjXCIsXG4gICAgKTtcblxuICAgIGV4cGVjdChPYmplY3Qua2V5cyhnZW5lcmF0b3IudmVyc2lvbnMpKS50b0NvbnRhaW4oXG4gICAgICBcInJlZ2lzdHJ5Lm9wZW50b2Z1Lm9yZy9oYXNoaWNvcnAvYXdzY2NcIixcbiAgICApO1xuICB9KTtcblxuICBpdChcIm1hdGNoZXMgYSBzaG9ydGhhbmQgc291cmNlIGFnYWluc3QgYSBUZXJyYWZvcm0gcmVnaXN0cnkgc2NoZW1hIGtleVwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ2VuZXJhdG9yID0gZ2VuZXJhdGVGb3IoXG4gICAgICBcInJlZ2lzdHJ5LnRlcnJhZm9ybS5pby9oYXNoaWNvcnAvYXdzY2NcIixcbiAgICAgIFwiaGFzaGljb3JwL2F3c2NjXCIsXG4gICAgKTtcblxuICAgIGV4cGVjdChPYmplY3Qua2V5cyhnZW5lcmF0b3IudmVyc2lvbnMpKS50b0NvbnRhaW4oXG4gICAgICBcInJlZ2lzdHJ5LnRlcnJhZm9ybS5pby9oYXNoaWNvcnAvYXdzY2NcIixcbiAgICApO1xuICB9KTtcblxuICBpdChcImtlZXBzIGFuIGV4cGxpY2l0IGhvc3RuYW1lIHN0cmljdCBhbmQgZG9lcyBub3QgY3Jvc3MgcmVnaXN0cmllc1wiLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+XG4gICAgICBnZW5lcmF0ZUZvcihcbiAgICAgICAgXCJyZWdpc3RyeS5vcGVudG9mdS5vcmcvaGFzaGljb3JwL2F3c2NjXCIsXG4gICAgICAgIFwicmVnaXN0cnkudGVycmFmb3JtLmlvL2hhc2hpY29ycC9hd3NjY1wiLFxuICAgICAgKSxcbiAgICApLnRvVGhyb3coL0NvdWxkIG5vdCBmaW5kIHByb3ZpZGVyIHdpdGggY29uc3RyYWludC8pO1xuICB9KTtcblxuICBpdChcIm1hdGNoZXMgYW4gZXhwbGljaXQgaG9zdG5hbWUgd2hlbiBpdCBhZ3JlZXMgd2l0aCB0aGUgc2NoZW1hIGtleVwiLCAoKSA9PiB7XG4gICAgY29uc3QgZ2VuZXJhdG9yID0gZ2VuZXJhdGVGb3IoXG4gICAgICBcInJlZ2lzdHJ5Lm9wZW50b2Z1Lm9yZy9oYXNoaWNvcnAvYXdzY2NcIixcbiAgICAgIFwicmVnaXN0cnkub3BlbnRvZnUub3JnL2hhc2hpY29ycC9hd3NjY1wiLFxuICAgICk7XG5cbiAgICBleHBlY3QoT2JqZWN0LmtleXMoZ2VuZXJhdG9yLnZlcnNpb25zKSkudG9Db250YWluKFxuICAgICAgXCJyZWdpc3RyeS5vcGVudG9mdS5vcmcvaGFzaGljb3JwL2F3c2NjXCIsXG4gICAgKTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -39,6 +39,10 @@ test("generate provider", async () => {
|
|
|
39
39
|
await code.save(workdir);
|
|
40
40
|
const output = fs.readFileSync(path.join(workdir, "providers/aws/provider/index.ts"), "utf-8");
|
|
41
41
|
expect(output).toMatchSnapshot();
|
|
42
|
+
// aws has no provider-defined functions in this fixture - no getter, no
|
|
43
|
+
// cross-directory import should be emitted.
|
|
44
|
+
expect(output).not.toContain("public get functions()");
|
|
45
|
+
expect(output).not.toContain("provider-functions");
|
|
42
46
|
});
|
|
43
47
|
test("generate provider with only block_types", async () => {
|
|
44
48
|
const code = new codemaker_1.CodeMaker();
|
|
@@ -48,5 +52,9 @@ test("generate provider with only block_types", async () => {
|
|
|
48
52
|
await code.save(workdir);
|
|
49
53
|
const output = fs.readFileSync(path.join(workdir, "providers/elasticstack/provider/index.ts"), "utf-8");
|
|
50
54
|
expect(output).toMatchSnapshot();
|
|
55
|
+
// elasticstack has no provider-defined functions in this fixture - no
|
|
56
|
+
// getter, no cross-directory import should be emitted.
|
|
57
|
+
expect(output).not.toContain("public get functions()");
|
|
58
|
+
expect(output).not.toContain("provider-functions");
|
|
51
59
|
});
|
|
52
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
60
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9nZXQvX190ZXN0c19fL2dlbmVyYXRvci9wcm92aWRlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFDN0IsMkVBQWdGO0FBQ2hGLHlDQUFzQztBQUN0QyxrQ0FBMEM7QUFFMUMsTUFBTSxHQUFHLEdBQUcsSUFBQSxzQkFBZSxHQUFFLENBQUM7QUFFOUIsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ25DLE1BQU0sSUFBSSxHQUFHLElBQUkscUJBQVMsRUFBRSxDQUFDO0lBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUNyQixFQUFFLENBQUMsWUFBWSxDQUNiLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxnQ0FBZ0MsQ0FBQyxFQUNsRSxPQUFPLENBQ1IsQ0FDRixDQUFDO0lBQ0YsSUFBSSwrQ0FBMEIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDekQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXpCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGlDQUFpQyxDQUFDLEVBQ3JELE9BQU8sQ0FDUixDQUFDO0lBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ2pDLHdFQUF3RTtJQUN4RSw0Q0FBNEM7SUFDNUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3JELENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLHlDQUF5QyxFQUFFLEtBQUssSUFBSSxFQUFFO0lBQ3pELE1BQU0sSUFBSSxHQUFHLElBQUkscUJBQVMsRUFBRSxDQUFDO0lBQzdCLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUNyQixFQUFFLENBQUMsWUFBWSxDQUNiLElBQUksQ0FBQyxJQUFJLENBQ1AsU0FBUyxFQUNULFVBQVUsRUFDVix5Q0FBeUMsQ0FDMUMsRUFDRCxPQUFPLENBQ1IsQ0FDRixDQUFDO0lBQ0YsSUFBSSwrQ0FBMEIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDekQsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXpCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLDBDQUEwQyxDQUFDLEVBQzlELE9BQU8sQ0FDUixDQUFDO0lBQ0YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ2pDLHNFQUFzRTtJQUN0RSx1REFBdUQ7SUFDdkQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3JELENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgVGVycmFmb3JtUHJvdmlkZXJHZW5lcmF0b3IgfSBmcm9tIFwiLi4vLi4vZ2VuZXJhdG9yL3Byb3ZpZGVyLWdlbmVyYXRvclwiO1xuaW1wb3J0IHsgQ29kZU1ha2VyIH0gZnJvbSBcImNvZGVtYWtlclwiO1xuaW1wb3J0IHsgY3JlYXRlVG1wSGVscGVyIH0gZnJvbSBcIi4uL3V0aWxcIjtcblxuY29uc3QgdG1wID0gY3JlYXRlVG1wSGVscGVyKCk7XG5cbnRlc3QoXCJnZW5lcmF0ZSBwcm92aWRlclwiLCBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IGNvZGUgPSBuZXcgQ29kZU1ha2VyKCk7XG4gIGNvbnN0IHdvcmtkaXIgPSB0bXAoXCJwcm92aWRlci50ZXN0XCIpO1xuICBjb25zdCBzcGVjID0gSlNPTi5wYXJzZShcbiAgICBmcy5yZWFkRmlsZVN5bmMoXG4gICAgICBwYXRoLmpvaW4oX19kaXJuYW1lLCBcImZpeHR1cmVzXCIsIFwiYXdzLXByb3ZpZGVyLnRlc3QuZml4dHVyZS5qc29uXCIpLFxuICAgICAgXCJ1dGYtOFwiLFxuICAgICksXG4gICk7XG4gIG5ldyBUZXJyYWZvcm1Qcm92aWRlckdlbmVyYXRvcihjb2RlLCBzcGVjKS5nZW5lcmF0ZUFsbCgpO1xuICBhd2FpdCBjb2RlLnNhdmUod29ya2Rpcik7XG5cbiAgY29uc3Qgb3V0cHV0ID0gZnMucmVhZEZpbGVTeW5jKFxuICAgIHBhdGguam9pbih3b3JrZGlyLCBcInByb3ZpZGVycy9hd3MvcHJvdmlkZXIvaW5kZXgudHNcIiksXG4gICAgXCJ1dGYtOFwiLFxuICApO1xuICBleHBlY3Qob3V0cHV0KS50b01hdGNoU25hcHNob3QoKTtcbiAgLy8gYXdzIGhhcyBubyBwcm92aWRlci1kZWZpbmVkIGZ1bmN0aW9ucyBpbiB0aGlzIGZpeHR1cmUgLSBubyBnZXR0ZXIsIG5vXG4gIC8vIGNyb3NzLWRpcmVjdG9yeSBpbXBvcnQgc2hvdWxkIGJlIGVtaXR0ZWQuXG4gIGV4cGVjdChvdXRwdXQpLm5vdC50b0NvbnRhaW4oXCJwdWJsaWMgZ2V0IGZ1bmN0aW9ucygpXCIpO1xuICBleHBlY3Qob3V0cHV0KS5ub3QudG9Db250YWluKFwicHJvdmlkZXItZnVuY3Rpb25zXCIpO1xufSk7XG5cbnRlc3QoXCJnZW5lcmF0ZSBwcm92aWRlciB3aXRoIG9ubHkgYmxvY2tfdHlwZXNcIiwgYXN5bmMgKCkgPT4ge1xuICBjb25zdCBjb2RlID0gbmV3IENvZGVNYWtlcigpO1xuICBjb25zdCB3b3JrZGlyID0gdG1wKFwicHJvdmlkZXIudGVzdFwiKTtcbiAgY29uc3Qgc3BlYyA9IEpTT04ucGFyc2UoXG4gICAgZnMucmVhZEZpbGVTeW5jKFxuICAgICAgcGF0aC5qb2luKFxuICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgIFwiZml4dHVyZXNcIixcbiAgICAgICAgXCJlbGFzdGljc3RhY2stcHJvdmlkZXIudGVzdC5maXh0dXJlLmpzb25cIixcbiAgICAgICksXG4gICAgICBcInV0Zi04XCIsXG4gICAgKSxcbiAgKTtcbiAgbmV3IFRlcnJhZm9ybVByb3ZpZGVyR2VuZXJhdG9yKGNvZGUsIHNwZWMpLmdlbmVyYXRlQWxsKCk7XG4gIGF3YWl0IGNvZGUuc2F2ZSh3b3JrZGlyKTtcblxuICBjb25zdCBvdXRwdXQgPSBmcy5yZWFkRmlsZVN5bmMoXG4gICAgcGF0aC5qb2luKHdvcmtkaXIsIFwicHJvdmlkZXJzL2VsYXN0aWNzdGFjay9wcm92aWRlci9pbmRleC50c1wiKSxcbiAgICBcInV0Zi04XCIsXG4gICk7XG4gIGV4cGVjdChvdXRwdXQpLnRvTWF0Y2hTbmFwc2hvdCgpO1xuICAvLyBlbGFzdGljc3RhY2sgaGFzIG5vIHByb3ZpZGVyLWRlZmluZWQgZnVuY3Rpb25zIGluIHRoaXMgZml4dHVyZSAtIG5vXG4gIC8vIGdldHRlciwgbm8gY3Jvc3MtZGlyZWN0b3J5IGltcG9ydCBzaG91bGQgYmUgZW1pdHRlZC5cbiAgZXhwZWN0KG91dHB1dCkubm90LnRvQ29udGFpbihcInB1YmxpYyBnZXQgZnVuY3Rpb25zKClcIik7XG4gIGV4cGVjdChvdXRwdXQpLm5vdC50b0NvbnRhaW4oXCJwcm92aWRlci1mdW5jdGlvbnNcIik7XG59KTtcbiJdfQ==
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// Copyright (c) HashiCorp, Inc
|
|
4
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
5
|
+
const commons_1 = require("@cdktn/commons");
|
|
6
|
+
const supported_stored_classes_1 = require("../../generator/models/supported-stored-classes");
|
|
7
|
+
const models_1 = require("../../generator/models");
|
|
8
|
+
describe("resolveStoredClassName", () => {
|
|
9
|
+
test("own composed name resolves as-is when supported (not collapsed)", () => {
|
|
10
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("stringListMap", "list")).toEqual({
|
|
11
|
+
name: "StringListMap",
|
|
12
|
+
collapsed: false,
|
|
13
|
+
});
|
|
14
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("stringMapMap", "map")).toEqual({
|
|
15
|
+
name: "StringMapMap",
|
|
16
|
+
collapsed: false,
|
|
17
|
+
});
|
|
18
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("numberMapMap", "map")).toEqual({
|
|
19
|
+
name: "NumberMapMap",
|
|
20
|
+
collapsed: false,
|
|
21
|
+
});
|
|
22
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("booleanMapMap", "map")).toEqual({
|
|
23
|
+
name: "BooleanMapMap",
|
|
24
|
+
collapsed: false,
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
test("unsupported own composed name collapses to nearest Any-wrapper", () => {
|
|
28
|
+
// map(map(list(string))) - own "stringListMapMap" unsupported, element is a map
|
|
29
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("stringListMapMap", "map")).toEqual({
|
|
30
|
+
name: "AnyMapMap",
|
|
31
|
+
collapsed: true,
|
|
32
|
+
});
|
|
33
|
+
// list(map(map(string))) - own "stringMapMapList" unsupported, element is a map
|
|
34
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("stringMapMapList", "map")).toEqual({
|
|
35
|
+
name: "AnyMapList",
|
|
36
|
+
collapsed: true,
|
|
37
|
+
});
|
|
38
|
+
// set(map(list(number))) - own "numberListMapList" unsupported, element is a map
|
|
39
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("numberListMapList", "map")).toEqual({
|
|
40
|
+
name: "AnyMapList",
|
|
41
|
+
collapsed: true,
|
|
42
|
+
});
|
|
43
|
+
// map(map(map(list(string)))) - own "stringListMapMapMap" unsupported, element is a map
|
|
44
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("stringListMapMapMap", "map")).toEqual({
|
|
45
|
+
name: "AnyMapMap",
|
|
46
|
+
collapsed: true,
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
test("returns undefined when neither the own name nor a collapsed Any-wrapper exists", () => {
|
|
50
|
+
// Own name doesn't end in List/Map at all.
|
|
51
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("somethingWeird", "map")).toBeUndefined();
|
|
52
|
+
// Own name ends in Map, but the element isn't itself a list/set/map, so there is no
|
|
53
|
+
// "AnyXMap" candidate to fall back to.
|
|
54
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("weirdMap", "struct")).toBeUndefined();
|
|
55
|
+
expect((0, supported_stored_classes_1.resolveStoredClassName)("weirdMap", "simple")).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
// A minimal stand-in for a non-complex, non-collection AttributeTypeModel whose
|
|
59
|
+
// typeModelType is neither "list", "set", "map", nor "simple"/"struct" - i.e. a shape the
|
|
60
|
+
// generator's collapse logic has no candidate class name for. Used to exercise the
|
|
61
|
+
// defensive plain-getter fallback in AttributeModel.getterType without needing a real
|
|
62
|
+
// (currently nonexistent) unsupported shape.
|
|
63
|
+
class UnresolvableStubTypeModel {
|
|
64
|
+
get struct() {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
get isComplex() {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
getStoredClassInitializer(_name) {
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
get storedClassType() {
|
|
74
|
+
return "unresolvable";
|
|
75
|
+
}
|
|
76
|
+
get inputTypeDefinition() {
|
|
77
|
+
return "any";
|
|
78
|
+
}
|
|
79
|
+
getAttributeAccessFunction(name) {
|
|
80
|
+
return `this.interpolationForAttribute('${name}')`;
|
|
81
|
+
}
|
|
82
|
+
get toTerraformFunction() {
|
|
83
|
+
return "cdktn.anyToTerraform";
|
|
84
|
+
}
|
|
85
|
+
get toHclTerraformFunction() {
|
|
86
|
+
return "cdktn.anyToHclTerraform";
|
|
87
|
+
}
|
|
88
|
+
get typeModelType() {
|
|
89
|
+
return "unresolvable-shape";
|
|
90
|
+
}
|
|
91
|
+
get hasReferenceClass() {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
get isTokenizable() {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
get isStoredClassUnavailable() {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
describe("AttributeModel.getterType loud fallback", () => {
|
|
102
|
+
test("falls back to a plain getter and logs a debug breadcrumb when no stored class (not even a collapsed Any-wrapper) is available", () => {
|
|
103
|
+
const debugSpy = jest.spyOn(commons_1.logger, "debug").mockImplementation();
|
|
104
|
+
try {
|
|
105
|
+
// A map whose element is itself an unrecognized shape: own composed name
|
|
106
|
+
// ("unresolvableMap") isn't in the supported set, and the element's typeModelType
|
|
107
|
+
// isn't "list"/"set"/"map", so there is no "AnyXMap" candidate either.
|
|
108
|
+
const type = new models_1.MapAttributeTypeModel(new UnresolvableStubTypeModel());
|
|
109
|
+
expect(type.isStoredClassUnavailable).toBe(true);
|
|
110
|
+
const attribute = new models_1.AttributeModel({
|
|
111
|
+
storageName: "_weirdAttribute",
|
|
112
|
+
name: "weirdAttribute",
|
|
113
|
+
type,
|
|
114
|
+
optional: false,
|
|
115
|
+
computed: true,
|
|
116
|
+
terraformName: "weird_attribute",
|
|
117
|
+
terraformFullName: "test_resource.weird_attribute",
|
|
118
|
+
provider: false,
|
|
119
|
+
required: false,
|
|
120
|
+
});
|
|
121
|
+
expect(attribute.getterType).toEqual({ _type: "plain" });
|
|
122
|
+
expect(attribute.storedClassBoundaryKind).toEqual("fallback");
|
|
123
|
+
expect(debugSpy).toHaveBeenCalledTimes(1);
|
|
124
|
+
const [message] = debugSpy.mock.calls[0];
|
|
125
|
+
expect(message).toContain("test_resource.weird_attribute");
|
|
126
|
+
expect(message).toContain("unresolvableMap");
|
|
127
|
+
// Repeated access must not spam the logger.
|
|
128
|
+
void attribute.getterType;
|
|
129
|
+
void attribute.getterType;
|
|
130
|
+
expect(debugSpy).toHaveBeenCalledTimes(1);
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
debugSpy.mockRestore();
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwcG9ydGVkLXN0b3JlZC1jbGFzc2VzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZ2V0L19fdGVzdHNfXy9nZW5lcmF0b3Ivc3VwcG9ydGVkLXN0b3JlZC1jbGFzc2VzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLDRDQUF3QztBQUN4Qyw4RkFBeUY7QUFDekYsbURBSWdDO0FBRWhDLFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7SUFDdEMsSUFBSSxDQUFDLGlFQUFpRSxFQUFFLEdBQUcsRUFBRTtRQUMzRSxNQUFNLENBQUMsSUFBQSxpREFBc0IsRUFBQyxlQUFlLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDOUQsSUFBSSxFQUFFLGVBQWU7WUFDckIsU0FBUyxFQUFFLEtBQUs7U0FDakIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLElBQUEsaURBQXNCLEVBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzVELElBQUksRUFBRSxjQUFjO1lBQ3BCLFNBQVMsRUFBRSxLQUFLO1NBQ2pCLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxJQUFBLGlEQUFzQixFQUFDLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUM1RCxJQUFJLEVBQUUsY0FBYztZQUNwQixTQUFTLEVBQUUsS0FBSztTQUNqQixDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsSUFBQSxpREFBc0IsRUFBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDN0QsSUFBSSxFQUFFLGVBQWU7WUFDckIsU0FBUyxFQUFFLEtBQUs7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsZ0VBQWdFLEVBQUUsR0FBRyxFQUFF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VUFBVSxDQUFDO1lBQzFCLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDO2dCQUFTLENBQUM7WUFDVCxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDekIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIEhhc2hpQ29ycCwgSW5jXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogTVBMLTIuMFxuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSBcIkBjZGt0bi9jb21tb25zXCI7XG5pbXBvcnQgeyByZXNvbHZlU3RvcmVkQ2xhc3NOYW1lIH0gZnJvbSBcIi4uLy4uL2dlbmVyYXRvci9tb2RlbHMvc3VwcG9ydGVkLXN0b3JlZC1jbGFzc2VzXCI7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVNb2RlbCxcbiAgQXR0cmlidXRlVHlwZU1vZGVsLFxuICBNYXBBdHRyaWJ1dGVUeXBlTW9kZWwsXG59IGZyb20gXCIuLi8uLi9nZW5lcmF0b3IvbW9kZWxzXCI7XG5cbmRlc2NyaWJlKFwicmVzb2x2ZVN0b3JlZENsYXNzTmFtZVwiLCAoKSA9PiB7XG4gIHRlc3QoXCJvd24gY29tcG9zZWQgbmFtZSByZXNvbHZlcyBhcy1pcyB3aGVuIHN1cHBvcnRlZCAobm90IGNvbGxhcHNlZClcIiwgKCkgPT4ge1xuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwic3RyaW5nTGlzdE1hcFwiLCBcImxpc3RcIikpLnRvRXF1YWwoe1xuICAgICAgbmFtZTogXCJTdHJpbmdMaXN0TWFwXCIsXG4gICAgICBjb2xsYXBzZWQ6IGZhbHNlLFxuICAgIH0pO1xuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwic3RyaW5nTWFwTWFwXCIsIFwibWFwXCIpKS50b0VxdWFsKHtcbiAgICAgIG5hbWU6IFwiU3RyaW5nTWFwTWFwXCIsXG4gICAgICBjb2xsYXBzZWQ6IGZhbHNlLFxuICAgIH0pO1xuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwibnVtYmVyTWFwTWFwXCIsIFwibWFwXCIpKS50b0VxdWFsKHtcbiAgICAgIG5hbWU6IFwiTnVtYmVyTWFwTWFwXCIsXG4gICAgICBjb2xsYXBzZWQ6IGZhbHNlLFxuICAgIH0pO1xuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwiYm9vbGVhbk1hcE1hcFwiLCBcIm1hcFwiKSkudG9FcXVhbCh7XG4gICAgICBuYW1lOiBcIkJvb2xlYW5NYXBNYXBcIixcbiAgICAgIGNvbGxhcHNlZDogZmFsc2UsXG4gICAgfSk7XG4gIH0pO1xuXG4gIHRlc3QoXCJ1bnN1cHBvcnRlZCBvd24gY29tcG9zZWQgbmFtZSBjb2xsYXBzZXMgdG8gbmVhcmVzdCBBbnktd3JhcHBlclwiLCAoKSA9PiB7XG4gICAgLy8gbWFwKG1hcChsaXN0KHN0cmluZykpKSAtIG93biBcInN0cmluZ0xpc3RNYXBNYXBcIiB1bnN1cHBvcnRlZCwgZWxlbWVudCBpcyBhIG1hcFxuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwic3RyaW5nTGlzdE1hcE1hcFwiLCBcIm1hcFwiKSkudG9FcXVhbCh7XG4gICAgICBuYW1lOiBcIkFueU1hcE1hcFwiLFxuICAgICAgY29sbGFwc2VkOiB0cnVlLFxuICAgIH0pO1xuICAgIC8vIGxpc3QobWFwKG1hcChzdHJpbmcpKSkgLSBvd24gXCJzdHJpbmdNYXBNYXBMaXN0XCIgdW5zdXBwb3J0ZWQsIGVsZW1lbnQgaXMgYSBtYXBcbiAgICBleHBlY3QocmVzb2x2ZVN0b3JlZENsYXNzTmFtZShcInN0cmluZ01hcE1hcExpc3RcIiwgXCJtYXBcIikpLnRvRXF1YWwoe1xuICAgICAgbmFtZTogXCJBbnlNYXBMaXN0XCIsXG4gICAgICBjb2xsYXBzZWQ6IHRydWUsXG4gICAgfSk7XG4gICAgLy8gc2V0KG1hcChsaXN0KG51bWJlcikpKSAtIG93biBcIm51bWJlckxpc3RNYXBMaXN0XCIgdW5zdXBwb3J0ZWQsIGVsZW1lbnQgaXMgYSBtYXBcbiAgICBleHBlY3QocmVzb2x2ZVN0b3JlZENsYXNzTmFtZShcIm51bWJlckxpc3RNYXBMaXN0XCIsIFwibWFwXCIpKS50b0VxdWFsKHtcbiAgICAgIG5hbWU6IFwiQW55TWFwTGlzdFwiLFxuICAgICAgY29sbGFwc2VkOiB0cnVlLFxuICAgIH0pO1xuICAgIC8vIG1hcChtYXAobWFwKGxpc3Qoc3RyaW5nKSkpKSAtIG93biBcInN0cmluZ0xpc3RNYXBNYXBNYXBcIiB1bnN1cHBvcnRlZCwgZWxlbWVudCBpcyBhIG1hcFxuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwic3RyaW5nTGlzdE1hcE1hcE1hcFwiLCBcIm1hcFwiKSkudG9FcXVhbCh7XG4gICAgICBuYW1lOiBcIkFueU1hcE1hcFwiLFxuICAgICAgY29sbGFwc2VkOiB0cnVlLFxuICAgIH0pO1xuICB9KTtcblxuICB0ZXN0KFwicmV0dXJucyB1bmRlZmluZWQgd2hlbiBuZWl0aGVyIHRoZSBvd24gbmFtZSBub3IgYSBjb2xsYXBzZWQgQW55LXdyYXBwZXIgZXhpc3RzXCIsICgpID0+IHtcbiAgICAvLyBPd24gbmFtZSBkb2Vzbid0IGVuZCBpbiBMaXN0L01hcCBhdCBhbGwuXG4gICAgZXhwZWN0KHJlc29sdmVTdG9yZWRDbGFzc05hbWUoXCJzb21ldGhpbmdXZWlyZFwiLCBcIm1hcFwiKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIC8vIE93biBuYW1lIGVuZHMgaW4gTWFwLCBidXQgdGhlIGVsZW1lbnQgaXNuJ3QgaXRzZWxmIGEgbGlzdC9zZXQvbWFwLCBzbyB0aGVyZSBpcyBub1xuICAgIC8vIFwiQW55WE1hcFwiIGNhbmRpZGF0ZSB0byBmYWxsIGJhY2sgdG8uXG4gICAgZXhwZWN0KHJlc29sdmVTdG9yZWRDbGFzc05hbWUoXCJ3ZWlyZE1hcFwiLCBcInN0cnVjdFwiKSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIGV4cGVjdChyZXNvbHZlU3RvcmVkQ2xhc3NOYW1lKFwid2VpcmRNYXBcIiwgXCJzaW1wbGVcIikpLnRvQmVVbmRlZmluZWQoKTtcbiAgfSk7XG59KTtcblxuLy8gQSBtaW5pbWFsIHN0YW5kLWluIGZvciBhIG5vbi1jb21wbGV4LCBub24tY29sbGVjdGlvbiBBdHRyaWJ1dGVUeXBlTW9kZWwgd2hvc2Vcbi8vIHR5cGVNb2RlbFR5cGUgaXMgbmVpdGhlciBcImxpc3RcIiwgXCJzZXRcIiwgXCJtYXBcIiwgbm9yIFwic2ltcGxlXCIvXCJzdHJ1Y3RcIiAtIGkuZS4gYSBzaGFwZSB0aGVcbi8vIGdlbmVyYXRvcidzIGNvbGxhcHNlIGxvZ2ljIGhhcyBubyBjYW5kaWRhdGUgY2xhc3MgbmFtZSBmb3IuIFVzZWQgdG8gZXhlcmNpc2UgdGhlXG4vLyBkZWZlbnNpdmUgcGxhaW4tZ2V0dGVyIGZhbGxiYWNrIGluIEF0dHJpYnV0ZU1vZGVsLmdldHRlclR5cGUgd2l0aG91dCBuZWVkaW5nIGEgcmVhbFxuLy8gKGN1cnJlbnRseSBub25leGlzdGVudCkgdW5zdXBwb3J0ZWQgc2hhcGUuXG5jbGFzcyBVbnJlc29sdmFibGVTdHViVHlwZU1vZGVsIGltcGxlbWVudHMgQXR0cmlidXRlVHlwZU1vZGVsIHtcbiAgZ2V0IHN0cnVjdCgpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGdldCBpc0NvbXBsZXgoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGdldFN0b3JlZENsYXNzSW5pdGlhbGl6ZXIoX25hbWU6IHN0cmluZykge1xuICAgIHJldHVybiBcIlwiO1xuICB9XG4gIGdldCBzdG9yZWRDbGFzc1R5cGUoKSB7XG4gICAgcmV0dXJuIFwidW5yZXNvbHZhYmxlXCI7XG4gIH1cbiAgZ2V0IGlucHV0VHlwZURlZmluaXRpb24oKSB7XG4gICAgcmV0dXJuIFwiYW55XCI7XG4gIH1cbiAgZ2V0QXR0cmlidXRlQWNjZXNzRnVuY3Rpb24obmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGB0aGlzLmludGVycG9sYXRpb25Gb3JBdHRyaWJ1dGUoJyR7bmFtZX0nKWA7XG4gIH1cbiAgZ2V0IHRvVGVycmFmb3JtRnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFwiY2RrdG4uYW55VG9UZXJyYWZvcm1cIjtcbiAgfVxuICBnZXQgdG9IY2xUZXJyYWZvcm1GdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJjZGt0bi5hbnlUb0hjbFRlcnJhZm9ybVwiO1xuICB9XG4gIGdldCB0eXBlTW9kZWxUeXBlKCkge1xuICAgIHJldHVybiBcInVucmVzb2x2YWJsZS1zaGFwZVwiO1xuICB9XG4gIGdldCBoYXNSZWZlcmVuY2VDbGFzcygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZ2V0IGlzVG9rZW5pemFibGUoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGdldCBpc1N0b3JlZENsYXNzVW5hdmFpbGFibGUoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmRlc2NyaWJlKFwiQXR0cmlidXRlTW9kZWwuZ2V0dGVyVHlwZSBsb3VkIGZhbGxiYWNrXCIsICgpID0+IHtcbiAgdGVzdChcImZhbGxzIGJhY2sgdG8gYSBwbGFpbiBnZXR0ZXIgYW5kIGxvZ3MgYSBkZWJ1ZyBicmVhZGNydW1iIHdoZW4gbm8gc3RvcmVkIGNsYXNzIChub3QgZXZlbiBhIGNvbGxhcHNlZCBBbnktd3JhcHBlcikgaXMgYXZhaWxhYmxlXCIsICgpID0+IHtcbiAgICBjb25zdCBkZWJ1Z1NweSA9IGplc3Quc3B5T24obG9nZ2VyLCBcImRlYnVnXCIpLm1vY2tJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEEgbWFwIHdob3NlIGVsZW1lbnQgaXMgaXRzZWxmIGFuIHVucmVjb2duaXplZCBzaGFwZTogb3duIGNvbXBvc2VkIG5hbWVcbiAgICAgIC8vIChcInVucmVzb2x2YWJsZU1hcFwiKSBpc24ndCBpbiB0aGUgc3VwcG9ydGVkIHNldCwgYW5kIHRoZSBlbGVtZW50J3MgdHlwZU1vZGVsVHlwZVxuICAgICAgLy8gaXNuJ3QgXCJsaXN0XCIvXCJzZXRcIi9cIm1hcFwiLCBzbyB0aGVyZSBpcyBubyBcIkFueVhNYXBcIiBjYW5kaWRhdGUgZWl0aGVyLlxuICAgICAgY29uc3QgdHlwZSA9IG5ldyBNYXBBdHRyaWJ1dGVUeXBlTW9kZWwobmV3IFVucmVzb2x2YWJsZVN0dWJUeXBlTW9kZWwoKSk7XG4gICAgICBleHBlY3QodHlwZS5pc1N0b3JlZENsYXNzVW5hdmFpbGFibGUpLnRvQmUodHJ1ZSk7XG5cbiAgICAgIGNvbnN0IGF0dHJpYnV0ZSA9IG5ldyBBdHRyaWJ1dGVNb2RlbCh7XG4gICAgICAgIHN0b3JhZ2VOYW1lOiBcIl93ZWlyZEF0dHJpYnV0ZVwiLFxuICAgICAgICBuYW1lOiBcIndlaXJkQXR0cmlidXRlXCIsXG4gICAgICAgIHR5cGUsXG4gICAgICAgIG9wdGlvbmFsOiBmYWxzZSxcbiAgICAgICAgY29tcHV0ZWQ6IHRydWUsXG4gICAgICAgIHRlcnJhZm9ybU5hbWU6IFwid2VpcmRfYXR0cmlidXRlXCIsXG4gICAgICAgIHRlcnJhZm9ybUZ1bGxOYW1lOiBcInRlc3RfcmVzb3VyY2Uud2VpcmRfYXR0cmlidXRlXCIsXG4gICAgICAgIHByb3ZpZGVyOiBmYWxzZSxcbiAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChhdHRyaWJ1dGUuZ2V0dGVyVHlwZSkudG9FcXVhbCh7IF90eXBlOiBcInBsYWluXCIgfSk7XG4gICAgICBleHBlY3QoYXR0cmlidXRlLnN0b3JlZENsYXNzQm91bmRhcnlLaW5kKS50b0VxdWFsKFwiZmFsbGJhY2tcIik7XG5cbiAgICAgIGV4cGVjdChkZWJ1Z1NweSkudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICAgICAgY29uc3QgW21lc3NhZ2VdID0gZGVidWdTcHkubW9jay5jYWxsc1swXTtcbiAgICAgIGV4cGVjdChtZXNzYWdlKS50b0NvbnRhaW4oXCJ0ZXN0X3Jlc291cmNlLndlaXJkX2F0dHJpYnV0ZVwiKTtcbiAgICAgIGV4cGVjdChtZXNzYWdlKS50b0NvbnRhaW4oXCJ1bnJlc29sdmFibGVNYXBcIik7XG5cbiAgICAgIC8vIFJlcGVhdGVkIGFjY2VzcyBtdXN0IG5vdCBzcGFtIHRoZSBsb2dnZXIuXG4gICAgICB2b2lkIGF0dHJpYnV0ZS5nZXR0ZXJUeXBlO1xuICAgICAgdm9pZCBhdHRyaWJ1dGUuZ2V0dGVyVHlwZTtcbiAgICAgIGV4cGVjdChkZWJ1Z1NweSkudG9IYXZlQmVlbkNhbGxlZFRpbWVzKDEpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBkZWJ1Z1NweS5tb2NrUmVzdG9yZSgpO1xuICAgIH1cbiAgfSk7XG59KTtcbiJdfQ==
|