@pipeline-builder/pipeline-manager 4.1.14 → 4.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/config.yml +16 -37
  2. package/dist/boilerplate.js +10 -2
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +97 -79
  5. package/dist/commands/audit-stacks.js +3 -3
  6. package/dist/commands/create-pat.d.ts +2 -3
  7. package/dist/commands/create-pat.d.ts.map +1 -1
  8. package/dist/commands/create-pat.js +3 -4
  9. package/dist/commands/create-pipeline.d.ts.map +1 -1
  10. package/dist/commands/create-pipeline.js +198 -190
  11. package/dist/commands/list-pipelines.js +2 -2
  12. package/dist/commands/list-plugins.js +2 -2
  13. package/dist/commands/login.d.ts +2 -2
  14. package/dist/commands/login.js +3 -3
  15. package/dist/commands/new-plugin.d.ts +48 -5
  16. package/dist/commands/new-plugin.d.ts.map +1 -1
  17. package/dist/commands/new-plugin.js +261 -95
  18. package/dist/commands/plugin-lifecycle.d.ts +29 -0
  19. package/dist/commands/plugin-lifecycle.d.ts.map +1 -0
  20. package/dist/commands/plugin-lifecycle.js +147 -0
  21. package/dist/commands/provision.d.ts +42 -2
  22. package/dist/commands/provision.d.ts.map +1 -1
  23. package/dist/commands/provision.js +184 -147
  24. package/dist/commands/publish-plugin.d.ts +62 -0
  25. package/dist/commands/publish-plugin.d.ts.map +1 -0
  26. package/dist/commands/publish-plugin.js +224 -0
  27. package/dist/commands/redrive-events.d.ts +1 -1
  28. package/dist/commands/redrive-events.js +2 -2
  29. package/dist/commands/store-token.d.ts +46 -1
  30. package/dist/commands/store-token.d.ts.map +1 -1
  31. package/dist/commands/store-token.js +127 -102
  32. package/dist/commands/test-plugin.d.ts +72 -0
  33. package/dist/commands/test-plugin.d.ts.map +1 -0
  34. package/dist/commands/test-plugin.js +285 -0
  35. package/dist/commands/upload-plugin.d.ts +6 -7
  36. package/dist/commands/upload-plugin.d.ts.map +1 -1
  37. package/dist/commands/upload-plugin.js +127 -189
  38. package/dist/commands/validate-plugin.d.ts +37 -4
  39. package/dist/commands/validate-plugin.d.ts.map +1 -1
  40. package/dist/commands/validate-plugin.js +129 -144
  41. package/dist/commands/validate-templates.d.ts.map +1 -1
  42. package/dist/commands/validate-templates.js +8 -9
  43. package/dist/config/plugin-catalog-assets.d.ts +13 -0
  44. package/dist/config/plugin-catalog-assets.d.ts.map +1 -0
  45. package/dist/config/plugin-catalog-assets.js +21 -0
  46. package/dist/config.yml +16 -37
  47. package/dist/lambda/token-renew-handler.d.ts.map +1 -1
  48. package/dist/lambda/token-renew-handler.js +109 -154
  49. package/dist/types/config.d.ts +2 -6
  50. package/dist/types/config.d.ts.map +1 -1
  51. package/dist/types/config.js +1 -1
  52. package/dist/types/plugin.d.ts +21 -0
  53. package/dist/types/plugin.d.ts.map +1 -1
  54. package/dist/types/plugin.js +1 -1
  55. package/dist/utils/aws-env.d.ts +1 -2
  56. package/dist/utils/aws-env.d.ts.map +1 -1
  57. package/dist/utils/aws-env.js +2 -3
  58. package/dist/utils/catalog-prompt.d.ts +26 -0
  59. package/dist/utils/catalog-prompt.d.ts.map +1 -0
  60. package/dist/utils/catalog-prompt.js +113 -0
  61. package/dist/utils/command-utils.d.ts.map +1 -1
  62. package/dist/utils/command-utils.js +14 -3
  63. package/dist/utils/config-loader.d.ts.map +1 -1
  64. package/dist/utils/config-loader.js +4 -6
  65. package/dist/utils/credential-store.d.ts +16 -0
  66. package/dist/utils/credential-store.d.ts.map +1 -1
  67. package/dist/utils/credential-store.js +57 -2
  68. package/dist/utils/deploy-runner.d.ts.map +1 -1
  69. package/dist/utils/deploy-runner.js +7 -2
  70. package/dist/utils/pipeline-config.d.ts +1 -2
  71. package/dist/utils/pipeline-config.d.ts.map +1 -1
  72. package/dist/utils/pipeline-config.js +1 -1
  73. package/dist/utils/plugin-docker.d.ts +44 -0
  74. package/dist/utils/plugin-docker.d.ts.map +1 -0
  75. package/dist/utils/plugin-docker.js +71 -0
  76. package/dist/utils/plugin-package.d.ts +40 -0
  77. package/dist/utils/plugin-package.d.ts.map +1 -0
  78. package/dist/utils/plugin-package.js +159 -0
  79. package/dist/utils/plugin-resolver.d.ts.map +1 -1
  80. package/dist/utils/plugin-resolver.js +43 -29
  81. package/dist/utils/plugin-scan.d.ts +22 -0
  82. package/dist/utils/plugin-scan.d.ts.map +1 -0
  83. package/dist/utils/plugin-scan.js +52 -0
  84. package/dist/utils/plugin-zip.d.ts +15 -0
  85. package/dist/utils/plugin-zip.d.ts.map +1 -0
  86. package/dist/utils/plugin-zip.js +96 -0
  87. package/dist/utils/registry.d.ts +15 -0
  88. package/dist/utils/registry.d.ts.map +1 -1
  89. package/dist/utils/registry.js +17 -2
  90. package/dist/utils/service-account.d.ts.map +1 -1
  91. package/dist/utils/service-account.js +9 -10
  92. package/package.json +45 -8
@@ -2,128 +2,294 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import fs from 'fs';
4
4
  import path from 'path';
5
+ import { PLUGIN_BASE_IMAGES, PLUGIN_CATEGORIES, PLUGIN_COMPUTE_TYPES, PLUGIN_NAME_PATTERN, PLUGIN_SUMMARY_MAX, PLUGIN_TYPES, isAllowedSpdxId, validateCatalogField, } from '@pipeline-builder/api-core';
5
6
  import { Command } from 'commander';
6
- import YAML from 'yaml';
7
+ import { CURATED_ICON_KEYS } from '../config/plugin-catalog-assets.js';
7
8
  import { printCommandHeader } from '../utils/command-utils.js';
8
9
  import { ERROR_CODES, handleError, ValidationError } from '../utils/error-handler.js';
