@macedon-technologies/batman 1.24.2 → 1.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +2 -2
- package/architecture-rules/README.md +60 -5
- package/architecture-rules/check.ts +58 -2
- package/lib/BatmanProject.js +1 -1
- package/lib/BootcampProject.js +1 -1
- package/lib/CodeOwnersFile.js +1 -1
- package/lib/ProductionDeployWorkflow.js +1 -1
- package/lib/SoftwareFactoryArchitectureRules.js +119 -8
- package/lib/SoftwareFactoryFiles.js +1 -1
- package/lib/StagingDeployWorkflow.js +1 -1
- package/lib/WorkflowAutoDiscover.js +1 -1
- package/package.json +1 -1
package/.jsii
CHANGED
|
@@ -1283,6 +1283,6 @@
|
|
|
1283
1283
|
"symbolId": "src/WorkflowAutoDiscover:WorkflowAutoDiscover"
|
|
1284
1284
|
}
|
|
1285
1285
|
},
|
|
1286
|
-
"version": "1.
|
|
1287
|
-
"fingerprint": "
|
|
1286
|
+
"version": "1.25.0",
|
|
1287
|
+
"fingerprint": "PndeNL5NXQb1TkD3BzT8gxANwXiAJBG0k+/ZMUVENRk="
|
|
1288
1288
|
}
|
|
@@ -9,6 +9,9 @@ needs a genuinely new kind of check.
|
|
|
9
9
|
|
|
10
10
|
## Rule shape
|
|
11
11
|
|
|
12
|
+
Two `check.type`s are implemented: `forbidden-import` (whole-repo import-graph
|
|
13
|
+
check) and `required-companion` (diff-based co-change check).
|
|
14
|
+
|
|
12
15
|
```json
|
|
13
16
|
{
|
|
14
17
|
"id": "unique-id",
|
|
@@ -23,6 +26,56 @@ needs a genuinely new kind of check.
|
|
|
23
26
|
}
|
|
24
27
|
```
|
|
25
28
|
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"id": "unique-id",
|
|
32
|
+
"description": "What this enforces and why.",
|
|
33
|
+
"enabled": true,
|
|
34
|
+
"severity": "low" | "medium" | "high" | "critical",
|
|
35
|
+
"check": {
|
|
36
|
+
"type": "required-companion",
|
|
37
|
+
"from": ["glob patterns selecting changed files that trigger the requirement"],
|
|
38
|
+
"requireOneOf": ["glob patterns -- at least one CHANGED file must match one of these"],
|
|
39
|
+
"exempt": ["optional -- from-files matching these globs don't trigger the requirement"]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`required-companion` evaluates the set of files changed in the current diff
|
|
45
|
+
(`git diff --name-only --diff-filter=ACMR <baseRef>...HEAD`), not the whole
|
|
46
|
+
repo tree: if any changed file matches `from` (and doesn't match `exempt`) but
|
|
47
|
+
no changed file matches `requireOneOf`, that's a violation. The base ref
|
|
48
|
+
defaults to `origin/main` and can be overridden with the
|
|
49
|
+
`ARCHITECTURE_RULES_BASE_REF` environment variable. This means the checkout
|
|
50
|
+
running `pnpm validate:architecture` must have that base ref fetched and
|
|
51
|
+
resolvable (a shallow, single-branch checkout will make the check fail closed
|
|
52
|
+
with an error rather than silently reporting no violations) — make sure
|
|
53
|
+
whatever runs this task fetches enough history for `git diff <baseRef>...HEAD`
|
|
54
|
+
to succeed.
|
|
55
|
+
|
|
56
|
+
`from`/`requireOneOf`/`exempt` globs are matched against the paths `git
|
|
57
|
+
diff --name-only` reports, which are relative to the git repository's
|
|
58
|
+
top-level directory. This lines up with `from`'s own directory (the parent of
|
|
59
|
+
`architecture-rules/`) in the common case — a single project generated at the
|
|
60
|
+
repo root — but if `architecture-rules/` instead lives under a nested
|
|
61
|
+
subdirectory of a larger git repo, write globs relative to the git root, not
|
|
62
|
+
to that subdirectory.
|
|
63
|
+
|
|
64
|
+
**`required-companion` is a coverage check, not a correctness check.** It only
|
|
65
|
+
confirms that *some* changed file matches `requireOneOf` — it can't tell
|
|
66
|
+
whether that change is actually related to the triggering `from` change (a
|
|
67
|
+
trivial or unrelated edit to a file under `requireOneOf` satisfies the rule
|
|
68
|
+
just as well as a substantive one), and it can't tell whether a given `from`
|
|
69
|
+
change genuinely needed a companion at all (a pure refactor might not).
|
|
70
|
+
`exempt` covers *known, glob-expressible* exceptions, but not every false
|
|
71
|
+
positive is expressible as a glob — that judgment call still belongs to the
|
|
72
|
+
rule author (scoping `from`/`exempt`) and the reviewer (reading the companion
|
|
73
|
+
diff, not just trusting that the check passed). Also note that `main()`
|
|
74
|
+
fails the whole run on *any* violation regardless of `severity` — `severity`
|
|
75
|
+
is informational only, not a leniency lever — so start with a narrowly
|
|
76
|
+
scoped `from` (or `enabled: false`) and widen it as the convention proves
|
|
77
|
+
itself, the same guidance as for `forbidden-import`.
|
|
78
|
+
|
|
26
79
|
`enabled: false` rules are skipped (reported as "deferred") rather than
|
|
27
80
|
evaluated — use this for a rule you've named and described but don't yet
|
|
28
81
|
have a concrete convention to check.
|
|
@@ -35,8 +88,10 @@ conventions solidify (e.g. an event-sourced/CQRS module layout under
|
|
|
35
88
|
|
|
36
89
|
## Adding a check type
|
|
37
90
|
|
|
38
|
-
`forbidden-import`
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
91
|
+
`forbidden-import` (whole-repo import graph) and `required-companion`
|
|
92
|
+
(diff-based co-change) are the implemented `check.type`s. If a future rule
|
|
93
|
+
needs a data source neither provides (e.g. "every aggregate file must have a
|
|
94
|
+
matching events file", which is a repo-wide naming convention rather than
|
|
95
|
+
either an import-graph or a diff check), add a new `type` value, a matching
|
|
96
|
+
interface, and a case in `evaluateRule()` in `check.ts` — keep the engine
|
|
97
|
+
itself generic; rule-specific knowledge belongs in `rules.json`.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from 'node:fs';
|
|
8
8
|
import * as path from 'node:path';
|
|
9
|
+
import { execFileSync } from 'node:child_process';
|
|
9
10
|
import rulesFile from './rules.json';
|
|
10
11
|
|
|
11
12
|
interface ForbiddenImportCheck {
|
|
@@ -16,12 +17,22 @@ interface ForbiddenImportCheck {
|
|
|
16
17
|
forbid: string[];
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
interface RequiredCompanionCheck {
|
|
21
|
+
type: 'required-companion';
|
|
22
|
+
// Glob patterns selecting changed files that trigger the requirement.
|
|
23
|
+
from: string[];
|
|
24
|
+
// Glob patterns -- at least one CHANGED file must match one of these.
|
|
25
|
+
requireOneOf: string[];
|
|
26
|
+
// Optional -- 'from' files matching these globs don't trigger the requirement.
|
|
27
|
+
exempt?: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
19
30
|
interface Rule {
|
|
20
31
|
id: string;
|
|
21
32
|
description: string;
|
|
22
33
|
enabled: boolean;
|
|
23
34
|
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
24
|
-
check: ForbiddenImportCheck;
|
|
35
|
+
check: ForbiddenImportCheck | RequiredCompanionCheck;
|
|
25
36
|
}
|
|
26
37
|
|
|
27
38
|
interface Violation {
|
|
@@ -32,6 +43,7 @@ interface Violation {
|
|
|
32
43
|
|
|
33
44
|
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
34
45
|
const IGNORED_DIRS = new Set(['node_modules', '.git', '.swamp', 'cdk.out', 'lib', 'build', 'dist']);
|
|
46
|
+
const BASE_REF = process.env.ARCHITECTURE_RULES_BASE_REF || 'origin/main';
|
|
35
47
|
|
|
36
48
|
// Minimal glob -> RegExp: supports "*", "**", "**/" and literal path segments.
|
|
37
49
|
// No new dependency for this — the only pattern shapes rules.json ever needs
|
|
@@ -69,6 +81,26 @@ function toRepoRelative(absPath: string): string {
|
|
|
69
81
|
return path.relative(REPO_ROOT, absPath).split(path.sep).join('/');
|
|
70
82
|
}
|
|
71
83
|
|
|
84
|
+
// Files changed relative to baseRef, sourced from git rather than the whole-tree
|
|
85
|
+
// walk() below -- required-companion checks care about what a PR touched, not
|
|
86
|
+
// the full repo. Throws (rather than returning []) if baseRef cannot be resolved,
|
|
87
|
+
// so an unfetched base ref fails the check instead of silently reporting no violations.
|
|
88
|
+
function getChangedFiles(baseRef: string): string[] {
|
|
89
|
+
let output: string;
|
|
90
|
+
try {
|
|
91
|
+
output = execFileSync('git', ['diff', '--name-only', '--diff-filter=ACMR', `${baseRef}...HEAD`], {
|
|
92
|
+
cwd: REPO_ROOT,
|
|
93
|
+
encoding: 'utf8',
|
|
94
|
+
});
|
|
95
|
+
} catch (err) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`architecture-rules: failed to compute the changed-file set against base ref "${baseRef}" -- ` +
|
|
98
|
+
`is it fetched and resolvable in this checkout? (${(err as Error).message})`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return output.split('\n').map((line) => line.trim()).filter((line) => line.length > 0);
|
|
102
|
+
}
|
|
103
|
+
|
|
72
104
|
function walk(dir: string, acc: string[] = []): string[] {
|
|
73
105
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
74
106
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
@@ -103,7 +135,7 @@ function resolvedCandidates(fromFile: string, spec: string): string[] {
|
|
|
103
135
|
}
|
|
104
136
|
|
|
105
137
|
function evaluateForbiddenImport(rule: Rule): Violation[] {
|
|
106
|
-
const { from, forbid } = rule.check;
|
|
138
|
+
const { from, forbid } = rule.check as ForbiddenImportCheck;
|
|
107
139
|
if (from.length === 0 || forbid.length === 0) return [];
|
|
108
140
|
|
|
109
141
|
const violations: Violation[] = [];
|
|
@@ -126,10 +158,34 @@ function evaluateForbiddenImport(rule: Rule): Violation[] {
|
|
|
126
158
|
return violations;
|
|
127
159
|
}
|
|
128
160
|
|
|
161
|
+
function evaluateRequiredCompanion(rule: Rule): Violation[] {
|
|
162
|
+
const { from, requireOneOf, exempt } = rule.check as RequiredCompanionCheck;
|
|
163
|
+
if (from.length === 0 || requireOneOf.length === 0) return [];
|
|
164
|
+
|
|
165
|
+
const changedFiles = getChangedFiles(BASE_REF);
|
|
166
|
+
const triggering = changedFiles.filter(
|
|
167
|
+
(file) => matchesAny(file, from) && !(exempt && matchesAny(file, exempt)),
|
|
168
|
+
);
|
|
169
|
+
if (triggering.length === 0) return [];
|
|
170
|
+
|
|
171
|
+
const satisfied = changedFiles.some((file) => matchesAny(file, requireOneOf));
|
|
172
|
+
if (satisfied) return [];
|
|
173
|
+
|
|
174
|
+
return [
|
|
175
|
+
{
|
|
176
|
+
ruleId: rule.id,
|
|
177
|
+
severity: rule.severity,
|
|
178
|
+
message: `changed file(s) ${triggering.join(', ')} match rule "${rule.id}"'s "from" patterns, but no changed file matches its "requireOneOf" patterns`,
|
|
179
|
+
},
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
|
|
129
183
|
function evaluateRule(rule: Rule): Violation[] {
|
|
130
184
|
switch (rule.check.type) {
|
|
131
185
|
case 'forbidden-import':
|
|
132
186
|
return evaluateForbiddenImport(rule);
|
|
187
|
+
case 'required-companion':
|
|
188
|
+
return evaluateRequiredCompanion(rule);
|
|
133
189
|
default:
|
|
134
190
|
throw new Error(`architecture-rules: unknown check.type "${(rule.check as { type: string }).type}" on rule "${rule.id}"`);
|
|
135
191
|
}
|
package/lib/BatmanProject.js
CHANGED
|
@@ -12,7 +12,7 @@ const SoftwareFactoryFiles_1 = require("./SoftwareFactoryFiles");
|
|
|
12
12
|
const utils_1 = require("./utils");
|
|
13
13
|
const ViteReactProject_1 = require("./ViteReactProject");
|
|
14
14
|
class BatmanProject extends awscdk_1.AwsCdkTypeScriptApp {
|
|
15
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.BatmanProject", version: "1.
|
|
15
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.BatmanProject", version: "1.25.0" };
|
|
16
16
|
constructor(options) {
|
|
17
17
|
super({
|
|
18
18
|
...options,
|
package/lib/BootcampProject.js
CHANGED
|
@@ -12,7 +12,7 @@ const SoftwareFactoryFiles_1 = require("./SoftwareFactoryFiles");
|
|
|
12
12
|
const utils_1 = require("./utils");
|
|
13
13
|
const ViteReactProject_1 = require("./ViteReactProject");
|
|
14
14
|
class BootcampProject extends awscdk_1.AwsCdkTypeScriptApp {
|
|
15
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.BootcampProject", version: "1.
|
|
15
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.BootcampProject", version: "1.25.0" };
|
|
16
16
|
constructor(options) {
|
|
17
17
|
super({
|
|
18
18
|
...options,
|
package/lib/CodeOwnersFile.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.CodeOwnersFile = void 0;
|
|
|
4
4
|
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
5
5
|
const projen_1 = require("projen");
|
|
6
6
|
class CodeOwnersFile extends projen_1.TextFile {
|
|
7
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.CodeOwnersFile", version: "1.
|
|
7
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.CodeOwnersFile", version: "1.25.0" };
|
|
8
8
|
constructor(project, options = {}) {
|
|
9
9
|
const defaultOwners = ['* @macedon-technologies/platform', '* @macedon-technologies/ai-development-team'];
|
|
10
10
|
const allOwners = [...defaultOwners, ...(options.additionalOwners || [])];
|
|
@@ -7,7 +7,7 @@ const javascript_1 = require("projen/lib/javascript");
|
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
8
|
const WorkflowActionVersions_1 = require("./WorkflowActionVersions");
|
|
9
9
|
class ProductionDeployWorkflow extends projen_1.YamlFile {
|
|
10
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.ProductionDeployWorkflow", version: "1.
|
|
10
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.ProductionDeployWorkflow", version: "1.25.0" };
|
|
11
11
|
constructor(project, options) {
|
|
12
12
|
const packageManager = project.package.packageManager;
|
|
13
13
|
const actionVersions = (0, WorkflowActionVersions_1.resolveActionVersions)(options.actionVersions);
|
|
@@ -21,6 +21,7 @@ class SoftwareFactoryArchitectureRules {
|
|
|
21
21
|
' */',
|
|
22
22
|
"import * as fs from 'node:fs';",
|
|
23
23
|
"import * as path from 'node:path';",
|
|
24
|
+
"import { execFileSync } from 'node:child_process';",
|
|
24
25
|
"import rulesFile from './rules.json';",
|
|
25
26
|
'',
|
|
26
27
|
'interface ForbiddenImportCheck {',
|
|
@@ -31,12 +32,22 @@ class SoftwareFactoryArchitectureRules {
|
|
|
31
32
|
' forbid: string[];',
|
|
32
33
|
'}',
|
|
33
34
|
'',
|
|
35
|
+
'interface RequiredCompanionCheck {',
|
|
36
|
+
" type: 'required-companion';",
|
|
37
|
+
' // Glob patterns selecting changed files that trigger the requirement.',
|
|
38
|
+
' from: string[];',
|
|
39
|
+
' // Glob patterns -- at least one CHANGED file must match one of these.',
|
|
40
|
+
' requireOneOf: string[];',
|
|
41
|
+
" // Optional -- 'from' files matching these globs don't trigger the requirement.",
|
|
42
|
+
' exempt?: string[];',
|
|
43
|
+
'}',
|
|
44
|
+
'',
|
|
34
45
|
'interface Rule {',
|
|
35
46
|
' id: string;',
|
|
36
47
|
' description: string;',
|
|
37
48
|
' enabled: boolean;',
|
|
38
49
|
" severity: 'low' | 'medium' | 'high' | 'critical';",
|
|
39
|
-
' check: ForbiddenImportCheck;',
|
|
50
|
+
' check: ForbiddenImportCheck | RequiredCompanionCheck;',
|
|
40
51
|
'}',
|
|
41
52
|
'',
|
|
42
53
|
'interface Violation {',
|
|
@@ -47,6 +58,7 @@ class SoftwareFactoryArchitectureRules {
|
|
|
47
58
|
'',
|
|
48
59
|
"const REPO_ROOT = path.resolve(__dirname, '..');",
|
|
49
60
|
"const IGNORED_DIRS = new Set(['node_modules', '.git', '.swamp', 'cdk.out', 'lib', 'build', 'dist']);",
|
|
61
|
+
"const BASE_REF = process.env.ARCHITECTURE_RULES_BASE_REF || 'origin/main';",
|
|
50
62
|
'',
|
|
51
63
|
'// Minimal glob -> RegExp: supports "*", "**", "**/" and literal path segments.',
|
|
52
64
|
'// No new dependency for this — the only pattern shapes rules.json ever needs',
|
|
@@ -84,6 +96,26 @@ class SoftwareFactoryArchitectureRules {
|
|
|
84
96
|
" return path.relative(REPO_ROOT, absPath).split(path.sep).join('/');",
|
|
85
97
|
'}',
|
|
86
98
|
'',
|
|
99
|
+
'// Files changed relative to baseRef, sourced from git rather than the whole-tree',
|
|
100
|
+
'// walk() below -- required-companion checks care about what a PR touched, not',
|
|
101
|
+
'// the full repo. Throws (rather than returning []) if baseRef cannot be resolved,',
|
|
102
|
+
'// so an unfetched base ref fails the check instead of silently reporting no violations.',
|
|
103
|
+
'function getChangedFiles(baseRef: string): string[] {',
|
|
104
|
+
' let output: string;',
|
|
105
|
+
' try {',
|
|
106
|
+
" output = execFileSync('git', ['diff', '--name-only', '--diff-filter=ACMR', `${baseRef}...HEAD`], {",
|
|
107
|
+
' cwd: REPO_ROOT,',
|
|
108
|
+
" encoding: 'utf8',",
|
|
109
|
+
' });',
|
|
110
|
+
' } catch (err) {',
|
|
111
|
+
' throw new Error(',
|
|
112
|
+
' `architecture-rules: failed to compute the changed-file set against base ref "${baseRef}" -- ` +',
|
|
113
|
+
' `is it fetched and resolvable in this checkout? (${(err as Error).message})`,',
|
|
114
|
+
' );',
|
|
115
|
+
' }',
|
|
116
|
+
" return output.split('\\n').map((line) => line.trim()).filter((line) => line.length > 0);",
|
|
117
|
+
'}',
|
|
118
|
+
'',
|
|
87
119
|
'function walk(dir: string, acc: string[] = []): string[] {',
|
|
88
120
|
' for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {',
|
|
89
121
|
' if (IGNORED_DIRS.has(entry.name)) continue;',
|
|
@@ -118,7 +150,7 @@ class SoftwareFactoryArchitectureRules {
|
|
|
118
150
|
'}',
|
|
119
151
|
'',
|
|
120
152
|
'function evaluateForbiddenImport(rule: Rule): Violation[] {',
|
|
121
|
-
' const { from, forbid } = rule.check;',
|
|
153
|
+
' const { from, forbid } = rule.check as ForbiddenImportCheck;',
|
|
122
154
|
' if (from.length === 0 || forbid.length === 0) return [];',
|
|
123
155
|
'',
|
|
124
156
|
' const violations: Violation[] = [];',
|
|
@@ -141,10 +173,34 @@ class SoftwareFactoryArchitectureRules {
|
|
|
141
173
|
' return violations;',
|
|
142
174
|
'}',
|
|
143
175
|
'',
|
|
176
|
+
'function evaluateRequiredCompanion(rule: Rule): Violation[] {',
|
|
177
|
+
' const { from, requireOneOf, exempt } = rule.check as RequiredCompanionCheck;',
|
|
178
|
+
' if (from.length === 0 || requireOneOf.length === 0) return [];',
|
|
179
|
+
'',
|
|
180
|
+
' const changedFiles = getChangedFiles(BASE_REF);',
|
|
181
|
+
' const triggering = changedFiles.filter(',
|
|
182
|
+
' (file) => matchesAny(file, from) && !(exempt && matchesAny(file, exempt)),',
|
|
183
|
+
' );',
|
|
184
|
+
' if (triggering.length === 0) return [];',
|
|
185
|
+
'',
|
|
186
|
+
' const satisfied = changedFiles.some((file) => matchesAny(file, requireOneOf));',
|
|
187
|
+
' if (satisfied) return [];',
|
|
188
|
+
'',
|
|
189
|
+
' return [',
|
|
190
|
+
' {',
|
|
191
|
+
' ruleId: rule.id,',
|
|
192
|
+
' severity: rule.severity,',
|
|
193
|
+
' message: `changed file(s) ${triggering.join(\', \')} match rule "${rule.id}"\'s "from" patterns, but no changed file matches its "requireOneOf" patterns`,',
|
|
194
|
+
' },',
|
|
195
|
+
' ];',
|
|
196
|
+
'}',
|
|
197
|
+
'',
|
|
144
198
|
'function evaluateRule(rule: Rule): Violation[] {',
|
|
145
199
|
' switch (rule.check.type) {',
|
|
146
200
|
" case 'forbidden-import':",
|
|
147
201
|
' return evaluateForbiddenImport(rule);',
|
|
202
|
+
" case 'required-companion':",
|
|
203
|
+
' return evaluateRequiredCompanion(rule);',
|
|
148
204
|
' default:',
|
|
149
205
|
' throw new Error(`architecture-rules: unknown check.type "${(rule.check as { type: string }).type}" on rule "${rule.id}"`);',
|
|
150
206
|
' }',
|
|
@@ -203,6 +259,9 @@ class SoftwareFactoryArchitectureRules {
|
|
|
203
259
|
'',
|
|
204
260
|
'## Rule shape',
|
|
205
261
|
'',
|
|
262
|
+
'Two `check.type`s are implemented: `forbidden-import` (whole-repo import-graph',
|
|
263
|
+
'check) and `required-companion` (diff-based co-change check).',
|
|
264
|
+
'',
|
|
206
265
|
'```json',
|
|
207
266
|
'{',
|
|
208
267
|
' "id": "unique-id",',
|
|
@@ -217,6 +276,56 @@ class SoftwareFactoryArchitectureRules {
|
|
|
217
276
|
'}',
|
|
218
277
|
'```',
|
|
219
278
|
'',
|
|
279
|
+
'```json',
|
|
280
|
+
'{',
|
|
281
|
+
' "id": "unique-id",',
|
|
282
|
+
' "description": "What this enforces and why.",',
|
|
283
|
+
' "enabled": true,',
|
|
284
|
+
' "severity": "low" | "medium" | "high" | "critical",',
|
|
285
|
+
' "check": {',
|
|
286
|
+
' "type": "required-companion",',
|
|
287
|
+
' "from": ["glob patterns selecting changed files that trigger the requirement"],',
|
|
288
|
+
' "requireOneOf": ["glob patterns -- at least one CHANGED file must match one of these"],',
|
|
289
|
+
' "exempt": ["optional -- from-files matching these globs don\'t trigger the requirement"]',
|
|
290
|
+
' }',
|
|
291
|
+
'}',
|
|
292
|
+
'```',
|
|
293
|
+
'',
|
|
294
|
+
'`required-companion` evaluates the set of files changed in the current diff',
|
|
295
|
+
'(`git diff --name-only --diff-filter=ACMR <baseRef>...HEAD`), not the whole',
|
|
296
|
+
'repo tree: if any changed file matches `from` (and doesn\'t match `exempt`) but',
|
|
297
|
+
'no changed file matches `requireOneOf`, that\'s a violation. The base ref',
|
|
298
|
+
'defaults to `origin/main` and can be overridden with the',
|
|
299
|
+
'`ARCHITECTURE_RULES_BASE_REF` environment variable. This means the checkout',
|
|
300
|
+
'running `pnpm validate:architecture` must have that base ref fetched and',
|
|
301
|
+
'resolvable (a shallow, single-branch checkout will make the check fail closed',
|
|
302
|
+
'with an error rather than silently reporting no violations) — make sure',
|
|
303
|
+
'whatever runs this task fetches enough history for `git diff <baseRef>...HEAD`',
|
|
304
|
+
'to succeed.',
|
|
305
|
+
'',
|
|
306
|
+
'`from`/`requireOneOf`/`exempt` globs are matched against the paths `git',
|
|
307
|
+
'diff --name-only` reports, which are relative to the git repository\'s',
|
|
308
|
+
'top-level directory. This lines up with `from`\'s own directory (the parent of',
|
|
309
|
+
'`architecture-rules/`) in the common case — a single project generated at the',
|
|
310
|
+
'repo root — but if `architecture-rules/` instead lives under a nested',
|
|
311
|
+
'subdirectory of a larger git repo, write globs relative to the git root, not',
|
|
312
|
+
'to that subdirectory.',
|
|
313
|
+
'',
|
|
314
|
+
'**`required-companion` is a coverage check, not a correctness check.** It only',
|
|
315
|
+
'confirms that *some* changed file matches `requireOneOf` — it can\'t tell',
|
|
316
|
+
'whether that change is actually related to the triggering `from` change (a',
|
|
317
|
+
'trivial or unrelated edit to a file under `requireOneOf` satisfies the rule',
|
|
318
|
+
'just as well as a substantive one), and it can\'t tell whether a given `from`',
|
|
319
|
+
'change genuinely needed a companion at all (a pure refactor might not).',
|
|
320
|
+
'`exempt` covers *known, glob-expressible* exceptions, but not every false',
|
|
321
|
+
'positive is expressible as a glob — that judgment call still belongs to the',
|
|
322
|
+
'rule author (scoping `from`/`exempt`) and the reviewer (reading the companion',
|
|
323
|
+
'diff, not just trusting that the check passed). Also note that `main()`',
|
|
324
|
+
'fails the whole run on *any* violation regardless of `severity` — `severity`',
|
|
325
|
+
'is informational only, not a leniency lever — so start with a narrowly',
|
|
326
|
+
'scoped `from` (or `enabled: false`) and widen it as the convention proves',
|
|
327
|
+
'itself, the same guidance as for `forbidden-import`.',
|
|
328
|
+
'',
|
|
220
329
|
'`enabled: false` rules are skipped (reported as "deferred") rather than',
|
|
221
330
|
"evaluated — use this for a rule you've named and described but don't yet",
|
|
222
331
|
'have a concrete convention to check.',
|
|
@@ -229,11 +338,13 @@ class SoftwareFactoryArchitectureRules {
|
|
|
229
338
|
'',
|
|
230
339
|
'## Adding a check type',
|
|
231
340
|
'',
|
|
232
|
-
'`forbidden-import`
|
|
233
|
-
'
|
|
234
|
-
'
|
|
235
|
-
'
|
|
236
|
-
'
|
|
341
|
+
'`forbidden-import` (whole-repo import graph) and `required-companion`',
|
|
342
|
+
'(diff-based co-change) are the implemented `check.type`s. If a future rule',
|
|
343
|
+
'needs a data source neither provides (e.g. "every aggregate file must have a',
|
|
344
|
+
'matching events file", which is a repo-wide naming convention rather than',
|
|
345
|
+
'either an import-graph or a diff check), add a new `type` value, a matching',
|
|
346
|
+
'interface, and a case in `evaluateRule()` in `check.ts` — keep the engine',
|
|
347
|
+
'itself generic; rule-specific knowledge belongs in `rules.json`.',
|
|
237
348
|
],
|
|
238
349
|
});
|
|
239
350
|
new projen_1.SampleFile(project, 'architecture-rules/rules.json', {
|
|
@@ -242,4 +353,4 @@ class SoftwareFactoryArchitectureRules {
|
|
|
242
353
|
}
|
|
243
354
|
}
|
|
244
355
|
exports.SoftwareFactoryArchitectureRules = SoftwareFactoryArchitectureRules;
|
|
245
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29mdHdhcmVGYWN0b3J5QXJjaGl0ZWN0dXJlUnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU29mdHdhcmVGYWN0b3J5QXJjaGl0ZWN0dXJlUnVsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXdEO0FBR3hEOzs7OztHQUtHO0FBQ0gsTUFBYSxnQ0FBZ0M7SUFDM0MsWUFBWSxPQUFvQjtRQUM5QixJQUFJLGlCQUFRLENBQUMsT0FBTyxFQUFFLDZCQUE2QixFQUFFO1lBQ25ELE1BQU0sRUFBRSxJQUFJO1lBQ1osS0FBSyxFQUFFO2dCQUNMLEtBQUs7Z0JBQ0wsK0VBQStFO2dCQUMvRSw4RUFBOEU7Z0JBQzlFLGdGQUFnRjtnQkFDaEYsOEJBQThCO2dCQUM5QixLQUFLO2dCQUNMLGdDQUFnQztnQkFDaEMsb0NBQW9DO2dCQUNwQyx1Q0FBdUM7Z0JBQ3ZDLEVBQUU7Z0JBQ0Ysa0NBQWtDO2dCQUNsQyw2QkFBNkI7Z0JBQzdCLG9GQUFvRjtnQkFDcEYsbUJBQW1CO2dCQUNuQixtRkFBbUY7Z0JBQ25GLHFCQUFxQjtnQkFDckIsR0FBRztnQkFDSCxFQUFFO2dCQUNGLGtCQUFrQjtnQkFDbEIsZUFBZTtnQkFDZix3QkFBd0I7Z0JBQ3hCLHFCQUFxQjtnQkFDckIscURBQXFEO2dCQUNyRCxnQ0FBZ0M7Z0JBQ2hDLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRix1QkFBdUI7Z0JBQ3ZCLG1CQUFtQjtnQkFDbkIscUJBQXFCO2dCQUNyQixvQkFBb0I7Z0JBQ3BCLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRixrREFBa0Q7Z0JBQ2xELHNHQUFzRztnQkFDdEcsRUFBRTtnQkFDRixpRkFBaUY7Z0JBQ2pGLCtFQUErRTtnQkFDL0UsaUVBQWlFO2dCQUNqRSwrQ0FBK0M7Z0JBQy9DLGlCQUFpQjtnQkFDakIsMkNBQTJDO2dCQUMzQyx3QkFBd0I7Z0JBQ3hCLDZDQUE2QztnQkFDN0MsWUFBWTtnQkFDWixrQ0FBa0M7Z0JBQ2xDLDRC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QUMsT0FBTyxFQUFFLDhCQUE4QixFQUFFO1lBQ3BELE1BQU0sRUFBRSxJQUFJO1lBQ1osS0FBSyxFQUFFO2dCQUNMLHNCQUFzQjtnQkFDdEIsRUFBRTtnQkFDRixrRUFBa0U7Z0JBQ2xFLHlFQUF5RTtnQkFDekUsNkVBQTZFO2dCQUM3RSwyRUFBMkU7Z0JBQzNFLDJFQUEyRTtnQkFDM0Usc0NBQXNDO2dCQUN0QyxFQUFFO2dCQUNGLGVBQWU7Z0JBQ2YsRUFBRTtnQkFDRixTQUFTO2dCQUNULEdBQUc7Z0JBQ0gsc0JBQXNCO2dCQUN0QixpREFBaUQ7Z0JBQ2pELG9CQUFvQjtnQkFDcEIsdURBQXVEO2dCQUN2RCxjQUFjO2dCQUNkLGlDQUFpQztnQkFDakMsbUVBQW1FO2dCQUNuRSxpRUFBaUU7Z0JBQ2pFLEtBQUs7Z0JBQ0wsR0FBRztnQkFDSCxLQUFLO2dCQUNMLEVBQUU7Z0JBQ0YseUVBQXlFO2dCQUN6RSwwRUFBMEU7Z0JBQzFFLHNDQUFzQztnQkFDdEMsRUFBRTtnQkFDRixrQkFBa0I7Z0JBQ2xCLEVBQUU7Z0JBQ0Ysc0VBQXNFO2dCQUN0RSxzRUFBc0U7Z0JBQ3RFLGtFQUFrRTtnQkFDbEUsRUFBRTtnQkFDRix3QkFBd0I7Z0JBQ3hCLEVBQUU7Z0JBQ0YsMkVBQTJFO2dCQUMzRSwyRUFBMkU7Z0JBQzNFLDZFQUE2RTtnQkFDN0UsMEVBQTBFO2dCQUMxRSxrREFBa0Q7YUFDbkQ7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLCtCQUErQixFQUFFO1lBQ3ZELFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJO1NBQ3hELENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTNPRCw0RUEyT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKc29uRmlsZSwgU2FtcGxlRmlsZSwgVGV4dEZpbGUgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgTm9kZVByb2plY3QgfSBmcm9tICdwcm9qZW4vbGliL2phdmFzY3JpcHQnO1xuXG4vKipcbiAqIFRoZSBnZW5lcmljLCBkYXRhLWRyaXZlbiBhcmNoaXRlY3R1cmUgcnVsZSBlbmdpbmUgcGx1cyBhbiBlbXB0eSBzZWVkXG4gKiBydWxlcy5qc29uLiBgY2hlY2sudHNgL2B0c2NvbmZpZy5qc29uYC9gUkVBRE1FLm1kYCBhcmUgbWFuYWdlZCAoQmF0bWFuXG4gKiBvd25zIHRoZSBlbmdpbmUpOyBgcnVsZXMuanNvbmAgaXMgYSBgU2FtcGxlRmlsZWAg4oCUIGVhY2ggcmVwbydzIG93biBydWxlc1xuICogYXJlIGRhdGEgdGhlIHRlYW0gb3ducywgbm90IHNvbWV0aGluZyBCYXRtYW4gc2hvdWxkIG92ZXJ3cml0ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNvZnR3YXJlRmFjdG9yeUFyY2hpdGVjdHVyZVJ1bGVzIHtcbiAgY29uc3RydWN0b3IocHJvamVjdDogTm9kZVByb2plY3QpIHtcbiAgICBuZXcgVGV4dEZpbGUocHJvamVjdCwgJ2FyY2hpdGVjdHVyZS1ydWxlcy9jaGVjay50cycsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcvKionLFxuICAgICAgICAnICogR2VuZXJpYyBhcmNoaXRlY3R1cmUtcnVsZSBlbmdpbmUuIFJ1bGVzIGxpdmUgZW50aXJlbHkgaW4gcnVsZXMuanNvbiDigJQgdGhpcycsXG4gICAgICAgICcgKiBmaWxlIG9ubHkga25vd3MgaG93IHRvIGV2YWx1YXRlIHRoZSBjaGVjayBcInR5cGVzXCIgdGhhdCBydWxlcyBjYW4gZGVjbGFyZS4nLFxuICAgICAgICAnICogQWRkIGEgbmV3IHJ1bGUgYnkgYWRkaW5nIGEgcnVsZXMuanNvbiBlbnRyeTsgYWRkIGEgbmV3IGNoZWNrIHR5cGUgYnkgYWRkaW5nJyxcbiAgICAgICAgJyAqIGEgY2FzZSBpbiBldmFsdWF0ZVJ1bGUoKS4nLFxuICAgICAgICAnICovJyxcbiAgICAgICAgXCJpbXBvcnQgKiBhcyBmcyBmcm9tICdub2RlOmZzJztcIixcbiAgICAgICAgXCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XCIsXG4gICAgICAgIFwiaW1wb3J0IHJ1bGVzRmlsZSBmcm9tICcuL3J1bGVzLmpzb24nO1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2ludGVyZmFjZSBGb3JiaWRkZW5JbXBvcnRDaGVjayB7JyxcbiAgICAgICAgXCIgIHR5cGU6ICdmb3JiaWRkZW4taW1wb3J0JztcIixcbiAgICAgICAgJyAgLy8gR2xvYiBwYXR0ZXJucyAocmVsYXRpdmUgdG8gcmVwbyByb290KSBzZWxlY3RpbmcgdGhlIGZpbGVzIHRoaXMgcnVsZSBpbnNwZWN0cy4nLFxuICAgICAgICAnICBmcm9tOiBzdHJpbmdbXTsnLFxuICAgICAgICAnICAvLyBHbG9iIHBhdHRlcm5zIChyZWxhdGl2ZSB0byByZXBvIHJvb3QpIHRoYXQgXCJmcm9tXCIgZmlsZXMgbWF5IG5vdCBpbXBvcnQgZnJvbS4nLFxuICAgICAgICAnICBmb3JiaWQ6IHN0cmluZ1tdOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdpbnRlcmZhY2UgUnVsZSB7JyxcbiAgICAgICAgJyAgaWQ6IHN0cmluZzsnLFxuICAgICAgICAnICBkZXNjcmlwdGlvbjogc3RyaW5nOycsXG4gICAgICAgICcgIGVuYWJsZWQ6IGJvb2xlYW47JyxcbiAgICAgICAgXCIgIHNldmVyaXR5OiAnbG93JyB8ICdtZWRpdW0nIHwgJ2hpZ2gnIHwgJ2NyaXRpY2FsJztcIixcbiAgICAgICAgJyAgY2hlY2s6IEZvcmJpZGRlbkltcG9ydENoZWNrOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdpbnRlcmZhY2UgVmlvbGF0aW9uIHsnLFxuICAgICAgICAnICBydWxlSWQ6IHN0cmluZzsnLFxuICAgICAgICAnICBzZXZlcml0eTogc3RyaW5nOycsXG4gICAgICAgICcgIG1lc3NhZ2U6IHN0cmluZzsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICBcImNvbnN0IFJFUE9fUk9PVCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLicpO1wiLFxuICAgICAgICBcImNvbnN0IElHTk9SRURfRElSUyA9IG5ldyBTZXQoWydub2RlX21vZHVsZXMnLCAnLmdpdCcsICcuc3dhbXAnLCAnY2RrLm91dCcsICdsaWInLCAnYnVpbGQnLCAnZGlzdCddKTtcIixcbiAgICAgICAgJycsXG4gICAgICAgICcvLyBNaW5pbWFsIGdsb2IgLT4gUmVnRXhwOiBzdXBwb3J0cyBcIipcIiwgXCIqKlwiLCBcIioqL1wiIGFuZCBsaXRlcmFsIHBhdGggc2VnbWVudHMuJyxcbiAgICAgICAgJy8vIE5vIG5ldyBkZXBlbmRlbmN5IGZvciB0aGlzIOKAlCB0aGUgb25seSBwYXR0ZXJuIHNoYXBlcyBydWxlcy5qc29uIGV2ZXIgbmVlZHMnLFxuICAgICAgICAnLy8gYXJlIGRpcmVjdG9yeS1wcmVmaXggZ2xvYnMgbGlrZSBcInNyYy9kb21haW5zLyovY29tbWFuZHMvKipcIi4nLFxuICAgICAgICAnZnVuY3Rpb24gZ2xvYlRvUmVnRXhwKGdsb2I6IHN0cmluZyk6IFJlZ0V4cCB7JyxcbiAgICAgICAgXCIgIGxldCBvdXQgPSAnJztcIixcbiAgICAgICAgJyAgZm9yIChsZXQgaSA9IDA7IGkgPCBnbG9iLmxlbmd0aDsgaSsrKSB7JyxcbiAgICAgICAgJyAgICBjb25zdCBjID0gZ2xvYltpXTsnLFxuICAgICAgICBcIiAgICBpZiAoYyA9PT0gJyonICYmIGdsb2JbaSArIDFdID09PSAnKicpIHtcIixcbiAgICAgICAgJyAgICAgIGkrKzsnLFxuICAgICAgICBcIiAgICAgIGlmIChnbG9iW2kgKyAxXSA9PT0gJy8nKSB7XCIsXG4gICAgICAgIFwiICAgICAgICBvdXQgKz0gJyg/Oi4qLyk/JztcIixcbiAgICAgICAgJyAgICAgICAgaSsrOycsXG4gICAgICAgICcgICAgICB9IGVsc2UgeycsXG4gICAgICAgIFwiICAgICAgICBvdXQgKz0gJy4qJztcIixcbiAgICAgICAgJyAgICAgIH0nLFxuICAgICAgICBcIiAgICB9IGVsc2UgaWYgKGMgPT09ICcqJykge1wiLFxuICAgICAgICBcIiAgICAgIG91dCArPSAnW14vXSonO1wiLFxuICAgICAgICBcIiAgICB9IGVsc2UgaWYgKGMgPT09ICc/Jykge1wiLFxuICAgICAgICBcIiAgICAgIG91dCArPSAnW14vXSc7XCIsXG4gICAgICAgIFwiICAgIH0gZWxzZSBpZiAoJy4rXiR7fSgpfFtdXFxcXFxcXFwnLmluY2x1ZGVzKGMpKSB7XCIsXG4gICAgICAgICcgICAgICBvdXQgKz0gYFxcXFxcXFxcJHtjfWA7JyxcbiAgICAgICAgJyAgICB9IGVsc2UgeycsXG4gICAgICAgICcgICAgICBvdXQgKz0gYzsnLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJyAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke291dH0kYCk7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIG1hdGNoZXNBbnkocmVsRmlsZTogc3RyaW5nLCBnbG9iczogc3RyaW5nW10pOiBib29sZWFuIHsnLFxuICAgICAgICAnICByZXR1cm4gZ2xvYnMuc29tZSgoZ2xvYikgPT4gZ2xvYlRvUmVnRXhwKGdsb2IpLnRlc3QocmVsRmlsZSkpOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiB0b1JlcG9SZWxhdGl2ZShhYnNQYXRoOiBzdHJpbmcpOiBzdHJpbmcgeycsXG4gICAgICAgIFwiICByZXR1cm4gcGF0aC5yZWxhdGl2ZShSRVBPX1JPT1QsIGFic1BhdGgpLnNwbGl0KHBhdGguc2VwKS5qb2luKCcvJyk7XCIsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiB3YWxrKGRpcjogc3RyaW5nLCBhY2M6IHN0cmluZ1tdID0gW10pOiBzdHJpbmdbXSB7JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBlbnRyeSBvZiBmcy5yZWFkZGlyU3luYyhkaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkgeycsXG4gICAgICAgICcgICAgaWYgKElHTk9SRURfRElSUy5oYXMoZW50cnkubmFtZSkpIGNvbnRpbnVlOycsXG4gICAgICAgICcgICAgY29uc3QgZnVsbCA9IHBhdGguam9pbihkaXIsIGVudHJ5Lm5hbWUpOycsXG4gICAgICAgICcgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsnLFxuICAgICAgICAnICAgICAgd2FsayhmdWxsLCBhY2MpOycsXG4gICAgICAgIFwiICAgIH0gZWxzZSBpZiAoZW50cnkuaXNGaWxlKCkgJiYgKGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50cycpIHx8IGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50c3gnKSkpIHtcIixcbiAgICAgICAgJyAgICAgIGFjYy5wdXNoKGZ1bGwpOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnICByZXR1cm4gYWNjOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgIFwiY29uc3QgUkVMQVRJVkVfSU1QT1JUX1JFID0gLyg/OmltcG9ydHxleHBvcnQpXFxcXHMrKD86W14nXFxcIjtdKj9cXFxcYmZyb21cXFxccyspP1snXFxcIl0oXFxcXC5bXidcXFwiXSspWydcXFwiXS9nO1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGZpbmRSZWxhdGl2ZUltcG9ydHMoc291cmNlOiBzdHJpbmcpOiBzdHJpbmdbXSB7JyxcbiAgICAgICAgJyAgY29uc3Qgc3BlY3M6IHN0cmluZ1tdID0gW107JyxcbiAgICAgICAgJyAgUkVMQVRJVkVfSU1QT1JUX1JFLmxhc3RJbmRleCA9IDA7JyxcbiAgICAgICAgJyAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsOycsXG4gICAgICAgICcgIHdoaWxlICgobWF0Y2ggPSBSRUxBVElWRV9JTVBPUlRfUkUuZXhlYyhzb3VyY2UpKSkgeycsXG4gICAgICAgICcgICAgc3BlY3MucHVzaChtYXRjaFsxXSk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIHJldHVybiBzcGVjczsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnLy8gQW4gaW1wb3J0IHNwZWMgcmVzb2x2ZXMgdG8gYSBtb2R1bGUsIG5vdCBhIHNwZWNpZmljIGZpbGUgZXh0ZW5zaW9uLCBzbyBhJyxcbiAgICAgICAgJy8vIGZvcmJpZCBnbG9iIGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgYmFyZSByZXNvbHZlZCBwYXRoIHBsdXMgaXRzIC50cy9pbmRleC50cycsXG4gICAgICAgICcvLyB2YXJpYW50cy4nLFxuICAgICAgICAnZnVuY3Rpb24gcmVzb2x2ZWRDYW5kaWRhdGVzKGZyb21GaWxlOiBzdHJpbmcsIHNwZWM6IHN0cmluZyk6IHN0cmluZ1tdIHsnLFxuICAgICAgICAnICBjb25zdCByZXNvbHZlZCA9IHRvUmVwb1JlbGF0aXZlKHBhdGgubm9ybWFsaXplKHBhdGguam9pbihwYXRoLmRpcm5hbWUoZnJvbUZpbGUpLCBzcGVjKSkpOycsXG4gICAgICAgICcgIHJldHVybiBbcmVzb2x2ZWQsIGAke3Jlc29sdmVkfS50c2AsIGAke3Jlc29sdmVkfS9pbmRleC50c2BdOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBldmFsdWF0ZUZvcmJpZGRlbkltcG9ydChydWxlOiBSdWxlKTogVmlvbGF0aW9uW10geycsXG4gICAgICAgICcgIGNvbnN0IHsgZnJvbSwgZm9yYmlkIH0gPSBydWxlLmNoZWNrOycsXG4gICAgICAgICcgIGlmIChmcm9tLmxlbmd0aCA9PT0gMCB8fCBmb3JiaWQubGVuZ3RoID09PSAwKSByZXR1cm4gW107JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGNvbnN0IHZpb2xhdGlvbnM6IFZpb2xhdGlvbltdID0gW107JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBmaWxlIG9mIHdhbGsoUkVQT19ST09UKSkgeycsXG4gICAgICAgICcgICAgY29uc3QgcmVsRmlsZSA9IHRvUmVwb1JlbGF0aXZlKGZpbGUpOycsXG4gICAgICAgICcgICAgaWYgKCFtYXRjaGVzQW55KHJlbEZpbGUsIGZyb20pKSBjb250aW51ZTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgXCIgICAgY29uc3Qgc291cmNlID0gZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7XCIsXG4gICAgICAgICcgICAgZm9yIChjb25zdCBzcGVjIG9mIGZpbmRSZWxhdGl2ZUltcG9ydHMoc291cmNlKSkgeycsXG4gICAgICAgICcgICAgICBjb25zdCBjYW5kaWRhdGVzID0gcmVzb2x2ZWRDYW5kaWRhdGVzKGZpbGUsIHNwZWMpOycsXG4gICAgICAgICcgICAgICBpZiAoY2FuZGlkYXRlcy5zb21lKChjYW5kaWRhdGUpID0+IG1hdGNoZXNBbnkoY2FuZGlkYXRlLCBmb3JiaWQpKSkgeycsXG4gICAgICAgICcgICAgICAgIHZpb2xhdGlvbnMucHVzaCh7JyxcbiAgICAgICAgJyAgICAgICAgICBydWxlSWQ6IHJ1bGUuaWQsJyxcbiAgICAgICAgJyAgICAgICAgICBzZXZlcml0eTogcnVsZS5zZXZlcml0eSwnLFxuICAgICAgICAnICAgICAgICAgIG1lc3NhZ2U6IGAke3JlbEZpbGV9IGltcG9ydHMgXCIke3NwZWN9XCIsIHdoaWNoIHJlc29sdmVzIHVuZGVyIGEgcGF0aCBmb3JiaWRkZW4gYnkgcnVsZSBcIiR7cnVsZS5pZH1cImAsJyxcbiAgICAgICAgJyAgICAgICAgfSk7JyxcbiAgICAgICAgJyAgICAgIH0nLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJyAgcmV0dXJuIHZpb2xhdGlvbnM7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGV2YWx1YXRlUnVsZShydWxlOiBSdWxlKTogVmlvbGF0aW9uW10geycsXG4gICAgICAgICcgIHN3aXRjaCAocnVsZS5jaGVjay50eXBlKSB7JyxcbiAgICAgICAgXCIgICAgY2FzZSAnZm9yYmlkZGVuLWltcG9ydCc6XCIsXG4gICAgICAgICcgICAgICByZXR1cm4gZXZhbHVhdGVGb3JiaWRkZW5JbXBvcnQocnVsZSk7JyxcbiAgICAgICAgJyAgICBkZWZhdWx0OicsXG4gICAgICAgICcgICAgICB0aHJvdyBuZXcgRXJyb3IoYGFyY2hpdGVjdHVyZS1ydWxlczogdW5rbm93biBjaGVjay50eXBlIFwiJHsocnVsZS5jaGVjayBhcyB7IHR5cGU6IHN0cmluZyB9KS50eXBlfVwiIG9uIHJ1bGUgXCIke3J1bGUuaWR9XCJgKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIG1haW4oKTogbnVtYmVyIHsnLFxuICAgICAgICAnICBjb25zdCBydWxlcyA9IChydWxlc0ZpbGUgYXMgeyBydWxlczogUnVsZVtdIH0pLnJ1bGVzOycsXG4gICAgICAgICcgIGxldCBldmFsdWF0ZWQgPSAwOycsXG4gICAgICAgICcgIGxldCBkZWZlcnJlZCA9IDA7JyxcbiAgICAgICAgJyAgY29uc3QgdmlvbGF0aW9uczogVmlvbGF0aW9uW10gPSBbXTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7JyxcbiAgICAgICAgJyAgICBpZiAoIXJ1bGUuZW5hYmxlZCkgeycsXG4gICAgICAgICcgICAgICBkZWZlcnJlZCsrOycsXG4gICAgICAgICcgICAgICBjb25zb2xlLmxvZyhgW2RlZmVycmVkXSAke3J1bGUuaWR9OiAke3J1bGUuZGVzY3JpcHRpb259YCk7JyxcbiAgICAgICAgJyAgICAgIGNvbnRpbnVlOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgICAgZXZhbHVhdGVkKys7JyxcbiAgICAgICAgJyAgICB2aW9sYXRpb25zLnB1c2goLi4uZXZhbHVhdGVSdWxlKHJ1bGUpKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGNvbnNvbGUubG9nKGBcXFxcbmFyY2hpdGVjdHVyZS1ydWxlczogJHtldmFsdWF0ZWR9IHJ1bGUocykgZXZhbHVhdGVkLCAke2RlZmVycmVkfSBkZWZlcnJlZCwgJHt2aW9sYXRpb25zLmxlbmd0aH0gdmlvbGF0aW9uKHMpYCk7JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCB2aW9sYXRpb24gb2YgdmlvbGF0aW9ucykgeycsXG4gICAgICAgICcgICAgY29uc29sZS5lcnJvcihgICBbJHt2aW9sYXRpb24uc2V2ZXJpdHl9XSAke3Zpb2xhdGlvbi5ydWxlSWR9OiAke3Zpb2xhdGlvbi5tZXNzYWdlfWApOycsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgcmV0dXJuIHZpb2xhdGlvbnMubGVuZ3RoID4gMCA/IDEgOiAwOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdwcm9jZXNzLmV4aXQobWFpbigpKTsnLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIG5ldyBKc29uRmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL3RzY29uZmlnLmpzb24nLCB7XG4gICAgICBtYXJrZXI6IGZhbHNlLFxuICAgICAgb2JqOiB7XG4gICAgICAgIGV4dGVuZHM6ICcuLi90c2NvbmZpZy5qc29uJyxcbiAgICAgICAgY29tcGlsZXJPcHRpb25zOiB7XG4gICAgICAgICAgbm9FbWl0OiB0cnVlLFxuICAgICAgICAgIHJvb3REaXI6ICcuJyxcbiAgICAgICAgfSxcbiAgICAgICAgaW5jbHVkZTogWycqLnRzJywgJyouanNvbiddLFxuICAgICAgICBleGNsdWRlOiBbJ25vZGVfbW9kdWxlcyddLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIG5ldyBUZXh0RmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL1JFQURNRS5tZCcsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcjIEFyY2hpdGVjdHVyZSBydWxlcycsXG4gICAgICAgICcnLFxuICAgICAgICAnQSBkYXRhLWRyaXZlbiByZWdpc3RyeSBvZiBhcmNoaXRlY3R1cmFsIGNvbnN0cmFpbnRzLCBlbmZvcmNlZCBieScsXG4gICAgICAgICdgcG5wbSB2YWxpZGF0ZTphcmNoaXRlY3R1cmVgIGFuZCBydW4gYXMgcGFydCBvZiB0aGUgcHJlLVBSIHZlcmlmaWNhdGlvbicsXG4gICAgICAgICd3b3JrZmxvdyAoYHdvcmtmbG93cy93b3JrZmxvdy1wcmUtcHItdmVyaWZ5LnlhbWxgKSBiZWZvcmUgdGhlIHN3YW1wIGZhY3RvcnknLFxuICAgICAgICAnb3BlbnMgYSBQUi4gTmV3IHJ1bGVzIGFyZSBuZXcgZW50cmllcyBpbiBgcnVsZXMuanNvbmAsIG5vdCBuZXcgY29kZSDigJQgdGhlJyxcbiAgICAgICAgJ2VuZ2luZSAoYGNoZWNrLnRzYCkgb25seSBuZWVkcyBhIG5ldyBjYXNlIGluIGBldmFsdWF0ZVJ1bGUoKWAgd2hlbiBhIHJ1bGUnLFxuICAgICAgICAnbmVlZHMgYSBnZW51aW5lbHkgbmV3IGtpbmQgb2YgY2hlY2suJyxcbiAgICAgICAgJycsXG4gICAgICAgICcjIyBSdWxlIHNoYXBlJyxcbiAgICAgICAgJycsXG4gICAgICAgICdgYGBqc29uJyxcbiAgICAgICAgJ3snLFxuICAgICAgICAnICBcImlkXCI6IFwidW5pcXVlLWlkXCIsJyxcbiAgICAgICAgJyAgXCJkZXNjcmlwdGlvblwiOiBcIldoYXQgdGhpcyBlbmZvcmNlcyBhbmQgd2h5LlwiLCcsXG4gICAgICAgICcgIFwiZW5hYmxlZFwiOiB0cnVlLCcsXG4gICAgICAgICcgIFwic2V2ZXJpdHlcIjogXCJsb3dcIiB8IFwibWVkaXVtXCIgfCBcImhpZ2hcIiB8IFwiY3JpdGljYWxcIiwnLFxuICAgICAgICAnICBcImNoZWNrXCI6IHsnLFxuICAgICAgICAnICAgIFwidHlwZVwiOiBcImZvcmJpZGRlbi1pbXBvcnRcIiwnLFxuICAgICAgICAnICAgIFwiZnJvbVwiOiBbXCJnbG9iIHBhdHRlcm5zIHNlbGVjdGluZyBmaWxlcyB0aGlzIHJ1bGUgaW5zcGVjdHNcIl0sJyxcbiAgICAgICAgJyAgICBcImZvcmJpZFwiOiBbXCJnbG9iIHBhdHRlcm5zIHRob3NlIGZpbGVzIG1heSBub3QgaW1wb3J0IGZyb21cIl0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnYGBgJyxcbiAgICAgICAgJycsXG4gICAgICAgICdgZW5hYmxlZDogZmFsc2VgIHJ1bGVzIGFyZSBza2lwcGVkIChyZXBvcnRlZCBhcyBcImRlZmVycmVkXCIpIHJhdGhlciB0aGFuJyxcbiAgICAgICAgXCJldmFsdWF0ZWQg4oCUIHVzZSB0aGlzIGZvciBhIHJ1bGUgeW91J3ZlIG5hbWVkIGFuZCBkZXNjcmliZWQgYnV0IGRvbid0IHlldFwiLFxuICAgICAgICAnaGF2ZSBhIGNvbmNyZXRlIGNvbnZlbnRpb24gdG8gY2hlY2suJyxcbiAgICAgICAgJycsXG4gICAgICAgICcjIyBDdXJyZW50IHJ1bGVzJyxcbiAgICAgICAgJycsXG4gICAgICAgICdOb25lIHlldCDigJQgYHJ1bGVzLmpzb25gIHNoaXBzIGVtcHR5LiBBZGQgcnVsZXMgYXMgeW91ciBkb21haW4gbW9kdWxlJyxcbiAgICAgICAgJ2NvbnZlbnRpb25zIHNvbGlkaWZ5IChlLmcuIGFuIGV2ZW50LXNvdXJjZWQvQ1FSUyBtb2R1bGUgbGF5b3V0IHVuZGVyJyxcbiAgICAgICAgJ2BzcmMvZG9tYWlucy88bmFtZT4ve2NvbW1hbmRzLGV2ZW50cyxhZ2dyZWdhdGVzLHByb2plY3Rpb25zfS9gKS4nLFxuICAgICAgICAnJyxcbiAgICAgICAgJyMjIEFkZGluZyBhIGNoZWNrIHR5cGUnLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Bmb3JiaWRkZW4taW1wb3J0YCBpcyB0aGUgb25seSBpbXBsZW1lbnRlZCBgY2hlY2sudHlwZWAuIElmIGEgZnV0dXJlIHJ1bGUnLFxuICAgICAgICAnbmVlZHMgc29tZXRoaW5nIGl0IGNhblxcJ3QgZXhwcmVzcyAoZS5nLiBcImV2ZXJ5IGFnZ3JlZ2F0ZSBmaWxlIG11c3QgaGF2ZSBhJyxcbiAgICAgICAgJ21hdGNoaW5nIGV2ZW50cyBmaWxlXCIpLCBhZGQgYSBuZXcgYHR5cGVgIHZhbHVlLCBhIG1hdGNoaW5nIGludGVyZmFjZSwgYW5kIGEnLFxuICAgICAgICAnY2FzZSBpbiBgZXZhbHVhdGVSdWxlKClgIGluIGBjaGVjay50c2Ag4oCUIGtlZXAgdGhlIGVuZ2luZSBpdHNlbGYgZ2VuZXJpYzsnLFxuICAgICAgICAncnVsZS1zcGVjaWZpYyBrbm93bGVkZ2UgYmVsb25ncyBpbiBgcnVsZXMuanNvbmAuJyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBuZXcgU2FtcGxlRmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL3J1bGVzLmpzb24nLCB7XG4gICAgICBjb250ZW50czogSlNPTi5zdHJpbmdpZnkoeyBydWxlczogW10gfSwgbnVsbCwgMikgKyAnXFxuJyxcbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
356
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU29mdHdhcmVGYWN0b3J5QXJjaGl0ZWN0dXJlUnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvU29mdHdhcmVGYWN0b3J5QXJjaGl0ZWN0dXJlUnVsZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXdEO0FBR3hEOzs7OztHQUtHO0FBQ0gsTUFBYSxnQ0FBZ0M7SUFDM0MsWUFBWSxPQUFvQjtRQUM5QixJQUFJLGlCQUFRLENBQUMsT0FBTyxFQUFFLDZCQUE2QixFQUFFO1lBQ25ELE1BQU0sRUFBRSxJQUFJO1lBQ1osS0FBSyxFQUFFO2dCQUNMLEtBQUs7Z0JBQ0wsK0VBQStFO2dCQUMvRSw4RUFBOEU7Z0JBQzlFLGdGQUFnRjtnQkFDaEYsOEJBQThCO2dCQUM5QixLQUFLO2dCQUNMLGdDQUFnQztnQkFDaEMsb0NBQW9DO2dCQUNwQyxvREFBb0Q7Z0JBQ3BELHVDQUF1QztnQkFDdkMsRUFBRTtnQkFDRixrQ0FBa0M7Z0JBQ2xDLDZCQUE2QjtnQkFDN0Isb0ZBQW9GO2dCQUNwRixtQkFBbUI7Z0JBQ25CLG1GQUFtRjtnQkFDbkYscUJBQXFCO2dCQUNyQixHQUFHO2dCQUNILEVBQUU7Z0JBQ0Ysb0NBQW9DO2dCQUNwQywrQkFBK0I7Z0JBQy9CLDBFQUEwRTtnQkFDMUUsbUJBQW1CO2dCQUNuQiwwRUFBMEU7Z0JBQzFFLDJCQUEyQjtnQkFDM0IsbUZBQW1GO2dCQUNuRixzQkFBc0I7Z0JBQ3RCLEdBQUc7Z0JBQ0gsRUFBRTtnQkFDRixrQkFBa0I7Z0JBQ2xCLGVBQWU7Z0JBQ2Ysd0JBQXdCO2dCQUN4QixxQkFBcUI7Z0JBQ3JCLHFEQUFxRDtnQkFDckQseURBQXlEO2dCQUN6RCxHQUFHO2dCQUNILEVBQUU7Z0JBQ0YsdUJBQXVCO2dCQUN2QixtQkFBbUI7Z0JBQ25CLHFCQUFxQjtnQkFDckIsb0JBQW9CO2dCQUNwQixHQUFHO2dCQUNILEVBQUU7Z0JBQ0Ysa0RBQWtEO2dCQUNsRCxzR0FBc0c7Z0JBQ3RHLDRF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RDtnQkFDdEQsRUFBRTtnQkFDRix5RUFBeUU7Z0JBQ3pFLDBFQUEwRTtnQkFDMUUsc0NBQXNDO2dCQUN0QyxFQUFFO2dCQUNGLGtCQUFrQjtnQkFDbEIsRUFBRTtnQkFDRixzRUFBc0U7Z0JBQ3RFLHNFQUFzRTtnQkFDdEUsa0VBQWtFO2dCQUNsRSxFQUFFO2dCQUNGLHdCQUF3QjtnQkFDeEIsRUFBRTtnQkFDRix1RUFBdUU7Z0JBQ3ZFLDRFQUE0RTtnQkFDNUUsOEVBQThFO2dCQUM5RSwyRUFBMkU7Z0JBQzNFLDZFQUE2RTtnQkFDN0UsMkVBQTJFO2dCQUMzRSxrRUFBa0U7YUFDbkU7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLG1CQUFVLENBQUMsT0FBTyxFQUFFLCtCQUErQixFQUFFO1lBQ3ZELFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJO1NBQ3hELENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTFWRCw0RUEwVkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBKc29uRmlsZSwgU2FtcGxlRmlsZSwgVGV4dEZpbGUgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgTm9kZVByb2plY3QgfSBmcm9tICdwcm9qZW4vbGliL2phdmFzY3JpcHQnO1xuXG4vKipcbiAqIFRoZSBnZW5lcmljLCBkYXRhLWRyaXZlbiBhcmNoaXRlY3R1cmUgcnVsZSBlbmdpbmUgcGx1cyBhbiBlbXB0eSBzZWVkXG4gKiBydWxlcy5qc29uLiBgY2hlY2sudHNgL2B0c2NvbmZpZy5qc29uYC9gUkVBRE1FLm1kYCBhcmUgbWFuYWdlZCAoQmF0bWFuXG4gKiBvd25zIHRoZSBlbmdpbmUpOyBgcnVsZXMuanNvbmAgaXMgYSBgU2FtcGxlRmlsZWAg4oCUIGVhY2ggcmVwbydzIG93biBydWxlc1xuICogYXJlIGRhdGEgdGhlIHRlYW0gb3ducywgbm90IHNvbWV0aGluZyBCYXRtYW4gc2hvdWxkIG92ZXJ3cml0ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNvZnR3YXJlRmFjdG9yeUFyY2hpdGVjdHVyZVJ1bGVzIHtcbiAgY29uc3RydWN0b3IocHJvamVjdDogTm9kZVByb2plY3QpIHtcbiAgICBuZXcgVGV4dEZpbGUocHJvamVjdCwgJ2FyY2hpdGVjdHVyZS1ydWxlcy9jaGVjay50cycsIHtcbiAgICAgIG1hcmtlcjogdHJ1ZSxcbiAgICAgIGxpbmVzOiBbXG4gICAgICAgICcvKionLFxuICAgICAgICAnICogR2VuZXJpYyBhcmNoaXRlY3R1cmUtcnVsZSBlbmdpbmUuIFJ1bGVzIGxpdmUgZW50aXJlbHkgaW4gcnVsZXMuanNvbiDigJQgdGhpcycsXG4gICAgICAgICcgKiBmaWxlIG9ubHkga25vd3MgaG93IHRvIGV2YWx1YXRlIHRoZSBjaGVjayBcInR5cGVzXCIgdGhhdCBydWxlcyBjYW4gZGVjbGFyZS4nLFxuICAgICAgICAnICogQWRkIGEgbmV3IHJ1bGUgYnkgYWRkaW5nIGEgcnVsZXMuanNvbiBlbnRyeTsgYWRkIGEgbmV3IGNoZWNrIHR5cGUgYnkgYWRkaW5nJyxcbiAgICAgICAgJyAqIGEgY2FzZSBpbiBldmFsdWF0ZVJ1bGUoKS4nLFxuICAgICAgICAnICovJyxcbiAgICAgICAgXCJpbXBvcnQgKiBhcyBmcyBmcm9tICdub2RlOmZzJztcIixcbiAgICAgICAgXCJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XCIsXG4gICAgICAgIFwiaW1wb3J0IHsgZXhlY0ZpbGVTeW5jIH0gZnJvbSAnbm9kZTpjaGlsZF9wcm9jZXNzJztcIixcbiAgICAgICAgXCJpbXBvcnQgcnVsZXNGaWxlIGZyb20gJy4vcnVsZXMuanNvbic7XCIsXG4gICAgICAgICcnLFxuICAgICAgICAnaW50ZXJmYWNlIEZvcmJpZGRlbkltcG9ydENoZWNrIHsnLFxuICAgICAgICBcIiAgdHlwZTogJ2ZvcmJpZGRlbi1pbXBvcnQnO1wiLFxuICAgICAgICAnICAvLyBHbG9iIHBhdHRlcm5zIChyZWxhdGl2ZSB0byByZXBvIHJvb3QpIHNlbGVjdGluZyB0aGUgZmlsZXMgdGhpcyBydWxlIGluc3BlY3RzLicsXG4gICAgICAgICcgIGZyb206IHN0cmluZ1tdOycsXG4gICAgICAgICcgIC8vIEdsb2IgcGF0dGVybnMgKHJlbGF0aXZlIHRvIHJlcG8gcm9vdCkgdGhhdCBcImZyb21cIiBmaWxlcyBtYXkgbm90IGltcG9ydCBmcm9tLicsXG4gICAgICAgICcgIGZvcmJpZDogc3RyaW5nW107JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2ludGVyZmFjZSBSZXF1aXJlZENvbXBhbmlvbkNoZWNrIHsnLFxuICAgICAgICBcIiAgdHlwZTogJ3JlcXVpcmVkLWNvbXBhbmlvbic7XCIsXG4gICAgICAgICcgIC8vIEdsb2IgcGF0dGVybnMgc2VsZWN0aW5nIGNoYW5nZWQgZmlsZXMgdGhhdCB0cmlnZ2VyIHRoZSByZXF1aXJlbWVudC4nLFxuICAgICAgICAnICBmcm9tOiBzdHJpbmdbXTsnLFxuICAgICAgICAnICAvLyBHbG9iIHBhdHRlcm5zIC0tIGF0IGxlYXN0IG9uZSBDSEFOR0VEIGZpbGUgbXVzdCBtYXRjaCBvbmUgb2YgdGhlc2UuJyxcbiAgICAgICAgJyAgcmVxdWlyZU9uZU9mOiBzdHJpbmdbXTsnLFxuICAgICAgICBcIiAgLy8gT3B0aW9uYWwgLS0gJ2Zyb20nIGZpbGVzIG1hdGNoaW5nIHRoZXNlIGdsb2JzIGRvbid0IHRyaWdnZXIgdGhlIHJlcXVpcmVtZW50LlwiLFxuICAgICAgICAnICBleGVtcHQ/OiBzdHJpbmdbXTsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnaW50ZXJmYWNlIFJ1bGUgeycsXG4gICAgICAgICcgIGlkOiBzdHJpbmc7JyxcbiAgICAgICAgJyAgZGVzY3JpcHRpb246IHN0cmluZzsnLFxuICAgICAgICAnICBlbmFibGVkOiBib29sZWFuOycsXG4gICAgICAgIFwiICBzZXZlcml0eTogJ2xvdycgfCAnbWVkaXVtJyB8ICdoaWdoJyB8ICdjcml0aWNhbCc7XCIsXG4gICAgICAgICcgIGNoZWNrOiBGb3JiaWRkZW5JbXBvcnRDaGVjayB8IFJlcXVpcmVkQ29tcGFuaW9uQ2hlY2s7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2ludGVyZmFjZSBWaW9sYXRpb24geycsXG4gICAgICAgICcgIHJ1bGVJZDogc3RyaW5nOycsXG4gICAgICAgICcgIHNldmVyaXR5OiBzdHJpbmc7JyxcbiAgICAgICAgJyAgbWVzc2FnZTogc3RyaW5nOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgIFwiY29uc3QgUkVQT19ST09UID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJyk7XCIsXG4gICAgICAgIFwiY29uc3QgSUdOT1JFRF9ESVJTID0gbmV3IFNldChbJ25vZGVfbW9kdWxlcycsICcuZ2l0JywgJy5zd2FtcCcsICdjZGsub3V0JywgJ2xpYicsICdidWlsZCcsICdkaXN0J10pO1wiLFxuICAgICAgICBcImNvbnN0IEJBU0VfUkVGID0gcHJvY2Vzcy5lbnYuQVJDSElURUNUVVJFX1JVTEVTX0JBU0VfUkVGIHx8ICdvcmlnaW4vbWFpbic7XCIsXG4gICAgICAgICcnLFxuICAgICAgICAnLy8gTWluaW1hbCBnbG9iIC0+IFJlZ0V4cDogc3VwcG9ydHMgXCIqXCIsIFwiKipcIiwgXCIqKi9cIiBhbmQgbGl0ZXJhbCBwYXRoIHNlZ21lbnRzLicsXG4gICAgICAgICcvLyBObyBuZXcgZGVwZW5kZW5jeSBmb3IgdGhpcyDigJQgdGhlIG9ubHkgcGF0dGVybiBzaGFwZXMgcnVsZXMuanNvbiBldmVyIG5lZWRzJyxcbiAgICAgICAgJy8vIGFyZSBkaXJlY3RvcnktcHJlZml4IGdsb2JzIGxpa2UgXCJzcmMvZG9tYWlucy8qL2NvbW1hbmRzLyoqXCIuJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGdsb2JUb1JlZ0V4cChnbG9iOiBzdHJpbmcpOiBSZWdFeHAgeycsXG4gICAgICAgIFwiICBsZXQgb3V0ID0gJyc7XCIsXG4gICAgICAgICcgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2xvYi5sZW5ndGg7IGkrKykgeycsXG4gICAgICAgICcgICAgY29uc3QgYyA9IGdsb2JbaV07JyxcbiAgICAgICAgXCIgICAgaWYgKGMgPT09ICcqJyAmJiBnbG9iW2kgKyAxXSA9PT0gJyonKSB7XCIsXG4gICAgICAgICcgICAgICBpKys7JyxcbiAgICAgICAgXCIgICAgICBpZiAoZ2xvYltpICsgMV0gPT09ICcvJykge1wiLFxuICAgICAgICBcIiAgICAgICAgb3V0ICs9ICcoPzouKi8pPyc7XCIsXG4gICAgICAgICcgICAgICAgIGkrKzsnLFxuICAgICAgICAnICAgICAgfSBlbHNlIHsnLFxuICAgICAgICBcIiAgICAgICAgb3V0ICs9ICcuKic7XCIsXG4gICAgICAgICcgICAgICB9JyxcbiAgICAgICAgXCIgICAgfSBlbHNlIGlmIChjID09PSAnKicpIHtcIixcbiAgICAgICAgXCIgICAgICBvdXQgKz0gJ1teL10qJztcIixcbiAgICAgICAgXCIgICAgfSBlbHNlIGlmIChjID09PSAnPycpIHtcIixcbiAgICAgICAgXCIgICAgICBvdXQgKz0gJ1teL10nO1wiLFxuICAgICAgICBcIiAgICB9IGVsc2UgaWYgKCcuK14ke30oKXxbXVxcXFxcXFxcJy5pbmNsdWRlcyhjKSkge1wiLFxuICAgICAgICAnICAgICAgb3V0ICs9IGBcXFxcXFxcXCR7Y31gOycsXG4gICAgICAgICcgICAgfSBlbHNlIHsnLFxuICAgICAgICAnICAgICAgb3V0ICs9IGM7JyxcbiAgICAgICAgJyAgICB9JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIHJldHVybiBuZXcgUmVnRXhwKGBeJHtvdXR9JGApOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBtYXRjaGVzQW55KHJlbEZpbGU6IHN0cmluZywgZ2xvYnM6IHN0cmluZ1tdKTogYm9vbGVhbiB7JyxcbiAgICAgICAgJyAgcmV0dXJuIGdsb2JzLnNvbWUoKGdsb2IpID0+IGdsb2JUb1JlZ0V4cChnbG9iKS50ZXN0KHJlbEZpbGUpKTsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnZnVuY3Rpb24gdG9SZXBvUmVsYXRpdmUoYWJzUGF0aDogc3RyaW5nKTogc3RyaW5nIHsnLFxuICAgICAgICBcIiAgcmV0dXJuIHBhdGgucmVsYXRpdmUoUkVQT19ST09ULCBhYnNQYXRoKS5zcGxpdChwYXRoLnNlcCkuam9pbignLycpO1wiLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnLy8gRmlsZXMgY2hhbmdlZCByZWxhdGl2ZSB0byBiYXNlUmVmLCBzb3VyY2VkIGZyb20gZ2l0IHJhdGhlciB0aGFuIHRoZSB3aG9sZS10cmVlJyxcbiAgICAgICAgJy8vIHdhbGsoKSBiZWxvdyAtLSByZXF1aXJlZC1jb21wYW5pb24gY2hlY2tzIGNhcmUgYWJvdXQgd2hhdCBhIFBSIHRvdWNoZWQsIG5vdCcsXG4gICAgICAgICcvLyB0aGUgZnVsbCByZXBvLiBUaHJvd3MgKHJhdGhlciB0aGFuIHJldHVybmluZyBbXSkgaWYgYmFzZVJlZiBjYW5ub3QgYmUgcmVzb2x2ZWQsJyxcbiAgICAgICAgJy8vIHNvIGFuIHVuZmV0Y2hlZCBiYXNlIHJlZiBmYWlscyB0aGUgY2hlY2sgaW5zdGVhZCBvZiBzaWxlbnRseSByZXBvcnRpbmcgbm8gdmlvbGF0aW9ucy4nLFxuICAgICAgICAnZnVuY3Rpb24gZ2V0Q2hhbmdlZEZpbGVzKGJhc2VSZWY6IHN0cmluZyk6IHN0cmluZ1tdIHsnLFxuICAgICAgICAnICBsZXQgb3V0cHV0OiBzdHJpbmc7JyxcbiAgICAgICAgJyAgdHJ5IHsnLFxuICAgICAgICBcIiAgICBvdXRwdXQgPSBleGVjRmlsZVN5bmMoJ2dpdCcsIFsnZGlmZicsICctLW5hbWUtb25seScsICctLWRpZmYtZmlsdGVyPUFDTVInLCBgJHtiYXNlUmVmfS4uLkhFQURgXSwge1wiLFxuICAgICAgICAnICAgICAgY3dkOiBSRVBPX1JPT1QsJyxcbiAgICAgICAgXCIgICAgICBlbmNvZGluZzogJ3V0ZjgnLFwiLFxuICAgICAgICAnICAgIH0pOycsXG4gICAgICAgICcgIH0gY2F0Y2ggKGVycikgeycsXG4gICAgICAgICcgICAgdGhyb3cgbmV3IEVycm9yKCcsXG4gICAgICAgICcgICAgICBgYXJjaGl0ZWN0dXJlLXJ1bGVzOiBmYWlsZWQgdG8gY29tcHV0ZSB0aGUgY2hhbmdlZC1maWxlIHNldCBhZ2FpbnN0IGJhc2UgcmVmIFwiJHtiYXNlUmVmfVwiIC0tIGAgKycsXG4gICAgICAgICcgICAgICAgIGBpcyBpdCBmZXRjaGVkIGFuZCByZXNvbHZhYmxlIGluIHRoaXMgY2hlY2tvdXQ/ICgkeyhlcnIgYXMgRXJyb3IpLm1lc3NhZ2V9KWAsJyxcbiAgICAgICAgJyAgICApOycsXG4gICAgICAgICcgIH0nLFxuICAgICAgICBcIiAgcmV0dXJuIG91dHB1dC5zcGxpdCgnXFxcXG4nKS5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKS5maWx0ZXIoKGxpbmUpID0+IGxpbmUubGVuZ3RoID4gMCk7XCIsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiB3YWxrKGRpcjogc3RyaW5nLCBhY2M6IHN0cmluZ1tdID0gW10pOiBzdHJpbmdbXSB7JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBlbnRyeSBvZiBmcy5yZWFkZGlyU3luYyhkaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkgeycsXG4gICAgICAgICcgICAgaWYgKElHTk9SRURfRElSUy5oYXMoZW50cnkubmFtZSkpIGNvbnRpbnVlOycsXG4gICAgICAgICcgICAgY29uc3QgZnVsbCA9IHBhdGguam9pbihkaXIsIGVudHJ5Lm5hbWUpOycsXG4gICAgICAgICcgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHsnLFxuICAgICAgICAnICAgICAgd2FsayhmdWxsLCBhY2MpOycsXG4gICAgICAgIFwiICAgIH0gZWxzZSBpZiAoZW50cnkuaXNGaWxlKCkgJiYgKGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50cycpIHx8IGVudHJ5Lm5hbWUuZW5kc1dpdGgoJy50c3gnKSkpIHtcIixcbiAgICAgICAgJyAgICAgIGFjYy5wdXNoKGZ1bGwpOycsXG4gICAgICAgICcgICAgfScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnICByZXR1cm4gYWNjOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgIFwiY29uc3QgUkVMQVRJVkVfSU1QT1JUX1JFID0gLyg/OmltcG9ydHxleHBvcnQpXFxcXHMrKD86W14nXFxcIjtdKj9cXFxcYmZyb21cXFxccyspP1snXFxcIl0oXFxcXC5bXidcXFwiXSspWydcXFwiXS9nO1wiLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGZpbmRSZWxhdGl2ZUltcG9ydHMoc291cmNlOiBzdHJpbmcpOiBzdHJpbmdbXSB7JyxcbiAgICAgICAgJyAgY29uc3Qgc3BlY3M6IHN0cmluZ1tdID0gW107JyxcbiAgICAgICAgJyAgUkVMQVRJVkVfSU1QT1JUX1JFLmxhc3RJbmRleCA9IDA7JyxcbiAgICAgICAgJyAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsOycsXG4gICAgICAgICcgIHdoaWxlICgobWF0Y2ggPSBSRUxBVElWRV9JTVBPUlRfUkUuZXhlYyhzb3VyY2UpKSkgeycsXG4gICAgICAgICcgICAgc3BlY3MucHVzaChtYXRjaFsxXSk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcgIHJldHVybiBzcGVjczsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAnLy8gQW4gaW1wb3J0IHNwZWMgcmVzb2x2ZXMgdG8gYSBtb2R1bGUsIG5vdCBhIHNwZWNpZmljIGZpbGUgZXh0ZW5zaW9uLCBzbyBhJyxcbiAgICAgICAgJy8vIGZvcmJpZCBnbG9iIGlzIGNoZWNrZWQgYWdhaW5zdCB0aGUgYmFyZSByZXNvbHZlZCBwYXRoIHBsdXMgaXRzIC50cy9pbmRleC50cycsXG4gICAgICAgICcvLyB2YXJpYW50cy4nLFxuICAgICAgICAnZnVuY3Rpb24gcmVzb2x2ZWRDYW5kaWRhdGVzKGZyb21GaWxlOiBzdHJpbmcsIHNwZWM6IHN0cmluZyk6IHN0cmluZ1tdIHsnLFxuICAgICAgICAnICBjb25zdCByZXNvbHZlZCA9IHRvUmVwb1JlbGF0aXZlKHBhdGgubm9ybWFsaXplKHBhdGguam9pbihwYXRoLmRpcm5hbWUoZnJvbUZpbGUpLCBzcGVjKSkpOycsXG4gICAgICAgICcgIHJldHVybiBbcmVzb2x2ZWQsIGAke3Jlc29sdmVkfS50c2AsIGAke3Jlc29sdmVkfS9pbmRleC50c2BdOycsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBldmFsdWF0ZUZvcmJpZGRlbkltcG9ydChydWxlOiBSdWxlKTogVmlvbGF0aW9uW10geycsXG4gICAgICAgICcgIGNvbnN0IHsgZnJvbSwgZm9yYmlkIH0gPSBydWxlLmNoZWNrIGFzIEZvcmJpZGRlbkltcG9ydENoZWNrOycsXG4gICAgICAgICcgIGlmIChmcm9tLmxlbmd0aCA9PT0gMCB8fCBmb3JiaWQubGVuZ3RoID09PSAwKSByZXR1cm4gW107JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGNvbnN0IHZpb2xhdGlvbnM6IFZpb2xhdGlvbltdID0gW107JyxcbiAgICAgICAgJyAgZm9yIChjb25zdCBmaWxlIG9mIHdhbGsoUkVQT19ST09UKSkgeycsXG4gICAgICAgICcgICAgY29uc3QgcmVsRmlsZSA9IHRvUmVwb1JlbGF0aXZlKGZpbGUpOycsXG4gICAgICAgICcgICAgaWYgKCFtYXRjaGVzQW55KHJlbEZpbGUsIGZyb20pKSBjb250aW51ZTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgXCIgICAgY29uc3Qgc291cmNlID0gZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGY4Jyk7XCIsXG4gICAgICAgICcgICAgZm9yIChjb25zdCBzcGVjIG9mIGZpbmRSZWxhdGl2ZUltcG9ydHMoc291cmNlKSkgeycsXG4gICAgICAgICcgICAgICBjb25zdCBjYW5kaWRhdGVzID0gcmVzb2x2ZWRDYW5kaWRhdGVzKGZpbGUsIHNwZWMpOycsXG4gICAgICAgICcgICAgICBpZiAoY2FuZGlkYXRlcy5zb21lKChjYW5kaWRhdGUpID0+IG1hdGNoZXNBbnkoY2FuZGlkYXRlLCBmb3JiaWQpKSkgeycsXG4gICAgICAgICcgICAgICAgIHZpb2xhdGlvbnMucHVzaCh7JyxcbiAgICAgICAgJyAgICAgICAgICBydWxlSWQ6IHJ1bGUuaWQsJyxcbiAgICAgICAgJyAgICAgICAgICBzZXZlcml0eTogcnVsZS5zZXZlcml0eSwnLFxuICAgICAgICAnICAgICAgICAgIG1lc3NhZ2U6IGAke3JlbEZpbGV9IGltcG9ydHMgXCIke3NwZWN9XCIsIHdoaWNoIHJlc29sdmVzIHVuZGVyIGEgcGF0aCBmb3JiaWRkZW4gYnkgcnVsZSBcIiR7cnVsZS5pZH1cImAsJyxcbiAgICAgICAgJyAgICAgICAgfSk7JyxcbiAgICAgICAgJyAgICAgIH0nLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJyAgcmV0dXJuIHZpb2xhdGlvbnM7JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGV2YWx1YXRlUmVxdWlyZWRDb21wYW5pb24ocnVsZTogUnVsZSk6IFZpb2xhdGlvbltdIHsnLFxuICAgICAgICAnICBjb25zdCB7IGZyb20sIHJlcXVpcmVPbmVPZiwgZXhlbXB0IH0gPSBydWxlLmNoZWNrIGFzIFJlcXVpcmVkQ29tcGFuaW9uQ2hlY2s7JyxcbiAgICAgICAgJyAgaWYgKGZyb20ubGVuZ3RoID09PSAwIHx8IHJlcXVpcmVPbmVPZi5sZW5ndGggPT09IDApIHJldHVybiBbXTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgY29uc3QgY2hhbmdlZEZpbGVzID0gZ2V0Q2hhbmdlZEZpbGVzKEJBU0VfUkVGKTsnLFxuICAgICAgICAnICBjb25zdCB0cmlnZ2VyaW5nID0gY2hhbmdlZEZpbGVzLmZpbHRlcignLFxuICAgICAgICAnICAgIChmaWxlKSA9PiBtYXRjaGVzQW55KGZpbGUsIGZyb20pICYmICEoZXhlbXB0ICYmIG1hdGNoZXNBbnkoZmlsZSwgZXhlbXB0KSksJyxcbiAgICAgICAgJyAgKTsnLFxuICAgICAgICAnICBpZiAodHJpZ2dlcmluZy5sZW5ndGggPT09IDApIHJldHVybiBbXTsnLFxuICAgICAgICAnJyxcbiAgICAgICAgJyAgY29uc3Qgc2F0aXNmaWVkID0gY2hhbmdlZEZpbGVzLnNvbWUoKGZpbGUpID0+IG1hdGNoZXNBbnkoZmlsZSwgcmVxdWlyZU9uZU9mKSk7JyxcbiAgICAgICAgJyAgaWYgKHNhdGlzZmllZCkgcmV0dXJuIFtdOycsXG4gICAgICAgICcnLFxuICAgICAgICAnICByZXR1cm4gWycsXG4gICAgICAgICcgICAgeycsXG4gICAgICAgICcgICAgICBydWxlSWQ6IHJ1bGUuaWQsJyxcbiAgICAgICAgJyAgICAgIHNldmVyaXR5OiBydWxlLnNldmVyaXR5LCcsXG4gICAgICAgICcgICAgICBtZXNzYWdlOiBgY2hhbmdlZCBmaWxlKHMpICR7dHJpZ2dlcmluZy5qb2luKFxcJywgXFwnKX0gbWF0Y2ggcnVsZSBcIiR7cnVsZS5pZH1cIlxcJ3MgXCJmcm9tXCIgcGF0dGVybnMsIGJ1dCBubyBjaGFuZ2VkIGZpbGUgbWF0Y2hlcyBpdHMgXCJyZXF1aXJlT25lT2ZcIiBwYXR0ZXJuc2AsJyxcbiAgICAgICAgJyAgICB9LCcsXG4gICAgICAgICcgIF07JyxcbiAgICAgICAgJ30nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2Z1bmN0aW9uIGV2YWx1YXRlUnVsZShydWxlOiBSdWxlKTogVmlvbGF0aW9uW10geycsXG4gICAgICAgICcgIHN3aXRjaCAocnVsZS5jaGVjay50eXBlKSB7JyxcbiAgICAgICAgXCIgICAgY2FzZSAnZm9yYmlkZGVuLWltcG9ydCc6XCIsXG4gICAgICAgICcgICAgICByZXR1cm4gZXZhbHVhdGVGb3JiaWRkZW5JbXBvcnQocnVsZSk7JyxcbiAgICAgICAgXCIgICAgY2FzZSAncmVxdWlyZWQtY29tcGFuaW9uJzpcIixcbiAgICAgICAgJyAgICAgIHJldHVybiBldmFsdWF0ZVJlcXVpcmVkQ29tcGFuaW9uKHJ1bGUpOycsXG4gICAgICAgICcgICAgZGVmYXVsdDonLFxuICAgICAgICAnICAgICAgdGhyb3cgbmV3IEVycm9yKGBhcmNoaXRlY3R1cmUtcnVsZXM6IHVua25vd24gY2hlY2sudHlwZSBcIiR7KHJ1bGUuY2hlY2sgYXMgeyB0eXBlOiBzdHJpbmcgfSkudHlwZX1cIiBvbiBydWxlIFwiJHtydWxlLmlkfVwiYCk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICd9JyxcbiAgICAgICAgJycsXG4gICAgICAgICdmdW5jdGlvbiBtYWluKCk6IG51bWJlciB7JyxcbiAgICAgICAgJyAgY29uc3QgcnVsZXMgPSAocnVsZXNGaWxlIGFzIHsgcnVsZXM6IFJ1bGVbXSB9KS5ydWxlczsnLFxuICAgICAgICAnICBsZXQgZXZhbHVhdGVkID0gMDsnLFxuICAgICAgICAnICBsZXQgZGVmZXJyZWQgPSAwOycsXG4gICAgICAgICcgIGNvbnN0IHZpb2xhdGlvbnM6IFZpb2xhdGlvbltdID0gW107JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIGZvciAoY29uc3QgcnVsZSBvZiBydWxlcykgeycsXG4gICAgICAgICcgICAgaWYgKCFydWxlLmVuYWJsZWQpIHsnLFxuICAgICAgICAnICAgICAgZGVmZXJyZWQrKzsnLFxuICAgICAgICAnICAgICAgY29uc29sZS5sb2coYFtkZWZlcnJlZF0gJHtydWxlLmlkfTogJHtydWxlLmRlc2NyaXB0aW9ufWApOycsXG4gICAgICAgICcgICAgICBjb250aW51ZTsnLFxuICAgICAgICAnICAgIH0nLFxuICAgICAgICAnICAgIGV2YWx1YXRlZCsrOycsXG4gICAgICAgICcgICAgdmlvbGF0aW9ucy5wdXNoKC4uLmV2YWx1YXRlUnVsZShydWxlKSk7JyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICcnLFxuICAgICAgICAnICBjb25zb2xlLmxvZyhgXFxcXG5hcmNoaXRlY3R1cmUtcnVsZXM6ICR7ZXZhbHVhdGVkfSBydWxlKHMpIGV2YWx1YXRlZCwgJHtkZWZlcnJlZH0gZGVmZXJyZWQsICR7dmlvbGF0aW9ucy5sZW5ndGh9IHZpb2xhdGlvbihzKWApOycsXG4gICAgICAgICcgIGZvciAoY29uc3QgdmlvbGF0aW9uIG9mIHZpb2xhdGlvbnMpIHsnLFxuICAgICAgICAnICAgIGNvbnNvbGUuZXJyb3IoYCAgWyR7dmlvbGF0aW9uLnNldmVyaXR5fV0gJHt2aW9sYXRpb24ucnVsZUlkfTogJHt2aW9sYXRpb24ubWVzc2FnZX1gKTsnLFxuICAgICAgICAnICB9JyxcbiAgICAgICAgJycsXG4gICAgICAgICcgIHJldHVybiB2aW9sYXRpb25zLmxlbmd0aCA+IDAgPyAxIDogMDsnLFxuICAgICAgICAnfScsXG4gICAgICAgICcnLFxuICAgICAgICAncHJvY2Vzcy5leGl0KG1haW4oKSk7JyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBuZXcgSnNvbkZpbGUocHJvamVjdCwgJ2FyY2hpdGVjdHVyZS1ydWxlcy90c2NvbmZpZy5qc29uJywge1xuICAgICAgbWFya2VyOiBmYWxzZSxcbiAgICAgIG9iajoge1xuICAgICAgICBleHRlbmRzOiAnLi4vdHNjb25maWcuanNvbicsXG4gICAgICAgIGNvbXBpbGVyT3B0aW9uczoge1xuICAgICAgICAgIG5vRW1pdDogdHJ1ZSxcbiAgICAgICAgICByb290RGlyOiAnLicsXG4gICAgICAgIH0sXG4gICAgICAgIGluY2x1ZGU6IFsnKi50cycsICcqLmpzb24nXSxcbiAgICAgICAgZXhjbHVkZTogWydub2RlX21vZHVsZXMnXSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBuZXcgVGV4dEZpbGUocHJvamVjdCwgJ2FyY2hpdGVjdHVyZS1ydWxlcy9SRUFETUUubWQnLCB7XG4gICAgICBtYXJrZXI6IHRydWUsXG4gICAgICBsaW5lczogW1xuICAgICAgICAnIyBBcmNoaXRlY3R1cmUgcnVsZXMnLFxuICAgICAgICAnJyxcbiAgICAgICAgJ0EgZGF0YS1kcml2ZW4gcmVnaXN0cnkgb2YgYXJjaGl0ZWN0dXJhbCBjb25zdHJhaW50cywgZW5mb3JjZWQgYnknLFxuICAgICAgICAnYHBucG0gdmFsaWRhdGU6YXJjaGl0ZWN0dXJlYCBhbmQgcnVuIGFzIHBhcnQgb2YgdGhlIHByZS1QUiB2ZXJpZmljYXRpb24nLFxuICAgICAgICAnd29ya2Zsb3cgKGB3b3JrZmxvd3Mvd29ya2Zsb3ctcHJlLXByLXZlcmlmeS55YW1sYCkgYmVmb3JlIHRoZSBzd2FtcCBmYWN0b3J5JyxcbiAgICAgICAgJ29wZW5zIGEgUFIuIE5ldyBydWxlcyBhcmUgbmV3IGVudHJpZXMgaW4gYHJ1bGVzLmpzb25gLCBub3QgbmV3IGNvZGUg4oCUIHRoZScsXG4gICAgICAgICdlbmdpbmUgKGBjaGVjay50c2ApIG9ubHkgbmVlZHMgYSBuZXcgY2FzZSBpbiBgZXZhbHVhdGVSdWxlKClgIHdoZW4gYSBydWxlJyxcbiAgICAgICAgJ25lZWRzIGEgZ2VudWluZWx5IG5ldyBraW5kIG9mIGNoZWNrLicsXG4gICAgICAgICcnLFxuICAgICAgICAnIyMgUnVsZSBzaGFwZScsXG4gICAgICAgICcnLFxuICAgICAgICAnVHdvIGBjaGVjay50eXBlYHMgYXJlIGltcGxlbWVudGVkOiBgZm9yYmlkZGVuLWltcG9ydGAgKHdob2xlLXJlcG8gaW1wb3J0LWdyYXBoJyxcbiAgICAgICAgJ2NoZWNrKSBhbmQgYHJlcXVpcmVkLWNvbXBhbmlvbmAgKGRpZmYtYmFzZWQgY28tY2hhbmdlIGNoZWNrKS4nLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2BgYGpzb24nLFxuICAgICAgICAneycsXG4gICAgICAgICcgIFwiaWRcIjogXCJ1bmlxdWUtaWRcIiwnLFxuICAgICAgICAnICBcImRlc2NyaXB0aW9uXCI6IFwiV2hhdCB0aGlzIGVuZm9yY2VzIGFuZCB3aHkuXCIsJyxcbiAgICAgICAgJyAgXCJlbmFibGVkXCI6IHRydWUsJyxcbiAgICAgICAgJyAgXCJzZXZlcml0eVwiOiBcImxvd1wiIHwgXCJtZWRpdW1cIiB8IFwiaGlnaFwiIHwgXCJjcml0aWNhbFwiLCcsXG4gICAgICAgICcgIFwiY2hlY2tcIjogeycsXG4gICAgICAgICcgICAgXCJ0eXBlXCI6IFwiZm9yYmlkZGVuLWltcG9ydFwiLCcsXG4gICAgICAgICcgICAgXCJmcm9tXCI6IFtcImdsb2IgcGF0dGVybnMgc2VsZWN0aW5nIGZpbGVzIHRoaXMgcnVsZSBpbnNwZWN0c1wiXSwnLFxuICAgICAgICAnICAgIFwiZm9yYmlkXCI6IFtcImdsb2IgcGF0dGVybnMgdGhvc2UgZmlsZXMgbWF5IG5vdCBpbXBvcnQgZnJvbVwiXScsXG4gICAgICAgICcgIH0nLFxuICAgICAgICAnfScsXG4gICAgICAgICdgYGAnLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2BgYGpzb24nLFxuICAgICAgICAneycsXG4gICAgICAgICcgIFwiaWRcIjogXCJ1bmlxdWUtaWRcIiwnLFxuICAgICAgICAnICBcImRlc2NyaXB0aW9uXCI6IFwiV2hhdCB0aGlzIGVuZm9yY2VzIGFuZCB3aHkuXCIsJyxcbiAgICAgICAgJyAgXCJlbmFibGVkXCI6IHRydWUsJyxcbiAgICAgICAgJyAgXCJzZXZlcml0eVwiOiBcImxvd1wiIHwgXCJtZWRpdW1cIiB8IFwiaGlnaFwiIHwgXCJjcml0aWNhbFwiLCcsXG4gICAgICAgICcgIFwiY2hlY2tcIjogeycsXG4gICAgICAgICcgICAgXCJ0eXBlXCI6IFwicmVxdWlyZWQtY29tcGFuaW9uXCIsJyxcbiAgICAgICAgJyAgICBcImZyb21cIjogW1wiZ2xvYiBwYXR0ZXJucyBzZWxlY3RpbmcgY2hhbmdlZCBmaWxlcyB0aGF0IHRyaWdnZXIgdGhlIHJlcXVpcmVtZW50XCJdLCcsXG4gICAgICAgICcgICAgXCJyZXF1aXJlT25lT2ZcIjogW1wiZ2xvYiBwYXR0ZXJucyAtLSBhdCBsZWFzdCBvbmUgQ0hBTkdFRCBmaWxlIG11c3QgbWF0Y2ggb25lIG9mIHRoZXNlXCJdLCcsXG4gICAgICAgICcgICAgXCJleGVtcHRcIjogW1wib3B0aW9uYWwgLS0gZnJvbS1maWxlcyBtYXRjaGluZyB0aGVzZSBnbG9icyBkb25cXCd0IHRyaWdnZXIgdGhlIHJlcXVpcmVtZW50XCJdJyxcbiAgICAgICAgJyAgfScsXG4gICAgICAgICd9JyxcbiAgICAgICAgJ2BgYCcsXG4gICAgICAgICcnLFxuICAgICAgICAnYHJlcXVpcmVkLWNvbXBhbmlvbmAgZXZhbHVhdGVzIHRoZSBzZXQgb2YgZmlsZXMgY2hhbmdlZCBpbiB0aGUgY3VycmVudCBkaWZmJyxcbiAgICAgICAgJyhgZ2l0IGRpZmYgLS1uYW1lLW9ubHkgLS1kaWZmLWZpbHRlcj1BQ01SIDxiYXNlUmVmPi4uLkhFQURgKSwgbm90IHRoZSB3aG9sZScsXG4gICAgICAgICdyZXBvIHRyZWU6IGlmIGFueSBjaGFuZ2VkIGZpbGUgbWF0Y2hlcyBgZnJvbWAgKGFuZCBkb2VzblxcJ3QgbWF0Y2ggYGV4ZW1wdGApIGJ1dCcsXG4gICAgICAgICdubyBjaGFuZ2VkIGZpbGUgbWF0Y2hlcyBgcmVxdWlyZU9uZU9mYCwgdGhhdFxcJ3MgYSB2aW9sYXRpb24uIFRoZSBiYXNlIHJlZicsXG4gICAgICAgICdkZWZhdWx0cyB0byBgb3JpZ2luL21haW5gIGFuZCBjYW4gYmUgb3ZlcnJpZGRlbiB3aXRoIHRoZScsXG4gICAgICAgICdgQVJDSElURUNUVVJFX1JVTEVTX0JBU0VfUkVGYCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gVGhpcyBtZWFucyB0aGUgY2hlY2tvdXQnLFxuICAgICAgICAncnVubmluZyBgcG5wbSB2YWxpZGF0ZTphcmNoaXRlY3R1cmVgIG11c3QgaGF2ZSB0aGF0IGJhc2UgcmVmIGZldGNoZWQgYW5kJyxcbiAgICAgICAgJ3Jlc29sdmFibGUgKGEgc2hhbGxvdywgc2luZ2xlLWJyYW5jaCBjaGVja291dCB3aWxsIG1ha2UgdGhlIGNoZWNrIGZhaWwgY2xvc2VkJyxcbiAgICAgICAgJ3dpdGggYW4gZXJyb3IgcmF0aGVyIHRoYW4gc2lsZW50bHkgcmVwb3J0aW5nIG5vIHZpb2xhdGlvbnMpIOKAlCBtYWtlIHN1cmUnLFxuICAgICAgICAnd2hhdGV2ZXIgcnVucyB0aGlzIHRhc2sgZmV0Y2hlcyBlbm91Z2ggaGlzdG9yeSBmb3IgYGdpdCBkaWZmIDxiYXNlUmVmPi4uLkhFQURgJyxcbiAgICAgICAgJ3RvIHN1Y2NlZWQuJyxcbiAgICAgICAgJycsXG4gICAgICAgICdgZnJvbWAvYHJlcXVpcmVPbmVPZmAvYGV4ZW1wdGAgZ2xvYnMgYXJlIG1hdGNoZWQgYWdhaW5zdCB0aGUgcGF0aHMgYGdpdCcsXG4gICAgICAgICdkaWZmIC0tbmFtZS1vbmx5YCByZXBvcnRzLCB3aGljaCBhcmUgcmVsYXRpdmUgdG8gdGhlIGdpdCByZXBvc2l0b3J5XFwncycsXG4gICAgICAgICd0b3AtbGV2ZWwgZGlyZWN0b3J5LiBUaGlzIGxpbmVzIHVwIHdpdGggYGZyb21gXFwncyBvd24gZGlyZWN0b3J5ICh0aGUgcGFyZW50IG9mJyxcbiAgICAgICAgJ2BhcmNoaXRlY3R1cmUtcnVsZXMvYCkgaW4gdGhlIGNvbW1vbiBjYXNlIOKAlCBhIHNpbmdsZSBwcm9qZWN0IGdlbmVyYXRlZCBhdCB0aGUnLFxuICAgICAgICAncmVwbyByb290IOKAlCBidXQgaWYgYGFyY2hpdGVjdHVyZS1ydWxlcy9gIGluc3RlYWQgbGl2ZXMgdW5kZXIgYSBuZXN0ZWQnLFxuICAgICAgICAnc3ViZGlyZWN0b3J5IG9mIGEgbGFyZ2VyIGdpdCByZXBvLCB3cml0ZSBnbG9icyByZWxhdGl2ZSB0byB0aGUgZ2l0IHJvb3QsIG5vdCcsXG4gICAgICAgICd0byB0aGF0IHN1YmRpcmVjdG9yeS4nLFxuICAgICAgICAnJyxcbiAgICAgICAgJyoqYHJlcXVpcmVkLWNvbXBhbmlvbmAgaXMgYSBjb3ZlcmFnZSBjaGVjaywgbm90IGEgY29ycmVjdG5lc3MgY2hlY2suKiogSXQgb25seScsXG4gICAgICAgICdjb25maXJtcyB0aGF0ICpzb21lKiBjaGFuZ2VkIGZpbGUgbWF0Y2hlcyBgcmVxdWlyZU9uZU9mYCDigJQgaXQgY2FuXFwndCB0ZWxsJyxcbiAgICAgICAgJ3doZXRoZXIgdGhhdCBjaGFuZ2UgaXMgYWN0dWFsbHkgcmVsYXRlZCB0byB0aGUgdHJpZ2dlcmluZyBgZnJvbWAgY2hhbmdlIChhJyxcbiAgICAgICAgJ3RyaXZpYWwgb3IgdW5yZWxhdGVkIGVkaXQgdG8gYSBmaWxlIHVuZGVyIGByZXF1aXJlT25lT2ZgIHNhdGlzZmllcyB0aGUgcnVsZScsXG4gICAgICAgICdqdXN0IGFzIHdlbGwgYXMgYSBzdWJzdGFudGl2ZSBvbmUpLCBhbmQgaXQgY2FuXFwndCB0ZWxsIHdoZXRoZXIgYSBnaXZlbiBgZnJvbWAnLFxuICAgICAgICAnY2hhbmdlIGdlbnVpbmVseSBuZWVkZWQgYSBjb21wYW5pb24gYXQgYWxsIChhIHB1cmUgcmVmYWN0b3IgbWlnaHQgbm90KS4nLFxuICAgICAgICAnYGV4ZW1wdGAgY292ZXJzICprbm93biwgZ2xvYi1leHByZXNzaWJsZSogZXhjZXB0aW9ucywgYnV0IG5vdCBldmVyeSBmYWxzZScsXG4gICAgICAgICdwb3NpdGl2ZSBpcyBleHByZXNzaWJsZSBhcyBhIGdsb2Ig4oCUIHRoYXQganVkZ21lbnQgY2FsbCBzdGlsbCBiZWxvbmdzIHRvIHRoZScsXG4gICAgICAgICdydWxlIGF1dGhvciAoc2NvcGluZyBgZnJvbWAvYGV4ZW1wdGApIGFuZCB0aGUgcmV2aWV3ZXIgKHJlYWRpbmcgdGhlIGNvbXBhbmlvbicsXG4gICAgICAgICdkaWZmLCBub3QganVzdCB0cnVzdGluZyB0aGF0IHRoZSBjaGVjayBwYXNzZWQpLiBBbHNvIG5vdGUgdGhhdCBgbWFpbigpYCcsXG4gICAgICAgICdmYWlscyB0aGUgd2hvbGUgcnVuIG9uICphbnkqIHZpb2xhdGlvbiByZWdhcmRsZXNzIG9mIGBzZXZlcml0eWAg4oCUIGBzZXZlcml0eWAnLFxuICAgICAgICAnaXMgaW5mb3JtYXRpb25hbCBvbmx5LCBub3QgYSBsZW5pZW5jeSBsZXZlciDigJQgc28gc3RhcnQgd2l0aCBhIG5hcnJvd2x5JyxcbiAgICAgICAgJ3Njb3BlZCBgZnJvbWAgKG9yIGBlbmFibGVkOiBmYWxzZWApIGFuZCB3aWRlbiBpdCBhcyB0aGUgY29udmVudGlvbiBwcm92ZXMnLFxuICAgICAgICAnaXRzZWxmLCB0aGUgc2FtZSBndWlkYW5jZSBhcyBmb3IgYGZvcmJpZGRlbi1pbXBvcnRgLicsXG4gICAgICAgICcnLFxuICAgICAgICAnYGVuYWJsZWQ6IGZhbHNlYCBydWxlcyBhcmUgc2tpcHBlZCAocmVwb3J0ZWQgYXMgXCJkZWZlcnJlZFwiKSByYXRoZXIgdGhhbicsXG4gICAgICAgIFwiZXZhbHVhdGVkIOKAlCB1c2UgdGhpcyBmb3IgYSBydWxlIHlvdSd2ZSBuYW1lZCBhbmQgZGVzY3JpYmVkIGJ1dCBkb24ndCB5ZXRcIixcbiAgICAgICAgJ2hhdmUgYSBjb25jcmV0ZSBjb252ZW50aW9uIHRvIGNoZWNrLicsXG4gICAgICAgICcnLFxuICAgICAgICAnIyMgQ3VycmVudCBydWxlcycsXG4gICAgICAgICcnLFxuICAgICAgICAnTm9uZSB5ZXQg4oCUIGBydWxlcy5qc29uYCBzaGlwcyBlbXB0eS4gQWRkIHJ1bGVzIGFzIHlvdXIgZG9tYWluIG1vZHVsZScsXG4gICAgICAgICdjb252ZW50aW9ucyBzb2xpZGlmeSAoZS5nLiBhbiBldmVudC1zb3VyY2VkL0NRUlMgbW9kdWxlIGxheW91dCB1bmRlcicsXG4gICAgICAgICdgc3JjL2RvbWFpbnMvPG5hbWU+L3tjb21tYW5kcyxldmVudHMsYWdncmVnYXRlcyxwcm9qZWN0aW9uc30vYCkuJyxcbiAgICAgICAgJycsXG4gICAgICAgICcjIyBBZGRpbmcgYSBjaGVjayB0eXBlJyxcbiAgICAgICAgJycsXG4gICAgICAgICdgZm9yYmlkZGVuLWltcG9ydGAgKHdob2xlLXJlcG8gaW1wb3J0IGdyYXBoKSBhbmQgYHJlcXVpcmVkLWNvbXBhbmlvbmAnLFxuICAgICAgICAnKGRpZmYtYmFzZWQgY28tY2hhbmdlKSBhcmUgdGhlIGltcGxlbWVudGVkIGBjaGVjay50eXBlYHMuIElmIGEgZnV0dXJlIHJ1bGUnLFxuICAgICAgICAnbmVlZHMgYSBkYXRhIHNvdXJjZSBuZWl0aGVyIHByb3ZpZGVzIChlLmcuIFwiZXZlcnkgYWdncmVnYXRlIGZpbGUgbXVzdCBoYXZlIGEnLFxuICAgICAgICAnbWF0Y2hpbmcgZXZlbnRzIGZpbGVcIiwgd2hpY2ggaXMgYSByZXBvLXdpZGUgbmFtaW5nIGNvbnZlbnRpb24gcmF0aGVyIHRoYW4nLFxuICAgICAgICAnZWl0aGVyIGFuIGltcG9ydC1ncmFwaCBvciBhIGRpZmYgY2hlY2spLCBhZGQgYSBuZXcgYHR5cGVgIHZhbHVlLCBhIG1hdGNoaW5nJyxcbiAgICAgICAgJ2ludGVyZmFjZSwgYW5kIGEgY2FzZSBpbiBgZXZhbHVhdGVSdWxlKClgIGluIGBjaGVjay50c2Ag4oCUIGtlZXAgdGhlIGVuZ2luZScsXG4gICAgICAgICdpdHNlbGYgZ2VuZXJpYzsgcnVsZS1zcGVjaWZpYyBrbm93bGVkZ2UgYmVsb25ncyBpbiBgcnVsZXMuanNvbmAuJyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBuZXcgU2FtcGxlRmlsZShwcm9qZWN0LCAnYXJjaGl0ZWN0dXJlLXJ1bGVzL3J1bGVzLmpzb24nLCB7XG4gICAgICBjb250ZW50czogSlNPTi5zdHJpbmdpZnkoeyBydWxlczogW10gfSwgbnVsbCwgMikgKyAnXFxuJyxcbiAgICB9KTtcbiAgfVxufVxuIl19
|
|
@@ -31,7 +31,7 @@ const DEFAULT_GITHUB_OWNER = 'macedon-technologies';
|
|
|
31
31
|
* workflows that wire them together) is templated.
|
|
32
32
|
*/
|
|
33
33
|
class SoftwareFactoryFiles {
|
|
34
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.SoftwareFactoryFiles", version: "1.
|
|
34
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.SoftwareFactoryFiles", version: "1.25.0" };
|
|
35
35
|
constructor(project, options) {
|
|
36
36
|
const { repoName, actionVersions } = options;
|
|
37
37
|
const githubOwner = options.githubOwner || DEFAULT_GITHUB_OWNER;
|
|
@@ -7,7 +7,7 @@ const javascript_1 = require("projen/lib/javascript");
|
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
8
|
const WorkflowActionVersions_1 = require("./WorkflowActionVersions");
|
|
9
9
|
class StagingDeployWorkflow extends projen_1.YamlFile {
|
|
10
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.StagingDeployWorkflow", version: "1.
|
|
10
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.StagingDeployWorkflow", version: "1.25.0" };
|
|
11
11
|
constructor(project, options) {
|
|
12
12
|
const packageManager = project.package.packageManager;
|
|
13
13
|
const actionVersions = (0, WorkflowActionVersions_1.resolveActionVersions)(options.actionVersions);
|
|
@@ -39,7 +39,7 @@ const fs = __importStar(require("fs"));
|
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
40
|
const projen_1 = require("projen");
|
|
41
41
|
class WorkflowAutoDiscover extends projen_1.Component {
|
|
42
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.WorkflowAutoDiscover", version: "1.
|
|
42
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@macedon-technologies/batman.WorkflowAutoDiscover", version: "1.25.0" };
|
|
43
43
|
constructor(project) {
|
|
44
44
|
super(project);
|
|
45
45
|
}
|