@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,275 @@
|
|
|
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 FormData from 'form-data';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import pico from 'picocolors';
|
|
9
|
+
import { FILE_SIZE_LIMITS, formatFileSize } from '../config/cli.constants.js';
|
|
10
|
+
import {} from '../types/index.js';
|
|
11
|
+
import { printCommandHeader, printSslWarning, createAuthenticatedClient, withSslOptions } from '../utils/command-utils.js';
|
|
12
|
+
import { ERROR_CODES, handleError, ValidationError } from '../utils/error-handler.js';
|
|
13
|
+
import { fileExists, printError, printInfo, printKeyValue, printSection, printSuccess, printWarning } from '../utils/output-utils.js';
|
|
14
|
+
import { extractSingleResponse } from '../utils/response-utils.js';
|
|
15
|
+
const { bold, green } = pico;
|
|
16
|
+
/**
|
|
17
|
+
* Registers the `upload-plugin` command with the CLI program.
|
|
18
|
+
*
|
|
19
|
+
* Validates a local plugin ZIP file (size, extension, readability),
|
|
20
|
+
* builds a multipart form, and uploads it to the platform API.
|
|
21
|
+
* Plugin name and version can be auto-detected from the package
|
|
22
|
+
* or overridden via CLI flags.
|
|
23
|
+
*
|
|
24
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```bash
|
|
28
|
+
* cli plugin upload --file plugin.zip --organization acme
|
|
29
|
+
* cli plugin upload --file plugin.zip --organization acme --public
|
|
30
|
+
* cli plugin upload --file plugin.zip --organization acme --name my-plugin --version 1.0.0
|
|
31
|
+
* cli plugin upload --file plugin.zip --organization acme --no-verify-ssl
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function uploadPlugin(program) {
|
|
35
|
+
withSslOptions(program
|
|
36
|
+
.command('upload')
|
|
37
|
+
.description('Upload and deploy a plugin package')
|
|
38
|
+
.requiredOption('-f, --file <file>', 'Path to plugin ZIP file')
|
|
39
|
+
.requiredOption('-o, --organization <organization>', 'Organization name')
|
|
40
|
+
.option('-n, --name <name>', 'Plugin name (optional, extracted from package if not provided)')
|
|
41
|
+
.option('-v, --version <version>', 'Plugin version (optional, extracted from package if not provided)')
|
|
42
|
+
.option('--public', 'Make plugin publicly accessible', false)
|
|
43
|
+
.option('--active', 'Set plugin as active', true)
|
|
44
|
+
.option('--no-active', 'Upload the plugin as inactive'))
|
|
45
|
+
.option('--dry-run', 'Validate file without uploading', false)
|
|
46
|
+
.action(async (options) => {
|
|
47
|
+
const executionId = printCommandHeader('Upload Plugin');
|
|
48
|
+
try {
|
|
49
|
+
// Display parameters
|
|
50
|
+
printInfo('Upload parameters', {
|
|
51
|
+
file: options.file,
|
|
52
|
+
organization: options.organization,
|
|
53
|
+
name: options.name || '(auto-detect)',
|
|
54
|
+
version: options.version || '(auto-detect)',
|
|
55
|
+
public: options.public ? 'Yes' : 'No',
|
|
56
|
+
active: options.active ? 'Yes' : 'No',
|
|
57
|
+
dryRun: options.dryRun,
|
|
58
|
+
verifySsl: options.verifySsl,
|
|
59
|
+
});
|
|
60
|
+
// Security warning for SSL verification disabled
|
|
61
|
+
printSslWarning(options.verifySsl);
|
|
62
|
+
// Validate organization
|
|
63
|
+
if (!options.organization || typeof options.organization !== 'string' || options.organization.trim().length === 0) {
|
|
64
|
+
printError('Invalid organization name', { provided: options.organization });
|
|
65
|
+
throw new ValidationError('Organization must be a non-empty string', 'organization', options.organization);
|
|
66
|
+
}
|
|
67
|
+
// Validate file path
|
|
68
|
+
if (!options.file || typeof options.file !== 'string' || options.file.trim().length === 0) {
|
|
69
|
+
printError('Invalid file path', { provided: options.file });
|
|
70
|
+
throw new ValidationError('File path must be a non-empty string', 'file', options.file);
|
|
71
|
+
}
|
|
72
|
+
const filePath = path.resolve(options.file);
|
|
73
|
+
// Validate file exists
|
|
74
|
+
printInfo('Validating plugin file', { path: filePath });
|
|
75
|
+
if (!fileExists(filePath)) {
|
|
76
|
+
printError('Plugin file not found', { path: filePath });
|
|
77
|
+
throw new ValidationError(`Plugin file not found: ${filePath}`, 'file', filePath);
|
|
78
|
+
}
|
|
79
|
+
// Validate file extension
|
|
80
|
+
const fileExt = path.extname(filePath).toLowerCase();
|
|
81
|
+
if (fileExt !== '.zip') {
|
|
82
|
+
printWarning('File extension is not .zip', {
|
|
83
|
+
provided: fileExt,
|
|
84
|
+
expected: '.zip',
|
|
85
|
+
});
|
|
86
|
+
throw new ValidationError('Plugin file must be a ZIP archive', 'file', filePath);
|
|
87
|
+
}
|
|
88
|
+
// Get file stats
|
|
89
|
+
const stats = fs.statSync(filePath);
|
|
90
|
+
const sizeBytes = stats.size;
|
|
91
|
+
const sizeFormatted = formatFileSize(sizeBytes);
|
|
92
|
+
printSuccess('Plugin file found', {
|
|
93
|
+
path: filePath,
|
|
94
|
+
size: sizeFormatted,
|
|
95
|
+
modified: new Date(stats.mtime).toLocaleString(),
|
|
96
|
+
});
|
|
97
|
+
// Check file size
|
|
98
|
+
if (sizeBytes > FILE_SIZE_LIMITS.PLUGIN) {
|
|
99
|
+
printError('Plugin file too large', {
|
|
100
|
+
size: sizeFormatted,
|
|
101
|
+
maximum: formatFileSize(FILE_SIZE_LIMITS.PLUGIN),
|
|
102
|
+
exceededBy: formatFileSize(sizeBytes - FILE_SIZE_LIMITS.PLUGIN),
|
|
103
|
+
});
|
|
104
|
+
throw new ValidationError(`Plugin file exceeds maximum size of ${formatFileSize(FILE_SIZE_LIMITS.PLUGIN)} (actual: ${sizeFormatted})`, 'file.size', sizeBytes);
|
|
105
|
+
}
|
|
106
|
+
// Check if file is readable
|
|
107
|
+
try {
|
|
108
|
+
fs.accessSync(filePath, fs.constants.R_OK);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
printError('Cannot read plugin file', {
|
|
112
|
+
path: filePath,
|
|
113
|
+
error: error instanceof Error ? error.message : String(error),
|
|
114
|
+
});
|
|
115
|
+
throw new ValidationError('Plugin file is not readable', 'file', filePath);
|
|
116
|
+
}
|
|
117
|
+
printSuccess('Plugin file validated');
|
|
118
|
+
// Validate version format if provided. Allows -prerelease and +build
|
|
119
|
+
// metadata (valid semver) to match validate-plugin and the DB constraint.
|
|
120
|
+
if (options.version) {
|
|
121
|
+
const versionRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/;
|
|
122
|
+
if (!versionRegex.test(options.version)) {
|
|
123
|
+
printWarning('Version format may be invalid', {
|
|
124
|
+
provided: options.version,
|
|
125
|
+
expected: 'semantic version (e.g., 1.0.0, 1.2.3-beta.1)',
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Validate name format if provided
|
|
130
|
+
if (options.name) {
|
|
131
|
+
const nameRegex = /^[a-z0-9-]+$/;
|
|
132
|
+
if (!nameRegex.test(options.name)) {
|
|
133
|
+
printWarning('Plugin name format may be invalid', {
|
|
134
|
+
provided: options.name,
|
|
135
|
+
expected: 'lowercase alphanumeric with dashes (e.g., my-plugin-name)',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Dry run mode
|
|
140
|
+
if (options.dryRun) {
|
|
141
|
+
console.log('');
|
|
142
|
+
printSection('Dry Run - Validation Complete');
|
|
143
|
+
printSuccess('File validation passed - no upload performed');
|
|
144
|
+
printKeyValue({
|
|
145
|
+
File: filePath,
|
|
146
|
+
Size: sizeFormatted,
|
|
147
|
+
Organization: options.organization,
|
|
148
|
+
Name: options.name || '(will be auto-detected)',
|
|
149
|
+
Version: options.version || '(will be auto-detected)',
|
|
150
|
+
Public: options.public ? 'Yes' : 'No',
|
|
151
|
+
Active: options.active ? 'Yes' : 'No',
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Create authenticated API client
|
|
156
|
+
const client = createAuthenticatedClient(options);
|
|
157
|
+
const config = client.getConfig();
|
|
158
|
+
// Create form data
|
|
159
|
+
console.log('');
|
|
160
|
+
printSection('Uploading Plugin');
|
|
161
|
+
printInfo('Preparing upload', {
|
|
162
|
+
file: path.basename(filePath),
|
|
163
|
+
size: sizeFormatted,
|
|
164
|
+
});
|
|
165
|
+
const formData = new FormData();
|
|
166
|
+
formData.append('plugin', fs.createReadStream(filePath), {
|
|
167
|
+
filename: path.basename(filePath),
|
|
168
|
+
contentType: 'application/zip',
|
|
169
|
+
});
|
|
170
|
+
formData.append('organization', options.organization);
|
|
171
|
+
if (options.name)
|
|
172
|
+
formData.append('name', options.name);
|
|
173
|
+
if (options.version)
|
|
174
|
+
formData.append('version', options.version);
|
|
175
|
+
formData.append('isPublic', options.public ? 'true' : 'false');
|
|
176
|
+
formData.append('isActive', options.active ? 'true' : 'false');
|
|
177
|
+
// Make API request
|
|
178
|
+
const endpoint = config.api.pluginUploadUrl;
|
|
179
|
+
printInfo('Uploading to API', {
|
|
180
|
+
endpoint: `${config.api.baseUrl}${endpoint}`,
|
|
181
|
+
});
|
|
182
|
+
console.log('');
|
|
183
|
+
const spinner = ora('Uploading plugin...').start();
|
|
184
|
+
let rawResponse;
|
|
185
|
+
let duration;
|
|
186
|
+
try {
|
|
187
|
+
const startTime = Date.now();
|
|
188
|
+
rawResponse = await client.postForm(endpoint, formData);
|
|
189
|
+
duration = Date.now() - startTime;
|
|
190
|
+
spinner.succeed('Plugin uploaded');
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
spinner.fail('Upload failed');
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
const response = extractSingleResponse(rawResponse, 'plugin', 'name');
|
|
197
|
+
if (!response) {
|
|
198
|
+
printError('No valid plugin data in response', {
|
|
199
|
+
responseKeys: rawResponse ? Object.keys(rawResponse) : '(null)',
|
|
200
|
+
});
|
|
201
|
+
throw new Error('Upload failed - no valid plugin data received');
|
|
202
|
+
}
|
|
203
|
+
console.log('');
|
|
204
|
+
printSection('Plugin Uploaded Successfully');
|
|
205
|
+
// Display plugin information
|
|
206
|
+
printKeyValue({
|
|
207
|
+
'Plugin ID': green(bold(response.id)),
|
|
208
|
+
'Name': response.name,
|
|
209
|
+
'Version': response.version,
|
|
210
|
+
'Organization': response.organization,
|
|
211
|
+
'Description': response.description || '(not set)',
|
|
212
|
+
});
|
|
213
|
+
console.log('');
|
|
214
|
+
printKeyValue({
|
|
215
|
+
'File URL': response.fileUrl || '(not available)',
|
|
216
|
+
'File Size': response.fileSize ? `${(response.fileSize / 1024).toFixed(2)} KB` : '(not available)',
|
|
217
|
+
'Checksum': response.checksum ? `${response.checksum.substring(0, 16)}...` : '(not available)',
|
|
218
|
+
});
|
|
219
|
+
console.log('');
|
|
220
|
+
printKeyValue({
|
|
221
|
+
'Public': response.isPublic ? 'Yes' : 'No',
|
|
222
|
+
'Active': response.isActive ? 'Yes' : 'No',
|
|
223
|
+
'Created At': response.createdAt || '(not available)',
|
|
224
|
+
'Uploaded By': response.uploadedBy || '(not available)',
|
|
225
|
+
});
|
|
226
|
+
console.log('');
|
|
227
|
+
printKeyValue({
|
|
228
|
+
'Execution ID': executionId,
|
|
229
|
+
'Upload Duration': `${(duration / 1000).toFixed(2)}s`,
|
|
230
|
+
'Status': green('✓ Success'),
|
|
231
|
+
});
|
|
232
|
+
// Print additional information if available
|
|
233
|
+
if (response.metadata) {
|
|
234
|
+
console.log('');
|
|
235
|
+
printInfo('Plugin metadata available', {
|
|
236
|
+
keys: Object.keys(response.metadata).length,
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// Print deployment logs URL if available
|
|
240
|
+
const resp = response;
|
|
241
|
+
const requestId = resp['X-Request-Id'] || resp.requestId;
|
|
242
|
+
if (requestId) {
|
|
243
|
+
console.log('');
|
|
244
|
+
printInfo('Deployment logs available', {
|
|
245
|
+
requestId,
|
|
246
|
+
url: `${config.api.baseUrl}/logs/${requestId}`,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
// Next steps
|
|
250
|
+
console.log('');
|
|
251
|
+
printInfo('Next steps', {
|
|
252
|
+
view: `Use "get-plugin --id ${response.id}" to view plugin details`,
|
|
253
|
+
list: 'Use "list-plugins" to see all plugins',
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
handleError(error, ERROR_CODES.API_REQUEST, {
|
|
258
|
+
debug: program.opts().debug,
|
|
259
|
+
exit: true,
|
|
260
|
+
context: {
|
|
261
|
+
command: 'upload-plugin',
|
|
262
|
+
executionId,
|
|
263
|
+
file: options.file,
|
|
264
|
+
organization: options.organization,
|
|
265
|
+
name: options.name,
|
|
266
|
+
version: options.version,
|
|
267
|
+
public: options.public,
|
|
268
|
+
active: options.active,
|
|
269
|
+
verifySsl: options.verifySsl,
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy91cGxvYWQtcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLFFBQVEsTUFBTSxXQUFXLENBQUM7QUFDakMsT0FBTyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBQ3RCLE9BQU8sSUFBSSxNQUFNLFlBQVksQ0FBQztBQUM5QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUFvQyxNQUFNLG1CQUFtQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxlQUFlLEVBQUUseUJBQXlCLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDM0gsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEYsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RJLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRW5FLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRTdCOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsT0FBZ0I7SUFDM0MsY0FBYyxDQUFDLE9BQU87U0FDbkIsT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMsb0NBQW9DLENBQUM7U0FDakQsY0FBYyxDQUFDLG1CQUFtQixFQUFFLHlCQUF5QixDQUFDO1NBQzlELGNBQWMsQ0FBQyxtQ0FBbUMsRUFBRSxtQkFBbUIsQ0FBQztTQUN4RSxNQUFNLENBQUMsbUJBQW1CLEVBQUUsZ0VBQWdFLENBQUM7U0FDN0YsTUFBTSxDQUFDLHlCQUF5QixFQUFFLG1FQUFtRSxDQUFDO1NBQ3RHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsaUNBQWlDLEVBQUUsS0FBSyxDQUFDO1NBQzVELE1BQU0sQ0FBQyxVQUFVLEVBQUUsc0JBQXNCLEVBQUUsSUFBSSxDQUFDO1NBQ2hELE1BQU0sQ0FBQyxhQUFhLEVBQUUsK0JBQStCLENBQUMsQ0FBQztTQUN2RCxNQUFNLENBQUMsV0FBVyxFQUFFLGlDQUFpQyxFQUFFLEtBQUssQ0FBQztTQUM3RCxNQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1FBQ3hCLE1BQU0sV0FBVyxHQUFHLGtCQUFrQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXhELElBQUksQ0FBQztZQUVILHFCQUFxQjtZQUNyQixTQUFTLENBQUMsbUJBQW1CLEVBQUU7Z0JBQzdCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtnQkFDbEIsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZO2dCQUNsQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxlQUFlO2dCQUNyQyxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sSUFBSSxlQUFlO2dCQUMzQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUNyQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUNyQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07Z0JBQ3RCLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUzthQUM3QixDQUFDLENBQUM7WUFFSCxpREFBaUQ7WUFDakQsZUFBZSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVuQyx3QkFBd0I7WUFDeEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLElBQUksT0FBTyxPQUFPLENBQUMsWUFBWSxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDbEgsVUFBVSxDQUFDLDJCQUEyQixFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RSxNQUFNLElBQUksZUFBZSxDQUFDLHlDQUF5QyxFQUFFLGNBQWMsRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDN0csQ0FBQztZQUVELHFCQUFxQjtZQUNyQixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxPQUFPLE9BQU8sQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxRixVQUFVLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzVELE1BQU0sSUFBSSxlQUFlLENBQUMsc0NBQXNDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxRixDQUFDO1lBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFNUMsdUJBQXVCO1lBQ3ZCLFNBQVMsQ0FBQyx3QkFBd0IsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBRXhELElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDMUIsVUFBVSxDQUFDLHVCQUF1QixFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7Z0JBQ3hELE1BQU0sSUFBSSxlQUFlLENBQUMsMEJBQTBCLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUNwRixDQUFDO1lBRUQsMEJBQTBCO1lBQzFCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckQsSUFBSSxPQUFPLEtBQUssTUFBTSxFQUFFLENBQUM7Z0JBQ3ZCLFlBQVksQ0FBQyw0QkFBNEIsRUFBRTtvQkFDekMsUUFBUSxFQUFFLE9BQU87b0JBQ2pCLFFBQVEsRUFBRSxNQUFNO2lCQUNqQixDQUFDLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLGVBQWUsQ0FBQyxtQ0FBbUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDbkYsQ0FBQztZQUVELGlCQUFpQjtZQUNqQixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDN0IsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRWhELFlBQVksQ0FBQyxtQkFBbUIsRUFBRTtnQkFDaEMsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLFFBQVEsRUFBRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsY0FBYyxFQUFFO2FBQ2pELENBQUMsQ0FBQztZQUVILGtCQUFrQjtZQUNsQixJQUFJLFNBQVMsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDeEMsVUFBVSxDQUFDLHVCQUF1QixFQUFFO29CQUNsQyxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsT0FBTyxFQUFFLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7b0JBQ2hELFVBQVUsRUFBRSxjQUFjLENBQUMsU0FBUyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztpQkFDaEUsQ0FBQyxDQUFDO2dCQUNILE1BQU0sSUFBSSxlQUFlLENBQ3ZCLHVDQUF1QyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLGFBQWEsYUFBYSxHQUFHLEVBQzNHLFdBQVcsRUFDWCxTQUFTLENBQ1YsQ0FBQztZQUNKLENBQUM7WUFFRCw0QkFBNEI7WUFDNUIsSUFBSSxDQUFDO2dCQUNILEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0MsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsVUFBVSxDQUFDLHlCQUF5QixFQUFFO29CQUNwQyxJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztpQkFDOUQsQ0FBQyxDQUFDO2dCQUNILE1BQU0sSUFBSSxlQUFlLENBQUMsNkJBQTZCLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzdFLENBQUM7WUFFRCxZQUFZLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUV0QyxxRUFBcUU7WUFDckUsMEVBQTBFO1lBQzFFLElBQUksT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNwQixNQUFNLFlBQVksR0FBRyxzREFBc0QsQ0FBQztnQkFDNUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ3hDLFlBQVksQ0FBQywrQkFBK0IsRUFBRTt3QkFDNUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxPQUFPO3dCQUN6QixRQUFRLEVBQUUsOENBQThDO3FCQUN6RCxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7WUFFRCxtQ0FBbUM7WUFDbkMsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2pCLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQztnQkFDakMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ2xDLFlBQVksQ0FBQyxtQ0FBbUMsRUFBRTt3QkFDaEQsUUFBUSxFQUFFLE9BQU8sQ0FBQyxJQUFJO3dCQUN0QixRQUFRLEVBQUUsMkRBQTJEO3FCQUN0RSxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7WUFFRCxlQUFlO1lBQ2YsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ25CLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2hCLFlBQVksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO2dCQUM5QyxZQUFZLENBQUMsOENBQThDLENBQUMsQ0FBQztnQkFFN0QsYUFBYSxDQUFDO29CQUNaLElBQUksRUFBRSxRQUFRO29CQUNkLElBQUksRUFBRSxhQUFhO29CQUNuQixZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVk7b0JBQ2xDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLHlCQUF5QjtvQkFDL0MsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUkseUJBQXlCO29CQUNyRCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO29CQUNyQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO2lCQUN0QyxDQUFDLENBQUM7Z0JBRUgsT0FBTztZQUNULENBQUM7WUFFRCxrQ0FBa0M7WUFDbEMsTUFBTSxNQUFNLEdBQUcseUJBQXlCLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBRWxDLG1CQUFtQjtZQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ2pDLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRTtnQkFDNUIsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUM3QixJQUFJLEVBQUUsYUFBYTthQUNwQixDQUFDLENBQUM7WUFFSCxNQUFNLFFBQVEsR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFDdkQsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUNqQyxXQUFXLEVBQUUsaUJBQWlCO2FBQy9CLENBQUMsQ0FBQztZQUNILFFBQVEsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUV0RCxJQUFJLE9BQU8sQ0FBQyxJQUFJO2dCQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4RCxJQUFJLE9BQU8sQ0FBQyxPQUFPO2dCQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNqRSxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQy9ELFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFL0QsbUJBQW1CO1lBQ25CLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDO1lBQzVDLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRTtnQkFDNUIsUUFBUSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsUUFBUSxFQUFFO2FBQzdDLENBQUMsQ0FBQztZQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFFaEIsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbkQsSUFBSSxXQUEyQixDQUFDO1lBQ2hDLElBQUksUUFBZ0IsQ0FBQztZQUNyQixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixXQUFXLEdBQUcsTUFBTSxNQUFNLENBQUMsUUFBUSxDQUFpQixRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3hFLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDO2dCQUNsQyxPQUFPLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDckMsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxLQUFLLENBQUM7WUFDZCxDQUFDO1lBRUQsTUFBTSxRQUFRLEdBQUcscUJBQXFCLENBQVMsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUU5RSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2QsVUFBVSxDQUFDLGtDQUFrQyxFQUFFO29CQUM3QyxZQUFZLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRO2lCQUNoRSxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLEtBQUssQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO1lBQ25FLENBQUM7WUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLFlBQVksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBRTdDLDZCQUE2QjtZQUM3QixhQUFhLENBQUM7Z0JBQ1osV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNyQyxNQUFNLEVBQUUsUUFBUSxDQUFDLElBQUk7Z0JBQ3JCLFNBQVMsRUFBRSxRQUFRLENBQUMsT0FBTztnQkFDM0IsY0FBYyxFQUFFLFFBQVEsQ0FBQyxZQUFZO2dCQUNyQyxhQUFhLEVBQUUsUUFBUSxDQUFDLFdBQVcsSUFBSSxXQUFXO2FBQ25ELENBQUMsQ0FBQztZQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEIsYUFBYSxDQUFDO2dCQUNaLFVBQVUsRUFBRSxRQUFRLENBQUMsT0FBTyxJQUFJLGlCQUFpQjtnQkFDakQsV0FBVyxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7Z0JBQ2xHLFVBQVUsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7YUFDL0YsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoQixhQUFhLENBQUM7Z0JBQ1osUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDMUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDMUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxTQUFTLElBQUksaUJBQWlCO2dCQUNyRCxhQUFhLEVBQUUsUUFBUSxDQUFDLFVBQVUsSUFBSSxpQkFBaUI7YUFDeEQsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoQixhQUFhLENBQUM7Z0JBQ1osY0FBYyxFQUFFLFdBQVc7Z0JBQzNCLGlCQUFpQixFQUFFLEdBQUcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHO2dCQUNyRCxRQUFRLEVBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQzthQUM3QixDQUFDLENBQUM7WUFFSCw0Q0FBNEM7WUFDNUMsSUFBSSxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2hCLFNBQVMsQ0FBQywyQkFBMkIsRUFBRTtvQkFDckMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU07aUJBQzVDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFFRCx5Q0FBeUM7WUFDekMsTUFBTSxJQUFJLEdBQUcsUUFBOEMsQ0FBQztZQUM1RCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUN6RCxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2hCLFNBQVMsQ0FBQywyQkFBMkIsRUFBRTtvQkFDckMsU0FBUztvQkFDVCxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sU0FBUyxTQUFTLEVBQUU7aUJBQy9DLENBQUMsQ0FBQztZQUNMLENBQUM7WUFFRCxhQUFhO1lBQ2IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoQixTQUFTLENBQUMsWUFBWSxFQUFFO2dCQUN0QixJQUFJLEVBQUUsd0JBQXdCLFFBQVEsQ0FBQyxFQUFFLDBCQUEwQjtnQkFDbkUsSUFBSSxFQUFFLHVDQUF1QzthQUM5QyxDQUFDLENBQUM7UUFFTCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLFdBQVcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLFdBQVcsRUFBRTtnQkFDMUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLO2dCQUMzQixJQUFJLEVBQUUsSUFBSTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsT0FBTyxFQUFFLGVBQWU7b0JBQ3hCLFdBQVc7b0JBQ1gsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO29CQUNsQixZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVk7b0JBQ2xDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtvQkFDbEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO29CQUN4QixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07b0JBQ3RCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtvQkFDdEIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO2lCQUM3QjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IEZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgb3JhIGZyb20gJ29yYSc7XG5pbXBvcnQgcGljbyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCB7IEZJTEVfU0laRV9MSU1JVFMsIGZvcm1hdEZpbGVTaXplIH0gZnJvbSAnLi4vY29uZmlnL2NsaS5jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgdHlwZSBQbHVnaW4sIHR5cGUgUGx1Z2luUmVzcG9uc2UgfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIsIHByaW50U3NsV2FybmluZywgY3JlYXRlQXV0aGVudGljYXRlZENsaWVudCwgd2l0aFNzbE9wdGlvbnMgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vdXRpbHMvZXJyb3ItaGFuZGxlci5qcyc7XG5pbXBvcnQgeyBmaWxlRXhpc3RzLCBwcmludEVycm9yLCBwcmludEluZm8sIHByaW50S2V5VmFsdWUsIHByaW50U2VjdGlvbiwgcHJpbnRTdWNjZXNzLCBwcmludFdhcm5pbmcgfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMuanMnO1xuaW1wb3J0IHsgZXh0cmFjdFNpbmdsZVJlc3BvbnNlIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UtdXRpbHMuanMnO1xuXG5jb25zdCB7IGJvbGQsIGdyZWVuIH0gPSBwaWNvO1xuXG4vKipcbiAqIFJlZ2lzdGVycyB0aGUgYHVwbG9hZC1wbHVnaW5gIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogVmFsaWRhdGVzIGEgbG9jYWwgcGx1Z2luIFpJUCBmaWxlIChzaXplLCBleHRlbnNpb24sIHJlYWRhYmlsaXR5KSxcbiAqIGJ1aWxkcyBhIG11bHRpcGFydCBmb3JtLCBhbmQgdXBsb2FkcyBpdCB0byB0aGUgcGxhdGZvcm0gQVBJLlxuICogUGx1Z2luIG5hbWUgYW5kIHZlcnNpb24gY2FuIGJlIGF1dG8tZGV0ZWN0ZWQgZnJvbSB0aGUgcGFja2FnZVxuICogb3Igb3ZlcnJpZGRlbiB2aWEgQ0xJIGZsYWdzLlxuICpcbiAqIEBwYXJhbSBwcm9ncmFtIC0gVGhlIHJvb3QgQ29tbWFuZGVyIHByb2dyYW0gaW5zdGFuY2UgdG8gYXR0YWNoIHRoZSBjb21tYW5kIHRvLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBiYXNoXG4gKiBjbGkgcGx1Z2luIHVwbG9hZCAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lXG4gKiBjbGkgcGx1Z2luIHVwbG9hZCAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lIC0tcHVibGljXG4gKiBjbGkgcGx1Z2luIHVwbG9hZCAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lIC0tbmFtZSBteS1wbHVnaW4gLS12ZXJzaW9uIDEuMC4wXG4gKiBjbGkgcGx1Z2luIHVwbG9hZCAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lIC0tbm8tdmVyaWZ5LXNzbFxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGxvYWRQbHVnaW4ocHJvZ3JhbTogQ29tbWFuZCk6IHZvaWQge1xuICB3aXRoU3NsT3B0aW9ucyhwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3VwbG9hZCcpXG4gICAgLmRlc2NyaXB0aW9uKCdVcGxvYWQgYW5kIGRlcGxveSBhIHBsdWdpbiBwYWNrYWdlJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1mLCAtLWZpbGUgPGZpbGU+JywgJ1BhdGggdG8gcGx1Z2luIFpJUCBmaWxlJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy1vLCAtLW9yZ2FuaXphdGlvbiA8b3JnYW5pemF0aW9uPicsICdPcmdhbml6YXRpb24gbmFtZScpXG4gICAgLm9wdGlvbignLW4sIC0tbmFtZSA8bmFtZT4nLCAnUGx1Z2luIG5hbWUgKG9wdGlvbmFsLCBleHRyYWN0ZWQgZnJvbSBwYWNrYWdlIGlmIG5vdCBwcm92aWRlZCknKVxuICAgIC5vcHRpb24oJy12LCAtLXZlcnNpb24gPHZlcnNpb24+JywgJ1BsdWdpbiB2ZXJzaW9uIChvcHRpb25hbCwgZXh0cmFjdGVkIGZyb20gcGFja2FnZSBpZiBub3QgcHJvdmlkZWQpJylcbiAgICAub3B0aW9uKCctLXB1YmxpYycsICdNYWtlIHBsdWdpbiBwdWJsaWNseSBhY2Nlc3NpYmxlJywgZmFsc2UpXG4gICAgLm9wdGlvbignLS1hY3RpdmUnLCAnU2V0IHBsdWdpbiBhcyBhY3RpdmUnLCB0cnVlKVxuICAgIC5vcHRpb24oJy0tbm8tYWN0aXZlJywgJ1VwbG9hZCB0aGUgcGx1Z2luIGFzIGluYWN0aXZlJykpXG4gICAgLm9wdGlvbignLS1kcnktcnVuJywgJ1ZhbGlkYXRlIGZpbGUgd2l0aG91dCB1cGxvYWRpbmcnLCBmYWxzZSlcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCBleGVjdXRpb25JZCA9IHByaW50Q29tbWFuZEhlYWRlcignVXBsb2FkIFBsdWdpbicpO1xuXG4gICAgICB0cnkge1xuXG4gICAgICAgIC8vIERpc3BsYXkgcGFyYW1ldGVyc1xuICAgICAgICBwcmludEluZm8oJ1VwbG9hZCBwYXJhbWV0ZXJzJywge1xuICAgICAgICAgIGZpbGU6IG9wdGlvbnMuZmlsZSxcbiAgICAgICAgICBvcmdhbml6YXRpb246IG9wdGlvbnMub3JnYW5pemF0aW9uLFxuICAgICAgICAgIG5hbWU6IG9wdGlvbnMubmFtZSB8fCAnKGF1dG8tZGV0ZWN0KScsXG4gICAgICAgICAgdmVyc2lvbjogb3B0aW9ucy52ZXJzaW9uIHx8ICcoYXV0by1kZXRlY3QpJyxcbiAgICAgICAgICBwdWJsaWM6IG9wdGlvbnMucHVibGljID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgIGFjdGl2ZTogb3B0aW9ucy5hY3RpdmUgPyAnWWVzJyA6ICdObycsXG4gICAgICAgICAgZHJ5UnVuOiBvcHRpb25zLmRyeVJ1bixcbiAgICAgICAgICB2ZXJpZnlTc2w6IG9wdGlvbnMudmVyaWZ5U3NsLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZWN1cml0eSB3YXJuaW5nIGZvciBTU0wgdmVyaWZpY2F0aW9uIGRpc2FibGVkXG4gICAgICAgIHByaW50U3NsV2FybmluZyhvcHRpb25zLnZlcmlmeVNzbCk7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgb3JnYW5pemF0aW9uXG4gICAgICAgIGlmICghb3B0aW9ucy5vcmdhbml6YXRpb24gfHwgdHlwZW9mIG9wdGlvbnMub3JnYW5pemF0aW9uICE9PSAnc3RyaW5nJyB8fCBvcHRpb25zLm9yZ2FuaXphdGlvbi50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignSW52YWxpZCBvcmdhbml6YXRpb24gbmFtZScsIHsgcHJvdmlkZWQ6IG9wdGlvbnMub3JnYW5pemF0aW9uIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ09yZ2FuaXphdGlvbiBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycsICdvcmdhbml6YXRpb24nLCBvcHRpb25zLm9yZ2FuaXphdGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWYWxpZGF0ZSBmaWxlIHBhdGhcbiAgICAgICAgaWYgKCFvcHRpb25zLmZpbGUgfHwgdHlwZW9mIG9wdGlvbnMuZmlsZSAhPT0gJ3N0cmluZycgfHwgb3B0aW9ucy5maWxlLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBwcmludEVycm9yKCdJbnZhbGlkIGZpbGUgcGF0aCcsIHsgcHJvdmlkZWQ6IG9wdGlvbnMuZmlsZSB9KTtcbiAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdGaWxlIHBhdGggbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnLCAnZmlsZScsIG9wdGlvbnMuZmlsZSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGgucmVzb2x2ZShvcHRpb25zLmZpbGUpO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGUgZXhpc3RzXG4gICAgICAgIHByaW50SW5mbygnVmFsaWRhdGluZyBwbHVnaW4gZmlsZScsIHsgcGF0aDogZmlsZVBhdGggfSk7XG5cbiAgICAgICAgaWYgKCFmaWxlRXhpc3RzKGZpbGVQYXRoKSkge1xuICAgICAgICAgIHByaW50RXJyb3IoJ1BsdWdpbiBmaWxlIG5vdCBmb3VuZCcsIHsgcGF0aDogZmlsZVBhdGggfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgUGx1Z2luIGZpbGUgbm90IGZvdW5kOiAke2ZpbGVQYXRofWAsICdmaWxlJywgZmlsZVBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgZmlsZSBleHRlbnNpb25cbiAgICAgICAgY29uc3QgZmlsZUV4dCA9IHBhdGguZXh0bmFtZShmaWxlUGF0aCkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgaWYgKGZpbGVFeHQgIT09ICcuemlwJykge1xuICAgICAgICAgIHByaW50V2FybmluZygnRmlsZSBleHRlbnNpb24gaXMgbm90IC56aXAnLCB7XG4gICAgICAgICAgICBwcm92aWRlZDogZmlsZUV4dCxcbiAgICAgICAgICAgIGV4cGVjdGVkOiAnLnppcCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUGx1Z2luIGZpbGUgbXVzdCBiZSBhIFpJUCBhcmNoaXZlJywgJ2ZpbGUnLCBmaWxlUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgZmlsZSBzdGF0c1xuICAgICAgICBjb25zdCBzdGF0cyA9IGZzLnN0YXRTeW5jKGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3Qgc2l6ZUJ5dGVzID0gc3RhdHMuc2l6ZTtcbiAgICAgICAgY29uc3Qgc2l6ZUZvcm1hdHRlZCA9IGZvcm1hdEZpbGVTaXplKHNpemVCeXRlcyk7XG5cbiAgICAgICAgcHJpbnRTdWNjZXNzKCdQbHVnaW4gZmlsZSBmb3VuZCcsIHtcbiAgICAgICAgICBwYXRoOiBmaWxlUGF0aCxcbiAgICAgICAgICBzaXplOiBzaXplRm9ybWF0dGVkLFxuICAgICAgICAgIG1vZGlmaWVkOiBuZXcgRGF0ZShzdGF0cy5tdGltZSkudG9Mb2NhbGVTdHJpbmcoKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2hlY2sgZmlsZSBzaXplXG4gICAgICAgIGlmIChzaXplQnl0ZXMgPiBGSUxFX1NJWkVfTElNSVRTLlBMVUdJTikge1xuICAgICAgICAgIHByaW50RXJyb3IoJ1BsdWdpbiBmaWxlIHRvbyBsYXJnZScsIHtcbiAgICAgICAgICAgIHNpemU6IHNpemVGb3JtYXR0ZWQsXG4gICAgICAgICAgICBtYXhpbXVtOiBmb3JtYXRGaWxlU2l6ZShGSUxFX1NJWkVfTElNSVRTLlBMVUdJTiksXG4gICAgICAgICAgICBleGNlZWRlZEJ5OiBmb3JtYXRGaWxlU2l6ZShzaXplQnl0ZXMgLSBGSUxFX1NJWkVfTElNSVRTLlBMVUdJTiksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICAgIGBQbHVnaW4gZmlsZSBleGNlZWRzIG1heGltdW0gc2l6ZSBvZiAke2Zvcm1hdEZpbGVTaXplKEZJTEVfU0laRV9MSU1JVFMuUExVR0lOKX0gKGFjdHVhbDogJHtzaXplRm9ybWF0dGVkfSlgLFxuICAgICAgICAgICAgJ2ZpbGUuc2l6ZScsXG4gICAgICAgICAgICBzaXplQnl0ZXMsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIGZpbGUgaXMgcmVhZGFibGVcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBmcy5hY2Nlc3NTeW5jKGZpbGVQYXRoLCBmcy5jb25zdGFudHMuUl9PSyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignQ2Fubm90IHJlYWQgcGx1Z2luIGZpbGUnLCB7XG4gICAgICAgICAgICBwYXRoOiBmaWxlUGF0aCxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignUGx1Z2luIGZpbGUgaXMgbm90IHJlYWRhYmxlJywgJ2ZpbGUnLCBmaWxlUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBwcmludFN1Y2Nlc3MoJ1BsdWdpbiBmaWxlIHZhbGlkYXRlZCcpO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIHZlcnNpb24gZm9ybWF0IGlmIHByb3ZpZGVkLiBBbGxvd3MgLXByZXJlbGVhc2UgYW5kICtidWlsZFxuICAgICAgICAvLyBtZXRhZGF0YSAodmFsaWQgc2VtdmVyKSB0byBtYXRjaCB2YWxpZGF0ZS1wbHVnaW4gYW5kIHRoZSBEQiBjb25zdHJhaW50LlxuICAgICAgICBpZiAob3B0aW9ucy52ZXJzaW9uKSB7XG4gICAgICAgICAgY29uc3QgdmVyc2lvblJlZ2V4ID0gL15cXGQrXFwuXFxkK1xcLlxcZCsoLVthLXpBLVowLTkuLV0rKT8oXFwrW2EtekEtWjAtOS4tXSspPyQvO1xuICAgICAgICAgIGlmICghdmVyc2lvblJlZ2V4LnRlc3Qob3B0aW9ucy52ZXJzaW9uKSkge1xuICAgICAgICAgICAgcHJpbnRXYXJuaW5nKCdWZXJzaW9uIGZvcm1hdCBtYXkgYmUgaW52YWxpZCcsIHtcbiAgICAgICAgICAgICAgcHJvdmlkZWQ6IG9wdGlvbnMudmVyc2lvbixcbiAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdzZW1hbnRpYyB2ZXJzaW9uIChlLmcuLCAxLjAuMCwgMS4yLjMtYmV0YS4xKScsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWYWxpZGF0ZSBuYW1lIGZvcm1hdCBpZiBwcm92aWRlZFxuICAgICAgICBpZiAob3B0aW9ucy5uYW1lKSB7XG4gICAgICAgICAgY29uc3QgbmFtZVJlZ2V4ID0gL15bYS16MC05LV0rJC87XG4gICAgICAgICAgaWYgKCFuYW1lUmVnZXgudGVzdChvcHRpb25zLm5hbWUpKSB7XG4gICAgICAgICAgICBwcmludFdhcm5pbmcoJ1BsdWdpbiBuYW1lIGZvcm1hdCBtYXkgYmUgaW52YWxpZCcsIHtcbiAgICAgICAgICAgICAgcHJvdmlkZWQ6IG9wdGlvbnMubmFtZSxcbiAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdsb3dlcmNhc2UgYWxwaGFudW1lcmljIHdpdGggZGFzaGVzIChlLmcuLCBteS1wbHVnaW4tbmFtZSknLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRHJ5IHJ1biBtb2RlXG4gICAgICAgIGlmIChvcHRpb25zLmRyeVJ1bikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgICBwcmludFNlY3Rpb24oJ0RyeSBSdW4gLSBWYWxpZGF0aW9uIENvbXBsZXRlJyk7XG4gICAgICAgICAgcHJpbnRTdWNjZXNzKCdGaWxlIHZhbGlkYXRpb24gcGFzc2VkIC0gbm8gdXBsb2FkIHBlcmZvcm1lZCcpO1xuXG4gICAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgICBGaWxlOiBmaWxlUGF0aCxcbiAgICAgICAgICAgIFNpemU6IHNpemVGb3JtYXR0ZWQsXG4gICAgICAgICAgICBPcmdhbml6YXRpb246IG9wdGlvbnMub3JnYW5pemF0aW9uLFxuICAgICAgICAgICAgTmFtZTogb3B0aW9ucy5uYW1lIHx8ICcod2lsbCBiZSBhdXRvLWRldGVjdGVkKScsXG4gICAgICAgICAgICBWZXJzaW9uOiBvcHRpb25zLnZlcnNpb24gfHwgJyh3aWxsIGJlIGF1dG8tZGV0ZWN0ZWQpJyxcbiAgICAgICAgICAgIFB1YmxpYzogb3B0aW9ucy5wdWJsaWMgPyAnWWVzJyA6ICdObycsXG4gICAgICAgICAgICBBY3RpdmU6IG9wdGlvbnMuYWN0aXZlID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGF1dGhlbnRpY2F0ZWQgQVBJIGNsaWVudFxuICAgICAgICBjb25zdCBjbGllbnQgPSBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50KG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBjb25maWcgPSBjbGllbnQuZ2V0Q29uZmlnKCk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGZvcm0gZGF0YVxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U2VjdGlvbignVXBsb2FkaW5nIFBsdWdpbicpO1xuICAgICAgICBwcmludEluZm8oJ1ByZXBhcmluZyB1cGxvYWQnLCB7XG4gICAgICAgICAgZmlsZTogcGF0aC5iYXNlbmFtZShmaWxlUGF0aCksXG4gICAgICAgICAgc2l6ZTogc2l6ZUZvcm1hdHRlZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdwbHVnaW4nLCBmcy5jcmVhdGVSZWFkU3RyZWFtKGZpbGVQYXRoKSwge1xuICAgICAgICAgIGZpbGVuYW1lOiBwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKSxcbiAgICAgICAgICBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL3ppcCcsXG4gICAgICAgIH0pO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ29yZ2FuaXphdGlvbicsIG9wdGlvbnMub3JnYW5pemF0aW9uKTtcblxuICAgICAgICBpZiAob3B0aW9ucy5uYW1lKSBmb3JtRGF0YS5hcHBlbmQoJ25hbWUnLCBvcHRpb25zLm5hbWUpO1xuICAgICAgICBpZiAob3B0aW9ucy52ZXJzaW9uKSBmb3JtRGF0YS5hcHBlbmQoJ3ZlcnNpb24nLCBvcHRpb25zLnZlcnNpb24pO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2lzUHVibGljJywgb3B0aW9ucy5wdWJsaWMgPyAndHJ1ZScgOiAnZmFsc2UnKTtcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdpc0FjdGl2ZScsIG9wdGlvbnMuYWN0aXZlID8gJ3RydWUnIDogJ2ZhbHNlJyk7XG5cbiAgICAgICAgLy8gTWFrZSBBUEkgcmVxdWVzdFxuICAgICAgICBjb25zdCBlbmRwb2ludCA9IGNvbmZpZy5hcGkucGx1Z2luVXBsb2FkVXJsO1xuICAgICAgICBwcmludEluZm8oJ1VwbG9hZGluZyB0byBBUEknLCB7XG4gICAgICAgICAgZW5kcG9pbnQ6IGAke2NvbmZpZy5hcGkuYmFzZVVybH0ke2VuZHBvaW50fWAsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcblxuICAgICAgICBjb25zdCBzcGlubmVyID0gb3JhKCdVcGxvYWRpbmcgcGx1Z2luLi4uJykuc3RhcnQoKTtcbiAgICAgICAgbGV0IHJhd1Jlc3BvbnNlOiBQbHVnaW5SZXNwb25zZTtcbiAgICAgICAgbGV0IGR1cmF0aW9uOiBudW1iZXI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICByYXdSZXNwb25zZSA9IGF3YWl0IGNsaWVudC5wb3N0Rm9ybTxQbHVnaW5SZXNwb25zZT4oZW5kcG9pbnQsIGZvcm1EYXRhKTtcbiAgICAgICAgICBkdXJhdGlvbiA9IERhdGUubm93KCkgLSBzdGFydFRpbWU7XG4gICAgICAgICAgc3Bpbm5lci5zdWNjZWVkKCdQbHVnaW4gdXBsb2FkZWQnKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBzcGlubmVyLmZhaWwoJ1VwbG9hZCBmYWlsZWQnKTtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZXh0cmFjdFNpbmdsZVJlc3BvbnNlPFBsdWdpbj4ocmF3UmVzcG9uc2UsICdwbHVnaW4nLCAnbmFtZScpO1xuXG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdObyB2YWxpZCBwbHVnaW4gZGF0YSBpbiByZXNwb25zZScsIHtcbiAgICAgICAgICAgIHJlc3BvbnNlS2V5czogcmF3UmVzcG9uc2UgPyBPYmplY3Qua2V5cyhyYXdSZXNwb25zZSkgOiAnKG51bGwpJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VwbG9hZCBmYWlsZWQgLSBubyB2YWxpZCBwbHVnaW4gZGF0YSByZWNlaXZlZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludFNlY3Rpb24oJ1BsdWdpbiBVcGxvYWRlZCBTdWNjZXNzZnVsbHknKTtcblxuICAgICAgICAvLyBEaXNwbGF5IHBsdWdpbiBpbmZvcm1hdGlvblxuICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAnUGx1Z2luIElEJzogZ3JlZW4oYm9sZChyZXNwb25zZS5pZCkpLFxuICAgICAgICAgICdOYW1lJzogcmVzcG9uc2UubmFtZSxcbiAgICAgICAgICAnVmVyc2lvbic6IHJlc3BvbnNlLnZlcnNpb24sXG4gICAgICAgICAgJ09yZ2FuaXphdGlvbic6IHJlc3BvbnNlLm9yZ2FuaXphdGlvbixcbiAgICAgICAgICAnRGVzY3JpcHRpb24nOiByZXNwb25zZS5kZXNjcmlwdGlvbiB8fCAnKG5vdCBzZXQpJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAnRmlsZSBVUkwnOiByZXNwb25zZS5maWxlVXJsIHx8ICcobm90IGF2YWlsYWJsZSknLFxuICAgICAgICAgICdGaWxlIFNpemUnOiByZXNwb25zZS5maWxlU2l6ZSA/IGAkeyhyZXNwb25zZS5maWxlU2l6ZSAvIDEwMjQpLnRvRml4ZWQoMil9IEtCYCA6ICcobm90IGF2YWlsYWJsZSknLFxuICAgICAgICAgICdDaGVja3N1bSc6IHJlc3BvbnNlLmNoZWNrc3VtID8gYCR7cmVzcG9uc2UuY2hlY2tzdW0uc3Vic3RyaW5nKDAsIDE2KX0uLi5gIDogJyhub3QgYXZhaWxhYmxlKScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgJ1B1YmxpYyc6IHJlc3BvbnNlLmlzUHVibGljID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgICdBY3RpdmUnOiByZXNwb25zZS5pc0FjdGl2ZSA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgICAnQ3JlYXRlZCBBdCc6IHJlc3BvbnNlLmNyZWF0ZWRBdCB8fCAnKG5vdCBhdmFpbGFibGUpJyxcbiAgICAgICAgICAnVXBsb2FkZWQgQnknOiByZXNwb25zZS51cGxvYWRlZEJ5IHx8ICcobm90IGF2YWlsYWJsZSknLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdFeGVjdXRpb24gSUQnOiBleGVjdXRpb25JZCxcbiAgICAgICAgICAnVXBsb2FkIER1cmF0aW9uJzogYCR7KGR1cmF0aW9uIC8gMTAwMCkudG9GaXhlZCgyKX1zYCxcbiAgICAgICAgICAnU3RhdHVzJzogZ3JlZW4oJ+KckyBTdWNjZXNzJyksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFByaW50IGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gaWYgYXZhaWxhYmxlXG4gICAgICAgIGlmIChyZXNwb25zZS5tZXRhZGF0YSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgICBwcmludEluZm8oJ1BsdWdpbiBtZXRhZGF0YSBhdmFpbGFibGUnLCB7XG4gICAgICAgICAgICBrZXlzOiBPYmplY3Qua2V5cyhyZXNwb25zZS5tZXRhZGF0YSkubGVuZ3RoLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJpbnQgZGVwbG95bWVudCBsb2dzIFVSTCBpZiBhdmFpbGFibGVcbiAgICAgICAgY29uc3QgcmVzcCA9IHJlc3BvbnNlIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIGNvbnN0IHJlcXVlc3RJZCA9IHJlc3BbJ1gtUmVxdWVzdC1JZCddIHx8IHJlc3AucmVxdWVzdElkO1xuICAgICAgICBpZiAocmVxdWVzdElkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50SW5mbygnRGVwbG95bWVudCBsb2dzIGF2YWlsYWJsZScsIHtcbiAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgIHVybDogYCR7Y29uZmlnLmFwaS5iYXNlVXJsfS9sb2dzLyR7cmVxdWVzdElkfWAsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOZXh0IHN0ZXBzXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRJbmZvKCdOZXh0IHN0ZXBzJywge1xuICAgICAgICAgIHZpZXc6IGBVc2UgXCJnZXQtcGx1Z2luIC0taWQgJHtyZXNwb25zZS5pZH1cIiB0byB2aWV3IHBsdWdpbiBkZXRhaWxzYCxcbiAgICAgICAgICBsaXN0OiAnVXNlIFwibGlzdC1wbHVnaW5zXCIgdG8gc2VlIGFsbCBwbHVnaW5zJyxcbiAgICAgICAgfSk7XG5cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGhhbmRsZUVycm9yKGVycm9yLCBFUlJPUl9DT0RFUy5BUElfUkVRVUVTVCwge1xuICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICBleGl0OiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6ICd1cGxvYWQtcGx1Z2luJyxcbiAgICAgICAgICAgIGV4ZWN1dGlvbklkLFxuICAgICAgICAgICAgZmlsZTogb3B0aW9ucy5maWxlLFxuICAgICAgICAgICAgb3JnYW5pemF0aW9uOiBvcHRpb25zLm9yZ2FuaXphdGlvbixcbiAgICAgICAgICAgIG5hbWU6IG9wdGlvbnMubmFtZSxcbiAgICAgICAgICAgIHZlcnNpb246IG9wdGlvbnMudmVyc2lvbixcbiAgICAgICAgICAgIHB1YmxpYzogb3B0aW9ucy5wdWJsaWMsXG4gICAgICAgICAgICBhY3RpdmU6IG9wdGlvbnMuYWN0aXZlLFxuICAgICAgICAgICAgdmVyaWZ5U3NsOiBvcHRpb25zLnZlcmlmeVNzbCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Register the `validate-plugin` command — run the same structural + `{{ }}`
|
|
4
|
+
* template checks the server's upload path enforces, against a LOCAL plugin
|
|
5
|
+
* directory, so authors catch problems before packaging/uploading. Exits
|
|
6
|
+
* non-zero on any problem (CI-friendly), mirroring `validate-templates`.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* pipeline-manager plugin validate --dir ./my-linter
|
|
10
|
+
*/
|
|
11
|
+
export declare function validatePlugin(program: Command): void;
|
|
12
|
+
//# sourceMappingURL=validate-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-plugin.d.ts","sourceRoot":"","sources":["../../src/commands/validate-plugin.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+IrD"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import YAML from 'yaml';
|
|
7
|
+
import { printCommandHeader } from '../utils/command-utils.js';
|
|
8
|
+
import { ERROR_CODES, handleError, ValidationError } from '../utils/error-handler.js';
|
|
9
|
+
import { printError, printSuccess, printWarning, fileExists } from '../utils/output-utils.js';
|
|
10
|
+
const PLUGIN_TYPES = ['CodeBuildStep', 'ShellStep', 'ManualApprovalStep'];
|
|
11
|
+
const COMPUTE_TYPES = ['SMALL', 'MEDIUM', 'LARGE', 'X2_LARGE'];
|
|
12
|
+
const FAILURE_BEHAVIORS = ['fail', 'warn', 'ignore'];
|
|
13
|
+
const BUILD_TYPES = ['build_image', 'prebuilt', 'metadata_only'];
|
|
14
|
+
/**
|
|
15
|
+
* Register the `validate-plugin` command — run the same structural + `{{ }}`
|
|
16
|
+
* template checks the server's upload path enforces, against a LOCAL plugin
|
|
17
|
+
* directory, so authors catch problems before packaging/uploading. Exits
|
|
18
|
+
* non-zero on any problem (CI-friendly), mirroring `validate-templates`.
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* pipeline-manager plugin validate --dir ./my-linter
|
|
22
|
+
*/
|
|
23
|
+
export function validatePlugin(program) {
|
|
24
|
+
program
|
|
25
|
+
.command('validate')
|
|
26
|
+
.description('Validate a local plugin directory (config.yaml + plugin-spec.yaml) before upload')
|
|
27
|
+
.requiredOption('--dir <path>', 'Path to the plugin directory')
|
|
28
|
+
.action(async (options) => {
|
|
29
|
+
const executionId = printCommandHeader('Validate Plugin');
|
|
30
|
+
try {
|
|
31
|
+
const dir = path.resolve(options.dir ?? '');
|
|
32
|
+
if (!fileExists(dir) || !fs.statSync(dir).isDirectory()) {
|
|
33
|
+
throw new ValidationError(`Not a directory: ${dir}`);
|
|
34
|
+
}
|
|
35
|
+
const problems = [];
|
|
36
|
+
// config.yaml (optional build manifest).
|
|
37
|
+
const configPath = ['config.yaml', 'config.yml'].map(f => path.join(dir, f)).find(fileExists);
|
|
38
|
+
let buildType = 'build_image';
|
|
39
|
+
let specFile = 'plugin-spec.yaml';
|
|
40
|
+
let dockerfileName = 'Dockerfile';
|
|
41
|
+
if (configPath) {
|
|
42
|
+
const config = (YAML.parse(fs.readFileSync(configPath, 'utf-8')) ?? {});
|
|
43
|
+
if (config.buildType !== undefined) {
|
|
44
|
+
if (typeof config.buildType !== 'string' || !BUILD_TYPES.includes(config.buildType)) {
|
|
45
|
+
problems.push(`config.yaml: buildType must be one of ${BUILD_TYPES.join(', ')}`);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
buildType = config.buildType;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (typeof config.pluginSpec === 'string')
|
|
52
|
+
specFile = config.pluginSpec;
|
|
53
|
+
if (typeof config.dockerfile === 'string')
|
|
54
|
+
dockerfileName = config.dockerfile;
|
|
55
|
+
if ((buildType === 'prebuilt' || buildType === 'metadata_only') && config.dockerfile) {
|
|
56
|
+
problems.push(`config.yaml: dockerfile is not allowed when buildType is ${buildType}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// plugin-spec.yaml (required).
|
|
60
|
+
const specPath = path.join(dir, specFile);
|
|
61
|
+
if (!fileExists(specPath))
|
|
62
|
+
throw new ValidationError(`Missing plugin spec: ${specPath}`);
|
|
63
|
+
const spec = (YAML.parse(fs.readFileSync(specPath, 'utf-8')) ?? {});
|
|
64
|
+
// Required fields.
|
|
65
|
+
if (typeof spec.name !== 'string' || !spec.name)
|
|
66
|
+
problems.push('plugin-spec.yaml: name is required');
|
|
67
|
+
else if (!/^[a-z0-9-]+$/.test(spec.name))
|
|
68
|
+
problems.push('plugin-spec.yaml: name must match /^[a-z0-9-]+$/');
|
|
69
|
+
if (typeof spec.version !== 'string' || !spec.version)
|
|
70
|
+
problems.push('plugin-spec.yaml: version is required');
|
|
71
|
+
// Match the server/DB semver check (allows -prerelease and +build metadata).
|
|
72
|
+
else if (!/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/.test(spec.version))
|
|
73
|
+
problems.push('plugin-spec.yaml: version must be semver (x.y.z)');
|
|
74
|
+
const pluginType = (typeof spec.pluginType === 'string' ? spec.pluginType : 'CodeBuildStep');
|
|
75
|
+
if (!PLUGIN_TYPES.includes(pluginType))
|
|
76
|
+
problems.push(`plugin-spec.yaml: pluginType must be one of ${PLUGIN_TYPES.join(', ')}`);
|
|
77
|
+
if (spec.computeType !== undefined && !COMPUTE_TYPES.includes(String(spec.computeType))) {
|
|
78
|
+
problems.push(`plugin-spec.yaml: computeType must be one of ${COMPUTE_TYPES.join(', ')}`);
|
|
79
|
+
}
|
|
80
|
+
if (spec.failureBehavior !== undefined && !FAILURE_BEHAVIORS.includes(String(spec.failureBehavior))) {
|
|
81
|
+
problems.push(`plugin-spec.yaml: failureBehavior must be one of ${FAILURE_BEHAVIORS.join(', ')}`);
|
|
82
|
+
}
|
|
83
|
+
const isApproval = pluginType === 'ManualApprovalStep';
|
|
84
|
+
if (!isApproval && (!Array.isArray(spec.commands) || spec.commands.length === 0)) {
|
|
85
|
+
problems.push('plugin-spec.yaml: commands[] is required (except for ManualApprovalStep)');
|
|
86
|
+
}
|
|
87
|
+
// Build-type prerequisites.
|
|
88
|
+
if (buildType === 'build_image' && !isApproval && !fileExists(path.join(dir, dockerfileName))) {
|
|
89
|
+
problems.push(`Dockerfile not found for buildType build_image: ${path.join(dir, dockerfileName)}`);
|
|
90
|
+
}
|
|
91
|
+
if (buildType === 'prebuilt' && !fileExists(path.join(dir, 'image.tar'))) {
|
|
92
|
+
problems.push('image.tar not found for buildType prebuilt');
|
|
93
|
+
}
|
|
94
|
+
// `{{ }}` template validation — same scope roots + templatable fields the
|
|
95
|
+
// server enforces at upload (pipeline-core primitives; no server dep).
|
|
96
|
+
const core = await import('@pipeline-builder/pipeline-core');
|
|
97
|
+
const isTpl = (f) => f === 'description' ||
|
|
98
|
+
f.startsWith('commands') ||
|
|
99
|
+
f.startsWith('installCommands') ||
|
|
100
|
+
f.startsWith('env.') || f.startsWith('env[') ||
|
|
101
|
+
f.startsWith('buildArgs.') || f.startsWith('buildArgs[');
|
|
102
|
+
const isKnown = core.allowedScopeRoots(['pipeline', 'plugin', 'env']);
|
|
103
|
+
const { errors } = core.validateTemplates(spec, isTpl, isKnown);
|
|
104
|
+
for (const e of errors)
|
|
105
|
+
problems.push(`template [${e.field ?? '?'}]: ${e.message}`);
|
|
106
|
+
// Plugin CONTRACT check — mirrors the server's upload validation
|
|
107
|
+
// (api/plugin/src/helpers/plugin-spec.ts) so a spec rejected at upload also
|
|
108
|
+
// fails here (no false-green). Two independent rules per `{{ pipeline.vars.X }}`
|
|
109
|
+
// / `{{ pipeline.metadata.X }}` reference:
|
|
110
|
+
// (a) declaration: unless the token has a `| default:`, X must be declared
|
|
111
|
+
// in requiredVars / requiredMetadata;
|
|
112
|
+
// (b) coercion type: if the token has a `| number|bool|json` filter, the
|
|
113
|
+
// declared type in varsTypes/metadataTypes (default 'string') must match.
|
|
114
|
+
const requiredVars = new Set(Array.isArray(spec.requiredVars) ? spec.requiredVars.map(String) : []);
|
|
115
|
+
const requiredMetadata = new Set(Array.isArray(spec.requiredMetadata) ? spec.requiredMetadata.map(String) : []);
|
|
116
|
+
const varsTypes = spec.varsTypes ?? {};
|
|
117
|
+
const metadataTypes = spec.metadataTypes ?? {};
|
|
118
|
+
const coerceToType = { number: 'number', bool: 'bool', json: 'json' };
|
|
119
|
+
const templatableStrings = [
|
|
120
|
+
...(typeof spec.description === 'string' ? [spec.description] : []),
|
|
121
|
+
...(Array.isArray(spec.commands) ? spec.commands.filter((c) => typeof c === 'string') : []),
|
|
122
|
+
...(Array.isArray(spec.installCommands) ? spec.installCommands.filter((c) => typeof c === 'string') : []),
|
|
123
|
+
...Object.values(spec.env ?? {}).filter((v) => typeof v === 'string'),
|
|
124
|
+
...Object.values(spec.buildArgs ?? {}).filter((v) => typeof v === 'string'),
|
|
125
|
+
];
|
|
126
|
+
for (const source of templatableStrings) {
|
|
127
|
+
let tokens;
|
|
128
|
+
try {
|
|
129
|
+
tokens = core.tokenize(source);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
for (const t of tokens) {
|
|
135
|
+
if (t.kind !== 'expr')
|
|
136
|
+
continue;
|
|
137
|
+
const [root, sub, key] = t.path;
|
|
138
|
+
if (root !== 'pipeline' || (sub !== 'vars' && sub !== 'metadata') || !key)
|
|
139
|
+
continue;
|
|
140
|
+
const isVars = sub === 'vars';
|
|
141
|
+
// (a) declaration — waived by a `| default:`.
|
|
142
|
+
if (t.defaultValue === undefined) {
|
|
143
|
+
const declared = isVars ? requiredVars.has(key) : requiredMetadata.has(key);
|
|
144
|
+
if (!declared)
|
|
145
|
+
problems.push(`contract: template references {{ pipeline.${sub}.${key} }} but '${key}' is not declared in ${isVars ? 'requiredVars' : 'requiredMetadata'}`);
|
|
146
|
+
}
|
|
147
|
+
// (b) coercion type — independent of default.
|
|
148
|
+
if (t.coerce) {
|
|
149
|
+
const declaredType = (isVars ? varsTypes : metadataTypes)[key] ?? 'string';
|
|
150
|
+
const expectedType = coerceToType[t.coerce];
|
|
151
|
+
if (expectedType && declaredType !== expectedType) {
|
|
152
|
+
problems.push(`contract: {{ pipeline.${sub}.${key} | ${t.coerce} }} but declared type is '${declaredType}' (add '${key}: ${expectedType}' to ${isVars ? 'varsTypes' : 'metadataTypes'})`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (problems.length === 0) {
|
|
158
|
+
printSuccess(`Plugin '${String(spec.name)}' is valid`, { executionId, buildType, pluginType });
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
printWarning(`Found ${problems.length} problem(s):`);
|
|
162
|
+
for (const p of problems)
|
|
163
|
+
printError(` • ${p}`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
handleError(err, err instanceof ValidationError ? ERROR_CODES.VALIDATION : ERROR_CODES.GENERAL, {
|
|
168
|
+
debug: program.opts().debug,
|
|
169
|
+
exit: true,
|
|
170
|
+
context: { command: 'validate-plugin', executionId },
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUtcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL3ZhbGlkYXRlLXBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLElBQUksTUFBTSxNQUFNLENBQUM7QUFDeEIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEYsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBTTlGLE1BQU0sWUFBWSxHQUFHLENBQUMsZUFBZSxFQUFFLFdBQVcsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0FBQzFFLE1BQU0sYUFBYSxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDL0QsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDckQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBRWpFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxPQUFnQjtJQUM3QyxPQUFPO1NBQ0osT0FBTyxDQUFDLFVBQVUsQ0FBQztTQUNuQixXQUFXLENBQUMsa0ZBQWtGLENBQUM7U0FDL0YsY0FBYyxDQUFDLGNBQWMsRUFBRSw4QkFBOEIsQ0FBQztTQUM5RCxNQUFNLENBQUMsS0FB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Z0JBQzlGLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSztnQkFDM0IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRTthQUNyRCxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IFlBTUwgZnJvbSAneWFtbCc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vdXRpbHMvZXJyb3ItaGFuZGxlci5qcyc7XG5pbXBvcnQgeyBwcmludEVycm9yLCBwcmludFN1Y2Nlc3MsIHByaW50V2FybmluZywgZmlsZUV4aXN0cyB9IGZyb20gJy4uL3V0aWxzL291dHB1dC11dGlscy5qcyc7XG5cbmludGVyZmFjZSBWYWxpZGF0ZVBsdWdpbk9wdGlvbnMge1xuICBkaXI/OiBzdHJpbmc7XG59XG5cbmNvbnN0IFBMVUdJTl9UWVBFUyA9IFsnQ29kZUJ1aWxkU3RlcCcsICdTaGVsbFN0ZXAnLCAnTWFudWFsQXBwcm92YWxTdGVwJ107XG5jb25zdCBDT01QVVRFX1RZUEVTID0gWydTTUFMTCcsICdNRURJVU0nLCAnTEFSR0UnLCAnWDJfTEFSR0UnXTtcbmNvbnN0IEZBSUxVUkVfQkVIQVZJT1JTID0gWydmYWlsJywgJ3dhcm4nLCAnaWdub3JlJ107XG5jb25zdCBCVUlMRF9UWVBFUyA9IFsnYnVpbGRfaW1hZ2UnLCAncHJlYnVpbHQnLCAnbWV0YWRhdGFfb25seSddO1xuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBgdmFsaWRhdGUtcGx1Z2luYCBjb21tYW5kIOKAlCBydW4gdGhlIHNhbWUgc3RydWN0dXJhbCArIGB7eyB9fWBcbiAqIHRlbXBsYXRlIGNoZWNrcyB0aGUgc2VydmVyJ3MgdXBsb2FkIHBhdGggZW5mb3JjZXMsIGFnYWluc3QgYSBMT0NBTCBwbHVnaW5cbiAqIGRpcmVjdG9yeSwgc28gYXV0aG9ycyBjYXRjaCBwcm9ibGVtcyBiZWZvcmUgcGFja2FnaW5nL3VwbG9hZGluZy4gRXhpdHNcbiAqIG5vbi16ZXJvIG9uIGFueSBwcm9ibGVtIChDSS1mcmllbmRseSksIG1pcnJvcmluZyBgdmFsaWRhdGUtdGVtcGxhdGVzYC5cbiAqXG4gKiBVc2FnZTpcbiAqICAgcGlwZWxpbmUtbWFuYWdlciBwbHVnaW4gdmFsaWRhdGUgLS1kaXIgLi9teS1saW50ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUGx1Z2luKHByb2dyYW06IENvbW1hbmQpOiB2b2lkIHtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKCd2YWxpZGF0ZScpXG4gICAgLmRlc2NyaXB0aW9uKCdWYWxpZGF0ZSBhIGxvY2FsIHBsdWdpbiBkaXJlY3RvcnkgKGNvbmZpZy55YW1sICsgcGx1Z2luLXNwZWMueWFtbCkgYmVmb3JlIHVwbG9hZCcpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctLWRpciA8cGF0aD4nLCAnUGF0aCB0byB0aGUgcGx1Z2luIGRpcmVjdG9yeScpXG4gICAgLmFjdGlvbihhc3luYyAob3B0aW9uczogVmFsaWRhdGVQbHVnaW5PcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCBleGVjdXRpb25JZCA9IHByaW50Q29tbWFuZEhlYWRlcignVmFsaWRhdGUgUGx1Z2luJyk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkaXIgPSBwYXRoLnJlc29sdmUob3B0aW9ucy5kaXIgPz8gJycpO1xuICAgICAgICBpZiAoIWZpbGVFeGlzdHMoZGlyKSB8fCAhZnMuc3RhdFN5bmMoZGlyKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgTm90IGEgZGlyZWN0b3J5OiAke2Rpcn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHByb2JsZW1zOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIC8vIGNvbmZpZy55YW1sIChvcHRpb25hbCBidWlsZCBtYW5pZmVzdCkuXG4gICAgICAgIGNvbnN0IGNvbmZpZ1BhdGggPSBbJ2NvbmZpZy55YW1sJywgJ2NvbmZpZy55bWwnXS5tYXAoZiA9PiBwYXRoLmpvaW4oZGlyLCBmKSkuZmluZChmaWxlRXhpc3RzKTtcbiAgICAgICAgbGV0IGJ1aWxkVHlwZSA9ICdidWlsZF9pbWFnZSc7XG4gICAgICAgIGxldCBzcGVjRmlsZSA9ICdwbHVnaW4tc3BlYy55YW1sJztcbiAgICAgICAgbGV0IGRvY2tlcmZpbGVOYW1lID0gJ0RvY2tlcmZpbGUnO1xuICAgICAgICBpZiAoY29uZmlnUGF0aCkge1xuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IChZQU1MLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhjb25maWdQYXRoLCAndXRmLTgnKSkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgIGlmIChjb25maWcuYnVpbGRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29uZmlnLmJ1aWxkVHlwZSAhPT0gJ3N0cmluZycgfHwgIUJVSUxEX1RZUEVTLmluY2x1ZGVzKGNvbmZpZy5idWlsZFR5cGUpKSB7XG4gICAgICAgICAgICAgIHByb2JsZW1zLnB1c2goYGNvbmZpZy55YW1sOiBidWlsZFR5cGUgbXVzdCBiZSBvbmUgb2YgJHtCVUlMRF9UWVBFUy5qb2luKCcsICcpfWApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYnVpbGRUeXBlID0gY29uZmlnLmJ1aWxkVHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcucGx1Z2luU3BlYyA9PT0gJ3N0cmluZycpIHNwZWNGaWxlID0gY29uZmlnLnBsdWdpblNwZWM7XG4gICAgICAgICAgaWYgKHR5cGVvZiBjb25maWcuZG9ja2VyZmlsZSA9PT0gJ3N0cmluZycpIGRvY2tlcmZpbGVOYW1lID0gY29uZmlnLmRvY2tlcmZpbGU7XG4gICAgICAgICAgaWYgKChidWlsZFR5cGUgPT09ICdwcmVidWlsdCcgfHwgYnVpbGRUeXBlID09PSAnbWV0YWRhdGFfb25seScpICYmIGNvbmZpZy5kb2NrZXJmaWxlKSB7XG4gICAgICAgICAgICBwcm9ibGVtcy5wdXNoKGBjb25maWcueWFtbDogZG9ja2VyZmlsZSBpcyBub3QgYWxsb3dlZCB3aGVuIGJ1aWxkVHlwZSBpcyAke2J1aWxkVHlwZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwbHVnaW4tc3BlYy55YW1sIChyZXF1aXJlZCkuXG4gICAgICAgIGNvbnN0IHNwZWNQYXRoID0gcGF0aC5qb2luKGRpciwgc3BlY0ZpbGUpO1xuICAgICAgICBpZiAoIWZpbGVFeGlzdHMoc3BlY1BhdGgpKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBNaXNzaW5nIHBsdWdpbiBzcGVjOiAke3NwZWNQYXRofWApO1xuICAgICAgICBjb25zdCBzcGVjID0gKFlBTUwucGFyc2UoZnMucmVhZEZpbGVTeW5jKHNwZWNQYXRoLCAndXRmLTgnKSkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4gICAgICAgIC8vIFJlcXVpcmVkIGZpZWxkcy5cbiAgICAgICAgaWYgKHR5cGVvZiBzcGVjLm5hbWUgIT09ICdzdHJpbmcnIHx8ICFzcGVjLm5hbWUpIHByb2JsZW1zLnB1c2goJ3BsdWdpbi1zcGVjLnlhbWw6IG5hbWUgaXMgcmVxdWlyZWQnKTtcbiAgICAgICAgZWxzZSBpZiAoIS9eW2EtejAtOS1dKyQvLnRlc3Qoc3BlYy5uYW1lKSkgcHJvYmxlbXMucHVzaCgncGx1Z2luLXNwZWMueWFtbDogbmFtZSBtdXN0IG1hdGNoIC9eW2EtejAtOS1dKyQvJyk7XG4gICAgICAgIGlmICh0eXBlb2Ygc3BlYy52ZXJzaW9uICE9PSAnc3RyaW5nJyB8fCAhc3BlYy52ZXJzaW9uKSBwcm9ibGVtcy5wdXNoKCdwbHVnaW4tc3BlYy55YW1sOiB2ZXJzaW9uIGlzIHJlcXVpcmVkJyk7XG4gICAgICAgIC8vIE1hdGNoIHRoZSBzZXJ2ZXIvREIgc2VtdmVyIGNoZWNrIChhbGxvd3MgLXByZXJlbGVhc2UgYW5kICtidWlsZCBtZXRhZGF0YSkuXG4gICAgICAgIGVsc2UgaWYgKCEvXlxcZCtcXC5cXGQrXFwuXFxkKygtW2EtekEtWjAtOS4tXSspPyhcXCtbYS16QS1aMC05Li1dKyk/JC8udGVzdChzcGVjLnZlcnNpb24pKSBwcm9ibGVtcy5wdXNoKCdwbHVnaW4tc3BlYy55YW1sOiB2ZXJzaW9uIG11c3QgYmUgc2VtdmVyICh4LnkueiknKTtcblxuICAgICAgICBjb25zdCBwbHVnaW5UeXBlID0gKHR5cGVvZiBzcGVjLnBsdWdpblR5cGUgPT09ICdzdHJpbmcnID8gc3BlYy5wbHVnaW5UeXBlIDogJ0NvZGVCdWlsZFN0ZXAnKTtcbiAgICAgICAgaWYgKCFQTFVHSU5fVFlQRVMuaW5jbHVkZXMocGx1Z2luVHlwZSkpIHByb2JsZW1zLnB1c2goYHBsdWdpbi1zcGVjLnlhbWw6IHBsdWdpblR5cGUgbXVzdCBiZSBvbmUgb2YgJHtQTFVHSU5fVFlQRVMuam9pbignLCAnKX1gKTtcbiAgICAgICAgaWYgKHNwZWMuY29tcHV0ZVR5cGUgIT09IHVuZGVmaW5lZCAmJiAhQ09NUFVURV9UWVBFUy5pbmNsdWRlcyhTdHJpbmcoc3BlYy5jb21wdXRlVHlwZSkpKSB7XG4gICAgICAgICAgcHJvYmxlbXMucHVzaChgcGx1Z2luLXNwZWMueWFtbDogY29tcHV0ZVR5cGUgbXVzdCBiZSBvbmUgb2YgJHtDT01QVVRFX1RZUEVTLmpvaW4oJywgJyl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNwZWMuZmFpbHVyZUJlaGF2aW9yICE9PSB1bmRlZmluZWQgJiYgIUZBSUxVUkVfQkVIQVZJT1JTLmluY2x1ZGVzKFN0cmluZyhzcGVjLmZhaWx1cmVCZWhhdmlvcikpKSB7XG4gICAgICAgICAgcHJvYmxlbXMucHVzaChgcGx1Z2luLXNwZWMueWFtbDogZmFpbHVyZUJlaGF2aW9yIG11c3QgYmUgb25lIG9mICR7RkFJTFVSRV9CRUhBVklPUlMuam9pbignLCAnKX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGlzQXBwcm92YWwgPSBwbHVnaW5UeXBlID09PSAnTWFudWFsQXBwcm92YWxTdGVwJztcbiAgICAgICAgaWYgKCFpc0FwcHJvdmFsICYmICghQXJyYXkuaXNBcnJheShzcGVjLmNvbW1hbmRzKSB8fCBzcGVjLmNvbW1hbmRzLmxlbmd0aCA9PT0gMCkpIHtcbiAgICAgICAgICBwcm9ibGVtcy5wdXNoKCdwbHVnaW4tc3BlYy55YW1sOiBjb21tYW5kc1tdIGlzIHJlcXVpcmVkIChleGNlcHQgZm9yIE1hbnVhbEFwcHJvdmFsU3RlcCknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJ1aWxkLXR5cGUgcHJlcmVxdWlzaXRlcy5cbiAgICAgICAgaWYgKGJ1aWxkVHlwZSA9PT0gJ2J1aWxkX2ltYWdlJyAmJiAhaXNBcHByb3ZhbCAmJiAhZmlsZUV4aXN0cyhwYXRoLmpvaW4oZGlyLCBkb2NrZXJmaWxlTmFtZSkpKSB7XG4gICAgICAgICAgcHJvYmxlbXMucHVzaChgRG9ja2VyZmlsZSBub3QgZm91bmQgZm9yIGJ1aWxkVHlwZSBidWlsZF9pbWFnZTogJHtwYXRoLmpvaW4oZGlyLCBkb2NrZXJmaWxlTmFtZSl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ1aWxkVHlwZSA9PT0gJ3ByZWJ1aWx0JyAmJiAhZmlsZUV4aXN0cyhwYXRoLmpvaW4oZGlyLCAnaW1hZ2UudGFyJykpKSB7XG4gICAgICAgICAgcHJvYmxlbXMucHVzaCgnaW1hZ2UudGFyIG5vdCBmb3VuZCBmb3IgYnVpbGRUeXBlIHByZWJ1aWx0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBge3sgfX1gIHRlbXBsYXRlIHZhbGlkYXRpb24g4oCUIHNhbWUgc2NvcGUgcm9vdHMgKyB0ZW1wbGF0YWJsZSBmaWVsZHMgdGhlXG4gICAgICAgIC8vIHNlcnZlciBlbmZvcmNlcyBhdCB1cGxvYWQgKHBpcGVsaW5lLWNvcmUgcHJpbWl0aXZlczsgbm8gc2VydmVyIGRlcCkuXG4gICAgICAgIGNvbnN0IGNvcmUgPSBhd2FpdCBpbXBvcnQoJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWNvcmUnKTtcbiAgICAgICAgY29uc3QgaXNUcGwgPSAoZjogc3RyaW5nKSA9PlxuICAgICAgICAgIGYgPT09ICdkZXNjcmlwdGlvbicgfHxcbiAgICAgICAgICBmLnN0YXJ0c1dpdGgoJ2NvbW1hbmRzJykgfHxcbiAgICAgICAgICBmLnN0YXJ0c1dpdGgoJ2luc3RhbGxDb21tYW5kcycpIHx8XG4gICAgICAgICAgZi5zdGFydHNXaXRoKCdlbnYuJykgfHwgZi5zdGFydHNXaXRoKCdlbnZbJykgfHxcbiAgICAgICAgICBmLnN0YXJ0c1dpdGgoJ2J1aWxkQXJncy4nKSB8fCBmLnN0YXJ0c1dpdGgoJ2J1aWxkQXJnc1snKTtcbiAgICAgICAgY29uc3QgaXNLbm93biA9IGNvcmUuYWxsb3dlZFNjb3BlUm9vdHMoWydwaXBlbGluZScsICdwbHVnaW4nLCAnZW52J10pO1xuICAgICAgICBjb25zdCB7IGVycm9ycyB9ID0gY29yZS52YWxpZGF0ZVRlbXBsYXRlcyhzcGVjLCBpc1RwbCwgaXNLbm93bik7XG4gICAgICAgIGZvciAoY29uc3QgZSBvZiBlcnJvcnMpIHByb2JsZW1zLnB1c2goYHRlbXBsYXRlIFske2UuZmllbGQgPz8gJz8nfV06ICR7ZS5tZXNzYWdlfWApO1xuXG4gICAgICAgIC8vIFBsdWdpbiBDT05UUkFDVCBjaGVjayDigJQgbWlycm9ycyB0aGUgc2VydmVyJ3MgdXBsb2FkIHZhbGlkYXRpb25cbiAgICAgICAgLy8gKGFwaS9wbHVnaW4vc3JjL2hlbHBlcnMvcGx1Z2luLXNwZWMudHMpIHNvIGEgc3BlYyByZWplY3RlZCBhdCB1cGxvYWQgYWxzb1xuICAgICAgICAvLyBmYWlscyBoZXJlIChubyBmYWxzZS1ncmVlbikuIFR3byBpbmRlcGVuZGVudCBydWxlcyBwZXIgYHt7IHBpcGVsaW5lLnZhcnMuWCB9fWBcbiAgICAgICAgLy8gLyBge3sgcGlwZWxpbmUubWV0YWRhdGEuWCB9fWAgcmVmZXJlbmNlOlxuICAgICAgICAvLyAgIChhKSBkZWNsYXJhdGlvbjogdW5sZXNzIHRoZSB0b2tlbiBoYXMgYSBgfCBkZWZhdWx0OmAsIFggbXVzdCBiZSBkZWNsYXJlZFxuICAgICAgICAvLyAgICAgICBpbiByZXF1aXJlZFZhcnMgLyByZXF1aXJlZE1ldGFkYXRhO1xuICAgICAgICAvLyAgIChiKSBjb2VyY2lvbiB0eXBlOiBpZiB0aGUgdG9rZW4gaGFzIGEgYHwgbnVtYmVyfGJvb2x8anNvbmAgZmlsdGVyLCB0aGVcbiAgICAgICAgLy8gICAgICAgZGVjbGFyZWQgdHlwZSBpbiB2YXJzVHlwZXMvbWV0YWRhdGFUeXBlcyAoZGVmYXVsdCAnc3RyaW5nJykgbXVzdCBtYXRjaC5cbiAgICAgICAgY29uc3QgcmVxdWlyZWRWYXJzID0gbmV3IFNldChBcnJheS5pc0FycmF5KHNwZWMucmVxdWlyZWRWYXJzKSA/IChzcGVjLnJlcXVpcmVkVmFycyBhcyB1bmtub3duW10pLm1hcChTdHJpbmcpIDogW10pO1xuICAgICAgICBjb25zdCByZXF1aXJlZE1ldGFkYXRhID0gbmV3IFNldChBcnJheS5pc0FycmF5KHNwZWMucmVxdWlyZWRNZXRhZGF0YSkgPyAoc3BlYy5yZXF1aXJlZE1ldGFkYXRhIGFzIHVua25vd25bXSkubWFwKFN0cmluZykgOiBbXSk7XG4gICAgICAgIGNvbnN0IHZhcnNUeXBlcyA9IChzcGVjLnZhcnNUeXBlcyBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA/PyB7fTtcbiAgICAgICAgY29uc3QgbWV0YWRhdGFUeXBlcyA9IChzcGVjLm1ldGFkYXRhVHlwZXMgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPikgPz8ge307XG4gICAgICAgIGNvbnN0IGNvZXJjZVRvVHlwZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgbnVtYmVyOiAnbnVtYmVyJywgYm9vbDogJ2Jvb2wnLCBqc29uOiAnanNvbicgfTtcbiAgICAgICAgY29uc3QgdGVtcGxhdGFibGVTdHJpbmdzOiBzdHJpbmdbXSA9IFtcbiAgICAgICAgICAuLi4odHlwZW9mIHNwZWMuZGVzY3JpcHRpb24gPT09ICdzdHJpbmcnID8gW3NwZWMuZGVzY3JpcHRpb25dIDogW10pLFxuICAgICAgICAgIC4uLihBcnJheS5pc0FycmF5KHNwZWMuY29tbWFuZHMpID8gc3BlYy5jb21tYW5kcy5maWx0ZXIoKGMpOiBjIGlzIHN0cmluZyA9PiB0eXBlb2YgYyA9PT0gJ3N0cmluZycpIDogW10pLFxuICAgICAgICAgIC4uLihBcnJheS5pc0FycmF5KHNwZWMuaW5zdGFsbENvbW1hbmRzKSA/IHNwZWMuaW5zdGFsbENvbW1hbmRzLmZpbHRlcigoYyk6IGMgaXMgc3RyaW5nID0+IHR5cGVvZiBjID09PSAnc3RyaW5nJykgOiBbXSksXG4gICAgICAgICAgLi4uT2JqZWN0LnZhbHVlcygoc3BlYy5lbnYgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID8/IHt9KS5maWx0ZXIoKHYpOiB2IGlzIHN0cmluZyA9PiB0eXBlb2YgdiA9PT0gJ3N0cmluZycpLFxuICAgICAgICAgIC4uLk9iamVjdC52YWx1ZXMoKHNwZWMuYnVpbGRBcmdzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA/PyB7fSkuZmlsdGVyKCh2KTogdiBpcyBzdHJpbmcgPT4gdHlwZW9mIHYgPT09ICdzdHJpbmcnKSxcbiAgICAgICAgXTtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2YgdGVtcGxhdGFibGVTdHJpbmdzKSB7XG4gICAgICAgICAgbGV0IHRva2VucztcbiAgICAgICAgICB0cnkgeyB0b2tlbnMgPSBjb3JlLnRva2VuaXplKHNvdXJjZSk7IH0gY2F0Y2ggeyBjb250aW51ZTsgfVxuICAgICAgICAgIGZvciAoY29uc3QgdCBvZiB0b2tlbnMpIHtcbiAgICAgICAgICAgIGlmICh0LmtpbmQgIT09ICdleHByJykgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBbcm9vdCwgc3ViLCBrZXldID0gdC5wYXRoO1xuICAgICAgICAgICAgaWYgKHJvb3QgIT09ICdwaXBlbGluZScgfHwgKHN1YiAhPT0gJ3ZhcnMnICYmIHN1YiAhPT0gJ21ldGFkYXRhJykgfHwgIWtleSkgY29udGludWU7XG4gICAgICAgICAgICBjb25zdCBpc1ZhcnMgPSBzdWIgPT09ICd2YXJzJztcbiAgICAgICAgICAgIC8vIChhKSBkZWNsYXJhdGlvbiDigJQgd2FpdmVkIGJ5IGEgYHwgZGVmYXVsdDpgLlxuICAgICAgICAgICAgaWYgKHQuZGVmYXVsdFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVjbGFyZWQgPSBpc1ZhcnMgPyByZXF1aXJlZFZhcnMuaGFzKGtleSkgOiByZXF1aXJlZE1ldGFkYXRhLmhhcyhrZXkpO1xuICAgICAgICAgICAgICBpZiAoIWRlY2xhcmVkKSBwcm9ibGVtcy5wdXNoKGBjb250cmFjdDogdGVtcGxhdGUgcmVmZXJlbmNlcyB7eyBwaXBlbGluZS4ke3N1Yn0uJHtrZXl9IH19IGJ1dCAnJHtrZXl9JyBpcyBub3QgZGVjbGFyZWQgaW4gJHtpc1ZhcnMgPyAncmVxdWlyZWRWYXJzJyA6ICdyZXF1aXJlZE1ldGFkYXRhJ31gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIChiKSBjb2VyY2lvbiB0eXBlIOKAlCBpbmRlcGVuZGVudCBvZiBkZWZhdWx0LlxuICAgICAgICAgICAgaWYgKHQuY29lcmNlKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGRlY2xhcmVkVHlwZSA9IChpc1ZhcnMgPyB2YXJzVHlwZXMgOiBtZXRhZGF0YVR5cGVzKVtrZXldID8/ICdzdHJpbmcnO1xuICAgICAgICAgICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSBjb2VyY2VUb1R5cGVbdC5jb2VyY2VdO1xuICAgICAgICAgICAgICBpZiAoZXhwZWN0ZWRUeXBlICYmIGRlY2xhcmVkVHlwZSAhPT0gZXhwZWN0ZWRUeXBlKSB7XG4gICAgICAgICAgICAgICAgcHJvYmxlbXMucHVzaChgY29udHJhY3Q6IHt7IHBpcGVsaW5lLiR7c3VifS4ke2tleX0gfCAke3QuY29lcmNlfSB9fSBidXQgZGVjbGFyZWQgdHlwZSBpcyAnJHtkZWNsYXJlZFR5cGV9JyAoYWRkICcke2tleX06ICR7ZXhwZWN0ZWRUeXBlfScgdG8gJHtpc1ZhcnMgPyAndmFyc1R5cGVzJyA6ICdtZXRhZGF0YVR5cGVzJ30pYCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvYmxlbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcHJpbnRTdWNjZXNzKGBQbHVnaW4gJyR7U3RyaW5nKHNwZWMubmFtZSl9JyBpcyB2YWxpZGAsIHsgZXhlY3V0aW9uSWQsIGJ1aWxkVHlwZSwgcGx1Z2luVHlwZSB9KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBwcmludFdhcm5pbmcoYEZvdW5kICR7cHJvYmxlbXMubGVuZ3RofSBwcm9ibGVtKHMpOmApO1xuICAgICAgICBmb3IgKGNvbnN0IHAgb2YgcHJvYmxlbXMpIHByaW50RXJyb3IoYCAg4oCiICR7cH1gKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGhhbmRsZUVycm9yKGVyciwgZXJyIGluc3RhbmNlb2YgVmFsaWRhdGlvbkVycm9yID8gRVJST1JfQ09ERVMuVkFMSURBVElPTiA6IEVSUk9SX0NPREVTLkdFTkVSQUwsIHtcbiAgICAgICAgICBkZWJ1ZzogcHJvZ3JhbS5vcHRzKCkuZGVidWcsXG4gICAgICAgICAgZXhpdDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7IGNvbW1hbmQ6ICd2YWxpZGF0ZS1wbHVnaW4nLCBleGVjdXRpb25JZCB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Register the `validate-templates` command.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* pipeline-manager template validate --pipeline <uuid>
|
|
7
|
+
* pipeline-manager template validate --plugin <name:version>
|
|
8
|
+
* pipeline-manager template validate --file ./plugin-spec.yaml
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateTemplatesCommand(program: Command): void;
|
|
11
|
+
//# sourceMappingURL=validate-templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-templates.d.ts","sourceRoot":"","sources":["../../src/commands/validate-templates.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkF/D"}
|