@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,315 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import ora from 'ora';
|
|
7
|
+
import pico from 'picocolors';
|
|
8
|
+
import { formatDuration, formatFileSize, FILE_SIZE_LIMITS, defaultPipelineName } from '../config/cli.constants.js';
|
|
9
|
+
import {} from '../types/index.js';
|
|
10
|
+
import { printCommandHeader, printSslWarning, createAuthenticatedClient, createAuthenticatedClientAsync, withSslOptions, withProfileOption, withRegionOption } from '../utils/command-utils.js';
|
|
11
|
+
import { runDeploy } from '../utils/deploy-runner.js';
|
|
12
|
+
import { ERROR_CODES, handleError, ValidationError } from '../utils/error-handler.js';
|
|
13
|
+
import { ensureOutputDirectory, printError, printInfo, printKeyValue, printSection, printSuccess, printWarning } from '../utils/output-utils.js';
|
|
14
|
+
import { fetchPipelineProps } from '../utils/pipeline-config.js';
|
|
15
|
+
import { extractSingleResponse } from '../utils/response-utils.js';
|
|
16
|
+
import { relaxTlsForCli } from '../utils/tls.js';
|
|
17
|
+
const { bold, cyan, dim, green } = pico;
|
|
18
|
+
/**
|
|
19
|
+
* Registers the `create-pipeline` command with the CLI program.
|
|
20
|
+
*
|
|
21
|
+
* Accepts a pipeline properties JSON file, validates it, resolves
|
|
22
|
+
* project/organization from CLI flags or the props file, and
|
|
23
|
+
* creates the pipeline via the platform API.
|
|
24
|
+
*
|
|
25
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
26
|
+
*/
|
|
27
|
+
export function createPipeline(program) {
|
|
28
|
+
withSslOptions(withRegionOption(withProfileOption(program
|
|
29
|
+
.command('create')
|
|
30
|
+
.description('Create a new pipeline — and optionally deploy it with --deploy')
|
|
31
|
+
.requiredOption('-f, --file <file>', 'Path to pipeline properties JSON file')
|
|
32
|
+
.option('-p, --project <project>', 'Project name (falls back to value in props file)')
|
|
33
|
+
.option('-o, --organization <organization>', 'Organization name (falls back to value in props file)')
|
|
34
|
+
.option('-n, --name <name>', 'Pipeline name')
|
|
35
|
+
.option('-a, --visibility <rung>', 'Sharing rung (private|org|public). Pipelines default to org — a team asset is visible to the team.', 'org')
|
|
36
|
+
.option('--default', 'Set as default pipeline', false)
|
|
37
|
+
.option('--active', 'Set pipeline as active', true)
|
|
38
|
+
.option('--no-active', 'Create the pipeline as inactive')
|
|
39
|
+
// --deploy: after creating the record, run the same CDK deploy + ARN
|
|
40
|
+
// registration as `pipeline deploy --id` (shared runDeploy). The flags
|
|
41
|
+
// below apply only with --deploy.
|
|
42
|
+
.option('--deploy', 'Deploy the pipeline with AWS CDK immediately after creating it', false)
|
|
43
|
+
.option('--require-approval <approval>', 'Deploy approval level: never|any-change|broadening (with --deploy)', 'never')
|
|
44
|
+
.option('--output <dir>', 'CDK output directory (with --deploy)', 'cdk.out')
|
|
45
|
+
.option('--store-tokens', 'Deploy auth via AWS Secrets Manager token (with --deploy; requires PLATFORM_SECRET_NAME)', false))))
|
|
46
|
+
.option('--dry-run', 'Validate inputs without creating pipeline', false)
|
|
47
|
+
.action(async (options) => {
|
|
48
|
+
const executionId = printCommandHeader('Create Pipeline', 'Creating Pipeline');
|
|
49
|
+
const startTime = Date.now();
|
|
50
|
+
try {
|
|
51
|
+
// Display parameters
|
|
52
|
+
printInfo('Configuration');
|
|
53
|
+
printKeyValue({
|
|
54
|
+
'Project': options.project || '(from props file)',
|
|
55
|
+
'Organization': options.organization || '(from props file)',
|
|
56
|
+
'Name': options.name || '(not set)',
|
|
57
|
+
'Visibility': options.visibility,
|
|
58
|
+
'Default Pipeline': options.default ? 'Yes' : 'No',
|
|
59
|
+
'Active': options.active ? 'Yes' : 'No',
|
|
60
|
+
'Deploy After Create': options.deploy ? `Yes (profile: ${options.profile || 'default'})` : 'No',
|
|
61
|
+
'Properties File': options.file,
|
|
62
|
+
'SSL Verification': options.verifySsl === false ? 'Disabled' : 'Enabled',
|
|
63
|
+
'Dry Run': options.dryRun ? 'Yes' : 'No',
|
|
64
|
+
});
|
|
65
|
+
// Security warning for SSL verification disabled
|
|
66
|
+
printSslWarning(options.verifySsl);
|
|
67
|
+
console.log('');
|
|
68
|
+
printSection('File Validation');
|
|
69
|
+
// Validate file exists
|
|
70
|
+
if (!fs.existsSync(options.file)) {
|
|
71
|
+
printError('Properties file not found', { path: options.file });
|
|
72
|
+
throw new ValidationError(`File not found: ${options.file}`, 'file');
|
|
73
|
+
}
|
|
74
|
+
// Check file extension
|
|
75
|
+
const fileExt = path.extname(options.file).toLowerCase();
|
|
76
|
+
if (fileExt !== '.json') {
|
|
77
|
+
printWarning('File extension is not .json', { extension: fileExt });
|
|
78
|
+
}
|
|
79
|
+
const fileStats = fs.statSync(options.file);
|
|
80
|
+
// Check file size
|
|
81
|
+
if (fileStats.size > FILE_SIZE_LIMITS.PIPELINE_PROPS) {
|
|
82
|
+
printError('Properties file is too large', {
|
|
83
|
+
size: formatFileSize(fileStats.size),
|
|
84
|
+
limit: formatFileSize(FILE_SIZE_LIMITS.PIPELINE_PROPS),
|
|
85
|
+
});
|
|
86
|
+
throw new ValidationError('Properties file exceeds size limit', 'file');
|
|
87
|
+
}
|
|
88
|
+
printSuccess('File validation passed');
|
|
89
|
+
printKeyValue({
|
|
90
|
+
'File Path': options.file,
|
|
91
|
+
'File Size': formatFileSize(fileStats.size),
|
|
92
|
+
'Extension': fileExt,
|
|
93
|
+
});
|
|
94
|
+
// Read and parse properties file
|
|
95
|
+
console.log('');
|
|
96
|
+
printInfo('Reading pipeline properties...');
|
|
97
|
+
const fileContent = fs.readFileSync(options.file, 'utf-8');
|
|
98
|
+
let props;
|
|
99
|
+
try {
|
|
100
|
+
props = JSON.parse(fileContent);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
printError('Invalid JSON in properties file', {
|
|
104
|
+
error: error instanceof Error ? error.message : String(error),
|
|
105
|
+
hint: 'Ensure the file contains valid JSON syntax',
|
|
106
|
+
});
|
|
107
|
+
throw new ValidationError('Properties file must contain valid JSON', 'file');
|
|
108
|
+
}
|
|
109
|
+
// Validate properties structure
|
|
110
|
+
if (typeof props !== 'object' || props === null) {
|
|
111
|
+
printError('Invalid properties format', {
|
|
112
|
+
type: typeof props,
|
|
113
|
+
hint: 'Properties must be a JSON object',
|
|
114
|
+
});
|
|
115
|
+
throw new ValidationError('Properties must be a valid object', 'file');
|
|
116
|
+
}
|
|
117
|
+
const propCount = Object.keys(props).length;
|
|
118
|
+
printSuccess('Properties parsed successfully');
|
|
119
|
+
printKeyValue({
|
|
120
|
+
'Total Keys': propCount.toString(),
|
|
121
|
+
'Sample Keys': Object.keys(props).slice(0, 5).join(', ') + (propCount > 5 ? '...' : ''),
|
|
122
|
+
});
|
|
123
|
+
// Validate properties content
|
|
124
|
+
if (propCount === 0) {
|
|
125
|
+
printWarning('Properties object is empty - pipeline will have no configuration');
|
|
126
|
+
}
|
|
127
|
+
// Resolve project & organization: prefer CLI flags, fall back to
|
|
128
|
+
// values embedded inside the props file (builderProps).
|
|
129
|
+
const resolvedProject = options.project ?? props.project;
|
|
130
|
+
const resolvedOrganization = options.organization ?? props.organization;
|
|
131
|
+
if (!resolvedProject) {
|
|
132
|
+
printError('Project is required', {
|
|
133
|
+
hint: 'Provide -p/--project flag or include "project" in the props file',
|
|
134
|
+
});
|
|
135
|
+
throw new ValidationError('Project is required', 'project');
|
|
136
|
+
}
|
|
137
|
+
if (!resolvedOrganization) {
|
|
138
|
+
printError('Organization is required', {
|
|
139
|
+
hint: 'Provide -o/--organization flag or include "organization" in the props file',
|
|
140
|
+
});
|
|
141
|
+
throw new ValidationError('Organization is required', 'organization');
|
|
142
|
+
}
|
|
143
|
+
// Resolve pipelineName with the shared default (mirrors pipeline-core's
|
|
144
|
+
// pipeline-configuration.ts) so create + registry + CDK all agree.
|
|
145
|
+
const resolvedPipelineName = options.name
|
|
146
|
+
?? props.pipelineName
|
|
147
|
+
?? defaultPipelineName(resolvedOrganization, resolvedProject);
|
|
148
|
+
const payload = {
|
|
149
|
+
project: resolvedProject,
|
|
150
|
+
organization: resolvedOrganization,
|
|
151
|
+
pipelineName: resolvedPipelineName,
|
|
152
|
+
props,
|
|
153
|
+
};
|
|
154
|
+
// Add optional fields only if provided
|
|
155
|
+
if (options.visibility) {
|
|
156
|
+
payload.visibility = options.visibility;
|
|
157
|
+
}
|
|
158
|
+
if (options.default !== undefined) {
|
|
159
|
+
payload.isDefault = options.default;
|
|
160
|
+
}
|
|
161
|
+
if (options.active !== undefined) {
|
|
162
|
+
payload.isActive = options.active;
|
|
163
|
+
}
|
|
164
|
+
// Dry run mode
|
|
165
|
+
if (options.dryRun) {
|
|
166
|
+
console.log('');
|
|
167
|
+
printSection('Dry Run - Request Preview');
|
|
168
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
169
|
+
console.log('');
|
|
170
|
+
printSuccess('✓ Validation complete - no pipeline created (dry run mode)');
|
|
171
|
+
console.log('');
|
|
172
|
+
if (options.deploy) {
|
|
173
|
+
printInfo('With --deploy, the pipeline would be deployed via CDK after creation', {
|
|
174
|
+
profile: options.profile || '(default)',
|
|
175
|
+
region: options.region || '(default)',
|
|
176
|
+
requireApproval: options.requireApproval,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
printInfo('To create the pipeline, run the command without --dry-run');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Create authenticated API client
|
|
183
|
+
const client = createAuthenticatedClient(options);
|
|
184
|
+
const config = client.getConfig();
|
|
185
|
+
// Create pipeline
|
|
186
|
+
console.log('');
|
|
187
|
+
printSection('Creating Pipeline');
|
|
188
|
+
const spinner = ora('Creating pipeline...').start();
|
|
189
|
+
let rawResponse;
|
|
190
|
+
let requestDuration;
|
|
191
|
+
try {
|
|
192
|
+
const requestStart = Date.now();
|
|
193
|
+
rawResponse = await client.post(config.api.pipelineUrl, payload);
|
|
194
|
+
requestDuration = Date.now() - requestStart;
|
|
195
|
+
spinner.succeed('Pipeline created');
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
spinner.fail('Pipeline creation failed');
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
const pipeline = extractSingleResponse(rawResponse, 'pipeline', 'id');
|
|
202
|
+
if (!pipeline?.id) {
|
|
203
|
+
printError('Invalid pipeline response', {
|
|
204
|
+
responseKeys: rawResponse ? Object.keys(rawResponse) : '(null)',
|
|
205
|
+
});
|
|
206
|
+
throw new Error('Pipeline creation failed - no valid pipeline data received');
|
|
207
|
+
}
|
|
208
|
+
console.log('');
|
|
209
|
+
printSection('✓ Pipeline Created Successfully');
|
|
210
|
+
// Display created pipeline info
|
|
211
|
+
printKeyValue({
|
|
212
|
+
'Pipeline ID': green(bold(pipeline.id)),
|
|
213
|
+
'Project': pipeline.project,
|
|
214
|
+
'Organization': pipeline.organization,
|
|
215
|
+
'Name': pipeline.pipelineName || '(not set)',
|
|
216
|
+
'Visibility': pipeline.visibility || 'org',
|
|
217
|
+
'Default': pipeline.isDefault ? 'Yes' : 'No',
|
|
218
|
+
'Active': pipeline.isActive ? 'Yes' : 'No',
|
|
219
|
+
'Properties': pipeline.props ? `${Object.keys(pipeline.props).length} keys` : '(not returned)',
|
|
220
|
+
});
|
|
221
|
+
if (pipeline.createdAt) {
|
|
222
|
+
console.log('');
|
|
223
|
+
printKeyValue({
|
|
224
|
+
'Created At': pipeline.createdAt,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
// Performance metrics
|
|
228
|
+
console.log('');
|
|
229
|
+
printKeyValue({
|
|
230
|
+
'Execution ID': executionId,
|
|
231
|
+
'Request Duration': formatDuration(requestDuration),
|
|
232
|
+
'Total Duration': formatDuration(Date.now() - startTime),
|
|
233
|
+
});
|
|
234
|
+
// Save pipeline info to file
|
|
235
|
+
const outputDir = './output';
|
|
236
|
+
ensureOutputDirectory(outputDir);
|
|
237
|
+
const outputFile = path.join(outputDir, `pipeline-${pipeline.id}.json`);
|
|
238
|
+
fs.writeFileSync(outputFile, JSON.stringify(pipeline, null, 2));
|
|
239
|
+
console.log('');
|
|
240
|
+
printSuccess('Pipeline details saved to file');
|
|
241
|
+
printKeyValue({
|
|
242
|
+
'Output File': outputFile,
|
|
243
|
+
'File Size': formatFileSize(fs.statSync(outputFile).size),
|
|
244
|
+
});
|
|
245
|
+
// ── Optional deploy (--deploy) ──
|
|
246
|
+
// The record now exists and is authoritative. If the deploy fails we KEEP
|
|
247
|
+
// it and surface the exact retry rather than rolling back (never false-green).
|
|
248
|
+
if (options.deploy) {
|
|
249
|
+
console.log('');
|
|
250
|
+
printSection('Deploying Pipeline');
|
|
251
|
+
try {
|
|
252
|
+
// Deploy touches the AWS SDK + the CDK synth subprocess; relax TLS the
|
|
253
|
+
// same way `deploy` does (refused in production by relaxTlsForCli).
|
|
254
|
+
relaxTlsForCli(options.verifySsl, printWarning);
|
|
255
|
+
// The async client adds --store-tokens (Secrets Manager) support and
|
|
256
|
+
// backs BOTH the props fetch and the registry callback.
|
|
257
|
+
const deployClient = await createAuthenticatedClientAsync(options);
|
|
258
|
+
const deployConfig = deployClient.getConfig();
|
|
259
|
+
// Re-fetch the just-created pipeline so plugins are resolved and the
|
|
260
|
+
// registry host is baked EXACTLY as `deploy --id` does — no drift.
|
|
261
|
+
const fetched = await fetchPipelineProps(deployClient, pipeline.id);
|
|
262
|
+
await runDeploy({
|
|
263
|
+
pipeline: fetched.pipeline,
|
|
264
|
+
propsWithIds: fetched.propsWithIds,
|
|
265
|
+
profile: options.profile,
|
|
266
|
+
region: options.region,
|
|
267
|
+
requireApproval: options.requireApproval,
|
|
268
|
+
output: options.output,
|
|
269
|
+
debug: program.opts().debug,
|
|
270
|
+
executionId,
|
|
271
|
+
platformClient: deployClient,
|
|
272
|
+
platformPipelineUrl: deployConfig.api.pipelineUrl,
|
|
273
|
+
platformBaseUrl: deployConfig.api.baseUrl,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
catch (deployError) {
|
|
277
|
+
printError('Pipeline was created but the deploy failed', {
|
|
278
|
+
pipelineId: pipeline.id,
|
|
279
|
+
error: deployError instanceof Error ? deployError.message : String(deployError),
|
|
280
|
+
retry: `pipeline-manager pipeline deploy --id ${pipeline.id}`,
|
|
281
|
+
});
|
|
282
|
+
// Re-throw so the process exits non-zero. The record is intentionally
|
|
283
|
+
// retained — re-run the deploy with the command above.
|
|
284
|
+
throw deployError;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// Next steps
|
|
288
|
+
console.log('');
|
|
289
|
+
printSection('Next Steps');
|
|
290
|
+
console.log(dim('You can now:'));
|
|
291
|
+
if (!options.deploy) {
|
|
292
|
+
console.log(` ${cyan('•')} Deploy: ${bold(`deploy --id ${pipeline.id}`)}`);
|
|
293
|
+
}
|
|
294
|
+
console.log(` ${cyan('•')} View: ${bold(`get-pipeline --id ${pipeline.id}`)}`);
|
|
295
|
+
console.log(` ${cyan('•')} API: ${config.api.baseUrl}${config.api.pipelineUrl}/${pipeline.id}`);
|
|
296
|
+
console.log('');
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
handleError(error, ERROR_CODES.API_REQUEST, {
|
|
300
|
+
debug: program.opts().debug,
|
|
301
|
+
exit: true,
|
|
302
|
+
context: {
|
|
303
|
+
command: 'create-pipeline',
|
|
304
|
+
executionId,
|
|
305
|
+
project: options.project,
|
|
306
|
+
organization: options.organization,
|
|
307
|
+
file: options.file,
|
|
308
|
+
verifySsl: options.verifySsl,
|
|
309
|
+
dryRun: options.dryRun,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLXBpcGVsaW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2NyZWF0ZS1waXBlbGluZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQ3RCLE9BQU8sSUFBSSxNQUFNLFlBQVksQ0FBQztBQUM5QixPQUFPLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25ILE9BQU8sRUFBK0YsTUFBTSxtQkFBbUIsQ0FBQztBQUNoSSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUFFLHlCQUF5QixFQUFFLDhCQUE4QixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2hNLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RixPQUFPLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNqSixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNqRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7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M0IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLE9BQU8sRUFBRSxpQkFBaUI7b0JBQzFCLFdBQVc7b0JBQ1gsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO29CQUN4QixZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVk7b0JBQ2xDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtvQkFDbEIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO29CQUM1QixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07aUJBQ3ZCO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgb3JhIGZyb20gJ29yYSc7XG5pbXBvcnQgcGljbyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCB7IGZvcm1hdER1cmF0aW9uLCBmb3JtYXRGaWxlU2l6ZSwgRklMRV9TSVpFX0xJTUlUUywgZGVmYXVsdFBpcGVsaW5lTmFtZSB9IGZyb20gJy4uL2NvbmZpZy9jbGkuY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IHR5cGUgUGlwZWxpbmUsIHR5cGUgUGlwZWxpbmVSZXNwb25zZSwgdHlwZSBDcmVhdGVQaXBlbGluZVJlcXVlc3QsIHR5cGUgUGxhdGZvcm1EZXBsb3lDb25maWcgfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIsIHByaW50U3NsV2FybmluZywgY3JlYXRlQXV0aGVudGljYXRlZENsaWVudCwgY3JlYXRlQXV0aGVudGljYXRlZENsaWVudEFzeW5jLCB3aXRoU3NsT3B0aW9ucywgd2l0aFByb2ZpbGVPcHRpb24sIHdpdGhSZWdpb25PcHRpb24gfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IHJ1bkRlcGxveSB9IGZyb20gJy4uL3V0aWxzL2RlcGxveS1ydW5uZXIuanMnO1xuaW1wb3J0IHsgRVJST1JfQ09ERVMsIGhhbmRsZUVycm9yLCBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuLi91dGlscy9lcnJvci1oYW5kbGVyLmpzJztcbmltcG9ydCB7IGVuc3VyZU91dHB1dERpcmVjdG9yeSwgcHJpbnRFcnJvciwgcHJpbnRJbmZvLCBwcmludEtleVZhbHVlLCBwcmludFNlY3Rpb24sIHByaW50U3VjY2VzcywgcHJpbnRXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvb3V0cHV0LXV0aWxzLmpzJztcbmltcG9ydCB7IGZldGNoUGlwZWxpbmVQcm9wcyB9IGZyb20gJy4uL3V0aWxzL3BpcGVsaW5lLWNvbmZpZy5qcyc7XG5pbXBvcnQgeyBleHRyYWN0U2luZ2xlUmVzcG9uc2UgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS11dGlscy5qcyc7XG5pbXBvcnQgeyByZWxheFRsc0ZvckNsaSB9IGZyb20gJy4uL3V0aWxzL3Rscy5qcyc7XG5cbmNvbnN0IHsgYm9sZCwgY3lhbiwgZGltLCBncmVlbiB9ID0gcGljbztcblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIGBjcmVhdGUtcGlwZWxpbmVgIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogQWNjZXB0cyBhIHBpcGVsaW5lIHByb3BlcnRpZXMgSlNPTiBmaWxlLCB2YWxpZGF0ZXMgaXQsIHJlc29sdmVzXG4gKiBwcm9qZWN0L29yZ2FuaXphdGlvbiBmcm9tIENMSSBmbGFncyBvciB0aGUgcHJvcHMgZmlsZSwgYW5kXG4gKiBjcmVhdGVzIHRoZSBwaXBlbGluZSB2aWEgdGhlIHBsYXRmb3JtIEFQSS5cbiAqXG4gKiBAcGFyYW0gcHJvZ3JhbSAtIFRoZSByb290IENvbW1hbmRlciBwcm9ncmFtIGluc3RhbmNlIHRvIGF0dGFjaCB0aGUgY29tbWFuZCB0by5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBpcGVsaW5lKHByb2dyYW06IENvbW1hbmQpOiB2b2lkIHtcbiAgd2l0aFNzbE9wdGlvbnMoXG4gICAgd2l0aFJlZ2lvbk9wdGlvbihcbiAgICAgIHdpdGhQcm9maWxlT3B0aW9uKHByb2dyYW1cbiAgICAgICAgLmNvbW1hbmQoJ2NyZWF0ZScpXG4gICAgICAgIC5kZXNjcmlwdGlvbignQ3JlYXRlIGEgbmV3IHBpcGVsaW5lIOKAlCBhbmQgb3B0aW9uYWxseSBkZXBsb3kgaXQgd2l0aCAtLWRlcGxveScpXG4gICAgICAgIC5yZXF1aXJlZE9wdGlvbignLWYsIC0tZmlsZSA8ZmlsZT4nLCAnUGF0aCB0byBwaXBlbGluZSBwcm9wZXJ0aWVzIEpTT04gZmlsZScpXG4gICAgICAgIC5vcHRpb24oJy1wLCAtLXByb2plY3QgPHByb2plY3Q+JywgJ1Byb2plY3QgbmFtZSAoZmFsbHMgYmFjayB0byB2YWx1ZSBpbiBwcm9wcyBmaWxlKScpXG4gICAgICAgIC5vcHRpb24oJy1vLCAtLW9yZ2FuaXphdGlvbiA8b3JnYW5pemF0aW9uPicsICdPcmdhbml6YXRpb24gbmFtZSAoZmFsbHMgYmFjayB0byB2YWx1ZSBpbiBwcm9wcyBmaWxlKScpXG4gICAgICAgIC5vcHRpb24oJy1uLCAtLW5hbWUgPG5hbWU+JywgJ1BpcGVsaW5lIG5hbWUnKVxuICAgICAgICAub3B0aW9uKCctYSwgLS12aXNpYmlsaXR5IDxydW5nPicsICdTaGFyaW5nIHJ1bmcgKHByaXZhdGV8b3JnfHB1YmxpYykuIFBpcGVsaW5lcyBkZWZhdWx0IHRvIG9yZyDigJQgYSB0ZWFtIGFzc2V0IGlzIHZpc2libGUgdG8gdGhlIHRlYW0uJywgJ29yZycpXG4gICAgICAgIC5vcHRpb24oJy0tZGVmYXVsdCcsICdTZXQgYXMgZGVmYXVsdCBwaXBlbGluZScsIGZhbHNlKVxuICAgICAgICAub3B0aW9uKCctLWFjdGl2ZScsICdTZXQgcGlwZWxpbmUgYXMgYWN0aXZlJywgdHJ1ZSlcbiAgICAgICAgLm9wdGlvbignLS1uby1hY3RpdmUnLCAnQ3JlYXRlIHRoZSBwaXBlbGluZSBhcyBpbmFjdGl2ZScpXG4gICAgICAgIC8vIC0tZGVwbG95OiBhZnRlciBjcmVhdGluZyB0aGUgcmVjb3JkLCBydW4gdGhlIHNhbWUgQ0RLIGRlcGxveSArIEFSTlxuICAgICAgICAvLyByZWdpc3RyYXRpb24gYXMgYHBpcGVsaW5lIGRlcGxveSAtLWlkYCAoc2hhcmVkIHJ1bkRlcGxveSkuIFRoZSBmbGFnc1xuICAgICAgICAvLyBiZWxvdyBhcHBseSBvbmx5IHdpdGggLS1kZXBsb3kuXG4gICAgICAgIC5vcHRpb24oJy0tZGVwbG95JywgJ0RlcGxveSB0aGUgcGlwZWxpbmUgd2l0aCBBV1MgQ0RLIGltbWVkaWF0ZWx5IGFmdGVyIGNyZWF0aW5nIGl0JywgZmFsc2UpXG4gICAgICAgIC5vcHRpb24oJy0tcmVxdWlyZS1hcHByb3ZhbCA8YXBwcm92YWw+JywgJ0RlcGxveSBhcHByb3ZhbCBsZXZlbDogbmV2ZXJ8YW55LWNoYW5nZXxicm9hZGVuaW5nICh3aXRoIC0tZGVwbG95KScsICduZXZlcicpXG4gICAgICAgIC5vcHRpb24oJy0tb3V0cHV0IDxkaXI+JywgJ0NESyBvdXRwdXQgZGlyZWN0b3J5ICh3aXRoIC0tZGVwbG95KScsICdjZGsub3V0JylcbiAgICAgICAgLm9wdGlvbignLS1zdG9yZS10b2tlbnMnLCAnRGVwbG95IGF1dGggdmlhIEFXUyBTZWNyZXRzIE1hbmFnZXIgdG9rZW4gKHdpdGggLS1kZXBsb3k7IHJlcXVpcmVzIFBMQVRGT1JNX1NFQ1JFVF9OQU1FKScsIGZhbHNlKSksXG4gICAgKSxcbiAgKVxuICAgIC5vcHRpb24oJy0tZHJ5LXJ1bicsICdWYWxpZGF0ZSBpbnB1dHMgd2l0aG91dCBjcmVhdGluZyBwaXBlbGluZScsIGZhbHNlKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgIGNvbnN0IGV4ZWN1dGlvbklkID0gcHJpbnRDb21tYW5kSGVhZGVyKCdDcmVhdGUgUGlwZWxpbmUnLCAnQ3JlYXRpbmcgUGlwZWxpbmUnKTtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgIHRyeSB7XG5cbiAgICAgICAgLy8gRGlzcGxheSBwYXJhbWV0ZXJzXG4gICAgICAgIHByaW50SW5mbygnQ29uZmlndXJhdGlvbicpO1xuICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAnUHJvamVjdCc6IG9wdGlvbnMucHJvamVjdCB8fCAnKGZyb20gcHJvcHMgZmlsZSknLFxuICAgICAgICAgICdPcmdhbml6YXRpb24nOiBvcHRpb25zLm9yZ2FuaXphdGlvbiB8fCAnKGZyb20gcHJvcHMgZmlsZSknLFxuICAgICAgICAgICdOYW1lJzogb3B0aW9ucy5uYW1lIHx8ICcobm90IHNldCknLFxuICAgICAgICAgICdWaXNpYmlsaXR5Jzogb3B0aW9ucy52aXNpYmlsaXR5LFxuICAgICAgICAgICdEZWZhdWx0IFBpcGVsaW5lJzogb3B0aW9ucy5kZWZhdWx0ID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgICdBY3RpdmUnOiBvcHRpb25zLmFjdGl2ZSA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgICAnRGVwbG95IEFmdGVyIENyZWF0ZSc6IG9wdGlvbnMuZGVwbG95ID8gYFllcyAocHJvZmlsZTogJHtvcHRpb25zLnByb2ZpbGUgfHwgJ2RlZmF1bHQnfSlgIDogJ05vJyxcbiAgICAgICAgICAnUHJvcGVydGllcyBGaWxlJzogb3B0aW9ucy5maWxlLFxuICAgICAgICAgICdTU0wgVmVyaWZpY2F0aW9uJzogb3B0aW9ucy52ZXJpZnlTc2wgPT09IGZhbHNlID8gJ0Rpc2FibGVkJyA6ICdFbmFibGVkJyxcbiAgICAgICAgICAnRHJ5IFJ1bic6IG9wdGlvbnMuZHJ5UnVuID8gJ1llcycgOiAnTm8nLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZWN1cml0eSB3YXJuaW5nIGZvciBTU0wgdmVyaWZpY2F0aW9uIGRpc2FibGVkXG4gICAgICAgIHByaW50U3NsV2FybmluZyhvcHRpb25zLnZlcmlmeVNzbCk7XG5cbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludFNlY3Rpb24oJ0ZpbGUgVmFsaWRhdGlvbicpO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGUgZXhpc3RzXG4gICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhvcHRpb25zLmZpbGUpKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignUHJvcGVydGllcyBmaWxlIG5vdCBmb3VuZCcsIHsgcGF0aDogb3B0aW9ucy5maWxlIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYEZpbGUgbm90IGZvdW5kOiAke29wdGlvbnMuZmlsZX1gLCAnZmlsZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZmlsZSBleHRlbnNpb25cbiAgICAgICAgY29uc3QgZmlsZUV4dCA9IHBhdGguZXh0bmFtZShvcHRpb25zLmZpbGUpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChmaWxlRXh0ICE9PSAnLmpzb24nKSB7XG4gICAgICAgICAgcHJpbnRXYXJuaW5nKCdGaWxlIGV4dGVuc2lvbiBpcyBub3QgLmpzb24nLCB7IGV4dGVuc2lvbjogZmlsZUV4dCB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpbGVTdGF0cyA9IGZzLnN0YXRTeW5jKG9wdGlvbnMuZmlsZSk7XG5cbiAgICAgICAgLy8gQ2hlY2sgZmlsZSBzaXplXG4gICAgICAgIGlmIChmaWxlU3RhdHMuc2l6ZSA+IEZJTEVfU0laRV9MSU1JVFMuUElQRUxJTkVfUFJPUFMpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdQcm9wZXJ0aWVzIGZpbGUgaXMgdG9vIGxhcmdlJywge1xuICAgICAgICAgICAgc2l6ZTogZm9ybWF0RmlsZVNpemUoZmlsZVN0YXRzLnNpemUpLFxuICAgICAgICAgICAgbGltaXQ6IGZvcm1hdEZpbGVTaXplKEZJTEVfU0laRV9MSU1JVFMuUElQRUxJTkVfUFJPUFMpLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1Byb3BlcnRpZXMgZmlsZSBleGNlZWRzIHNpemUgbGltaXQnLCAnZmlsZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJpbnRTdWNjZXNzKCdGaWxlIHZhbGlkYXRpb24gcGFzc2VkJyk7XG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdGaWxlIFBhdGgnOiBvcHRpb25zLmZpbGUsXG4gICAgICAgICAgJ0ZpbGUgU2l6ZSc6IGZvcm1hdEZpbGVTaXplKGZpbGVTdGF0cy5zaXplKSxcbiAgICAgICAgICAnRXh0ZW5zaW9uJzogZmlsZUV4dCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVhZCBhbmQgcGFyc2UgcHJvcGVydGllcyBmaWxlXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRJbmZvKCdSZWFkaW5nIHBpcGVsaW5lIHByb3BlcnRpZXMuLi4nKTtcblxuICAgICAgICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhvcHRpb25zLmZpbGUsICd1dGYtOCcpO1xuXG4gICAgICAgIGxldCBwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcHJvcHMgPSBKU09OLnBhcnNlKGZpbGVDb250ZW50KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdJbnZhbGlkIEpTT04gaW4gcHJvcGVydGllcyBmaWxlJywge1xuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICAgIGhpbnQ6ICdFbnN1cmUgdGhlIGZpbGUgY29udGFpbnMgdmFsaWQgSlNPTiBzeW50YXgnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1Byb3BlcnRpZXMgZmlsZSBtdXN0IGNvbnRhaW4gdmFsaWQgSlNPTicsICdmaWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWYWxpZGF0ZSBwcm9wZXJ0aWVzIHN0cnVjdHVyZVxuICAgICAgICBpZiAodHlwZW9mIHByb3BzICE9PSAnb2JqZWN0JyB8fCBwcm9wcyA9PT0gbnVsbCkge1xuICAgICAgICAgIHByaW50RXJyb3IoJ0ludmFsaWQgcHJvcGVydGllcyBmb3JtYXQnLCB7XG4gICAgICAgICAgICB0eXBlOiB0eXBlb2YgcHJvcHMsXG4gICAgICAgICAgICBoaW50OiAnUHJvcGVydGllcyBtdXN0IGJlIGEgSlNPTiBvYmplY3QnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1Byb3BlcnRpZXMgbXVzdCBiZSBhIHZhbGlkIG9iamVjdCcsICdmaWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcm9wQ291bnQgPSBPYmplY3Qua2V5cyhwcm9wcykubGVuZ3RoO1xuXG4gICAgICAgIHByaW50U3VjY2VzcygnUHJvcGVydGllcyBwYXJzZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdUb3RhbCBLZXlzJzogcHJvcENvdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgJ1NhbXBsZSBLZXlzJzogT2JqZWN0LmtleXMocHJvcHMpLnNsaWNlKDAsIDUpLmpvaW4oJywgJykgKyAocHJvcENvdW50ID4gNSA/ICcuLi4nIDogJycpLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWYWxpZGF0ZSBwcm9wZXJ0aWVzIGNvbnRlbnRcbiAgICAgICAgaWYgKHByb3BDb3VudCA9PT0gMCkge1xuICAgICAgICAgIHByaW50V2FybmluZygnUHJvcGVydGllcyBvYmplY3QgaXMgZW1wdHkgLSBwaXBlbGluZSB3aWxsIGhhdmUgbm8gY29uZmlndXJhdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzb2x2ZSBwcm9qZWN0ICYgb3JnYW5pemF0aW9uOiBwcmVmZXIgQ0xJIGZsYWdzLCBmYWxsIGJhY2sgdG9cbiAgICAgICAgLy8gdmFsdWVzIGVtYmVkZGVkIGluc2lkZSB0aGUgcHJvcHMgZmlsZSAoYnVpbGRlclByb3BzKS5cbiAgICAgICAgY29uc3QgcmVzb2x2ZWRQcm9qZWN0ID0gb3B0aW9ucy5wcm9qZWN0ID8/IChwcm9wcy5wcm9qZWN0IGFzIHN0cmluZyB8IHVuZGVmaW5lZCk7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkT3JnYW5pemF0aW9uID0gb3B0aW9ucy5vcmdhbml6YXRpb24gPz8gKHByb3BzLm9yZ2FuaXphdGlvbiBhcyBzdHJpbmcgfCB1bmRlZmluZWQpO1xuXG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9qZWN0KSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignUHJvamVjdCBpcyByZXF1aXJlZCcsIHtcbiAgICAgICAgICAgIGhpbnQ6ICdQcm92aWRlIC1wLy0tcHJvamVjdCBmbGFnIG9yIGluY2x1ZGUgXCJwcm9qZWN0XCIgaW4gdGhlIHByb3BzIGZpbGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1Byb2plY3QgaXMgcmVxdWlyZWQnLCAncHJvamVjdCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghcmVzb2x2ZWRPcmdhbml6YXRpb24pIHtcbiAgICAgICAgICBwcmludEVycm9yKCdPcmdhbml6YXRpb24gaXMgcmVxdWlyZWQnLCB7XG4gICAgICAgICAgICBoaW50OiAnUHJvdmlkZSAtby8tLW9yZ2FuaXphdGlvbiBmbGFnIG9yIGluY2x1ZGUgXCJvcmdhbml6YXRpb25cIiBpbiB0aGUgcHJvcHMgZmlsZScsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignT3JnYW5pemF0aW9uIGlzIHJlcXVpcmVkJywgJ29yZ2FuaXphdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzb2x2ZSBwaXBlbGluZU5hbWUgd2l0aCB0aGUgc2hhcmVkIGRlZmF1bHQgKG1pcnJvcnMgcGlwZWxpbmUtY29yZSdzXG4gICAgICAgIC8vIHBpcGVsaW5lLWNvbmZpZ3VyYXRpb24udHMpIHNvIGNyZWF0ZSArIHJlZ2lzdHJ5ICsgQ0RLIGFsbCBhZ3JlZS5cbiAgICAgICAgY29uc3QgcmVzb2x2ZWRQaXBlbGluZU5hbWUgPSBvcHRpb25zLm5hbWVcbiAgICAgICAgICA/PyAocHJvcHMucGlwZWxpbmVOYW1lIGFzIHN0cmluZyB8IHVuZGVmaW5lZClcbiAgICAgICAgICA/PyBkZWZhdWx0UGlwZWxpbmVOYW1lKHJlc29sdmVkT3JnYW5pemF0aW9uLCByZXNvbHZlZFByb2plY3QpO1xuXG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IENyZWF0ZVBpcGVsaW5lUmVxdWVzdCA9IHtcbiAgICAgICAgICBwcm9qZWN0OiByZXNvbHZlZFByb2plY3QsXG4gICAgICAgICAgb3JnYW5pemF0aW9uOiByZXNvbHZlZE9yZ2FuaXphdGlvbixcbiAgICAgICAgICBwaXBlbGluZU5hbWU6IHJlc29sdmVkUGlwZWxpbmVOYW1lLFxuICAgICAgICAgIHByb3BzLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEFkZCBvcHRpb25hbCBmaWVsZHMgb25seSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAob3B0aW9ucy52aXNpYmlsaXR5KSB7XG4gICAgICAgICAgcGF5bG9hZC52aXNpYmlsaXR5ID0gb3B0aW9ucy52aXNpYmlsaXR5O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHBheWxvYWQuaXNEZWZhdWx0ID0gb3B0aW9ucy5kZWZhdWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmFjdGl2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGF5bG9hZC5pc0FjdGl2ZSA9IG9wdGlvbnMuYWN0aXZlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRHJ5IHJ1biBtb2RlXG4gICAgICAgIGlmIChvcHRpb25zLmRyeVJ1bikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgICBwcmludFNlY3Rpb24oJ0RyeSBSdW4gLSBSZXF1ZXN0IFByZXZpZXcnKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShwYXlsb2FkLCBudWxsLCAyKSk7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50U3VjY2Vzcygn4pyTIFZhbGlkYXRpb24gY29tcGxldGUgLSBubyBwaXBlbGluZSBjcmVhdGVkIChkcnkgcnVuIG1vZGUpJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIGlmIChvcHRpb25zLmRlcGxveSkge1xuICAgICAgICAgICAgcHJpbnRJbmZvKCdXaXRoIC0tZGVwbG95LCB0aGUgcGlwZWxpbmUgd291bGQgYmUgZGVwbG95ZWQgdmlhIENESyBhZnRlciBjcmVhdGlvbicsIHtcbiAgICAgICAgICAgICAgcHJvZmlsZTogb3B0aW9ucy5wcm9maWxlIHx8ICcoZGVmYXVsdCknLFxuICAgICAgICAgICAgICByZWdpb246IG9wdGlvbnMucmVnaW9uIHx8ICcoZGVmYXVsdCknLFxuICAgICAgICAgICAgICByZXF1aXJlQXBwcm92YWw6IG9wdGlvbnMucmVxdWlyZUFwcHJvdmFsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHByaW50SW5mbygnVG8gY3JlYXRlIHRoZSBwaXBlbGluZSwgcnVuIHRoZSBjb21tYW5kIHdpdGhvdXQgLS1kcnktcnVuJyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGF1dGhlbnRpY2F0ZWQgQVBJIGNsaWVudFxuICAgICAgICBjb25zdCBjbGllbnQgPSBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50KG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBjb25maWcgPSBjbGllbnQuZ2V0Q29uZmlnKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHBpcGVsaW5lXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRTZWN0aW9uKCdDcmVhdGluZyBQaXBlbGluZScpO1xuXG4gICAgICAgIGNvbnN0IHNwaW5uZXIgPSBvcmEoJ0NyZWF0aW5nIHBpcGVsaW5lLi4uJykuc3RhcnQoKTtcbiAgICAgICAgbGV0IHJhd1Jlc3BvbnNlOiBQaXBlbGluZVJlc3BvbnNlO1xuICAgICAgICBsZXQgcmVxdWVzdER1cmF0aW9uOiBudW1iZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVxdWVzdFN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICByYXdSZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0PFBpcGVsaW5lUmVzcG9uc2U+KFxuICAgICAgICAgICAgY29uZmlnLmFwaS5waXBlbGluZVVybCxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXF1ZXN0RHVyYXRpb24gPSBEYXRlLm5vdygpIC0gcmVxdWVzdFN0YXJ0O1xuICAgICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnUGlwZWxpbmUgY3JlYXRlZCcpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHNwaW5uZXIuZmFpbCgnUGlwZWxpbmUgY3JlYXRpb24gZmFpbGVkJyk7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwaXBlbGluZSA9IGV4dHJhY3RTaW5nbGVSZXNwb25zZTxQaXBlbGluZT4ocmF3UmVzcG9uc2UsICdwaXBlbGluZScsICdpZCcpO1xuXG4gICAgICAgIGlmICghcGlwZWxpbmU/LmlkKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignSW52YWxpZCBwaXBlbGluZSByZXNwb25zZScsIHtcbiAgICAgICAgICAgIHJlc3BvbnNlS2V5czogcmF3UmVzcG9uc2UgPyBPYmplY3Qua2V5cyhyYXdSZXNwb25zZSkgOiAnKG51bGwpJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BpcGVsaW5lIGNyZWF0aW9uIGZhaWxlZCAtIG5vIHZhbGlkIHBpcGVsaW5lIGRhdGEgcmVjZWl2ZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRTZWN0aW9uKCfinJMgUGlwZWxpbmUgQ3JlYXRlZCBTdWNjZXNzZnVsbHknKTtcblxuICAgICAgICAvLyBEaXNwbGF5IGNyZWF0ZWQgcGlwZWxpbmUgaW5mb1xuICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAnUGlwZWxpbmUgSUQnOiBncmVlbihib2xkKHBpcGVsaW5lLmlkKSksXG4gICAgICAgICAgJ1Byb2plY3QnOiBwaXBlbGluZS5wcm9qZWN0LFxuICAgICAgICAgICdPcmdhbml6YXRpb24nOiBwaXBlbGluZS5vcmdhbml6YXRpb24sXG4gICAgICAgICAgJ05hbWUnOiBwaXBlbGluZS5waXBlbGluZU5hbWUgfHwgJyhub3Qgc2V0KScsXG4gICAgICAgICAgJ1Zpc2liaWxpdHknOiBwaXBlbGluZS52aXNpYmlsaXR5IHx8ICdvcmcnLFxuICAgICAgICAgICdEZWZhdWx0JzogcGlwZWxpbmUuaXNEZWZhdWx0ID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgICdBY3RpdmUnOiBwaXBlbGluZS5pc0FjdGl2ZSA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgICAnUHJvcGVydGllcyc6IHBpcGVsaW5lLnByb3BzID8gYCR7T2JqZWN0LmtleXMocGlwZWxpbmUucHJvcHMpLmxlbmd0aH0ga2V5c2AgOiAnKG5vdCByZXR1cm5lZCknLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocGlwZWxpbmUuY3JlYXRlZEF0KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICAgJ0NyZWF0ZWQgQXQnOiBwaXBlbGluZS5jcmVhdGVkQXQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQZXJmb3JtYW5jZSBtZXRyaWNzXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgJ0V4ZWN1dGlvbiBJRCc6IGV4ZWN1dGlvbklkLFxuICAgICAgICAgICdSZXF1ZXN0IER1cmF0aW9uJzogZm9ybWF0RHVyYXRpb24ocmVxdWVzdER1cmF0aW9uKSxcbiAgICAgICAgICAnVG90YWwgRHVyYXRpb24nOiBmb3JtYXREdXJhdGlvbihEYXRlLm5vdygpIC0gc3RhcnRUaW1lKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2F2ZSBwaXBlbGluZSBpbmZvIHRvIGZpbGVcbiAgICAgICAgY29uc3Qgb3V0cHV0RGlyID0gJy4vb3V0cHV0JztcbiAgICAgICAgZW5zdXJlT3V0cHV0RGlyZWN0b3J5KG91dHB1dERpcik7XG5cbiAgICAgICAgY29uc3Qgb3V0cHV0RmlsZSA9IHBhdGguam9pbihvdXRwdXREaXIsIGBwaXBlbGluZS0ke3BpcGVsaW5lLmlkfS5qc29uYCk7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMob3V0cHV0RmlsZSwgSlNPTi5zdHJpbmdpZnkocGlwZWxpbmUsIG51bGwsIDIpKTtcblxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2VzcygnUGlwZWxpbmUgZGV0YWlscyBzYXZlZCB0byBmaWxlJyk7XG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdPdXRwdXQgRmlsZSc6IG91dHB1dEZpbGUsXG4gICAgICAgICAgJ0ZpbGUgU2l6ZSc6IGZvcm1hdEZpbGVTaXplKGZzLnN0YXRTeW5jKG91dHB1dEZpbGUpLnNpemUpLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyDilIDilIAgT3B0aW9uYWwgZGVwbG95ICgtLWRlcGxveSkg4pSA4pSAXG4gICAgICAgIC8vIFRoZSByZWNvcmQgbm93IGV4aXN0cyBhbmQgaXMgYXV0aG9yaXRhdGl2ZS4gSWYgdGhlIGRlcGxveSBmYWlscyB3ZSBLRUVQXG4gICAgICAgIC8vIGl0IGFuZCBzdXJmYWNlIHRoZSBleGFjdCByZXRyeSByYXRoZXIgdGhhbiByb2xsaW5nIGJhY2sgKG5ldmVyIGZhbHNlLWdyZWVuKS5cbiAgICAgICAgaWYgKG9wdGlvbnMuZGVwbG95KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50U2VjdGlvbignRGVwbG95aW5nIFBpcGVsaW5lJyk7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIERlcGxveSB0b3VjaGVzIHRoZSBBV1MgU0RLICsgdGhlIENESyBzeW50aCBzdWJwcm9jZXNzOyByZWxheCBUTFMgdGhlXG4gICAgICAgICAgICAvLyBzYW1lIHdheSBgZGVwbG95YCBkb2VzIChyZWZ1c2VkIGluIHByb2R1Y3Rpb24gYnkgcmVsYXhUbHNGb3JDbGkpLlxuICAgICAgICAgICAgcmVsYXhUbHNGb3JDbGkob3B0aW9ucy52ZXJpZnlTc2wsIHByaW50V2FybmluZyk7XG4gICAgICAgICAgICAvLyBUaGUgYXN5bmMgY2xpZW50IGFkZHMgLS1zdG9yZS10b2tlbnMgKFNlY3JldHMgTWFuYWdlcikgc3VwcG9ydCBhbmRcbiAgICAgICAgICAgIC8vIGJhY2tzIEJPVEggdGhlIHByb3BzIGZldGNoIGFuZCB0aGUgcmVnaXN0cnkgY2FsbGJhY2suXG4gICAgICAgICAgICBjb25zdCBkZXBsb3lDbGllbnQgPSBhd2FpdCBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50QXN5bmMob3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBkZXBsb3lDb25maWcgPSBkZXBsb3lDbGllbnQuZ2V0Q29uZmlnKCkgYXMgUGxhdGZvcm1EZXBsb3lDb25maWc7XG4gICAgICAgICAgICAvLyBSZS1mZXRjaCB0aGUganVzdC1jcmVhdGVkIHBpcGVsaW5lIHNvIHBsdWdpbnMgYXJlIHJlc29sdmVkIGFuZCB0aGVcbiAgICAgICAgICAgIC8vIHJlZ2lzdHJ5IGhvc3QgaXMgYmFrZWQgRVhBQ1RMWSBhcyBgZGVwbG95IC0taWRgIGRvZXMg4oCUIG5vIGRyaWZ0LlxuICAgICAgICAgICAgY29uc3QgZmV0Y2hlZCA9IGF3YWl0IGZldGNoUGlwZWxpbmVQcm9wcyhkZXBsb3lDbGllbnQsIHBpcGVsaW5lLmlkKTtcbiAgICAgICAgICAgIGF3YWl0IHJ1bkRlcGxveSh7XG4gICAgICAgICAgICAgIHBpcGVsaW5lOiBmZXRjaGVkLnBpcGVsaW5lLFxuICAgICAgICAgICAgICBwcm9wc1dpdGhJZHM6IGZldGNoZWQucHJvcHNXaXRoSWRzLFxuICAgICAgICAgICAgICBwcm9maWxlOiBvcHRpb25zLnByb2ZpbGUsXG4gICAgICAgICAgICAgIHJlZ2lvbjogb3B0aW9ucy5yZWdpb24sXG4gICAgICAgICAgICAgIHJlcXVpcmVBcHByb3ZhbDogb3B0aW9ucy5yZXF1aXJlQXBwcm92YWwsXG4gICAgICAgICAgICAgIG91dHB1dDogb3B0aW9ucy5vdXRwdXQsXG4gICAgICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICAgICAgZXhlY3V0aW9uSWQsXG4gICAgICAgICAgICAgIHBsYXRmb3JtQ2xpZW50OiBkZXBsb3lDbGllbnQsXG4gICAgICAgICAgICAgIHBsYXRmb3JtUGlwZWxpbmVVcmw6IGRlcGxveUNvbmZpZy5hcGkucGlwZWxpbmVVcmwsXG4gICAgICAgICAgICAgIHBsYXRmb3JtQmFzZVVybDogZGVwbG95Q29uZmlnLmFwaS5iYXNlVXJsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBjYXRjaCAoZGVwbG95RXJyb3IpIHtcbiAgICAgICAgICAgIHByaW50RXJyb3IoJ1BpcGVsaW5lIHdhcyBjcmVhdGVkIGJ1dCB0aGUgZGVwbG95IGZhaWxlZCcsIHtcbiAgICAgICAgICAgICAgcGlwZWxpbmVJZDogcGlwZWxpbmUuaWQsXG4gICAgICAgICAgICAgIGVycm9yOiBkZXBsb3lFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZGVwbG95RXJyb3IubWVzc2FnZSA6IFN0cmluZyhkZXBsb3lFcnJvciksXG4gICAgICAgICAgICAgIHJldHJ5OiBgcGlwZWxpbmUtbWFuYWdlciBwaXBlbGluZSBkZXBsb3kgLS1pZCAke3BpcGVsaW5lLmlkfWAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIFJlLXRocm93IHNvIHRoZSBwcm9jZXNzIGV4aXRzIG5vbi16ZXJvLiBUaGUgcmVjb3JkIGlzIGludGVudGlvbmFsbHlcbiAgICAgICAgICAgIC8vIHJldGFpbmVkIOKAlCByZS1ydW4gdGhlIGRlcGxveSB3aXRoIHRoZSBjb21tYW5kIGFib3ZlLlxuICAgICAgICAgICAgdGhyb3cgZGVwbG95RXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTmV4dCBzdGVwc1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U2VjdGlvbignTmV4dCBTdGVwcycpO1xuICAgICAgICBjb25zb2xlLmxvZyhkaW0oJ1lvdSBjYW4gbm93OicpKTtcbiAgICAgICAgaWYgKCFvcHRpb25zLmRlcGxveSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICR7Y3lhbign4oCiJyl9IERlcGxveTogJHtib2xkKGBkZXBsb3kgLS1pZCAke3BpcGVsaW5lLmlkfWApfWApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKGAgICR7Y3lhbign4oCiJyl9IFZpZXc6ICR7Ym9sZChgZ2V0LXBpcGVsaW5lIC0taWQgJHtwaXBlbGluZS5pZH1gKX1gKTtcbiAgICAgICAgY29uc29sZS5sb2coYCAgJHtjeWFuKCfigKInKX0gQVBJOiAke2NvbmZpZy5hcGkuYmFzZVVybH0ke2NvbmZpZy5hcGkucGlwZWxpbmVVcmx9LyR7cGlwZWxpbmUuaWR9YCk7XG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcblxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IsIEVSUk9SX0NPREVTLkFQSV9SRVFVRVNULCB7XG4gICAgICAgICAgZGVidWc6IHByb2dyYW0ub3B0cygpLmRlYnVnLFxuICAgICAgICAgIGV4aXQ6IHRydWUsXG4gICAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgICAgY29tbWFuZDogJ2NyZWF0ZS1waXBlbGluZScsXG4gICAgICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgICAgIHByb2plY3Q6IG9wdGlvbnMucHJvamVjdCxcbiAgICAgICAgICAgIG9yZ2FuaXphdGlvbjogb3B0aW9ucy5vcmdhbml6YXRpb24sXG4gICAgICAgICAgICBmaWxlOiBvcHRpb25zLmZpbGUsXG4gICAgICAgICAgICB2ZXJpZnlTc2w6IG9wdGlvbnMudmVyaWZ5U3NsLFxuICAgICAgICAgICAgZHJ5UnVuOiBvcHRpb25zLmRyeVJ1bixcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbn0iXX0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Registers the `deploy` command with the CLI program.
|
|
4
|
+
*
|
|
5
|
+
* Fetches pipeline properties by ID from the platform API, then
|
|
6
|
+
* runs `cdk deploy` to provision the pipeline infrastructure in AWS.
|
|
7
|
+
* For synthesis only, use `pipeline-manager pipeline synth`.
|
|
8
|
+
*
|
|
9
|
+
* Requires service credentials to be pre-stored in AWS Secrets Manager.
|
|
10
|
+
* Create them first with: `pipeline-manager infra store-token`
|
|
11
|
+
*
|
|
12
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
13
|
+
*/
|
|
14
|
+
export declare function deploy(program: Command): void;
|
|
15
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiJ7C"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import {} from '../types/index.js';
|
|
7
|
+
import { auditLog } from '../utils/audit-log.js';
|
|
8
|
+
import { printCommandHeader, printSslWarning, createAuthenticatedClientAsync, withProfileOption, withRegionOption, withSslOptions } from '../utils/command-utils.js';
|
|
9
|
+
import { runDeploy } from '../utils/deploy-runner.js';
|
|
10
|
+
import { ERROR_CODES, handleError } from '../utils/error-handler.js';
|
|
11
|
+
import { printInfo, printKeyValue, printSuccess, printWarning } from '../utils/output-utils.js';
|
|
12
|
+
import { fetchPipelineProps, printResolvedOrExit } from '../utils/pipeline-config.js';
|
|
13
|
+
import { relaxTlsForCli } from '../utils/tls.js';
|
|
14
|
+
/**
|
|
15
|
+
* Registers the `deploy` command with the CLI program.
|
|
16
|
+
*
|
|
17
|
+
* Fetches pipeline properties by ID from the platform API, then
|
|
18
|
+
* runs `cdk deploy` to provision the pipeline infrastructure in AWS.
|
|
19
|
+
* For synthesis only, use `pipeline-manager pipeline synth`.
|
|
20
|
+
*
|
|
21
|
+
* Requires service credentials to be pre-stored in AWS Secrets Manager.
|
|
22
|
+
* Create them first with: `pipeline-manager infra store-token`
|
|
23
|
+
*
|
|
24
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
25
|
+
*/
|
|
26
|
+
export function deploy(program) {
|
|
27
|
+
withSslOptions(withRegionOption(withProfileOption(program
|
|
28
|
+
.command('deploy')
|
|
29
|
+
.description('Deploy pipeline by ID using AWS CDK, or --local-spec to deploy a local pipeline.json without the platform')
|
|
30
|
+
.option('-i, --id <id>', 'Pipeline ID (fetches config from the platform)')
|
|
31
|
+
.option('--local-spec <path>', 'Path to a local pipeline.json — deploys without contacting the platform (no auth, no compliance, no plugin lookup)'))
|
|
32
|
+
.option('--require-approval <approval>', 'Approval level: never|any-change|broadening', 'never')
|
|
33
|
+
.option('--output <dir>', 'CDK output directory', 'cdk.out')
|
|
34
|
+
.option('--store-tokens', 'Authenticate using token from AWS Secrets Manager (requires PLATFORM_SECRET_NAME env var)', false)))
|
|
35
|
+
.option('--show-resolved', 'Print the resolved pipeline config (with {{ ... }} templates expanded) and exit without deploying', false)
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
const executionId = printCommandHeader('Pipeline Deploy');
|
|
38
|
+
try {
|
|
39
|
+
// Mutually exclusive input sources — validated INSIDE the try so failures route
|
|
40
|
+
// through handleError (consistent exit code/format) like every other command.
|
|
41
|
+
if (!options.id && !options.localSpec) {
|
|
42
|
+
throw new Error('Either --id <pipeline-id> or --local-spec <path> is required');
|
|
43
|
+
}
|
|
44
|
+
if (options.id && options.localSpec) {
|
|
45
|
+
throw new Error('--id and --local-spec are mutually exclusive');
|
|
46
|
+
}
|
|
47
|
+
auditLog('deploy', { executionId, pipelineId: options.id, profile: options.profile });
|
|
48
|
+
printInfo('Deployment parameters', {
|
|
49
|
+
id: options.id,
|
|
50
|
+
awsProfile: options.profile,
|
|
51
|
+
outputDir: options.output,
|
|
52
|
+
requireApproval: options.requireApproval,
|
|
53
|
+
verifySsl: options.verifySsl,
|
|
54
|
+
});
|
|
55
|
+
// Security warning for SSL verification disabled
|
|
56
|
+
printSslWarning(options.verifySsl);
|
|
57
|
+
// Propagate to process.env so CDK constructs (Lambda, CodeBuild) inherit it,
|
|
58
|
+
// but refuse in production (see relaxTlsForCli) — the flag disables cert
|
|
59
|
+
// validation for ALL outbound TLS, including the AWS SDK.
|
|
60
|
+
relaxTlsForCli(options.verifySsl, printWarning);
|
|
61
|
+
// Local-tool prerequisites (cdk + esbuild/pnpm) are verified up front by
|
|
62
|
+
// the CLI's preAction hook, so by here they're guaranteed present.
|
|
63
|
+
let pipeline;
|
|
64
|
+
let propsWithIds;
|
|
65
|
+
// Remote-mode registry-post handles — null in --local-spec mode.
|
|
66
|
+
let platformClient;
|
|
67
|
+
let platformConfig;
|
|
68
|
+
if (options.localSpec) {
|
|
69
|
+
// --local-spec: read pipeline.json from disk; no platform contact.
|
|
70
|
+
// Compliance / quota / plugin-lookup features all require the platform —
|
|
71
|
+
// this mode is for air-gapped or simple standalone CDK deployments.
|
|
72
|
+
const absPath = path.resolve(options.localSpec);
|
|
73
|
+
printInfo('Loading local pipeline spec', { path: absPath });
|
|
74
|
+
if (!fs.existsSync(absPath)) {
|
|
75
|
+
throw new Error(`Local spec file not found: ${absPath}`);
|
|
76
|
+
}
|
|
77
|
+
const raw = fs.readFileSync(absPath, 'utf-8');
|
|
78
|
+
const parsed = JSON.parse(raw);
|
|
79
|
+
if (!parsed.props) {
|
|
80
|
+
throw new Error(`Local spec file is missing required 'props' field: ${absPath}`);
|
|
81
|
+
}
|
|
82
|
+
pipeline = {
|
|
83
|
+
id: parsed.id ?? 'local',
|
|
84
|
+
project: parsed.project ?? 'local-project',
|
|
85
|
+
organization: parsed.organization ?? 'local-org',
|
|
86
|
+
orgId: parsed.orgId,
|
|
87
|
+
isDefault: parsed.isDefault ?? false,
|
|
88
|
+
isActive: parsed.isActive ?? true,
|
|
89
|
+
props: parsed.props,
|
|
90
|
+
};
|
|
91
|
+
printSuccess('Local spec loaded');
|
|
92
|
+
printKeyValue({
|
|
93
|
+
Source: absPath,
|
|
94
|
+
Project: pipeline.project,
|
|
95
|
+
Organization: pipeline.organization,
|
|
96
|
+
});
|
|
97
|
+
propsWithIds = {
|
|
98
|
+
...pipeline.props,
|
|
99
|
+
...(pipeline.orgId && { orgId: pipeline.orgId }),
|
|
100
|
+
pipelineId: pipeline.id,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Remote path: fetch config from platform API. fetchPipelineProps does
|
|
105
|
+
// the fetch + plugin pre-resolution + registry pull-host bake — shared
|
|
106
|
+
// verbatim with `synth` so the two never drift.
|
|
107
|
+
platformClient = await createAuthenticatedClientAsync(options);
|
|
108
|
+
platformConfig = platformClient.getConfig();
|
|
109
|
+
printInfo('Fetching pipeline configuration', { id: options.id });
|
|
110
|
+
const fetched = await fetchPipelineProps(platformClient, options.id);
|
|
111
|
+
pipeline = fetched.pipeline;
|
|
112
|
+
propsWithIds = fetched.propsWithIds;
|
|
113
|
+
printSuccess('Pipeline configuration retrieved');
|
|
114
|
+
printKeyValue({
|
|
115
|
+
'ID': pipeline.id,
|
|
116
|
+
'Project': pipeline.project,
|
|
117
|
+
'Organization': pipeline.organization,
|
|
118
|
+
'Is Default': pipeline.isDefault,
|
|
119
|
+
'Is Active': pipeline.isActive,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// --show-resolved: print resolved config and exit (no CDK deploy)
|
|
123
|
+
if (options.showResolved) {
|
|
124
|
+
await printResolvedOrExit(propsWithIds);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Steps 5–9 (encode props → cdk deploy → register ARN) are shared with
|
|
128
|
+
// `pipeline create --deploy` via runDeploy so the two never drift.
|
|
129
|
+
await runDeploy({
|
|
130
|
+
pipeline,
|
|
131
|
+
propsWithIds,
|
|
132
|
+
profile: options.profile,
|
|
133
|
+
region: options.region,
|
|
134
|
+
requireApproval: options.requireApproval,
|
|
135
|
+
output: options.output,
|
|
136
|
+
debug: program.opts().debug,
|
|
137
|
+
executionId,
|
|
138
|
+
platformClient,
|
|
139
|
+
platformPipelineUrl: platformConfig?.api.pipelineUrl,
|
|
140
|
+
platformBaseUrl: platformConfig?.api.baseUrl,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
handleError(error, ERROR_CODES.API_REQUEST, {
|
|
145
|
+
debug: program.opts().debug,
|
|
146
|
+
exit: true,
|
|
147
|
+
context: {
|
|
148
|
+
command: 'deploy',
|
|
149
|
+
executionId,
|
|
150
|
+
pipelineId: options.id,
|
|
151
|
+
verifySsl: options.verifySsl,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2RlcGxveS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxFQUE0QyxNQUFNLG1CQUFtQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUFFLDhCQUE4QixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JLLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFakQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLE9BQWdCO0lBQ3JDLGNBQWMsQ0FDWixnQkFBZ0IsQ0FDZCxpQkFBaUIsQ0FBQyxPQUFPO1NBQ3RCLE9BQU8sQ0FBQyxRQUFRLENBQUM7U0FDakIsV0FBVyxDQUFDLDJHQUEyRyxDQUFDO1NBQ3hILE1BQU0sQ0FBQyxlQUFlLEVBQUUsZ0RBQWdELENBQUM7U0FDekUsTUFBTSxD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SUFBSTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsT0FBTyxFQUFFLFFBQVE7b0JBQ2pCLFdBQVc7b0JBQ1gsVUFBVSxFQUFFLE9BQU8sQ0FBQyxFQUFFO29CQUN0QixTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7aUJBQzdCO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdub2RlOmZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHsgdHlwZSBQaXBlbGluZSwgdHlwZSBQbGF0Zm9ybURlcGxveUNvbmZpZyB9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcbmltcG9ydCB7IGF1ZGl0TG9nIH0gZnJvbSAnLi4vdXRpbHMvYXVkaXQtbG9nLmpzJztcbmltcG9ydCB7IHByaW50Q29tbWFuZEhlYWRlciwgcHJpbnRTc2xXYXJuaW5nLCBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50QXN5bmMsIHdpdGhQcm9maWxlT3B0aW9uLCB3aXRoUmVnaW9uT3B0aW9uLCB3aXRoU3NsT3B0aW9ucyB9IGZyb20gJy4uL3V0aWxzL2NvbW1hbmQtdXRpbHMuanMnO1xuaW1wb3J0IHsgcnVuRGVwbG95IH0gZnJvbSAnLi4vdXRpbHMvZGVwbG95LXJ1bm5lci5qcyc7XG5pbXBvcnQgeyBFUlJPUl9DT0RFUywgaGFuZGxlRXJyb3IgfSBmcm9tICcuLi91dGlscy9lcnJvci1oYW5kbGVyLmpzJztcbmltcG9ydCB7IHByaW50SW5mbywgcHJpbnRLZXlWYWx1ZSwgcHJpbnRTdWNjZXNzLCBwcmludFdhcm5pbmcgfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMuanMnO1xuaW1wb3J0IHsgZmV0Y2hQaXBlbGluZVByb3BzLCBwcmludFJlc29sdmVkT3JFeGl0IH0gZnJvbSAnLi4vdXRpbHMvcGlwZWxpbmUtY29uZmlnLmpzJztcbmltcG9ydCB7IHJlbGF4VGxzRm9yQ2xpIH0gZnJvbSAnLi4vdXRpbHMvdGxzLmpzJztcblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIGBkZXBsb3lgIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogRmV0Y2hlcyBwaXBlbGluZSBwcm9wZXJ0aWVzIGJ5IElEIGZyb20gdGhlIHBsYXRmb3JtIEFQSSwgdGhlblxuICogcnVucyBgY2RrIGRlcGxveWAgdG8gcHJvdmlzaW9uIHRoZSBwaXBlbGluZSBpbmZyYXN0cnVjdHVyZSBpbiBBV1MuXG4gKiBGb3Igc3ludGhlc2lzIG9ubHksIHVzZSBgcGlwZWxpbmUtbWFuYWdlciBwaXBlbGluZSBzeW50aGAuXG4gKlxuICogUmVxdWlyZXMgc2VydmljZSBjcmVkZW50aWFscyB0byBiZSBwcmUtc3RvcmVkIGluIEFXUyBTZWNyZXRzIE1hbmFnZXIuXG4gKiBDcmVhdGUgdGhlbSBmaXJzdCB3aXRoOiBgcGlwZWxpbmUtbWFuYWdlciBpbmZyYSBzdG9yZS10b2tlbmBcbiAqXG4gKiBAcGFyYW0gcHJvZ3JhbSAtIFRoZSByb290IENvbW1hbmRlciBwcm9ncmFtIGluc3RhbmNlIHRvIGF0dGFjaCB0aGUgY29tbWFuZCB0by5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcGxveShwcm9ncmFtOiBDb21tYW5kKTogdm9pZCB7XG4gIHdpdGhTc2xPcHRpb25zKFxuICAgIHdpdGhSZWdpb25PcHRpb24oXG4gICAgICB3aXRoUHJvZmlsZU9wdGlvbihwcm9ncmFtXG4gICAgICAgIC5jb21tYW5kKCdkZXBsb3knKVxuICAgICAgICAuZGVzY3JpcHRpb24oJ0RlcGxveSBwaXBlbGluZSBieSBJRCB1c2luZyBBV1MgQ0RLLCBvciAtLWxvY2FsLXNwZWMgdG8gZGVwbG95IGEgbG9jYWwgcGlwZWxpbmUuanNvbiB3aXRob3V0IHRoZSBwbGF0Zm9ybScpXG4gICAgICAgIC5vcHRpb24oJy1pLCAtLWlkIDxpZD4nLCAnUGlwZWxpbmUgSUQgKGZldGNoZXMgY29uZmlnIGZyb20gdGhlIHBsYXRmb3JtKScpXG4gICAgICAgIC5vcHRpb24oJy0tbG9jYWwtc3BlYyA8cGF0aD4nLCAnUGF0aCB0byBhIGxvY2FsIHBpcGVsaW5lLmpzb24g4oCUIGRlcGxveXMgd2l0aG91dCBjb250YWN0aW5nIHRoZSBwbGF0Zm9ybSAobm8gYXV0aCwgbm8gY29tcGxpYW5jZSwgbm8gcGx1Z2luIGxvb2t1cCknKSlcbiAgICAgICAgLm9wdGlvbignLS1yZXF1aXJlLWFwcHJvdmFsIDxhcHByb3ZhbD4nLCAnQXBwcm92YWwgbGV2ZWw6IG5ldmVyfGFueS1jaGFuZ2V8YnJvYWRlbmluZycsICduZXZlcicpXG4gICAgICAgIC5vcHRpb24oJy0tb3V0cHV0IDxkaXI+JywgJ0NESyBvdXRwdXQgZGlyZWN0b3J5JywgJ2Nkay5vdXQnKVxuICAgICAgICAub3B0aW9uKCctLXN0b3JlLXRva2VucycsICdBdXRoZW50aWNhdGUgdXNpbmcgdG9rZW4gZnJvbSBBV1MgU2VjcmV0cyBNYW5hZ2VyIChyZXF1aXJlcyBQTEFURk9STV9TRUNSRVRfTkFNRSBlbnYgdmFyKScsIGZhbHNlKSxcbiAgICApLFxuICApXG4gICAgLm9wdGlvbignLS1zaG93LXJlc29sdmVkJywgJ1ByaW50IHRoZSByZXNvbHZlZCBwaXBlbGluZSBjb25maWcgKHdpdGgge3sgLi4uIH19IHRlbXBsYXRlcyBleHBhbmRlZCkgYW5kIGV4aXQgd2l0aG91dCBkZXBsb3lpbmcnLCBmYWxzZSlcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCBleGVjdXRpb25JZCA9IHByaW50Q29tbWFuZEhlYWRlcignUGlwZWxpbmUgRGVwbG95Jyk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIE11dHVhbGx5IGV4Y2x1c2l2ZSBpbnB1dCBzb3VyY2VzIOKAlCB2YWxpZGF0ZWQgSU5TSURFIHRoZSB0cnkgc28gZmFpbHVyZXMgcm91dGVcbiAgICAgICAgLy8gdGhyb3VnaCBoYW5kbGVFcnJvciAoY29uc2lzdGVudCBleGl0IGNvZGUvZm9ybWF0KSBsaWtlIGV2ZXJ5IG90aGVyIGNvbW1hbmQuXG4gICAgICAgIGlmICghb3B0aW9ucy5pZCAmJiAhb3B0aW9ucy5sb2NhbFNwZWMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciAtLWlkIDxwaXBlbGluZS1pZD4gb3IgLS1sb2NhbC1zcGVjIDxwYXRoPiBpcyByZXF1aXJlZCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHRpb25zLmlkICYmIG9wdGlvbnMubG9jYWxTcGVjKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCctLWlkIGFuZCAtLWxvY2FsLXNwZWMgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXVkaXRMb2coJ2RlcGxveScsIHsgZXhlY3V0aW9uSWQsIHBpcGVsaW5lSWQ6IG9wdGlvbnMuaWQsIHByb2ZpbGU6IG9wdGlvbnMucHJvZmlsZSB9KTtcblxuICAgICAgICBwcmludEluZm8oJ0RlcGxveW1lbnQgcGFyYW1ldGVycycsIHtcbiAgICAgICAgICBpZDogb3B0aW9ucy5pZCxcbiAgICAgICAgICBhd3NQcm9maWxlOiBvcHRpb25zLnByb2ZpbGUsXG4gICAgICAgICAgb3V0cHV0RGlyOiBvcHRpb25zLm91dHB1dCxcbiAgICAgICAgICByZXF1aXJlQXBwcm92YWw6IG9wdGlvbnMucmVxdWlyZUFwcHJvdmFsLFxuICAgICAgICAgIHZlcmlmeVNzbDogb3B0aW9ucy52ZXJpZnlTc2wsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNlY3VyaXR5IHdhcm5pbmcgZm9yIFNTTCB2ZXJpZmljYXRpb24gZGlzYWJsZWRcbiAgICAgICAgcHJpbnRTc2xXYXJuaW5nKG9wdGlvbnMudmVyaWZ5U3NsKTtcblxuICAgICAgICAvLyBQcm9wYWdhdGUgdG8gcHJvY2Vzcy5lbnYgc28gQ0RLIGNvbnN0cnVjdHMgKExhbWJkYSwgQ29kZUJ1aWxkKSBpbmhlcml0IGl0LFxuICAgICAgICAvLyBidXQgcmVmdXNlIGluIHByb2R1Y3Rpb24gKHNlZSByZWxheFRsc0ZvckNsaSkg4oCUIHRoZSBmbGFnIGRpc2FibGVzIGNlcnRcbiAgICAgICAgLy8gdmFsaWRhdGlvbiBmb3IgQUxMIG91dGJvdW5kIFRMUywgaW5jbHVkaW5nIHRoZSBBV1MgU0RLLlxuICAgICAgICByZWxheFRsc0ZvckNsaShvcHRpb25zLnZlcmlmeVNzbCwgcHJpbnRXYXJuaW5nKTtcblxuICAgICAgICAvLyBMb2NhbC10b29sIHByZXJlcXVpc2l0ZXMgKGNkayArIGVzYnVpbGQvcG5wbSkgYXJlIHZlcmlmaWVkIHVwIGZyb250IGJ5XG4gICAgICAgIC8vIHRoZSBDTEkncyBwcmVBY3Rpb24gaG9vaywgc28gYnkgaGVyZSB0aGV5J3JlIGd1YXJhbnRlZWQgcHJlc2VudC5cblxuICAgICAgICBsZXQgcGlwZWxpbmU6IFBpcGVsaW5lO1xuICAgICAgICBsZXQgcHJvcHNXaXRoSWRzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgLy8gUmVtb3RlLW1vZGUgcmVnaXN0cnktcG9zdCBoYW5kbGVzIOKAlCBudWxsIGluIC0tbG9jYWwtc3BlYyBtb2RlLlxuICAgICAgICBsZXQgcGxhdGZvcm1DbGllbnQ6IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlQXV0aGVudGljYXRlZENsaWVudEFzeW5jPj4gfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBwbGF0Zm9ybUNvbmZpZzogUGxhdGZvcm1EZXBsb3lDb25maWcgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubG9jYWxTcGVjKSB7XG4gICAgICAgICAgLy8gLS1sb2NhbC1zcGVjOiByZWFkIHBpcGVsaW5lLmpzb24gZnJvbSBkaXNrOyBubyBwbGF0Zm9ybSBjb250YWN0LlxuICAgICAgICAgIC8vIENvbXBsaWFuY2UgLyBxdW90YSAvIHBsdWdpbi1sb29rdXAgZmVhdHVyZXMgYWxsIHJlcXVpcmUgdGhlIHBsYXRmb3JtIOKAlFxuICAgICAgICAgIC8vIHRoaXMgbW9kZSBpcyBmb3IgYWlyLWdhcHBlZCBvciBzaW1wbGUgc3RhbmRhbG9uZSBDREsgZGVwbG95bWVudHMuXG4gICAgICAgICAgY29uc3QgYWJzUGF0aCA9IHBhdGgucmVzb2x2ZShvcHRpb25zLmxvY2FsU3BlYyk7XG4gICAgICAgICAgcHJpbnRJbmZvKCdMb2FkaW5nIGxvY2FsIHBpcGVsaW5lIHNwZWMnLCB7IHBhdGg6IGFic1BhdGggfSk7XG4gICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGFic1BhdGgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYExvY2FsIHNwZWMgZmlsZSBub3QgZm91bmQ6ICR7YWJzUGF0aH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKGFic1BhdGgsICd1dGYtOCcpO1xuICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KSBhcyBQYXJ0aWFsPFBpcGVsaW5lPiAmIHsgcHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9O1xuICAgICAgICAgIGlmICghcGFyc2VkLnByb3BzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYExvY2FsIHNwZWMgZmlsZSBpcyBtaXNzaW5nIHJlcXVpcmVkICdwcm9wcycgZmllbGQ6ICR7YWJzUGF0aH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGlwZWxpbmUgPSB7XG4gICAgICAgICAgICBpZDogcGFyc2VkLmlkID8/ICdsb2NhbCcsXG4gICAgICAgICAgICBwcm9qZWN0OiBwYXJzZWQucHJvamVjdCA/PyAnbG9jYWwtcHJvamVjdCcsXG4gICAgICAgICAgICBvcmdhbml6YXRpb246IHBhcnNlZC5vcmdhbml6YXRpb24gPz8gJ2xvY2FsLW9yZycsXG4gICAgICAgICAgICBvcmdJZDogcGFyc2VkLm9yZ0lkLFxuICAgICAgICAgICAgaXNEZWZhdWx0OiBwYXJzZWQuaXNEZWZhdWx0ID8/IGZhbHNlLFxuICAgICAgICAgICAgaXNBY3RpdmU6IHBhcnNlZC5pc0FjdGl2ZSA/PyB0cnVlLFxuICAgICAgICAgICAgcHJvcHM6IHBhcnNlZC5wcm9wcyxcbiAgICAgICAgICB9IGFzIFBpcGVsaW5lO1xuICAgICAgICAgIHByaW50U3VjY2VzcygnTG9jYWwgc3BlYyBsb2FkZWQnKTtcbiAgICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAgIFNvdXJjZTogYWJzUGF0aCxcbiAgICAgICAgICAgIFByb2plY3Q6IHBpcGVsaW5lLnByb2plY3QsXG4gICAgICAgICAgICBPcmdhbml6YXRpb246IHBpcGVsaW5lLm9yZ2FuaXphdGlvbixcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBwcm9wc1dpdGhJZHMgPSB7XG4gICAgICAgICAgICAuLi5waXBlbGluZS5wcm9wcyxcbiAgICAgICAgICAgIC4uLihwaXBlbGluZS5vcmdJZCAmJiB7IG9yZ0lkOiBwaXBlbGluZS5vcmdJZCB9KSxcbiAgICAgICAgICAgIHBpcGVsaW5lSWQ6IHBpcGVsaW5lLmlkLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVtb3RlIHBhdGg6IGZldGNoIGNvbmZpZyBmcm9tIHBsYXRmb3JtIEFQSS4gZmV0Y2hQaXBlbGluZVByb3BzIGRvZXNcbiAgICAgICAgICAvLyB0aGUgZmV0Y2ggKyBwbHVnaW4gcHJlLXJlc29sdXRpb24gKyByZWdpc3RyeSBwdWxsLWhvc3QgYmFrZSDigJQgc2hhcmVkXG4gICAgICAgICAgLy8gdmVyYmF0aW0gd2l0aCBgc3ludGhgIHNvIHRoZSB0d28gbmV2ZXIgZHJpZnQuXG4gICAgICAgICAgcGxhdGZvcm1DbGllbnQgPSBhd2FpdCBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50QXN5bmMob3B0aW9ucyk7XG4gICAgICAgICAgcGxhdGZvcm1Db25maWcgPSBwbGF0Zm9ybUNsaWVudC5nZXRDb25maWcoKSBhcyBQbGF0Zm9ybURlcGxveUNvbmZpZztcblxuICAgICAgICAgIHByaW50SW5mbygnRmV0Y2hpbmcgcGlwZWxpbmUgY29uZmlndXJhdGlvbicsIHsgaWQ6IG9wdGlvbnMuaWQgfSk7XG4gICAgICAgICAgY29uc3QgZmV0Y2hlZCA9IGF3YWl0IGZldGNoUGlwZWxpbmVQcm9wcyhwbGF0Zm9ybUNsaWVudCwgb3B0aW9ucy5pZCk7XG4gICAgICAgICAgcGlwZWxpbmUgPSBmZXRjaGVkLnBpcGVsaW5lO1xuICAgICAgICAgIHByb3BzV2l0aElkcyA9IGZldGNoZWQucHJvcHNXaXRoSWRzO1xuXG4gICAgICAgICAgcHJpbnRTdWNjZXNzKCdQaXBlbGluZSBjb25maWd1cmF0aW9uIHJldHJpZXZlZCcpO1xuICAgICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICAgJ0lEJzogcGlwZWxpbmUuaWQsXG4gICAgICAgICAgICAnUHJvamVjdCc6IHBpcGVsaW5lLnByb2plY3QsXG4gICAgICAgICAgICAnT3JnYW5pemF0aW9uJzogcGlwZWxpbmUub3JnYW5pemF0aW9uLFxuICAgICAgICAgICAgJ0lzIERlZmF1bHQnOiBwaXBlbGluZS5pc0RlZmF1bHQsXG4gICAgICAgICAgICAnSXMgQWN0aXZlJzogcGlwZWxpbmUuaXNBY3RpdmUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAtLXNob3ctcmVzb2x2ZWQ6IHByaW50IHJlc29sdmVkIGNvbmZpZyBhbmQgZXhpdCAobm8gQ0RLIGRlcGxveSlcbiAgICAgICAgaWYgKChvcHRpb25zIGFzIHsgc2hvd1Jlc29sdmVkPzogYm9vbGVhbiB9KS5zaG93UmVzb2x2ZWQpIHtcbiAgICAgICAgICBhd2FpdCBwcmludFJlc29sdmVkT3JFeGl0KHByb3BzV2l0aElkcyk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RlcHMgNeKAkzkgKGVuY29kZSBwcm9wcyDihpIgY2RrIGRlcGxveSDihpIgcmVnaXN0ZXIgQVJOKSBhcmUgc2hhcmVkIHdpdGhcbiAgICAgICAgLy8gYHBpcGVsaW5lIGNyZWF0ZSAtLWRlcGxveWAgdmlhIHJ1bkRlcGxveSBzbyB0aGUgdHdvIG5ldmVyIGRyaWZ0LlxuICAgICAgICBhd2FpdCBydW5EZXBsb3koe1xuICAgICAgICAgIHBpcGVsaW5lLFxuICAgICAgICAgIHByb3BzV2l0aElkcyxcbiAgICAgICAgICBwcm9maWxlOiBvcHRpb25zLnByb2ZpbGUsXG4gICAgICAgICAgcmVnaW9uOiBvcHRpb25zLnJlZ2lvbixcbiAgICAgICAgICByZXF1aXJlQXBwcm92YWw6IG9wdGlvbnMucmVxdWlyZUFwcHJvdmFsLFxuICAgICAgICAgIG91dHB1dDogb3B0aW9ucy5vdXRwdXQsXG4gICAgICAgICAgZGVidWc6IHByb2dyYW0ub3B0cygpLmRlYnVnLFxuICAgICAgICAgIGV4ZWN1dGlvbklkLFxuICAgICAgICAgIHBsYXRmb3JtQ2xpZW50LFxuICAgICAgICAgIHBsYXRmb3JtUGlwZWxpbmVVcmw6IHBsYXRmb3JtQ29uZmlnPy5hcGkucGlwZWxpbmVVcmwsXG4gICAgICAgICAgcGxhdGZvcm1CYXNlVXJsOiBwbGF0Zm9ybUNvbmZpZz8uYXBpLmJhc2VVcmwsXG4gICAgICAgIH0pO1xuXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBoYW5kbGVFcnJvcihlcnJvciwgRVJST1JfQ09ERVMuQVBJX1JFUVVFU1QsIHtcbiAgICAgICAgICBkZWJ1ZzogcHJvZ3JhbS5vcHRzKCkuZGVidWcsXG4gICAgICAgICAgZXhpdDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICBjb21tYW5kOiAnZGVwbG95JyxcbiAgICAgICAgICAgIGV4ZWN1dGlvbklkLFxuICAgICAgICAgICAgcGlwZWxpbmVJZDogb3B0aW9ucy5pZCxcbiAgICAgICAgICAgIHZlcmlmeVNzbDogb3B0aW9ucy52ZXJpZnlTc2wsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG59XG4iXX0=
|