@pipeline-builder/pipeline-manager 0.0.1
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/LICENSE +202 -0
- package/README.md +145 -0
- package/cdk.json +91 -0
- package/config.yml +94 -0
- package/dist/agent/ai.d.ts +48 -0
- package/dist/agent/ai.d.ts.map +1 -0
- package/dist/agent/ai.js +149 -0
- package/dist/agent/bootstrap.d.ts +39 -0
- package/dist/agent/bootstrap.d.ts.map +1 -0
- package/dist/agent/bootstrap.js +66 -0
- package/dist/agent/env-file.d.ts +17 -0
- package/dist/agent/env-file.d.ts.map +1 -0
- package/dist/agent/env-file.js +47 -0
- package/dist/agent/executor.d.ts +30 -0
- package/dist/agent/executor.d.ts.map +1 -0
- package/dist/agent/executor.js +60 -0
- package/dist/agent/health.d.ts +43 -0
- package/dist/agent/health.d.ts.map +1 -0
- package/dist/agent/health.js +109 -0
- package/dist/agent/ports.d.ts +26 -0
- package/dist/agent/ports.d.ts.map +1 -0
- package/dist/agent/ports.js +132 -0
- package/dist/agent/post-steps.d.ts +61 -0
- package/dist/agent/post-steps.d.ts.map +1 -0
- package/dist/agent/post-steps.js +131 -0
- package/dist/agent/prereqs.d.ts +26 -0
- package/dist/agent/prereqs.d.ts.map +1 -0
- package/dist/agent/prereqs.js +134 -0
- package/dist/agent/targets.d.ts +128 -0
- package/dist/agent/targets.d.ts.map +1 -0
- package/dist/agent/targets.js +265 -0
- package/dist/agent/tools.d.ts +13 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +75 -0
- package/dist/agent/troubleshoot.d.ts +30 -0
- package/dist/agent/troubleshoot.d.ts.map +1 -0
- package/dist/agent/troubleshoot.js +87 -0
- package/dist/boilerplate.d.ts +3 -0
- package/dist/boilerplate.d.ts.map +1 -0
- package/dist/boilerplate.js +54 -0
- package/dist/cdk.json +91 -0
- package/dist/cli.d.ts +62 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +463 -0
- package/dist/commands/audit-stacks.d.ts +24 -0
- package/dist/commands/audit-stacks.d.ts.map +1 -0
- package/dist/commands/audit-stacks.js +182 -0
- package/dist/commands/audit-tokens.d.ts +21 -0
- package/dist/commands/audit-tokens.d.ts.map +1 -0
- package/dist/commands/audit-tokens.js +153 -0
- package/dist/commands/bootstrap.d.ts +11 -0
- package/dist/commands/bootstrap.d.ts.map +1 -0
- package/dist/commands/bootstrap.js +159 -0
- package/dist/commands/create-pat.d.ts +27 -0
- package/dist/commands/create-pat.d.ts.map +1 -0
- package/dist/commands/create-pat.js +194 -0
- package/dist/commands/create-pipeline.d.ts +12 -0
- package/dist/commands/create-pipeline.d.ts.map +1 -0
- package/dist/commands/create-pipeline.js +315 -0
- package/dist/commands/deploy.d.ts +15 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +157 -0
- package/dist/commands/entity-get.d.ts +51 -0
- package/dist/commands/entity-get.d.ts.map +1 -0
- package/dist/commands/entity-get.js +69 -0
- package/dist/commands/entity-list.d.ts +39 -0
- package/dist/commands/entity-list.d.ts.map +1 -0
- package/dist/commands/entity-list.js +88 -0
- package/dist/commands/get-pipeline.d.ts +13 -0
- package/dist/commands/get-pipeline.d.ts.map +1 -0
- package/dist/commands/get-pipeline.js +49 -0
- package/dist/commands/get-plugin.d.ts +13 -0
- package/dist/commands/get-plugin.d.ts.map +1 -0
- package/dist/commands/get-plugin.js +51 -0
- package/dist/commands/instantiate-template.d.ts +20 -0
- package/dist/commands/instantiate-template.d.ts.map +1 -0
- package/dist/commands/instantiate-template.js +274 -0
- package/dist/commands/list-pipelines.d.ts +20 -0
- package/dist/commands/list-pipelines.d.ts.map +1 -0
- package/dist/commands/list-pipelines.js +99 -0
- package/dist/commands/list-plugins.d.ts +20 -0
- package/dist/commands/list-plugins.d.ts.map +1 -0
- package/dist/commands/list-plugins.js +92 -0
- package/dist/commands/login.d.ts +21 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +174 -0
- package/dist/commands/new-plugin.d.ts +12 -0
- package/dist/commands/new-plugin.d.ts.map +1 -0
- package/dist/commands/new-plugin.js +129 -0
- package/dist/commands/org-export.d.ts +25 -0
- package/dist/commands/org-export.d.ts.map +1 -0
- package/dist/commands/org-export.js +100 -0
- package/dist/commands/provision.d.ts +122 -0
- package/dist/commands/provision.d.ts.map +1 -0
- package/dist/commands/provision.js +867 -0
- package/dist/commands/redrive-events.d.ts +24 -0
- package/dist/commands/redrive-events.d.ts.map +1 -0
- package/dist/commands/redrive-events.js +127 -0
- package/dist/commands/register.d.ts +38 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +160 -0
- package/dist/commands/setup-events.d.ts +15 -0
- package/dist/commands/setup-events.d.ts.map +1 -0
- package/dist/commands/setup-events.js +168 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +81 -0
- package/dist/commands/store-token.d.ts +26 -0
- package/dist/commands/store-token.d.ts.map +1 -0
- package/dist/commands/store-token.js +305 -0
- package/dist/commands/synth.d.ts +21 -0
- package/dist/commands/synth.d.ts.map +1 -0
- package/dist/commands/synth.js +158 -0
- package/dist/commands/upload-plugin.d.ts +21 -0
- package/dist/commands/upload-plugin.d.ts.map +1 -0
- package/dist/commands/upload-plugin.js +275 -0
- package/dist/commands/validate-plugin.d.ts +12 -0
- package/dist/commands/validate-plugin.d.ts.map +1 -0
- package/dist/commands/validate-plugin.js +175 -0
- package/dist/commands/validate-templates.d.ts +11 -0
- package/dist/commands/validate-templates.d.ts.map +1 -0
- package/dist/commands/validate-templates.js +116 -0
- package/dist/commands/version.d.ts +12 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +216 -0
- package/dist/config/cli.constants.d.ts +116 -0
- package/dist/config/cli.constants.d.ts.map +1 -0
- package/dist/config/cli.constants.js +194 -0
- package/dist/config.yml +94 -0
- package/dist/lambda/token-renew-handler.d.ts +2 -0
- package/dist/lambda/token-renew-handler.d.ts.map +1 -0
- package/dist/lambda/token-renew-handler.js +125 -0
- package/dist/templates/events-stack.json +174 -0
- package/dist/templates/token-renew-stack.json +122 -0
- package/dist/types/config.d.ts +53 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +4 -0
- package/dist/types/error.d.ts +61 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +35 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +11 -0
- package/dist/types/pipeline-template.d.ts +48 -0
- package/dist/types/pipeline-template.d.ts.map +1 -0
- package/dist/types/pipeline-template.js +4 -0
- package/dist/types/pipeline.d.ts +121 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +4 -0
- package/dist/types/plugin.d.ts +135 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +4 -0
- package/dist/utils/api-client.d.ts +26 -0
- package/dist/utils/api-client.d.ts.map +1 -0
- package/dist/utils/api-client.js +151 -0
- package/dist/utils/audit-log.d.ts +8 -0
- package/dist/utils/audit-log.d.ts.map +1 -0
- package/dist/utils/audit-log.js +57 -0
- package/dist/utils/auth-guard.d.ts +20 -0
- package/dist/utils/auth-guard.d.ts.map +1 -0
- package/dist/utils/auth-guard.js +22 -0
- package/dist/utils/auth-utils.d.ts +68 -0
- package/dist/utils/auth-utils.d.ts.map +1 -0
- package/dist/utils/auth-utils.js +77 -0
- package/dist/utils/aws-env.d.ts +21 -0
- package/dist/utils/aws-env.d.ts.map +1 -0
- package/dist/utils/aws-env.js +34 -0
- package/dist/utils/aws-secrets.d.ts +48 -0
- package/dist/utils/aws-secrets.d.ts.map +1 -0
- package/dist/utils/aws-secrets.js +115 -0
- package/dist/utils/banner.d.ts +19 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +52 -0
- package/dist/utils/cdk-utils.d.ts +74 -0
- package/dist/utils/cdk-utils.d.ts.map +1 -0
- package/dist/utils/cdk-utils.js +152 -0
- package/dist/utils/command-utils.d.ts +75 -0
- package/dist/utils/command-utils.d.ts.map +1 -0
- package/dist/utils/command-utils.js +155 -0
- package/dist/utils/config-loader.d.ts +33 -0
- package/dist/utils/config-loader.d.ts.map +1 -0
- package/dist/utils/config-loader.js +154 -0
- package/dist/utils/cron.d.ts +28 -0
- package/dist/utils/cron.d.ts.map +1 -0
- package/dist/utils/cron.js +119 -0
- package/dist/utils/deploy-runner.d.ts +38 -0
- package/dist/utils/deploy-runner.d.ts.map +1 -0
- package/dist/utils/deploy-runner.js +112 -0
- package/dist/utils/error-handler.d.ts +29 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js +302 -0
- package/dist/utils/list-command-utils.d.ts +23 -0
- package/dist/utils/list-command-utils.d.ts.map +1 -0
- package/dist/utils/list-command-utils.js +57 -0
- package/dist/utils/output-utils.d.ts +40 -0
- package/dist/utils/output-utils.d.ts.map +1 -0
- package/dist/utils/output-utils.js +250 -0
- package/dist/utils/pipeline-config.d.ts +33 -0
- package/dist/utils/pipeline-config.d.ts.map +1 -0
- package/dist/utils/pipeline-config.js +55 -0
- package/dist/utils/platform-secret.d.ts +27 -0
- package/dist/utils/platform-secret.d.ts.map +1 -0
- package/dist/utils/platform-secret.js +92 -0
- package/dist/utils/plugin-resolver.d.ts +17 -0
- package/dist/utils/plugin-resolver.d.ts.map +1 -0
- package/dist/utils/plugin-resolver.js +101 -0
- package/dist/utils/preflight.d.ts +26 -0
- package/dist/utils/preflight.d.ts.map +1 -0
- package/dist/utils/preflight.js +59 -0
- package/dist/utils/rate-limiter.d.ts +15 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +164 -0
- package/dist/utils/registry.d.ts +86 -0
- package/dist/utils/registry.d.ts.map +1 -0
- package/dist/utils/registry.js +140 -0
- package/dist/utils/response-utils.d.ts +21 -0
- package/dist/utils/response-utils.d.ts.map +1 -0
- package/dist/utils/response-utils.js +70 -0
- package/dist/utils/tls.d.ts +52 -0
- package/dist/utils/tls.d.ts.map +1 -0
- package/dist/utils/tls.js +88 -0
- package/package.json +181 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import pico from 'picocolors';
|
|
7
|
+
import {} from '../types/index.js';
|
|
8
|
+
import { createAuthenticatedClient, printCommandHeader, printExecutionSummary, printSslWarning, withSslOptions } from '../utils/command-utils.js';
|
|
9
|
+
import { ERROR_CODES, handleError, ValidationError } from '../utils/error-handler.js';
|
|
10
|
+
import { outputData, printError, printInfo, printKeyValue, printSection, printSuccess, printWarning } from '../utils/output-utils.js';
|
|
11
|
+
import { extractListResponse, extractSingleResponse } from '../utils/response-utils.js';
|
|
12
|
+
const { bold, cyan, dim, green } = pico;
|
|
13
|
+
/**
|
|
14
|
+
* Accumulate a repeatable `--input KEY=VALUE` flag. This only collects — it does
|
|
15
|
+
* NOT validate, because Commander runs `parseArg` before the action callback, so
|
|
16
|
+
* a throw here would escape the action's `handleError` and surface as an
|
|
17
|
+
* unhandled stack trace with the wrong exit code instead of a clean validation
|
|
18
|
+
* failure. Parsing happens in {@link parseInputPairs}, inside the action.
|
|
19
|
+
*/
|
|
20
|
+
function collectInput(pair, previous) {
|
|
21
|
+
return [...previous, pair];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Split collected `KEY=VALUE` pairs into a map. Values stay strings; the platform
|
|
25
|
+
* coerces each to its declared input type (and rejects what doesn't fit), so the
|
|
26
|
+
* CLI does not guess types locally. Only the FIRST `=` splits, so a value may
|
|
27
|
+
* itself contain `=`.
|
|
28
|
+
*/
|
|
29
|
+
function parseInputPairs(pairs) {
|
|
30
|
+
const out = {};
|
|
31
|
+
for (const pair of pairs) {
|
|
32
|
+
const eq = pair.indexOf('=');
|
|
33
|
+
if (eq < 1) {
|
|
34
|
+
throw new ValidationError(`Invalid --input "${pair}" — expected KEY=VALUE`, 'input', pair, 'key=value', 'e.g. --input orgId=1234abcd-...');
|
|
35
|
+
}
|
|
36
|
+
out[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
/** Read and parse `--inputs-file`, which holds a flat `{ name: value }` object. */
|
|
41
|
+
function readInputsFile(file) {
|
|
42
|
+
if (!fs.existsSync(file)) {
|
|
43
|
+
throw new ValidationError(`Inputs file not found: ${file}`, 'inputs-file', file);
|
|
44
|
+
}
|
|
45
|
+
let parsed;
|
|
46
|
+
try {
|
|
47
|
+
parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new ValidationError(`Inputs file is not valid JSON: ${error instanceof Error ? error.message : String(error)}`, 'inputs-file', file);
|
|
51
|
+
}
|
|
52
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
53
|
+
throw new ValidationError('Inputs file must contain a JSON object of { "inputName": value }', 'inputs-file', file);
|
|
54
|
+
}
|
|
55
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
56
|
+
const t = typeof v;
|
|
57
|
+
if (t !== 'string' && t !== 'number' && t !== 'boolean') {
|
|
58
|
+
throw new ValidationError(`Input "${k}" must be a string, number, or boolean (got ${t})`, 'inputs-file', file);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return parsed;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve a template `name` to its id through the catalog list endpoint. The list
|
|
65
|
+
* is visibility-scoped server-side, so this only ever sees templates the caller
|
|
66
|
+
* may read. Matching is exact on `name` — the `name` query param is a filter, not
|
|
67
|
+
* a unique lookup, so a fuzzy backend match must not silently instantiate a
|
|
68
|
+
* DIFFERENT template than the one asked for.
|
|
69
|
+
*/
|
|
70
|
+
async function resolveTemplateByName(client, name) {
|
|
71
|
+
const url = client.getConfig().api.pipelineTemplateUrl;
|
|
72
|
+
const response = await client.get(url, { name, limit: 100 });
|
|
73
|
+
const { items } = extractListResponse(response, 'templates');
|
|
74
|
+
const exact = items.filter((t) => t.name === name);
|
|
75
|
+
if (exact.length === 0) {
|
|
76
|
+
throw new ValidationError(`No pipeline template named "${name}" is visible to you.`, 'name', name, undefined, items.length > 0
|
|
77
|
+
? `Did you mean one of: ${items.slice(0, 10).map((t) => t.name).join(', ')}`
|
|
78
|
+
: 'Load the sample catalog with deploy/bin/load-templates.sh, or pass --id.');
|
|
79
|
+
}
|
|
80
|
+
// A name is unique per org, but the visible set spans your org + parent + the
|
|
81
|
+
// system catalog, so the same name can legitimately appear more than once.
|
|
82
|
+
// Refuse to guess — the wrong pick would silently synth someone else's body.
|
|
83
|
+
if (exact.length > 1) {
|
|
84
|
+
throw new ValidationError(`"${name}" matches ${exact.length} visible templates — pass --id to choose one.`, 'name', name, undefined, `ids: ${exact.map((t) => t.id).join(', ')}`);
|
|
85
|
+
}
|
|
86
|
+
return exact[0];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Registers the `template instantiate` command.
|
|
90
|
+
*
|
|
91
|
+
* Renders a golden-path template into a concrete pipeline `props` document by
|
|
92
|
+
* supplying its declared inputs. It **creates nothing** — the rendered props are
|
|
93
|
+
* written to a file (or stdout) and go through the normal `pipeline create` path,
|
|
94
|
+
* where compliance and quota still apply.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```bash
|
|
98
|
+
* pipeline-manager template instantiate --name react-javascript \
|
|
99
|
+
* --project react --organization AcmeCorp \
|
|
100
|
+
* --input orgId=1234abcd-... --output pipeline-props.json
|
|
101
|
+
*
|
|
102
|
+
* pipeline-manager pipeline create --file pipeline-props.json --deploy
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export function instantiateTemplate(program) {
|
|
106
|
+
withSslOptions(program
|
|
107
|
+
.command('instantiate')
|
|
108
|
+
.description('Render a pipeline template into concrete pipeline props (creates nothing)')
|
|
109
|
+
.option('-n, --name <name>', 'Template name (resolved against the catalog you can see)')
|
|
110
|
+
.option('-i, --id <id>', 'Template ID (skips the name lookup)')
|
|
111
|
+
.requiredOption('-p, --project <project>', 'Project name for the pipeline this template will produce')
|
|
112
|
+
.requiredOption('-o, --organization <organization>', 'Organization name for the pipeline')
|
|
113
|
+
.option('--pipeline-name <name>', 'Pipeline name (defaults to <organization>-<project>-pipeline at synth)')
|
|
114
|
+
.option('--input <key=value>', 'Template input, repeatable (e.g. --input orgId=1234abcd-...)', collectInput, [])
|
|
115
|
+
.option('--inputs-file <file>', 'JSON file of { "inputName": value } — merged UNDER any --input flags')
|
|
116
|
+
.option('--output <file>', 'Write the rendered props to a file (default: stdout)')
|
|
117
|
+
.option('-f, --format <format>', 'Output format (json, yaml)', 'json'))
|
|
118
|
+
.option('--json', 'Print ONLY the rendered props as JSON (for piping); implies no decorative output', false)
|
|
119
|
+
.action(async (options) => {
|
|
120
|
+
// With --json (or props headed for stdout in any format) the payload IS the
|
|
121
|
+
// output, so the banner must not land on stdout ahead of it and break piping.
|
|
122
|
+
const toStdout = !options.output;
|
|
123
|
+
const quiet = options.json || toStdout;
|
|
124
|
+
const executionId = printCommandHeader('Instantiate Template', undefined, { quiet });
|
|
125
|
+
try {
|
|
126
|
+
if (!options.name && !options.id) {
|
|
127
|
+
throw new ValidationError('Provide --name or --id to select a template', 'name');
|
|
128
|
+
}
|
|
129
|
+
if (options.name && options.id) {
|
|
130
|
+
throw new ValidationError('Pass either --name or --id, not both', 'name');
|
|
131
|
+
}
|
|
132
|
+
// Only the round-trippable formats: the rendered props exist to be fed
|
|
133
|
+
// back to `pipeline create --file`, and `table`/`csv` would flatten them
|
|
134
|
+
// into something that can no longer be parsed as props.
|
|
135
|
+
if (!['json', 'yaml'].includes(options.format)) {
|
|
136
|
+
throw new ValidationError(`Unsupported --format "${options.format}" — rendered props must stay parseable`, 'format', options.format, 'json|yaml');
|
|
137
|
+
}
|
|
138
|
+
if (!quiet)
|
|
139
|
+
printSslWarning(options.verifySsl);
|
|
140
|
+
// --input flags win over --inputs-file so a file can hold shared defaults
|
|
141
|
+
// that a single flag overrides on the command line.
|
|
142
|
+
const inputs = {
|
|
143
|
+
...(options.inputsFile ? readInputsFile(options.inputsFile) : {}),
|
|
144
|
+
...parseInputPairs(options.input),
|
|
145
|
+
};
|
|
146
|
+
if (!quiet) {
|
|
147
|
+
printInfo('Request parameters', {
|
|
148
|
+
template: options.name ?? options.id,
|
|
149
|
+
project: options.project,
|
|
150
|
+
organization: options.organization,
|
|
151
|
+
pipelineName: options.pipelineName ?? '(default)',
|
|
152
|
+
inputs: Object.keys(inputs).length > 0 ? Object.keys(inputs).join(', ') : '(none)',
|
|
153
|
+
output: options.output ?? '(stdout)',
|
|
154
|
+
});
|
|
155
|
+
console.log('');
|
|
156
|
+
printSection('Rendering Template');
|
|
157
|
+
}
|
|
158
|
+
const client = createAuthenticatedClient(options);
|
|
159
|
+
const templateUrl = client.getConfig().api.pipelineTemplateUrl;
|
|
160
|
+
const startTime = Date.now();
|
|
161
|
+
const spinner = quiet ? null : ora('Resolving template...').start();
|
|
162
|
+
let templateId;
|
|
163
|
+
let templateName;
|
|
164
|
+
try {
|
|
165
|
+
if (options.id) {
|
|
166
|
+
templateId = options.id;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
const template = await resolveTemplateByName(client, options.name);
|
|
170
|
+
templateId = template.id;
|
|
171
|
+
templateName = template.name;
|
|
172
|
+
}
|
|
173
|
+
spinner?.succeed(`Template resolved${templateName ? ` (${templateName})` : ''}`);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
spinner?.fail('Template resolution failed');
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
const body = {
|
|
180
|
+
project: options.project,
|
|
181
|
+
organization: options.organization,
|
|
182
|
+
...(options.pipelineName ? { pipelineName: options.pipelineName } : {}),
|
|
183
|
+
...(Object.keys(inputs).length > 0 ? { inputs } : {}),
|
|
184
|
+
};
|
|
185
|
+
const renderSpinner = quiet ? null : ora('Instantiating...').start();
|
|
186
|
+
let rendered;
|
|
187
|
+
try {
|
|
188
|
+
const response = await client.post(`${templateUrl}/${encodeURIComponent(templateId)}/instantiate`, body);
|
|
189
|
+
// `props` is the identifier key: the envelope's data IS { props, ... }.
|
|
190
|
+
rendered = extractSingleResponse(response, 'template', 'props');
|
|
191
|
+
renderSpinner?.succeed('Template instantiated');
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
renderSpinner?.fail('Instantiate failed');
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
const duration = Date.now() - startTime;
|
|
198
|
+
if (!rendered?.props) {
|
|
199
|
+
printError('No props returned from API', { templateId });
|
|
200
|
+
throw new Error(`Template ${templateId} rendered no props`);
|
|
201
|
+
}
|
|
202
|
+
const props = rendered.props;
|
|
203
|
+
// A leftover `{{ ... }}` in a *self-scope* field means an input was never
|
|
204
|
+
// supplied and the placeholder would fail opaquely at synth. `pipeline.*`
|
|
205
|
+
// tokens are expected here — they resolve at synth, not at instantiate.
|
|
206
|
+
const unresolved = unresolvedSelfVars(props);
|
|
207
|
+
if (unresolved.length > 0) {
|
|
208
|
+
printWarning('Rendered props still contain unresolved placeholders', {
|
|
209
|
+
vars: unresolved.join(', '),
|
|
210
|
+
hint: 'Supply them with --input <name>=<value>',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
if (!quiet) {
|
|
214
|
+
console.log('');
|
|
215
|
+
printSection('Rendered Props');
|
|
216
|
+
printKeyValue({
|
|
217
|
+
'Template': green(bold(templateName ?? templateId)),
|
|
218
|
+
'Project': props.project,
|
|
219
|
+
'Organization': props.organization,
|
|
220
|
+
'Pipeline Name': props.pipelineName ?? dim('(default at synth)'),
|
|
221
|
+
'Vars': Object.keys(props.vars ?? {}).join(', ') || dim('(none)'),
|
|
222
|
+
'Stages': String(Array.isArray(props.stages) ? props.stages.length : 0),
|
|
223
|
+
});
|
|
224
|
+
printExecutionSummary(executionId, duration);
|
|
225
|
+
}
|
|
226
|
+
outputData(props, {
|
|
227
|
+
format: options.json ? 'json' : options.format,
|
|
228
|
+
file: options.output,
|
|
229
|
+
silent: quiet,
|
|
230
|
+
});
|
|
231
|
+
if (options.output && !quiet) {
|
|
232
|
+
console.log('');
|
|
233
|
+
printSuccess('Pipeline props saved', { path: options.output });
|
|
234
|
+
printInfo('Next step', {
|
|
235
|
+
command: `pipeline-manager pipeline create --file ${options.output} --deploy`,
|
|
236
|
+
});
|
|
237
|
+
console.log(dim(` ${cyan('Tip:')} instantiate only renders — nothing exists on the platform yet.`));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
handleError(error, ERROR_CODES.API_REQUEST, {
|
|
242
|
+
debug: program.opts().debug,
|
|
243
|
+
exit: true,
|
|
244
|
+
context: { command: 'instantiate-template', executionId, template: options.name ?? options.id },
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Names of `{{ vars.X }}` placeholders still present in the rendered props' own
|
|
251
|
+
* self-scope fields (`project`, `metadata.*`, `vars.*`) — i.e. inputs the caller
|
|
252
|
+
* never supplied. `{{ pipeline.* }}` tokens are deliberately ignored: those are
|
|
253
|
+
* synth-time references (e.g. the GitHub source token) and are SUPPOSED to
|
|
254
|
+
* survive instantiation.
|
|
255
|
+
*/
|
|
256
|
+
function unresolvedSelfVars(props) {
|
|
257
|
+
const found = new Set();
|
|
258
|
+
const scan = (value) => {
|
|
259
|
+
if (typeof value === 'string') {
|
|
260
|
+
for (const m of value.matchAll(/\{\{\s*vars\.([A-Za-z_][A-Za-z0-9_]*)/g))
|
|
261
|
+
found.add(m[1]);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (Array.isArray(value))
|
|
265
|
+
return value.forEach(scan);
|
|
266
|
+
if (value && typeof value === 'object')
|
|
267
|
+
return Object.values(value).forEach(scan);
|
|
268
|
+
};
|
|
269
|
+
scan(props.project);
|
|
270
|
+
scan(props.metadata);
|
|
271
|
+
scan(props.vars);
|
|
272
|
+
return [...found];
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFudGlhdGUtdGVtcGxhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvaW5zdGFudGlhdGUtdGVtcGxhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BDLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQztBQUN0QixPQUFPLElBQUksTUFBTSxZQUFZLENBQUM7QUFDOUIsT0FBTyxFQUtOLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFFLHlCQUF5QixFQUFFLGtCQUFrQixFQUFFLHFCQUFxQixFQUFFLGVBQWUsRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNsSixPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RixPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEksT0FBTyxFQUFFLG1CQUFtQixFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFeEYsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQztBQUV4Qzs7Ozs7O0dBTUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxJQUFZLEVBQUUsUUFBa0I7SUFDcEQsT0FBTyxDQUFDLEdBQUcsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQWU7SUFDdEMsTUFBTSxHQUFHLEdBQTJCLEVBQUUsQ0FB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QUFJLE9BQU8sQ0FBQyxFQUFFLEVBQUU7YUFDaEcsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsa0JBQWtCLENBQUMsS0FBb0I7SUFDOUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUNoQyxNQUFNLElBQUksR0FBRyxDQUFDLEtBQWMsRUFBUSxFQUFFO1FBQ3BDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUIsS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLHdDQUF3QyxDQUFDO2dCQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBRSxDQUFDLENBQUM7WUFDM0YsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JELElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFBRSxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BGLENBQUMsQ0FBQztJQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pCLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDO0FBQ3BCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgb3JhIGZyb20gJ29yYSc7XG5pbXBvcnQgcGljbyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCB7XG4gIHR5cGUgSW5zdGFudGlhdGVUZW1wbGF0ZVJlcXVlc3QsXG4gIHR5cGUgSW5zdGFudGlhdGVUZW1wbGF0ZVJlc3BvbnNlLFxuICB0eXBlIFBpcGVsaW5lVGVtcGxhdGUsXG4gIHR5cGUgUGlwZWxpbmVQcm9wcyxcbn0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuaW1wb3J0IHsgY3JlYXRlQXV0aGVudGljYXRlZENsaWVudCwgcHJpbnRDb21tYW5kSGVhZGVyLCBwcmludEV4ZWN1dGlvblN1bW1hcnksIHByaW50U3NsV2FybmluZywgd2l0aFNzbE9wdGlvbnMgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vdXRpbHMvZXJyb3ItaGFuZGxlci5qcyc7XG5pbXBvcnQgeyBvdXRwdXREYXRhLCBwcmludEVycm9yLCBwcmludEluZm8sIHByaW50S2V5VmFsdWUsIHByaW50U2VjdGlvbiwgcHJpbnRTdWNjZXNzLCBwcmludFdhcm5pbmcgfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMuanMnO1xuaW1wb3J0IHsgZXh0cmFjdExpc3RSZXNwb25zZSwgZXh0cmFjdFNpbmdsZVJlc3BvbnNlIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UtdXRpbHMuanMnO1xuXG5jb25zdCB7IGJvbGQsIGN5YW4sIGRpbSwgZ3JlZW4gfSA9IHBpY287XG5cbi8qKlxuICogQWNjdW11bGF0ZSBhIHJlcGVhdGFibGUgYC0taW5wdXQgS0VZPVZBTFVFYCBmbGFnLiBUaGlzIG9ubHkgY29sbGVjdHMg4oCUIGl0IGRvZXNcbiAqIE5PVCB2YWxpZGF0ZSwgYmVjYXVzZSBDb21tYW5kZXIgcnVucyBgcGFyc2VBcmdgIGJlZm9yZSB0aGUgYWN0aW9uIGNhbGxiYWNrLCBzb1xuICogYSB0aHJvdyBoZXJlIHdvdWxkIGVzY2FwZSB0aGUgYWN0aW9uJ3MgYGhhbmRsZUVycm9yYCBhbmQgc3VyZmFjZSBhcyBhblxuICogdW5oYW5kbGVkIHN0YWNrIHRyYWNlIHdpdGggdGhlIHdyb25nIGV4aXQgY29kZSBpbnN0ZWFkIG9mIGEgY2xlYW4gdmFsaWRhdGlvblxuICogZmFpbHVyZS4gUGFyc2luZyBoYXBwZW5zIGluIHtAbGluayBwYXJzZUlucHV0UGFpcnN9LCBpbnNpZGUgdGhlIGFjdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29sbGVjdElucHV0KHBhaXI6IHN0cmluZywgcHJldmlvdXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICByZXR1cm4gWy4uLnByZXZpb3VzLCBwYWlyXTtcbn1cblxuLyoqXG4gKiBTcGxpdCBjb2xsZWN0ZWQgYEtFWT1WQUxVRWAgcGFpcnMgaW50byBhIG1hcC4gVmFsdWVzIHN0YXkgc3RyaW5nczsgdGhlIHBsYXRmb3JtXG4gKiBjb2VyY2VzIGVhY2ggdG8gaXRzIGRlY2xhcmVkIGlucHV0IHR5cGUgKGFuZCByZWplY3RzIHdoYXQgZG9lc24ndCBmaXQpLCBzbyB0aGVcbiAqIENMSSBkb2VzIG5vdCBndWVzcyB0eXBlcyBsb2NhbGx5LiBPbmx5IHRoZSBGSVJTVCBgPWAgc3BsaXRzLCBzbyBhIHZhbHVlIG1heVxuICogaXRzZWxmIGNvbnRhaW4gYD1gLlxuICovXG5mdW5jdGlvbiBwYXJzZUlucHV0UGFpcnMocGFpcnM6IHN0cmluZ1tdKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IG91dDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHtcbiAgICBjb25zdCBlcSA9IHBhaXIuaW5kZXhPZignPScpO1xuICAgIGlmIChlcSA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIC0taW5wdXQgXCIke3BhaXJ9XCIg4oCUIGV4cGVjdGVkIEtFWT1WQUxVRWAsXG4gICAgICAgICdpbnB1dCcsIHBhaXIsICdrZXk9dmFsdWUnLCAnZS5nLiAtLWlucHV0IG9yZ0lkPTEyMzRhYmNkLS4uLicsXG4gICAgICApO1xuICAgIH1cbiAgICBvdXRbcGFpci5zbGljZSgwLCBlcSldID0gcGFpci5zbGljZShlcSArIDEpO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBSZWFkIGFuZCBwYXJzZSBgLS1pbnB1dHMtZmlsZWAsIHdoaWNoIGhvbGRzIGEgZmxhdCBgeyBuYW1lOiB2YWx1ZSB9YCBvYmplY3QuICovXG5mdW5jdGlvbiByZWFkSW5wdXRzRmlsZShmaWxlOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPiB7XG4gIGlmICghZnMuZXhpc3RzU3luYyhmaWxlKSkge1xuICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYElucHV0cyBmaWxlIG5vdCBmb3VuZDogJHtmaWxlfWAsICdpbnB1dHMtZmlsZScsIGZpbGUpO1xuICB9XG4gIGxldCBwYXJzZWQ6IHVua25vd247XG4gIHRyeSB7XG4gICAgcGFyc2VkID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0Zi04JykpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICBgSW5wdXRzIGZpbGUgaXMgbm90IHZhbGlkIEpTT046ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWAsXG4gICAgICAnaW5wdXRzLWZpbGUnLCBmaWxlLFxuICAgICk7XG4gIH1cbiAgaWYgKHR5cGVvZiBwYXJzZWQgIT09ICdvYmplY3QnIHx8IHBhcnNlZCA9PT0gbnVsbCB8fCBBcnJheS5pc0FycmF5KHBhcnNlZCkpIHtcbiAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdJbnB1dHMgZmlsZSBtdXN0IGNvbnRhaW4gYSBKU09OIG9iamVjdCBvZiB7IFwiaW5wdXROYW1lXCI6IHZhbHVlIH0nLCAnaW5wdXRzLWZpbGUnLCBmaWxlKTtcbiAgfVxuICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhwYXJzZWQgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKSB7XG4gICAgY29uc3QgdCA9IHR5cGVvZiB2O1xuICAgIGlmICh0ICE9PSAnc3RyaW5nJyAmJiB0ICE9PSAnbnVtYmVyJyAmJiB0ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYElucHV0IFwiJHtrfVwiIG11c3QgYmUgYSBzdHJpbmcsIG51bWJlciwgb3IgYm9vbGVhbiAoZ290ICR7dH0pYCwgJ2lucHV0cy1maWxlJywgZmlsZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBwYXJzZWQgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbj47XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHRlbXBsYXRlIGBuYW1lYCB0byBpdHMgaWQgdGhyb3VnaCB0aGUgY2F0YWxvZyBsaXN0IGVuZHBvaW50LiBUaGUgbGlzdFxuICogaXMgdmlzaWJpbGl0eS1zY29wZWQgc2VydmVyLXNpZGUsIHNvIHRoaXMgb25seSBldmVyIHNlZXMgdGVtcGxhdGVzIHRoZSBjYWxsZXJcbiAqIG1heSByZWFkLiBNYXRjaGluZyBpcyBleGFjdCBvbiBgbmFtZWAg4oCUIHRoZSBgbmFtZWAgcXVlcnkgcGFyYW0gaXMgYSBmaWx0ZXIsIG5vdFxuICogYSB1bmlxdWUgbG9va3VwLCBzbyBhIGZ1enp5IGJhY2tlbmQgbWF0Y2ggbXVzdCBub3Qgc2lsZW50bHkgaW5zdGFudGlhdGUgYVxuICogRElGRkVSRU5UIHRlbXBsYXRlIHRoYW4gdGhlIG9uZSBhc2tlZCBmb3IuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVUZW1wbGF0ZUJ5TmFtZShcbiAgY2xpZW50OiBSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50PixcbiAgbmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTxQaXBlbGluZVRlbXBsYXRlPiB7XG4gIGNvbnN0IHVybCA9IGNsaWVudC5nZXRDb25maWcoKS5hcGkucGlwZWxpbmVUZW1wbGF0ZVVybDtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuZ2V0KHVybCwgeyBuYW1lLCBsaW1pdDogMTAwIH0pO1xuICBjb25zdCB7IGl0ZW1zIH0gPSBleHRyYWN0TGlzdFJlc3BvbnNlPFBpcGVsaW5lVGVtcGxhdGU+KHJlc3BvbnNlLCAndGVtcGxhdGVzJyk7XG5cbiAgY29uc3QgZXhhY3QgPSBpdGVtcy5maWx0ZXIoKHQpID0+IHQubmFtZSA9PT0gbmFtZSk7XG4gIGlmIChleGFjdC5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgYE5vIHBpcGVsaW5lIHRlbXBsYXRlIG5hbWVkIFwiJHtuYW1lfVwiIGlzIHZpc2libGUgdG8geW91LmAsXG4gICAgICAnbmFtZScsIG5hbWUsIHVuZGVmaW5lZCxcbiAgICAgIGl0ZW1zLmxlbmd0aCA+IDBcbiAgICAgICAgPyBgRGlkIHlvdSBtZWFuIG9uZSBvZjogJHtpdGVtcy5zbGljZSgwLCAxMCkubWFwKCh0KSA9PiB0Lm5hbWUpLmpvaW4oJywgJyl9YFxuICAgICAgICA6ICdMb2FkIHRoZSBzYW1wbGUgY2F0YWxvZyB3aXRoIGRlcGxveS9iaW4vbG9hZC10ZW1wbGF0ZXMuc2gsIG9yIHBhc3MgLS1pZC4nLFxuICAgICk7XG4gIH1cbiAgLy8gQSBuYW1lIGlzIHVuaXF1ZSBwZXIgb3JnLCBidXQgdGhlIHZpc2libGUgc2V0IHNwYW5zIHlvdXIgb3JnICsgcGFyZW50ICsgdGhlXG4gIC8vIHN5c3RlbSBjYXRhbG9nLCBzbyB0aGUgc2FtZSBuYW1lIGNhbiBsZWdpdGltYXRlbHkgYXBwZWFyIG1vcmUgdGhhbiBvbmNlLlxuICAvLyBSZWZ1c2UgdG8gZ3Vlc3Mg4oCUIHRoZSB3cm9uZyBwaWNrIHdvdWxkIHNpbGVudGx5IHN5bnRoIHNvbWVvbmUgZWxzZSdzIGJvZHkuXG4gIGlmIChleGFjdC5sZW5ndGggPiAxKSB7XG4gICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgIGBcIiR7bmFtZX1cIiBtYXRjaGVzICR7ZXhhY3QubGVuZ3RofSB2aXNpYmxlIHRlbXBsYXRlcyDigJQgcGFzcyAtLWlkIHRvIGNob29zZSBvbmUuYCxcbiAgICAgICduYW1lJywgbmFtZSwgdW5kZWZpbmVkLFxuICAgICAgYGlkczogJHtleGFjdC5tYXAoKHQpID0+IHQuaWQpLmpvaW4oJywgJyl9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBleGFjdFswXSE7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIHRoZSBgdGVtcGxhdGUgaW5zdGFudGlhdGVgIGNvbW1hbmQuXG4gKlxuICogUmVuZGVycyBhIGdvbGRlbi1wYXRoIHRlbXBsYXRlIGludG8gYSBjb25jcmV0ZSBwaXBlbGluZSBgcHJvcHNgIGRvY3VtZW50IGJ5XG4gKiBzdXBwbHlpbmcgaXRzIGRlY2xhcmVkIGlucHV0cy4gSXQgKipjcmVhdGVzIG5vdGhpbmcqKiDigJQgdGhlIHJlbmRlcmVkIHByb3BzIGFyZVxuICogd3JpdHRlbiB0byBhIGZpbGUgKG9yIHN0ZG91dCkgYW5kIGdvIHRocm91Z2ggdGhlIG5vcm1hbCBgcGlwZWxpbmUgY3JlYXRlYCBwYXRoLFxuICogd2hlcmUgY29tcGxpYW5jZSBhbmQgcXVvdGEgc3RpbGwgYXBwbHkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGJhc2hcbiAqIHBpcGVsaW5lLW1hbmFnZXIgdGVtcGxhdGUgaW5zdGFudGlhdGUgLS1uYW1lIHJlYWN0LWphdmFzY3JpcHQgXFxcbiAqICAgLS1wcm9qZWN0IHJlYWN0IC0tb3JnYW5pemF0aW9uIEFjbWVDb3JwIFxcXG4gKiAgIC0taW5wdXQgb3JnSWQ9MTIzNGFiY2QtLi4uIC0tb3V0cHV0IHBpcGVsaW5lLXByb3BzLmpzb25cbiAqXG4gKiBwaXBlbGluZS1tYW5hZ2VyIHBpcGVsaW5lIGNyZWF0ZSAtLWZpbGUgcGlwZWxpbmUtcHJvcHMuanNvbiAtLWRlcGxveVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YW50aWF0ZVRlbXBsYXRlKHByb2dyYW06IENvbW1hbmQpOiB2b2lkIHtcbiAgd2l0aFNzbE9wdGlvbnMoXG4gICAgcHJvZ3JhbVxuICAgICAgLmNvbW1hbmQoJ2luc3RhbnRpYXRlJylcbiAgICAgIC5kZXNjcmlwdGlvbignUmVuZGVyIGEgcGlwZWxpbmUgdGVtcGxhdGUgaW50byBjb25jcmV0ZSBwaXBlbGluZSBwcm9wcyAoY3JlYXRlcyBub3RoaW5nKScpXG4gICAgICAub3B0aW9uKCctbiwgLS1uYW1lIDxuYW1lPicsICdUZW1wbGF0ZSBuYW1lIChyZXNvbHZlZCBhZ2FpbnN0IHRoZSBjYXRhbG9nIHlvdSBjYW4gc2VlKScpXG4gICAgICAub3B0aW9uKCctaSwgLS1pZCA8aWQ+JywgJ1RlbXBsYXRlIElEIChza2lwcyB0aGUgbmFtZSBsb29rdXApJylcbiAgICAgIC5yZXF1aXJlZE9wdGlvbignLXAsIC0tcHJvamVjdCA8cHJvamVjdD4nLCAnUHJvamVjdCBuYW1lIGZvciB0aGUgcGlwZWxpbmUgdGhpcyB0ZW1wbGF0ZSB3aWxsIHByb2R1Y2UnKVxuICAgICAgLnJlcXVpcmVkT3B0aW9uKCctbywgLS1vcmdhbml6YXRpb24gPG9yZ2FuaXphdGlvbj4nLCAnT3JnYW5pemF0aW9uIG5hbWUgZm9yIHRoZSBwaXBlbGluZScpXG4gICAgICAub3B0aW9uKCctLXBpcGVsaW5lLW5hbWUgPG5hbWU+JywgJ1BpcGVsaW5lIG5hbWUgKGRlZmF1bHRzIHRvIDxvcmdhbml6YXRpb24+LTxwcm9qZWN0Pi1waXBlbGluZSBhdCBzeW50aCknKVxuICAgICAgLm9wdGlvbignLS1pbnB1dCA8a2V5PXZhbHVlPicsICdUZW1wbGF0ZSBpbnB1dCwgcmVwZWF0YWJsZSAoZS5nLiAtLWlucHV0IG9yZ0lkPTEyMzRhYmNkLS4uLiknLCBjb2xsZWN0SW5wdXQsIFtdKVxuICAgICAgLm9wdGlvbignLS1pbnB1dHMtZmlsZSA8ZmlsZT4nLCAnSlNPTiBmaWxlIG9mIHsgXCJpbnB1dE5hbWVcIjogdmFsdWUgfSDigJQgbWVyZ2VkIFVOREVSIGFueSAtLWlucHV0IGZsYWdzJylcbiAgICAgIC5vcHRpb24oJy0tb3V0cHV0IDxmaWxlPicsICdXcml0ZSB0aGUgcmVuZGVyZWQgcHJvcHMgdG8gYSBmaWxlIChkZWZhdWx0OiBzdGRvdXQpJylcbiAgICAgIC5vcHRpb24oJy1mLCAtLWZvcm1hdCA8Zm9ybWF0PicsICdPdXRwdXQgZm9ybWF0IChqc29uLCB5YW1sKScsICdqc29uJyksXG4gIClcbiAgICAub3B0aW9uKCctLWpzb24nLCAnUHJpbnQgT05MWSB0aGUgcmVuZGVyZWQgcHJvcHMgYXMgSlNPTiAoZm9yIHBpcGluZyk7IGltcGxpZXMgbm8gZGVjb3JhdGl2ZSBvdXRwdXQnLCBmYWxzZSlcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRpb25zKSA9PiB7XG4gICAgICAvLyBXaXRoIC0tanNvbiAob3IgcHJvcHMgaGVhZGVkIGZvciBzdGRvdXQgaW4gYW55IGZvcm1hdCkgdGhlIHBheWxvYWQgSVMgdGhlXG4gICAgICAvLyBvdXRwdXQsIHNvIHRoZSBiYW5uZXIgbXVzdCBub3QgbGFuZCBvbiBzdGRvdXQgYWhlYWQgb2YgaXQgYW5kIGJyZWFrIHBpcGluZy5cbiAgICAgIGNvbnN0IHRvU3Rkb3V0ID0gIW9wdGlvbnMub3V0cHV0O1xuICAgICAgY29uc3QgcXVpZXQgPSBvcHRpb25zLmpzb24gfHwgdG9TdGRvdXQ7XG4gICAgICBjb25zdCBleGVjdXRpb25JZCA9IHByaW50Q29tbWFuZEhlYWRlcignSW5zdGFudGlhdGUgVGVtcGxhdGUnLCB1bmRlZmluZWQsIHsgcXVpZXQgfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghb3B0aW9ucy5uYW1lICYmICFvcHRpb25zLmlkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUHJvdmlkZSAtLW5hbWUgb3IgLS1pZCB0byBzZWxlY3QgYSB0ZW1wbGF0ZScsICduYW1lJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMubmFtZSAmJiBvcHRpb25zLmlkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUGFzcyBlaXRoZXIgLS1uYW1lIG9yIC0taWQsIG5vdCBib3RoJywgJ25hbWUnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPbmx5IHRoZSByb3VuZC10cmlwcGFibGUgZm9ybWF0czogdGhlIHJlbmRlcmVkIHByb3BzIGV4aXN0IHRvIGJlIGZlZFxuICAgICAgICAvLyBiYWNrIHRvIGBwaXBlbGluZSBjcmVhdGUgLS1maWxlYCwgYW5kIGB0YWJsZWAvYGNzdmAgd291bGQgZmxhdHRlbiB0aGVtXG4gICAgICAgIC8vIGludG8gc29tZXRoaW5nIHRoYXQgY2FuIG5vIGxvbmdlciBiZSBwYXJzZWQgYXMgcHJvcHMuXG4gICAgICAgIGlmICghWydqc29uJywgJ3lhbWwnXS5pbmNsdWRlcyhvcHRpb25zLmZvcm1hdCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgICAgYFVuc3VwcG9ydGVkIC0tZm9ybWF0IFwiJHtvcHRpb25zLmZvcm1hdH1cIiDigJQgcmVuZGVyZWQgcHJvcHMgbXVzdCBzdGF5IHBhcnNlYWJsZWAsXG4gICAgICAgICAgICAnZm9ybWF0Jywgb3B0aW9ucy5mb3JtYXQsICdqc29ufHlhbWwnLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFxdWlldCkgcHJpbnRTc2xXYXJuaW5nKG9wdGlvbnMudmVyaWZ5U3NsKTtcblxuICAgICAgICAvLyAtLWlucHV0IGZsYWdzIHdpbiBvdmVyIC0taW5wdXRzLWZpbGUgc28gYSBmaWxlIGNhbiBob2xkIHNoYXJlZCBkZWZhdWx0c1xuICAgICAgICAvLyB0aGF0IGEgc2luZ2xlIGZsYWcgb3ZlcnJpZGVzIG9uIHRoZSBjb21tYW5kIGxpbmUuXG4gICAgICAgIGNvbnN0IGlucHV0czogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbj4gPSB7XG4gICAgICAgICAgLi4uKG9wdGlvbnMuaW5wdXRzRmlsZSA/IHJlYWRJbnB1dHNGaWxlKG9wdGlvbnMuaW5wdXRzRmlsZSkgOiB7fSksXG4gICAgICAgICAgLi4ucGFyc2VJbnB1dFBhaXJzKG9wdGlvbnMuaW5wdXQgYXMgc3RyaW5nW10pLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghcXVpZXQpIHtcbiAgICAgICAgICBwcmludEluZm8oJ1JlcXVlc3QgcGFyYW1ldGVycycsIHtcbiAgICAgICAgICAgIHRlbXBsYXRlOiBvcHRpb25zLm5hbWUgPz8gb3B0aW9ucy5pZCxcbiAgICAgICAgICAgIHByb2plY3Q6IG9wdGlvbnMucHJvamVjdCxcbiAgICAgICAgICAgIG9yZ2FuaXphdGlvbjogb3B0aW9ucy5vcmdhbml6YXRpb24sXG4gICAgICAgICAgICBwaXBlbGluZU5hbWU6IG9wdGlvbnMucGlwZWxpbmVOYW1lID8/ICcoZGVmYXVsdCknLFxuICAgICAgICAgICAgaW5wdXRzOiBPYmplY3Qua2V5cyhpbnB1dHMpLmxlbmd0aCA+IDAgPyBPYmplY3Qua2V5cyhpbnB1dHMpLmpvaW4oJywgJykgOiAnKG5vbmUpJyxcbiAgICAgICAgICAgIG91dHB1dDogb3B0aW9ucy5vdXRwdXQgPz8gJyhzdGRvdXQpJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgICAgcHJpbnRTZWN0aW9uKCdSZW5kZXJpbmcgVGVtcGxhdGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsaWVudCA9IGNyZWF0ZUF1dGhlbnRpY2F0ZWRDbGllbnQob3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlVXJsID0gY2xpZW50LmdldENvbmZpZygpLmFwaS5waXBlbGluZVRlbXBsYXRlVXJsO1xuXG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIGNvbnN0IHNwaW5uZXIgPSBxdWlldCA/IG51bGwgOiBvcmEoJ1Jlc29sdmluZyB0ZW1wbGF0ZS4uLicpLnN0YXJ0KCk7XG4gICAgICAgIGxldCB0ZW1wbGF0ZUlkOiBzdHJpbmc7XG4gICAgICAgIGxldCB0ZW1wbGF0ZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBpZiAob3B0aW9ucy5pZCkge1xuICAgICAgICAgICAgdGVtcGxhdGVJZCA9IG9wdGlvbnMuaWQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlID0gYXdhaXQgcmVzb2x2ZVRlbXBsYXRlQnlOYW1lKGNsaWVudCwgb3B0aW9ucy5uYW1lKTtcbiAgICAgICAgICAgIHRlbXBsYXRlSWQgPSB0ZW1wbGF0ZS5pZDtcbiAgICAgICAgICAgIHRlbXBsYXRlTmFtZSA9IHRlbXBsYXRlLm5hbWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNwaW5uZXI/LnN1Y2NlZWQoYFRlbXBsYXRlIHJlc29sdmVkJHt0ZW1wbGF0ZU5hbWUgPyBgICgke3RlbXBsYXRlTmFtZX0pYCA6ICcnfWApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHNwaW5uZXI/LmZhaWwoJ1RlbXBsYXRlIHJlc29sdXRpb24gZmFpbGVkJyk7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBib2R5OiBJbnN0YW50aWF0ZVRlbXBsYXRlUmVxdWVzdCA9IHtcbiAgICAgICAgICBwcm9qZWN0OiBvcHRpb25zLnByb2plY3QsXG4gICAgICAgICAgb3JnYW5pemF0aW9uOiBvcHRpb25zLm9yZ2FuaXphdGlvbixcbiAgICAgICAgICAuLi4ob3B0aW9ucy5waXBlbGluZU5hbWUgPyB7IHBpcGVsaW5lTmFtZTogb3B0aW9ucy5waXBlbGluZU5hbWUgfSA6IHt9KSxcbiAgICAgICAgICAuLi4oT2JqZWN0LmtleXMoaW5wdXRzKS5sZW5ndGggPiAwID8geyBpbnB1dHMgfSA6IHt9KSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZW5kZXJTcGlubmVyID0gcXVpZXQgPyBudWxsIDogb3JhKCdJbnN0YW50aWF0aW5nLi4uJykuc3RhcnQoKTtcbiAgICAgICAgbGV0IHJlbmRlcmVkOiBJbnN0YW50aWF0ZVRlbXBsYXRlUmVzcG9uc2UgfCB1bmRlZmluZWQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucG9zdChgJHt0ZW1wbGF0ZVVybH0vJHtlbmNvZGVVUklDb21wb25lbnQodGVtcGxhdGVJZCl9L2luc3RhbnRpYXRlYCwgYm9keSk7XG4gICAgICAgICAgLy8gYHByb3BzYCBpcyB0aGUgaWRlbnRpZmllciBrZXk6IHRoZSBlbnZlbG9wZSdzIGRhdGEgSVMgeyBwcm9wcywgLi4uIH0uXG4gICAgICAgICAgcmVuZGVyZWQgPSBleHRyYWN0U2luZ2xlUmVzcG9uc2U8SW5zdGFudGlhdGVUZW1wbGF0ZVJlc3BvbnNlPihyZXNwb25zZSwgJ3RlbXBsYXRlJywgJ3Byb3BzJyk7XG4gICAgICAgICAgcmVuZGVyU3Bpbm5lcj8uc3VjY2VlZCgnVGVtcGxhdGUgaW5zdGFudGlhdGVkJyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVuZGVyU3Bpbm5lcj8uZmFpbCgnSW5zdGFudGlhdGUgZmFpbGVkJyk7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xuXG4gICAgICAgIGlmICghcmVuZGVyZWQ/LnByb3BzKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignTm8gcHJvcHMgcmV0dXJuZWQgZnJvbSBBUEknLCB7IHRlbXBsYXRlSWQgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW1wbGF0ZSAke3RlbXBsYXRlSWR9IHJlbmRlcmVkIG5vIHByb3BzYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvcHMgPSByZW5kZXJlZC5wcm9wcyBhcyBQaXBlbGluZVByb3BzO1xuXG4gICAgICAgIC8vIEEgbGVmdG92ZXIgYHt7IC4uLiB9fWAgaW4gYSAqc2VsZi1zY29wZSogZmllbGQgbWVhbnMgYW4gaW5wdXQgd2FzIG5ldmVyXG4gICAgICAgIC8vIHN1cHBsaWVkIGFuZCB0aGUgcGxhY2Vob2xkZXIgd291bGQgZmFpbCBvcGFxdWVseSBhdCBzeW50aC4gYHBpcGVsaW5lLipgXG4gICAgICAgIC8vIHRva2VucyBhcmUgZXhwZWN0ZWQgaGVyZSDigJQgdGhleSByZXNvbHZlIGF0IHN5bnRoLCBub3QgYXQgaW5zdGFudGlhdGUuXG4gICAgICAgIGNvbnN0IHVucmVzb2x2ZWQgPSB1bnJlc29sdmVkU2VsZlZhcnMocHJvcHMpO1xuICAgICAgICBpZiAodW5yZXNvbHZlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcHJpbnRXYXJuaW5nKCdSZW5kZXJlZCBwcm9wcyBzdGlsbCBjb250YWluIHVucmVzb2x2ZWQgcGxhY2Vob2xkZXJzJywge1xuICAgICAgICAgICAgdmFyczogdW5yZXNvbHZlZC5qb2luKCcsICcpLFxuICAgICAgICAgICAgaGludDogJ1N1cHBseSB0aGVtIHdpdGggLS1pbnB1dCA8bmFtZT49PHZhbHVlPicsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXF1aWV0KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50U2VjdGlvbignUmVuZGVyZWQgUHJvcHMnKTtcbiAgICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAgICdUZW1wbGF0ZSc6IGdyZWVuKGJvbGQodGVtcGxhdGVOYW1lID8/IHRlbXBsYXRlSWQpKSxcbiAgICAgICAgICAgICdQcm9qZWN0JzogcHJvcHMucHJvamVjdCBhcyBzdHJpbmcsXG4gICAgICAgICAgICAnT3JnYW5pemF0aW9uJzogcHJvcHMub3JnYW5pemF0aW9uIGFzIHN0cmluZyxcbiAgICAgICAgICAgICdQaXBlbGluZSBOYW1lJzogKHByb3BzLnBpcGVsaW5lTmFtZSBhcyBzdHJpbmcpID8/IGRpbSgnKGRlZmF1bHQgYXQgc3ludGgpJyksXG4gICAgICAgICAgICAnVmFycyc6IE9iamVjdC5rZXlzKChwcm9wcy52YXJzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA/PyB7fSkuam9pbignLCAnKSB8fCBkaW0oJyhub25lKScpLFxuICAgICAgICAgICAgJ1N0YWdlcyc6IFN0cmluZyhBcnJheS5pc0FycmF5KHByb3BzLnN0YWdlcykgPyBwcm9wcy5zdGFnZXMubGVuZ3RoIDogMCksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcHJpbnRFeGVjdXRpb25TdW1tYXJ5KGV4ZWN1dGlvbklkLCBkdXJhdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBvdXRwdXREYXRhKHByb3BzLCB7XG4gICAgICAgICAgZm9ybWF0OiBvcHRpb25zLmpzb24gPyAnanNvbicgOiBvcHRpb25zLmZvcm1hdCxcbiAgICAgICAgICBmaWxlOiBvcHRpb25zLm91dHB1dCxcbiAgICAgICAgICBzaWxlbnQ6IHF1aWV0LFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAob3B0aW9ucy5vdXRwdXQgJiYgIXF1aWV0KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50U3VjY2VzcygnUGlwZWxpbmUgcHJvcHMgc2F2ZWQnLCB7IHBhdGg6IG9wdGlvbnMub3V0cHV0IH0pO1xuICAgICAgICAgIHByaW50SW5mbygnTmV4dCBzdGVwJywge1xuICAgICAgICAgICAgY29tbWFuZDogYHBpcGVsaW5lLW1hbmFnZXIgcGlwZWxpbmUgY3JlYXRlIC0tZmlsZSAke29wdGlvbnMub3V0cHV0fSAtLWRlcGxveWAsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc29sZS5sb2coZGltKGAgICR7Y3lhbignVGlwOicpfSBpbnN0YW50aWF0ZSBvbmx5IHJlbmRlcnMg4oCUIG5vdGhpbmcgZXhpc3RzIG9uIHRoZSBwbGF0Zm9ybSB5ZXQuYCkpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBoYW5kbGVFcnJvcihlcnJvciwgRVJST1JfQ09ERVMuQVBJX1JFUVVFU1QsIHtcbiAgICAgICAgICBkZWJ1ZzogcHJvZ3JhbS5vcHRzKCkuZGVidWcsXG4gICAgICAgICAgZXhpdDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7IGNvbW1hbmQ6ICdpbnN0YW50aWF0ZS10ZW1wbGF0ZScsIGV4ZWN1dGlvbklkLCB0ZW1wbGF0ZTogb3B0aW9ucy5uYW1lID8/IG9wdGlvbnMuaWQgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG59XG5cbi8qKlxuICogTmFtZXMgb2YgYHt7IHZhcnMuWCB9fWAgcGxhY2Vob2xkZXJzIHN0aWxsIHByZXNlbnQgaW4gdGhlIHJlbmRlcmVkIHByb3BzJyBvd25cbiAqIHNlbGYtc2NvcGUgZmllbGRzIChgcHJvamVjdGAsIGBtZXRhZGF0YS4qYCwgYHZhcnMuKmApIOKAlCBpLmUuIGlucHV0cyB0aGUgY2FsbGVyXG4gKiBuZXZlciBzdXBwbGllZC4gYHt7IHBpcGVsaW5lLiogfX1gIHRva2VucyBhcmUgZGVsaWJlcmF0ZWx5IGlnbm9yZWQ6IHRob3NlIGFyZVxuICogc3ludGgtdGltZSByZWZlcmVuY2VzIChlLmcuIHRoZSBHaXRIdWIgc291cmNlIHRva2VuKSBhbmQgYXJlIFNVUFBPU0VEIHRvXG4gKiBzdXJ2aXZlIGluc3RhbnRpYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHVucmVzb2x2ZWRTZWxmVmFycyhwcm9wczogUGlwZWxpbmVQcm9wcyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgZm91bmQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3Qgc2NhbiA9ICh2YWx1ZTogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmb3IgKGNvbnN0IG0gb2YgdmFsdWUubWF0Y2hBbGwoL1xce1xce1xccyp2YXJzXFwuKFtBLVphLXpfXVtBLVphLXowLTlfXSopL2cpKSBmb3VuZC5hZGQobVsxXSEpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZS5mb3JFYWNoKHNjYW4pO1xuICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSByZXR1cm4gT2JqZWN0LnZhbHVlcyh2YWx1ZSkuZm9yRWFjaChzY2FuKTtcbiAgfTtcbiAgc2Nhbihwcm9wcy5wcm9qZWN0KTtcbiAgc2Nhbihwcm9wcy5tZXRhZGF0YSk7XG4gIHNjYW4ocHJvcHMudmFycyk7XG4gIHJldHVybiBbLi4uZm91bmRdO1xufVxuIl19
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Registers the `list-pipelines` command with the CLI program.
|
|
4
|
+
*
|
|
5
|
+
* Queries pipelines with filters for project, organization, name,
|
|
6
|
+
* access modifier, active/default status, plus pagination and sorting.
|
|
7
|
+
*
|
|
8
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```bash
|
|
12
|
+
* cli pipeline list
|
|
13
|
+
* cli pipeline list --project my-app --is-active true
|
|
14
|
+
* cli pipeline list --organization my-org
|
|
15
|
+
* cli pipeline list --limit 50 --offset 100 --sort "pipelineName:asc"
|
|
16
|
+
* cli pipeline list --format json --output pipelines.json
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function listPipelines(program: Command): void;
|
|
20
|
+
//# sourceMappingURL=list-pipelines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-pipelines.d.ts","sourceRoot":"","sources":["../../src/commands/list-pipelines.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgEpD"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { runListEntity } from './entity-list.js';
|
|
5
|
+
import { validateBoolean } from '../config/cli.constants.js';
|
|
6
|
+
import {} from '../types/index.js';
|
|
7
|
+
import { withSslOptions } from '../utils/command-utils.js';
|
|
8
|
+
import {} from '../utils/list-command-utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Registers the `list-pipelines` command with the CLI program.
|
|
11
|
+
*
|
|
12
|
+
* Queries pipelines with filters for project, organization, name,
|
|
13
|
+
* access modifier, active/default status, plus pagination and sorting.
|
|
14
|
+
*
|
|
15
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```bash
|
|
19
|
+
* cli pipeline list
|
|
20
|
+
* cli pipeline list --project my-app --is-active true
|
|
21
|
+
* cli pipeline list --organization my-org
|
|
22
|
+
* cli pipeline list --limit 50 --offset 100 --sort "pipelineName:asc"
|
|
23
|
+
* cli pipeline list --format json --output pipelines.json
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function listPipelines(program) {
|
|
27
|
+
withSslOptions(program
|
|
28
|
+
.command('list')
|
|
29
|
+
.description('Query pipelines with comprehensive filters')
|
|
30
|
+
// Common filter options
|
|
31
|
+
.option('--id <id>', 'Filter by pipeline ID (can specify multiple with commas)')
|
|
32
|
+
.option('--visibility <rung>', 'Filter by sharing rung (private/org/public)')
|
|
33
|
+
.option('--is-default <boolean>', 'Filter by default status (true/false)')
|
|
34
|
+
.option('--is-active <boolean>', 'Filter by active status (true/false)')
|
|
35
|
+
.option('--limit <number>', 'Maximum number of results (1-1000)', (v) => parseInt(v, 10), 50)
|
|
36
|
+
.option('--offset <number>', 'Number of results to skip', (v) => parseInt(v, 10), 0)
|
|
37
|
+
.option('--sort <sort>', 'Sort format: field:direction (e.g., pipelineName:asc, createdAt:desc)')
|
|
38
|
+
// Pipeline-specific filter options
|
|
39
|
+
.option('--project <project>', 'Filter by exact project name')
|
|
40
|
+
.option('--organization <organization>', 'Filter by exact organization name')
|
|
41
|
+
.option('--pipeline-name <name>', 'Filter by exact pipeline name')
|
|
42
|
+
// Output options
|
|
43
|
+
.option('-f, --format <format>', 'Output format (json, yaml, table, csv)', 'table')
|
|
44
|
+
.option('-o, --output <file>', 'Save output to file')
|
|
45
|
+
.option('--show-props', 'Include pipeline properties in output (json/yaml only)', false))
|
|
46
|
+
.action((options) => runListEntity(program, options, {
|
|
47
|
+
labelPlural: 'Pipelines',
|
|
48
|
+
responseKey: 'pipelines',
|
|
49
|
+
listUrl: (config) => config.api.pipelineListUrl,
|
|
50
|
+
commandName: 'list-pipelines',
|
|
51
|
+
buildFilters: (options, base) => {
|
|
52
|
+
const filters = { ...base };
|
|
53
|
+
if (options.visibility)
|
|
54
|
+
filters.visibility = options.visibility;
|
|
55
|
+
if (options.isDefault !== undefined)
|
|
56
|
+
filters.isDefault = validateBoolean(options.isDefault, 'is-default');
|
|
57
|
+
if (options.project)
|
|
58
|
+
filters.project = options.project;
|
|
59
|
+
if (options.organization)
|
|
60
|
+
filters.organization = options.organization;
|
|
61
|
+
if (options.pipelineName)
|
|
62
|
+
filters.pipelineName = options.pipelineName;
|
|
63
|
+
return filters;
|
|
64
|
+
},
|
|
65
|
+
activeFilters: (filters) => {
|
|
66
|
+
const active = {};
|
|
67
|
+
if (filters.id)
|
|
68
|
+
active.ID = filters.id;
|
|
69
|
+
if (filters.visibility)
|
|
70
|
+
active.Visibility = filters.visibility;
|
|
71
|
+
if (filters.isDefault !== undefined)
|
|
72
|
+
active['Is Default'] = filters.isDefault;
|
|
73
|
+
if (filters.isActive !== undefined)
|
|
74
|
+
active['Is Active'] = filters.isActive;
|
|
75
|
+
if (filters.project)
|
|
76
|
+
active.Project = filters.project;
|
|
77
|
+
if (filters.organization)
|
|
78
|
+
active.Organization = filters.organization;
|
|
79
|
+
if (filters.pipelineName)
|
|
80
|
+
active['Pipeline Name'] = filters.pipelineName;
|
|
81
|
+
return active;
|
|
82
|
+
},
|
|
83
|
+
statistics: (pipelines) => ({
|
|
84
|
+
'Active Pipelines': `${pipelines.filter(p => p.isActive).length}/${pipelines.length}`,
|
|
85
|
+
'Default Pipelines': `${pipelines.filter(p => p.isDefault).length}/${pipelines.length}`,
|
|
86
|
+
}),
|
|
87
|
+
rows: (pipelines, options) => options.showProps ? pipelines : pipelines.map(p => ({
|
|
88
|
+
'ID': p.id,
|
|
89
|
+
'Project': p.project,
|
|
90
|
+
'Organization': p.organization,
|
|
91
|
+
'Name': p.pipelineName || 'N/A',
|
|
92
|
+
'Visibility': p.visibility || 'private',
|
|
93
|
+
'Default': p.isDefault ? 'Yes' : 'No',
|
|
94
|
+
'Active': p.isActive ? 'Yes' : 'No',
|
|
95
|
+
'Created At': p.createdAt || 'N/A',
|
|
96
|
+
})),
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1waXBlbGluZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvbGlzdC1waXBlbGluZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFpQixNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQTJCLE1BQU0sZ0NBQWdDLENBQUM7QUFnQnpFOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxPQUFnQjtJQUM1QyxjQUFjLENBQUMsT0FBTztTQUNuQixPQUFPLENBQUMsTUFBTSxDQUFDO1NBQ2YsV0FBVyxDQUFDLDRDQUE0QyxDQUFDO1FBRTFELHdCQUF3QjtTQUN2QixNQUFNLENBQUMsV0FBVyxFQUFFLDBEQUEwRCxDQUFDO1NBQy9FLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSw2Q0FBNkMsQ0FBQztTQUM1RSxNQUFNLENBQUMsd0JBQXdCLEVBQUUsdUNBQXVDLENBQUM7U0FDekUsTUFBTSxDQUFDLHVCQUF1QixFQUFFLHNDQUFzQyxDQUFDO1NBQ3ZFLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxvQ0FBb0MsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7U0FDNUYsTUFBTSxDQUFDLG1CQUFtQixFQUFFLDJCQUEyQixFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FB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QUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sSUFBSSxTQUFTLENBQUMsTUFBTSxFQUFFO1lBQ3JGLG1CQUFtQixFQUFFLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRTtTQUN4RixDQUFDO1FBQ0YsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoRixJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUU7WUFDVixTQUFTLEVBQUUsQ0FBQyxDQUFDLE9BQU87WUFDcEIsY0FBYyxFQUFFLENBQUMsQ0FBQyxZQUFZO1lBQzlCLE1BQU0sRUFBRSxDQUFDLENBQUMsWUFBWSxJQUFJLEtBQUs7WUFDL0IsWUFBWSxFQUFFLENBQUMsQ0FBQyxVQUFVLElBQUksU0FBUztZQUN2QyxTQUFTLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ3JDLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDbkMsWUFBWSxFQUFFLENBQUMsQ0FBQyxTQUFTLElBQUksS0FBSztTQUNuQyxDQUFDLENBQUM7S0FDSixDQUFDLENBQUMsQ0FBQztBQUNSLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBydW5MaXN0RW50aXR5IH0gZnJvbSAnLi9lbnRpdHktbGlzdC5qcyc7XG5pbXBvcnQgeyB2YWxpZGF0ZUJvb2xlYW4gfSBmcm9tICcuLi9jb25maWcvY2xpLmNvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyB0eXBlIFBpcGVsaW5lIH0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuaW1wb3J0IHsgd2l0aFNzbE9wdGlvbnMgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IHR5cGUgQ29tbW9uRmlsdGVyUGFyYW1zIH0gZnJvbSAnLi4vdXRpbHMvbGlzdC1jb21tYW5kLXV0aWxzLmpzJztcblxuLyoqXG4gKiBRdWVyeSBwYXJhbWV0ZXJzIGZvciB0aGUgcGlwZWxpbmUgbGlzdCBBUEkgZW5kcG9pbnQuXG4gKiBDb21iaW5lcyBjb21tb24gZmlsdGVycyAocGFnaW5hdGlvbiwgc29ydCwgYWNjZXNzKSB3aXRoIHBpcGVsaW5lLXNwZWNpZmljIGZpbHRlcnMuXG4gKi9cbmludGVyZmFjZSBQaXBlbGluZUZpbHRlclBhcmFtcyBleHRlbmRzIENvbW1vbkZpbHRlclBhcmFtcyB7XG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW47XG5cbiAgLy8gUGlwZWxpbmUtc3BlY2lmaWMgZmlsdGVyc1xuICBwcm9qZWN0Pzogc3RyaW5nO1xuICBvcmdhbml6YXRpb24/OiBzdHJpbmc7XG4gIHBpcGVsaW5lTmFtZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIGBsaXN0LXBpcGVsaW5lc2AgY29tbWFuZCB3aXRoIHRoZSBDTEkgcHJvZ3JhbS5cbiAqXG4gKiBRdWVyaWVzIHBpcGVsaW5lcyB3aXRoIGZpbHRlcnMgZm9yIHByb2plY3QsIG9yZ2FuaXphdGlvbiwgbmFtZSxcbiAqIGFjY2VzcyBtb2RpZmllciwgYWN0aXZlL2RlZmF1bHQgc3RhdHVzLCBwbHVzIHBhZ2luYXRpb24gYW5kIHNvcnRpbmcuXG4gKlxuICogQHBhcmFtIHByb2dyYW0gLSBUaGUgcm9vdCBDb21tYW5kZXIgcHJvZ3JhbSBpbnN0YW5jZSB0byBhdHRhY2ggdGhlIGNvbW1hbmQgdG8uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGJhc2hcbiAqIGNsaSBwaXBlbGluZSBsaXN0XG4gKiBjbGkgcGlwZWxpbmUgbGlzdCAtLXByb2plY3QgbXktYXBwIC0taXMtYWN0aXZlIHRydWVcbiAqIGNsaSBwaXBlbGluZSBsaXN0IC0tb3JnYW5pemF0aW9uIG15LW9yZ1xuICogY2xpIHBpcGVsaW5lIGxpc3QgLS1saW1pdCA1MCAtLW9mZnNldCAxMDAgLS1zb3J0IFwicGlwZWxpbmVOYW1lOmFzY1wiXG4gKiBjbGkgcGlwZWxpbmUgbGlzdCAtLWZvcm1hdCBqc29uIC0tb3V0cHV0IHBpcGVsaW5lcy5qc29uXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RQaXBlbGluZXMocHJvZ3JhbTogQ29tbWFuZCk6IHZvaWQge1xuICB3aXRoU3NsT3B0aW9ucyhwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2xpc3QnKVxuICAgIC5kZXNjcmlwdGlvbignUXVlcnkgcGlwZWxpbmVzIHdpdGggY29tcHJlaGVuc2l2ZSBmaWx0ZXJzJylcblxuICAgIC8vIENvbW1vbiBmaWx0ZXIgb3B0aW9uc1xuICAgIC5vcHRpb24oJy0taWQgPGlkPicsICdGaWx0ZXIgYnkgcGlwZWxpbmUgSUQgKGNhbiBzcGVjaWZ5IG11bHRpcGxlIHdpdGggY29tbWFzKScpXG4gICAgLm9wdGlvbignLS12aXNpYmlsaXR5IDxydW5nPicsICdGaWx0ZXIgYnkgc2hhcmluZyBydW5nIChwcml2YXRlL29yZy9wdWJsaWMpJylcbiAgICAub3B0aW9uKCctLWlzLWRlZmF1bHQgPGJvb2xlYW4+JywgJ0ZpbHRlciBieSBkZWZhdWx0IHN0YXR1cyAodHJ1ZS9mYWxzZSknKVxuICAgIC5vcHRpb24oJy0taXMtYWN0aXZlIDxib29sZWFuPicsICdGaWx0ZXIgYnkgYWN0aXZlIHN0YXR1cyAodHJ1ZS9mYWxzZSknKVxuICAgIC5vcHRpb24oJy0tbGltaXQgPG51bWJlcj4nLCAnTWF4aW11bSBudW1iZXIgb2YgcmVzdWx0cyAoMS0xMDAwKScsICh2KSA9PiBwYXJzZUludCh2LCAxMCksIDUwKVxuICAgIC5vcHRpb24oJy0tb2Zmc2V0IDxudW1iZXI+JywgJ051bWJlciBvZiByZXN1bHRzIHRvIHNraXAnLCAodikgPT4gcGFyc2VJbnQodiwgMTApLCAwKVxuICAgIC5vcHRpb24oJy0tc29ydCA8c29ydD4nLCAnU29ydCBmb3JtYXQ6IGZpZWxkOmRpcmVjdGlvbiAoZS5nLiwgcGlwZWxpbmVOYW1lOmFzYywgY3JlYXRlZEF0OmRlc2MpJylcblxuICAgIC8vIFBpcGVsaW5lLXNwZWNpZmljIGZpbHRlciBvcHRpb25zXG4gICAgLm9wdGlvbignLS1wcm9qZWN0IDxwcm9qZWN0PicsICdGaWx0ZXIgYnkgZXhhY3QgcHJvamVjdCBuYW1lJylcbiAgICAub3B0aW9uKCctLW9yZ2FuaXphdGlvbiA8b3JnYW5pemF0aW9uPicsICdGaWx0ZXIgYnkgZXhhY3Qgb3JnYW5pemF0aW9uIG5hbWUnKVxuICAgIC5vcHRpb24oJy0tcGlwZWxpbmUtbmFtZSA8bmFtZT4nLCAnRmlsdGVyIGJ5IGV4YWN0IHBpcGVsaW5lIG5hbWUnKVxuXG4gICAgLy8gT3V0cHV0IG9wdGlvbnNcbiAgICAub3B0aW9uKCctZiwgLS1mb3JtYXQgPGZvcm1hdD4nLCAnT3V0cHV0IGZvcm1hdCAoanNvbiwgeWFtbCwgdGFibGUsIGNzdiknLCAndGFibGUnKVxuICAgIC5vcHRpb24oJy1vLCAtLW91dHB1dCA8ZmlsZT4nLCAnU2F2ZSBvdXRwdXQgdG8gZmlsZScpXG4gICAgLm9wdGlvbignLS1zaG93LXByb3BzJywgJ0luY2x1ZGUgcGlwZWxpbmUgcHJvcGVydGllcyBpbiBvdXRwdXQgKGpzb24veWFtbCBvbmx5KScsIGZhbHNlKSlcblxuICAgIC5hY3Rpb24oKG9wdGlvbnMpID0+IHJ1bkxpc3RFbnRpdHk8UGlwZWxpbmUsIFBpcGVsaW5lRmlsdGVyUGFyYW1zPihwcm9ncmFtLCBvcHRpb25zLCB7XG4gICAgICBsYWJlbFBsdXJhbDogJ1BpcGVsaW5lcycsXG4gICAgICByZXNwb25zZUtleTogJ3BpcGVsaW5lcycsXG4gICAgICBsaXN0VXJsOiAoY29uZmlnKSA9PiBjb25maWcuYXBpLnBpcGVsaW5lTGlzdFVybCxcbiAgICAgIGNvbW1hbmROYW1lOiAnbGlzdC1waXBlbGluZXMnLFxuICAgICAgYnVpbGRGaWx0ZXJzOiAob3B0aW9ucywgYmFzZSkgPT4ge1xuICAgICAgICBjb25zdCBmaWx0ZXJzOiBQaXBlbGluZUZpbHRlclBhcmFtcyA9IHsgLi4uYmFzZSB9O1xuICAgICAgICBpZiAob3B0aW9ucy52aXNpYmlsaXR5KSBmaWx0ZXJzLnZpc2liaWxpdHkgPSBvcHRpb25zLnZpc2liaWxpdHkgYXMgc3RyaW5nO1xuICAgICAgICBpZiAob3B0aW9ucy5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkgZmlsdGVycy5pc0RlZmF1bHQgPSB2YWxpZGF0ZUJvb2xlYW4ob3B0aW9ucy5pc0RlZmF1bHQgYXMgc3RyaW5nLCAnaXMtZGVmYXVsdCcpO1xuICAgICAgICBpZiAob3B0aW9ucy5wcm9qZWN0KSBmaWx0ZXJzLnByb2plY3QgPSBvcHRpb25zLnByb2plY3QgYXMgc3RyaW5nO1xuICAgICAgICBpZiAob3B0aW9ucy5vcmdhbml6YXRpb24pIGZpbHRlcnMub3JnYW5pemF0aW9uID0gb3B0aW9ucy5vcmdhbml6YXRpb24gYXMgc3RyaW5nO1xuICAgICAgICBpZiAob3B0aW9ucy5waXBlbGluZU5hbWUpIGZpbHRlcnMucGlwZWxpbmVOYW1lID0gb3B0aW9ucy5waXBlbGluZU5hbWUgYXMgc3RyaW5nO1xuICAgICAgICByZXR1cm4gZmlsdGVycztcbiAgICAgIH0sXG4gICAgICBhY3RpdmVGaWx0ZXJzOiAoZmlsdGVycykgPT4ge1xuICAgICAgICBjb25zdCBhY3RpdmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgICAgIGlmIChmaWx0ZXJzLmlkKSBhY3RpdmUuSUQgPSBmaWx0ZXJzLmlkO1xuICAgICAgICBpZiAoZmlsdGVycy52aXNpYmlsaXR5KSBhY3RpdmUuVmlzaWJpbGl0eSA9IGZpbHRlcnMudmlzaWJpbGl0eTtcbiAgICAgICAgaWYgKGZpbHRlcnMuaXNEZWZhdWx0ICE9PSB1bmRlZmluZWQpIGFjdGl2ZVsnSXMgRGVmYXVsdCddID0gZmlsdGVycy5pc0RlZmF1bHQ7XG4gICAgICAgIGlmIChmaWx0ZXJzLmlzQWN0aXZlICE9PSB1bmRlZmluZWQpIGFjdGl2ZVsnSXMgQWN0aXZlJ10gPSBmaWx0ZXJzLmlzQWN0aXZlO1xuICAgICAgICBpZiAoZmlsdGVycy5wcm9qZWN0KSBhY3RpdmUuUHJvamVjdCA9IGZpbHRlcnMucHJvamVjdDtcbiAgICAgICAgaWYgKGZpbHRlcnMub3JnYW5pemF0aW9uKSBhY3RpdmUuT3JnYW5pemF0aW9uID0gZmlsdGVycy5vcmdhbml6YXRpb247XG4gICAgICAgIGlmIChmaWx0ZXJzLnBpcGVsaW5lTmFtZSkgYWN0aXZlWydQaXBlbGluZSBOYW1lJ10gPSBmaWx0ZXJzLnBpcGVsaW5lTmFtZTtcbiAgICAgICAgcmV0dXJuIGFjdGl2ZTtcbiAgICAgIH0sXG4gICAgICBzdGF0aXN0aWNzOiAocGlwZWxpbmVzKSA9PiAoe1xuICAgICAgICAnQWN0aXZlIFBpcGVsaW5lcyc6IGAke3BpcGVsaW5lcy5maWx0ZXIocCA9PiBwLmlzQWN0aXZlKS5sZW5ndGh9LyR7cGlwZWxpbmVzLmxlbmd0aH1gLFxuICAgICAgICAnRGVmYXVsdCBQaXBlbGluZXMnOiBgJHtwaXBlbGluZXMuZmlsdGVyKHAgPT4gcC5pc0RlZmF1bHQpLmxlbmd0aH0vJHtwaXBlbGluZXMubGVuZ3RofWAsXG4gICAgICB9KSxcbiAgICAgIHJvd3M6IChwaXBlbGluZXMsIG9wdGlvbnMpID0+IG9wdGlvbnMuc2hvd1Byb3BzID8gcGlwZWxpbmVzIDogcGlwZWxpbmVzLm1hcChwID0+ICh7XG4gICAgICAgICdJRCc6IHAuaWQsXG4gICAgICAgICdQcm9qZWN0JzogcC5wcm9qZWN0LFxuICAgICAgICAnT3JnYW5pemF0aW9uJzogcC5vcmdhbml6YXRpb24sXG4gICAgICAgICdOYW1lJzogcC5waXBlbGluZU5hbWUgfHwgJ04vQScsXG4gICAgICAgICdWaXNpYmlsaXR5JzogcC52aXNpYmlsaXR5IHx8ICdwcml2YXRlJyxcbiAgICAgICAgJ0RlZmF1bHQnOiBwLmlzRGVmYXVsdCA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgJ0FjdGl2ZSc6IHAuaXNBY3RpdmUgPyAnWWVzJyA6ICdObycsXG4gICAgICAgICdDcmVhdGVkIEF0JzogcC5jcmVhdGVkQXQgfHwgJ04vQScsXG4gICAgICB9KSksXG4gICAgfSkpO1xufVxuIl19
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Registers the `list-plugins` command with the CLI program.
|
|
4
|
+
*
|
|
5
|
+
* Queries plugins with filters for name, version, image tag,
|
|
6
|
+
* active status, plus pagination and sorting.
|
|
7
|
+
*
|
|
8
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```bash
|
|
12
|
+
* cli plugin list
|
|
13
|
+
* cli plugin list --name auth-plugin --is-active true
|
|
14
|
+
* cli plugin list --version "^1.0.0"
|
|
15
|
+
* cli plugin list --limit 50 --offset 100 --sort "name:asc"
|
|
16
|
+
* cli plugin list --format json --output plugins.json
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function listPlugins(program: Command): void;
|
|
20
|
+
//# sourceMappingURL=list-plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-plugins.d.ts","sourceRoot":"","sources":["../../src/commands/list-plugins.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+DlD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { runListEntity } from './entity-list.js';
|
|
5
|
+
import { formatFileSize } from '../config/cli.constants.js';
|
|
6
|
+
import {} from '../types/index.js';
|
|
7
|
+
import { withSslOptions } from '../utils/command-utils.js';
|
|
8
|
+
import {} from '../utils/list-command-utils.js';
|
|
9
|
+
import { printWarning } from '../utils/output-utils.js';
|
|
10
|
+
/**
|
|
11
|
+
* Registers the `list-plugins` command with the CLI program.
|
|
12
|
+
*
|
|
13
|
+
* Queries plugins with filters for name, version, image tag,
|
|
14
|
+
* active status, plus pagination and sorting.
|
|
15
|
+
*
|
|
16
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```bash
|
|
20
|
+
* cli plugin list
|
|
21
|
+
* cli plugin list --name auth-plugin --is-active true
|
|
22
|
+
* cli plugin list --version "^1.0.0"
|
|
23
|
+
* cli plugin list --limit 50 --offset 100 --sort "name:asc"
|
|
24
|
+
* cli plugin list --format json --output plugins.json
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function listPlugins(program) {
|
|
28
|
+
withSslOptions(program
|
|
29
|
+
.command('list')
|
|
30
|
+
.description('Query plugins with comprehensive filters')
|
|
31
|
+
// Common filter options
|
|
32
|
+
.option('--id <id>', 'Filter by plugin ID (can specify multiple with commas)')
|
|
33
|
+
.option('--is-active <boolean>', 'Filter by active status (true/false)')
|
|
34
|
+
.option('--limit <number>', 'Maximum number of results (1-1000)', (v) => parseInt(v, 10), 50)
|
|
35
|
+
.option('--offset <number>', 'Number of results to skip', (v) => parseInt(v, 10), 0)
|
|
36
|
+
.option('--sort <sort>', 'Sort format: field:direction (e.g., name:asc, createdAt:desc)')
|
|
37
|
+
// Plugin-specific filter options
|
|
38
|
+
.option('--name <name>', 'Filter by exact plugin name')
|
|
39
|
+
.option('--version <version>', 'Filter by version (supports semver, e.g., "^1.0.0")')
|
|
40
|
+
// Output options
|
|
41
|
+
.option('-f, --format <format>', 'Output format (json, yaml, table, csv)', 'table')
|
|
42
|
+
.option('-o, --output <file>', 'Save output to file')
|
|
43
|
+
.option('--show-metadata', 'Include full metadata in output (json/yaml only)', false))
|
|
44
|
+
.action((options) => runListEntity(program, options, {
|
|
45
|
+
labelPlural: 'Plugins',
|
|
46
|
+
responseKey: 'plugins',
|
|
47
|
+
listUrl: (config) => config.api.pluginListUrl,
|
|
48
|
+
commandName: 'list-plugins',
|
|
49
|
+
buildFilters: (options, base) => {
|
|
50
|
+
const filters = { ...base };
|
|
51
|
+
if (options.name)
|
|
52
|
+
filters.name = options.name;
|
|
53
|
+
if (options.version) {
|
|
54
|
+
// Validate semver format
|
|
55
|
+
const versionPattern = /^(\^|~)?(\d+)\.(\d+)\.(\d+)(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
56
|
+
if (!versionPattern.test(options.version)) {
|
|
57
|
+
printWarning(`Version "${options.version}" may not be valid semver format`);
|
|
58
|
+
}
|
|
59
|
+
filters.version = options.version;
|
|
60
|
+
}
|
|
61
|
+
return filters;
|
|
62
|
+
},
|
|
63
|
+
activeFilters: (filters) => {
|
|
64
|
+
const active = {};
|
|
65
|
+
if (filters.id)
|
|
66
|
+
active.ID = filters.id;
|
|
67
|
+
if (filters.isActive !== undefined)
|
|
68
|
+
active['Is Active'] = filters.isActive;
|
|
69
|
+
if (filters.name)
|
|
70
|
+
active.Name = filters.name;
|
|
71
|
+
if (filters.version)
|
|
72
|
+
active.Version = filters.version;
|
|
73
|
+
return active;
|
|
74
|
+
},
|
|
75
|
+
statistics: (plugins) => ({
|
|
76
|
+
'Active Plugins': `${plugins.filter(p => p.isActive).length}/${plugins.length}`,
|
|
77
|
+
'Public Plugins': `${plugins.filter(p => p.isPublic === true).length}/${plugins.length}`,
|
|
78
|
+
'Total Size': formatFileSize(plugins.reduce((sum, p) => sum + (p.fileSize || 0), 0)),
|
|
79
|
+
}),
|
|
80
|
+
rows: (plugins, options) => options.showMetadata ? plugins : plugins.map(p => ({
|
|
81
|
+
'ID': p.id,
|
|
82
|
+
'Name': p.name,
|
|
83
|
+
'Version': p.version,
|
|
84
|
+
'Organization': p.organization,
|
|
85
|
+
'Active': p.isActive ? 'Yes' : 'No',
|
|
86
|
+
'Public': p.isPublic ? 'Yes' : 'No',
|
|
87
|
+
'Size': p.fileSize ? formatFileSize(p.fileSize) : 'N/A',
|
|
88
|
+
'Created At': p.createdAt || 'N/A',
|
|
89
|
+
})),
|
|
90
|
+
}));
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2xpc3QtcGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM1RCxPQUFPLEVBQWUsTUFBTSxtQkFBbUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDM0QsT0FBTyxFQUEyQixNQUFNLGdDQUFnQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQVl4RDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsT0FBZ0I7SUFDMUMsY0FBYyxDQUFDLE9BQU87U0FDbkIsT0FBTyxDQUFDLE1BQU0sQ0FBQztTQUNmLFdBQVcsQ0FBQywwQ0FBMEMsQ0FBQztRQUV4RCx3QkFBd0I7U0FDdkIsTUFBTSxDQUFDLFdBQVcsRUFBRSx3REFBd0QsQ0FBQztTQUM3RSxNQUFNLENBQUMsdUJBQXVCLEVBQUUsc0NBQXNDLENBQUM7U0FDdkUsTUFBTSxDQUFDLGtCQUFrQixFQUFFLG9DQUFvQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztTQUM1RixNQUFNLENBQUMsbUJBQW1CLEVBQUUsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ25GLE1BQU0sQ0FBQyxlQUFlLEVBQUUs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QUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDN0UsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFO1lBQ1YsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJO1lBQ2QsU0FBUyxFQUFFLENBQUMsQ0FBQyxPQUFPO1lBQ3BCLGNBQWMsRUFBRSxDQUFDLENBQUMsWUFBWTtZQUM5QixRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ25DLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDbkMsTUFBTSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUs7WUFDdkQsWUFBWSxFQUFFLENBQUMsQ0FBQyxTQUFTLElBQUksS0FBSztTQUNuQyxDQUFDLENBQUM7S0FDSixDQUFDLENBQUMsQ0FBQztBQUNSLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBydW5MaXN0RW50aXR5IH0gZnJvbSAnLi9lbnRpdHktbGlzdC5qcyc7XG5pbXBvcnQgeyBmb3JtYXRGaWxlU2l6ZSB9IGZyb20gJy4uL2NvbmZpZy9jbGkuY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IHR5cGUgUGx1Z2luIH0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xuaW1wb3J0IHsgd2l0aFNzbE9wdGlvbnMgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IHR5cGUgQ29tbW9uRmlsdGVyUGFyYW1zIH0gZnJvbSAnLi4vdXRpbHMvbGlzdC1jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IHByaW50V2FybmluZyB9IGZyb20gJy4uL3V0aWxzL291dHB1dC11dGlscy5qcyc7XG5cbi8qKlxuICogUXVlcnkgcGFyYW1ldGVycyBmb3IgdGhlIHBsdWdpbiBsaXN0IEFQSSBlbmRwb2ludC5cbiAqIENvbWJpbmVzIGNvbW1vbiBmaWx0ZXJzIChwYWdpbmF0aW9uLCBzb3J0KSB3aXRoIHBsdWdpbi1zcGVjaWZpYyBmaWx0ZXJzLlxuICovXG5pbnRlcmZhY2UgUGx1Z2luRmlsdGVyUGFyYW1zIGV4dGVuZHMgQ29tbW9uRmlsdGVyUGFyYW1zIHtcbiAgLy8gUGx1Z2luLXNwZWNpZmljIGZpbHRlcnNcbiAgbmFtZT86IHN0cmluZztcbiAgdmVyc2lvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIGBsaXN0LXBsdWdpbnNgIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogUXVlcmllcyBwbHVnaW5zIHdpdGggZmlsdGVycyBmb3IgbmFtZSwgdmVyc2lvbiwgaW1hZ2UgdGFnLFxuICogYWN0aXZlIHN0YXR1cywgcGx1cyBwYWdpbmF0aW9uIGFuZCBzb3J0aW5nLlxuICpcbiAqIEBwYXJhbSBwcm9ncmFtIC0gVGhlIHJvb3QgQ29tbWFuZGVyIHByb2dyYW0gaW5zdGFuY2UgdG8gYXR0YWNoIHRoZSBjb21tYW5kIHRvLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBiYXNoXG4gKiBjbGkgcGx1Z2luIGxpc3RcbiAqIGNsaSBwbHVnaW4gbGlzdCAtLW5hbWUgYXV0aC1wbHVnaW4gLS1pcy1hY3RpdmUgdHJ1ZVxuICogY2xpIHBsdWdpbiBsaXN0IC0tdmVyc2lvbiBcIl4xLjAuMFwiXG4gKiBjbGkgcGx1Z2luIGxpc3QgLS1saW1pdCA1MCAtLW9mZnNldCAxMDAgLS1zb3J0IFwibmFtZTphc2NcIlxuICogY2xpIHBsdWdpbiBsaXN0IC0tZm9ybWF0IGpzb24gLS1vdXRwdXQgcGx1Z2lucy5qc29uXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RQbHVnaW5zKHByb2dyYW06IENvbW1hbmQpOiB2b2lkIHtcbiAgd2l0aFNzbE9wdGlvbnMocHJvZ3JhbVxuICAgIC5jb21tYW5kKCdsaXN0JylcbiAgICAuZGVzY3JpcHRpb24oJ1F1ZXJ5IHBsdWdpbnMgd2l0aCBjb21wcmVoZW5zaXZlIGZpbHRlcnMnKVxuXG4gICAgLy8gQ29tbW9uIGZpbHRlciBvcHRpb25zXG4gICAgLm9wdGlvbignLS1pZCA8aWQ+JywgJ0ZpbHRlciBieSBwbHVnaW4gSUQgKGNhbiBzcGVjaWZ5IG11bHRpcGxlIHdpdGggY29tbWFzKScpXG4gICAgLm9wdGlvbignLS1pcy1hY3RpdmUgPGJvb2xlYW4+JywgJ0ZpbHRlciBieSBhY3RpdmUgc3RhdHVzICh0cnVlL2ZhbHNlKScpXG4gICAgLm9wdGlvbignLS1saW1pdCA8bnVtYmVyPicsICdNYXhpbXVtIG51bWJlciBvZiByZXN1bHRzICgxLTEwMDApJywgKHYpID0+IHBhcnNlSW50KHYsIDEwKSwgNTApXG4gICAgLm9wdGlvbignLS1vZmZzZXQgPG51bWJlcj4nLCAnTnVtYmVyIG9mIHJlc3VsdHMgdG8gc2tpcCcsICh2KSA9PiBwYXJzZUludCh2LCAxMCksIDApXG4gICAgLm9wdGlvbignLS1zb3J0IDxzb3J0PicsICdTb3J0IGZvcm1hdDogZmllbGQ6ZGlyZWN0aW9uIChlLmcuLCBuYW1lOmFzYywgY3JlYXRlZEF0OmRlc2MpJylcblxuICAgIC8vIFBsdWdpbi1zcGVjaWZpYyBmaWx0ZXIgb3B0aW9uc1xuICAgIC5vcHRpb24oJy0tbmFtZSA8bmFtZT4nLCAnRmlsdGVyIGJ5IGV4YWN0IHBsdWdpbiBuYW1lJylcbiAgICAub3B0aW9uKCctLXZlcnNpb24gPHZlcnNpb24+JywgJ0ZpbHRlciBieSB2ZXJzaW9uIChzdXBwb3J0cyBzZW12ZXIsIGUuZy4sIFwiXjEuMC4wXCIpJylcblxuICAgIC8vIE91dHB1dCBvcHRpb25zXG4gICAgLm9wdGlvbignLWYsIC0tZm9ybWF0IDxmb3JtYXQ+JywgJ091dHB1dCBmb3JtYXQgKGpzb24sIHlhbWwsIHRhYmxlLCBjc3YpJywgJ3RhYmxlJylcbiAgICAub3B0aW9uKCctbywgLS1vdXRwdXQgPGZpbGU+JywgJ1NhdmUgb3V0cHV0IHRvIGZpbGUnKVxuICAgIC5vcHRpb24oJy0tc2hvdy1tZXRhZGF0YScsICdJbmNsdWRlIGZ1bGwgbWV0YWRhdGEgaW4gb3V0cHV0IChqc29uL3lhbWwgb25seSknLCBmYWxzZSkpXG5cbiAgICAuYWN0aW9uKChvcHRpb25zKSA9PiBydW5MaXN0RW50aXR5PFBsdWdpbiwgUGx1Z2luRmlsdGVyUGFyYW1zPihwcm9ncmFtLCBvcHRpb25zLCB7XG4gICAgICBsYWJlbFBsdXJhbDogJ1BsdWdpbnMnLFxuICAgICAgcmVzcG9uc2VLZXk6ICdwbHVnaW5zJyxcbiAgICAgIGxpc3RVcmw6IChjb25maWcpID0+IGNvbmZpZy5hcGkucGx1Z2luTGlzdFVybCxcbiAgICAgIGNvbW1hbmROYW1lOiAnbGlzdC1wbHVnaW5zJyxcbiAgICAgIGJ1aWxkRmlsdGVyczogKG9wdGlvbnMsIGJhc2UpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyczogUGx1Z2luRmlsdGVyUGFyYW1zID0geyAuLi5iYXNlIH07XG4gICAgICAgIGlmIChvcHRpb25zLm5hbWUpIGZpbHRlcnMubmFtZSA9IG9wdGlvbnMubmFtZSBhcyBzdHJpbmc7XG4gICAgICAgIGlmIChvcHRpb25zLnZlcnNpb24pIHtcbiAgICAgICAgICAvLyBWYWxpZGF0ZSBzZW12ZXIgZm9ybWF0XG4gICAgICAgICAgY29uc3QgdmVyc2lvblBhdHRlcm4gPSAvXihcXF58fik/KFxcZCspXFwuKFxcZCspXFwuKFxcZCspKC1bYS16QS1aMC05Li1dKyk/KFxcK1thLXpBLVowLTkuLV0rKT8kLztcbiAgICAgICAgICBpZiAoIXZlcnNpb25QYXR0ZXJuLnRlc3Qob3B0aW9ucy52ZXJzaW9uIGFzIHN0cmluZykpIHtcbiAgICAgICAgICAgIHByaW50V2FybmluZyhgVmVyc2lvbiBcIiR7b3B0aW9ucy52ZXJzaW9ufVwiIG1heSBub3QgYmUgdmFsaWQgc2VtdmVyIGZvcm1hdGApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaWx0ZXJzLnZlcnNpb24gPSBvcHRpb25zLnZlcnNpb24gYXMgc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJzO1xuICAgICAgfSxcbiAgICAgIGFjdGl2ZUZpbHRlcnM6IChmaWx0ZXJzKSA9PiB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICAgICAgaWYgKGZpbHRlcnMuaWQpIGFjdGl2ZS5JRCA9IGZpbHRlcnMuaWQ7XG4gICAgICAgIGlmIChmaWx0ZXJzLmlzQWN0aXZlICE9PSB1bmRlZmluZWQpIGFjdGl2ZVsnSXMgQWN0aXZlJ10gPSBmaWx0ZXJzLmlzQWN0aXZlO1xuICAgICAgICBpZiAoZmlsdGVycy5uYW1lKSBhY3RpdmUuTmFtZSA9IGZpbHRlcnMubmFtZTtcbiAgICAgICAgaWYgKGZpbHRlcnMudmVyc2lvbikgYWN0aXZlLlZlcnNpb24gPSBmaWx0ZXJzLnZlcnNpb247XG4gICAgICAgIHJldHVybiBhY3RpdmU7XG4gICAgICB9LFxuICAgICAgc3RhdGlzdGljczogKHBsdWdpbnMpID0+ICh7XG4gICAgICAgICdBY3RpdmUgUGx1Z2lucyc6IGAke3BsdWdpbnMuZmlsdGVyKHAgPT4gcC5pc0FjdGl2ZSkubGVuZ3RofS8ke3BsdWdpbnMubGVuZ3RofWAsXG4gICAgICAgICdQdWJsaWMgUGx1Z2lucyc6IGAke3BsdWdpbnMuZmlsdGVyKHAgPT4gcC5pc1B1YmxpYyA9PT0gdHJ1ZSkubGVuZ3RofS8ke3BsdWdpbnMubGVuZ3RofWAsXG4gICAgICAgICdUb3RhbCBTaXplJzogZm9ybWF0RmlsZVNpemUocGx1Z2lucy5yZWR1Y2UoKHN1bSwgcCkgPT4gc3VtICsgKHAuZmlsZVNpemUgfHwgMCksIDApKSxcbiAgICAgIH0pLFxuICAgICAgcm93czogKHBsdWdpbnMsIG9wdGlvbnMpID0+IG9wdGlvbnMuc2hvd01ldGFkYXRhID8gcGx1Z2lucyA6IHBsdWdpbnMubWFwKHAgPT4gKHtcbiAgICAgICAgJ0lEJzogcC5pZCxcbiAgICAgICAgJ05hbWUnOiBwLm5hbWUsXG4gICAgICAgICdWZXJzaW9uJzogcC52ZXJzaW9uLFxuICAgICAgICAnT3JnYW5pemF0aW9uJzogcC5vcmdhbml6YXRpb24sXG4gICAgICAgICdBY3RpdmUnOiBwLmlzQWN0aXZlID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAnUHVibGljJzogcC5pc1B1YmxpYyA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgJ1NpemUnOiBwLmZpbGVTaXplID8gZm9ybWF0RmlsZVNpemUocC5maWxlU2l6ZSkgOiAnTi9BJyxcbiAgICAgICAgJ0NyZWF0ZWQgQXQnOiBwLmNyZWF0ZWRBdCB8fCAnTi9BJyxcbiAgICAgIH0pKSxcbiAgICB9KSk7XG59XG4iXX0=
|