9
- import { printInfo, printSection, printSuccess, fileExists, ensureOutputDirectory } from '../utils/output-utils.js';
10
- const PLUGIN_TYPES = ['CodeBuildStep', 'ShellStep', 'ManualApprovalStep'];
11
- const COMPUTE_TYPES = ['SMALL', 'MEDIUM', 'LARGE', 'X2_LARGE'];
12
- const BUILD_TYPES = ['build_image', 'prebuilt', 'metadata_only'];
10
+ import { printInfo, printSection, printSuccess, printWarning, fileExists, ensureOutputDirectory } from '../utils/output-utils.js';
11
+ /** `my-linter` → `My Linter`. */
12
+ export const displayNameOf = (name) => name.split('-').filter(Boolean).map(w => w[0].toUpperCase() + w.slice(1)).join(' ');
13
+ /** YAML double-quoted scalar (JSON strings are valid YAML). */
14
+ const q = (s) => JSON.stringify(s);
15
+ /** Validate the flags into a scaffold request (throws ValidationError). */
16
+ export function resolveScaffoldInput(options, now = new Date()) {
17
+ const name = options.name ?? '';
18
+ if (!name || !PLUGIN_NAME_PATTERN.test(name) || name.length > 64) {
19
+ throw new ValidationError('--name must be 1-64 lowercase letters, digits and hyphens', 'name', name);
20
+ }
21
+ const category = options.category ?? '';
22
+ if (!PLUGIN_CATEGORIES.includes(category)) {
23
+ throw new ValidationError(`--category must be one of: ${PLUGIN_CATEGORIES.join(', ')}`, 'category', category);
24
+ }
25
+ const base = PLUGIN_BASE_IMAGES.find(b => b.key === (options.base ?? 'plugin'));
26
+ if (!base)
27
+ throw new ValidationError(`--base must be one of: ${PLUGIN_BASE_IMAGES.map(b => b.key).join(', ')} (see --list-bases)`, 'base', options.base);
28
+ const pluginType = options.type ?? 'CodeBuildStep';
29
+ if (!PLUGIN_TYPES.includes(pluginType))
30
+ throw new ValidationError(`--type must be one of: ${PLUGIN_TYPES.join(', ')}`, 'type', pluginType);
31
+ const computeType = options.compute ?? 'SMALL';
32
+ if (!PLUGIN_COMPUTE_TYPES.includes(computeType))
33
+ throw new ValidationError(`--compute must be one of: ${PLUGIN_COMPUTE_TYPES.join(', ')}`, 'compute', computeType);
34
+ const license = options.license ?? 'Apache-2.0';
35
+ if (!isAllowedSpdxId(license))
36
+ throw new ValidationError('--license must be a supported SPDX identifier (e.g. Apache-2.0, MIT)', 'license', license);
37
+ const icon = options.icon && options.icon !== 'none' ? options.icon : null;
38
+ if (icon !== null && !CURATED_ICON_KEYS.includes(icon)) {
39
+ throw new ValidationError(`--icon must be a curated key (${CURATED_ICON_KEYS.join(', ')}) or none`, 'icon', icon);
40
+ }
41
+ const display = displayNameOf(name);
42
+ const summary = options.summary ?? `${display} as a pipeline step.`;
43
+ const description = options.description
44
+ ?? `${display} runs as a CodeBuild step in your pipeline. Replace this with what the plugin checks or builds, what it reads from the workspace and what it writes.`;
45
+ for (const [field, value] of [['summary', summary], ['description', description]]) {
46
+ const checked = validateCatalogField(field, value);
47
+ if (!checked.ok)
48
+ throw new ValidationError(`--${field} ${checked.error}${field === 'summary' ? ` (max ${PLUGIN_SUMMARY_MAX})` : ''}`, field, value);
49
+ }
50
+ return {
51
+ name,
52
+ category,
53
+ base,
54
+ summary,
55
+ description,
56
+ license,
57
+ icon,
58
+ pluginType,
59
+ computeType,
60
+ author: options.author ?? `The ${name} authors`,
61
+ year: now.getUTCFullYear(),
62
+ };
63
+ }
64
+ const MIT_TEXT = (year, author) => `MIT License
65
+
66
+ Copyright (c) ${year} ${author}
67
+
68
+ Permission is hereby granted, free of charge, to any person obtaining a copy
69
+ of this software and associated documentation files (the "Software"), to deal
70
+ in the Software without restriction, including without limitation the rights
71
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
72
+ copies of the Software, and to permit persons to whom the Software is
73
+ furnished to do so, subject to the following conditions:
74
+
75
+ The above copyright notice and this permission notice shall be included in all
76
+ copies or substantial portions of the Software.
77
+
78
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
79
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
80
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
81
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
82
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
83
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
84
+ SOFTWARE.
85
+ `;
86
+ /** LICENSE: the MIT text in full, else the SPDX notice (Apache-2.0's own recommended form). */
87
+ export function licenseText(input) {
88
+ if (input.license === 'MIT')
89
+ return MIT_TEXT(input.year, input.author);
90
+ if (input.license === 'Apache-2.0') {
91
+ return `Copyright ${input.year} ${input.author}
92
+
93
+ Licensed under the Apache License, Version 2.0 (the "License");
94
+ you may not use this file except in compliance with the License.
95
+ You may obtain a copy of the License at
96
+
97
+ http://www.apache.org/licenses/LICENSE-2.0
98
+
99
+ Unless required by applicable law or agreed to in writing, software
100
+ distributed under the License is distributed on an "AS IS" BASIS,
101
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
102
+ See the License for the specific language governing permissions and
103
+ limitations under the License.
104
+
105
+ SPDX-License-Identifier: Apache-2.0
106
+ `;
107
+ }
108
+ return `Copyright ${input.year} ${input.author}
109
+
110
+ This plugin is licensed under ${input.license}.
111
+ Full text: https://spdx.org/licenses/${input.license}.html
112
+
113
+ SPDX-License-Identifier: ${input.license}
114
+ `;
115
+ }
116
+ /** Keywords: the category plus the name's words (≤ 10, each ≤ 32, no duplicates). */
117
+ export function scaffoldKeywords(name, category) {
118
+ return [...new Set([category, ...name.split('-')].filter(w => w.length >= 2 && w.length <= 32))].slice(0, 10);
119
+ }
120
+ function dockerfileText(input) {
121
+ const display = displayNameOf(input.name);
122
+ return `# ${display} — ${input.summary}
123
+ #
124
+ # Thin layer over ${input.base.image} (deploy/plugins/_base/${input.base.dir}:
125
+ # ${input.base.provides}). Add ONLY this plugin's own tool, pinned. Rules
126
+ # (deploy/plugins/README.md, enforced by test-plugins.sh and \`plugin validate\`):
127
+ # - every download goes through fetch-verified with a pinned version and a
128
+ # pinned per-architecture digest; never a rolling URL, never curl | sh;
129
+ # - switch to root only for the steps that need it, and end as USER 1000:1000;
130
+ # - a tool that ships several versions puts them under /opt/<tool>/versions
131
+ # with the active one symlinked from a uid-1000-owned /opt/<tool>/bin.
132
+
133
+ FROM ${input.base.image}
134
+
135
+ # ─── Tool install (uncomment and fill in) ───
136
+ # Take each digest from the vendor's published checksum file.
137
+ # USER root
138
+ # ARG TOOL_VERSION=1.2.3
139
+ # ARG TOOL_SHA256_AMD64=<sha256 of the linux-amd64 asset>
140
+ # ARG TOOL_SHA256_ARM64=<sha256 of the linux-arm64 asset>
141
+ # RUN set -eux; \\
142
+ # case "$(dpkg --print-architecture)" in \\
143
+ # amd64) arch=amd64; sum="\${TOOL_SHA256_AMD64}" ;; \\
144
+ # arm64) arch=arm64; sum="\${TOOL_SHA256_ARM64}" ;; \\
145
+ # *) echo "unsupported architecture: $(dpkg --print-architecture)" >&2; exit 1 ;; \\
146
+ # esac; \\
147
+ # fetch-verified "https://example.com/tool/v\${TOOL_VERSION}/tool-linux-\${arch}.tar.gz" "$sum" /tmp/tool.tar.gz; \\
148
+ # install -d /opt/tool/bin; \\
149
+ # tar -xzf /tmp/tool.tar.gz -C /opt/tool/bin; \\
150
+ # rm -f /tmp/tool.tar.gz; \\
151
+ # chmod -R a+rX /opt/tool
152
+ # ENV PATH="/opt/tool/bin:\${PATH}"
153
+
154
+ WORKDIR /app
155
+ USER 1000:1000
156
+ CMD ["bash"]
157
+ `;
158
+ }
159
+ function specText(input) {
160
+ const out = `${input.name}-reports`;
161
+ const isApproval = input.pluginType === 'ManualApprovalStep';
162
+ const lines = [
163
+ `name: ${input.name}`,
164
+ `summary: ${q(input.summary)}`,
165
+ `description: ${q(input.description)}`,
166
+ 'keywords:',
167
+ ...scaffoldKeywords(input.name, input.category).map(k => ` - ${k}`),
168
+ `category: ${input.category}`,
169
+ 'version: 0.1.0',
170
+ `pluginType: ${input.pluginType}`,
171
+ `computeType: ${input.computeType}`,
172
+ `timeout: ${isApproval ? 0 : 10}`,
173
+ 'failureBehavior: fail',
174
+ 'secrets: []',
175
+ ];
176
+ if (!isApproval) {
177
+ lines.push(`primaryOutputDirectory: ${out}`, 'dockerfile: Dockerfile', 'installCommands:', ` - mkdir -p ${out}`, 'commands:', ' # Replace with the real tool invocation. run-logged (from the base image)', ' # streams output to the console AND the log, and exits with the command\'s', ' # own status, so a failure is never masked.', ' - |', ' set -e', ` echo "Running ${input.name} in $(pwd)"`, ` run-logged ${out}/${input.name}.log -- echo "${input.name} ran"`, '# Run against the built image by test-plugins.sh --build and `plugin test`.', `smokeTest: ${q(input.base.smokeTest)}`);
178
+ }
179
+ lines.push('', '# ─── Catalog metadata ───', `license: ${input.license}`, input.icon
180
+ ? `icon: ${input.icon} # curated keys are for Official and Verified listings; Community listings upload an icon`
181
+ : '# icon: none — a Community listing uploads a raster icon or shows its monogram', 'changelog: |', ' 0.1.0: Initial release.', '');
182
+ return lines.join('\n');
183
+ }
184
+ function readmeText(input, relDir) {
185
+ const display = displayNameOf(input.name);
186
+ return `# ${display}
187
+
188
+ ${input.description}
189
+
190
+ ## Use it in a pipeline
191
+
192
+ \`\`\`yaml
193
+ steps:
194
+ - plugin: { name: ${input.name} }
195
+ \`\`\`
196
+
197
+ ${input.pluginType === 'ManualApprovalStep' ? '' : `The step writes its results to \`${input.name}-reports/\` (its primary output).
198
+
199
+ `}## Develop
200
+
201
+ \`\`\`bash
202
+ pipeline-manager plugin validate --dir ${relDir} # the server's schema + catalog report
203
+ pipeline-manager plugin test --dir ${relDir} --workspace ./sample-app
204
+ pipeline-manager plugin publish --dir ${relDir} # pre-flight, accept or edit metadata, submit
205
+ \`\`\`
206
+
207
+ The image builds FROM \`${input.base.image}\`; build the bases first with
208
+ \`deploy/bin/build-plugin-images.sh\`, or pass \`--image\` to \`plugin test\`.
209
+
210
+ ## License
211
+
212
+ ${input.license} — see [LICENSE](LICENSE).
213
+ `;
214
+ }
215
+ /** Every file of a new plugin, keyed by path relative to the plugin directory. */
216
+ export function scaffoldFiles(input, relDir = `./${input.name}`) {
217
+ const isApproval = input.pluginType === 'ManualApprovalStep';
218
+ const files = {
219
+ 'config.yaml': isApproval
220
+ ? 'pluginSpec: plugin-spec.yaml\nbuildType: metadata_only\n'
221
+ : 'pluginSpec: plugin-spec.yaml\nbuildType: build_image\ndockerfile: Dockerfile\n',
222
+ 'plugin-spec.yaml': specText(input),
223
+ 'README.md': readmeText(input, relDir),
224
+ 'LICENSE': licenseText(input),
225
+ };
226
+ if (!isApproval)
227
+ files.Dockerfile = dockerfileText(input);
228
+ return files;
229
+ }
230
+ /** Print the available plugin bases. */
231
+ export function printBases() {
232
+ printSection('Plugin base images', 'deploy/plugins/_base');
233
+ for (const b of PLUGIN_BASE_IMAGES)
234
+ console.log(` ${b.key.padEnd(8)} ${b.image.padEnd(28)} ${b.provides}`);
235
+ }
13
236
  /**
14
- * Register the `new-plugin` command — scaffold a local plugin directory
15
- * (`config.yaml`, `plugin-spec.yaml`, and a starter `Dockerfile`) that
16
- * `validate-plugin` accepts and `upload-plugin` can package.
237
+ * Register `plugin new` — scaffold a plugin FROM a `pipeline-<eco>-base` image:
238
+ * a Dockerfile that follows the catalog rules, a spec with catalog metadata, a
239
+ * README, a changelog entry and a LICENSE. It passes `plugin validate` and
240
+ * test-plugins.sh's static checks as generated.
17
241
  *
18
242
  * Usage:
19
- * pipeline-manager plugin new --name my-linter --category quality
20
- * pipeline-manager plugin new --name approve --type ManualApprovalStep
243
+ * pipeline-manager plugin new --list-bases
244
+ * pipeline-manager plugin new --name my-linter --category quality --base node
21
245
  */
