@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,159 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import pico from 'picocolors';
|
|
5
|
+
import { assertShellSafe } from '../config/cli.constants.js';
|
|
6
|
+
import { auditLog } from '../utils/audit-log.js';
|
|
7
|
+
import { resolveAwsRegion } from '../utils/aws-env.js';
|
|
8
|
+
import { executeCdkShellCommand } from '../utils/cdk-utils.js';
|
|
9
|
+
import { printCommandHeader, withProfileOption, withRegionOption } from '../utils/command-utils.js';
|
|
10
|
+
import { ERROR_CODES, handleError } from '../utils/error-handler.js';
|
|
11
|
+
import { printError, printInfo, printKeyValue, printSection } from '../utils/output-utils.js';
|
|
12
|
+
const { bold, cyan, dim } = pico;
|
|
13
|
+
/**
|
|
14
|
+
* Resolves the AWS account ID from the CLI option or environment variable.
|
|
15
|
+
* @returns The account ID string, or `undefined` if not available.
|
|
16
|
+
*/
|
|
17
|
+
/** @internal Exported for testing only */
|
|
18
|
+
export function resolveAccount(optionValue) {
|
|
19
|
+
return optionValue || process.env.AWS_ACCOUNT_ID || process.env.CDK_DEFAULT_ACCOUNT;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolves the AWS region from the CLI option or environment variable.
|
|
23
|
+
* @returns The region string, or `undefined` if not available.
|
|
24
|
+
*/
|
|
25
|
+
/** @internal Exported for testing only */
|
|
26
|
+
export function resolveRegion(optionValue) {
|
|
27
|
+
return resolveAwsRegion(optionValue);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Builds the `cdk bootstrap` command string from the resolved options.
|
|
31
|
+
*/
|
|
32
|
+
/** @internal Exported for testing only */
|
|
33
|
+
export function buildBootstrapCommand(options) {
|
|
34
|
+
// Every value below is interpolated into a string run via `execSync` (a shell),
|
|
35
|
+
// so validate ALL operator-supplied inputs — not just account/region/profile.
|
|
36
|
+
assertShellSafe(options.account, 'account');
|
|
37
|
+
assertShellSafe(options.region, 'region');
|
|
38
|
+
if (options.profile)
|
|
39
|
+
assertShellSafe(options.profile, 'profile');
|
|
40
|
+
if (options.qualifier)
|
|
41
|
+
assertShellSafe(options.qualifier, 'qualifier');
|
|
42
|
+
if (options.trust)
|
|
43
|
+
assertShellSafe(options.trust, 'trust');
|
|
44
|
+
if (options.cloudformationExecutionPolicies)
|
|
45
|
+
assertShellSafe(options.cloudformationExecutionPolicies, 'cloudformation-execution-policies');
|
|
46
|
+
const parts = [
|
|
47
|
+
'cdk',
|
|
48
|
+
'bootstrap',
|
|
49
|
+
`aws://${options.account}/${options.region}`,
|
|
50
|
+
];
|
|
51
|
+
if (options.profile) {
|
|
52
|
+
parts.push(`--profile=${options.profile}`);
|
|
53
|
+
}
|
|
54
|
+
if (options.qualifier) {
|
|
55
|
+
parts.push(`--qualifier=${options.qualifier}`);
|
|
56
|
+
}
|
|
57
|
+
if (options.trust) {
|
|
58
|
+
parts.push(`--trust=${options.trust}`);
|
|
59
|
+
}
|
|
60
|
+
if (options.cloudformationExecutionPolicies) {
|
|
61
|
+
parts.push(`--cloudformation-execution-policies=${options.cloudformationExecutionPolicies}`);
|
|
62
|
+
}
|
|
63
|
+
return parts.join(' ');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Registers the `bootstrap` command with the CLI program.
|
|
67
|
+
*
|
|
68
|
+
* Provisions the CDK toolkit stack in the target AWS account/region
|
|
69
|
+
* so that CDK deployments can proceed.
|
|
70
|
+
*
|
|
71
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
72
|
+
*/
|
|
73
|
+
export function bootstrap(program) {
|
|
74
|
+
withProfileOption(withRegionOption(program
|
|
75
|
+
.command('bootstrap')
|
|
76
|
+
.description('Bootstrap AWS CDK toolkit stack in target account/region')
|
|
77
|
+
.option('--account <id>', 'AWS account ID (defaults to AWS_ACCOUNT_ID or CDK_DEFAULT_ACCOUNT env)')))
|
|
78
|
+
.option('--qualifier <qualifier>', 'Bootstrap qualifier for environment isolation')
|
|
79
|
+
.option('--trust <accounts>', 'Comma-separated account IDs to trust for cross-account deployments')
|
|
80
|
+
.option('--cloudformation-execution-policies <arns>', 'IAM policy ARNs for CloudFormation execution role')
|
|
81
|
+
.option('--json', 'Output result as JSON', false)
|
|
82
|
+
.action(async (options) => {
|
|
83
|
+
const executionId = printCommandHeader('CDK Bootstrap', undefined, { quiet: options.json });
|
|
84
|
+
try {
|
|
85
|
+
// Never persist the AWS account id to the on-disk audit log (~/.pipeline-manager/audit.log).
|
|
86
|
+
// The audit module records operation metadata only — region/profile are safe; the account id is not.
|
|
87
|
+
auditLog('bootstrap', { executionId, region: options.region, profile: options.profile });
|
|
88
|
+
// Resolve account and region
|
|
89
|
+
const account = resolveAccount(options.account);
|
|
90
|
+
const region = resolveRegion(options.region);
|
|
91
|
+
if (!account) {
|
|
92
|
+
printError('AWS account ID is required');
|
|
93
|
+
console.log(dim('Provide --account <id> or set AWS_ACCOUNT_ID / CDK_DEFAULT_ACCOUNT environment variable'));
|
|
94
|
+
throw new Error('AWS account ID not provided');
|
|
95
|
+
}
|
|
96
|
+
printInfo('Bootstrap parameters', {
|
|
97
|
+
account,
|
|
98
|
+
region,
|
|
99
|
+
profile: options.profile,
|
|
100
|
+
qualifier: options.qualifier || '(default)',
|
|
101
|
+
trust: options.trust || '(none)',
|
|
102
|
+
cloudformationExecutionPolicies: options.cloudformationExecutionPolicies || '(none)',
|
|
103
|
+
});
|
|
104
|
+
// CDK availability is verified up front by the CLI's preAction hook.
|
|
105
|
+
// Build bootstrap command
|
|
106
|
+
const command = buildBootstrapCommand({
|
|
107
|
+
account,
|
|
108
|
+
region,
|
|
109
|
+
profile: options.profile,
|
|
110
|
+
qualifier: options.qualifier,
|
|
111
|
+
trust: options.trust,
|
|
112
|
+
cloudformationExecutionPolicies: options.cloudformationExecutionPolicies,
|
|
113
|
+
});
|
|
114
|
+
printSection('CDK Execution');
|
|
115
|
+
console.log(cyan(bold('Command:')), dim(command));
|
|
116
|
+
console.log('');
|
|
117
|
+
// Execute bootstrap
|
|
118
|
+
const result = executeCdkShellCommand(command, {
|
|
119
|
+
debug: program.opts().debug,
|
|
120
|
+
showOutput: true,
|
|
121
|
+
});
|
|
122
|
+
console.log('');
|
|
123
|
+
printSection('Bootstrap Complete');
|
|
124
|
+
if (result.success) {
|
|
125
|
+
if (options.json) {
|
|
126
|
+
console.log(JSON.stringify({
|
|
127
|
+
success: true,
|
|
128
|
+
executionId,
|
|
129
|
+
account,
|
|
130
|
+
region,
|
|
131
|
+
duration: result.duration,
|
|
132
|
+
}, null, 2));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
printKeyValue({
|
|
136
|
+
'Execution ID': executionId,
|
|
137
|
+
'Account': account,
|
|
138
|
+
'Region': region,
|
|
139
|
+
'Duration': `${result.duration}ms`,
|
|
140
|
+
'Status': '✓ Success',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
handleError(error, ERROR_CODES.VALIDATION, {
|
|
147
|
+
debug: program.opts().debug,
|
|
148
|
+
exit: true,
|
|
149
|
+
context: {
|
|
150
|
+
command: 'bootstrap',
|
|
151
|
+
executionId,
|
|
152
|
+
account: options.account,
|
|
153
|
+
region: options.region,
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2Jvb3RzdHJhcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDakQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDcEcsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFOUYsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRWpDOzs7R0FHRztBQUNILDBDQUEwQztBQUMxQyxNQUFNLFVBQVUsY0FBYyxDQUFDLFdBQW9CO0lBQ2pELE9BQU8sV0FBVyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUM7QUFDdEYsQ0FBQztBQUVEOzs7R0FHRztBQUNILDBDQUEwQztBQUMxQyxNQUFNLFVBQVUsYUFBYSxDQUFDLFdBQW9CO0lBQ2hELE9BQU8sZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDdkMs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RixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHBpY28gZnJvbSAncGljb2NvbG9ycyc7XG5pbXBvcnQgeyBhc3NlcnRTaGVsbFNhZmUgfSBmcm9tICcuLi9jb25maWcvY2xpLmNvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBhdWRpdExvZyB9IGZyb20gJy4uL3V0aWxzL2F1ZGl0LWxvZy5qcyc7XG5pbXBvcnQgeyByZXNvbHZlQXdzUmVnaW9uIH0gZnJvbSAnLi4vdXRpbHMvYXdzLWVudi5qcyc7XG5pbXBvcnQgeyBleGVjdXRlQ2RrU2hlbGxDb21tYW5kIH0gZnJvbSAnLi4vdXRpbHMvY2RrLXV0aWxzLmpzJztcbmltcG9ydCB7IHByaW50Q29tbWFuZEhlYWRlciwgd2l0aFByb2ZpbGVPcHRpb24sIHdpdGhSZWdpb25PcHRpb24gfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzLmpzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciB9IGZyb20gJy4uL3V0aWxzL2Vycm9yLWhhbmRsZXIuanMnO1xuaW1wb3J0IHsgcHJpbnRFcnJvciwgcHJpbnRJbmZvLCBwcmludEtleVZhbHVlLCBwcmludFNlY3Rpb24gfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMuanMnO1xuXG5jb25zdCB7IGJvbGQsIGN5YW4sIGRpbSB9ID0gcGljbztcblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgQVdTIGFjY291bnQgSUQgZnJvbSB0aGUgQ0xJIG9wdGlvbiBvciBlbnZpcm9ubWVudCB2YXJpYWJsZS5cbiAqIEByZXR1cm5zIFRoZSBhY2NvdW50IElEIHN0cmluZywgb3IgYHVuZGVmaW5lZGAgaWYgbm90IGF2YWlsYWJsZS5cbiAqL1xuLyoqIEBpbnRlcm5hbCBFeHBvcnRlZCBmb3IgdGVzdGluZyBvbmx5ICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUFjY291bnQob3B0aW9uVmFsdWU/OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gb3B0aW9uVmFsdWUgfHwgcHJvY2Vzcy5lbnYuQVdTX0FDQ09VTlRfSUQgfHwgcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfQUNDT1VOVDtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgQVdTIHJlZ2lvbiBmcm9tIHRoZSBDTEkgb3B0aW9uIG9yIGVudmlyb25tZW50IHZhcmlhYmxlLlxuICogQHJldHVybnMgVGhlIHJlZ2lvbiBzdHJpbmcsIG9yIGB1bmRlZmluZWRgIGlmIG5vdCBhdmFpbGFibGUuXG4gKi9cbi8qKiBAaW50ZXJuYWwgRXhwb3J0ZWQgZm9yIHRlc3Rpbmcgb25seSAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVSZWdpb24ob3B0aW9uVmFsdWU/OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcmVzb2x2ZUF3c1JlZ2lvbihvcHRpb25WYWx1ZSk7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBgY2RrIGJvb3RzdHJhcGAgY29tbWFuZCBzdHJpbmcgZnJvbSB0aGUgcmVzb2x2ZWQgb3B0aW9ucy5cbiAqL1xuLyoqIEBpbnRlcm5hbCBFeHBvcnRlZCBmb3IgdGVzdGluZyBvbmx5ICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRCb290c3RyYXBDb21tYW5kKG9wdGlvbnM6IHtcbiAgYWNjb3VudDogc3RyaW5nO1xuICByZWdpb246IHN0cmluZztcbiAgcHJvZmlsZT86IHN0cmluZztcbiAgcXVhbGlmaWVyPzogc3RyaW5nO1xuICB0cnVzdD86IHN0cmluZztcbiAgY2xvdWRmb3JtYXRpb25FeGVjdXRpb25Qb2xpY2llcz86IHN0cmluZztcbn0pOiBzdHJpbmcge1xuICAvLyBFdmVyeSB2YWx1ZSBiZWxvdyBpcyBpbnRlcnBvbGF0ZWQgaW50byBhIHN0cmluZyBydW4gdmlhIGBleGVjU3luY2AgKGEgc2hlbGwpLFxuICAvLyBzbyB2YWxpZGF0ZSBBTEwgb3BlcmF0b3Itc3VwcGxpZWQgaW5wdXRzIOKAlCBub3QganVzdCBhY2NvdW50L3JlZ2lvbi9wcm9maWxlLlxuICBhc3NlcnRTaGVsbFNhZmUob3B0aW9ucy5hY2NvdW50LCAnYWNjb3VudCcpO1xuICBhc3NlcnRTaGVsbFNhZmUob3B0aW9ucy5yZWdpb24sICdyZWdpb24nKTtcbiAgaWYgKG9wdGlvbnMucHJvZmlsZSkgYXNzZXJ0U2hlbGxTYWZlKG9wdGlvbnMucHJvZmlsZSwgJ3Byb2ZpbGUnKTtcbiAgaWYgKG9wdGlvbnMucXVhbGlmaWVyKSBhc3NlcnRTaGVsbFNhZmUob3B0aW9ucy5xdWFsaWZpZXIsICdxdWFsaWZpZXInKTtcbiAgaWYgKG9wdGlvbnMudHJ1c3QpIGFzc2VydFNoZWxsU2FmZShvcHRpb25zLnRydXN0LCAndHJ1c3QnKTtcbiAgaWYgKG9wdGlvbnMuY2xvdWRmb3JtYXRpb25FeGVjdXRpb25Qb2xpY2llcykgYXNzZXJ0U2hlbGxTYWZlKG9wdGlvbnMuY2xvdWRmb3JtYXRpb25FeGVjdXRpb25Qb2xpY2llcywgJ2Nsb3VkZm9ybWF0aW9uLWV4ZWN1dGlvbi1wb2xpY2llcycpO1xuXG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtcbiAgICAnY2RrJyxcbiAgICAnYm9vdHN0cmFwJyxcbiAgICBgYXdzOi8vJHtvcHRpb25zLmFjY291bnR9LyR7b3B0aW9ucy5yZWdpb259YCxcbiAgXTtcblxuICBpZiAob3B0aW9ucy5wcm9maWxlKSB7XG4gICAgcGFydHMucHVzaChgLS1wcm9maWxlPSR7b3B0aW9ucy5wcm9maWxlfWApO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMucXVhbGlmaWVyKSB7XG4gICAgcGFydHMucHVzaChgLS1xdWFsaWZpZXI9JHtvcHRpb25zLnF1YWxpZmllcn1gKTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLnRydXN0KSB7XG4gICAgcGFydHMucHVzaChgLS10cnVzdD0ke29wdGlvbnMudHJ1c3R9YCk7XG4gIH1cblxuICBpZiAob3B0aW9ucy5jbG91ZGZvcm1hdGlvbkV4ZWN1dGlvblBvbGljaWVzKSB7XG4gICAgcGFydHMucHVzaChgLS1jbG91ZGZvcm1hdGlvbi1leGVjdXRpb24tcG9saWNpZXM9JHtvcHRpb25zLmNsb3VkZm9ybWF0aW9uRXhlY3V0aW9uUG9saWNpZXN9YCk7XG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignICcpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyB0aGUgYGJvb3RzdHJhcGAgY29tbWFuZCB3aXRoIHRoZSBDTEkgcHJvZ3JhbS5cbiAqXG4gKiBQcm92aXNpb25zIHRoZSBDREsgdG9vbGtpdCBzdGFjayBpbiB0aGUgdGFyZ2V0IEFXUyBhY2NvdW50L3JlZ2lvblxuICogc28gdGhhdCBDREsgZGVwbG95bWVudHMgY2FuIHByb2NlZWQuXG4gKlxuICogQHBhcmFtIHByb2dyYW0gLSBUaGUgcm9vdCBDb21tYW5kZXIgcHJvZ3JhbSBpbnN0YW5jZSB0byBhdHRhY2ggdGhlIGNvbW1hbmQgdG8uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBib290c3RyYXAocHJvZ3JhbTogQ29tbWFuZCk6IHZvaWQge1xuICB3aXRoUHJvZmlsZU9wdGlvbihcbiAgICB3aXRoUmVnaW9uT3B0aW9uKHByb2dyYW1cbiAgICAgIC5jb21tYW5kKCdib290c3RyYXAnKVxuICAgICAgLmRlc2NyaXB0aW9uKCdCb290c3RyYXAgQVdTIENESyB0b29sa2l0IHN0YWNrIGluIHRhcmdldCBhY2NvdW50L3JlZ2lvbicpXG4gICAgICAub3B0aW9uKCctLWFjY291bnQgPGlkPicsICdBV1MgYWNjb3VudCBJRCAoZGVmYXVsdHMgdG8gQVdTX0FDQ09VTlRfSUQgb3IgQ0RLX0RFRkFVTFRfQUNDT1VOVCBlbnYpJykpLFxuICApXG4gICAgLm9wdGlvbignLS1xdWFsaWZpZXIgPHF1YWxpZmllcj4nLCAnQm9vdHN0cmFwIHF1YWxpZmllciBmb3IgZW52aXJvbm1lbnQgaXNvbGF0aW9uJylcbiAgICAub3B0aW9uKCctLXRydXN0IDxhY2NvdW50cz4nLCAnQ29tbWEtc2VwYXJhdGVkIGFjY291bnQgSURzIHRvIHRydXN0IGZvciBjcm9zcy1hY2NvdW50IGRlcGxveW1lbnRzJylcbiAgICAub3B0aW9uKCctLWNsb3VkZm9ybWF0aW9uLWV4ZWN1dGlvbi1wb2xpY2llcyA8YXJucz4nLCAnSUFNIHBvbGljeSBBUk5zIGZvciBDbG91ZEZvcm1hdGlvbiBleGVjdXRpb24gcm9sZScpXG4gICAgLm9wdGlvbignLS1qc29uJywgJ091dHB1dCByZXN1bHQgYXMgSlNPTicsIGZhbHNlKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgIGNvbnN0IGV4ZWN1dGlvbklkID0gcHJpbnRDb21tYW5kSGVhZGVyKCdDREsgQm9vdHN0cmFwJywgdW5kZWZpbmVkLCB7IHF1aWV0OiBvcHRpb25zLmpzb24gfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIE5ldmVyIHBlcnNpc3QgdGhlIEFXUyBhY2NvdW50IGlkIHRvIHRoZSBvbi1kaXNrIGF1ZGl0IGxvZyAofi8ucGlwZWxpbmUtbWFuYWdlci9hdWRpdC5sb2cpLlxuICAgICAgICAvLyBUaGUgYXVkaXQgbW9kdWxlIHJlY29yZHMgb3BlcmF0aW9uIG1ldGFkYXRhIG9ubHkg4oCUIHJlZ2lvbi9wcm9maWxlIGFyZSBzYWZlOyB0aGUgYWNjb3VudCBpZCBpcyBub3QuXG4gICAgICAgIGF1ZGl0TG9nKCdib290c3RyYXAnLCB7IGV4ZWN1dGlvbklkLCByZWdpb246IG9wdGlvbnMucmVnaW9uLCBwcm9maWxlOiBvcHRpb25zLnByb2ZpbGUgfSk7XG5cbiAgICAgICAgLy8gUmVzb2x2ZSBhY2NvdW50IGFuZCByZWdpb25cbiAgICAgICAgY29uc3QgYWNjb3VudCA9IHJlc29sdmVBY2NvdW50KG9wdGlvbnMuYWNjb3VudCk7XG4gICAgICAgIGNvbnN0IHJlZ2lvbiA9IHJlc29sdmVSZWdpb24ob3B0aW9ucy5yZWdpb24pO1xuXG4gICAgICAgIGlmICghYWNjb3VudCkge1xuICAgICAgICAgIHByaW50RXJyb3IoJ0FXUyBhY2NvdW50IElEIGlzIHJlcXVpcmVkJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coZGltKCdQcm92aWRlIC0tYWNjb3VudCA8aWQ+IG9yIHNldCBBV1NfQUNDT1VOVF9JRCAvIENES19ERUZBVUxUX0FDQ09VTlQgZW52aXJvbm1lbnQgdmFyaWFibGUnKSk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBV1MgYWNjb3VudCBJRCBub3QgcHJvdmlkZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByaW50SW5mbygnQm9vdHN0cmFwIHBhcmFtZXRlcnMnLCB7XG4gICAgICAgICAgYWNjb3VudCxcbiAgICAgICAgICByZWdpb24sXG4gICAgICAgICAgcHJvZmlsZTogb3B0aW9ucy5wcm9maWxlLFxuICAgICAgICAgIHF1YWxpZmllcjogb3B0aW9ucy5xdWFsaWZpZXIgfHwgJyhkZWZhdWx0KScsXG4gICAgICAgICAgdHJ1c3Q6IG9wdGlvbnMudHJ1c3QgfHwgJyhub25lKScsXG4gICAgICAgICAgY2xvdWRmb3JtYXRpb25FeGVjdXRpb25Qb2xpY2llczogb3B0aW9ucy5jbG91ZGZvcm1hdGlvbkV4ZWN1dGlvblBvbGljaWVzIHx8ICcobm9uZSknLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDREsgYXZhaWxhYmlsaXR5IGlzIHZlcmlmaWVkIHVwIGZyb250IGJ5IHRoZSBDTEkncyBwcmVBY3Rpb24gaG9vay5cblxuICAgICAgICAvLyBCdWlsZCBib290c3RyYXAgY29tbWFuZFxuICAgICAgICBjb25zdCBjb21tYW5kID0gYnVpbGRCb290c3RyYXBDb21tYW5kKHtcbiAgICAgICAgICBhY2NvdW50LFxuICAgICAgICAgIHJlZ2lvbixcbiAgICAgICAgICBwcm9maWxlOiBvcHRpb25zLnByb2ZpbGUsXG4gICAgICAgICAgcXVhbGlmaWVyOiBvcHRpb25zLnF1YWxpZmllcixcbiAgICAgICAgICB0cnVzdDogb3B0aW9ucy50cnVzdCxcbiAgICAgICAgICBjbG91ZGZvcm1hdGlvbkV4ZWN1dGlvblBvbGljaWVzOiBvcHRpb25zLmNsb3VkZm9ybWF0aW9uRXhlY3V0aW9uUG9saWNpZXMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHByaW50U2VjdGlvbignQ0RLIEV4ZWN1dGlvbicpO1xuICAgICAgICBjb25zb2xlLmxvZyhjeWFuKGJvbGQoJ0NvbW1hbmQ6JykpLCBkaW0oY29tbWFuZCkpO1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG5cbiAgICAgICAgLy8gRXhlY3V0ZSBib290c3RyYXBcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZXhlY3V0ZUNka1NoZWxsQ29tbWFuZChjb21tYW5kLCB7XG4gICAgICAgICAgZGVidWc6IHByb2dyYW0ub3B0cygpLmRlYnVnLFxuICAgICAgICAgIHNob3dPdXRwdXQ6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRTZWN0aW9uKCdCb290c3RyYXAgQ29tcGxldGUnKTtcblxuICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICBpZiAob3B0aW9ucy5qc29uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgIGV4ZWN1dGlvbklkLFxuICAgICAgICAgICAgICBhY2NvdW50LFxuICAgICAgICAgICAgICByZWdpb24sXG4gICAgICAgICAgICAgIGR1cmF0aW9uOiByZXN1bHQuZHVyYXRpb24sXG4gICAgICAgICAgICB9LCBudWxsLCAyKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICAgICAnRXhlY3V0aW9uIElEJzogZXhlY3V0aW9uSWQsXG4gICAgICAgICAgICAgICdBY2NvdW50JzogYWNjb3VudCxcbiAgICAgICAgICAgICAgJ1JlZ2lvbic6IHJlZ2lvbixcbiAgICAgICAgICAgICAgJ0R1cmF0aW9uJzogYCR7cmVzdWx0LmR1cmF0aW9ufW1zYCxcbiAgICAgICAgICAgICAgJ1N0YXR1cyc6ICfinJMgU3VjY2VzcycsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IsIEVSUk9SX0NPREVTLlZBTElEQVRJT04sIHtcbiAgICAgICAgICBkZWJ1ZzogcHJvZ3JhbS5vcHRzKCkuZGVidWcsXG4gICAgICAgICAgZXhpdDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICBjb21tYW5kOiAnYm9vdHN0cmFwJyxcbiAgICAgICAgICAgIGV4ZWN1dGlvbklkLFxuICAgICAgICAgICAgYWNjb3VudDogb3B0aW9ucy5hY2NvdW50LFxuICAgICAgICAgICAgcmVnaW9uOiBvcHRpb25zLnJlZ2lvbixcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Registers the `create-pat` command with the CLI program.
|
|
4
|
+
*
|
|
5
|
+
* Mints a named Personal Access Token — a durable, individually-revocable API
|
|
6
|
+
* credential — for CI/automation. Unlike `login` (which returns a short-lived
|
|
7
|
+
* session token), a PAT is the right long-lived credential for scripts.
|
|
8
|
+
*
|
|
9
|
+
* The platform gates PAT creation behind step-up re-authentication, so this
|
|
10
|
+
* command chains three calls: login (→ access token), step-up with the same
|
|
11
|
+
* password (→ step-up token), then POST /user/pats. The PAT binds to the user's
|
|
12
|
+
* active org; pass `--org` to switch first (persists as the active org).
|
|
13
|
+
*
|
|
14
|
+
* The raw token is printed ONCE. `--quiet` prints only `export PLATFORM_TOKEN=…`
|
|
15
|
+
* so it can be `eval`'d — the PAT is itself a valid Bearer credential.
|
|
16
|
+
*
|
|
17
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```bash
|
|
21
|
+
* PLATFORM_PASSWORD=secret pipeline-manager auth pat --name ci-deploy -u ci@example.com
|
|
22
|
+
* pipeline-manager auth pat --name ci --expires-days 30 -u ci@example.com -p secret
|
|
23
|
+
* eval $(PLATFORM_PASSWORD=secret pipeline-manager auth pat --name ci -u ci@example.com --quiet)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function createPat(program: Command): void;
|
|
27
|
+
//# sourceMappingURL=create-pat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pat.d.ts","sourceRoot":"","sources":["../../src/commands/create-pat.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkLhD"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import pico from 'picocolors';
|
|
6
|
+
import { TIMEOUTS } from '../config/cli.constants.js';
|
|
7
|
+
import { assertCredentialTlsAllowed, credentialHttpsAgent, postLogin, resolveCredentials, switchOrganization } from '../utils/auth-utils.js';
|
|
8
|
+
import { printCommandHeader, withSslOptions } from '../utils/command-utils.js';
|
|
9
|
+
import { ERROR_CODES, handleError } from '../utils/error-handler.js';
|
|
10
|
+
import { printDebug, printError, printInfo, printKeyValue, printSuccess, printWarning } from '../utils/output-utils.js';
|
|
11
|
+
import { checkAuthRateLimit, recordAuthFailure, recordAuthSuccess } from '../utils/rate-limiter.js';
|
|
12
|
+
const { bold, green, yellow } = pico;
|
|
13
|
+
const MAX_EXPIRES_DAYS = 365;
|
|
14
|
+
/**
|
|
15
|
+
* Registers the `create-pat` command with the CLI program.
|
|
16
|
+
*
|
|
17
|
+
* Mints a named Personal Access Token — a durable, individually-revocable API
|
|
18
|
+
* credential — for CI/automation. Unlike `login` (which returns a short-lived
|
|
19
|
+
* session token), a PAT is the right long-lived credential for scripts.
|
|
20
|
+
*
|
|
21
|
+
* The platform gates PAT creation behind step-up re-authentication, so this
|
|
22
|
+
* command chains three calls: login (→ access token), step-up with the same
|
|
23
|
+
* password (→ step-up token), then POST /user/pats. The PAT binds to the user's
|
|
24
|
+
* active org; pass `--org` to switch first (persists as the active org).
|
|
25
|
+
*
|
|
26
|
+
* The raw token is printed ONCE. `--quiet` prints only `export PLATFORM_TOKEN=…`
|
|
27
|
+
* so it can be `eval`'d — the PAT is itself a valid Bearer credential.
|
|
28
|
+
*
|
|
29
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```bash
|
|
33
|
+
* PLATFORM_PASSWORD=secret pipeline-manager auth pat --name ci-deploy -u ci@example.com
|
|
34
|
+
* pipeline-manager auth pat --name ci --expires-days 30 -u ci@example.com -p secret
|
|
35
|
+
* eval $(PLATFORM_PASSWORD=secret pipeline-manager auth pat --name ci -u ci@example.com --quiet)
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function createPat(program) {
|
|
39
|
+
withSslOptions(program
|
|
40
|
+
.command('pat')
|
|
41
|
+
.description('Create a named Personal Access Token (long-lived CLI/automation credential)')
|
|
42
|
+
.requiredOption('--name <name>', 'Human-readable token name (e.g. ci-deploy)')
|
|
43
|
+
.option('--expires-days <days>', `Token lifetime in days (1-${MAX_EXPIRES_DAYS})`, '90')
|
|
44
|
+
.option('--scope <scope>', 'Optional token scope')
|
|
45
|
+
.option('-u, --identifier <identifier>', 'Username or email')
|
|
46
|
+
.option('-p, --password <password>', 'Password (prefer PLATFORM_PASSWORD env)')
|
|
47
|
+
.option('--org <orgId>', 'Bind the token to a specific organization (switches active org)')
|
|
48
|
+
.option('--url <url>', 'Platform base URL', process.env.PLATFORM_BASE_URL || 'https://localhost:8443'))
|
|
49
|
+
.option('--quiet', 'Only print the export statement (useful for eval)')
|
|
50
|
+
.action(async (options) => {
|
|
51
|
+
// SECURITY: this POSTs a plaintext password (login + step-up). Never send it
|
|
52
|
+
// over an unverified TLS connection in production — a MITM would harvest it.
|
|
53
|
+
// Mirrors the guard in `login`. Non-production still honors --no-verify-ssl.
|
|
54
|
+
assertCredentialTlsAllowed(options.verifySsl);
|
|
55
|
+
// Credentials from flags OR PLATFORM_IDENTIFIER/PLATFORM_PASSWORD env (so the
|
|
56
|
+
// password need not appear in shell history / `ps`).
|
|
57
|
+
const { identifier, password } = resolveCredentials(options);
|
|
58
|
+
const quiet = options.quiet ?? false;
|
|
59
|
+
const executionId = printCommandHeader('Create Personal Access Token', 'Create Personal Access Token', { quiet });
|
|
60
|
+
try {
|
|
61
|
+
// Validate name.
|
|
62
|
+
const name = typeof options.name === 'string' ? options.name.trim() : '';
|
|
63
|
+
if (!name) {
|
|
64
|
+
printError('Token name is required (--name)');
|
|
65
|
+
process.exit(ERROR_CODES.VALIDATION);
|
|
66
|
+
}
|
|
67
|
+
if (name.length > 100) {
|
|
68
|
+
printError('Token name must be 100 characters or fewer');
|
|
69
|
+
process.exit(ERROR_CODES.VALIDATION);
|
|
70
|
+
}
|
|
71
|
+
// Validate expiry → seconds.
|
|
72
|
+
const days = Math.floor(Number(options.expiresDays));
|
|
73
|
+
if (!Number.isFinite(days) || days < 1 || days > MAX_EXPIRES_DAYS) {
|
|
74
|
+
printError(`--expires-days must be an integer between 1 and ${MAX_EXPIRES_DAYS}`);
|
|
75
|
+
process.exit(ERROR_CODES.VALIDATION);
|
|
76
|
+
}
|
|
77
|
+
const expiresIn = days * 86400;
|
|
78
|
+
// Credentials required — step-up needs a password, so --refresh can't work here.
|
|
79
|
+
if (!identifier || !password) {
|
|
80
|
+
printError('create-pat requires --identifier and --password (or PLATFORM_IDENTIFIER/PLATFORM_PASSWORD env)');
|
|
81
|
+
process.exit(ERROR_CODES.AUTHENTICATION);
|
|
82
|
+
}
|
|
83
|
+
if (options.password) {
|
|
84
|
+
printWarning('Passing --password on the command line can expose it via shell history; prefer the PLATFORM_PASSWORD env var.');
|
|
85
|
+
}
|
|
86
|
+
// Rate limiting — prevent brute force (keyed to identifier + url, like login).
|
|
87
|
+
const rateLimitMsg = checkAuthRateLimit(identifier, options.url);
|
|
88
|
+
if (rateLimitMsg) {
|
|
89
|
+
printError(rateLimitMsg);
|
|
90
|
+
process.exit(ERROR_CODES.AUTHENTICATION);
|
|
91
|
+
}
|
|
92
|
+
if (!quiet) {
|
|
93
|
+
printInfo('Authenticating', { identifier, url: options.url, verifySsl: options.verifySsl });
|
|
94
|
+
}
|
|
95
|
+
const httpsAgent = credentialHttpsAgent(options.verifySsl);
|
|
96
|
+
const timeout = TIMEOUTS.HTTP_REQUEST;
|
|
97
|
+
// 1) Login → session access token.
|
|
98
|
+
let accessToken;
|
|
99
|
+
try {
|
|
100
|
+
accessToken = await postLogin({ url: options.url, identifier, password, httpsAgent, timeout });
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
recordAuthFailure(identifier, options.url);
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
if (!accessToken) {
|
|
107
|
+
recordAuthFailure(identifier, options.url);
|
|
108
|
+
printError('Login failed: no access token in response');
|
|
109
|
+
process.exit(ERROR_CODES.AUTHENTICATION);
|
|
110
|
+
}
|
|
111
|
+
recordAuthSuccess(identifier, options.url);
|
|
112
|
+
// 2) Optionally bind to a specific org (persists as the active org, which the
|
|
113
|
+
// PAT inherits).
|
|
114
|
+
if (options.org) {
|
|
115
|
+
if (!quiet)
|
|
116
|
+
printInfo('Switching to organization', { orgId: options.org });
|
|
117
|
+
accessToken = await switchOrganization({
|
|
118
|
+
url: options.url,
|
|
119
|
+
orgId: options.org,
|
|
120
|
+
accessToken,
|
|
121
|
+
httpsAgent,
|
|
122
|
+
timeout,
|
|
123
|
+
quiet,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// 3) Step-up — re-verify the password to unlock the gated create call.
|
|
127
|
+
// The returned token is short-lived (~60s), so we use it immediately.
|
|
128
|
+
const stepUpUrl = `${options.url}/api/auth/step-up`;
|
|
129
|
+
printDebug('POST', { url: stepUpUrl });
|
|
130
|
+
const stepUpRes = await axios.post(stepUpUrl, { password }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` }, httpsAgent, timeout });
|
|
131
|
+
const stepUpToken = stepUpRes.data?.data?.stepUpToken;
|
|
132
|
+
if (!stepUpToken) {
|
|
133
|
+
printError('Step-up verification failed: no step-up token in response');
|
|
134
|
+
process.exit(ERROR_CODES.AUTHENTICATION);
|
|
135
|
+
}
|
|
136
|
+
// 4) Create the PAT.
|
|
137
|
+
const patUrl = `${options.url}/api/user/pats`;
|
|
138
|
+
printDebug('POST', { url: patUrl });
|
|
139
|
+
const patRes = await axios.post(patUrl, { name, expiresIn, ...(options.scope ? { scope: options.scope } : {}) }, {
|
|
140
|
+
headers: {
|
|
141
|
+
'Content-Type': 'application/json',
|
|
142
|
+
'Authorization': `Bearer ${accessToken}`,
|
|
143
|
+
'X-Step-Up-Token': stepUpToken,
|
|
144
|
+
},
|
|
145
|
+
httpsAgent,
|
|
146
|
+
timeout,
|
|
147
|
+
});
|
|
148
|
+
const token = patRes.data?.data?.token;
|
|
149
|
+
const pat = patRes.data?.data?.pat;
|
|
150
|
+
if (!token) {
|
|
151
|
+
printError('Create token failed: no token in response');
|
|
152
|
+
process.exit(ERROR_CODES.API_REQUEST);
|
|
153
|
+
}
|
|
154
|
+
// Quiet mode: emit only the export line (the PAT is a valid Bearer token).
|
|
155
|
+
if (quiet) {
|
|
156
|
+
console.log(`export PLATFORM_TOKEN=${token}`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
console.log('');
|
|
160
|
+
printSuccess('Personal access token created');
|
|
161
|
+
console.log('');
|
|
162
|
+
printKeyValue({
|
|
163
|
+
'Name': pat?.name ?? name,
|
|
164
|
+
'Token ID (jti)': pat?.jti ?? '(unknown)',
|
|
165
|
+
'Expires': pat?.expiresAt ?? `${days} day(s)`,
|
|
166
|
+
...(pat?.scope ? { Scope: pat.scope } : {}),
|
|
167
|
+
});
|
|
168
|
+
console.log('');
|
|
169
|
+
console.log(yellow(bold('Copy your token now — it will not be shown again:')));
|
|
170
|
+
console.log(green(token));
|
|
171
|
+
console.log('');
|
|
172
|
+
printInfo('Tip: use it as PLATFORM_TOKEN for subsequent commands:');
|
|
173
|
+
console.log(green(' export PLATFORM_TOKEN=<token>'));
|
|
174
|
+
console.log(green(` # or: eval $(pipeline-manager auth pat --name ${name} -u ${identifier} --quiet)`));
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (axios.isAxiosError(error)) {
|
|
178
|
+
const status = error.response?.status;
|
|
179
|
+
const message = error.response?.data?.message;
|
|
180
|
+
printError('Create token failed', {
|
|
181
|
+
status: status ?? 'no response',
|
|
182
|
+
...(message ? { message } : {}),
|
|
183
|
+
});
|
|
184
|
+
process.exit(ERROR_CODES.AUTHENTICATION);
|
|
185
|
+
}
|
|
186
|
+
handleError(error, ERROR_CODES.API_REQUEST, {
|
|
187
|
+
debug: program.opts().debug,
|
|
188
|
+
exit: true,
|
|
189
|
+
context: { command: 'create-pat', executionId, identifier: options.identifier, url: options.url },
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlLXBhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9jcmVhdGUtcGF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsb0JBQW9CLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0ksT0FBTyxFQUFFLGtCQUFrQixFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckUsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDeEgsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFcEcsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBaUJyQyxNQUFNLGdCQUFnQixHQUFHLEdBQUcsQ0FBQztBQUU3Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLE9BQWdCO0lBQ3hDLGNBQWMsQ0FBQyxPQUFPO1NBQ25CLE9BQU8sQ0FBQyxLQUFLLENBQUM7U0FDZCxXQUFXLENBQUMsNkVBQTZFLENBQUM7U0FDMUYsY0FBYyxD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LENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztpQkFDaEMsQ0FBQyxDQUFDO2dCQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQzNDLENBQUM7WUFDRCxXQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxXQUFXLEVBQUU7Z0JBQzFDLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSztnQkFDM0IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUU7YUFDbEcsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgcGljbyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCB7IFRJTUVPVVRTIH0gZnJvbSAnLi4vY29uZmlnL2NsaS5jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgYXNzZXJ0Q3JlZGVudGlhbFRsc0FsbG93ZWQsIGNyZWRlbnRpYWxIdHRwc0FnZW50LCBwb3N0TG9naW4sIHJlc29sdmVDcmVkZW50aWFscywgc3dpdGNoT3JnYW5pemF0aW9uIH0gZnJvbSAnLi4vdXRpbHMvYXV0aC11dGlscy5qcyc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIsIHdpdGhTc2xPcHRpb25zIH0gZnJvbSAnLi4vdXRpbHMvY29tbWFuZC11dGlscy5qcyc7XG5pbXBvcnQgeyBFUlJPUl9DT0RFUywgaGFuZGxlRXJyb3IgfSBmcm9tICcuLi91dGlscy9lcnJvci1oYW5kbGVyLmpzJztcbmltcG9ydCB7IHByaW50RGVidWcsIHByaW50RXJyb3IsIHByaW50SW5mbywgcHJpbnRLZXlWYWx1ZSwgcHJpbnRTdWNjZXNzLCBwcmludFdhcm5pbmcgfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMuanMnO1xuaW1wb3J0IHsgY2hlY2tBdXRoUmF0ZUxpbWl0LCByZWNvcmRBdXRoRmFpbHVyZSwgcmVjb3JkQXV0aFN1Y2Nlc3MgfSBmcm9tICcuLi91dGlscy9yYXRlLWxpbWl0ZXIuanMnO1xuXG5jb25zdCB7IGJvbGQsIGdyZWVuLCB5ZWxsb3cgfSA9IHBpY287XG5cbi8qKiBTdGVwLXVwIHJlc3BvbnNlIOKAlCBhIHNob3J0LWxpdmVkICg2MHMpIEpXVCBib3VuZCB0byB0aGUgdXNlcidzIHN1Yi4gKi9cbmludGVyZmFjZSBTdGVwVXBSZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIGRhdGE6IHsgc3RlcFVwVG9rZW46IHN0cmluZyB9O1xufVxuXG4vKiogQ3JlYXRlLVBBVCByZXNwb25zZSDigJQgdGhlIHJhdyB0b2tlbiBpcyByZXR1cm5lZCBleGFjdGx5IG9uY2UuICovXG5pbnRlcmZhY2UgQ3JlYXRlUGF0UmVzcG9uc2Uge1xuICBzdWNjZXNzOiBib29sZWFuO1xuICBkYXRhOiB7XG4gICAgdG9rZW46IHN0cmluZztcbiAgICBwYXQ6IHsganRpOiBzdHJpbmc7IG5hbWU6IHN0cmluZzsgZXhwaXJlc0F0OiBzdHJpbmc7IHNjb3BlPzogc3RyaW5nIHwgbnVsbCB9O1xuICB9O1xufVxuXG5jb25zdCBNQVhfRVhQSVJFU19EQVlTID0gMzY1O1xuXG4vKipcbiAqIFJlZ2lzdGVycyB0aGUgYGNyZWF0ZS1wYXRgIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogTWludHMgYSBuYW1lZCBQZXJzb25hbCBBY2Nlc3MgVG9rZW4g4oCUIGEgZHVyYWJsZSwgaW5kaXZpZHVhbGx5LXJldm9jYWJsZSBBUElcbiAqIGNyZWRlbnRpYWwg4oCUIGZvciBDSS9hdXRvbWF0aW9uLiBVbmxpa2UgYGxvZ2luYCAod2hpY2ggcmV0dXJucyBhIHNob3J0LWxpdmVkXG4gKiBzZXNzaW9uIHRva2VuKSwgYSBQQVQgaXMgdGhlIHJpZ2h0IGxvbmctbGl2ZWQgY3JlZGVudGlhbCBmb3Igc2NyaXB0cy5cbiAqXG4gKiBUaGUgcGxhdGZvcm0gZ2F0ZXMgUEFUIGNyZWF0aW9uIGJlaGluZCBzdGVwLXVwIHJlLWF1dGhlbnRpY2F0aW9uLCBzbyB0aGlzXG4gKiBjb21tYW5kIGNoYWlucyB0aHJlZSBjYWxsczogbG9naW4gKOKGkiBhY2Nlc3MgdG9rZW4pLCBzdGVwLXVwIHdpdGggdGhlIHNhbWVcbiAqIHBhc3N3b3JkICjihpIgc3RlcC11cCB0b2tlbiksIHRoZW4gUE9TVCAvdXNlci9wYXRzLiBUaGUgUEFUIGJpbmRzIHRvIHRoZSB1c2VyJ3NcbiAqIGFjdGl2ZSBvcmc7IHBhc3MgYC0tb3JnYCB0byBzd2l0Y2ggZmlyc3QgKHBlcnNpc3RzIGFzIHRoZSBhY3RpdmUgb3JnKS5cbiAqXG4gKiBUaGUgcmF3IHRva2VuIGlzIHByaW50ZWQgT05DRS4gYC0tcXVpZXRgIHByaW50cyBvbmx5IGBleHBvcnQgUExBVEZPUk1fVE9LRU494oCmYFxuICogc28gaXQgY2FuIGJlIGBldmFsYCdkIOKAlCB0aGUgUEFUIGlzIGl0c2VsZiBhIHZhbGlkIEJlYXJlciBjcmVkZW50aWFsLlxuICpcbiAqIEBwYXJhbSBwcm9ncmFtIC0gVGhlIHJvb3QgQ29tbWFuZGVyIHByb2dyYW0gaW5zdGFuY2UgdG8gYXR0YWNoIHRoZSBjb21tYW5kIHRvLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBiYXNoXG4gKiBQTEFURk9STV9QQVNTV09SRD1zZWNyZXQgcGlwZWxpbmUtbWFuYWdlciBhdXRoIHBhdCAtLW5hbWUgY2ktZGVwbG95IC11IGNpQGV4YW1wbGUuY29tXG4gKiBwaXBlbGluZS1tYW5hZ2VyIGF1dGggcGF0IC0tbmFtZSBjaSAtLWV4cGlyZXMtZGF5cyAzMCAtdSBjaUBleGFtcGxlLmNvbSAtcCBzZWNyZXRcbiAqIGV2YWwgJChQTEFURk9STV9QQVNTV09SRD1zZWNyZXQgcGlwZWxpbmUtbWFuYWdlciBhdXRoIHBhdCAtLW5hbWUgY2kgLXUgY2lAZXhhbXBsZS5jb20gLS1xdWlldClcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGF0KHByb2dyYW06IENvbW1hbmQpOiB2b2lkIHtcbiAgd2l0aFNzbE9wdGlvbnMocHJvZ3JhbVxuICAgIC5jb21tYW5kKCdwYXQnKVxuICAgIC5kZXNjcmlwdGlvbignQ3JlYXRlIGEgbmFtZWQgUGVyc29uYWwgQWNjZXNzIFRva2VuIChsb25nLWxpdmVkIENMSS9hdXRvbWF0aW9uIGNyZWRlbnRpYWwpJylcbiAgICAucmVxdWlyZWRPcHRpb24oJy0tbmFtZSA8bmFtZT4nLCAnSHVtYW4tcmVhZGFibGUgdG9rZW4gbmFtZSAoZS5nLiBjaS1kZXBsb3kpJylcbiAgICAub3B0aW9uKCctLWV4cGlyZXMtZGF5cyA8ZGF5cz4nLCBgVG9rZW4gbGlmZXRpbWUgaW4gZGF5cyAoMS0ke01BWF9FWFBJUkVTX0RBWVN9KWAsICc5MCcpXG4gICAgLm9wdGlvbignLS1zY29wZSA8c2NvcGU+JywgJ09wdGlvbmFsIHRva2VuIHNjb3BlJylcbiAgICAub3B0aW9uKCctdSwgLS1pZGVudGlmaWVyIDxpZGVudGlmaWVyPicsICdVc2VybmFtZSBvciBlbWFpbCcpXG4gICAgLm9wdGlvbignLXAsIC0tcGFzc3dvcmQgPHBhc3N3b3JkPicsICdQYXNzd29yZCAocHJlZmVyIFBMQVRGT1JNX1BBU1NXT1JEIGVudiknKVxuICAgIC5vcHRpb24oJy0tb3JnIDxvcmdJZD4nLCAnQmluZCB0aGUgdG9rZW4gdG8gYSBzcGVjaWZpYyBvcmdhbml6YXRpb24gKHN3aXRjaGVzIGFjdGl2ZSBvcmcpJylcbiAgICAub3B0aW9uKCctLXVybCA8dXJsPicsICdQbGF0Zm9ybSBiYXNlIFVSTCcsIHByb2Nlc3MuZW52LlBMQVRGT1JNX0JBU0VfVVJMIHx8ICdodHRwczovL2xvY2FsaG9zdDo4NDQzJykpXG4gICAgLm9wdGlvbignLS1xdWlldCcsICdPbmx5IHByaW50IHRoZSBleHBvcnQgc3RhdGVtZW50ICh1c2VmdWwgZm9yIGV2YWwpJylcbiAgICAuYWN0aW9uKGFzeW5jIChvcHRpb25zKSA9PiB7XG4gICAgICAvLyBTRUNVUklUWTogdGhpcyBQT1NUcyBhIHBsYWludGV4dCBwYXNzd29yZCAobG9naW4gKyBzdGVwLXVwKS4gTmV2ZXIgc2VuZCBpdFxuICAgICAgLy8gb3ZlciBhbiB1bnZlcmlmaWVkIFRMUyBjb25uZWN0aW9uIGluIHByb2R1Y3Rpb24g4oCUIGEgTUlUTSB3b3VsZCBoYXJ2ZXN0IGl0LlxuICAgICAgLy8gTWlycm9ycyB0aGUgZ3VhcmQgaW4gYGxvZ2luYC4gTm9uLXByb2R1Y3Rpb24gc3RpbGwgaG9ub3JzIC0tbm8tdmVyaWZ5LXNzbC5cbiAgICAgIGFzc2VydENyZWRlbnRpYWxUbHNBbGxvd2VkKG9wdGlvbnMudmVyaWZ5U3NsKTtcblxuICAgICAgLy8gQ3JlZGVudGlhbHMgZnJvbSBmbGFncyBPUiBQTEFURk9STV9JREVOVElGSUVSL1BMQVRGT1JNX1BBU1NXT1JEIGVudiAoc28gdGhlXG4gICAgICAvLyBwYXNzd29yZCBuZWVkIG5vdCBhcHBlYXIgaW4gc2hlbGwgaGlzdG9yeSAvIGBwc2ApLlxuICAgICAgY29uc3QgeyBpZGVudGlmaWVyLCBwYXNzd29yZCB9ID0gcmVzb2x2ZUNyZWRlbnRpYWxzKG9wdGlvbnMpO1xuICAgICAgY29uc3QgcXVpZXQgPSBvcHRpb25zLnF1aWV0ID8/IGZhbHNlO1xuICAgICAgY29uc3QgZXhlY3V0aW9uSWQgPSBwcmludENvbW1hbmRIZWFkZXIoXG4gICAgICAgICdDcmVhdGUgUGVyc29uYWwgQWNjZXNzIFRva2VuJyxcbiAgICAgICAgJ0NyZWF0ZSBQZXJzb25hbCBBY2Nlc3MgVG9rZW4nLFxuICAgICAgICB7IHF1aWV0IH0sXG4gICAgICApO1xuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBWYWxpZGF0ZSBuYW1lLlxuICAgICAgICBjb25zdCBuYW1lID0gdHlwZW9mIG9wdGlvbnMubmFtZSA9PT0gJ3N0cmluZycgPyBvcHRpb25zLm5hbWUudHJpbSgpIDogJyc7XG4gICAgICAgIGlmICghbmFtZSkge1xuICAgICAgICAgIHByaW50RXJyb3IoJ1Rva2VuIG5hbWUgaXMgcmVxdWlyZWQgKC0tbmFtZSknKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoRVJST1JfQ09ERVMuVkFMSURBVElPTik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hbWUubGVuZ3RoID4gMTAwKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignVG9rZW4gbmFtZSBtdXN0IGJlIDEwMCBjaGFyYWN0ZXJzIG9yIGZld2VyJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KEVSUk9SX0NPREVTLlZBTElEQVRJT04pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgZXhwaXJ5IOKGkiBzZWNvbmRzLlxuICAgICAgICBjb25zdCBkYXlzID0gTWF0aC5mbG9vcihOdW1iZXIob3B0aW9ucy5leHBpcmVzRGF5cykpO1xuICAgICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShkYXlzKSB8fCBkYXlzIDwgMSB8fCBkYXlzID4gTUFYX0VYUElSRVNfREFZUykge1xuICAgICAgICAgIHByaW50RXJyb3IoYC0tZXhwaXJlcy1kYXlzIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kICR7TUFYX0VYUElSRVNfREFZU31gKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoRVJST1JfQ09ERVMuVkFMSURBVElPTik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZXhwaXJlc0luID0gZGF5cyAqIDg2NDAwO1xuXG4gICAgICAgIC8vIENyZWRlbnRpYWxzIHJlcXVpcmVkIOKAlCBzdGVwLXVwIG5lZWRzIGEgcGFzc3dvcmQsIHNvIC0tcmVmcmVzaCBjYW4ndCB3b3JrIGhlcmUuXG4gICAgICAgIGlmICghaWRlbnRpZmllciB8fCAhcGFzc3dvcmQpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdjcmVhdGUtcGF0IHJlcXVpcmVzIC0taWRlbnRpZmllciBhbmQgLS1wYXNzd29yZCAob3IgUExBVEZPUk1fSURFTlRJRklFUi9QTEFURk9STV9QQVNTV09SRCBlbnYpJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KEVSUk9SX0NPREVTLkFVVEhFTlRJQ0FUSU9OKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0aW9ucy5wYXNzd29yZCkge1xuICAgICAgICAgIHByaW50V2FybmluZygnUGFzc2luZyAtLXBhc3N3b3JkIG9uIHRoZSBjb21tYW5kIGxpbmUgY2FuIGV4cG9zZSBpdCB2aWEgc2hlbGwgaGlzdG9yeTsgcHJlZmVyIHRoZSBQTEFURk9STV9QQVNTV09SRCBlbnYgdmFyLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmF0ZSBsaW1pdGluZyDigJQgcHJldmVudCBicnV0ZSBmb3JjZSAoa2V5ZWQgdG8gaWRlbnRpZmllciArIHVybCwgbGlrZSBsb2dpbikuXG4gICAgICAgIGNvbnN0IHJhdGVMaW1pdE1zZyA9IGNoZWNrQXV0aFJhdGVMaW1pdChpZGVudGlmaWVyLCBvcHRpb25zLnVybCk7XG4gICAgICAgIGlmIChyYXRlTGltaXRNc2cpIHtcbiAgICAgICAgICBwcmludEVycm9yKHJhdGVMaW1pdE1zZyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KEVSUk9SX0NPREVTLkFVVEhFTlRJQ0FUSU9OKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcXVpZXQpIHtcbiAgICAgICAgICBwcmludEluZm8oJ0F1dGhlbnRpY2F0aW5nJywgeyBpZGVudGlmaWVyLCB1cmw6IG9wdGlvbnMudXJsLCB2ZXJpZnlTc2w6IG9wdGlvbnMudmVyaWZ5U3NsIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaHR0cHNBZ2VudCA9IGNyZWRlbnRpYWxIdHRwc0FnZW50KG9wdGlvbnMudmVyaWZ5U3NsKTtcbiAgICAgICAgY29uc3QgdGltZW91dCA9IFRJTUVPVVRTLkhUVFBfUkVRVUVTVDtcblxuICAgICAgICAvLyAxKSBMb2dpbiDihpIgc2Vzc2lvbiBhY2Nlc3MgdG9rZW4uXG4gICAgICAgIGxldCBhY2Nlc3NUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGFjY2Vzc1Rva2VuID0gYXdhaXQgcG9zdExvZ2luKHsgdXJsOiBvcHRpb25zLnVybCwgaWRlbnRpZmllciwgcGFzc3dvcmQsIGh0dHBzQWdlbnQsIHRpbWVvdXQgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVjb3JkQXV0aEZhaWx1cmUoaWRlbnRpZmllciwgb3B0aW9ucy51cmwpO1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYWNjZXNzVG9rZW4pIHtcbiAgICAgICAgICByZWNvcmRBdXRoRmFpbHVyZShpZGVudGlmaWVyLCBvcHRpb25zLnVybCk7XG4gICAgICAgICAgcHJpbnRFcnJvcignTG9naW4gZmFpbGVkOiBubyBhY2Nlc3MgdG9rZW4gaW4gcmVzcG9uc2UnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoRVJST1JfQ09ERVMuQVVUSEVOVElDQVRJT04pO1xuICAgICAgICB9XG4gICAgICAgIHJlY29yZEF1dGhTdWNjZXNzKGlkZW50aWZpZXIsIG9wdGlvbnMudXJsKTtcblxuICAgICAgICAvLyAyKSBPcHRpb25hbGx5IGJpbmQgdG8gYSBzcGVjaWZpYyBvcmcgKHBlcnNpc3RzIGFzIHRoZSBhY3RpdmUgb3JnLCB3aGljaCB0aGVcbiAgICAgICAgLy8gICAgUEFUIGluaGVyaXRzKS5cbiAgICAgICAgaWYgKG9wdGlvbnMub3JnKSB7XG4gICAgICAgICAgaWYgKCFxdWlldCkgcHJpbnRJbmZvKCdTd2l0Y2hpbmcgdG8gb3JnYW5pemF0aW9uJywgeyBvcmdJZDogb3B0aW9ucy5vcmcgfSk7XG4gICAgICAgICAgYWNjZXNzVG9rZW4gPSBhd2FpdCBzd2l0Y2hPcmdhbml6YXRpb24oe1xuICAgICAgICAgICAgdXJsOiBvcHRpb25zLnVybCxcbiAgICAgICAgICAgIG9yZ0lkOiBvcHRpb25zLm9yZyxcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgaHR0cHNBZ2VudCxcbiAgICAgICAgICAgIHRpbWVvdXQsXG4gICAgICAgICAgICBxdWlldCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDMpIFN0ZXAtdXAg4oCUIHJlLXZlcmlmeSB0aGUgcGFzc3dvcmQgdG8gdW5sb2NrIHRoZSBnYXRlZCBjcmVhdGUgY2FsbC5cbiAgICAgICAgLy8gICAgVGhlIHJldHVybmVkIHRva2VuIGlzIHNob3J0LWxpdmVkICh+NjBzKSwgc28gd2UgdXNlIGl0IGltbWVkaWF0ZWx5LlxuICAgICAgICBjb25zdCBzdGVwVXBVcmwgPSBgJHtvcHRpb25zLnVybH0vYXBpL2F1dGgvc3RlcC11cGA7XG4gICAgICAgIHByaW50RGVidWcoJ1BPU1QnLCB7IHVybDogc3RlcFVwVXJsIH0pO1xuICAgICAgICBjb25zdCBzdGVwVXBSZXMgPSBhd2FpdCBheGlvcy5wb3N0PFN0ZXBVcFJlc3BvbnNlPihcbiAgICAgICAgICBzdGVwVXBVcmwsXG4gICAgICAgICAgeyBwYXNzd29yZCB9LFxuICAgICAgICAgIHsgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLCAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gIH0sIGh0dHBzQWdlbnQsIHRpbWVvdXQgfSxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgc3RlcFVwVG9rZW4gPSBzdGVwVXBSZXMuZGF0YT8uZGF0YT8uc3RlcFVwVG9rZW47XG4gICAgICAgIGlmICghc3RlcFVwVG9rZW4pIHtcbiAgICAgICAgICBwcmludEVycm9yKCdTdGVwLXVwIHZlcmlmaWNhdGlvbiBmYWlsZWQ6IG5vIHN0ZXAtdXAgdG9rZW4gaW4gcmVzcG9uc2UnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoRVJST1JfQ09ERVMuQVVUSEVOVElDQVRJT04pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gNCkgQ3JlYXRlIHRoZSBQQVQuXG4gICAgICAgIGNvbnN0IHBhdFVybCA9IGAke29wdGlvbnMudXJsfS9hcGkvdXNlci9wYXRzYDtcbiAgICAgICAgcHJpbnREZWJ1ZygnUE9TVCcsIHsgdXJsOiBwYXRVcmwgfSk7XG4gICAgICAgIGNvbnN0IHBhdFJlcyA9IGF3YWl0IGF4aW9zLnBvc3Q8Q3JlYXRlUGF0UmVzcG9uc2U+KFxuICAgICAgICAgIHBhdFVybCxcbiAgICAgICAgICB7IG5hbWUsIGV4cGlyZXNJbiwgLi4uKG9wdGlvbnMuc2NvcGUgPyB7IHNjb3BlOiBvcHRpb25zLnNjb3BlIH0gOiB7fSkgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgICAgICAgICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke2FjY2Vzc1Rva2VufWAsXG4gICAgICAgICAgICAgICdYLVN0ZXAtVXAtVG9rZW4nOiBzdGVwVXBUb2tlbixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBodHRwc0FnZW50LFxuICAgICAgICAgICAgdGltZW91dCxcbiAgICAgICAgICB9LFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHRva2VuID0gcGF0UmVzLmRhdGE/LmRhdGE/LnRva2VuO1xuICAgICAgICBjb25zdCBwYXQgPSBwYXRSZXMuZGF0YT8uZGF0YT8ucGF0O1xuICAgICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignQ3JlYXRlIHRva2VuIGZhaWxlZDogbm8gdG9rZW4gaW4gcmVzcG9uc2UnKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoRVJST1JfQ09ERVMuQVBJX1JFUVVFU1QpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUXVpZXQgbW9kZTogZW1pdCBvbmx5IHRoZSBleHBvcnQgbGluZSAodGhlIFBBVCBpcyBhIHZhbGlkIEJlYXJlciB0b2tlbikuXG4gICAgICAgIGlmIChxdWlldCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBleHBvcnQgUExBVEZPUk1fVE9LRU49JHt0b2tlbn1gKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2VzcygnUGVyc29uYWwgYWNjZXNzIHRva2VuIGNyZWF0ZWQnKTtcbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAnTmFtZSc6IHBhdD8ubmFtZSA/PyBuYW1lLFxuICAgICAgICAgICdUb2tlbiBJRCAoanRpKSc6IHBhdD8uanRpID8/ICcodW5rbm93biknLFxuICAgICAgICAgICdFeHBpcmVzJzogcGF0Py5leHBpcmVzQXQgPz8gYCR7ZGF5c30gZGF5KHMpYCxcbiAgICAgICAgICAuLi4ocGF0Py5zY29wZSA/IHsgU2NvcGU6IHBhdC5zY29wZSB9IDoge30pLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBjb25zb2xlLmxvZyh5ZWxsb3coYm9sZCgnQ29weSB5b3VyIHRva2VuIG5vdyDigJQgaXQgd2lsbCBub3QgYmUgc2hvd24gYWdhaW46JykpKTtcbiAgICAgICAgY29uc29sZS5sb2coZ3JlZW4odG9rZW4pKTtcbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludEluZm8oJ1RpcDogdXNlIGl0IGFzIFBMQVRGT1JNX1RPS0VOIGZvciBzdWJzZXF1ZW50IGNvbW1hbmRzOicpO1xuICAgICAgICBjb25zb2xlLmxvZyhncmVlbignICBleHBvcnQgUExBVEZPUk1fVE9LRU49PHRva2VuPicpKTtcbiAgICAgICAgY29uc29sZS5sb2coZ3JlZW4oYCAgIyBvcjogIGV2YWwgJChwaXBlbGluZS1tYW5hZ2VyIGF1dGggcGF0IC0tbmFtZSAke25hbWV9IC11ICR7aWRlbnRpZmllcn0gLS1xdWlldClgKSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoYXhpb3MuaXNBeGlvc0Vycm9yKGVycm9yKSkge1xuICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IGVycm9yLnJlc3BvbnNlPy5zdGF0dXM7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZSA9IChlcnJvci5yZXNwb25zZT8uZGF0YSBhcyB7IG1lc3NhZ2U/OiBzdHJpbmcgfSk/Lm1lc3NhZ2U7XG4gICAgICAgICAgcHJpbnRFcnJvcignQ3JlYXRlIHRva2VuIGZhaWxlZCcsIHtcbiAgICAgICAgICAgIHN0YXR1czogc3RhdHVzID8/ICdubyByZXNwb25zZScsXG4gICAgICAgICAgICAuLi4obWVzc2FnZSA/IHsgbWVzc2FnZSB9IDoge30pLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdChFUlJPUl9DT0RFUy5BVVRIRU5USUNBVElPTik7XG4gICAgICAgIH1cbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IsIEVSUk9SX0NPREVTLkFQSV9SRVFVRVNULCB7XG4gICAgICAgICAgZGVidWc6IHByb2dyYW0ub3B0cygpLmRlYnVnLFxuICAgICAgICAgIGV4aXQ6IHRydWUsXG4gICAgICAgICAgY29udGV4dDogeyBjb21tYW5kOiAnY3JlYXRlLXBhdCcsIGV4ZWN1dGlvbklkLCBpZGVudGlmaWVyOiBvcHRpb25zLmlkZW50aWZpZXIsIHVybDogb3B0aW9ucy51cmwgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* Registers the `create-pipeline` command with the CLI program.
|
|
4
|
+
*
|
|
5
|
+
* Accepts a pipeline properties JSON file, validates it, resolves
|
|
6
|
+
* project/organization from CLI flags or the props file, and
|
|
7
|
+
* creates the pipeline via the platform API.
|
|
8
|
+
*
|
|
9
|
+
* @param program - The root Commander program instance to attach the command to.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createPipeline(program: Command): void;
|
|
12
|
+
//# sourceMappingURL=create-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-pipeline.d.ts","sourceRoot":"","sources":["../../src/commands/create-pipeline.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuUrD"}
|