@pipeline-builder/pipeline-manager 3.1.0

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.
Files changed (110) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +74 -0
  3. package/cdk.json +91 -0
  4. package/config.yml +94 -0
  5. package/dist/boilerplate.d.ts +3 -0
  6. package/dist/boilerplate.d.ts.map +1 -0
  7. package/dist/boilerplate.js +58 -0
  8. package/dist/cdk.json +91 -0
  9. package/dist/cli.d.ts +62 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +372 -0
  12. package/dist/commands/bootstrap.d.ts +11 -0
  13. package/dist/commands/bootstrap.d.ts.map +1 -0
  14. package/dist/commands/bootstrap.js +159 -0
  15. package/dist/commands/create-pipeline.d.ts +12 -0
  16. package/dist/commands/create-pipeline.d.ts.map +1 -0
  17. package/dist/commands/create-pipeline.js +291 -0
  18. package/dist/commands/deploy.d.ts +15 -0
  19. package/dist/commands/deploy.d.ts.map +1 -0
  20. package/dist/commands/deploy.js +167 -0
  21. package/dist/commands/get-pipeline.d.ts +13 -0
  22. package/dist/commands/get-pipeline.d.ts.map +1 -0
  23. package/dist/commands/get-pipeline.js +97 -0
  24. package/dist/commands/get-plugin.d.ts +13 -0
  25. package/dist/commands/get-plugin.d.ts.map +1 -0
  26. package/dist/commands/get-plugin.js +98 -0
  27. package/dist/commands/list-pipelines.d.ts +20 -0
  28. package/dist/commands/list-pipelines.d.ts.map +1 -0
  29. package/dist/commands/list-pipelines.js +172 -0
  30. package/dist/commands/list-plugins.d.ts +20 -0
  31. package/dist/commands/list-plugins.d.ts.map +1 -0
  32. package/dist/commands/list-plugins.js +167 -0
  33. package/dist/commands/login.d.ts +21 -0
  34. package/dist/commands/login.d.ts.map +1 -0
  35. package/dist/commands/login.js +179 -0
  36. package/dist/commands/setup-events.d.ts +15 -0
  37. package/dist/commands/setup-events.d.ts.map +1 -0
  38. package/dist/commands/setup-events.js +177 -0
  39. package/dist/commands/status.d.ts +11 -0
  40. package/dist/commands/status.d.ts.map +1 -0
  41. package/dist/commands/status.js +89 -0
  42. package/dist/commands/store-token.d.ts +20 -0
  43. package/dist/commands/store-token.d.ts.map +1 -0
  44. package/dist/commands/store-token.js +233 -0
  45. package/dist/commands/synth.d.ts +21 -0
  46. package/dist/commands/synth.d.ts.map +1 -0
  47. package/dist/commands/synth.js +143 -0
  48. package/dist/commands/upload-plugin.d.ts +21 -0
  49. package/dist/commands/upload-plugin.d.ts.map +1 -0
  50. package/dist/commands/upload-plugin.js +311 -0
  51. package/dist/commands/version.d.ts +12 -0
  52. package/dist/commands/version.d.ts.map +1 -0
  53. package/dist/commands/version.js +223 -0
  54. package/dist/config/cli.constants.d.ts +101 -0
  55. package/dist/config/cli.constants.d.ts.map +1 -0
  56. package/dist/config/cli.constants.js +165 -0
  57. package/dist/config.yml +94 -0
  58. package/dist/templates/events-stack.json +141 -0
  59. package/dist/types/config.d.ts +44 -0
  60. package/dist/types/config.d.ts.map +1 -0
  61. package/dist/types/config.js +5 -0
  62. package/dist/types/error.d.ts +61 -0
  63. package/dist/types/error.d.ts.map +1 -0
  64. package/dist/types/error.js +39 -0
  65. package/dist/types/index.d.ts +8 -0
  66. package/dist/types/index.d.ts.map +1 -0
  67. package/dist/types/index.js +26 -0
  68. package/dist/types/pipeline.d.ts +144 -0
  69. package/dist/types/pipeline.d.ts.map +1 -0
  70. package/dist/types/pipeline.js +5 -0
  71. package/dist/types/plugin.d.ts +160 -0
  72. package/dist/types/plugin.d.ts.map +1 -0
  73. package/dist/types/plugin.js +5 -0
  74. package/dist/utils/api-client.d.ts +26 -0
  75. package/dist/utils/api-client.d.ts.map +1 -0
  76. package/dist/utils/api-client.js +160 -0
  77. package/dist/utils/audit-log.d.ts +8 -0
  78. package/dist/utils/audit-log.d.ts.map +1 -0
  79. package/dist/utils/audit-log.js +53 -0
  80. package/dist/utils/auth-guard.d.ts +16 -0
  81. package/dist/utils/auth-guard.d.ts.map +1 -0
  82. package/dist/utils/auth-guard.js +25 -0
  83. package/dist/utils/aws-secrets.d.ts +21 -0
  84. package/dist/utils/aws-secrets.d.ts.map +1 -0
  85. package/dist/utils/aws-secrets.js +74 -0
  86. package/dist/utils/banner.d.ts +19 -0
  87. package/dist/utils/banner.d.ts.map +1 -0
  88. package/dist/utils/banner.js +59 -0
  89. package/dist/utils/cdk-utils.d.ts +51 -0
  90. package/dist/utils/cdk-utils.d.ts.map +1 -0
  91. package/dist/utils/cdk-utils.js +101 -0
  92. package/dist/utils/command-utils.d.ts +56 -0
  93. package/dist/utils/command-utils.d.ts.map +1 -0
  94. package/dist/utils/command-utils.js +138 -0
  95. package/dist/utils/config-loader.d.ts +27 -0
  96. package/dist/utils/config-loader.d.ts.map +1 -0
  97. package/dist/utils/config-loader.js +166 -0
  98. package/dist/utils/error-handler.d.ts +29 -0
  99. package/dist/utils/error-handler.d.ts.map +1 -0
  100. package/dist/utils/error-handler.js +255 -0
  101. package/dist/utils/list-command-utils.d.ts +23 -0
  102. package/dist/utils/list-command-utils.d.ts.map +1 -0
  103. package/dist/utils/list-command-utils.js +60 -0
  104. package/dist/utils/output-utils.d.ts +60 -0
  105. package/dist/utils/output-utils.d.ts.map +1 -0
  106. package/dist/utils/output-utils.js +320 -0
  107. package/dist/utils/rate-limiter.d.ts +14 -0
  108. package/dist/utils/rate-limiter.d.ts.map +1 -0
  109. package/dist/utils/rate-limiter.js +73 -0
  110. package/package.json +144 -0
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.login = login;
9
+ const https_1 = __importDefault(require("https"));
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const picocolors_1 = __importDefault(require("picocolors"));
12
+ const cli_constants_1 = require("../config/cli.constants");
13
+ const error_handler_1 = require("../utils/error-handler");
14
+ const output_utils_1 = require("../utils/output-utils");
15
+ const rate_limiter_1 = require("../utils/rate-limiter");
16
+ const { bold, cyan, green, magenta } = picocolors_1.default;
17
+ /**
18
+ * Registers the `login` command with the CLI program.
19
+ *
20
+ * Authenticates against the platform API and prints an export statement
21
+ * for `PLATFORM_TOKEN` on success. Does NOT require `PLATFORM_TOKEN`
22
+ * to be set beforehand (unlike other commands).
23
+ *
24
+ * @param program - The root Commander program instance to attach the command to.
25
+ *
26
+ * @example
27
+ * ```bash
28
+ * pipeline-manager login --identifier admin@example.com --password secret
29
+ * pipeline-manager login -u admin@example.com -p secret
30
+ * pipeline-manager login -u admin@example.com -p secret --url https://myhost:8443
31
+ * eval $(pipeline-manager login -u admin@example.com -p secret --quiet)
32
+ * pipeline-manager login --refresh <refresh-token>
33
+ * ```
34
+ */
35
+ function login(program) {
36
+ program
37
+ .command('login')
38
+ .description('Authenticate with the platform and obtain a PLATFORM_TOKEN')
39
+ .option('-u, --identifier <identifier>', 'Username or email')
40
+ .option('-p, --password <password>', 'Password')
41
+ .option('--refresh <refreshToken>', 'Use a refresh token instead of login credentials')
42
+ .option('--org <orgId>', 'Switch to a specific organization after login')
43
+ .option('--url <url>', 'Platform base URL', process.env.PLATFORM_BASE_URL || 'https://localhost:8443')
44
+ .option('--verify-ssl', 'Enable SSL certificate verification')
45
+ .option('--no-verify-ssl', 'Disable SSL certificate verification')
46
+ .option('--quiet', 'Only print the export statement (useful for eval)')
47
+ .action(async (options) => {
48
+ const executionId = (0, cli_constants_1.generateExecutionId)();
49
+ const isRefresh = !!options.refresh;
50
+ try {
51
+ // Validate required options
52
+ if (!isRefresh && (!options.identifier || !options.password)) {
53
+ (0, output_utils_1.printError)('Login requires --identifier and --password, or --refresh <token>');
54
+ process.exit(error_handler_1.ERROR_CODES.AUTHENTICATION);
55
+ }
56
+ // Rate limiting — prevent brute force (login only)
57
+ if (!isRefresh) {
58
+ const rateLimitMsg = (0, rate_limiter_1.checkAuthRateLimit)();
59
+ if (rateLimitMsg) {
60
+ (0, output_utils_1.printError)(rateLimitMsg);
61
+ process.exit(error_handler_1.ERROR_CODES.AUTHENTICATION);
62
+ }
63
+ }
64
+ const quiet = options.quiet ?? false;
65
+ if (!quiet) {
66
+ (0, output_utils_1.printSection)(isRefresh ? 'Token Refresh' : 'Login');
67
+ console.log(`${magenta(`[EXE-${executionId}]`)} ${cyan(bold(isRefresh ? 'Token Refresh' : 'Platform Authentication'))}`);
68
+ console.log('');
69
+ (0, output_utils_1.printInfo)(isRefresh ? 'Refreshing access token' : 'Authenticating', {
70
+ ...(options.identifier ? { identifier: options.identifier } : {}),
71
+ url: options.url,
72
+ verifySsl: options.verifySsl,
73
+ });
74
+ }
75
+ const httpsAgent = new https_1.default.Agent({
76
+ rejectUnauthorized: options.verifySsl ?? true,
77
+ });
78
+ let token;
79
+ if (isRefresh) {
80
+ const refreshUrl = `${options.url}/api/auth/refresh`;
81
+ (0, output_utils_1.printDebug)('POST', { url: refreshUrl });
82
+ const response = await axios_1.default.post(refreshUrl, { refreshToken: options.refresh }, {
83
+ headers: { 'Content-Type': 'application/json' },
84
+ httpsAgent,
85
+ timeout: cli_constants_1.TIMEOUTS.HTTP_REQUEST,
86
+ });
87
+ token = response.data?.data?.accessToken;
88
+ }
89
+ else {
90
+ const loginUrl = `${options.url}/api/auth/login`;
91
+ (0, output_utils_1.printDebug)('POST', { url: loginUrl });
92
+ const response = await axios_1.default.post(loginUrl, {
93
+ identifier: options.identifier,
94
+ password: options.password,
95
+ }, {
96
+ headers: { 'Content-Type': 'application/json' },
97
+ httpsAgent,
98
+ timeout: cli_constants_1.TIMEOUTS.HTTP_REQUEST,
99
+ });
100
+ token = response.data?.data?.accessToken;
101
+ }
102
+ if (!token) {
103
+ if (!isRefresh)
104
+ (0, rate_limiter_1.recordAuthFailure)();
105
+ (0, output_utils_1.printError)(`${isRefresh ? 'Token refresh' : 'Login'} failed: no access token in response`);
106
+ process.exit(error_handler_1.ERROR_CODES.AUTHENTICATION);
107
+ }
108
+ if (!isRefresh)
109
+ (0, rate_limiter_1.recordAuthSuccess)();
110
+ // Switch to a specific organization if --org is provided
111
+ if (options.org) {
112
+ if (!quiet) {
113
+ (0, output_utils_1.printInfo)('Switching to organization', { orgId: options.org });
114
+ }
115
+ const switchUrl = `${options.url}/api/auth/switch-org`;
116
+ (0, output_utils_1.printDebug)('POST', { url: switchUrl });
117
+ const switchResponse = await axios_1.default.post(switchUrl, { organizationId: options.org }, {
118
+ headers: {
119
+ 'Content-Type': 'application/json',
120
+ 'Authorization': `Bearer ${token}`,
121
+ },
122
+ httpsAgent,
123
+ timeout: cli_constants_1.TIMEOUTS.HTTP_REQUEST,
124
+ });
125
+ const switchedToken = switchResponse.data?.data?.accessToken;
126
+ if (!switchedToken) {
127
+ (0, output_utils_1.printError)('Organization switch failed: no access token in response');
128
+ process.exit(error_handler_1.ERROR_CODES.AUTHENTICATION);
129
+ }
130
+ token = switchedToken;
131
+ if (!quiet) {
132
+ (0, output_utils_1.printSuccess)(`Switched to organization ${options.org}`);
133
+ }
134
+ }
135
+ if (!quiet) {
136
+ console.log('');
137
+ (0, output_utils_1.printSuccess)(isRefresh ? 'Token refreshed successfully' : 'Login successful');
138
+ console.log('');
139
+ }
140
+ console.log(`export PLATFORM_TOKEN=${token}`);
141
+ if (!quiet) {
142
+ console.log('');
143
+ (0, output_utils_1.printInfo)('Tip: Run the following to set the token in your shell:');
144
+ const orgFlag = options.org ? ` --org ${options.org}` : '';
145
+ if (isRefresh) {
146
+ console.log(green(` eval $(pipeline-manager login --refresh '<refresh-token>'${orgFlag} --quiet)`));
147
+ }
148
+ else {
149
+ console.log(green(` eval $(pipeline-manager login -u ${options.identifier} -p '***'${orgFlag} --quiet)`));
150
+ }
151
+ }
152
+ }
153
+ catch (error) {
154
+ if (!isRefresh)
155
+ (0, rate_limiter_1.recordAuthFailure)();
156
+ // Provide a clear failure message for auth errors
157
+ if (axios_1.default.isAxiosError(error)) {
158
+ const status = error.response?.status;
159
+ const message = error.response?.data?.message;
160
+ (0, output_utils_1.printError)(`${isRefresh ? 'Token refresh' : 'Login'} failed`, {
161
+ status: status ?? 'no response',
162
+ ...(message ? { message } : {}),
163
+ });
164
+ process.exit(error_handler_1.ERROR_CODES.AUTHENTICATION);
165
+ }
166
+ (0, error_handler_1.handleError)(error, error_handler_1.ERROR_CODES.AUTHENTICATION, {
167
+ debug: program.opts().debug,
168
+ exit: true,
169
+ context: {
170
+ command: 'login',
171
+ executionId,
172
+ identifier: options.identifier,
173
+ url: options.url,
174
+ },
175
+ });
176
+ }
177
+ });
178
+ }
179
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9naW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29tbWFuZHMvbG9naW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7Ozs7O0FBMEN0QyxzQkE4S0M7QUF0TkQsa0RBQTBCO0FBQzFCLGtEQUEwQjtBQUUxQiw0REFBOEI7QUFDOUIsMkRBQXdFO0FBQ3hFLDBEQUFrRTtBQUNsRSx3REFBc0c7QUFDdEcsd0RBQWlHO0FBRWpHLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsR0FBRyxvQkFBSSxDQUFDO0FBYTVDOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILFNBQWdCLEtBQUssQ0FBQyxPQUFnQjtJQUNwQyxPQUFPO1NBQ0osT0FBTyxDQUFDLE9BQU8sQ0FBQztTQUNoQixXQUFXLENBQUMsNERBQTRELENBQUM7U0FDekUsTUFBTSxDQUFDLCtCQUErQixFQUFFLG1CQUFtQixDQUFDO1NBQzVELE1BQU0sQ0FBQywyQkFBMkIsRUFBRSxVQUFVLENBQUM7U0FDL0MsTUFBTSxDQUFDLDBCQUEwQixFQUFFLGtEQUFrRCxDQUFDO1NBQ3RGLE1BQU0sQ0FBQyxlQUFlLEVBQUUsK0NBQStDLENBQUM7U0FDeEUsTUFBTSxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLHdCQUF3QixDQUFDO1NBQ3JHLE1BQU0sQ0FBQyxjQUFjLEVBQUUscUNBQXFDLENBQUM7U0FDN0QsTUFBTSxDQUFDLGlCQUFpQixFQUFFLHNDQUFzQyxDQUFDO1NBQ2pFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsbURBQW1ELENBQUM7U0FDdEUsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUN4QixNQUFNLFdBQVcsR0FBRyxJQUFBLG1DQUFtQixHQUFFLENBQUM7UUFDMUMsTUFBTSxTQUFTLEdBQUcsQ0FB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RSwyQkFBVyxDQUFDLGNBQWMsRUFBRTtnQkFDN0MsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLO2dCQUMzQixJQUFJLEVBQUUsSUFBSTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsT0FBTyxFQUFFLE9BQU87b0JBQ2hCLFdBQVc7b0JBQ1gsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO29CQUM5QixHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUc7aUJBQ2pCO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgaHR0cHMgZnJvbSAnaHR0cHMnO1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHBpY28gZnJvbSAncGljb2NvbG9ycyc7XG5pbXBvcnQgeyBnZW5lcmF0ZUV4ZWN1dGlvbklkLCBUSU1FT1VUUyB9IGZyb20gJy4uL2NvbmZpZy9jbGkuY29uc3RhbnRzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciB9IGZyb20gJy4uL3V0aWxzL2Vycm9yLWhhbmRsZXInO1xuaW1wb3J0IHsgcHJpbnREZWJ1ZywgcHJpbnRFcnJvciwgcHJpbnRJbmZvLCBwcmludFNlY3Rpb24sIHByaW50U3VjY2VzcyB9IGZyb20gJy4uL3V0aWxzL291dHB1dC11dGlscyc7XG5pbXBvcnQgeyBjaGVja0F1dGhSYXRlTGltaXQsIHJlY29yZEF1dGhGYWlsdXJlLCByZWNvcmRBdXRoU3VjY2VzcyB9IGZyb20gJy4uL3V0aWxzL3JhdGUtbGltaXRlcic7XG5cbmNvbnN0IHsgYm9sZCwgY3lhbiwgZ3JlZW4sIG1hZ2VudGEgfSA9IHBpY287XG5cbi8qKlxuICogRXhwZWN0ZWQgc2hhcGUgb2YgdGhlIGxvZ2luL3JlZnJlc2ggQVBJIHJlc3BvbnNlLlxuICovXG5pbnRlcmZhY2UgTG9naW5SZXNwb25zZSB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIGRhdGE6IHtcbiAgICBhY2Nlc3NUb2tlbjogc3RyaW5nO1xuICAgIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xuICB9O1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyB0aGUgYGxvZ2luYCBjb21tYW5kIHdpdGggdGhlIENMSSBwcm9ncmFtLlxuICpcbiAqIEF1dGhlbnRpY2F0ZXMgYWdhaW5zdCB0aGUgcGxhdGZvcm0gQVBJIGFuZCBwcmludHMgYW4gZXhwb3J0IHN0YXRlbWVudFxuICogZm9yIGBQTEFURk9STV9UT0tFTmAgb24gc3VjY2Vzcy4gIERvZXMgTk9UIHJlcXVpcmUgYFBMQVRGT1JNX1RPS0VOYFxuICogdG8gYmUgc2V0IGJlZm9yZWhhbmQgKHVubGlrZSBvdGhlciBjb21tYW5kcykuXG4gKlxuICogQHBhcmFtIHByb2dyYW0gLSBUaGUgcm9vdCBDb21tYW5kZXIgcHJvZ3JhbSBpbnN0YW5jZSB0byBhdHRhY2ggdGhlIGNvbW1hbmQgdG8uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGJhc2hcbiAqIHBpcGVsaW5lLW1hbmFnZXIgbG9naW4gLS1pZGVudGlmaWVyIGFkbWluQGV4YW1wbGUuY29tIC0tcGFzc3dvcmQgc2VjcmV0XG4gKiBwaXBlbGluZS1tYW5hZ2VyIGxvZ2luIC11IGFkbWluQGV4YW1wbGUuY29tIC1wIHNlY3JldFxuICogcGlwZWxpbmUtbWFuYWdlciBsb2dpbiAtdSBhZG1pbkBleGFtcGxlLmNvbSAtcCBzZWNyZXQgLS11cmwgaHR0cHM6Ly9teWhvc3Q6ODQ0M1xuICogZXZhbCAkKHBpcGVsaW5lLW1hbmFnZXIgbG9naW4gLXUgYWRtaW5AZXhhbXBsZS5jb20gLXAgc2VjcmV0IC0tcXVpZXQpXG4gKiBwaXBlbGluZS1tYW5hZ2VyIGxvZ2luIC0tcmVmcmVzaCA8cmVmcmVzaC10b2tlbj5cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9naW4ocHJvZ3JhbTogQ29tbWFuZCk6IHZvaWQge1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ2xvZ2luJylcbiAgICAuZGVzY3JpcHRpb24oJ0F1dGhlbnRpY2F0ZSB3aXRoIHRoZSBwbGF0Zm9ybSBhbmQgb2J0YWluIGEgUExBVEZPUk1fVE9LRU4nKVxuICAgIC5vcHRpb24oJy11LCAtLWlkZW50aWZpZXIgPGlkZW50aWZpZXI+JywgJ1VzZXJuYW1lIG9yIGVtYWlsJylcbiAgICAub3B0aW9uKCctcCwgLS1wYXNzd29yZCA8cGFzc3dvcmQ+JywgJ1Bhc3N3b3JkJylcbiAgICAub3B0aW9uKCctLXJlZnJlc2ggPHJlZnJlc2hUb2tlbj4nLCAnVXNlIGEgcmVmcmVzaCB0b2tlbiBpbnN0ZWFkIG9mIGxvZ2luIGNyZWRlbnRpYWxzJylcbiAgICAub3B0aW9uKCctLW9yZyA8b3JnSWQ+JywgJ1N3aXRjaCB0byBhIHNwZWNpZmljIG9yZ2FuaXphdGlvbiBhZnRlciBsb2dpbicpXG4gICAgLm9wdGlvbignLS11cmwgPHVybD4nLCAnUGxhdGZvcm0gYmFzZSBVUkwnLCBwcm9jZXNzLmVudi5QTEFURk9STV9CQVNFX1VSTCB8fCAnaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0MycpXG4gICAgLm9wdGlvbignLS12ZXJpZnktc3NsJywgJ0VuYWJsZSBTU0wgY2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uJylcbiAgICAub3B0aW9uKCctLW5vLXZlcmlmeS1zc2wnLCAnRGlzYWJsZSBTU0wgY2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uJylcbiAgICAub3B0aW9uKCctLXF1aWV0JywgJ09ubHkgcHJpbnQgdGhlIGV4cG9ydCBzdGF0ZW1lbnQgKHVzZWZ1bCBmb3IgZXZhbCknKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgIGNvbnN0IGV4ZWN1dGlvbklkID0gZ2VuZXJhdGVFeGVjdXRpb25JZCgpO1xuICAgICAgY29uc3QgaXNSZWZyZXNoID0gISFvcHRpb25zLnJlZnJlc2g7XG5cbiAgICAgIHRyeSB7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgcmVxdWlyZWQgb3B0aW9uc1xuICAgICAgICBpZiAoIWlzUmVmcmVzaCAmJiAoIW9wdGlvbnMuaWRlbnRpZmllciB8fCAhb3B0aW9ucy5wYXNzd29yZCkpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdMb2dpbiByZXF1aXJlcyAtLWlkZW50aWZpZXIgYW5kIC0tcGFzc3dvcmQsIG9yIC0tcmVmcmVzaCA8dG9rZW4+Jyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KEVSUk9SX0NPREVTLkFVVEhFTlRJQ0FUSU9OKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJhdGUgbGltaXRpbmcg4oCUIHByZXZlbnQgYnJ1dGUgZm9yY2UgKGxvZ2luIG9ubHkpXG4gICAgICAgIGlmICghaXNSZWZyZXNoKSB7XG4gICAgICAgICAgY29uc3QgcmF0ZUxpbWl0TXNnID0gY2hlY2tBdXRoUmF0ZUxpbWl0KCk7XG4gICAgICAgICAgaWYgKHJhdGVMaW1pdE1zZykge1xuICAgICAgICAgICAgcHJpbnRFcnJvcihyYXRlTGltaXRNc2cpO1xuICAgICAgICAgICAgcHJvY2Vzcy5leGl0KEVSUk9SX0NPREVTLkFVVEhFTlRJQ0FUSU9OKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBxdWlldCA9IG9wdGlvbnMucXVpZXQgPz8gZmFsc2U7XG5cbiAgICAgICAgaWYgKCFxdWlldCkge1xuICAgICAgICAgIHByaW50U2VjdGlvbihpc1JlZnJlc2ggPyAnVG9rZW4gUmVmcmVzaCcgOiAnTG9naW4nKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgJHttYWdlbnRhKGBbRVhFLSR7ZXhlY3V0aW9uSWR9XWApfSAke2N5YW4oYm9sZChpc1JlZnJlc2ggPyAnVG9rZW4gUmVmcmVzaCcgOiAnUGxhdGZvcm0gQXV0aGVudGljYXRpb24nKSl9YCk7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50SW5mbyhpc1JlZnJlc2ggPyAnUmVmcmVzaGluZyBhY2Nlc3MgdG9rZW4nIDogJ0F1dGhlbnRpY2F0aW5nJywge1xuICAgICAgICAgICAgLi4uKG9wdGlvbnMuaWRlbnRpZmllciA/IHsgaWRlbnRpZmllcjogb3B0aW9ucy5pZGVudGlmaWVyIH0gOiB7fSksXG4gICAgICAgICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgICAgICAgdmVyaWZ5U3NsOiBvcHRpb25zLnZlcmlmeVNzbCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGh0dHBzQWdlbnQgPSBuZXcgaHR0cHMuQWdlbnQoe1xuICAgICAgICAgIHJlamVjdFVuYXV0aG9yaXplZDogb3B0aW9ucy52ZXJpZnlTc2wgPz8gdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IHRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKGlzUmVmcmVzaCkge1xuICAgICAgICAgIGNvbnN0IHJlZnJlc2hVcmwgPSBgJHtvcHRpb25zLnVybH0vYXBpL2F1dGgvcmVmcmVzaGA7XG4gICAgICAgICAgcHJpbnREZWJ1ZygnUE9TVCcsIHsgdXJsOiByZWZyZXNoVXJsIH0pO1xuXG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBheGlvcy5wb3N0PExvZ2luUmVzcG9uc2U+KFxuICAgICAgICAgICAgcmVmcmVzaFVybCxcbiAgICAgICAgICAgIHsgcmVmcmVzaFRva2VuOiBvcHRpb25zLnJlZnJlc2ggfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgICAgICAgIGh0dHBzQWdlbnQsXG4gICAgICAgICAgICAgIHRpbWVvdXQ6IFRJTUVPVVRTLkhUVFBfUkVRVUVTVCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHRva2VuID0gcmVzcG9uc2UuZGF0YT8uZGF0YT8uYWNjZXNzVG9rZW47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbG9naW5VcmwgPSBgJHtvcHRpb25zLnVybH0vYXBpL2F1dGgvbG9naW5gO1xuICAgICAgICAgIHByaW50RGVidWcoJ1BPU1QnLCB7IHVybDogbG9naW5VcmwgfSk7XG5cbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF4aW9zLnBvc3Q8TG9naW5SZXNwb25zZT4oXG4gICAgICAgICAgICBsb2dpblVybCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWRlbnRpZmllcjogb3B0aW9ucy5pZGVudGlmaWVyLFxuICAgICAgICAgICAgICBwYXNzd29yZDogb3B0aW9ucy5wYXNzd29yZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICAgICAgICBodHRwc0FnZW50LFxuICAgICAgICAgICAgICB0aW1lb3V0OiBUSU1FT1VUUy5IVFRQX1JFUVVFU1QsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0b2tlbiA9IHJlc3BvbnNlLmRhdGE/LmRhdGE/LmFjY2Vzc1Rva2VuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0b2tlbikge1xuICAgICAgICAgIGlmICghaXNSZWZyZXNoKSByZWNvcmRBdXRoRmFpbHVyZSgpO1xuICAgICAgICAgIHByaW50RXJyb3IoYCR7aXNSZWZyZXNoID8gJ1Rva2VuIHJlZnJlc2gnIDogJ0xvZ2luJ30gZmFpbGVkOiBubyBhY2Nlc3MgdG9rZW4gaW4gcmVzcG9uc2VgKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoRVJST1JfQ09ERVMuQVVUSEVOVElDQVRJT04pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFpc1JlZnJlc2gpIHJlY29yZEF1dGhTdWNjZXNzKCk7XG5cbiAgICAgICAgLy8gU3dpdGNoIHRvIGEgc3BlY2lmaWMgb3JnYW5pemF0aW9uIGlmIC0tb3JnIGlzIHByb3ZpZGVkXG4gICAgICAgIGlmIChvcHRpb25zLm9yZykge1xuICAgICAgICAgIGlmICghcXVpZXQpIHtcbiAgICAgICAgICAgIHByaW50SW5mbygnU3dpdGNoaW5nIHRvIG9yZ2FuaXphdGlvbicsIHsgb3JnSWQ6IG9wdGlvbnMub3JnIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHN3aXRjaFVybCA9IGAke29wdGlvbnMudXJsfS9hcGkvYXV0aC9zd2l0Y2gtb3JnYDtcbiAgICAgICAgICBwcmludERlYnVnKCdQT1NUJywgeyB1cmw6IHN3aXRjaFVybCB9KTtcblxuICAgICAgICAgIGNvbnN0IHN3aXRjaFJlc3BvbnNlID0gYXdhaXQgYXhpb3MucG9zdDxMb2dpblJlc3BvbnNlPihcbiAgICAgICAgICAgIHN3aXRjaFVybCxcbiAgICAgICAgICAgIHsgb3JnYW5pemF0aW9uSWQ6IG9wdGlvbnMub3JnIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgICAgICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke3Rva2VufWAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGh0dHBzQWdlbnQsXG4gICAgICAgICAgICAgIHRpbWVvdXQ6IFRJTUVPVVRTLkhUVFBfUkVRVUVTVCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHN3aXRjaGVkVG9rZW4gPSBzd2l0Y2hSZXNwb25zZS5kYXRhPy5kYXRhPy5hY2Nlc3NUb2tlbjtcbiAgICAgICAgICBpZiAoIXN3aXRjaGVkVG9rZW4pIHtcbiAgICAgICAgICAgIHByaW50RXJyb3IoJ09yZ2FuaXphdGlvbiBzd2l0Y2ggZmFpbGVkOiBubyBhY2Nlc3MgdG9rZW4gaW4gcmVzcG9uc2UnKTtcbiAgICAgICAgICAgIHByb2Nlc3MuZXhpdChFUlJPUl9DT0RFUy5BVVRIRU5USUNBVElPTik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdG9rZW4gPSBzd2l0Y2hlZFRva2VuO1xuXG4gICAgICAgICAgaWYgKCFxdWlldCkge1xuICAgICAgICAgICAgcHJpbnRTdWNjZXNzKGBTd2l0Y2hlZCB0byBvcmdhbml6YXRpb24gJHtvcHRpb25zLm9yZ31gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXF1aWV0KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50U3VjY2Vzcyhpc1JlZnJlc2ggPyAnVG9rZW4gcmVmcmVzaGVkIHN1Y2Nlc3NmdWxseScgOiAnTG9naW4gc3VjY2Vzc2Z1bCcpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGBleHBvcnQgUExBVEZPUk1fVE9LRU49JHt0b2tlbn1gKTtcblxuICAgICAgICBpZiAoIXF1aWV0KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgIHByaW50SW5mbygnVGlwOiBSdW4gdGhlIGZvbGxvd2luZyB0byBzZXQgdGhlIHRva2VuIGluIHlvdXIgc2hlbGw6Jyk7XG4gICAgICAgICAgY29uc3Qgb3JnRmxhZyA9IG9wdGlvbnMub3JnID8gYCAtLW9yZyAke29wdGlvbnMub3JnfWAgOiAnJztcbiAgICAgICAgICBpZiAoaXNSZWZyZXNoKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhncmVlbihgICBldmFsICQocGlwZWxpbmUtbWFuYWdlciBsb2dpbiAtLXJlZnJlc2ggJzxyZWZyZXNoLXRva2VuPicke29yZ0ZsYWd9IC0tcXVpZXQpYCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhncmVlbihgICBldmFsICQocGlwZWxpbmUtbWFuYWdlciBsb2dpbiAtdSAke29wdGlvbnMuaWRlbnRpZmllcn0gLXAgJyoqKicke29yZ0ZsYWd9IC0tcXVpZXQpYCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKCFpc1JlZnJlc2gpIHJlY29yZEF1dGhGYWlsdXJlKCk7XG4gICAgICAgIC8vIFByb3ZpZGUgYSBjbGVhciBmYWlsdXJlIG1lc3NhZ2UgZm9yIGF1dGggZXJyb3JzXG4gICAgICAgIGlmIChheGlvcy5pc0F4aW9zRXJyb3IoZXJyb3IpKSB7XG4gICAgICAgICAgY29uc3Qgc3RhdHVzID0gZXJyb3IucmVzcG9uc2U/LnN0YXR1cztcbiAgICAgICAgICBjb25zdCBtZXNzYWdlID0gKGVycm9yLnJlc3BvbnNlPy5kYXRhIGFzIHsgbWVzc2FnZT86IHN0cmluZyB9KT8ubWVzc2FnZTtcblxuICAgICAgICAgIHByaW50RXJyb3IoYCR7aXNSZWZyZXNoID8gJ1Rva2VuIHJlZnJlc2gnIDogJ0xvZ2luJ30gZmFpbGVkYCwge1xuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMgPz8gJ25vIHJlc3BvbnNlJyxcbiAgICAgICAgICAgIC4uLihtZXNzYWdlID8geyBtZXNzYWdlIH0gOiB7fSksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KEVSUk9SX0NPREVTLkFVVEhFTlRJQ0FUSU9OKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhhbmRsZUVycm9yKGVycm9yLCBFUlJPUl9DT0RFUy5BVVRIRU5USUNBVElPTiwge1xuICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICBleGl0OiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgIGNvbW1hbmQ6ICdsb2dpbicsXG4gICAgICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgICAgIGlkZW50aWZpZXI6IG9wdGlvbnMuaWRlbnRpZmllcixcbiAgICAgICAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG59XG4iXX0=
@@ -0,0 +1,15 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Registers the `setup-events` command with the CLI program.
4
+ *
5
+ * Deploys EventBridge → SQS → Lambda infrastructure for pipeline reporting.
6
+ *
7
+ * 1. Deploys CloudFormation stack (rule + queue + Lambda shell + IAM)
8
+ * 2. Downloads @pipeline-builder/event-bridge from npm registry
9
+ * 3. Uploads handler code directly to Lambda (no S3 needed)
10
+ *
11
+ * Uses PLATFORM_BASE_URL from environment (same as all other commands).
12
+ * Idempotent — running again updates the stack and code.
13
+ */
14
+ export declare function setupEvents(program: Command): void;
15
+ //# sourceMappingURL=setup-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-events.d.ts","sourceRoot":"","sources":["../../src/commands/setup-events.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmIlD"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || (function () {
21
+ var ownKeys = function(o) {
22
+ ownKeys = Object.getOwnPropertyNames || function (o) {
23
+ var ar = [];
24
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
+ return ar;
26
+ };
27
+ return ownKeys(o);
28
+ };
29
+ return function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ })();
37
+ var __importDefault = (this && this.__importDefault) || function (mod) {
38
+ return (mod && mod.__esModule) ? mod : { "default": mod };
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.setupEvents = setupEvents;
42
+ const child_process_1 = require("child_process");
43
+ const fs = __importStar(require("fs"));
44
+ const os = __importStar(require("os"));
45
+ const path_1 = __importDefault(require("path"));
46
+ const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
47
+ const client_lambda_1 = require("@aws-sdk/client-lambda");
48
+ const command_utils_1 = require("../utils/command-utils");
49
+ const error_handler_1 = require("../utils/error-handler");
50
+ const output_utils_1 = require("../utils/output-utils");
51
+ const STACK_NAME = 'pipeline-builder-events';
52
+ // Existing CFN-managed Lambda function name — do NOT rename without a migration plan
53
+ const LAMBDA_NAME = 'pipeline-builder-event-ingestion';
54
+ const PACKAGE_NAME = '@pipeline-builder/event-bridge';
55
+ /**
56
+ * Registers the `setup-events` command with the CLI program.
57
+ *
58
+ * Deploys EventBridge → SQS → Lambda infrastructure for pipeline reporting.
59
+ *
60
+ * 1. Deploys CloudFormation stack (rule + queue + Lambda shell + IAM)
61
+ * 2. Downloads @pipeline-builder/event-bridge from npm registry
62
+ * 3. Uploads handler code directly to Lambda (no S3 needed)
63
+ *
64
+ * Uses PLATFORM_BASE_URL from environment (same as all other commands).
65
+ * Idempotent — running again updates the stack and code.
66
+ */
67
+ function setupEvents(program) {
68
+ program
69
+ .command('setup-events')
70
+ .description('Deploy EventBridge event ingestion infrastructure for pipeline reporting')
71
+ .option('--package-version <version>', 'event-bridge package version (default: latest)')
72
+ .option('--secret-name <name>', 'Platform secret name (e.g. pipeline-builder/{orgId}/platform)')
73
+ .option('--region <region>', 'AWS region')
74
+ .option('--profile <profile>', 'AWS CLI profile', 'default')
75
+ .action(async (options) => {
76
+ const executionId = (0, command_utils_1.printCommandHeader)('Setup Event Ingestion');
77
+ try {
78
+ const region = options.region || process.env.AWS_REGION || process.env.CDK_DEFAULT_REGION;
79
+ if (!region) {
80
+ (0, output_utils_1.printError)('AWS region is required');
81
+ throw new Error('AWS region not provided');
82
+ }
83
+ const platformUrl = process.env.PLATFORM_BASE_URL;
84
+ if (!platformUrl) {
85
+ (0, output_utils_1.printError)('PLATFORM_BASE_URL environment variable is required');
86
+ throw new Error('PLATFORM_BASE_URL not set');
87
+ }
88
+ const secretName = options.secretName || process.env.PLATFORM_SECRET_NAME;
89
+ if (!secretName) {
90
+ (0, output_utils_1.printError)('--secret-name or PLATFORM_SECRET_NAME env var is required');
91
+ throw new Error('Platform secret name not provided');
92
+ }
93
+ (0, output_utils_1.printInfo)('Parameters', {
94
+ stack: STACK_NAME,
95
+ region,
96
+ platformUrl,
97
+ secretName,
98
+ packageVersion: options.packageVersion || 'latest',
99
+ });
100
+ // Step 1: Deploy CloudFormation (infra only — Lambda gets placeholder code)
101
+ (0, output_utils_1.printSection)('Deploy Infrastructure');
102
+ const templatePath = path_1.default.join(__dirname, '../templates/events-stack.json');
103
+ const cfnArgs = [
104
+ 'cloudformation', 'deploy',
105
+ '--stack-name', STACK_NAME,
106
+ '--template-file', templatePath,
107
+ '--parameter-overrides',
108
+ `PlatformBaseUrl=${platformUrl}`,
109
+ `PlatformSecretName=${secretName}`,
110
+ '--capabilities', 'CAPABILITY_NAMED_IAM',
111
+ '--no-fail-on-empty-changeset',
112
+ '--region', region,
113
+ ];
114
+ if (options.profile)
115
+ cfnArgs.push('--profile', options.profile);
116
+ (0, child_process_1.execFileSync)('aws', cfnArgs, { stdio: 'inherit' });
117
+ (0, output_utils_1.printSuccess)('Infrastructure deployed');
118
+ // Step 2: Download handler from registry and upload to Lambda
119
+ (0, output_utils_1.printSection)('Deploy Lambda Code');
120
+ const tmpDir = fs.mkdtempSync(path_1.default.join(os.tmpdir(), 'event-ingestion-'));
121
+ try {
122
+ const versionSpec = options.packageVersion ? `${PACKAGE_NAME}@${options.packageVersion}` : PACKAGE_NAME;
123
+ (0, output_utils_1.printInfo)('Installing from registry', { package: versionSpec });
124
+ (0, child_process_1.execFileSync)('npm', ['install', '--prefix', tmpDir, versionSpec], { stdio: 'pipe' });
125
+ const handlerSrc = path_1.default.join(tmpDir, 'node_modules', PACKAGE_NAME, 'lib', 'index.js');
126
+ if (!fs.existsSync(handlerSrc)) {
127
+ throw new Error(`Handler not found at ${handlerSrc}. Ensure the package is published.`);
128
+ }
129
+ // Get version from installed package
130
+ const pkgJsonPath = path_1.default.join(tmpDir, 'node_modules', PACKAGE_NAME, 'package.json');
131
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
132
+ const version = pkgJson.version || 'unknown';
133
+ // ZIP the handler
134
+ const zipPath = path_1.default.join(tmpDir, 'index.zip');
135
+ (0, child_process_1.execFileSync)('zip', ['-j', zipPath, 'index.js'], { cwd: path_1.default.dirname(handlerSrc), stdio: 'pipe' });
136
+ // Upload directly to Lambda via SDK (no S3 needed)
137
+ (0, output_utils_1.printInfo)('Uploading code to Lambda', { function: LAMBDA_NAME, version });
138
+ const lambdaClient = new client_lambda_1.LambdaClient({ region });
139
+ await lambdaClient.send(new client_lambda_1.UpdateFunctionCodeCommand({
140
+ FunctionName: LAMBDA_NAME,
141
+ ZipFile: fs.readFileSync(zipPath),
142
+ }));
143
+ (0, output_utils_1.printSuccess)(`Lambda code deployed (${PACKAGE_NAME}@${version})`);
144
+ }
145
+ finally {
146
+ fs.rmSync(tmpDir, { recursive: true, force: true });
147
+ }
148
+ // Step 3: Show outputs via SDK
149
+ const cfnClient = new client_cloudformation_1.CloudFormationClient({ region });
150
+ const describeResult = await cfnClient.send(new client_cloudformation_1.DescribeStacksCommand({ StackName: STACK_NAME }));
151
+ const outputs = describeResult.Stacks?.[0]?.Outputs ?? [];
152
+ const outputMap = Object.fromEntries(outputs.map(o => [o.OutputKey ?? '', o.OutputValue ?? '']));
153
+ console.log('');
154
+ (0, output_utils_1.printSection)('Event Ingestion Ready');
155
+ (0, output_utils_1.printKeyValue)({
156
+ 'Stack': STACK_NAME,
157
+ 'Region': region,
158
+ 'Platform URL': platformUrl,
159
+ 'Lambda': outputMap.LambdaFunctionArn || LAMBDA_NAME,
160
+ 'Event Queue': outputMap.EventQueueUrl || '(see AWS console)',
161
+ 'Dead Letter Queue': outputMap.DeadLetterQueueUrl || '(see AWS console)',
162
+ 'EventBridge Rule': outputMap.EventRuleName || '(see AWS console)',
163
+ 'Status': '✓ Deployed',
164
+ });
165
+ console.log('');
166
+ (0, output_utils_1.printSuccess)('EventBridge event ingestion is active.');
167
+ }
168
+ catch (error) {
169
+ (0, error_handler_1.handleError)(error, error_handler_1.ERROR_CODES.API_REQUEST, {
170
+ debug: program.opts().debug,
171
+ exit: true,
172
+ context: { command: 'setup-events', executionId, stack: STACK_NAME },
173
+ });
174
+ }
175
+ });
176
+ }
177
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2V0dXAtZXZlbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL3NldHVwLWV2ZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE4QnRDLGtDQW1JQztBQS9KRCxpREFBNkM7QUFDN0MsdUNBQXlCO0FBQ3pCLHVDQUF5QjtBQUN6QixnREFBd0I7QUFDeEIsMEVBQTZGO0FBQzdGLDBEQUFpRjtBQUVqRiwwREFBNEQ7QUFDNUQsMERBQWtFO0FBQ2xFLHdEQUF5RztBQUV6RyxNQUFNLFVBQVUsR0FBRyx5QkFBeUIsQ0FBQztBQUM3QyxxRkFBcUY7QUFDckYsTUFBTSxXQUFXLEdBQUcsa0NBQWtDLENBQUM7QUFDdkQsTUFBTSxZQUFZLEdBQUcsZ0NBQWdDLENBQUM7QUFFdEQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxTQUFnQixXQUFXLENBQUMsT0FBZ0I7SUFDMUMsT0FBTztTQUNKLE9BQU8sQ0FBQyxjQUFjLENBQUM7U0FDdkIsV0FBVyxDQUFDLDBFQUEwRSxDQUFDO1NBQ3ZGLE1BQU0sQ0FBQyw2QkFBNkIsRUFBRSxnREFBZ0QsQ0FBQztTQUN2RixNQUFNLENBQUMsc0JBQXNCLEVBQUUsK0RBQStELENBQUM7U0FDL0YsTUFBTSxDQUFDLG1CQUFtQixFQUFFLFlBQVksQ0FBQztTQUN6QyxNQUFNLENBQUMscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDO1NBQzNELE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDeEIsTUFBTSxXQUFXLEdBQUcsSUFBQSxrQ0FBa0IsRUFBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBRWhFLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksT0FBTyxD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RSxrQkFBa0IsRUFBRSxTQUFTLENBQUMsYUFBYSxJQUFJLG1CQUFtQjtnQkFDbEUsUUFBUSxFQUFFLFlBQVk7YUFDdkIsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoQixJQUFBLDJCQUFZLEVBQUMsd0NBQXdDLENBQUMsQ0FBQztRQUV6RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUEsMkJBQVcsRUFBQyxLQUFLLEVBQUUsMkJBQVcsQ0FBQyxXQUFXLEVBQUU7Z0JBQzFDLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSztnQkFDM0IsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRTthQUNyRSxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IGV4ZWNGaWxlU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBDbG91ZEZvcm1hdGlvbkNsaWVudCwgRGVzY3JpYmVTdGFja3NDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNsb3VkZm9ybWF0aW9uJztcbmltcG9ydCB7IExhbWJkYUNsaWVudCwgVXBkYXRlRnVuY3Rpb25Db2RlQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1sYW1iZGEnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciB9IGZyb20gJy4uL3V0aWxzL2Vycm9yLWhhbmRsZXInO1xuaW1wb3J0IHsgcHJpbnRFcnJvciwgcHJpbnRJbmZvLCBwcmludEtleVZhbHVlLCBwcmludFNlY3Rpb24sIHByaW50U3VjY2VzcyB9IGZyb20gJy4uL3V0aWxzL291dHB1dC11dGlscyc7XG5cbmNvbnN0IFNUQUNLX05BTUUgPSAncGlwZWxpbmUtYnVpbGRlci1ldmVudHMnO1xuLy8gRXhpc3RpbmcgQ0ZOLW1hbmFnZWQgTGFtYmRhIGZ1bmN0aW9uIG5hbWUg4oCUIGRvIE5PVCByZW5hbWUgd2l0aG91dCBhIG1pZ3JhdGlvbiBwbGFuXG5jb25zdCBMQU1CREFfTkFNRSA9ICdwaXBlbGluZS1idWlsZGVyLWV2ZW50LWluZ2VzdGlvbic7XG5jb25zdCBQQUNLQUdFX05BTUUgPSAnQHBpcGVsaW5lLWJ1aWxkZXIvZXZlbnQtYnJpZGdlJztcblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIGBzZXR1cC1ldmVudHNgIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogRGVwbG95cyBFdmVudEJyaWRnZSDihpIgU1FTIOKGkiBMYW1iZGEgaW5mcmFzdHJ1Y3R1cmUgZm9yIHBpcGVsaW5lIHJlcG9ydGluZy5cbiAqXG4gKiAxLiBEZXBsb3lzIENsb3VkRm9ybWF0aW9uIHN0YWNrIChydWxlICsgcXVldWUgKyBMYW1iZGEgc2hlbGwgKyBJQU0pXG4gKiAyLiBEb3dubG9hZHMgQHBpcGVsaW5lLWJ1aWxkZXIvZXZlbnQtYnJpZGdlIGZyb20gbnBtIHJlZ2lzdHJ5XG4gKiAzLiBVcGxvYWRzIGhhbmRsZXIgY29kZSBkaXJlY3RseSB0byBMYW1iZGEgKG5vIFMzIG5lZWRlZClcbiAqXG4gKiBVc2VzIFBMQVRGT1JNX0JBU0VfVVJMIGZyb20gZW52aXJvbm1lbnQgKHNhbWUgYXMgYWxsIG90aGVyIGNvbW1hbmRzKS5cbiAqIElkZW1wb3RlbnQg4oCUIHJ1bm5pbmcgYWdhaW4gdXBkYXRlcyB0aGUgc3RhY2sgYW5kIGNvZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXR1cEV2ZW50cyhwcm9ncmFtOiBDb21tYW5kKTogdm9pZCB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgnc2V0dXAtZXZlbnRzJylcbiAgICAuZGVzY3JpcHRpb24oJ0RlcGxveSBFdmVudEJyaWRnZSBldmVudCBpbmdlc3Rpb24gaW5mcmFzdHJ1Y3R1cmUgZm9yIHBpcGVsaW5lIHJlcG9ydGluZycpXG4gICAgLm9wdGlvbignLS1wYWNrYWdlLXZlcnNpb24gPHZlcnNpb24+JywgJ2V2ZW50LWJyaWRnZSBwYWNrYWdlIHZlcnNpb24gKGRlZmF1bHQ6IGxhdGVzdCknKVxuICAgIC5vcHRpb24oJy0tc2VjcmV0LW5hbWUgPG5hbWU+JywgJ1BsYXRmb3JtIHNlY3JldCBuYW1lIChlLmcuIHBpcGVsaW5lLWJ1aWxkZXIve29yZ0lkfS9wbGF0Zm9ybSknKVxuICAgIC5vcHRpb24oJy0tcmVnaW9uIDxyZWdpb24+JywgJ0FXUyByZWdpb24nKVxuICAgIC5vcHRpb24oJy0tcHJvZmlsZSA8cHJvZmlsZT4nLCAnQVdTIENMSSBwcm9maWxlJywgJ2RlZmF1bHQnKVxuICAgIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICAgIGNvbnN0IGV4ZWN1dGlvbklkID0gcHJpbnRDb21tYW5kSGVhZGVyKCdTZXR1cCBFdmVudCBJbmdlc3Rpb24nKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVnaW9uID0gb3B0aW9ucy5yZWdpb24gfHwgcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiB8fCBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT047XG4gICAgICAgIGlmICghcmVnaW9uKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignQVdTIHJlZ2lvbiBpcyByZXF1aXJlZCcpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQVdTIHJlZ2lvbiBub3QgcHJvdmlkZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBsYXRmb3JtVXJsID0gcHJvY2Vzcy5lbnYuUExBVEZPUk1fQkFTRV9VUkw7XG4gICAgICAgIGlmICghcGxhdGZvcm1VcmwpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdQTEFURk9STV9CQVNFX1VSTCBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyByZXF1aXJlZCcpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUExBVEZPUk1fQkFTRV9VUkwgbm90IHNldCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc2VjcmV0TmFtZSA9IG9wdGlvbnMuc2VjcmV0TmFtZSB8fCBwcm9jZXNzLmVudi5QTEFURk9STV9TRUNSRVRfTkFNRTtcbiAgICAgICAgaWYgKCFzZWNyZXROYW1lKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignLS1zZWNyZXQtbmFtZSBvciBQTEFURk9STV9TRUNSRVRfTkFNRSBlbnYgdmFyIGlzIHJlcXVpcmVkJyk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbGF0Zm9ybSBzZWNyZXQgbmFtZSBub3QgcHJvdmlkZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByaW50SW5mbygnUGFyYW1ldGVycycsIHtcbiAgICAgICAgICBzdGFjazogU1RBQ0tfTkFNRSxcbiAgICAgICAgICByZWdpb24sXG4gICAgICAgICAgcGxhdGZvcm1VcmwsXG4gICAgICAgICAgc2VjcmV0TmFtZSxcbiAgICAgICAgICBwYWNrYWdlVmVyc2lvbjogb3B0aW9ucy5wYWNrYWdlVmVyc2lvbiB8fCAnbGF0ZXN0JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3RlcCAxOiBEZXBsb3kgQ2xvdWRGb3JtYXRpb24gKGluZnJhIG9ubHkg4oCUIExhbWJkYSBnZXRzIHBsYWNlaG9sZGVyIGNvZGUpXG4gICAgICAgIHByaW50U2VjdGlvbignRGVwbG95IEluZnJhc3RydWN0dXJlJyk7XG5cbiAgICAgICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL3RlbXBsYXRlcy9ldmVudHMtc3RhY2suanNvbicpO1xuXG4gICAgICAgIGNvbnN0IGNmbkFyZ3MgPSBbXG4gICAgICAgICAgJ2Nsb3VkZm9ybWF0aW9uJywgJ2RlcGxveScsXG4gICAgICAgICAgJy0tc3RhY2stbmFtZScsIFNUQUNLX05BTUUsXG4gICAgICAgICAgJy0tdGVtcGxhdGUtZmlsZScsIHRlbXBsYXRlUGF0aCxcbiAgICAgICAgICAnLS1wYXJhbWV0ZXItb3ZlcnJpZGVzJyxcbiAgICAgICAgICBgUGxhdGZvcm1CYXNlVXJsPSR7cGxhdGZvcm1Vcmx9YCxcbiAgICAgICAgICBgUGxhdGZvcm1TZWNyZXROYW1lPSR7c2VjcmV0TmFtZX1gLFxuICAgICAgICAgICctLWNhcGFiaWxpdGllcycsICdDQVBBQklMSVRZX05BTUVEX0lBTScsXG4gICAgICAgICAgJy0tbm8tZmFpbC1vbi1lbXB0eS1jaGFuZ2VzZXQnLFxuICAgICAgICAgICctLXJlZ2lvbicsIHJlZ2lvbixcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKG9wdGlvbnMucHJvZmlsZSkgY2ZuQXJncy5wdXNoKCctLXByb2ZpbGUnLCBvcHRpb25zLnByb2ZpbGUpO1xuXG4gICAgICAgIGV4ZWNGaWxlU3luYygnYXdzJywgY2ZuQXJncywgeyBzdGRpbzogJ2luaGVyaXQnIH0pO1xuXG4gICAgICAgIHByaW50U3VjY2VzcygnSW5mcmFzdHJ1Y3R1cmUgZGVwbG95ZWQnKTtcblxuICAgICAgICAvLyBTdGVwIDI6IERvd25sb2FkIGhhbmRsZXIgZnJvbSByZWdpc3RyeSBhbmQgdXBsb2FkIHRvIExhbWJkYVxuICAgICAgICBwcmludFNlY3Rpb24oJ0RlcGxveSBMYW1iZGEgQ29kZScpO1xuXG4gICAgICAgIGNvbnN0IHRtcERpciA9IGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihvcy50bXBkaXIoKSwgJ2V2ZW50LWluZ2VzdGlvbi0nKSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB2ZXJzaW9uU3BlYyA9IG9wdGlvbnMucGFja2FnZVZlcnNpb24gPyBgJHtQQUNLQUdFX05BTUV9QCR7b3B0aW9ucy5wYWNrYWdlVmVyc2lvbn1gIDogUEFDS0FHRV9OQU1FO1xuICAgICAgICAgIHByaW50SW5mbygnSW5zdGFsbGluZyBmcm9tIHJlZ2lzdHJ5JywgeyBwYWNrYWdlOiB2ZXJzaW9uU3BlYyB9KTtcblxuICAgICAgICAgIGV4ZWNGaWxlU3luYygnbnBtJywgWydpbnN0YWxsJywgJy0tcHJlZml4JywgdG1wRGlyLCB2ZXJzaW9uU3BlY10sIHsgc3RkaW86ICdwaXBlJyB9KTtcblxuICAgICAgICAgIGNvbnN0IGhhbmRsZXJTcmMgPSBwYXRoLmpvaW4odG1wRGlyLCAnbm9kZV9tb2R1bGVzJywgUEFDS0FHRV9OQU1FLCAnbGliJywgJ2luZGV4LmpzJyk7XG4gICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGhhbmRsZXJTcmMpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhhbmRsZXIgbm90IGZvdW5kIGF0ICR7aGFuZGxlclNyY30uIEVuc3VyZSB0aGUgcGFja2FnZSBpcyBwdWJsaXNoZWQuYCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gR2V0IHZlcnNpb24gZnJvbSBpbnN0YWxsZWQgcGFja2FnZVxuICAgICAgICAgIGNvbnN0IHBrZ0pzb25QYXRoID0gcGF0aC5qb2luKHRtcERpciwgJ25vZGVfbW9kdWxlcycsIFBBQ0tBR0VfTkFNRSwgJ3BhY2thZ2UuanNvbicpO1xuICAgICAgICAgIGNvbnN0IHBrZ0pzb24gPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwa2dKc29uUGF0aCwgJ3V0Zi04JykpO1xuICAgICAgICAgIGNvbnN0IHZlcnNpb24gPSBwa2dKc29uLnZlcnNpb24gfHwgJ3Vua25vd24nO1xuXG4gICAgICAgICAgLy8gWklQIHRoZSBoYW5kbGVyXG4gICAgICAgICAgY29uc3QgemlwUGF0aCA9IHBhdGguam9pbih0bXBEaXIsICdpbmRleC56aXAnKTtcbiAgICAgICAgICBleGVjRmlsZVN5bmMoJ3ppcCcsIFsnLWonLCB6aXBQYXRoLCAnaW5kZXguanMnXSwgeyBjd2Q6IHBhdGguZGlybmFtZShoYW5kbGVyU3JjKSwgc3RkaW86ICdwaXBlJyB9KTtcblxuICAgICAgICAgIC8vIFVwbG9hZCBkaXJlY3RseSB0byBMYW1iZGEgdmlhIFNESyAobm8gUzMgbmVlZGVkKVxuICAgICAgICAgIHByaW50SW5mbygnVXBsb2FkaW5nIGNvZGUgdG8gTGFtYmRhJywgeyBmdW5jdGlvbjogTEFNQkRBX05BTUUsIHZlcnNpb24gfSk7XG5cbiAgICAgICAgICBjb25zdCBsYW1iZGFDbGllbnQgPSBuZXcgTGFtYmRhQ2xpZW50KHsgcmVnaW9uIH0pO1xuICAgICAgICAgIGF3YWl0IGxhbWJkYUNsaWVudC5zZW5kKG5ldyBVcGRhdGVGdW5jdGlvbkNvZGVDb21tYW5kKHtcbiAgICAgICAgICAgIEZ1bmN0aW9uTmFtZTogTEFNQkRBX05BTUUsXG4gICAgICAgICAgICBaaXBGaWxlOiBmcy5yZWFkRmlsZVN5bmMoemlwUGF0aCksXG4gICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgcHJpbnRTdWNjZXNzKGBMYW1iZGEgY29kZSBkZXBsb3llZCAoJHtQQUNLQUdFX05BTUV9QCR7dmVyc2lvbn0pYCk7XG5cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBmcy5ybVN5bmModG1wRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdGVwIDM6IFNob3cgb3V0cHV0cyB2aWEgU0RLXG4gICAgICAgIGNvbnN0IGNmbkNsaWVudCA9IG5ldyBDbG91ZEZvcm1hdGlvbkNsaWVudCh7IHJlZ2lvbiB9KTtcbiAgICAgICAgY29uc3QgZGVzY3JpYmVSZXN1bHQgPSBhd2FpdCBjZm5DbGllbnQuc2VuZChuZXcgRGVzY3JpYmVTdGFja3NDb21tYW5kKHsgU3RhY2tOYW1lOiBTVEFDS19OQU1FIH0pKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0cyA9IGRlc2NyaWJlUmVzdWx0LlN0YWNrcz8uWzBdPy5PdXRwdXRzID8/IFtdO1xuICAgICAgICBjb25zdCBvdXRwdXRNYXAgPSBPYmplY3QuZnJvbUVudHJpZXMob3V0cHV0cy5tYXAobyA9PiBbby5PdXRwdXRLZXkgPz8gJycsIG8uT3V0cHV0VmFsdWUgPz8gJyddKSk7XG5cbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludFNlY3Rpb24oJ0V2ZW50IEluZ2VzdGlvbiBSZWFkeScpO1xuXG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdTdGFjayc6IFNUQUNLX05BTUUsXG4gICAgICAgICAgJ1JlZ2lvbic6IHJlZ2lvbixcbiAgICAgICAgICAnUGxhdGZvcm0gVVJMJzogcGxhdGZvcm1VcmwsXG4gICAgICAgICAgJ0xhbWJkYSc6IG91dHB1dE1hcC5MYW1iZGFGdW5jdGlvbkFybiB8fCBMQU1CREFfTkFNRSxcbiAgICAgICAgICAnRXZlbnQgUXVldWUnOiBvdXRwdXRNYXAuRXZlbnRRdWV1ZVVybCB8fCAnKHNlZSBBV1MgY29uc29sZSknLFxuICAgICAgICAgICdEZWFkIExldHRlciBRdWV1ZSc6IG91dHB1dE1hcC5EZWFkTGV0dGVyUXVldWVVcmwgfHwgJyhzZWUgQVdTIGNvbnNvbGUpJyxcbiAgICAgICAgICAnRXZlbnRCcmlkZ2UgUnVsZSc6IG91dHB1dE1hcC5FdmVudFJ1bGVOYW1lIHx8ICcoc2VlIEFXUyBjb25zb2xlKScsXG4gICAgICAgICAgJ1N0YXR1cyc6ICfinJMgRGVwbG95ZWQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2VzcygnRXZlbnRCcmlkZ2UgZXZlbnQgaW5nZXN0aW9uIGlzIGFjdGl2ZS4nKTtcblxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IsIEVSUk9SX0NPREVTLkFQSV9SRVFVRVNULCB7XG4gICAgICAgICAgZGVidWc6IHByb2dyYW0ub3B0cygpLmRlYnVnLFxuICAgICAgICAgIGV4aXQ6IHRydWUsXG4gICAgICAgICAgY29udGV4dDogeyBjb21tYW5kOiAnc2V0dXAtZXZlbnRzJywgZXhlY3V0aW9uSWQsIHN0YWNrOiBTVEFDS19OQU1FIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xufVxuIl19
@@ -0,0 +1,11 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Registers the `status` command with the CLI program.
4
+ *
5
+ * Checks environment variables, CDK availability, platform connectivity,
6
+ * and token expiry to give a quick overview of the current setup.
7
+ *
8
+ * @param program - The root Commander program instance to attach the command to.
9
+ */
10
+ export declare function status(program: Command): void;
11
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqE7C"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.status = status;
9
+ const https_1 = __importDefault(require("https"));
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const cli_constants_1 = require("../config/cli.constants");
12
+ const cdk_utils_1 = require("../utils/cdk-utils");
13
+ const command_utils_1 = require("../utils/command-utils");
14
+ const error_handler_1 = require("../utils/error-handler");
15
+ const output_utils_1 = require("../utils/output-utils");
16
+ /**
17
+ * Registers the `status` command with the CLI program.
18
+ *
19
+ * Checks environment variables, CDK availability, platform connectivity,
20
+ * and token expiry to give a quick overview of the current setup.
21
+ *
22
+ * @param program - The root Commander program instance to attach the command to.
23
+ */
24
+ function status(program) {
25
+ program
26
+ .command('status')
27
+ .description('Show environment and connectivity status')
28
+ .option('--json', 'Output result as JSON', false)
29
+ .action(async (options) => {
30
+ const executionId = (0, command_utils_1.printCommandHeader)('Status');
31
+ try {
32
+ const results = {};
33
+ // 1. Check PLATFORM_TOKEN
34
+ const token = process.env[cli_constants_1.ENV_VARS.PLATFORM_TOKEN];
35
+ results.PLATFORM_TOKEN = token ? 'set' : 'not set';
36
+ // 2. Check PLATFORM_SECRET_NAME
37
+ const secretName = process.env.PLATFORM_SECRET_NAME;
38
+ results.PLATFORM_SECRET_NAME = secretName || 'not set';
39
+ // 3. Check CDK availability
40
+ results['CDK Available'] = (0, cdk_utils_1.checkCdkAvailable)() ? 'yes' : 'no';
41
+ // 4. Check platform health
42
+ const baseUrl = process.env[cli_constants_1.ENV_VARS.PLATFORM_BASE_URL] || 'https://localhost:8443';
43
+ results.PLATFORM_BASE_URL = baseUrl;
44
+ try {
45
+ const httpsAgent = new https_1.default.Agent({ rejectUnauthorized: false });
46
+ await axios_1.default.get(`${baseUrl}/health`, {
47
+ timeout: cli_constants_1.TIMEOUTS.HEALTH_CHECK,
48
+ httpsAgent,
49
+ });
50
+ results['Platform Health'] = 'reachable';
51
+ }
52
+ catch {
53
+ results['Platform Health'] = 'unreachable';
54
+ }
55
+ // 5. Decode token expiry
56
+ if (token) {
57
+ try {
58
+ const parts = token.split('.');
59
+ if (parts.length === 3 && parts[1]) {
60
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf-8'));
61
+ if (typeof payload.exp === 'number') {
62
+ const expiresAt = new Date(payload.exp * 1000);
63
+ results['Token Expires'] = expiresAt.toISOString();
64
+ results['Token Expired'] = expiresAt.getTime() < Date.now() ? 'yes' : 'no';
65
+ }
66
+ }
67
+ }
68
+ catch {
69
+ results['Token Expires'] = 'unable to decode';
70
+ }
71
+ }
72
+ if (options.json) {
73
+ console.log(JSON.stringify({ success: true, executionId, ...results }, null, 2));
74
+ }
75
+ else {
76
+ (0, output_utils_1.printSection)('Environment Status');
77
+ (0, output_utils_1.printKeyValue)(results);
78
+ }
79
+ }
80
+ catch (error) {
81
+ (0, error_handler_1.handleError)(error, error_handler_1.ERROR_CODES.GENERAL, {
82
+ debug: program.opts().debug,
83
+ exit: true,
84
+ context: { command: 'status', executionId },
85
+ });
86
+ }
87
+ });
88
+ }
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdHVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL3N0YXR1cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7Ozs7QUFtQnRDLHdCQXFFQztBQXRGRCxrREFBMEI7QUFDMUIsa0RBQTBCO0FBRTFCLDJEQUE2RDtBQUM3RCxrREFBdUQ7QUFDdkQsMERBQTREO0FBQzVELDBEQUFrRTtBQUNsRSx3REFBb0U7QUFFcEU7Ozs7Ozs7R0FPRztBQUNILFNBQWdCLE1BQU0sQ0FBQyxPQUFnQjtJQUNyQyxPQUFPO1NBQ0osT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNqQixXQUFXLENBQUMsMENBQTBDLENBQUM7U0FDdkQsTUFBTSxDQUFDLFFBQVEsRUFBRSx1QkFBdUIsRUFBRSxLQUFLLENBQUM7U0FDaEQsTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtRQUN4QixNQUFNLFdBQVcsR0FBRyxJQUFBLGtDQUFrQixFQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWpELElBQUksQ0FBQztZQUNILE1BQU0sT0FBTyxHQUEyQixFQUFFLENBQUM7WUFFM0MsMEJBQTBCO1lBQzFCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0JBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNuRCxPQUFPLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFFbkQsZ0NBQWdDO1lBQ2hDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7WUFDcEQsT0FBTyxDQUFDLG9CQUFvQixHQUFHLFVBQVUsSUFBSSxTQUFTLENBQUM7WUFFdkQsNEJBQTRCO1lBQzVCLE9BQU8sQ0FBQyxlQUFlLENBQUMsR0FBRyxJQUFBLDZCQUFpQixHQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FB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UGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBodHRwcyBmcm9tICdodHRwcyc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBFTlZfVkFSUywgVElNRU9VVFMgfSBmcm9tICcuLi9jb25maWcvY2xpLmNvbnN0YW50cyc7XG5pbXBvcnQgeyBjaGVja0Nka0F2YWlsYWJsZSB9IGZyb20gJy4uL3V0aWxzL2Nkay11dGlscyc7XG5pbXBvcnQgeyBwcmludENvbW1hbmRIZWFkZXIgfSBmcm9tICcuLi91dGlscy9jb21tYW5kLXV0aWxzJztcbmltcG9ydCB7IEVSUk9SX0NPREVTLCBoYW5kbGVFcnJvciB9IGZyb20gJy4uL3V0aWxzL2Vycm9yLWhhbmRsZXInO1xuaW1wb3J0IHsgcHJpbnRLZXlWYWx1ZSwgcHJpbnRTZWN0aW9uIH0gZnJvbSAnLi4vdXRpbHMvb3V0cHV0LXV0aWxzJztcblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIGBzdGF0dXNgIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogQ2hlY2tzIGVudmlyb25tZW50IHZhcmlhYmxlcywgQ0RLIGF2YWlsYWJpbGl0eSwgcGxhdGZvcm0gY29ubmVjdGl2aXR5LFxuICogYW5kIHRva2VuIGV4cGlyeSB0byBnaXZlIGEgcXVpY2sgb3ZlcnZpZXcgb2YgdGhlIGN1cnJlbnQgc2V0dXAuXG4gKlxuICogQHBhcmFtIHByb2dyYW0gLSBUaGUgcm9vdCBDb21tYW5kZXIgcHJvZ3JhbSBpbnN0YW5jZSB0byBhdHRhY2ggdGhlIGNvbW1hbmQgdG8uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGF0dXMocHJvZ3JhbTogQ29tbWFuZCk6IHZvaWQge1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3N0YXR1cycpXG4gICAgLmRlc2NyaXB0aW9uKCdTaG93IGVudmlyb25tZW50IGFuZCBjb25uZWN0aXZpdHkgc3RhdHVzJylcbiAgICAub3B0aW9uKCctLWpzb24nLCAnT3V0cHV0IHJlc3VsdCBhcyBKU09OJywgZmFsc2UpXG4gICAgLmFjdGlvbihhc3luYyAob3B0aW9ucykgPT4ge1xuICAgICAgY29uc3QgZXhlY3V0aW9uSWQgPSBwcmludENvbW1hbmRIZWFkZXIoJ1N0YXR1cycpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZXN1bHRzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICAgICAgLy8gMS4gQ2hlY2sgUExBVEZPUk1fVE9LRU5cbiAgICAgICAgY29uc3QgdG9rZW4gPSBwcm9jZXNzLmVudltFTlZfVkFSUy5QTEFURk9STV9UT0tFTl07XG4gICAgICAgIHJlc3VsdHMuUExBVEZPUk1fVE9LRU4gPSB0b2tlbiA/ICdzZXQnIDogJ25vdCBzZXQnO1xuXG4gICAgICAgIC8vIDIuIENoZWNrIFBMQVRGT1JNX1NFQ1JFVF9OQU1FXG4gICAgICAgIGNvbnN0IHNlY3JldE5hbWUgPSBwcm9jZXNzLmVudi5QTEFURk9STV9TRUNSRVRfTkFNRTtcbiAgICAgICAgcmVzdWx0cy5QTEFURk9STV9TRUNSRVRfTkFNRSA9IHNlY3JldE5hbWUgfHwgJ25vdCBzZXQnO1xuXG4gICAgICAgIC8vIDMuIENoZWNrIENESyBhdmFpbGFiaWxpdHlcbiAgICAgICAgcmVzdWx0c1snQ0RLIEF2YWlsYWJsZSddID0gY2hlY2tDZGtBdmFpbGFibGUoKSA/ICd5ZXMnIDogJ25vJztcblxuICAgICAgICAvLyA0LiBDaGVjayBwbGF0Zm9ybSBoZWFsdGhcbiAgICAgICAgY29uc3QgYmFzZVVybCA9IHByb2Nlc3MuZW52W0VOVl9WQVJTLlBMQVRGT1JNX0JBU0VfVVJMXSB8fCAnaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0Myc7XG4gICAgICAgIHJlc3VsdHMuUExBVEZPUk1fQkFTRV9VUkwgPSBiYXNlVXJsO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgaHR0cHNBZ2VudCA9IG5ldyBodHRwcy5BZ2VudCh7IHJlamVjdFVuYXV0aG9yaXplZDogZmFsc2UgfSk7XG4gICAgICAgICAgYXdhaXQgYXhpb3MuZ2V0KGAke2Jhc2VVcmx9L2hlYWx0aGAsIHtcbiAgICAgICAgICAgIHRpbWVvdXQ6IFRJTUVPVVRTLkhFQUxUSF9DSEVDSyxcbiAgICAgICAgICAgIGh0dHBzQWdlbnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmVzdWx0c1snUGxhdGZvcm0gSGVhbHRoJ10gPSAncmVhY2hhYmxlJztcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmVzdWx0c1snUGxhdGZvcm0gSGVhbHRoJ10gPSAndW5yZWFjaGFibGUnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gNS4gRGVjb2RlIHRva2VuIGV4cGlyeVxuICAgICAgICBpZiAodG9rZW4pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGFydHMgPSB0b2tlbi5zcGxpdCgnLicpO1xuICAgICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMyAmJiBwYXJ0c1sxXSkge1xuICAgICAgICAgICAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5wYXJzZShCdWZmZXIuZnJvbShwYXJ0c1sxXSwgJ2Jhc2U2NHVybCcpLnRvU3RyaW5nKCd1dGYtOCcpKSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXlsb2FkLmV4cCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBleHBpcmVzQXQgPSBuZXcgRGF0ZShwYXlsb2FkLmV4cCAqIDEwMDApO1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbJ1Rva2VuIEV4cGlyZXMnXSA9IGV4cGlyZXNBdC50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbJ1Rva2VuIEV4cGlyZWQnXSA9IGV4cGlyZXNBdC5nZXRUaW1lKCkgPCBEYXRlLm5vdygpID8gJ3llcycgOiAnbm8nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICByZXN1bHRzWydUb2tlbiBFeHBpcmVzJ10gPSAndW5hYmxlIHRvIGRlY29kZSc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuanNvbikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHsgc3VjY2VzczogdHJ1ZSwgZXhlY3V0aW9uSWQsIC4uLnJlc3VsdHMgfSwgbnVsbCwgMikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByaW50U2VjdGlvbignRW52aXJvbm1lbnQgU3RhdHVzJyk7XG4gICAgICAgICAgcHJpbnRLZXlWYWx1ZShyZXN1bHRzKTtcbiAgICAgICAgfVxuXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBoYW5kbGVFcnJvcihlcnJvciwgRVJST1JfQ09ERVMuR0VORVJBTCwge1xuICAgICAgICAgIGRlYnVnOiBwcm9ncmFtLm9wdHMoKS5kZWJ1ZyxcbiAgICAgICAgICBleGl0OiB0cnVlLFxuICAgICAgICAgIGNvbnRleHQ6IHsgY29tbWFuZDogJ3N0YXR1cycsIGV4ZWN1dGlvbklkIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xufVxuIl19
@@ -0,0 +1,20 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Registers the `store-token` command with the CLI program.
4
+ *
5
+ * Generates a long-lived JWT token via the platform API and stores it
6
+ * in AWS Secrets Manager for use by the synth/deploy --store-tokens flag.
7
+ *
8
+ * Requires PLATFORM_TOKEN to be set, or use --email/--password to login inline.
9
+ *
10
+ * @example
11
+ * ```bash
12
+ * pipeline-manager store-token --region us-east-1
13
+ * pipeline-manager store-token --days 90 --region us-east-1
14
+ * pipeline-manager store-token --days 7 --secret-name my-custom-secret --no-verify-ssl
15
+ * pipeline-manager store-token --dry-run
16
+ * pipeline-manager store-token -e admin -p '***' --region us-east-1
17
+ * ```
18
+ */
19
+ export declare function storeToken(program: Command): void;
20
+ //# sourceMappingURL=store-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-token.d.ts","sourceRoot":"","sources":["../../src/commands/store-token.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmLjD"}