22
246
  export function newPlugin(program) {
23
247
  program
24
248
  .command('new')
25
- .description('Scaffold a local plugin directory (config.yaml, plugin-spec.yaml, Dockerfile)')
26
- .requiredOption('--name <name>', 'Plugin name (lowercase letters, digits, hyphens)')
27
- .option('--category <category>', 'Plugin category (e.g. quality, security, language)', 'general')
249
+ .description('Scaffold a plugin from a pipeline-<eco>-base image (Dockerfile, spec, README, LICENSE)')
250
+ .option('--name <name>', 'Plugin name (lowercase letters, digits, hyphens)')
251
+ .option('--category <category>', `Category: ${PLUGIN_CATEGORIES.join(' | ')}`)
252
+ .option('--base <eco>', `Base image: ${PLUGIN_BASE_IMAGES.map(b => b.key).join(' | ')}`, 'plugin')
253
+ .option('--summary <text>', `Catalog one-liner (≤ ${PLUGIN_SUMMARY_MAX})`)
254
+ .option('--description <text>', 'Catalog description')
255
+ .option('--license <spdx>', 'SPDX license id', 'Apache-2.0')
256
+ .option('--icon <key>', 'Curated icon key (Official/Verified listings only), or none', 'none')
257
+ .option('--author <name>', 'Copyright holder for LICENSE')
28
258
  .option('--type <type>', `Plugin type: ${PLUGIN_TYPES.join(' | ')}`, 'CodeBuildStep')
29
- .option('--compute <compute>', `Compute type: ${COMPUTE_TYPES.join(' | ')}`, 'SMALL')
30
- .option('--build-type <buildType>', `Build type: ${BUILD_TYPES.join(' | ')}`, 'build_image')
259
+ .option('--compute <compute>', `Compute type: ${PLUGIN_COMPUTE_TYPES.join(' | ')}`, 'SMALL')
31
260
  .option('--dir <path>', 'Target directory (default ./<name>)')
32
261
  .option('--force', 'Overwrite an existing directory', false)
262
+ .option('--list-bases', 'List the available base images and exit', false)
33
263
  .action((options) => {
264
+ if (options.listBases) {
265
+ printBases();
266
+ return;
267
+ }
34
268
  const executionId = printCommandHeader('New Plugin');
35
269
  try {
36
- const name = options.name ?? '';
37
- // Canonical plugin-name pattern (matches validate-plugin, upload-plugin,
38
- // and the server's NAME_PATTERN).
39
- if (!/^[a-z0-9-]+$/.test(name)) {
40
- throw new ValidationError('Plugin name must contain only lowercase letters, digits, and hyphens (/^[a-z0-9-]+$/)');
41
- }
42
- const pluginType = options.type ?? 'CodeBuildStep';
43
- if (!PLUGIN_TYPES.includes(pluginType))
44
- throw new ValidationError(`--type must be one of: ${PLUGIN_TYPES.join(', ')}`);
45
- const computeType = options.compute ?? 'SMALL';
46
- if (!COMPUTE_TYPES.includes(computeType))
47
- throw new ValidationError(`--compute must be one of: ${COMPUTE_TYPES.join(', ')}`);
48
- const buildType = options.buildType ?? 'build_image';
49
- if (!BUILD_TYPES.includes(buildType))
50
- throw new ValidationError(`--build-type must be one of: ${BUILD_TYPES.join(', ')}`);
51
- const targetDir = path.resolve(options.dir ?? `./${name}`);
270
+ const input = resolveScaffoldInput(options);
271
+ const relDir = options.dir ?? `./${input.name}`;
272
+ const targetDir = path.resolve(relDir);
52
273
  if (fileExists(targetDir) && !options.force) {
53
274
  throw new ValidationError(`Directory already exists: ${targetDir} (use --force to overwrite)`);
54
275
  }
55
276
  ensureOutputDirectory(targetDir);
56
- const isApproval = pluginType === 'ManualApprovalStep';
57
- // Dockerfile only for image builds of a real build step.
58
- const needsDockerfile = buildType === 'build_image' && !isApproval;
59
- // config.yaml — build manifest.
60
- const config = { pluginSpec: 'plugin-spec.yaml', buildType };
61
- if (needsDockerfile)
62
- config.dockerfile = 'Dockerfile';
63
- fs.writeFileSync(path.join(targetDir, 'config.yaml'), YAML.stringify(config), 'utf-8');
64
- // plugin-spec.yaml — the PluginSpec.
65
- const spec = {
66
- name,
67
- version: '1.0.0',
68
- description: `${name} plugin`,
69
- keywords: [],
70
- category: options.category ?? 'general',
71
- pluginType,
72
- computeType,
73
- timeout: isApproval ? 0 : 10,
74
- failureBehavior: 'fail',
75
- secrets: [],
76
- };
77
- if (!isApproval) {
78
- spec.installCommands = ['echo "install step — add your setup commands"'];
79
- spec.commands = [`echo "run step for ${name} — replace with real commands"`];
80
- if (needsDockerfile)
81
- spec.dockerfile = 'Dockerfile';
82
- }
83
- fs.writeFileSync(path.join(targetDir, 'plugin-spec.yaml'), YAML.stringify(spec), 'utf-8');
84
- // Starter Dockerfile.
85
- if (needsDockerfile) {
86
- const dockerfile = [
87
- `# Dockerfile for the ${name} plugin.`,
88
- '# The base image provides the toolchain your commands need — keep it minimal and pinned.',
89
- 'FROM alpine:3.20',
90
- '',
91
- '# TODO: install the tools your plugin-spec commands invoke, e.g.:',
92
- '# RUN apk add --no-cache python3',
93
- '',
94
- 'WORKDIR /workspace',
95
- '',
96
- ].join('\n');
97
- fs.writeFileSync(path.join(targetDir, 'Dockerfile'), dockerfile, 'utf-8');
98
- }
99
- // README.
100
- const relDir = options.dir ?? `./${name}`;
101
- fs.writeFileSync(path.join(targetDir, 'README.md'), [
102
- `# ${name}`,
103
- '',
104
- `${name} plugin.`,
105
- '',
106
- 'Validate before upload:',
107
- '',
108
- ` pipeline-manager plugin validate --dir ${relDir}`,
109
- '',
110
- 'Package and upload:',
111
- '',
112
- ` (cd ${relDir} && zip -r ../${name}.zip .)`,
113
- ` pipeline-manager plugin upload --file ${name}.zip --organization <org>`,
114
- '',
115
- ].join('\n'), 'utf-8');
277
+ const files = scaffoldFiles(input, relDir);
278
+ for (const [file, content] of Object.entries(files))
279
+ fs.writeFileSync(path.join(targetDir, file), content, 'utf-8');
280
+ if (input.icon)
281
+ printWarning('Curated icons are reserved for Official listings and Verified publishers who own the mark; a Community listing with one is refused at submit');
116
282
  printSection('Scaffolded plugin', targetDir);
117
- printInfo('Created files', { files: ['config.yaml', 'plugin-spec.yaml', ...(needsDockerfile ? ['Dockerfile'] : []), 'README.md'] });
118
- printSuccess('Plugin scaffold created — edit plugin-spec.yaml then run validate-plugin', { executionId, dir: targetDir });
283
+ printInfo('Created files', { files: Object.keys(files), base: input.base.image });
284
+ printSuccess('Plugin scaffold created — next: plugin validate, plugin test, plugin publish', { executionId, dir: targetDir });
119
285
  }
120
286
  catch (err) {
121
287
  handleError(err, err instanceof ValidationError ? ERROR_CODES.VALIDATION : ERROR_CODES.GENERAL, {
122
288
  debug: program.opts().debug,
123
289
  exit: true,
124
- context: { command: 'new-plugin', executionId },
290
+ context: { command: 'plugin new', executionId },
125
291
  });
126
292
  }
127
293
  });
128
294
  }
