@pipeline-builder/pipeline-manager 4.1.15 → 4.1.17
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/config.yml +16 -37
- package/dist/boilerplate.js +10 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +97 -79
- package/dist/commands/audit-stacks.js +3 -3
- package/dist/commands/create-pat.d.ts +2 -3
- package/dist/commands/create-pat.d.ts.map +1 -1
- package/dist/commands/create-pat.js +3 -4
- package/dist/commands/create-pipeline.d.ts.map +1 -1
- package/dist/commands/create-pipeline.js +198 -190
- package/dist/commands/list-pipelines.js +2 -2
- package/dist/commands/list-plugins.js +2 -2
- package/dist/commands/login.d.ts +2 -2
- package/dist/commands/login.js +3 -3
- package/dist/commands/new-plugin.d.ts +48 -5
- package/dist/commands/new-plugin.d.ts.map +1 -1
- package/dist/commands/new-plugin.js +261 -95
- package/dist/commands/plugin-lifecycle.d.ts +29 -0
- package/dist/commands/plugin-lifecycle.d.ts.map +1 -0
- package/dist/commands/plugin-lifecycle.js +147 -0
- package/dist/commands/provision.d.ts +42 -2
- package/dist/commands/provision.d.ts.map +1 -1
- package/dist/commands/provision.js +184 -147
- package/dist/commands/publish-plugin.d.ts +62 -0
- package/dist/commands/publish-plugin.d.ts.map +1 -0
- package/dist/commands/publish-plugin.js +224 -0
- package/dist/commands/redrive-events.d.ts +1 -1
- package/dist/commands/redrive-events.js +2 -2
- package/dist/commands/store-token.d.ts +46 -1
- package/dist/commands/store-token.d.ts.map +1 -1
- package/dist/commands/store-token.js +127 -102
- package/dist/commands/test-plugin.d.ts +72 -0
- package/dist/commands/test-plugin.d.ts.map +1 -0
- package/dist/commands/test-plugin.js +285 -0
- package/dist/commands/upload-plugin.d.ts +6 -7
- package/dist/commands/upload-plugin.d.ts.map +1 -1
- package/dist/commands/upload-plugin.js +127 -189
- package/dist/commands/validate-plugin.d.ts +37 -4
- package/dist/commands/validate-plugin.d.ts.map +1 -1
- package/dist/commands/validate-plugin.js +129 -144
- package/dist/commands/validate-templates.d.ts.map +1 -1
- package/dist/commands/validate-templates.js +8 -9
- package/dist/config/plugin-catalog-assets.d.ts +13 -0
- package/dist/config/plugin-catalog-assets.d.ts.map +1 -0
- package/dist/config/plugin-catalog-assets.js +21 -0
- package/dist/config.yml +16 -37
- package/dist/lambda/token-renew-handler.d.ts.map +1 -1
- package/dist/lambda/token-renew-handler.js +109 -154
- package/dist/types/config.d.ts +2 -6
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +1 -1
- package/dist/types/plugin.d.ts +21 -0
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/plugin.js +1 -1
- package/dist/utils/aws-env.d.ts +1 -2
- package/dist/utils/aws-env.d.ts.map +1 -1
- package/dist/utils/aws-env.js +2 -3
- package/dist/utils/catalog-prompt.d.ts +26 -0
- package/dist/utils/catalog-prompt.d.ts.map +1 -0
- package/dist/utils/catalog-prompt.js +113 -0
- package/dist/utils/command-utils.d.ts.map +1 -1
- package/dist/utils/command-utils.js +14 -3
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +4 -6
- package/dist/utils/credential-store.d.ts +16 -0
- package/dist/utils/credential-store.d.ts.map +1 -1
- package/dist/utils/credential-store.js +57 -2
- package/dist/utils/deploy-runner.d.ts.map +1 -1
- package/dist/utils/deploy-runner.js +7 -2
- package/dist/utils/pipeline-config.d.ts +1 -2
- package/dist/utils/pipeline-config.d.ts.map +1 -1
- package/dist/utils/pipeline-config.js +1 -1
- package/dist/utils/plugin-docker.d.ts +44 -0
- package/dist/utils/plugin-docker.d.ts.map +1 -0
- package/dist/utils/plugin-docker.js +71 -0
- package/dist/utils/plugin-package.d.ts +40 -0
- package/dist/utils/plugin-package.d.ts.map +1 -0
- package/dist/utils/plugin-package.js +159 -0
- package/dist/utils/plugin-resolver.d.ts.map +1 -1
- package/dist/utils/plugin-resolver.js +43 -29
- package/dist/utils/plugin-scan.d.ts +22 -0
- package/dist/utils/plugin-scan.d.ts.map +1 -0
- package/dist/utils/plugin-scan.js +52 -0
- package/dist/utils/plugin-zip.d.ts +15 -0
- package/dist/utils/plugin-zip.d.ts.map +1 -0
- package/dist/utils/plugin-zip.js +96 -0
- package/dist/utils/registry.d.ts +15 -0
- package/dist/utils/registry.d.ts.map +1 -1
- package/dist/utils/registry.js +17 -2
- package/dist/utils/service-account.d.ts.map +1 -1
- package/dist/utils/service-account.js +9 -10
- package/package.json +45 -8
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { STEP_BOOTSTRAP_CMD, extractMetadataEnv, resolveFailureBehavior, resolvePluginTemplates, wrapCommandsForFailureBehavior, } from '@pipeline-builder/pipeline-core';
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { printCommandHeader } from '../utils/command-utils.js';
|
|
9
|
+
import { ERROR_CODES, handleError, ValidationError } from '../utils/error-handler.js';
|
|
10
|
+
import { printError, printInfo, printSection, printSuccess, printWarning } from '../utils/output-utils.js';
|
|
11
|
+
import { buildPluginImage, hasTool, imageUser, isRootUser, localImageTag, removeImage, spawnExec, } from '../utils/plugin-docker.js';
|
|
12
|
+
import { packageProblems, readPluginPackage } from '../utils/plugin-package.js';
|
|
13
|
+
/** Mount point of the sample workspace inside the container (the step's source dir). */
|
|
14
|
+
export const CONTAINER_WORKSPACE = '/workspace';
|
|
15
|
+
/** A plugin run that failed: the step would be red in CodeBuild. */
|
|
16
|
+
export class PluginTestFailure extends Error {
|
|
17
|
+
constructor(message) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'PluginTestFailure';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** `KEY=VALUE` flags → a record (the value may itself contain `=`). */
|
|
23
|
+
export function parseKeyValues(pairs, flag) {
|
|
24
|
+
const out = {};
|
|
25
|
+
for (const pair of pairs ?? []) {
|
|
26
|
+
const eq = pair.indexOf('=');
|
|
27
|
+
if (eq <= 0)
|
|
28
|
+
throw new ValidationError(`${flag} expects KEY=VALUE (got "${pair}")`, flag, pair);
|
|
29
|
+
out[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
const collect = (value, previous = []) => [...previous, value];
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the spec the way the pipeline step does: `{{ … }}` templates against
|
|
36
|
+
* the given pipeline metadata/vars, env = spec env ← non-namespaced metadata ←
|
|
37
|
+
* `--env`, the step's WORKDIR bootstrap, and the build commands wrapped for the
|
|
38
|
+
* effective failureBehavior (a security-category plugin is always `fail`).
|
|
39
|
+
*/
|
|
40
|
+
export function planPluginTest(spec, flags, hostEnv = process.env) {
|
|
41
|
+
const metadata = { ...(spec.metadata ?? {}), ...(flags.metadata ?? {}) };
|
|
42
|
+
let resolved;
|
|
43
|
+
try {
|
|
44
|
+
resolved = resolvePluginTemplates(spec, {
|
|
45
|
+
pipeline: {
|
|
46
|
+
projectName: 'plugin-test',
|
|
47
|
+
project: 'plugin-test',
|
|
48
|
+
orgId: 'local',
|
|
49
|
+
organization: 'local',
|
|
50
|
+
pipelineName: 'plugin-test',
|
|
51
|
+
metadata,
|
|
52
|
+
vars: flags.vars ?? {},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
throw new PluginTestFailure(`${err.message} — supply the value with --metadata KEY=VALUE or --var KEY=VALUE`);
|
|
58
|
+
}
|
|
59
|
+
const strings = (v) => (Array.isArray(v) ? v.filter((c) => typeof c === 'string') : []);
|
|
60
|
+
const env = {
|
|
61
|
+
...(resolved.env ?? {}),
|
|
62
|
+
...extractMetadataEnv(metadata),
|
|
63
|
+
...(flags.env ?? {}),
|
|
64
|
+
};
|
|
65
|
+
const secrets = Array.isArray(spec.secrets) ? spec.secrets : [];
|
|
66
|
+
const missingRequired = secrets.filter(s => s.required && !hostEnv[s.name]).map(s => s.name);
|
|
67
|
+
if (missingRequired.length) {
|
|
68
|
+
throw new PluginTestFailure(`Required secret(s) not set in your environment: ${missingRequired.join(', ')} — export them before running plugin test`);
|
|
69
|
+
}
|
|
70
|
+
const secretNames = secrets.filter(s => hostEnv[s.name]).map(s => s.name);
|
|
71
|
+
for (const name of secretNames)
|
|
72
|
+
delete env[name];
|
|
73
|
+
const failureBehavior = resolveFailureBehavior(typeof spec.category === 'string' ? spec.category : undefined, spec.failureBehavior);
|
|
74
|
+
const script = (commands) => ['set -e', STEP_BOOTSTRAP_CMD, ...commands].join('\n');
|
|
75
|
+
const timeout = typeof spec.timeout === 'number' && spec.timeout > 0 ? spec.timeout * 60_000 : undefined;
|
|
76
|
+
return {
|
|
77
|
+
name: String(spec.name),
|
|
78
|
+
version: String(spec.version),
|
|
79
|
+
failureBehavior,
|
|
80
|
+
env,
|
|
81
|
+
secretNames,
|
|
82
|
+
missingOptionalSecrets: secrets.filter(s => !s.required && !hostEnv[s.name]).map(s => s.name),
|
|
83
|
+
installScript: script(strings(resolved.installCommands)),
|
|
84
|
+
buildScript: script(wrapCommandsForFailureBehavior(strings(resolved.commands), failureBehavior)),
|
|
85
|
+
primaryOutputDirectory: typeof spec.primaryOutputDirectory === 'string' && spec.primaryOutputDirectory ? spec.primaryOutputDirectory : undefined,
|
|
86
|
+
smokeTest: typeof spec.smokeTest === 'string' && spec.smokeTest.trim() ? spec.smokeTest : undefined,
|
|
87
|
+
timeoutMs: timeout,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** `docker run` arguments for one phase (secret VALUES never appear here). */
|
|
91
|
+
export function dockerRunArgs(image, workspace, plan, script) {
|
|
92
|
+
return [
|
|
93
|
+
'run', '--rm',
|
|
94
|
+
'-v', `${workspace}:${CONTAINER_WORKSPACE}`, '-w', CONTAINER_WORKSPACE,
|
|
95
|
+
...Object.entries(plan.env).flatMap(([k, v]) => ['-e', `${k}=${v}`]),
|
|
96
|
+
...plan.secretNames.flatMap(name => ['-e', name]),
|
|
97
|
+
// CodeBuild runs a step's commands under /bin/sh, so the test does too.
|
|
98
|
+
'--entrypoint', '/bin/sh',
|
|
99
|
+
image, '-c', script,
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
/** Copy the sample workspace to a scratch dir the container's uid 1000 can write. */
|
|
103
|
+
export function prepareWorkspace(source) {
|
|
104
|
+
const ws = fs.mkdtempSync(path.join(os.tmpdir(), 'pipeline-manager-plugin-test-'));
|
|
105
|
+
if (source) {
|
|
106
|
+
const src = path.resolve(source);
|
|
107
|
+
if (!fs.existsSync(src) || !fs.statSync(src).isDirectory())
|
|
108
|
+
throw new ValidationError(`--workspace is not a directory: ${src}`, 'workspace', src);
|
|
109
|
+
fs.cpSync(src, ws, { recursive: true });
|
|
110
|
+
}
|
|
111
|
+
// The container runs as the image's user (uid 1000), not the host user.
|
|
112
|
+
// Executable bits are kept (a `gradlew`), symlinks are left alone (never
|
|
113
|
+
// chmod through a link to something outside the scratch dir).
|
|
114
|
+
const open = (p) => {
|
|
115
|
+
const st = fs.lstatSync(p);
|
|
116
|
+
if (st.isSymbolicLink())
|
|
117
|
+
return;
|
|
118
|
+
const ownerExecutable = Math.floor((st.mode % 0o1000) / 0o100) % 2 === 1;
|
|
119
|
+
fs.chmodSync(p, st.isDirectory() || ownerExecutable ? 0o777 : 0o666);
|
|
120
|
+
if (st.isDirectory())
|
|
121
|
+
for (const e of fs.readdirSync(p))
|
|
122
|
+
open(path.join(p, e));
|
|
123
|
+
};
|
|
124
|
+
open(ws);
|
|
125
|
+
return ws;
|
|
126
|
+
}
|
|
127
|
+
/** Where the step's primary output lands on the host, honouring a relative WORKDIR. */
|
|
128
|
+
export function outputPath(workspace, plan) {
|
|
129
|
+
if (!plan.primaryOutputDirectory)
|
|
130
|
+
return null;
|
|
131
|
+
const workdir = plan.env.WORKDIR ?? './';
|
|
132
|
+
const base = workdir.startsWith('/')
|
|
133
|
+
? (workdir.startsWith(CONTAINER_WORKSPACE) ? path.join(workspace, path.relative(CONTAINER_WORKSPACE, workdir)) : null)
|
|
134
|
+
: path.join(workspace, workdir);
|
|
135
|
+
return base === null ? null : path.join(base, plan.primaryOutputDirectory);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Build (or take) the image, then run the plugin as its CodeBuild step would:
|
|
139
|
+
* install phase, build phase (failureBehavior applied), the primary output
|
|
140
|
+
* check, then the spec's smokeTest. Any failure throws — a step that can't run
|
|
141
|
+
* or that fails is red, never green.
|
|
142
|
+
*/
|
|
143
|
+
export async function runPluginTest(options, exec = spawnExec) {
|
|
144
|
+
const pkg = readPluginPackage(options.dir);
|
|
145
|
+
const problems = await packageProblems(pkg);
|
|
146
|
+
if (problems.length) {
|
|
147
|
+
for (const p of problems)
|
|
148
|
+
printError(` • ${p}`);
|
|
149
|
+
throw new ValidationError(`The plugin has ${problems.length} validation problem(s); run "plugin validate" and fix them first`);
|
|
150
|
+
}
|
|
151
|
+
const spec = pkg.spec;
|
|
152
|
+
if (spec.pluginType === 'ManualApprovalStep') {
|
|
153
|
+
throw new ValidationError('A ManualApprovalStep runs no commands, so there is nothing to test');
|
|
154
|
+
}
|
|
155
|
+
if (!hasTool(exec, 'docker'))
|
|
156
|
+
throw new PluginTestFailure('docker is not available — plugin test runs the plugin in its image');
|
|
157
|
+
const plan = planPluginTest(spec, {
|
|
158
|
+
env: parseKeyValues(options.env, '--env'),
|
|
159
|
+
metadata: parseKeyValues(options.metadata, '--metadata'),
|
|
160
|
+
vars: parseKeyValues(options.var, '--var'),
|
|
161
|
+
});
|
|
162
|
+
const workspace = prepareWorkspace(options.workspace);
|
|
163
|
+
let image = options.image;
|
|
164
|
+
let built = null;
|
|
165
|
+
try {
|
|
166
|
+
if (!image) {
|
|
167
|
+
if (pkg.buildType === 'build_image') {
|
|
168
|
+
built = localImageTag(plan.name, plan.version);
|
|
169
|
+
printSection('Building image', built);
|
|
170
|
+
const buildArgs = spec.buildArgs ?? {};
|
|
171
|
+
const error = buildPluginImage(exec, { dir: pkg.dir, dockerfile: path.join(pkg.dir, pkg.dockerfileName), tag: built, buildArgs });
|
|
172
|
+
if (error)
|
|
173
|
+
throw new PluginTestFailure(error);
|
|
174
|
+
image = built;
|
|
175
|
+
}
|
|
176
|
+
else if (pkg.buildType === 'prebuilt') {
|
|
177
|
+
const r = exec('docker', ['load', '-i', path.join(pkg.dir, 'image.tar')]);
|
|
178
|
+
const loaded = /Loaded image(?: ID)?: (\S+)/.exec(r.stdout)?.[1];
|
|
179
|
+
if (r.status !== 0 || !loaded)
|
|
180
|
+
throw new PluginTestFailure(`docker load image.tar failed: ${(r.stderr || r.stdout).trim()}`);
|
|
181
|
+
image = loaded;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
throw new ValidationError('A metadata_only plugin has no image of its own; pass the image it runs in with --image');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (!image)
|
|
188
|
+
throw new PluginTestFailure('No image to run');
|
|
189
|
+
const user = imageUser(exec, image);
|
|
190
|
+
if ('error' in user)
|
|
191
|
+
throw new PluginTestFailure(user.error);
|
|
192
|
+
if (isRootUser(user.user)) {
|
|
193
|
+
throw new PluginTestFailure(`The image runs as root (USER '${user.user || '(unset)'}'); end the Dockerfile with \`USER 1000:1000\``);
|
|
194
|
+
}
|
|
195
|
+
printInfo('Running plugin', {
|
|
196
|
+
image,
|
|
197
|
+
runsAs: user.user,
|
|
198
|
+
workspace,
|
|
199
|
+
failureBehavior: plan.failureBehavior,
|
|
200
|
+
env: Object.keys(plan.env),
|
|
201
|
+
secrets: plan.secretNames,
|
|
202
|
+
});
|
|
203
|
+
if (plan.missingOptionalSecrets.length)
|
|
204
|
+
printWarning('Optional secrets not set (the step runs without them)', { secrets: plan.missingOptionalSecrets });
|
|
205
|
+
for (const [phase, script] of [['install', plan.installScript], ['build', plan.buildScript]]) {
|
|
206
|
+
printSection(`Phase: ${phase}`);
|
|
207
|
+
const r = exec('docker', dockerRunArgs(image, workspace, plan, script), { inherit: true, timeoutMs: plan.timeoutMs });
|
|
208
|
+
if (r.error)
|
|
209
|
+
throw new PluginTestFailure(`${phase} phase did not complete: ${r.error.message}`);
|
|
210
|
+
if (r.status !== 0)
|
|
211
|
+
throw new PluginTestFailure(`${phase} phase failed (exit ${r.status})`);
|
|
212
|
+
}
|
|
213
|
+
let outputFiles = null;
|
|
214
|
+
const out = outputPath(workspace, plan);
|
|
215
|
+
if (plan.primaryOutputDirectory && out === null) {
|
|
216
|
+
printWarning('WORKDIR is outside the workspace; primaryOutputDirectory cannot be checked on the host');
|
|
217
|
+
}
|
|
218
|
+
else if (out) {
|
|
219
|
+
if (!fs.existsSync(out) || !fs.statSync(out).isDirectory()) {
|
|
220
|
+
throw new PluginTestFailure(`primaryOutputDirectory '${plan.primaryOutputDirectory}' was not created`);
|
|
221
|
+
}
|
|
222
|
+
outputFiles = fs.readdirSync(out).length;
|
|
223
|
+
if (outputFiles === 0)
|
|
224
|
+
throw new PluginTestFailure(`primaryOutputDirectory '${plan.primaryOutputDirectory}' is empty`);
|
|
225
|
+
printSuccess(`primaryOutputDirectory '${plan.primaryOutputDirectory}' has ${outputFiles} entr${outputFiles === 1 ? 'y' : 'ies'}`);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
printWarning('The spec declares no primaryOutputDirectory; no output to check');
|
|
229
|
+
}
|
|
230
|
+
if (plan.smokeTest) {
|
|
231
|
+
printSection('Smoke test', plan.smokeTest);
|
|
232
|
+
const r = exec('docker', ['run', '--rm', '--entrypoint', '/bin/bash', image, '-c', plan.smokeTest], { inherit: true });
|
|
233
|
+
if (r.error || r.status !== 0)
|
|
234
|
+
throw new PluginTestFailure(`smokeTest failed: ${plan.smokeTest}`);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
printWarning('The spec declares no smokeTest');
|
|
238
|
+
}
|
|
239
|
+
return { outputFiles };
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
if (options.keep)
|
|
243
|
+
printInfo('Workspace kept', { workspace });
|
|
244
|
+
else
|
|
245
|
+
fs.rmSync(workspace, { recursive: true, force: true });
|
|
246
|
+
if (built && !options.keep)
|
|
247
|
+
removeImage(exec, built);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Register `plugin test` — run a plugin's install + build commands locally in
|
|
252
|
+
* its image against a sample workspace, check its primary output, and run its
|
|
253
|
+
* smokeTest. Exits non-zero on any failure.
|
|
254
|
+
*
|
|
255
|
+
* Usage:
|
|
256
|
+
* pipeline-manager plugin test --dir ./my-linter --workspace ./sample-app
|
|
257
|
+
* pipeline-manager plugin test --dir ./my-linter --image my-linter:dev --metadata STAGE=dev
|
|
258
|
+
*/
|
|
259
|
+
export function testPlugin(program) {
|
|
260
|
+
program
|
|
261
|
+
.command('test')
|
|
262
|
+
.description('Run a plugin\'s install + build commands locally in its image against a sample workspace')
|
|
263
|
+
.option('--dir <path>', 'Plugin directory', '.')
|
|
264
|
+
.option('--image <ref>', 'Use this image instead of building the plugin\'s Dockerfile')
|
|
265
|
+
.option('--workspace <path>', 'Sample workspace copied in as the step\'s source (default: empty)')
|
|
266
|
+
.option('--env <KEY=VALUE>', 'Extra environment variable (repeatable)', collect)
|
|
267
|
+
.option('--metadata <KEY=VALUE>', 'Pipeline metadata value (repeatable; also exported as env, as in the pipeline)', collect)
|
|
268
|
+
.option('--var <KEY=VALUE>', 'Pipeline var for {{ pipeline.vars.* }} (repeatable)', collect)
|
|
269
|
+
.option('--keep', 'Keep the scratch workspace and built image for inspection', false)
|
|
270
|
+
.action(async (options) => {
|
|
271
|
+
const executionId = printCommandHeader('Test Plugin');
|
|
272
|
+
try {
|
|
273
|
+
const result = await runPluginTest(options);
|
|
274
|
+
printSuccess('Plugin test passed', { executionId, outputEntries: result.outputFiles });
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
handleError(err, err instanceof ValidationError ? ERROR_CODES.VALIDATION : ERROR_CODES.GENERAL, {
|
|
278
|
+
debug: program.opts().debug,
|
|
279
|
+
exit: true,
|
|
280
|
+
context: { command: 'plugin test', executionId },
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1wbHVnaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvdGVzdC1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDcEIsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQ0wsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsc0JBQXNCLEVBQUUsc0JBQXNCLEVBQUUsOEJBQThCLEdBQ3ZILE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzNHLE9BQU8sRUFDTCxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsV0FBVyxFQUFFLFNBQVMsR0FDeEYsTUFBTSwyQkFBMkIsQ0FBQztBQUNuQyxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFaEYsd0ZBQXdGO0FBQ3hGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLFlBQVksQ0FBQztBQVloRCxvRUFBb0U7QUFDcEUsTUFBTSxPQUFPLGlCQUFrQixTQUFRLEtBQUs7SUFDMUMsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdB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U0FDcEYsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUEwQixFQUFFLEVBQUU7UUFDM0MsTUFBTSxXQUFXLEdBQUcsa0JBQWtCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDdEQsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUMsWUFBWSxDQUFDLG9CQUFvQixFQUFFLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUN6RixDQUFDO1FBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUNiLFdBQVcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxZQUFZLGVBQWUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRTtnQkFDOUYsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLO2dCQUMzQixJQUFJLEVBQUUsSUFBSTtnQkFDVixPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRTthQUNqRCxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQge1xuICBTVEVQX0JPT1RTVFJBUF9DTUQsIGV4dHJhY3RNZXRhZGF0YUVudiwgcmVzb2x2ZUZhaWx1cmVCZWhhdmlvciwgcmVzb2x2ZVBsdWdpblRlbXBsYXRlcywgd3JhcENvbW1hbmRzRm9yRmFpbHVyZUJlaGF2aW9yLFxufSBmcm9tICdAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1jb3JlJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHsgcHJpbnRDb21tYW5kSGVhZGVyIH0gZnJvbSAnLi4vdXRpbHMvY29tbWFuZC11dGlscy5qcyc7XG5pbXBvcnQgeyBFUlJPUl9DT0RFUywgaGFuZGxlRXJyb3IsIFZhbGlkYXRpb25FcnJvciB9IGZyb20gJy4uL3V0aWxzL2Vycm9yLWhhbmRsZXIuanMnO1xuaW1wb3J0IHsgcHJpbnRFcnJvciwgcHJpbnRJbmZvLCBwcmludFNlY3Rpb24sIHByaW50U3VjY2VzcywgcHJpbnRXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvb3V0cHV0LXV0aWxzLmpzJztcbmltcG9ydCB7XG4gIGJ1aWxkUGx1Z2luSW1hZ2UsIGhhc1Rvb2wsIGltYWdlVXNlciwgaXNSb290VXNlciwgbG9jYWxJbWFnZVRhZywgcmVtb3ZlSW1hZ2UsIHNwYXduRXhlYywgdHlwZSBFeGVjLFxufSBmcm9tICcuLi91dGlscy9wbHVnaW4tZG9ja2VyLmpzJztcbmltcG9ydCB7IHBhY2thZ2VQcm9ibGVtcywgcmVhZFBsdWdpblBhY2thZ2UgfSBmcm9tICcuLi91dGlscy9wbHVnaW4tcGFja2FnZS5qcyc7XG5cbi8qKiBNb3VudCBwb2ludCBvZiB0aGUgc2FtcGxlIHdvcmtzcGFjZSBpbnNpZGUgdGhlIGNvbnRhaW5lciAodGhlIHN0ZXAncyBzb3VyY2UgZGlyKS4gKi9cbmV4cG9ydCBjb25zdCBDT05UQUlORVJfV09SS1NQQUNFID0gJy93b3Jrc3BhY2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RQbHVnaW5PcHRpb25zIHtcbiAgZGlyOiBzdHJpbmc7XG4gIGltYWdlPzogc3RyaW5nO1xuICB3b3Jrc3BhY2U/OiBzdHJpbmc7XG4gIGVudj86IHN0cmluZ1tdO1xuICBtZXRhZGF0YT86IHN0cmluZ1tdO1xuICB2YXI/OiBzdHJpbmdbXTtcbiAga2VlcD86IGJvb2xlYW47XG59XG5cbi8qKiBBIHBsdWdpbiBydW4gdGhhdCBmYWlsZWQ6IHRoZSBzdGVwIHdvdWxkIGJlIHJlZCBpbiBDb2RlQnVpbGQuICovXG5leHBvcnQgY2xhc3MgUGx1Z2luVGVzdEZhaWx1cmUgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZykge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9ICdQbHVnaW5UZXN0RmFpbHVyZSc7XG4gIH1cbn1cblxuLyoqIGBLRVk9VkFMVUVgIGZsYWdzIOKGkiBhIHJlY29yZCAodGhlIHZhbHVlIG1heSBpdHNlbGYgY29udGFpbiBgPWApLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlS2V5VmFsdWVzKHBhaXJzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCwgZmxhZzogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMgPz8gW10pIHtcbiAgICBjb25zdCBlcSA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChlcSA8PSAwKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGAke2ZsYWd9IGV4cGVjdHMgS0VZPVZBTFVFIChnb3QgXCIke3BhaXJ9XCIpYCwgZmxhZywgcGFpcik7XG4gICAgb3V0W3BhaXIuc2xpY2UoMCwgZXEpXSA9IHBhaXIuc2xpY2UoZXEgKyAxKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5jb25zdCBjb2xsZWN0ID0gKHZhbHVlOiBzdHJpbmcsIHByZXZpb3VzOiBzdHJpbmdbXSA9IFtdKTogc3RyaW5nW10gPT4gWy4uLnByZXZpb3VzLCB2YWx1ZV07XG5cbi8qKiBXaGF0IGEgcnVuIG5lZWRzLCByZXNvbHZlZCBmcm9tIHRoZSBzcGVjICsgZmxhZ3MgKG5vIHNpZGUgZWZmZWN0cykuICovXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RQbGFuIHtcbiAgbmFtZTogc3RyaW5nO1xuICB2ZXJzaW9uOiBzdHJpbmc7XG4gIGZhaWx1cmVCZWhhdmlvcjogJ2ZhaWwnIHwgJ3dhcm4nIHwgJ2lnbm9yZSc7XG4gIC8qKiBQbGFpbiBlbnYgcGFzc2VkIGFzIGAtZSBLRVk9VkFMVUVgLiAqL1xuICBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIC8qKiBTZWNyZXQgTkFNRVMgcGFzc2VkIGFzIGAtZSBOQU1FYCAoZG9ja2VyIHJlYWRzIHRoZSB2YWx1ZSBmcm9tIHRoaXMgcHJvY2VzcydzIGVudikuICovXG4gIHNlY3JldE5hbWVzOiBzdHJpbmdbXTtcbiAgbWlzc2luZ09wdGlvbmFsU2VjcmV0czogc3RyaW5nW107XG4gIGluc3RhbGxTY3JpcHQ6IHN0cmluZztcbiAgYnVpbGRTY3JpcHQ6IHN0cmluZztcbiAgcHJpbWFyeU91dHB1dERpcmVjdG9yeTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBzbW9rZVRlc3Q6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgdGltZW91dE1zOiBudW1iZXIgfCB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgc3BlYyB0aGUgd2F5IHRoZSBwaXBlbGluZSBzdGVwIGRvZXM6IGB7eyDigKYgfX1gIHRlbXBsYXRlcyBhZ2FpbnN0XG4gKiB0aGUgZ2l2ZW4gcGlwZWxpbmUgbWV0YWRhdGEvdmFycywgZW52ID0gc3BlYyBlbnYg4oaQIG5vbi1uYW1lc3BhY2VkIG1ldGFkYXRhIOKGkFxuICogYC0tZW52YCwgdGhlIHN0ZXAncyBXT1JLRElSIGJvb3RzdHJhcCwgYW5kIHRoZSBidWlsZCBjb21tYW5kcyB3cmFwcGVkIGZvciB0aGVcbiAqIGVmZmVjdGl2ZSBmYWlsdXJlQmVoYXZpb3IgKGEgc2VjdXJpdHktY2F0ZWdvcnkgcGx1Z2luIGlzIGFsd2F5cyBgZmFpbGApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGxhblBsdWdpblRlc3QoXG4gIHNwZWM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBmbGFnczogeyBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+OyBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47IHZhcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IH0sXG4gIGhvc3RFbnY6IE5vZGVKUy5Qcm9jZXNzRW52ID0gcHJvY2Vzcy5lbnYsXG4pOiBUZXN0UGxhbiB7XG4gIGNvbnN0IG1ldGFkYXRhID0geyAuLi4oc3BlYy5tZXRhZGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiA/PyB7fSksIC4uLihmbGFncy5tZXRhZGF0YSA/PyB7fSkgfTtcbiAgbGV0IHJlc29sdmVkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgdHJ5IHtcbiAgICByZXNvbHZlZCA9IHJlc29sdmVQbHVnaW5UZW1wbGF0ZXMoc3BlYyBhcyBuZXZlciwge1xuICAgICAgcGlwZWxpbmU6IHtcbiAgICAgICAgcHJvamVjdE5hbWU6ICdwbHVnaW4tdGVzdCcsXG4gICAgICAgIHByb2plY3Q6ICdwbHVnaW4tdGVzdCcsXG4gICAgICAgIG9yZ0lkOiAnbG9jYWwnLFxuICAgICAgICBvcmdhbml6YXRpb246ICdsb2NhbCcsXG4gICAgICAgIHBpcGVsaW5lTmFtZTogJ3BsdWdpbi10ZXN0JyxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHZhcnM6IGZsYWdzLnZhcnMgPz8ge30sXG4gICAgICB9LFxuICAgIH0pIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZShgJHsoZXJyIGFzIEVycm9yKS5tZXNzYWdlfSDigJQgc3VwcGx5IHRoZSB2YWx1ZSB3aXRoIC0tbWV0YWRhdGEgS0VZPVZBTFVFIG9yIC0tdmFyIEtFWT1WQUxVRWApO1xuICB9XG5cbiAgY29uc3Qgc3RyaW5ncyA9ICh2OiB1bmtub3duKTogc3RyaW5nW10gPT4gKEFycmF5LmlzQXJyYXkodikgPyB2LmZpbHRlcigoYyk6IGMgaXMgc3RyaW5nID0+IHR5cGVvZiBjID09PSAnc3RyaW5nJykgOiBbXSk7XG4gIGNvbnN0IGVudjogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAuLi4ocmVzb2x2ZWQuZW52IGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPz8ge30pLFxuICAgIC4uLmV4dHJhY3RNZXRhZGF0YUVudihtZXRhZGF0YSksXG4gICAgLi4uKGZsYWdzLmVudiA/PyB7fSksXG4gIH07XG5cbiAgY29uc3Qgc2VjcmV0cyA9IEFycmF5LmlzQXJyYXkoc3BlYy5zZWNyZXRzKSA/IHNwZWMuc2VjcmV0cyBhcyBBcnJheTx7IG5hbWU6IHN0cmluZzsgcmVxdWlyZWQ6IGJvb2xlYW4gfT4gOiBbXTtcbiAgY29uc3QgbWlzc2luZ1JlcXVpcmVkID0gc2VjcmV0cy5maWx0ZXIocyA9PiBzLnJlcXVpcmVkICYmICFob3N0RW52W3MubmFtZV0pLm1hcChzID0+IHMubmFtZSk7XG4gIGlmIChtaXNzaW5nUmVxdWlyZWQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFBsdWdpblRlc3RGYWlsdXJlKGBSZXF1aXJlZCBzZWNyZXQocykgbm90IHNldCBpbiB5b3VyIGVudmlyb25tZW50OiAke21pc3NpbmdSZXF1aXJlZC5qb2luKCcsICcpfSDigJQgZXhwb3J0IHRoZW0gYmVmb3JlIHJ1bm5pbmcgcGx1Z2luIHRlc3RgKTtcbiAgfVxuICBjb25zdCBzZWNyZXROYW1lcyA9IHNlY3JldHMuZmlsdGVyKHMgPT4gaG9zdEVudltzLm5hbWVdKS5tYXAocyA9PiBzLm5hbWUpO1xuICBmb3IgKGNvbnN0IG5hbWUgb2Ygc2VjcmV0TmFtZXMpIGRlbGV0ZSBlbnZbbmFtZV07XG5cbiAgY29uc3QgZmFpbHVyZUJlaGF2aW9yID0gcmVzb2x2ZUZhaWx1cmVCZWhhdmlvcihcbiAgICB0eXBlb2Ygc3BlYy5jYXRlZ29yeSA9PT0gJ3N0cmluZycgPyBzcGVjLmNhdGVnb3J5IDogdW5kZWZpbmVkLFxuICAgIHNwZWMuZmFpbHVyZUJlaGF2aW9yIGFzICdmYWlsJyB8ICd3YXJuJyB8ICdpZ25vcmUnIHwgdW5kZWZpbmVkLFxuICApO1xuICBjb25zdCBzY3JpcHQgPSAoY29tbWFuZHM6IHN0cmluZ1tdKTogc3RyaW5nID0+IFsnc2V0IC1lJywgU1RFUF9CT09UU1RSQVBfQ01ELCAuLi5jb21tYW5kc10uam9pbignXFxuJyk7XG4gIGNvbnN0IHRpbWVvdXQgPSB0eXBlb2Ygc3BlYy50aW1lb3V0ID09PSAnbnVtYmVyJyAmJiBzcGVjLnRpbWVvdXQgPiAwID8gc3BlYy50aW1lb3V0ICogNjBfMDAwIDogdW5kZWZpbmVkO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogU3RyaW5nKHNwZWMubmFtZSksXG4gICAgdmVyc2lvbjogU3RyaW5nKHNwZWMudmVyc2lvbiksXG4gICAgZmFpbHVyZUJlaGF2aW9yLFxuICAgIGVudixcbiAgICBzZWNyZXROYW1lcyxcbiAgICBtaXNzaW5nT3B0aW9uYWxTZWNyZXRzOiBzZWNyZXRzLmZpbHRlcihzID0+ICFzLnJlcXVpcmVkICYmICFob3N0RW52W3MubmFtZV0pLm1hcChzID0+IHMubmFtZSksXG4gICAgaW5zdGFsbFNjcmlwdDogc2NyaXB0KHN0cmluZ3MocmVzb2x2ZWQuaW5zdGFsbENvbW1hbmRzKSksXG4gICAgYnVpbGRTY3JpcHQ6IHNjcmlwdCh3cmFwQ29tbWFuZHNGb3JGYWlsdXJlQmVoYXZpb3Ioc3RyaW5ncyhyZXNvbHZlZC5jb21tYW5kcyksIGZhaWx1cmVCZWhhdmlvcikpLFxuICAgIHByaW1hcnlPdXRwdXREaXJlY3Rvcnk6IHR5cGVvZiBzcGVjLnByaW1hcnlPdXRwdXREaXJlY3RvcnkgPT09ICdzdHJpbmcnICYmIHNwZWMucHJpbWFyeU91dHB1dERpcmVjdG9yeSA/IHNwZWMucHJpbWFyeU91dHB1dERpcmVjdG9yeSA6IHVuZGVmaW5lZCxcbiAgICBzbW9rZVRlc3Q6IHR5cGVvZiBzcGVjLnNtb2tlVGVzdCA9PT0gJ3N0cmluZycgJiYgc3BlYy5zbW9rZVRlc3QudHJpbSgpID8gc3BlYy5zbW9rZVRlc3QgOiB1bmRlZmluZWQsXG4gICAgdGltZW91dE1zOiB0aW1lb3V0LFxuICB9O1xufVxuXG4vKiogYGRvY2tlciBydW5gIGFyZ3VtZW50cyBmb3Igb25lIHBoYXNlIChzZWNyZXQgVkFMVUVTIG5ldmVyIGFwcGVhciBoZXJlKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkb2NrZXJSdW5BcmdzKGltYWdlOiBzdHJpbmcsIHdvcmtzcGFjZTogc3RyaW5nLCBwbGFuOiBQaWNrPFRlc3RQbGFuLCAnZW52JyB8ICdzZWNyZXROYW1lcyc+LCBzY3JpcHQ6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIFtcbiAgICAncnVuJywgJy0tcm0nLFxuICAgICctdicsIGAke3dvcmtzcGFjZX06JHtDT05UQUlORVJfV09SS1NQQUNFfWAsICctdycsIENPTlRBSU5FUl9XT1JLU1BBQ0UsXG4gICAgLi4uT2JqZWN0LmVudHJpZXMocGxhbi5lbnYpLmZsYXRNYXAoKFtrLCB2XSkgPT4gWyctZScsIGAke2t9PSR7dn1gXSksXG4gICAgLi4ucGxhbi5zZWNyZXROYW1lcy5mbGF0TWFwKG5hbWUgPT4gWyctZScsIG5hbWVdKSxcbiAgICAvLyBDb2RlQnVpbGQgcnVucyBhIHN0ZXAncyBjb21tYW5kcyB1bmRlciAvYmluL3NoLCBzbyB0aGUgdGVzdCBkb2VzIHRvby5cbiAgICAnLS1lbnRyeXBvaW50JywgJy9iaW4vc2gnLFxuICAgIGltYWdlLCAnLWMnLCBzY3JpcHQsXG4gIF07XG59XG5cbi8qKiBDb3B5IHRoZSBzYW1wbGUgd29ya3NwYWNlIHRvIGEgc2NyYXRjaCBkaXIgdGhlIGNvbnRhaW5lcidzIHVpZCAxMDAwIGNhbiB3cml0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlV29ya3NwYWNlKHNvdXJjZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgY29uc3Qgd3MgPSBmcy5ta2R0ZW1wU3luYyhwYXRoLmpvaW4ob3MudG1wZGlyKCksICdwaXBlbGluZS1tYW5hZ2VyLXBsdWdpbi10ZXN0LScpKTtcbiAgaWYgKHNvdXJjZSkge1xuICAgIGNvbnN0IHNyYyA9IHBhdGgucmVzb2x2ZShzb3VyY2UpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzcmMpIHx8ICFmcy5zdGF0U3luYyhzcmMpLmlzRGlyZWN0b3J5KCkpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYC0td29ya3NwYWNlIGlzIG5vdCBhIGRpcmVjdG9yeTogJHtzcmN9YCwgJ3dvcmtzcGFjZScsIHNyYyk7XG4gICAgZnMuY3BTeW5jKHNyYywgd3MsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICB9XG4gIC8vIFRoZSBjb250YWluZXIgcnVucyBhcyB0aGUgaW1hZ2UncyB1c2VyICh1aWQgMTAwMCksIG5vdCB0aGUgaG9zdCB1c2VyLlxuICAvLyBFeGVjdXRhYmxlIGJpdHMgYXJlIGtlcHQgKGEgYGdyYWRsZXdgKSwgc3ltbGlua3MgYXJlIGxlZnQgYWxvbmUgKG5ldmVyXG4gIC8vIGNobW9kIHRocm91Z2ggYSBsaW5rIHRvIHNvbWV0aGluZyBvdXRzaWRlIHRoZSBzY3JhdGNoIGRpcikuXG4gIGNvbnN0IG9wZW4gPSAocDogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgY29uc3Qgc3QgPSBmcy5sc3RhdFN5bmMocCk7XG4gICAgaWYgKHN0LmlzU3ltYm9saWNMaW5rKCkpIHJldHVybjtcbiAgICBjb25zdCBvd25lckV4ZWN1dGFibGUgPSBNYXRoLmZsb29yKChzdC5tb2RlICUgMG8xMDAwKSAvIDBvMTAwKSAlIDIgPT09IDE7XG4gICAgZnMuY2htb2RTeW5jKHAsIHN0LmlzRGlyZWN0b3J5KCkgfHwgb3duZXJFeGVjdXRhYmxlID8gMG83NzcgOiAwbzY2Nik7XG4gICAgaWYgKHN0LmlzRGlyZWN0b3J5KCkpIGZvciAoY29uc3QgZSBvZiBmcy5yZWFkZGlyU3luYyhwKSkgb3BlbihwYXRoLmpvaW4ocCwgZSkpO1xuICB9O1xuICBvcGVuKHdzKTtcbiAgcmV0dXJuIHdzO1xufVxuXG4vKiogV2hlcmUgdGhlIHN0ZXAncyBwcmltYXJ5IG91dHB1dCBsYW5kcyBvbiB0aGUgaG9zdCwgaG9ub3VyaW5nIGEgcmVsYXRpdmUgV09SS0RJUi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvdXRwdXRQYXRoKHdvcmtzcGFjZTogc3RyaW5nLCBwbGFuOiBQaWNrPFRlc3RQbGFuLCAnZW52JyB8ICdwcmltYXJ5T3V0cHV0RGlyZWN0b3J5Jz4pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFwbGFuLnByaW1hcnlPdXRwdXREaXJlY3RvcnkpIHJldHVybiBudWxsO1xuICBjb25zdCB3b3JrZGlyID0gcGxhbi5lbnYuV09SS0RJUiA/PyAnLi8nO1xuICBjb25zdCBiYXNlID0gd29ya2Rpci5zdGFydHNXaXRoKCcvJylcbiAgICA/ICh3b3JrZGlyLnN0YXJ0c1dpdGgoQ09OVEFJTkVSX1dPUktTUEFDRSkgPyBwYXRoLmpvaW4od29ya3NwYWNlLCBwYXRoLnJlbGF0aXZlKENPTlRBSU5FUl9XT1JLU1BBQ0UsIHdvcmtkaXIpKSA6IG51bGwpXG4gICAgOiBwYXRoLmpvaW4od29ya3NwYWNlLCB3b3JrZGlyKTtcbiAgcmV0dXJuIGJhc2UgPT09IG51bGwgPyBudWxsIDogcGF0aC5qb2luKGJhc2UsIHBsYW4ucHJpbWFyeU91dHB1dERpcmVjdG9yeSk7XG59XG5cbi8qKlxuICogQnVpbGQgKG9yIHRha2UpIHRoZSBpbWFnZSwgdGhlbiBydW4gdGhlIHBsdWdpbiBhcyBpdHMgQ29kZUJ1aWxkIHN0ZXAgd291bGQ6XG4gKiBpbnN0YWxsIHBoYXNlLCBidWlsZCBwaGFzZSAoZmFpbHVyZUJlaGF2aW9yIGFwcGxpZWQpLCB0aGUgcHJpbWFyeSBvdXRwdXRcbiAqIGNoZWNrLCB0aGVuIHRoZSBzcGVjJ3Mgc21va2VUZXN0LiBBbnkgZmFpbHVyZSB0aHJvd3Mg4oCUIGEgc3RlcCB0aGF0IGNhbid0IHJ1blxuICogb3IgdGhhdCBmYWlscyBpcyByZWQsIG5ldmVyIGdyZWVuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuUGx1Z2luVGVzdChvcHRpb25zOiBUZXN0UGx1Z2luT3B0aW9ucywgZXhlYzogRXhlYyA9IHNwYXduRXhlYyk6IFByb21pc2U8eyBvdXRwdXRGaWxlczogbnVtYmVyIHwgbnVsbCB9PiB7XG4gIGNvbnN0IHBrZyA9IHJlYWRQbHVnaW5QYWNrYWdlKG9wdGlvbnMuZGlyKTtcbiAgY29uc3QgcHJvYmxlbXMgPSBhd2FpdCBwYWNrYWdlUHJvYmxlbXMocGtnKTtcbiAgaWYgKHByb2JsZW1zLmxlbmd0aCkge1xuICAgIGZvciAoY29uc3QgcCBvZiBwcm9ibGVtcykgcHJpbnRFcnJvcihgICDigKIgJHtwfWApO1xuICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFRoZSBwbHVnaW4gaGFzICR7cHJvYmxlbXMubGVuZ3RofSB2YWxpZGF0aW9uIHByb2JsZW0ocyk7IHJ1biBcInBsdWdpbiB2YWxpZGF0ZVwiIGFuZCBmaXggdGhlbSBmaXJzdGApO1xuICB9XG4gIGNvbnN0IHNwZWMgPSBwa2cuc3BlYyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBpZiAoc3BlYy5wbHVnaW5UeXBlID09PSAnTWFudWFsQXBwcm92YWxTdGVwJykge1xuICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0EgTWFudWFsQXBwcm92YWxTdGVwIHJ1bnMgbm8gY29tbWFuZHMsIHNvIHRoZXJlIGlzIG5vdGhpbmcgdG8gdGVzdCcpO1xuICB9XG4gIGlmICghaGFzVG9vbChleGVjLCAnZG9ja2VyJykpIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZSgnZG9ja2VyIGlzIG5vdCBhdmFpbGFibGUg4oCUIHBsdWdpbiB0ZXN0IHJ1bnMgdGhlIHBsdWdpbiBpbiBpdHMgaW1hZ2UnKTtcblxuICBjb25zdCBwbGFuID0gcGxhblBsdWdpblRlc3Qoc3BlYywge1xuICAgIGVudjogcGFyc2VLZXlWYWx1ZXMob3B0aW9ucy5lbnYsICctLWVudicpLFxuICAgIG1ldGFkYXRhOiBwYXJzZUtleVZhbHVlcyhvcHRpb25zLm1ldGFkYXRhLCAnLS1tZXRhZGF0YScpLFxuICAgIHZhcnM6IHBhcnNlS2V5VmFsdWVzKG9wdGlvbnMudmFyLCAnLS12YXInKSxcbiAgfSk7XG5cbiAgY29uc3Qgd29ya3NwYWNlID0gcHJlcGFyZVdvcmtzcGFjZShvcHRpb25zLndvcmtzcGFjZSk7XG4gIGxldCBpbWFnZSA9IG9wdGlvbnMuaW1hZ2U7XG4gIGxldCBidWlsdDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHRyeSB7XG4gICAgaWYgKCFpbWFnZSkge1xuICAgICAgaWYgKHBrZy5idWlsZFR5cGUgPT09ICdidWlsZF9pbWFnZScpIHtcbiAgICAgICAgYnVpbHQgPSBsb2NhbEltYWdlVGFnKHBsYW4ubmFtZSwgcGxhbi52ZXJzaW9uKTtcbiAgICAgICAgcHJpbnRTZWN0aW9uKCdCdWlsZGluZyBpbWFnZScsIGJ1aWx0KTtcbiAgICAgICAgY29uc3QgYnVpbGRBcmdzID0gKHNwZWMuYnVpbGRBcmdzIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID8/IHt9O1xuICAgICAgICBjb25zdCBlcnJvciA9IGJ1aWxkUGx1Z2luSW1hZ2UoZXhlYywgeyBkaXI6IHBrZy5kaXIsIGRvY2tlcmZpbGU6IHBhdGguam9pbihwa2cuZGlyLCBwa2cuZG9ja2VyZmlsZU5hbWUpLCB0YWc6IGJ1aWx0LCBidWlsZEFyZ3MgfSk7XG4gICAgICAgIGlmIChlcnJvcikgdGhyb3cgbmV3IFBsdWdpblRlc3RGYWlsdXJlKGVycm9yKTtcbiAgICAgICAgaW1hZ2UgPSBidWlsdDtcbiAgICAgIH0gZWxzZSBpZiAocGtnLmJ1aWxkVHlwZSA9PT0gJ3ByZWJ1aWx0Jykge1xuICAgICAgICBjb25zdCByID0gZXhlYygnZG9ja2VyJywgWydsb2FkJywgJy1pJywgcGF0aC5qb2luKHBrZy5kaXIsICdpbWFnZS50YXInKV0pO1xuICAgICAgICBjb25zdCBsb2FkZWQgPSAvTG9hZGVkIGltYWdlKD86IElEKT86IChcXFMrKS8uZXhlYyhyLnN0ZG91dCk/LlsxXTtcbiAgICAgICAgaWYgKHIuc3RhdHVzICE9PSAwIHx8ICFsb2FkZWQpIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZShgZG9ja2VyIGxvYWQgaW1hZ2UudGFyIGZhaWxlZDogJHsoci5zdGRlcnIgfHwgci5zdGRvdXQpLnRyaW0oKX1gKTtcbiAgICAgICAgaW1hZ2UgPSBsb2FkZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdBIG1ldGFkYXRhX29ubHkgcGx1Z2luIGhhcyBubyBpbWFnZSBvZiBpdHMgb3duOyBwYXNzIHRoZSBpbWFnZSBpdCBydW5zIGluIHdpdGggLS1pbWFnZScpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWltYWdlKSB0aHJvdyBuZXcgUGx1Z2luVGVzdEZhaWx1cmUoJ05vIGltYWdlIHRvIHJ1bicpO1xuICAgIGNvbnN0IHVzZXIgPSBpbWFnZVVzZXIoZXhlYywgaW1hZ2UpO1xuICAgIGlmICgnZXJyb3InIGluIHVzZXIpIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZSh1c2VyLmVycm9yKTtcbiAgICBpZiAoaXNSb290VXNlcih1c2VyLnVzZXIpKSB7XG4gICAgICB0aHJvdyBuZXcgUGx1Z2luVGVzdEZhaWx1cmUoYFRoZSBpbWFnZSBydW5zIGFzIHJvb3QgKFVTRVIgJyR7dXNlci51c2VyIHx8ICcodW5zZXQpJ30nKTsgZW5kIHRoZSBEb2NrZXJmaWxlIHdpdGggXFxgVVNFUiAxMDAwOjEwMDBcXGBgKTtcbiAgICB9XG5cbiAgICBwcmludEluZm8oJ1J1bm5pbmcgcGx1Z2luJywge1xuICAgICAgaW1hZ2UsXG4gICAgICBydW5zQXM6IHVzZXIudXNlcixcbiAgICAgIHdvcmtzcGFjZSxcbiAgICAgIGZhaWx1cmVCZWhhdmlvcjogcGxhbi5mYWlsdXJlQmVoYXZpb3IsXG4gICAgICBlbnY6IE9iamVjdC5rZXlzKHBsYW4uZW52KSxcbiAgICAgIHNlY3JldHM6IHBsYW4uc2VjcmV0TmFtZXMsXG4gICAgfSk7XG4gICAgaWYgKHBsYW4ubWlzc2luZ09wdGlvbmFsU2VjcmV0cy5sZW5ndGgpIHByaW50V2FybmluZygnT3B0aW9uYWwgc2VjcmV0cyBub3Qgc2V0ICh0aGUgc3RlcCBydW5zIHdpdGhvdXQgdGhlbSknLCB7IHNlY3JldHM6IHBsYW4ubWlzc2luZ09wdGlvbmFsU2VjcmV0cyB9KTtcblxuICAgIGZvciAoY29uc3QgW3BoYXNlLCBzY3JpcHRdIG9mIFtbJ2luc3RhbGwnLCBwbGFuLmluc3RhbGxTY3JpcHRdLCBbJ2J1aWxkJywgcGxhbi5idWlsZFNjcmlwdF1dIGFzIGNvbnN0KSB7XG4gICAgICBwcmludFNlY3Rpb24oYFBoYXNlOiAke3BoYXNlfWApO1xuICAgICAgY29uc3QgciA9IGV4ZWMoJ2RvY2tlcicsIGRvY2tlclJ1bkFyZ3MoaW1hZ2UsIHdvcmtzcGFjZSwgcGxhbiwgc2NyaXB0KSwgeyBpbmhlcml0OiB0cnVlLCB0aW1lb3V0TXM6IHBsYW4udGltZW91dE1zIH0pO1xuICAgICAgaWYgKHIuZXJyb3IpIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZShgJHtwaGFzZX0gcGhhc2UgZGlkIG5vdCBjb21wbGV0ZTogJHtyLmVycm9yLm1lc3NhZ2V9YCk7XG4gICAgICBpZiAoci5zdGF0dXMgIT09IDApIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZShgJHtwaGFzZX0gcGhhc2UgZmFpbGVkIChleGl0ICR7ci5zdGF0dXN9KWApO1xuICAgIH1cblxuICAgIGxldCBvdXRwdXRGaWxlczogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgY29uc3Qgb3V0ID0gb3V0cHV0UGF0aCh3b3Jrc3BhY2UsIHBsYW4pO1xuICAgIGlmIChwbGFuLnByaW1hcnlPdXRwdXREaXJlY3RvcnkgJiYgb3V0ID09PSBudWxsKSB7XG4gICAgICBwcmludFdhcm5pbmcoJ1dPUktESVIgaXMgb3V0c2lkZSB0aGUgd29ya3NwYWNlOyBwcmltYXJ5T3V0cHV0RGlyZWN0b3J5IGNhbm5vdCBiZSBjaGVja2VkIG9uIHRoZSBob3N0Jyk7XG4gICAgfSBlbHNlIGlmIChvdXQpIHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhvdXQpIHx8ICFmcy5zdGF0U3luYyhvdXQpLmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBsdWdpblRlc3RGYWlsdXJlKGBwcmltYXJ5T3V0cHV0RGlyZWN0b3J5ICcke3BsYW4ucHJpbWFyeU91dHB1dERpcmVjdG9yeX0nIHdhcyBub3QgY3JlYXRlZGApO1xuICAgICAgfVxuICAgICAgb3V0cHV0RmlsZXMgPSBmcy5yZWFkZGlyU3luYyhvdXQpLmxlbmd0aDtcbiAgICAgIGlmIChvdXRwdXRGaWxlcyA9PT0gMCkgdGhyb3cgbmV3IFBsdWdpblRlc3RGYWlsdXJlKGBwcmltYXJ5T3V0cHV0RGlyZWN0b3J5ICcke3BsYW4ucHJpbWFyeU91dHB1dERpcmVjdG9yeX0nIGlzIGVtcHR5YCk7XG4gICAgICBwcmludFN1Y2Nlc3MoYHByaW1hcnlPdXRwdXREaXJlY3RvcnkgJyR7cGxhbi5wcmltYXJ5T3V0cHV0RGlyZWN0b3J5fScgaGFzICR7b3V0cHV0RmlsZXN9IGVudHIke291dHB1dEZpbGVzID09PSAxID8gJ3knIDogJ2llcyd9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByaW50V2FybmluZygnVGhlIHNwZWMgZGVjbGFyZXMgbm8gcHJpbWFyeU91dHB1dERpcmVjdG9yeTsgbm8gb3V0cHV0IHRvIGNoZWNrJyk7XG4gICAgfVxuXG4gICAgaWYgKHBsYW4uc21va2VUZXN0KSB7XG4gICAgICBwcmludFNlY3Rpb24oJ1Ntb2tlIHRlc3QnLCBwbGFuLnNtb2tlVGVzdCk7XG4gICAgICBjb25zdCByID0gZXhlYygnZG9ja2VyJywgWydydW4nLCAnLS1ybScsICctLWVudHJ5cG9pbnQnLCAnL2Jpbi9iYXNoJywgaW1hZ2UsICctYycsIHBsYW4uc21va2VUZXN0XSwgeyBpbmhlcml0OiB0cnVlIH0pO1xuICAgICAgaWYgKHIuZXJyb3IgfHwgci5zdGF0dXMgIT09IDApIHRocm93IG5ldyBQbHVnaW5UZXN0RmFpbHVyZShgc21va2VUZXN0IGZhaWxlZDogJHtwbGFuLnNtb2tlVGVzdH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJpbnRXYXJuaW5nKCdUaGUgc3BlYyBkZWNsYXJlcyBubyBzbW9rZVRlc3QnKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgb3V0cHV0RmlsZXMgfTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAob3B0aW9ucy5rZWVwKSBwcmludEluZm8oJ1dvcmtzcGFjZSBrZXB0JywgeyB3b3Jrc3BhY2UgfSk7XG4gICAgZWxzZSBmcy5ybVN5bmMod29ya3NwYWNlLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgaWYgKGJ1aWx0ICYmICFvcHRpb25zLmtlZXApIHJlbW92ZUltYWdlKGV4ZWMsIGJ1aWx0KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlZ2lzdGVyIGBwbHVnaW4gdGVzdGAg4oCUIHJ1biBhIHBsdWdpbidzIGluc3RhbGwgKyBidWlsZCBjb21tYW5kcyBsb2NhbGx5IGluXG4gKiBpdHMgaW1hZ2UgYWdhaW5zdCBhIHNhbXBsZSB3b3Jrc3BhY2UsIGNoZWNrIGl0cyBwcmltYXJ5IG91dHB1dCwgYW5kIHJ1biBpdHNcbiAqIHNtb2tlVGVzdC4gRXhpdHMgbm9uLXplcm8gb24gYW55IGZhaWx1cmUuXG4gKlxuICogVXNhZ2U6XG4gKiAgIHBpcGVsaW5lLW1hbmFnZXIgcGx1Z2luIHRlc3QgLS1kaXIgLi9teS1saW50ZXIgLS13b3Jrc3BhY2UgLi9zYW1wbGUtYXBwXG4gKiAgIHBpcGVsaW5lLW1hbmFnZXIgcGx1Z2luIHRlc3QgLS1kaXIgLi9teS1saW50ZXIgLS1pbWFnZSBteS1saW50ZXI6ZGV2IC0tbWV0YWRhdGEgU1RBR0U9ZGV2XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0UGx1Z2luKHByb2dyYW06IENvbW1hbmQpOiB2b2lkIHtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCd0ZXN0JylcbiAgICAuZGVzY3JpcHRpb24oJ1J1biBhIHBsdWdpblxcJ3MgaW5zdGFsbCArIGJ1aWxkIGNvbW1hbmRzIGxvY2FsbHkgaW4gaXRzIGltYWdlIGFnYWluc3QgYSBzYW1wbGUgd29ya3NwYWNlJylcbiAgICAub3B0aW9uKCctLWRpciA8cGF0aD4nLCAnUGx1Z2luIGRpcmVjdG9yeScsICcuJylcbiAgICAub3B0aW9uKCctLWltYWdlIDxyZWY+JywgJ1VzZSB0aGlzIGltYWdlIGluc3RlYWQgb2YgYnVpbGRpbmcgdGhlIHBsdWdpblxcJ3MgRG9ja2VyZmlsZScpXG4gICAgLm9wdGlvbignLS13b3Jrc3BhY2UgPHBhdGg+JywgJ1NhbXBsZSB3b3Jrc3BhY2UgY29waWVkIGluIGFzIHRoZSBzdGVwXFwncyBzb3VyY2UgKGRlZmF1bHQ6IGVtcHR5KScpXG4gICAgLm9wdGlvbignLS1lbnYgPEtFWT1WQUxVRT4nLCAnRXh0cmEgZW52aXJvbm1lbnQgdmFyaWFibGUgKHJlcGVhdGFibGUpJywgY29sbGVjdClcbiAgICAub3B0aW9uKCctLW1ldGFkYXRhIDxLRVk9VkFMVUU+JywgJ1BpcGVsaW5lIG1ldGFkYXRhIHZhbHVlIChyZXBlYXRhYmxlOyBhbHNvIGV4cG9ydGVkIGFzIGVudiwgYXMgaW4gdGhlIHBpcGVsaW5lKScsIGNvbGxlY3QpXG4gICAgLm9wdGlvbignLS12YXIgPEtFWT1WQUxVRT4nLCAnUGlwZWxpbmUgdmFyIGZvciB7eyBwaXBlbGluZS52YXJzLiogfX0gKHJlcGVhdGFibGUpJywgY29sbGVjdClcbiAgICAub3B0aW9uKCctLWtlZXAnLCAnS2VlcCB0aGUgc2NyYXRjaCB3b3Jrc3BhY2UgYW5kIGJ1aWx0IGltYWdlIGZvciBpbnNwZWN0aW9uJywgZmFsc2UpXG4gICAgLmFjdGlvbihhc3luYyAob3B0aW9uczogVGVzdFBsdWdpbk9wdGlvbnMpID0+IHtcbiAgICAgIGNvbnN0IGV4ZWN1dGlvbklkID0gcHJpbnRDb21tYW5kSGVhZGVyKCdUZXN0IFBsdWdpbicpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnVuUGx1Z2luVGVzdChvcHRpb25zKTtcbiAgICAgICAgcHJpbnRTdWNjZXNzKCdQbHVnaW4gdGVzdCBwYXNzZWQnLCB7IGV4ZWN1dGlvbklkLCBvdXRwdXRFbnRyaWVzOiByZXN1bHQub3V0cHV0RmlsZXMgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyLCBlcnIgaW5zdGFuY2VvZiBWYWxpZGF0aW9uRXJyb3IgPyBFUlJPUl9DT0RFUy5WQUxJREFUSU9OIDogRVJST1JfQ09ERVMuR0VORVJBTCwge1xuICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICBleGl0OiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHsgY29tbWFuZDogJ3BsdWdpbiB0ZXN0JywgZXhlY3V0aW9uSWQgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG59XG4iXX0=
|
|
@@ -3,18 +3,17 @@ import { Command } from 'commander';
|
|
|
3
3
|
* Registers the `upload-plugin` command with the CLI program.
|
|
4
4
|
*
|
|
5
5
|
* Validates a local plugin ZIP file (size, extension, readability),
|
|
6
|
-
* builds a multipart form, and uploads it to the platform API.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* builds a multipart form, and uploads it to the platform API. The
|
|
7
|
+
* plugin's name and version always come from the package's
|
|
8
|
+
* `plugin-spec.yaml`, and the organization from the signed-in session.
|
|
9
9
|
*
|
|
10
10
|
* @param program - The root Commander program instance to attach the command to.
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```bash
|
|
14
|
-
* cli plugin upload --file plugin.zip
|
|
15
|
-
* cli plugin upload --file plugin.zip --
|
|
16
|
-
* cli plugin upload --file plugin.zip --
|
|
17
|
-
* cli plugin upload --file plugin.zip --organization acme --no-verify-ssl
|
|
14
|
+
* cli plugin upload --file plugin.zip
|
|
15
|
+
* cli plugin upload --file plugin.zip --public
|
|
16
|
+
* cli plugin upload --file plugin.zip --no-verify-ssl
|
|
18
17
|
* ```
|
|
19
18
|
*/
|
|
20
19
|
export declare function uploadPlugin(program: Command): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload-plugin.d.ts","sourceRoot":"","sources":["../../src/commands/upload-plugin.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"upload-plugin.d.ts","sourceRoot":"","sources":["../../src/commands/upload-plugin.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8IpC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6FnD"}
|