129
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9uZXctcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BDLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RixPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFZcEgsTUFBTSxZQUFZLEdBQUcsQ0FBQyxlQUFlLEVBQUUsV0FBVyxFQUFFLG9CQUFvQixDQUFDLENBQUM7QUFDMUUsTUFBTSxhQUFhLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztBQUMvRCxNQUFNLFdBQVcsR0FBRyxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsZUFBZSxDQUFDLENBQUM7QUFFakU7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLE9BQWdCO0lBQ3hDLE9BQU87U0FDSixPQUFPLENBQUMsS0FBSyxDQUFDO1NBQ2QsV0FBVyxDQUFDLCtFQUErRSxDQUFDO1NBQzVGLGNBQWMsQ0FBQyxlQUFlLEVBQUUsa0RBQWtELENBQUM7U0FDbkYsTUFBTSxDQUFDLHVCQUF1QixFQUFFLG9EQUFvRCxFQUFFLFNBQVMsQ0FBQztTQUNoRyxNQUFNLENBQUMsZUFBZSxFQUFFLGdCQUFn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QkFDVixPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRTthQUNoRCxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IFlBTUwgZnJvbSAneWFtbCc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vdXRpbHMvZXJyb3ItaGFuZGxlci5qcyc7XG5pbXBvcnQgeyBwcmludEluZm8sIHByaW50U2VjdGlvbiwgcHJpbnRTdWNjZXNzLCBmaWxlRXhpc3RzLCBlbnN1cmVPdXRwdXREaXJlY3RvcnkgfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMuanMnO1xuXG5pbnRlcmZhY2UgTmV3UGx1Z2luT3B0aW9ucyB7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICB0eXBlPzogc3RyaW5nO1xuICBjb21wdXRlPzogc3RyaW5nO1xuICBidWlsZFR5cGU/OiBzdHJpbmc7XG4gIGRpcj86IHN0cmluZztcbiAgZm9yY2U/OiBib29sZWFuO1xufVxuXG5jb25zdCBQTFVHSU5fVFlQRVMgPSBbJ0NvZGVCdWlsZFN0ZXAnLCAnU2hlbGxTdGVwJywgJ01hbnVhbEFwcHJvdmFsU3RlcCddO1xuY29uc3QgQ09NUFVURV9UWVBFUyA9IFsnU01BTEwnLCAnTUVESVVNJywgJ0xBUkdFJywgJ1gyX0xBUkdFJ107XG5jb25zdCBCVUlMRF9UWVBFUyA9IFsnYnVpbGRfaW1hZ2UnLCAncHJlYnVpbHQnLCAnbWV0YWRhdGFfb25seSddO1xuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBgbmV3LXBsdWdpbmAgY29tbWFuZCDigJQgc2NhZmZvbGQgYSBsb2NhbCBwbHVnaW4gZGlyZWN0b3J5XG4gKiAoYGNvbmZpZy55YW1sYCwgYHBsdWdpbi1zcGVjLnlhbWxgLCBhbmQgYSBzdGFydGVyIGBEb2NrZXJmaWxlYCkgdGhhdFxuICogYHZhbGlkYXRlLXBsdWdpbmAgYWNjZXB0cyBhbmQgYHVwbG9hZC1wbHVnaW5gIGNhbiBwYWNrYWdlLlxuICpcbiAqIFVzYWdlOlxuICogICBwaXBlbGluZS1tYW5hZ2VyIHBsdWdpbiBuZXcgLS1uYW1lIG15LWxpbnRlciAtLWNhdGVnb3J5IHF1YWxpdHlcbiAqICAgcGlwZWxpbmUtbWFuYWdlciBwbHVnaW4gbmV3IC0tbmFtZSBhcHByb3ZlIC0tdHlwZSBNYW51YWxBcHByb3ZhbFN0ZXBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5ld1BsdWdpbihwcm9ncmFtOiBDb21tYW5kKTogdm9pZCB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnbmV3JylcbiAgICAuZGVzY3JpcHRpb24oJ1NjYWZmb2xkIGEgbG9jYWwgcGx1Z2luIGRpcmVjdG9yeSAoY29uZmlnLnlhbWwsIHBsdWdpbi1zcGVjLnlhbWwsIERvY2tlcmZpbGUpJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0tbmFtZSA8bmFtZT4nLCAnUGx1Z2luIG5hbWUgKGxvd2VyY2FzZSBsZXR0ZXJzLCBkaWdpdHMsIGh5cGhlbnMpJylcbiAgICAub3B0aW9uKCctLWNhdGVnb3J5IDxjYXRlZ29yeT4nLCAnUGx1Z2luIGNhdGVnb3J5IChlLmcuIHF1YWxpdHksIHNlY3VyaXR5LCBsYW5ndWFnZSknLCAnZ2VuZXJhbCcpXG4gICAgLm9wdGlvbignLS10eXBlIDx0eXBlPicsIGBQbHVnaW4gdHlwZTogJHtQTFVHSU5fVFlQRVMuam9pbignIHwgJyl9YCwgJ0NvZGVCdWlsZFN0ZXAnKVxuICAgIC5vcHRpb24oJy0tY29tcHV0ZSA8Y29tcHV0ZT4nLCBgQ29tcHV0ZSB0eXBlOiAke0NPTVBVVEVfVFlQRVMuam9pbignIHwgJyl9YCwgJ1NNQUxMJylcbiAgICAub3B0aW9uKCctLWJ1aWxkLXR5cGUgPGJ1aWxkVHlwZT4nLCBgQnVpbGQgdHlwZTogJHtCVUlMRF9UWVBFUy5qb2luKCcgfCAnKX1gLCAnYnVpbGRfaW1hZ2UnKVxuICAgIC5vcHRpb24oJy0tZGlyIDxwYXRoPicsICdUYXJnZXQgZGlyZWN0b3J5IChkZWZhdWx0IC4vPG5hbWU+KScpXG4gICAgLm9wdGlvbignLS1mb3JjZScsICdPdmVyd3JpdGUgYW4gZXhpc3RpbmcgZGlyZWN0b3J5JywgZmFsc2UpXG4gICAgLmFjdGlvbigob3B0aW9uczogTmV3UGx1Z2luT3B0aW9ucykgPT4ge1xuICAgICAgY29uc3QgZXhlY3V0aW9uSWQgPSBwcmludENvbW1hbmRIZWFkZXIoJ05ldyBQbHVnaW4nKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBvcHRpb25zLm5hbWUgPz8gJyc7XG4gICAgICAgIC8vIENhbm9uaWNhbCBwbHVnaW4tbmFtZSBwYXR0ZXJuIChtYXRjaGVzIHZhbGlkYXRlLXBsdWdpbiwgdXBsb2FkLXBsdWdpbixcbiAgICAgICAgLy8gYW5kIHRoZSBzZXJ2ZXIncyBOQU1FX1BBVFRFUk4pLlxuICAgICAgICBpZiAoIS9eW2EtejAtOS1dKyQvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdQbHVnaW4gbmFtZSBtdXN0IGNvbnRhaW4gb25seSBsb3dlcmNhc2UgbGV0dGVycywgZGlnaXRzLCBhbmQgaHlwaGVucyAoL15bYS16MC05LV0rJC8pJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGx1Z2luVHlwZSA9IG9wdGlvbnMudHlwZSA/PyAnQ29kZUJ1aWxkU3RlcCc7XG4gICAgICAgIGlmICghUExVR0lOX1RZUEVTLmluY2x1ZGVzKHBsdWdpblR5cGUpKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGAtLXR5cGUgbXVzdCBiZSBvbmUgb2Y6ICR7UExVR0lOX1RZUEVTLmpvaW4oJywgJyl9YCk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVUeXBlID0gb3B0aW9ucy5jb21wdXRlID8/ICdTTUFMTCc7XG4gICAgICAgIGlmICghQ09NUFVURV9UWVBFUy5pbmNsdWRlcyhjb21wdXRlVHlwZSkpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYC0tY29tcHV0ZSBtdXN0IGJlIG9uZSBvZjogJHtDT01QVVRFX1RZUEVTLmpvaW4oJywgJyl9YCk7XG4gICAgICAgIGNvbnN0IGJ1aWxkVHlwZSA9IG9wdGlvbnMuYnVpbGRUeXBlID8/ICdidWlsZF9pbWFnZSc7XG4gICAgICAgIGlmICghQlVJTERfVFlQRVMuaW5jbHVkZXMoYnVpbGRUeXBlKSkgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgLS1idWlsZC10eXBlIG11c3QgYmUgb25lIG9mOiAke0JVSUxEX1RZUEVTLmpvaW4oJywgJyl9YCk7XG5cbiAgICAgICAgY29uc3QgdGFyZ2V0RGlyID0gcGF0aC5yZXNvbHZlKG9wdGlvbnMuZGlyID8/IGAuLyR7bmFtZX1gKTtcbiAgICAgICAgaWYgKGZpbGVFeGlzdHModGFyZ2V0RGlyKSAmJiAhb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYERpcmVjdG9yeSBhbHJlYWR5IGV4aXN0czogJHt0YXJnZXREaXJ9ICh1c2UgLS1mb3JjZSB0byBvdmVyd3JpdGUpYCk7XG4gICAgICAgIH1cbiAgICAgICAgZW5zdXJlT3V0cHV0RGlyZWN0b3J5KHRhcmdldERpcik7XG5cbiAgICAgICAgY29uc3QgaXNBcHByb3ZhbCA9IHBsdWdpblR5cGUgPT09ICdNYW51YWxBcHByb3ZhbFN0ZXAnO1xuICAgICAgICAvLyBEb2NrZXJmaWxlIG9ubHkgZm9yIGltYWdlIGJ1aWxkcyBvZiBhIHJlYWwgYnVpbGQgc3RlcC5cbiAgICAgICAgY29uc3QgbmVlZHNEb2NrZXJmaWxlID0gYnVpbGRUeXBlID09PSAnYnVpbGRfaW1hZ2UnICYmICFpc0FwcHJvdmFsO1xuXG4gICAgICAgIC8vIGNvbmZpZy55YW1sIOKAlCBidWlsZCBtYW5pZmVzdC5cbiAgICAgICAgY29uc3QgY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHsgcGx1Z2luU3BlYzogJ3BsdWdpbi1zcGVjLnlhbWwnLCBidWlsZFR5cGUgfTtcbiAgICAgICAgaWYgKG5lZWRzRG9ja2VyZmlsZSkgY29uZmlnLmRvY2tlcmZpbGUgPSAnRG9ja2VyZmlsZSc7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHRhcmdldERpciwgJ2NvbmZpZy55YW1sJyksIFlBTUwuc3RyaW5naWZ5KGNvbmZpZyksICd1dGYtOCcpO1xuXG4gICAgICAgIC8vIHBsdWdpbi1zcGVjLnlhbWwg4oCUIHRoZSBQbHVnaW5TcGVjLlxuICAgICAgICBjb25zdCBzcGVjOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIHZlcnNpb246ICcxLjAuMCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGAke25hbWV9IHBsdWdpbmAsXG4gICAgICAgICAga2V5d29yZHM6IFtdIGFzIHN0cmluZ1tdLFxuICAgICAgICAgIGNhdGVnb3J5OiBvcHRpb25zLmNhdGVnb3J5ID8/ICdnZW5lcmFsJyxcbiAgICAgICAgICBwbHVnaW5UeXBlLFxuICAgICAgICAgIGNvbXB1dGVUeXBlLFxuICAgICAgICAgIHRpbWVvdXQ6IGlzQXBwcm92YWwgPyAwIDogMTAsXG4gICAgICAgICAgZmFpbHVyZUJlaGF2aW9yOiAnZmFpbCcsXG4gICAgICAgICAgc2VjcmV0czogW10gYXMgdW5rbm93bltdLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoIWlzQXBwcm92YWwpIHtcbiAgICAgICAgICBzcGVjLmluc3RhbGxDb21tYW5kcyA9IFsnZWNobyBcImluc3RhbGwgc3RlcCDigJQgYWRkIHlvdXIgc2V0dXAgY29tbWFuZHNcIiddO1xuICAgICAgICAgIHNwZWMuY29tbWFuZHMgPSBbYGVjaG8gXCJydW4gc3RlcCBmb3IgJHtuYW1lfSDigJQgcmVwbGFjZSB3aXRoIHJlYWwgY29tbWFuZHNcImBdO1xuICAgICAgICAgIGlmIChuZWVkc0RvY2tlcmZpbGUpIHNwZWMuZG9ja2VyZmlsZSA9ICdEb2NrZXJmaWxlJztcbiAgICAgICAgfVxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbih0YXJnZXREaXIsICdwbHVnaW4tc3BlYy55YW1sJyksIFlBTUwuc3RyaW5naWZ5KHNwZWMpLCAndXRmLTgnKTtcblxuICAgICAgICAvLyBTdGFydGVyIERvY2tlcmZpbGUuXG4gICAgICAgIGlmIChuZWVkc0RvY2tlcmZpbGUpIHtcbiAgICAgICAgICBjb25zdCBkb2NrZXJmaWxlID0gW1xuICAgICAgICAgICAgYCMgRG9ja2VyZmlsZSBmb3IgdGhlICR7bmFtZX0gcGx1Z2luLmAsXG4gICAgICAgICAgICAnIyBUaGUgYmFzZSBpbWFnZSBwcm92aWRlcyB0aGUgdG9vbGNoYWluIHlvdXIgY29tbWFuZHMgbmVlZCDigJQga2VlcCBpdCBtaW5pbWFsIGFuZCBwaW5uZWQuJyxcbiAgICAgICAgICAgICdGUk9NIGFscGluZTozLjIwJyxcbiAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgJyMgVE9ETzogaW5zdGFsbCB0aGUgdG9vbHMgeW91ciBwbHVnaW4tc3BlYyBjb21tYW5kcyBpbnZva2UsIGUuZy46JyxcbiAgICAgICAgICAgICcjIFJVTiBhcGsgYWRkIC0tbm8tY2FjaGUgcHl0aG9uMycsXG4gICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICdXT1JLRElSIC93b3Jrc3BhY2UnLFxuICAgICAgICAgICAgJycsXG4gICAgICAgICAgXS5qb2luKCdcXG4nKTtcbiAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbih0YXJnZXREaXIsICdEb2NrZXJmaWxlJyksIGRvY2tlcmZpbGUsICd1dGYtOCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUkVBRE1FLlxuICAgICAgICBjb25zdCByZWxEaXIgPSBvcHRpb25zLmRpciA/PyBgLi8ke25hbWV9YDtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4odGFyZ2V0RGlyLCAnUkVBRE1FLm1kJyksIFtcbiAgICAgICAgICBgIyAke25hbWV9YCxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICBgJHtuYW1lfSBwbHVnaW4uYCxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICAnVmFsaWRhdGUgYmVmb3JlIHVwbG9hZDonLFxuICAgICAgICAgICcnLFxuICAgICAgICAgIGAgICAgcGlwZWxpbmUtbWFuYWdlciBwbHVnaW4gdmFsaWRhdGUgLS1kaXIgJHtyZWxEaXJ9YCxcbiAgICAgICAgICAnJyxcbiAgICAgICAgICAnUGFja2FnZSBhbmQgdXBsb2FkOicsXG4gICAgICAgICAgJycsXG4gICAgICAgICAgYCAgICAoY2QgJHtyZWxEaXJ9ICYmIHppcCAtciAuLi8ke25hbWV9LnppcCAuKWAsXG4gICAgICAgICAgYCAgICBwaXBlbGluZS1tYW5hZ2VyIHBsdWdpbiB1cGxvYWQgLS1maWxlICR7bmFtZX0uemlwIC0tb3JnYW5pemF0aW9uIDxvcmc+YCxcbiAgICAgICAgICAnJyxcbiAgICAgICAgXS5qb2luKCdcXG4nKSwgJ3V0Zi04Jyk7XG5cbiAgICAgICAgcHJpbnRTZWN0aW9uKCdTY2FmZm9sZGVkIHBsdWdpbicsIHRhcmdldERpcik7XG4gICAgICAgIHByaW50SW5mbygnQ3JlYXRlZCBmaWxlcycsIHsgZmlsZXM6IFsnY29uZmlnLnlhbWwnLCAncGx1Z2luLXNwZWMueWFtbCcsIC4uLihuZWVkc0RvY2tlcmZpbGUgPyBbJ0RvY2tlcmZpbGUnXSA6IFtdKSwgJ1JFQURNRS5tZCddIH0pO1xuICAgICAgICBwcmludFN1Y2Nlc3MoJ1BsdWdpbiBzY2FmZm9sZCBjcmVhdGVkIOKAlCBlZGl0IHBsdWdpbi1zcGVjLnlhbWwgdGhlbiBydW4gdmFsaWRhdGUtcGx1Z2luJywgeyBleGVjdXRpb25JZCwgZGlyOiB0YXJnZXREaXIgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBlcnIgaW5zdGFuY2VvZiBWYWxpZGF0aW9uRXJyb3IgPyBFUlJPUl9DT0RFUy5WQUxJREFUSU9OIDogRVJST1JfQ09ERVMuR0VORVJBTCwge1xuICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICBleGl0OiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHsgY29tbWFuZDogJ25ldy1wbHVnaW4nLCBleGVjdXRpb25JZCB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbn1cbiJdfQ==
295
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9uZXctcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQ0wsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsb0JBQW9CLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUNsSCxlQUFlLEVBQUUsb0JBQW9CLEdBQ3RDLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN2RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RixPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBaUNsSSxpQ0FBaUM7QUFDakMsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBWSxFQUFVLEVBQUUsQ0FDcEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBRSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFFdkYsK0RB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QzlGLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSztnQkFDM0IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUU7YUFDaEQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQge1xuICBQTFVHSU5fQkFTRV9JTUFHRVMsIFBMVUdJTl9DQVRFR09SSUVTLCBQTFVHSU5fQ09NUFVURV9UWVBFUywgUExVR0lOX05BTUVfUEFUVEVSTiwgUExVR0lOX1NVTU1BUllfTUFYLCBQTFVHSU5fVFlQRVMsXG4gIGlzQWxsb3dlZFNwZHhJZCwgdmFsaWRhdGVDYXRhbG9nRmllbGQsIHR5cGUgUGx1Z2luQmFzZUltYWdlLFxufSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZSc7XG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSAnY29tbWFuZGVyJztcbmltcG9ydCB7IENVUkFURURfSUNPTl9LRVlTIH0gZnJvbSAnLi4vY29uZmlnL3BsdWdpbi1jYXRhbG9nLWFzc2V0cy5qcyc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vdXRpbHMvZXJyb3ItaGFuZGxlci5qcyc7XG5pbXBvcnQgeyBwcmludEluZm8sIHByaW50U2VjdGlvbiwgcHJpbnRTdWNjZXNzLCBwcmludFdhcm5pbmcsIGZpbGVFeGlzdHMsIGVuc3VyZU91dHB1dERpcmVjdG9yeSB9IGZyb20gJy4uL3V0aWxzL291dHB1dC11dGlscy5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV3UGx1Z2luT3B0aW9ucyB7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIGNhdGVnb3J5Pzogc3RyaW5nO1xuICBiYXNlPzogc3RyaW5nO1xuICBzdW1tYXJ5Pzogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgbGljZW5zZT86IHN0cmluZztcbiAgaWNvbj86IHN0cmluZztcbiAgYXV0aG9yPzogc3RyaW5nO1xuICB0eXBlPzogc3RyaW5nO1xuICBjb21wdXRlPzogc3RyaW5nO1xuICBkaXI/OiBzdHJpbmc7XG4gIGZvcmNlPzogYm9vbGVhbjtcbiAgbGlzdEJhc2VzPzogYm9vbGVhbjtcbn1cblxuLyoqIEEgdmFsaWRhdGVkIHNjYWZmb2xkIHJlcXVlc3QuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjYWZmb2xkSW5wdXQge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIGJhc2U6IFBsdWdpbkJhc2VJbWFnZTtcbiAgc3VtbWFyeTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBsaWNlbnNlOiBzdHJpbmc7XG4gIGljb246IHN0cmluZyB8IG51bGw7XG4gIGF1dGhvcjogc3RyaW5nO1xuICBwbHVnaW5UeXBlOiBzdHJpbmc7XG4gIGNvbXB1dGVUeXBlOiBzdHJpbmc7XG4gIHllYXI6IG51bWJlcjtcbn1cblxuLyoqIGBteS1saW50ZXJgIOKGkiBgTXkgTGludGVyYC4gKi9cbmV4cG9ydCBjb25zdCBkaXNwbGF5TmFtZU9mID0gKG5hbWU6IHN0cmluZyk6IHN0cmluZyA9PlxuICBuYW1lLnNwbGl0KCctJykuZmlsdGVyKEJvb2xlYW4pLm1hcCh3ID0+IHdbMF0hLnRvVXBwZXJDYXNlKCkgKyB3LnNsaWNlKDEpKS5qb2luKCcgJyk7XG5cbi8qKiBZQU1MIGRvdWJsZS1xdW90ZWQgc2NhbGFyIChKU09OIHN0cmluZ3MgYXJlIHZhbGlkIFlBTUwpLiAqL1xuY29uc3QgcSA9IChzOiBzdHJpbmcpOiBzdHJpbmcgPT4gSlNPTi5zdHJpbmdpZnkocyk7XG5cbi8qKiBWYWxpZGF0ZSB0aGUgZmxhZ3MgaW50byBhIHNjYWZmb2xkIHJlcXVlc3QgKHRocm93cyBWYWxpZGF0aW9uRXJyb3IpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTY2FmZm9sZElucHV0KG9wdGlvbnM6IE5ld1BsdWdpbk9wdGlvbnMsIG5vdyA9IG5ldyBEYXRlKCkpOiBTY2FmZm9sZElucHV0IHtcbiAgY29uc3QgbmFtZSA9IG9wdGlvbnMubmFtZSA/PyAnJztcbiAgaWYgKCFuYW1lIHx8ICFQTFVHSU5fTkFNRV9QQVRURVJOLnRlc3QobmFtZSkgfHwgbmFtZS5sZW5ndGggPiA2NCkge1xuICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJy0tbmFtZSBtdXN0IGJlIDEtNjQgbG93ZXJjYXNlIGxldHRlcnMsIGRpZ2l0cyBhbmQgaHlwaGVucycsICduYW1lJywgbmFtZSk7XG4gIH1cbiAgY29uc3QgY2F0ZWdvcnkgPSBvcHRpb25zLmNhdGVnb3J5ID8/ICcnO1xuICBpZiAoIShQTFVHSU5fQ0FURUdPUklFUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXMoY2F0ZWdvcnkpKSB7XG4gICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgLS1jYXRlZ29yeSBtdXN0IGJlIG9uZSBvZjogJHtQTFVHSU5fQ0FURUdPUklFUy5qb2luKCcsICcpfWAsICdjYXRlZ29yeScsIGNhdGVnb3J5KTtcbiAgfVxuICBjb25zdCBiYXNlID0gUExVR0lOX0JBU0VfSU1BR0VTLmZpbmQoYiA9PiBiLmtleSA9PT0gKG9wdGlvbnMuYmFzZSA/PyAncGx1Z2luJykpO1xuICBpZiAoIWJhc2UpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYC0tYmFzZSBtdXN0IGJlIG9uZSBvZjogJHtQTFVHSU5fQkFTRV9JTUFHRVMubWFwKGIgPT4gYi5rZXkpLmpvaW4oJywgJyl9IChzZWUgLS1saXN0LWJhc2VzKWAsICdiYXNlJywgb3B0aW9ucy5iYXNlKTtcbiAgY29uc3QgcGx1Z2luVHlwZSA9IG9wdGlvbnMudHlwZSA/PyAnQ29kZUJ1aWxkU3RlcCc7XG4gIGlmICghKFBMVUdJTl9UWVBFUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXMocGx1Z2luVHlwZSkpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYC0tdHlwZSBtdXN0IGJlIG9uZSBvZjogJHtQTFVHSU5fVFlQRVMuam9pbignLCAnKX1gLCAndHlwZScsIHBsdWdpblR5cGUpO1xuICBjb25zdCBjb21wdXRlVHlwZSA9IG9wdGlvbnMuY29tcHV0ZSA/PyAnU01BTEwnO1xuICBpZiAoIShQTFVHSU5fQ09NUFVURV9UWVBFUyBhcyByZWFkb25seSBzdHJpbmdbXSkuaW5jbHVkZXMoY29tcHV0ZVR5cGUpKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGAtLWNvbXB1dGUgbXVzdCBiZSBvbmUgb2Y6ICR7UExVR0lOX0NPTVBVVEVfVFlQRVMuam9pbignLCAnKX1gLCAnY29tcHV0ZScsIGNvbXB1dGVUeXBlKTtcbiAgY29uc3QgbGljZW5zZSA9IG9wdGlvbnMubGljZW5zZSA/PyAnQXBhY2hlLTIuMCc7XG4gIGlmICghaXNBbGxvd2VkU3BkeElkKGxpY2Vuc2UpKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCctLWxpY2Vuc2UgbXVzdCBiZSBhIHN1cHBvcnRlZCBTUERYIGlkZW50aWZpZXIgKGUuZy4gQXBhY2hlLTIuMCwgTUlUKScsICdsaWNlbnNlJywgbGljZW5zZSk7XG4gIGNvbnN0IGljb24gPSBvcHRpb25zLmljb24gJiYgb3B0aW9ucy5pY29uICE9PSAnbm9uZScgPyBvcHRpb25zLmljb24gOiBudWxsO1xuICBpZiAoaWNvbiAhPT0gbnVsbCAmJiAhQ1VSQVRFRF9JQ09OX0tFWVMuaW5jbHVkZXMoaWNvbikpIHtcbiAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGAtLWljb24gbXVzdCBiZSBhIGN1cmF0ZWQga2V5ICgke0NVUkFURURfSUNPTl9LRVlTLmpvaW4oJywgJyl9KSBvciBub25lYCwgJ2ljb24nLCBpY29uKTtcbiAgfVxuXG4gIGNvbnN0IGRpc3BsYXkgPSBkaXNwbGF5TmFtZU9mKG5hbWUpO1xuICBjb25zdCBzdW1tYXJ5ID0gb3B0aW9ucy5zdW1tYXJ5ID8/IGAke2Rpc3BsYXl9IGFzIGEgcGlwZWxpbmUgc3RlcC5gO1xuICBjb25zdCBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb25cbiAgICA/PyBgJHtkaXNwbGF5fSBydW5zIGFzIGEgQ29kZUJ1aWxkIHN0ZXAgaW4geW91ciBwaXBlbGluZS4gUmVwbGFjZSB0aGlzIHdpdGggd2hhdCB0aGUgcGx1Z2luIGNoZWNrcyBvciBidWlsZHMsIHdoYXQgaXQgcmVhZHMgZnJvbSB0aGUgd29ya3NwYWNlIGFuZCB3aGF0IGl0IHdyaXRlcy5gO1xuICBmb3IgKGNvbnN0IFtmaWVsZCwgdmFsdWVdIG9mIFtbJ3N1bW1hcnknLCBzdW1tYXJ5XSwgWydkZXNjcmlwdGlvbicsIGRlc2NyaXB0aW9uXV0gYXMgY29uc3QpIHtcbiAgICBjb25zdCBjaGVja2VkID0gdmFsaWRhdGVDYXRhbG9nRmllbGQoZmllbGQsIHZhbHVlKTtcbiAgICBpZiAoIWNoZWNrZWQub2spIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYC0tJHtmaWVsZH0gJHtjaGVja2VkLmVycm9yfSR7ZmllbGQgPT09ICdzdW1tYXJ5JyA/IGAgKG1heCAke1BMVUdJTl9TVU1NQVJZX01BWH0pYCA6ICcnfWAsIGZpZWxkLCB2YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBuYW1lLFxuICAgIGNhdGVnb3J5LFxuICAgIGJhc2UsXG4gICAgc3VtbWFyeSxcbiAgICBkZXNjcmlwdGlvbixcbiAgICBsaWNlbnNlLFxuICAgIGljb24sXG4gICAgcGx1Z2luVHlwZSxcbiAgICBjb21wdXRlVHlwZSxcbiAgICBhdXRob3I6IG9wdGlvbnMuYXV0aG9yID8/IGBUaGUgJHtuYW1lfSBhdXRob3JzYCxcbiAgICB5ZWFyOiBub3cuZ2V0VVRDRnVsbFllYXIoKSxcbiAgfTtcbn1cblxuY29uc3QgTUlUX1RFWFQgPSAoeWVhcjogbnVtYmVyLCBhdXRob3I6IHN0cmluZyk6IHN0cmluZyA9PiBgTUlUIExpY2Vuc2VcblxuQ29weXJpZ2h0IChjKSAke3llYXJ9ICR7YXV0aG9yfVxuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG5vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG5pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG50byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG5jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuU09GVFdBUkUuXG5gO1xuXG4vKiogTElDRU5TRTogdGhlIE1JVCB0ZXh0IGluIGZ1bGwsIGVsc2UgdGhlIFNQRFggbm90aWNlIChBcGFjaGUtMi4wJ3Mgb3duIHJlY29tbWVuZGVkIGZvcm0pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpY2Vuc2VUZXh0KGlucHV0OiBQaWNrPFNjYWZmb2xkSW5wdXQsICdsaWNlbnNlJyB8ICd5ZWFyJyB8ICdhdXRob3InPik6IHN0cmluZyB7XG4gIGlmIChpbnB1dC5saWNlbnNlID09PSAnTUlUJykgcmV0dXJuIE1JVF9URVhUKGlucHV0LnllYXIsIGlucHV0LmF1dGhvcik7XG4gIGlmIChpbnB1dC5saWNlbnNlID09PSAnQXBhY2hlLTIuMCcpIHtcbiAgICByZXR1cm4gYENvcHlyaWdodCAke2lucHV0LnllYXJ9ICR7aW5wdXQuYXV0aG9yfVxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcbmA7XG4gIH1cbiAgcmV0dXJuIGBDb3B5cmlnaHQgJHtpbnB1dC55ZWFyfSAke2lucHV0LmF1dGhvcn1cblxuVGhpcyBwbHVnaW4gaXMgbGljZW5zZWQgdW5kZXIgJHtpbnB1dC5saWNlbnNlfS5cbkZ1bGwgdGV4dDogaHR0cHM6Ly9zcGR4Lm9yZy9saWNlbnNlcy8ke2lucHV0LmxpY2Vuc2V9Lmh0bWxcblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6ICR7aW5wdXQubGljZW5zZX1cbmA7XG59XG5cbi8qKiBLZXl3b3JkczogdGhlIGNhdGVnb3J5IHBsdXMgdGhlIG5hbWUncyB3b3JkcyAo4omkIDEwLCBlYWNoIOKJpCAzMiwgbm8gZHVwbGljYXRlcykuICovXG5leHBvcnQgZnVuY3Rpb24gc2NhZmZvbGRLZXl3b3JkcyhuYW1lOiBzdHJpbmcsIGNhdGVnb3J5OiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBbLi4ubmV3IFNldChbY2F0ZWdvcnksIC4uLm5hbWUuc3BsaXQoJy0nKV0uZmlsdGVyKHcgPT4gdy5sZW5ndGggPj0gMiAmJiB3Lmxlbmd0aCA8PSAzMikpXS5zbGljZSgwLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGRvY2tlcmZpbGVUZXh0KGlucHV0OiBTY2FmZm9sZElucHV0KTogc3RyaW5nIHtcbiAgY29uc3QgZGlzcGxheSA9IGRpc3BsYXlOYW1lT2YoaW5wdXQubmFtZSk7XG4gIHJldHVybiBgIyAke2Rpc3BsYXl9IOKAlCAke2lucHV0LnN1bW1hcnl9XG4jXG4jIFRoaW4gbGF5ZXIgb3ZlciAke2lucHV0LmJhc2UuaW1hZ2V9IChkZXBsb3kvcGx1Z2lucy9fYmFzZS8ke2lucHV0LmJhc2UuZGlyfTpcbiMgJHtpbnB1dC5iYXNlLnByb3ZpZGVzfSkuIEFkZCBPTkxZIHRoaXMgcGx1Z2luJ3Mgb3duIHRvb2wsIHBpbm5lZC4gUnVsZXNcbiMgKGRlcGxveS9wbHVnaW5zL1JFQURNRS5tZCwgZW5mb3JjZWQgYnkgdGVzdC1wbHVnaW5zLnNoIGFuZCBcXGBwbHVnaW4gdmFsaWRhdGVcXGApOlxuIyAgIC0gZXZlcnkgZG93bmxvYWQgZ29lcyB0aHJvdWdoIGZldGNoLXZlcmlmaWVkIHdpdGggYSBwaW5uZWQgdmVyc2lvbiBhbmQgYVxuIyAgICAgcGlubmVkIHBlci1hcmNoaXRlY3R1cmUgZGlnZXN0OyBuZXZlciBhIHJvbGxpbmcgVVJMLCBuZXZlciBjdXJsIHwgc2g7XG4jICAgLSBzd2l0Y2ggdG8gcm9vdCBvbmx5IGZvciB0aGUgc3RlcHMgdGhhdCBuZWVkIGl0LCBhbmQgZW5kIGFzIFVTRVIgMTAwMDoxMDAwO1xuIyAgIC0gYSB0b29sIHRoYXQgc2hpcHMgc2V2ZXJhbCB2ZXJzaW9ucyBwdXRzIHRoZW0gdW5kZXIgL29wdC88dG9vbD4vdmVyc2lvbnNcbiMgICAgIHdpdGggdGhlIGFjdGl2ZSBvbmUgc3ltbGlua2VkIGZyb20gYSB1aWQtMTAwMC1vd25lZCAvb3B0Lzx0b29sPi9iaW4uXG5cbkZST00gJHtpbnB1dC5iYXNlLmltYWdlfVxuXG4jIOKUgOKUgOKUgCBUb29sIGluc3RhbGwgKHVuY29tbWVudCBhbmQgZmlsbCBpbikg4pSA4pSA4pSAXG4jIFRha2UgZWFjaCBkaWdlc3QgZnJvbSB0aGUgdmVuZG9yJ3MgcHVibGlzaGVkIGNoZWNrc3VtIGZpbGUuXG4jIFVTRVIgcm9vdFxuIyBBUkcgVE9PTF9WRVJTSU9OPTEuMi4zXG4jIEFSRyBUT09MX1NIQTI1Nl9BTUQ2ND08c2hhMjU2IG9mIHRoZSBsaW51eC1hbWQ2NCBhc3NldD5cbiMgQVJHIFRPT0xfU0hBMjU2X0FSTTY0PTxzaGEyNTYgb2YgdGhlIGxpbnV4LWFybTY0IGFzc2V0PlxuIyBSVU4gc2V0IC1ldXg7IFxcXFxcbiMgICAgIGNhc2UgXCIkKGRwa2cgLS1wcmludC1hcmNoaXRlY3R1cmUpXCIgaW4gXFxcXFxuIyAgICAgICBhbWQ2NCkgYXJjaD1hbWQ2NDsgc3VtPVwiXFwke1RPT0xfU0hBMjU2X0FNRDY0fVwiIDs7IFxcXFxcbiMgICAgICAgYXJtNjQpIGFyY2g9YXJtNjQ7IHN1bT1cIlxcJHtUT09MX1NIQTI1Nl9BUk02NH1cIiA7OyBcXFxcXG4jICAgICAgICopIGVjaG8gXCJ1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmU6ICQoZHBrZyAtLXByaW50LWFyY2hpdGVjdHVyZSlcIiA+JjI7IGV4aXQgMSA7OyBcXFxcXG4jICAgICBlc2FjOyBcXFxcXG4jICAgICBmZXRjaC12ZXJpZmllZCBcImh0dHBzOi8vZXhhbXBsZS5jb20vdG9vbC92XFwke1RPT0xfVkVSU0lPTn0vdG9vbC1saW51eC1cXCR7YXJjaH0udGFyLmd6XCIgXCIkc3VtXCIgL3RtcC90b29sLnRhci5nejsgXFxcXFxuIyAgICAgaW5zdGFsbCAtZCAvb3B0L3Rvb2wvYmluOyBcXFxcXG4jICAgICB0YXIgLXh6ZiAvdG1wL3Rvb2wudGFyLmd6IC1DIC9vcHQvdG9vbC9iaW47IFxcXFxcbiMgICAgIHJtIC1mIC90bXAvdG9vbC50YXIuZ3o7IFxcXFxcbiMgICAgIGNobW9kIC1SIGErclggL29wdC90b29sXG4jIEVOViBQQVRIPVwiL29wdC90b29sL2JpbjpcXCR7UEFUSH1cIlxuXG5XT1JLRElSIC9hcHBcblVTRVIgMTAwMDoxMDAwXG5DTUQgW1wiYmFzaFwiXVxuYDtcbn1cblxuZnVuY3Rpb24gc3BlY1RleHQoaW5wdXQ6IFNjYWZmb2xkSW5wdXQpOiBzdHJpbmcge1xuICBjb25zdCBvdXQgPSBgJHtpbnB1dC5uYW1lfS1yZXBvcnRzYDtcbiAgY29uc3QgaXNBcHByb3ZhbCA9IGlucHV0LnBsdWdpblR5cGUgPT09ICdNYW51YWxBcHByb3ZhbFN0ZXAnO1xuICBjb25zdCBsaW5lcyA9IFtcbiAgICBgbmFtZTogJHtpbnB1dC5uYW1lfWAsXG4gICAgYHN1bW1hcnk6ICR7cShpbnB1dC5zdW1tYXJ5KX1gLFxuICAgIGBkZXNjcmlwdGlvbjogJHtxKGlucHV0LmRlc2NyaXB0aW9uKX1gLFxuICAgICdrZXl3b3JkczonLFxuICAgIC4uLnNjYWZmb2xkS2V5d29yZHMoaW5wdXQubmFtZSwgaW5wdXQuY2F0ZWdvcnkpLm1hcChrID0+IGAgIC0gJHtrfWApLFxuICAgIGBjYXRlZ29yeTogJHtpbnB1dC5jYXRlZ29yeX1gLFxuICAgICd2ZXJzaW9uOiAwLjEuMCcsXG4gICAgYHBsdWdpblR5cGU6ICR7aW5wdXQucGx1Z2luVHlwZX1gLFxuICAgIGBjb21wdXRlVHlwZTogJHtpbnB1dC5jb21wdXRlVHlwZX1gLFxuICAgIGB0aW1lb3V0OiAke2lzQXBwcm92YWwgPyAwIDogMTB9YCxcbiAgICAnZmFpbHVyZUJlaGF2aW9yOiBmYWlsJyxcbiAgICAnc2VjcmV0czogW10nLFxuICBdO1xuICBpZiAoIWlzQXBwcm92YWwpIHtcbiAgICBsaW5lcy5wdXNoKFxuICAgICAgYHByaW1hcnlPdXRwdXREaXJlY3Rvcnk6ICR7b3V0fWAsXG4gICAgICAnZG9ja2VyZmlsZTogRG9ja2VyZmlsZScsXG4gICAgICAnaW5zdGFsbENvbW1hbmRzOicsXG4gICAgICBgICAtIG1rZGlyIC1wICR7b3V0fWAsXG4gICAgICAnY29tbWFuZHM6JyxcbiAgICAgICcgICMgUmVwbGFjZSB3aXRoIHRoZSByZWFsIHRvb2wgaW52b2NhdGlvbi4gcnVuLWxvZ2dlZCAoZnJvbSB0aGUgYmFzZSBpbWFnZSknLFxuICAgICAgJyAgIyBzdHJlYW1zIG91dHB1dCB0byB0aGUgY29uc29sZSBBTkQgdGhlIGxvZywgYW5kIGV4aXRzIHdpdGggdGhlIGNvbW1hbmRcXCdzJyxcbiAgICAgICcgICMgb3duIHN0YXR1cywgc28gYSBmYWlsdXJlIGlzIG5ldmVyIG1hc2tlZC4nLFxuICAgICAgJyAgLSB8JyxcbiAgICAgICcgICAgc2V0IC1lJyxcbiAgICAgIGAgICAgZWNobyBcIlJ1bm5pbmcgJHtpbnB1dC5uYW1lfSBpbiAkKHB3ZClcImAsXG4gICAgICBgICAgIHJ1bi1sb2dnZWQgJHtvdXR9LyR7aW5wdXQubmFtZX0ubG9nIC0tIGVjaG8gXCIke2lucHV0Lm5hbWV9IHJhblwiYCxcbiAgICAgICcjIFJ1biBhZ2FpbnN0IHRoZSBidWlsdCBpbWFnZSBieSB0ZXN0LXBsdWdpbnMuc2ggLS1idWlsZCBhbmQgYHBsdWdpbiB0ZXN0YC4nLFxuICAgICAgYHNtb2tlVGVzdDogJHtxKGlucHV0LmJhc2Uuc21va2VUZXN0KX1gLFxuICAgICk7XG4gIH1cbiAgbGluZXMucHVzaChcbiAgICAnJyxcbiAgICAnIyDilIDilIDilIAgQ2F0YWxvZyBtZXRhZGF0YSDilIDilIDilIAnLFxuICAgIGBsaWNlbnNlOiAke2lucHV0LmxpY2Vuc2V9YCxcbiAgICBpbnB1dC5pY29uXG4gICAgICA/IGBpY29uOiAke2lucHV0Lmljb259ICAjIGN1cmF0ZWQga2V5cyBhcmUgZm9yIE9mZmljaWFsIGFuZCBWZXJpZmllZCBsaXN0aW5nczsgQ29tbXVuaXR5IGxpc3RpbmdzIHVwbG9hZCBhbiBpY29uYFxuICAgICAgOiAnIyBpY29uOiBub25lIOKAlCBhIENvbW11bml0eSBsaXN0aW5nIHVwbG9hZHMgYSByYXN0ZXIgaWNvbiBvciBzaG93cyBpdHMgbW9ub2dyYW0nLFxuICAgICdjaGFuZ2Vsb2c6IHwnLFxuICAgICcgIDAuMS4wOiBJbml0aWFsIHJlbGVhc2UuJyxcbiAgICAnJyxcbiAgKTtcbiAgcmV0dXJuIGxpbmVzLmpvaW4oJ1xcbicpO1xufVxuXG5mdW5jdGlvbiByZWFkbWVUZXh0KGlucHV0OiBTY2FmZm9sZElucHV0LCByZWxEaXI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGRpc3BsYXkgPSBkaXNwbGF5TmFtZU9mKGlucHV0Lm5hbWUpO1xuICByZXR1cm4gYCMgJHtkaXNwbGF5fVxuXG4ke2lucHV0LmRlc2NyaXB0aW9ufVxuXG4jIyBVc2UgaXQgaW4gYSBwaXBlbGluZVxuXG5cXGBcXGBcXGB5YW1sXG5zdGVwczpcbiAgLSBwbHVnaW46IHsgbmFtZTogJHtpbnB1dC5uYW1lfSB9XG5cXGBcXGBcXGBcblxuJHtpbnB1dC5wbHVnaW5UeXBlID09PSAnTWFudWFsQXBwcm92YWxTdGVwJyA/ICcnIDogYFRoZSBzdGVwIHdyaXRlcyBpdHMgcmVzdWx0cyB0byBcXGAke2lucHV0Lm5hbWV9LXJlcG9ydHMvXFxgIChpdHMgcHJpbWFyeSBvdXRwdXQpLlxuXG5gfSMjIERldmVsb3BcblxuXFxgXFxgXFxgYmFzaFxucGlwZWxpbmUtbWFuYWdlciBwbHVnaW4gdmFsaWRhdGUgLS1kaXIgJHtyZWxEaXJ9ICAgIyB0aGUgc2VydmVyJ3Mgc2NoZW1hICsgY2F0YWxvZyByZXBvcnRcbnBpcGVsaW5lLW1hbmFnZXIgcGx1Z2luIHRlc3QgLS1kaXIgJHtyZWxEaXJ9IC0td29ya3NwYWNlIC4vc2FtcGxlLWFwcFxucGlwZWxpbmUtbWFuYWdlciBwbHVnaW4gcHVibGlzaCAtLWRpciAke3JlbERpcn0gICAgIyBwcmUtZmxpZ2h0LCBhY2NlcHQgb3IgZWRpdCBtZXRhZGF0YSwgc3VibWl0XG5cXGBcXGBcXGBcblxuVGhlIGltYWdlIGJ1aWxkcyBGUk9NIFxcYCR7aW5wdXQuYmFzZS5pbWFnZX1cXGA7IGJ1aWxkIHRoZSBiYXNlcyBmaXJzdCB3aXRoXG5cXGBkZXBsb3kvYmluL2J1aWxkLXBsdWdpbi1pbWFnZXMuc2hcXGAsIG9yIHBhc3MgXFxgLS1pbWFnZVxcYCB0byBcXGBwbHVnaW4gdGVzdFxcYC5cblxuIyMgTGljZW5zZVxuXG4ke2lucHV0LmxpY2Vuc2V9IOKAlCBzZWUgW0xJQ0VOU0VdKExJQ0VOU0UpLlxuYDtcbn1cblxuLyoqIEV2ZXJ5IGZpbGUgb2YgYSBuZXcgcGx1Z2luLCBrZXllZCBieSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBwbHVnaW4gZGlyZWN0b3J5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNjYWZmb2xkRmlsZXMoaW5wdXQ6IFNjYWZmb2xkSW5wdXQsIHJlbERpciA9IGAuLyR7aW5wdXQubmFtZX1gKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGlzQXBwcm92YWwgPSBpbnB1dC5wbHVnaW5UeXBlID09PSAnTWFudWFsQXBwcm92YWxTdGVwJztcbiAgY29uc3QgZmlsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgJ2NvbmZpZy55YW1sJzogaXNBcHByb3ZhbFxuICAgICAgPyAncGx1Z2luU3BlYzogcGx1Z2luLXNwZWMueWFtbFxcbmJ1aWxkVHlwZTogbWV0YWRhdGFfb25seVxcbidcbiAgICAgIDogJ3BsdWdpblNwZWM6IHBsdWdpbi1zcGVjLnlhbWxcXG5idWlsZFR5cGU6IGJ1aWxkX2ltYWdlXFxuZG9ja2VyZmlsZTogRG9ja2VyZmlsZVxcbicsXG4gICAgJ3BsdWdpbi1zcGVjLnlhbWwnOiBzcGVjVGV4dChpbnB1dCksXG4gICAgJ1JFQURNRS5tZCc6IHJlYWRtZVRleHQoaW5wdXQsIHJlbERpciksXG4gICAgJ0xJQ0VOU0UnOiBsaWNlbnNlVGV4dChpbnB1dCksXG4gIH07XG4gIGlmICghaXNBcHByb3ZhbCkgZmlsZXMuRG9ja2VyZmlsZSA9IGRvY2tlcmZpbGVUZXh0KGlucHV0KTtcbiAgcmV0dXJuIGZpbGVzO1xufVxuXG4vKiogUHJpbnQgdGhlIGF2YWlsYWJsZSBwbHVnaW4gYmFzZXMuICovXG5leHBvcnQgZnVuY3Rpb24gcHJpbnRCYXNlcygpOiB2b2lkIHtcbiAgcHJpbnRTZWN0aW9uKCdQbHVnaW4gYmFzZSBpbWFnZXMnLCAnZGVwbG95L3BsdWdpbnMvX2Jhc2UnKTtcbiAgZm9yIChjb25zdCBiIG9mIFBMVUdJTl9CQVNFX0lNQUdFUykgY29uc29sZS5sb2coYCAgJHtiLmtleS5wYWRFbmQoOCl9ICR7Yi5pbWFnZS5wYWRFbmQoMjgpfSAke2IucHJvdmlkZXN9YCk7XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgYHBsdWdpbiBuZXdgIOKAlCBzY2FmZm9sZCBhIHBsdWdpbiBGUk9NIGEgYHBpcGVsaW5lLTxlY28+LWJhc2VgIGltYWdlOlxuICogYSBEb2NrZXJmaWxlIHRoYXQgZm9sbG93cyB0aGUgY2F0YWxvZyBydWxlcywgYSBzcGVjIHdpdGggY2F0YWxvZyBtZXRhZGF0YSwgYVxuICogUkVBRE1FLCBhIGNoYW5nZWxvZyBlbnRyeSBhbmQgYSBMSUNFTlNFLiBJdCBwYXNzZXMgYHBsdWdpbiB2YWxpZGF0ZWAgYW5kXG4gKiB0ZXN0LXBsdWdpbnMuc2gncyBzdGF0aWMgY2hlY2tzIGFzIGdlbmVyYXRlZC5cbiAqXG4gKiBVc2FnZTpcbiAqICAgcGlwZWxpbmUtbWFuYWdlciBwbHVnaW4gbmV3IC0tbGlzdC1iYXNlc1xuICogICBwaXBlbGluZS1tYW5hZ2VyIHBsdWdpbiBuZXcgLS1uYW1lIG15LWxpbnRlciAtLWNhdGVnb3J5IHF1YWxpdHkgLS1iYXNlIG5vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5ld1BsdWdpbihwcm9ncmFtOiBDb21tYW5kKTogdm9pZCB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnbmV3JylcbiAgICAuZGVzY3JpcHRpb24oJ1NjYWZmb2xkIGEgcGx1Z2luIGZyb20gYSBwaXBlbGluZS08ZWNvPi1iYXNlIGltYWdlIChEb2NrZXJmaWxlLCBzcGVjLCBSRUFETUUsIExJQ0VOU0UpJylcbiAgICAub3B0aW9uKCctLW5hbWUgPG5hbWU+JywgJ1BsdWdpbiBuYW1lIChsb3dlcmNhc2UgbGV0dGVycywgZGlnaXRzLCBoeXBoZW5zKScpXG4gICAgLm9wdGlvbignLS1jYXRlZ29yeSA8Y2F0ZWdvcnk+JywgYENhdGVnb3J5OiAke1BMVUdJTl9DQVRFR09SSUVTLmpvaW4oJyB8ICcpfWApXG4gICAgLm9wdGlvbignLS1iYXNlIDxlY28+JywgYEJhc2UgaW1hZ2U6ICR7UExVR0lOX0JBU0VfSU1BR0VTLm1hcChiID0+IGIua2V5KS5qb2luKCcgfCAnKX1gLCAncGx1Z2luJylcbiAgICAub3B0aW9uKCctLXN1bW1hcnkgPHRleHQ+JywgYENhdGFsb2cgb25lLWxpbmVyICjiiaQgJHtQTFVHSU5fU1VNTUFSWV9NQVh9KWApXG4gICAgLm9wdGlvbignLS1kZXNjcmlwdGlvbiA8dGV4dD4nLCAnQ2F0YWxvZyBkZXNjcmlwdGlvbicpXG4gICAgLm9wdGlvbignLS1saWNlbnNlIDxzcGR4PicsICdTUERYIGxpY2Vuc2UgaWQnLCAnQXBhY2hlLTIuMCcpXG4gICAgLm9wdGlvbignLS1pY29uIDxrZXk+JywgJ0N1cmF0ZWQgaWNvbiBrZXkgKE9mZmljaWFsL1ZlcmlmaWVkIGxpc3RpbmdzIG9ubHkpLCBvciBub25lJywgJ25vbmUnKVxuICAgIC5vcHRpb24oJy0tYXV0aG9yIDxuYW1lPicsICdDb3B5cmlnaHQgaG9sZGVyIGZvciBMSUNFTlNFJylcbiAgICAub3B0aW9uKCctLXR5cGUgPHR5cGU+JywgYFBsdWdpbiB0eXBlOiAke1BMVUdJTl9UWVBFUy5qb2luKCcgfCAnKX1gLCAnQ29kZUJ1aWxkU3RlcCcpXG4gICAgLm9wdGlvbignLS1jb21wdXRlIDxjb21wdXRlPicsIGBDb21wdXRlIHR5cGU6ICR7UExVR0lOX0NPTVBVVEVfVFlQRVMuam9pbignIHwgJyl9YCwgJ1NNQUxMJylcbiAgICAub3B0aW9uKCctLWRpciA8cGF0aD4nLCAnVGFyZ2V0IGRpcmVjdG9yeSAoZGVmYXVsdCAuLzxuYW1lPiknKVxuICAgIC5vcHRpb24oJy0tZm9yY2UnLCAnT3ZlcndyaXRlIGFuIGV4aXN0aW5nIGRpcmVjdG9yeScsIGZhbHNlKVxuICAgIC5vcHRpb24oJy0tbGlzdC1iYXNlcycsICdMaXN0IHRoZSBhdmFpbGFibGUgYmFzZSBpbWFnZXMgYW5kIGV4aXQnLCBmYWxzZSlcbiAgICAuYWN0aW9uKChvcHRpb25zOiBOZXdQbHVnaW5PcHRpb25zKSA9PiB7XG4gICAgICBpZiAob3B0aW9ucy5saXN0QmFzZXMpIHtcbiAgICAgICAgcHJpbnRCYXNlcygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBleGVjdXRpb25JZCA9IHByaW50Q29tbWFuZEhlYWRlcignTmV3IFBsdWdpbicpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSByZXNvbHZlU2NhZmZvbGRJbnB1dChvcHRpb25zKTtcbiAgICAgICAgY29uc3QgcmVsRGlyID0gb3B0aW9ucy5kaXIgPz8gYC4vJHtpbnB1dC5uYW1lfWA7XG4gICAgICAgIGNvbnN0IHRhcmdldERpciA9IHBhdGgucmVzb2x2ZShyZWxEaXIpO1xuICAgICAgICBpZiAoZmlsZUV4aXN0cyh0YXJnZXREaXIpICYmICFvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgRGlyZWN0b3J5IGFscmVhZHkgZXhpc3RzOiAke3RhcmdldERpcn0gKHVzZSAtLWZvcmNlIHRvIG92ZXJ3cml0ZSlgKTtcbiAgICAgICAgfVxuICAgICAgICBlbnN1cmVPdXRwdXREaXJlY3RvcnkodGFyZ2V0RGlyKTtcbiAgICAgICAgY29uc3QgZmlsZXMgPSBzY2FmZm9sZEZpbGVzKGlucHV0LCByZWxEaXIpO1xuICAgICAgICBmb3IgKGNvbnN0IFtmaWxlLCBjb250ZW50XSBvZiBPYmplY3QuZW50cmllcyhmaWxlcykpIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHRhcmdldERpciwgZmlsZSksIGNvbnRlbnQsICd1dGYtOCcpO1xuXG4gICAgICAgIGlmIChpbnB1dC5pY29uKSBwcmludFdhcm5pbmcoJ0N1cmF0ZWQgaWNvbnMgYXJlIHJlc2VydmVkIGZvciBPZmZpY2lhbCBsaXN0aW5ncyBhbmQgVmVyaWZpZWQgcHVibGlzaGVycyB3aG8gb3duIHRoZSBtYXJrOyBhIENvbW11bml0eSBsaXN0aW5nIHdpdGggb25lIGlzIHJlZnVzZWQgYXQgc3VibWl0Jyk7XG4gICAgICAgIHByaW50U2VjdGlvbignU2NhZmZvbGRlZCBwbHVnaW4nLCB0YXJnZXREaXIpO1xuICAgICAgICBwcmludEluZm8oJ0NyZWF0ZWQgZmlsZXMnLCB7IGZpbGVzOiBPYmplY3Qua2V5cyhmaWxlcyksIGJhc2U6IGlucHV0LmJhc2UuaW1hZ2UgfSk7XG4gICAgICAgIHByaW50U3VjY2VzcygnUGx1Z2luIHNjYWZmb2xkIGNyZWF0ZWQg4oCUIG5leHQ6IHBsdWdpbiB2YWxpZGF0ZSwgcGx1Z2luIHRlc3QsIHBsdWdpbiBwdWJsaXNoJywgeyBleGVjdXRpb25JZCwgZGlyOiB0YXJnZXREaXIgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBlcnIgaW5zdGFuY2VvZiBWYWxpZGF0aW9uRXJyb3IgPyBFUlJPUl9DT0RFUy5WQUxJREFUSU9OIDogRVJST1JfQ09ERVMuR0VORVJBTCwge1xuICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICBleGl0OiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHsgY29tbWFuZDogJ3BsdWdpbiBuZXcnLCBleGVjdXRpb25JZCB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbn1cbiJdfQ==
@@ -0,0 +1,29 @@
1
+ import { Command } from 'commander';
2
+ /** Server cap on a deprecation message / yank reason. */
3
+ export declare const LIFECYCLE_TEXT_MAX = 500;
4
+ /**
5
+ * Registers `plugin deprecate`: mark a version deprecated (or clear it with
6
+ * `--undo`). A deprecated version keeps resolving, but synth prints a warning,
7
+ * AI selection stops offering it, and the org approvers of every org whose
8
+ * pipelines use it are notified.
9
+ *
10
+ * @example
11
+ * ```bash
12
+ * pipeline-manager plugin deprecate --id <plugin-id> --message "Use 2.x"
13
+ * pipeline-manager plugin deprecate --id <plugin-id> --undo
14
+ * ```
15
+ */
16
+ export declare function deprecatePlugin(program: Command): void;
17
+ /**
18
+ * Registers `plugin yank`: stop a version resolving for new synths. Ranges,
19
+ * `latest` and the default skip it; an exact pin still resolves, with a warning
20
+ * carrying the reason. Yanking the default promotes the next version. A version
21
+ * published to the ecosystem is refused (409) — request the yank there.
22
+ *
23
+ * @example
24
+ * ```bash
25
+ * pipeline-manager plugin yank --id <plugin-id> --reason "Leaks tokens in logs; use 1.2.1"
26
+ * ```
27
+ */
28
+ export declare function yankPlugin(program: Command): void;
29
+ //# sourceMappingURL=plugin-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-lifecycle.d.ts","sourceRoot":"","sources":["../../src/commands/plugin-lifecycle.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,yDAAyD;AACzD,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAmCtC;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6CtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0CjD"}