@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.
- package/LICENSE +202 -0
- package/README.md +74 -0
- package/cdk.json +91 -0
- package/config.yml +94 -0
- package/dist/boilerplate.d.ts +3 -0
- package/dist/boilerplate.d.ts.map +1 -0
- package/dist/boilerplate.js +58 -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 +372 -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-pipeline.d.ts +12 -0
- package/dist/commands/create-pipeline.d.ts.map +1 -0
- package/dist/commands/create-pipeline.js +291 -0
- package/dist/commands/deploy.d.ts +15 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +167 -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 +97 -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 +98 -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 +172 -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 +167 -0
- package/dist/commands/login.d.ts +21 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +179 -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 +177 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +89 -0
- package/dist/commands/store-token.d.ts +20 -0
- package/dist/commands/store-token.d.ts.map +1 -0
- package/dist/commands/store-token.js +233 -0
- package/dist/commands/synth.d.ts +21 -0
- package/dist/commands/synth.d.ts.map +1 -0
- package/dist/commands/synth.js +143 -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 +311 -0
- package/dist/commands/version.d.ts +12 -0
- package/dist/commands/version.d.ts.map +1 -0
- package/dist/commands/version.js +223 -0
- package/dist/config/cli.constants.d.ts +101 -0
- package/dist/config/cli.constants.d.ts.map +1 -0
- package/dist/config/cli.constants.js +165 -0
- package/dist/config.yml +94 -0
- package/dist/templates/events-stack.json +141 -0
- package/dist/types/config.d.ts +44 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +5 -0
- package/dist/types/error.d.ts +61 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +39 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +26 -0
- package/dist/types/pipeline.d.ts +144 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +5 -0
- package/dist/types/plugin.d.ts +160 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +5 -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 +160 -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 +53 -0
- package/dist/utils/auth-guard.d.ts +16 -0
- package/dist/utils/auth-guard.d.ts.map +1 -0
- package/dist/utils/auth-guard.js +25 -0
- package/dist/utils/aws-secrets.d.ts +21 -0
- package/dist/utils/aws-secrets.d.ts.map +1 -0
- package/dist/utils/aws-secrets.js +74 -0
- package/dist/utils/banner.d.ts +19 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +59 -0
- package/dist/utils/cdk-utils.d.ts +51 -0
- package/dist/utils/cdk-utils.d.ts.map +1 -0
- package/dist/utils/cdk-utils.js +101 -0
- package/dist/utils/command-utils.d.ts +56 -0
- package/dist/utils/command-utils.d.ts.map +1 -0
- package/dist/utils/command-utils.js +138 -0
- package/dist/utils/config-loader.d.ts +27 -0
- package/dist/utils/config-loader.d.ts.map +1 -0
- package/dist/utils/config-loader.js +166 -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 +255 -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 +60 -0
- package/dist/utils/output-utils.d.ts +60 -0
- package/dist/utils/output-utils.d.ts.map +1 -0
- package/dist/utils/output-utils.js +320 -0
- package/dist/utils/rate-limiter.d.ts +14 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +73 -0
- package/package.json +144 -0
|
@@ -0,0 +1,320 @@
|
|
|
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.printSuccess = printSuccess;
|
|
9
|
+
exports.printInfo = printInfo;
|
|
10
|
+
exports.printWarning = printWarning;
|
|
11
|
+
exports.printError = printError;
|
|
12
|
+
exports.printDebug = printDebug;
|
|
13
|
+
exports.outputData = outputData;
|
|
14
|
+
exports.formatTable = formatTable;
|
|
15
|
+
exports.ensureOutputDirectory = ensureOutputDirectory;
|
|
16
|
+
exports.fileExists = fileExists;
|
|
17
|
+
exports.printSection = printSection;
|
|
18
|
+
exports.printKeyValue = printKeyValue;
|
|
19
|
+
exports.printDivider = printDivider;
|
|
20
|
+
exports.unwrapEnvelope = unwrapEnvelope;
|
|
21
|
+
exports.extractSingleResponse = extractSingleResponse;
|
|
22
|
+
exports.extractListResponse = extractListResponse;
|
|
23
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
24
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
25
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
26
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
27
|
+
const cli_constants_1 = require("../config/cli.constants");
|
|
28
|
+
const { bold, cyan, green, yellow, red, dim, magenta, white } = picocolors_1.default;
|
|
29
|
+
// --- Logging functions ---
|
|
30
|
+
function logOutput(level, message, data) {
|
|
31
|
+
const colors = { info: cyan, success: green, warn: yellow, error: red, debug: magenta };
|
|
32
|
+
const prefixes = { info: 'ℹ', success: '✓', warn: '⚠', error: '✗', debug: '●' };
|
|
33
|
+
const writers = { error: console.error, warn: console.warn, info: console.log, success: console.log, debug: console.log };
|
|
34
|
+
const styledMessage = `${colors[level](prefixes[level])} ${message}`;
|
|
35
|
+
const write = writers[level];
|
|
36
|
+
write(styledMessage);
|
|
37
|
+
if (data !== undefined)
|
|
38
|
+
write(dim(formatDataForLog(data)));
|
|
39
|
+
}
|
|
40
|
+
function formatDataForLog(data) {
|
|
41
|
+
if (typeof data === 'string')
|
|
42
|
+
return data;
|
|
43
|
+
if (typeof data === 'object' && data !== null) {
|
|
44
|
+
const entries = Object.entries(data);
|
|
45
|
+
if (entries.length <= 5) {
|
|
46
|
+
return '\n' + entries.map(([key, value]) => {
|
|
47
|
+
const valueStr = typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
48
|
+
return ` ${key}: ${valueStr}`;
|
|
49
|
+
}).join('\n');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return JSON.stringify(data, null, 2);
|
|
53
|
+
}
|
|
54
|
+
function printSuccess(message, data) { logOutput('success', message, data); }
|
|
55
|
+
function printInfo(message, data) { logOutput('info', message, data); }
|
|
56
|
+
function printWarning(message, data) { logOutput('warn', message, data); }
|
|
57
|
+
function printError(message, data) { logOutput('error', message, data); }
|
|
58
|
+
function printDebug(message, data) {
|
|
59
|
+
if (process.env.DEBUG === 'true')
|
|
60
|
+
logOutput('debug', message, data);
|
|
61
|
+
}
|
|
62
|
+
// --- Data output ---
|
|
63
|
+
/**
|
|
64
|
+
* Output data in specified format (console or file)
|
|
65
|
+
*/
|
|
66
|
+
function outputData(data, options = {}) {
|
|
67
|
+
const { format = 'json', file, pretty = true, silent = false, append = false } = options;
|
|
68
|
+
let output;
|
|
69
|
+
switch (format) {
|
|
70
|
+
case 'table':
|
|
71
|
+
if (!silent)
|
|
72
|
+
printInfo('Rendering as table');
|
|
73
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
74
|
+
console.log(formatTable(data));
|
|
75
|
+
}
|
|
76
|
+
else if (typeof data === 'object' && data !== null) {
|
|
77
|
+
console.log(formatTable([data]));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.table(Array.isArray(data) ? data : [data]);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
case 'csv':
|
|
84
|
+
if (!silent)
|
|
85
|
+
printInfo('Rendering as CSV');
|
|
86
|
+
output = formatCsv(data);
|
|
87
|
+
break;
|
|
88
|
+
case 'yaml':
|
|
89
|
+
if (!silent)
|
|
90
|
+
printInfo('Rendering as YAML');
|
|
91
|
+
output = yaml_1.default.stringify(data);
|
|
92
|
+
break;
|
|
93
|
+
case 'json':
|
|
94
|
+
default:
|
|
95
|
+
if (!silent)
|
|
96
|
+
printInfo('Rendering as JSON');
|
|
97
|
+
output = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
if (file) {
|
|
101
|
+
writeToFile(file, output, format, append);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.log(output);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// --- Table formatting ---
|
|
108
|
+
function formatTable(data, columns) {
|
|
109
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
110
|
+
return dim('(No data to display)');
|
|
111
|
+
const firstItem = data[0];
|
|
112
|
+
if (typeof firstItem !== 'object' || firstItem === null)
|
|
113
|
+
return JSON.stringify(data, null, 2);
|
|
114
|
+
const cols = columns || Object.keys(firstItem).map(key => ({ header: key, key }));
|
|
115
|
+
const colWidths = cols.map(col => {
|
|
116
|
+
if (col.width)
|
|
117
|
+
return col.width;
|
|
118
|
+
const headerWidth = col.header.length;
|
|
119
|
+
const dataWidth = Math.max(...data.map(item => {
|
|
120
|
+
const value = col.formatter
|
|
121
|
+
? col.formatter(item[col.key])
|
|
122
|
+
: String(item[col.key] ?? '');
|
|
123
|
+
return value.length;
|
|
124
|
+
}));
|
|
125
|
+
return Math.max(headerWidth, dataWidth, 3);
|
|
126
|
+
});
|
|
127
|
+
const { border } = cli_constants_1.TABLE_OPTIONS;
|
|
128
|
+
const horizontalLine = (left, middle, right) => left + colWidths.map(w => border.bodyJoin.repeat((w ?? 0) + 2)).join(middle) + right;
|
|
129
|
+
const topLine = horizontalLine(border.topLeft, border.topJoin, border.topRight);
|
|
130
|
+
const midLine = horizontalLine(border.joinLeft, border.joinJoin, border.joinRight);
|
|
131
|
+
const bottomLine = horizontalLine(border.bottomLeft, border.bottomJoin, border.bottomRight);
|
|
132
|
+
const formatCell = (value, width, align = 'left') => {
|
|
133
|
+
if (value.length > width)
|
|
134
|
+
return value.substring(0, width - 3) + '...';
|
|
135
|
+
if (align === 'center') {
|
|
136
|
+
const leftPad = Math.floor((width - value.length) / 2);
|
|
137
|
+
return ' '.repeat(leftPad) + value + ' '.repeat(width - value.length - leftPad);
|
|
138
|
+
}
|
|
139
|
+
return align === 'right' ? value.padStart(width) : value.padEnd(width);
|
|
140
|
+
};
|
|
141
|
+
const headerRow = border.bodyLeft + ' ' +
|
|
142
|
+
cols.map((col, i) => cyan(bold(formatCell(col.header, colWidths[i] ?? 0)))).join(` ${border.bodyJoin} `) +
|
|
143
|
+
` ${border.bodyRight}`;
|
|
144
|
+
let table = cyan(topLine) + '\n' + headerRow + '\n' + cyan(midLine) + '\n';
|
|
145
|
+
data.forEach(item => {
|
|
146
|
+
const row = border.bodyLeft + ' ' +
|
|
147
|
+
cols.map((col, i) => {
|
|
148
|
+
const value = col.formatter
|
|
149
|
+
? col.formatter(item[col.key])
|
|
150
|
+
: String(item[col.key] ?? '');
|
|
151
|
+
return formatCell(value, colWidths[i] ?? 0, col.align);
|
|
152
|
+
}).join(` ${border.bodyJoin} `) +
|
|
153
|
+
` ${border.bodyRight}`;
|
|
154
|
+
table += row + '\n';
|
|
155
|
+
});
|
|
156
|
+
table += cyan(bottomLine);
|
|
157
|
+
return table;
|
|
158
|
+
}
|
|
159
|
+
// --- CSV formatting ---
|
|
160
|
+
function formatCsv(data) {
|
|
161
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
162
|
+
return '';
|
|
163
|
+
const firstItem = data[0];
|
|
164
|
+
if (typeof firstItem !== 'object' || firstItem === null)
|
|
165
|
+
return data.join(',');
|
|
166
|
+
const headers = Object.keys(firstItem);
|
|
167
|
+
const rows = [headers.map(h => escapeCsvValue(h)).join(',')];
|
|
168
|
+
data.forEach(item => {
|
|
169
|
+
rows.push(headers.map(h => escapeCsvValue(item[h])).join(','));
|
|
170
|
+
});
|
|
171
|
+
return rows.join('\n');
|
|
172
|
+
}
|
|
173
|
+
function escapeCsvValue(value) {
|
|
174
|
+
if (value === null || value === undefined)
|
|
175
|
+
return '';
|
|
176
|
+
const str = String(value);
|
|
177
|
+
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
178
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
179
|
+
}
|
|
180
|
+
return str;
|
|
181
|
+
}
|
|
182
|
+
// --- File operations ---
|
|
183
|
+
/**
|
|
184
|
+
* Validate that a file path resolves within the current working directory.
|
|
185
|
+
* Prevents path traversal attacks (e.g., --output ../../etc/passwd).
|
|
186
|
+
*/
|
|
187
|
+
function validateOutputPath(filePath) {
|
|
188
|
+
const resolved = node_path_1.default.resolve(filePath);
|
|
189
|
+
const cwd = node_path_1.default.resolve(process.cwd());
|
|
190
|
+
if (!resolved.startsWith(cwd + node_path_1.default.sep) && resolved !== cwd) {
|
|
191
|
+
throw new Error(`Path traversal rejected: "${filePath}" resolves outside the current directory`);
|
|
192
|
+
}
|
|
193
|
+
return resolved;
|
|
194
|
+
}
|
|
195
|
+
function writeToFile(filePath, content, format, append = false) {
|
|
196
|
+
try {
|
|
197
|
+
const safePath = validateOutputPath(filePath);
|
|
198
|
+
const dir = node_path_1.default.dirname(safePath);
|
|
199
|
+
if (dir !== '.')
|
|
200
|
+
ensureOutputDirectory(dir);
|
|
201
|
+
if (append) {
|
|
202
|
+
node_fs_1.default.appendFileSync(safePath, content + '\n', 'utf-8');
|
|
203
|
+
printSuccess('Output appended to file', { path: safePath, format });
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
node_fs_1.default.writeFileSync(safePath, content, 'utf-8');
|
|
207
|
+
const stats = node_fs_1.default.statSync(safePath);
|
|
208
|
+
printSuccess('Output saved to file', { path: safePath, format, size: (0, cli_constants_1.formatFileSize)(stats.size) });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
printError('Failed to write file', {
|
|
213
|
+
path: filePath,
|
|
214
|
+
error: error instanceof Error ? error.message : String(error),
|
|
215
|
+
});
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function ensureOutputDirectory(outputPath) {
|
|
220
|
+
if (node_fs_1.default.existsSync(outputPath))
|
|
221
|
+
return;
|
|
222
|
+
try {
|
|
223
|
+
node_fs_1.default.mkdirSync(outputPath, { recursive: true });
|
|
224
|
+
printDebug('Directory created', { path: outputPath });
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
printError('Failed to create directory', {
|
|
228
|
+
path: outputPath,
|
|
229
|
+
error: error instanceof Error ? error.message : String(error),
|
|
230
|
+
});
|
|
231
|
+
throw error;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function fileExists(filePath) {
|
|
235
|
+
return node_fs_1.default.existsSync(filePath);
|
|
236
|
+
}
|
|
237
|
+
// --- Display helpers ---
|
|
238
|
+
function printSection(title, subtitle) {
|
|
239
|
+
const width = process.stdout.columns || 80;
|
|
240
|
+
console.log('');
|
|
241
|
+
console.log(cyan('═'.repeat(width)));
|
|
242
|
+
console.log(cyan(bold(title)));
|
|
243
|
+
if (subtitle)
|
|
244
|
+
console.log(dim(subtitle));
|
|
245
|
+
console.log(cyan('═'.repeat(width)));
|
|
246
|
+
}
|
|
247
|
+
function printKeyValue(data, options = {}) {
|
|
248
|
+
const { indent = 0, separator = '│' } = options;
|
|
249
|
+
const maxKeyLength = Math.max(...Object.keys(data).map(k => k.length));
|
|
250
|
+
const indentStr = ' '.repeat(indent);
|
|
251
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
252
|
+
const paddedKey = key.padEnd(maxKeyLength);
|
|
253
|
+
const formattedValue = typeof value === 'object' && value !== null
|
|
254
|
+
? JSON.stringify(value) : String(value);
|
|
255
|
+
console.log(`${indentStr}${dim(paddedKey)} ${cyan(separator)} ${white(formattedValue)}`);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function printDivider(char = '─', width) {
|
|
259
|
+
const effectiveWidth = width || process.stdout.columns || 80;
|
|
260
|
+
console.log(dim(char.repeat(effectiveWidth)));
|
|
261
|
+
}
|
|
262
|
+
// --- Response parsing ---
|
|
263
|
+
/**
|
|
264
|
+
* Unwrap a sendSuccess API envelope: { success, statusCode, data: { ... } }
|
|
265
|
+
* Returns the inner `data` object, or the original response if not wrapped.
|
|
266
|
+
*/
|
|
267
|
+
function unwrapEnvelope(response) {
|
|
268
|
+
if (response && typeof response === 'object') {
|
|
269
|
+
const obj = response;
|
|
270
|
+
if ('success' in obj && 'data' in obj && obj.data && typeof obj.data === 'object') {
|
|
271
|
+
return obj.data;
|
|
272
|
+
}
|
|
273
|
+
return obj;
|
|
274
|
+
}
|
|
275
|
+
return {};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Extract a single entity from an API response, handling envelope formats.
|
|
279
|
+
* Tries: payload[entityKey], payload directly (if identifierKey exists), or undefined.
|
|
280
|
+
*/
|
|
281
|
+
function extractSingleResponse(response, entityKey, identifierKey) {
|
|
282
|
+
const payload = unwrapEnvelope(response);
|
|
283
|
+
// Direct entity: payload has the identifier (e.g. payload.id, payload.props, payload.name)
|
|
284
|
+
if (identifierKey in payload)
|
|
285
|
+
return payload;
|
|
286
|
+
// Nested under entity key: payload.pipeline, payload.plugin
|
|
287
|
+
const nested = payload[entityKey];
|
|
288
|
+
if (nested && typeof nested === 'object' && identifierKey in nested)
|
|
289
|
+
return nested;
|
|
290
|
+
return undefined;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Extract items from an API list response, handling multiple response formats.
|
|
294
|
+
* Supports: `{ <key>: T[] }`, `{ items: T[] }`, `T[]`, or invalid formats.
|
|
295
|
+
*/
|
|
296
|
+
function extractListResponse(response, itemsKey) {
|
|
297
|
+
if (Array.isArray(response)) {
|
|
298
|
+
return { items: response, total: undefined, hasMore: false };
|
|
299
|
+
}
|
|
300
|
+
if (response && typeof response === 'object') {
|
|
301
|
+
const obj = unwrapEnvelope(response);
|
|
302
|
+
// Extract pagination metadata if present
|
|
303
|
+
const pagination = obj.pagination;
|
|
304
|
+
const total = (pagination?.total ?? obj.total);
|
|
305
|
+
const hasMore = (pagination?.hasMore ?? obj.hasMore) || false;
|
|
306
|
+
// Try primary key (e.g. 'pipelines', 'plugins')
|
|
307
|
+
if (itemsKey in obj && Array.isArray(obj[itemsKey])) {
|
|
308
|
+
return { items: obj[itemsKey], total, hasMore };
|
|
309
|
+
}
|
|
310
|
+
// Try generic 'items' key
|
|
311
|
+
if ('items' in obj && Array.isArray(obj.items)) {
|
|
312
|
+
return { items: obj.items, total, hasMore };
|
|
313
|
+
}
|
|
314
|
+
printWarning('Unexpected response format, attempting to handle');
|
|
315
|
+
return { items: [], total: undefined, hasMore: false };
|
|
316
|
+
}
|
|
317
|
+
printError('Invalid response format from API');
|
|
318
|
+
throw new Error('Unexpected API response format');
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0cHV0LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL291dHB1dC11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7Ozs7QUFrRXRDLG9DQUE0RztBQUM1Ryw4QkFBc0c7QUFDdEcsb0NBQXlHO0FBQ3pHLGdDQUF3RztBQUV4RyxnQ0FFQztBQU9ELGdDQXVDQztBQUlELGtDQTBEQztBQWdFRCxzREFZQztBQUVELGdDQUVDO0FBSUQsb0NBT0M7QUFFRCxzQ0FjQztBQUVELG9DQUdDO0FBUUQsd0NBU0M7QUFNRCxzREFRQztBQVlELGtEQTZCQztBQTNXRCxzREFBeUI7QUFDekIsMERBQTZCO0FBQzdCLDREQUE4QjtBQUM5QixnREFBd0I7QUFDeEIsMkRBSWlDO0FBRWpDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsb0JBQUksQ0FBQztBQTBCckUsNEJBQTRCO0FBRTVCLFNBQVMsU0FBUyxDQUFDLEtBQWUsRUFBRSxPQUFlLEVBQUUsSUFBYztJQUNqRSxNQUFNLE1BQU0sR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3hGLE1BQU0sUUFBUSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDaEYsTUFBTSxPQUFPLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsT0FB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LENBQUMsT0FBTyxDQUFhLElBQUksS0FBSyxDQUFDO1FBRTNFLGdEQUFnRDtRQUNoRCxJQUFJLFFBQVEsSUFBSSxHQUFHLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3BELE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLFFBQVEsQ0FBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUN6RCxDQUFDO1FBRUQsMEJBQTBCO1FBQzFCLElBQUksT0FBTyxJQUFJLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9DLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQVksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDckQsQ0FBQztRQUVELFlBQVksQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO1FBQ2pFLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ3pELENBQUM7SUFFRCxVQUFVLENBQUMsa0NBQWtDLENBQUMsQ0FBQztJQUMvQyxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7QUFDcEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHBpY28gZnJvbSAncGljb2NvbG9ycyc7XG5pbXBvcnQgWUFNTCBmcm9tICd5YW1sJztcbmltcG9ydCB7XG4gIE91dHB1dEZvcm1hdCxcbiAgZm9ybWF0RmlsZVNpemUsXG4gIFRBQkxFX09QVElPTlMsXG59IGZyb20gJy4uL2NvbmZpZy9jbGkuY29uc3RhbnRzJztcblxuY29uc3QgeyBib2xkLCBjeWFuLCBncmVlbiwgeWVsbG93LCByZWQsIGRpbSwgbWFnZW50YSwgd2hpdGUgfSA9IHBpY287XG5cbnR5cGUgTG9nTGV2ZWwgPSAnaW5mbycgfCAnc3VjY2VzcycgfCAnd2FybicgfCAnZXJyb3InIHwgJ2RlYnVnJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciBvdXRwdXREYXRhIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3V0cHV0T3B0aW9ucyB7XG4gIGZvcm1hdD86IE91dHB1dEZvcm1hdDtcbiAgZmlsZT86IHN0cmluZztcbiAgcHJldHR5PzogYm9vbGVhbjtcbiAgc2lsZW50PzogYm9vbGVhbjtcbiAgYXBwZW5kPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUYWJsZSBjb2x1bW4gY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlQ29sdW1uIHtcbiAgaGVhZGVyOiBzdHJpbmc7XG4gIGtleTogc3RyaW5nO1xuICB3aWR0aD86IG51bWJlcjtcbiAgYWxpZ24/OiAnbGVmdCcgfCAnY2VudGVyJyB8ICdyaWdodCc7XG4gIGZvcm1hdHRlcj86ICh2YWx1ZTogdW5rbm93bikgPT4gc3RyaW5nO1xufVxuXG4vLyAtLS0gTG9nZ2luZyBmdW5jdGlvbnMgLS0tXG5cbmZ1bmN0aW9uIGxvZ091dHB1dChsZXZlbDogTG9nTGV2ZWwsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pOiB2b2lkIHtcbiAgY29uc3QgY29sb3JzID0geyBpbmZvOiBjeWFuLCBzdWNjZXNzOiBncmVlbiwgd2FybjogeWVsbG93LCBlcnJvcjogcmVkLCBkZWJ1ZzogbWFnZW50YSB9O1xuICBjb25zdCBwcmVmaXhlcyA9IHsgaW5mbzogJ+KEuScsIHN1Y2Nlc3M6ICfinJMnLCB3YXJuOiAn4pqgJywgZXJyb3I6ICfinJcnLCBkZWJ1ZzogJ+KXjycgfTtcbiAgY29uc3Qgd3JpdGVycyA9IHsgZXJyb3I6IGNvbnNvbGUuZXJyb3IsIHdhcm46IGNvbnNvbGUud2FybiwgaW5mbzogY29uc29sZS5sb2csIHN1Y2Nlc3M6IGNvbnNvbGUubG9nLCBkZWJ1ZzogY29uc29sZS5sb2cgfTtcblxuICBjb25zdCBzdHlsZWRNZXNzYWdlID0gYCR7Y29sb3JzW2xldmVsXShwcmVmaXhlc1tsZXZlbF0pfSAke21lc3NhZ2V9YDtcbiAgY29uc3Qgd3JpdGUgPSB3cml0ZXJzW2xldmVsXTtcblxuICB3cml0ZShzdHlsZWRNZXNzYWdlKTtcbiAgaWYgKGRhdGEgIT09IHVuZGVmaW5lZCkgd3JpdGUoZGltKGZvcm1hdERhdGFGb3JMb2coZGF0YSkpKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGF0YUZvckxvZyhkYXRhOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykgcmV0dXJuIGRhdGE7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiYgZGF0YSAhPT0gbnVsbCkge1xuICAgIGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyhkYXRhKTtcbiAgICBpZiAoZW50cmllcy5sZW5ndGggPD0gNSkge1xuICAgICAgcmV0dXJuICdcXG4nICsgZW50cmllcy5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZVN0ciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgOiBTdHJpbmcodmFsdWUpO1xuICAgICAgICByZXR1cm4gYCAgJHtrZXl9OiAke3ZhbHVlU3RyfWA7XG4gICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJpbnRTdWNjZXNzKG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pOiB2b2lkIHsgbG9nT3V0cHV0KCdzdWNjZXNzJywgbWVzc2FnZSwgZGF0YSk7IH1cbmV4cG9ydCBmdW5jdGlvbiBwcmludEluZm8obWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bik6IHZvaWQgeyBsb2dPdXRwdXQoJ2luZm8nLCBtZXNzYWdlLCBkYXRhKTsgfVxuZXhwb3J0IGZ1bmN0aW9uIHByaW50V2FybmluZyhtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogdm9pZCB7IGxvZ091dHB1dCgnd2FybicsIG1lc3NhZ2UsIGRhdGEpOyB9XG5leHBvcnQgZnVuY3Rpb24gcHJpbnRFcnJvcihtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogdm9pZCB7IGxvZ091dHB1dCgnZXJyb3InLCBtZXNzYWdlLCBkYXRhKTsgfVxuXG5leHBvcnQgZnVuY3Rpb24gcHJpbnREZWJ1ZyhtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKTogdm9pZCB7XG4gIGlmIChwcm9jZXNzLmVudi5ERUJVRyA9PT0gJ3RydWUnKSBsb2dPdXRwdXQoJ2RlYnVnJywgbWVzc2FnZSwgZGF0YSk7XG59XG5cbi8vIC0tLSBEYXRhIG91dHB1dCAtLS1cblxuLyoqXG4gKiBPdXRwdXQgZGF0YSBpbiBzcGVjaWZpZWQgZm9ybWF0IChjb25zb2xlIG9yIGZpbGUpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvdXRwdXREYXRhKGRhdGE6IHVua25vd24sIG9wdGlvbnM6IE91dHB1dE9wdGlvbnMgPSB7fSk6IHZvaWQge1xuICBjb25zdCB7IGZvcm1hdCA9ICdqc29uJywgZmlsZSwgcHJldHR5ID0gdHJ1ZSwgc2lsZW50ID0gZmFsc2UsIGFwcGVuZCA9IGZhbHNlIH0gPSBvcHRpb25zO1xuXG4gIGxldCBvdXRwdXQ6IHN0cmluZztcblxuICBzd2l0Y2ggKGZvcm1hdCkge1xuICAgIGNhc2UgJ3RhYmxlJzpcbiAgICAgIGlmICghc2lsZW50KSBwcmludEluZm8oJ1JlbmRlcmluZyBhcyB0YWJsZScpO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkgJiYgZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGZvcm1hdFRhYmxlKGRhdGEpKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnICYmIGRhdGEgIT09IG51bGwpIHtcbiAgICAgICAgY29uc29sZS5sb2coZm9ybWF0VGFibGUoW2RhdGFdKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLnRhYmxlKEFycmF5LmlzQXJyYXkoZGF0YSkgPyBkYXRhIDogW2RhdGFdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcblxuICAgIGNhc2UgJ2Nzdic6XG4gICAgICBpZiAoIXNpbGVudCkgcHJpbnRJbmZvKCdSZW5kZXJpbmcgYXMgQ1NWJyk7XG4gICAgICBvdXRwdXQgPSBmb3JtYXRDc3YoZGF0YSk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3lhbWwnOlxuICAgICAgaWYgKCFzaWxlbnQpIHByaW50SW5mbygnUmVuZGVyaW5nIGFzIFlBTUwnKTtcbiAgICAgIG91dHB1dCA9IFlBTUwuc3RyaW5naWZ5KGRhdGEpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICdqc29uJzpcbiAgICBkZWZhdWx0OlxuICAgICAgaWYgKCFzaWxlbnQpIHByaW50SW5mbygnUmVuZGVyaW5nIGFzIEpTT04nKTtcbiAgICAgIG91dHB1dCA9IHByZXR0eSA/IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpIDogSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIGlmIChmaWxlKSB7XG4gICAgd3JpdGVUb0ZpbGUoZmlsZSwgb3V0cHV0LCBmb3JtYXQsIGFwcGVuZCk7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5sb2cob3V0cHV0KTtcbiAgfVxufVxuXG4vLyAtLS0gVGFibGUgZm9ybWF0dGluZyAtLS1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFRhYmxlKGRhdGE6IHVua25vd25bXSwgY29sdW1ucz86IFRhYmxlQ29sdW1uW10pOiBzdHJpbmcge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoZGF0YSkgfHwgZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBkaW0oJyhObyBkYXRhIHRvIGRpc3BsYXkpJyk7XG5cbiAgY29uc3QgZmlyc3RJdGVtID0gZGF0YVswXTtcbiAgaWYgKHR5cGVvZiBmaXJzdEl0ZW0gIT09ICdvYmplY3QnIHx8IGZpcnN0SXRlbSA9PT0gbnVsbCkgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpO1xuXG4gIGNvbnN0IGNvbHM6IFRhYmxlQ29sdW1uW10gPSBjb2x1bW5zIHx8IE9iamVjdC5rZXlzKGZpcnN0SXRlbSkubWFwKGtleSA9PiAoeyBoZWFkZXI6IGtleSwga2V5IH0pKTtcblxuICBjb25zdCBjb2xXaWR0aHM6IG51bWJlcltdID0gY29scy5tYXAoY29sID0+IHtcbiAgICBpZiAoY29sLndpZHRoKSByZXR1cm4gY29sLndpZHRoO1xuICAgIGNvbnN0IGhlYWRlcldpZHRoID0gY29sLmhlYWRlci5sZW5ndGg7XG4gICAgY29uc3QgZGF0YVdpZHRoID0gTWF0aC5tYXgoLi4uZGF0YS5tYXAoaXRlbSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbC5mb3JtYXR0ZXJcbiAgICAgICAgPyBjb2wuZm9ybWF0dGVyKChpdGVtIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtjb2wua2V5XSlcbiAgICAgICAgOiBTdHJpbmcoKGl0ZW0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NvbC5rZXldID8/ICcnKTtcbiAgICAgIHJldHVybiB2YWx1ZS5sZW5ndGg7XG4gICAgfSkpO1xuICAgIHJldHVybiBNYXRoLm1heChoZWFkZXJXaWR0aCwgZGF0YVdpZHRoLCAzKTtcbiAgfSk7XG5cbiAgY29uc3QgeyBib3JkZXIgfSA9IFRBQkxFX09QVElPTlM7XG5cbiAgY29uc3QgaG9yaXpvbnRhbExpbmUgPSAobGVmdDogc3RyaW5nLCBtaWRkbGU6IHN0cmluZywgcmlnaHQ6IHN0cmluZykgPT5cbiAgICBsZWZ0ICsgY29sV2lkdGhzLm1hcCh3ID0+IGJvcmRlci5ib2R5Sm9pbi5yZXBlYXQoKHcgPz8gMCkgKyAyKSkuam9pbihtaWRkbGUpICsgcmlnaHQ7XG5cbiAgY29uc3QgdG9wTGluZSA9IGhvcml6b250YWxMaW5lKGJvcmRlci50b3BMZWZ0LCBib3JkZXIudG9wSm9pbiwgYm9yZGVyLnRvcFJpZ2h0KTtcbiAgY29uc3QgbWlkTGluZSA9IGhvcml6b250YWxMaW5lKGJvcmRlci5qb2luTGVmdCwgYm9yZGVyLmpvaW5Kb2luLCBib3JkZXIuam9pblJpZ2h0KTtcbiAgY29uc3QgYm90dG9tTGluZSA9IGhvcml6b250YWxMaW5lKGJvcmRlci5ib3R0b21MZWZ0LCBib3JkZXIuYm90dG9tSm9pbiwgYm9yZGVyLmJvdHRvbVJpZ2h0KTtcblxuICBjb25zdCBmb3JtYXRDZWxsID0gKHZhbHVlOiBzdHJpbmcsIHdpZHRoOiBudW1iZXIsIGFsaWduOiAnbGVmdCcgfCAnY2VudGVyJyB8ICdyaWdodCcgPSAnbGVmdCcpOiBzdHJpbmcgPT4ge1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPiB3aWR0aCkgcmV0dXJuIHZhbHVlLnN1YnN0cmluZygwLCB3aWR0aCAtIDMpICsgJy4uLic7XG4gICAgaWYgKGFsaWduID09PSAnY2VudGVyJykge1xuICAgICAgY29uc3QgbGVmdFBhZCA9IE1hdGguZmxvb3IoKHdpZHRoIC0gdmFsdWUubGVuZ3RoKSAvIDIpO1xuICAgICAgcmV0dXJuICcgJy5yZXBlYXQobGVmdFBhZCkgKyB2YWx1ZSArICcgJy5yZXBlYXQod2lkdGggLSB2YWx1ZS5sZW5ndGggLSBsZWZ0UGFkKTtcbiAgICB9XG4gICAgcmV0dXJuIGFsaWduID09PSAncmlnaHQnID8gdmFsdWUucGFkU3RhcnQod2lkdGgpIDogdmFsdWUucGFkRW5kKHdpZHRoKTtcbiAgfTtcblxuICBjb25zdCBoZWFkZXJSb3cgPSBib3JkZXIuYm9keUxlZnQgKyAnICcgK1xuICAgIGNvbHMubWFwKChjb2wsIGkpID0+IGN5YW4oYm9sZChmb3JtYXRDZWxsKGNvbC5oZWFkZXIsIGNvbFdpZHRoc1tpXSA/PyAwKSkpKS5qb2luKGAgJHtib3JkZXIuYm9keUpvaW59IGApICtcbiAgICBgICR7Ym9yZGVyLmJvZHlSaWdodH1gO1xuXG4gIGxldCB0YWJsZSA9IGN5YW4odG9wTGluZSkgKyAnXFxuJyArIGhlYWRlclJvdyArICdcXG4nICsgY3lhbihtaWRMaW5lKSArICdcXG4nO1xuXG4gIGRhdGEuZm9yRWFjaChpdGVtID0+IHtcbiAgICBjb25zdCByb3cgPSBib3JkZXIuYm9keUxlZnQgKyAnICcgK1xuICAgICAgY29scy5tYXAoKGNvbCwgaSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbC5mb3JtYXR0ZXJcbiAgICAgICAgICA/IGNvbC5mb3JtYXR0ZXIoKGl0ZW0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2NvbC5rZXldKVxuICAgICAgICAgIDogU3RyaW5nKChpdGVtIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtjb2wua2V5XSA/PyAnJyk7XG4gICAgICAgIHJldHVybiBmb3JtYXRDZWxsKHZhbHVlLCBjb2xXaWR0aHNbaV0gPz8gMCwgY29sLmFsaWduKTtcbiAgICAgIH0pLmpvaW4oYCAke2JvcmRlci5ib2R5Sm9pbn0gYCkgK1xuICAgICAgYCAke2JvcmRlci5ib2R5UmlnaHR9YDtcbiAgICB0YWJsZSArPSByb3cgKyAnXFxuJztcbiAgfSk7XG5cbiAgdGFibGUgKz0gY3lhbihib3R0b21MaW5lKTtcbiAgcmV0dXJuIHRhYmxlO1xufVxuXG4vLyAtLS0gQ1NWIGZvcm1hdHRpbmcgLS0tXG5cbmZ1bmN0aW9uIGZvcm1hdENzdihkYXRhOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpIHx8IGRhdGEubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gIGNvbnN0IGZpcnN0SXRlbSA9IGRhdGFbMF07XG4gIGlmICh0eXBlb2YgZmlyc3RJdGVtICE9PSAnb2JqZWN0JyB8fCBmaXJzdEl0ZW0gPT09IG51bGwpIHJldHVybiBkYXRhLmpvaW4oJywnKTtcblxuICBjb25zdCBoZWFkZXJzID0gT2JqZWN0LmtleXMoZmlyc3RJdGVtKTtcbiAgY29uc3Qgcm93czogc3RyaW5nW10gPSBbaGVhZGVycy5tYXAoaCA9PiBlc2NhcGVDc3ZWYWx1ZShoKSkuam9pbignLCcpXTtcbiAgZGF0YS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgIHJvd3MucHVzaChoZWFkZXJzLm1hcChoID0+IGVzY2FwZUNzdlZhbHVlKChpdGVtIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtoXSkpLmpvaW4oJywnKSk7XG4gIH0pO1xuICByZXR1cm4gcm93cy5qb2luKCdcXG4nKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlQ3N2VmFsdWUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuICcnO1xuICBjb25zdCBzdHIgPSBTdHJpbmcodmFsdWUpO1xuICBpZiAoc3RyLmluY2x1ZGVzKCcsJykgfHwgc3RyLmluY2x1ZGVzKCdcIicpIHx8IHN0ci5pbmNsdWRlcygnXFxuJykpIHtcbiAgICByZXR1cm4gYFwiJHtzdHIucmVwbGFjZSgvXCIvZywgJ1wiXCInKX1cImA7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuLy8gLS0tIEZpbGUgb3BlcmF0aW9ucyAtLS1cblxuLyoqXG4gKiBWYWxpZGF0ZSB0aGF0IGEgZmlsZSBwYXRoIHJlc29sdmVzIHdpdGhpbiB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS5cbiAqIFByZXZlbnRzIHBhdGggdHJhdmVyc2FsIGF0dGFja3MgKGUuZy4sIC0tb3V0cHV0IC4uLy4uL2V0Yy9wYXNzd2QpLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZU91dHB1dFBhdGgoZmlsZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJlc29sdmVkID0gcGF0aC5yZXNvbHZlKGZpbGVQYXRoKTtcbiAgY29uc3QgY3dkID0gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCkpO1xuICBpZiAoIXJlc29sdmVkLnN0YXJ0c1dpdGgoY3dkICsgcGF0aC5zZXApICYmIHJlc29sdmVkICE9PSBjd2QpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFBhdGggdHJhdmVyc2FsIHJlamVjdGVkOiBcIiR7ZmlsZVBhdGh9XCIgcmVzb2x2ZXMgb3V0c2lkZSB0aGUgY3VycmVudCBkaXJlY3RvcnlgKTtcbiAgfVxuICByZXR1cm4gcmVzb2x2ZWQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlVG9GaWxlKGZpbGVQYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZywgZm9ybWF0OiBPdXRwdXRGb3JtYXQsIGFwcGVuZDogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgY29uc3Qgc2FmZVBhdGggPSB2YWxpZGF0ZU91dHB1dFBhdGgoZmlsZVBhdGgpO1xuICAgIGNvbnN0IGRpciA9IHBhdGguZGlybmFtZShzYWZlUGF0aCk7XG4gICAgaWYgKGRpciAhPT0gJy4nKSBlbnN1cmVPdXRwdXREaXJlY3RvcnkoZGlyKTtcblxuICAgIGlmIChhcHBlbmQpIHtcbiAgICAgIGZzLmFwcGVuZEZpbGVTeW5jKHNhZmVQYXRoLCBjb250ZW50ICsgJ1xcbicsICd1dGYtOCcpO1xuICAgICAgcHJpbnRTdWNjZXNzKCdPdXRwdXQgYXBwZW5kZWQgdG8gZmlsZScsIHsgcGF0aDogc2FmZVBhdGgsIGZvcm1hdCB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhzYWZlUGF0aCwgY29udGVudCwgJ3V0Zi04Jyk7XG4gICAgICBjb25zdCBzdGF0cyA9IGZzLnN0YXRTeW5jKHNhZmVQYXRoKTtcbiAgICAgIHByaW50U3VjY2VzcygnT3V0cHV0IHNhdmVkIHRvIGZpbGUnLCB7IHBhdGg6IHNhZmVQYXRoLCBmb3JtYXQsIHNpemU6IGZvcm1hdEZpbGVTaXplKHN0YXRzLnNpemUpIH0pO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBwcmludEVycm9yKCdGYWlsZWQgdG8gd3JpdGUgZmlsZScsIHtcbiAgICAgIHBhdGg6IGZpbGVQYXRoLFxuICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICB9KTtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlT3V0cHV0RGlyZWN0b3J5KG91dHB1dFBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBpZiAoZnMuZXhpc3RzU3luYyhvdXRwdXRQYXRoKSkgcmV0dXJuO1xuICB0cnkge1xuICAgIGZzLm1rZGlyU3luYyhvdXRwdXRQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBwcmludERlYnVnKCdEaXJlY3RvcnkgY3JlYXRlZCcsIHsgcGF0aDogb3V0cHV0UGF0aCB9KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBwcmludEVycm9yKCdGYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeScsIHtcbiAgICAgIHBhdGg6IG91dHB1dFBhdGgsXG4gICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgIH0pO1xuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaWxlRXhpc3RzKGZpbGVQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpO1xufVxuXG4vLyAtLS0gRGlzcGxheSBoZWxwZXJzIC0tLVxuXG5leHBvcnQgZnVuY3Rpb24gcHJpbnRTZWN0aW9uKHRpdGxlOiBzdHJpbmcsIHN1YnRpdGxlPzogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IHdpZHRoID0gcHJvY2Vzcy5zdGRvdXQuY29sdW1ucyB8fCA4MDtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZyhjeWFuKCfilZAnLnJlcGVhdCh3aWR0aCkpKTtcbiAgY29uc29sZS5sb2coY3lhbihib2xkKHRpdGxlKSkpO1xuICBpZiAoc3VidGl0bGUpIGNvbnNvbGUubG9nKGRpbShzdWJ0aXRsZSkpO1xuICBjb25zb2xlLmxvZyhjeWFuKCfilZAnLnJlcGVhdCh3aWR0aCkpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByaW50S2V5VmFsdWUoXG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvcHRpb25zOiB7IGluZGVudD86IG51bWJlcjsgc2VwYXJhdG9yPzogc3RyaW5nIH0gPSB7fSxcbik6IHZvaWQge1xuICBjb25zdCB7IGluZGVudCA9IDAsIHNlcGFyYXRvciA9ICfilIInIH0gPSBvcHRpb25zO1xuICBjb25zdCBtYXhLZXlMZW5ndGggPSBNYXRoLm1heCguLi5PYmplY3Qua2V5cyhkYXRhKS5tYXAoayA9PiBrLmxlbmd0aCkpO1xuICBjb25zdCBpbmRlbnRTdHIgPSAnICcucmVwZWF0KGluZGVudCk7XG5cbiAgT2JqZWN0LmVudHJpZXMoZGF0YSkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgY29uc3QgcGFkZGVkS2V5ID0ga2V5LnBhZEVuZChtYXhLZXlMZW5ndGgpO1xuICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbFxuICAgICAgPyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgOiBTdHJpbmcodmFsdWUpO1xuICAgIGNvbnNvbGUubG9nKGAke2luZGVudFN0cn0ke2RpbShwYWRkZWRLZXkpfSAke2N5YW4oc2VwYXJhdG9yKX0gJHt3aGl0ZShmb3JtYXR0ZWRWYWx1ZSl9YCk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJpbnREaXZpZGVyKGNoYXI6IHN0cmluZyA9ICfilIAnLCB3aWR0aD86IG51bWJlcik6IHZvaWQge1xuICBjb25zdCBlZmZlY3RpdmVXaWR0aCA9IHdpZHRoIHx8IHByb2Nlc3Muc3Rkb3V0LmNvbHVtbnMgfHwgODA7XG4gIGNvbnNvbGUubG9nKGRpbShjaGFyLnJlcGVhdChlZmZlY3RpdmVXaWR0aCkpKTtcbn1cblxuLy8gLS0tIFJlc3BvbnNlIHBhcnNpbmcgLS0tXG5cbi8qKlxuICogVW53cmFwIGEgc2VuZFN1Y2Nlc3MgQVBJIGVudmVsb3BlOiB7IHN1Y2Nlc3MsIHN0YXR1c0NvZGUsIGRhdGE6IHsgLi4uIH0gfVxuICogUmV0dXJucyB0aGUgaW5uZXIgYGRhdGFgIG9iamVjdCwgb3IgdGhlIG9yaWdpbmFsIHJlc3BvbnNlIGlmIG5vdCB3cmFwcGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW53cmFwRW52ZWxvcGUocmVzcG9uc2U6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChyZXNwb25zZSAmJiB0eXBlb2YgcmVzcG9uc2UgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3Qgb2JqID0gcmVzcG9uc2UgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgaWYgKCdzdWNjZXNzJyBpbiBvYmogJiYgJ2RhdGEnIGluIG9iaiAmJiBvYmouZGF0YSAmJiB0eXBlb2Ygb2JqLmRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gb2JqLmRhdGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH1cbiAgcmV0dXJuIHt9O1xufVxuXG4vKipcbiAqIEV4dHJhY3QgYSBzaW5nbGUgZW50aXR5IGZyb20gYW4gQVBJIHJlc3BvbnNlLCBoYW5kbGluZyBlbnZlbG9wZSBmb3JtYXRzLlxuICogVHJpZXM6IHBheWxvYWRbZW50aXR5S2V5XSwgcGF5bG9hZCBkaXJlY3RseSAoaWYgaWRlbnRpZmllcktleSBleGlzdHMpLCBvciB1bmRlZmluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0U2luZ2xlUmVzcG9uc2U8VD4ocmVzcG9uc2U6IHVua25vd24sIGVudGl0eUtleTogc3RyaW5nLCBpZGVudGlmaWVyS2V5OiBzdHJpbmcpOiBUIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGF5bG9hZCA9IHVud3JhcEVudmVsb3BlKHJlc3BvbnNlKTtcbiAgLy8gRGlyZWN0IGVudGl0eTogcGF5bG9hZCBoYXMgdGhlIGlkZW50aWZpZXIgKGUuZy4gcGF5bG9hZC5pZCwgcGF5bG9hZC5wcm9wcywgcGF5bG9hZC5uYW1lKVxuICBpZiAoaWRlbnRpZmllcktleSBpbiBwYXlsb2FkKSByZXR1cm4gcGF5bG9hZCBhcyB1bmtub3duIGFzIFQ7XG4gIC8vIE5lc3RlZCB1bmRlciBlbnRpdHkga2V5OiBwYXlsb2FkLnBpcGVsaW5lLCBwYXlsb2FkLnBsdWdpblxuICBjb25zdCBuZXN0ZWQgPSBwYXlsb2FkW2VudGl0eUtleV0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQ7XG4gIGlmIChuZXN0ZWQgJiYgdHlwZW9mIG5lc3RlZCA9PT0gJ29iamVjdCcgJiYgaWRlbnRpZmllcktleSBpbiBuZXN0ZWQpIHJldHVybiBuZXN0ZWQgYXMgdW5rbm93biBhcyBUO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RSZXNwb25zZVJlc3VsdDxUPiB7XG4gIGl0ZW1zOiBUW107XG4gIHRvdGFsPzogbnVtYmVyO1xuICBoYXNNb3JlOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEV4dHJhY3QgaXRlbXMgZnJvbSBhbiBBUEkgbGlzdCByZXNwb25zZSwgaGFuZGxpbmcgbXVsdGlwbGUgcmVzcG9uc2UgZm9ybWF0cy5cbiAqIFN1cHBvcnRzOiBgeyA8a2V5PjogVFtdIH1gLCBgeyBpdGVtczogVFtdIH1gLCBgVFtdYCwgb3IgaW52YWxpZCBmb3JtYXRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdExpc3RSZXNwb25zZTxUPihyZXNwb25zZTogdW5rbm93biwgaXRlbXNLZXk6IHN0cmluZyk6IExpc3RSZXNwb25zZVJlc3VsdDxUPiB7XG4gIGlmIChBcnJheS5pc0FycmF5KHJlc3BvbnNlKSkge1xuICAgIHJldHVybiB7IGl0ZW1zOiByZXNwb25zZSwgdG90YWw6IHVuZGVmaW5lZCwgaGFzTW9yZTogZmFsc2UgfTtcbiAgfVxuXG4gIGlmIChyZXNwb25zZSAmJiB0eXBlb2YgcmVzcG9uc2UgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3Qgb2JqID0gdW53cmFwRW52ZWxvcGUocmVzcG9uc2UpO1xuXG4gICAgLy8gRXh0cmFjdCBwYWdpbmF0aW9uIG1ldGFkYXRhIGlmIHByZXNlbnRcbiAgICBjb25zdCBwYWdpbmF0aW9uID0gb2JqLnBhZ2luYXRpb24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgdG90YWwgPSAocGFnaW5hdGlvbj8udG90YWwgPz8gb2JqLnRvdGFsKSBhcyBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgaGFzTW9yZSA9ICgocGFnaW5hdGlvbj8uaGFzTW9yZSA/PyBvYmouaGFzTW9yZSkgYXMgYm9vbGVhbikgfHwgZmFsc2U7XG5cbiAgICAvLyBUcnkgcHJpbWFyeSBrZXkgKGUuZy4gJ3BpcGVsaW5lcycsICdwbHVnaW5zJylcbiAgICBpZiAoaXRlbXNLZXkgaW4gb2JqICYmIEFycmF5LmlzQXJyYXkob2JqW2l0ZW1zS2V5XSkpIHtcbiAgICAgIHJldHVybiB7IGl0ZW1zOiBvYmpbaXRlbXNLZXldIGFzIFRbXSwgdG90YWwsIGhhc01vcmUgfTtcbiAgICB9XG5cbiAgICAvLyBUcnkgZ2VuZXJpYyAnaXRlbXMnIGtleVxuICAgIGlmICgnaXRlbXMnIGluIG9iaiAmJiBBcnJheS5pc0FycmF5KG9iai5pdGVtcykpIHtcbiAgICAgIHJldHVybiB7IGl0ZW1zOiBvYmouaXRlbXMgYXMgVFtdLCB0b3RhbCwgaGFzTW9yZSB9O1xuICAgIH1cblxuICAgIHByaW50V2FybmluZygnVW5leHBlY3RlZCByZXNwb25zZSBmb3JtYXQsIGF0dGVtcHRpbmcgdG8gaGFuZGxlJyk7XG4gICAgcmV0dXJuIHsgaXRlbXM6IFtdLCB0b3RhbDogdW5kZWZpbmVkLCBoYXNNb3JlOiBmYWxzZSB9O1xuICB9XG5cbiAgcHJpbnRFcnJvcignSW52YWxpZCByZXNwb25zZSBmb3JtYXQgZnJvbSBBUEknKTtcbiAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIEFQSSByZXNwb25zZSBmb3JtYXQnKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if auth attempts are currently rate-limited.
|
|
3
|
+
* @returns null if allowed, or a message string if blocked.
|
|
4
|
+
*/
|
|
5
|
+
export declare function checkAuthRateLimit(): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Record a successful auth — resets the failure counter.
|
|
8
|
+
*/
|
|
9
|
+
export declare function recordAuthSuccess(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Record a failed auth attempt. After MAX_FAILURES, locks out for COOLDOWN_MS.
|
|
12
|
+
*/
|
|
13
|
+
export declare function recordAuthFailure(): void;
|
|
14
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/utils/rate-limiter.ts"],"names":[],"mappings":"AAsCA;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAelD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAWxC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
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.checkAuthRateLimit = checkAuthRateLimit;
|
|
9
|
+
exports.recordAuthSuccess = recordAuthSuccess;
|
|
10
|
+
exports.recordAuthFailure = recordAuthFailure;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
/**
|
|
15
|
+
* Simple file-based rate limiter for auth operations.
|
|
16
|
+
* Tracks failed attempts and enforces a cooldown period after too many failures.
|
|
17
|
+
* State is persisted in a temp file so it survives across CLI invocations.
|
|
18
|
+
*/
|
|
19
|
+
const STATE_FILE = path_1.default.join(os_1.default.tmpdir(), '.pipeline-manager-auth-state.json');
|
|
20
|
+
const MAX_FAILURES = 5;
|
|
21
|
+
const COOLDOWN_MS = 60_000; // 1 minute
|
|
22
|
+
function readState() {
|
|
23
|
+
try {
|
|
24
|
+
if (fs_1.default.existsSync(STATE_FILE)) {
|
|
25
|
+
return JSON.parse(fs_1.default.readFileSync(STATE_FILE, 'utf-8'));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch { /* ignore corrupt state */ }
|
|
29
|
+
return { failures: 0, lastFailure: 0, lockedUntil: 0 };
|
|
30
|
+
}
|
|
31
|
+
function writeState(state) {
|
|
32
|
+
try {
|
|
33
|
+
fs_1.default.writeFileSync(STATE_FILE, JSON.stringify(state), { mode: 0o600 });
|
|
34
|
+
}
|
|
35
|
+
catch { /* best-effort */ }
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check if auth attempts are currently rate-limited.
|
|
39
|
+
* @returns null if allowed, or a message string if blocked.
|
|
40
|
+
*/
|
|
41
|
+
function checkAuthRateLimit() {
|
|
42
|
+
const state = readState();
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
if (state.lockedUntil > now) {
|
|
45
|
+
const waitSec = Math.ceil((state.lockedUntil - now) / 1000);
|
|
46
|
+
return `Too many failed login attempts. Try again in ${waitSec}s.`;
|
|
47
|
+
}
|
|
48
|
+
// Reset if cooldown has passed
|
|
49
|
+
if (now - state.lastFailure > COOLDOWN_MS) {
|
|
50
|
+
writeState({ failures: 0, lastFailure: 0, lockedUntil: 0 });
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Record a successful auth — resets the failure counter.
|
|
56
|
+
*/
|
|
57
|
+
function recordAuthSuccess() {
|
|
58
|
+
writeState({ failures: 0, lastFailure: 0, lockedUntil: 0 });
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Record a failed auth attempt. After MAX_FAILURES, locks out for COOLDOWN_MS.
|
|
62
|
+
*/
|
|
63
|
+
function recordAuthFailure() {
|
|
64
|
+
const state = readState();
|
|
65
|
+
const now = Date.now();
|
|
66
|
+
state.failures += 1;
|
|
67
|
+
state.lastFailure = now;
|
|
68
|
+
if (state.failures >= MAX_FAILURES) {
|
|
69
|
+
state.lockedUntil = now + COOLDOWN_MS;
|
|
70
|
+
}
|
|
71
|
+
writeState(state);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0ZS1saW1pdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3JhdGUtbGltaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7Ozs7QUF5Q3RDLGdEQWVDO0FBS0QsOENBRUM7QUFLRCw4Q0FXQztBQTdFRCw0Q0FBb0I7QUFDcEIsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUV4Qjs7OztHQUlHO0FBRUgsTUFBTSxVQUFVLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxZQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsbUNBQW1DLENBQUMsQ0FBQztBQUMvRSxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDdkIsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLENBQUMsV0FBVztBQVF2QyxTQUFTLFNBQVM7SUFDaEIsSUFBSSxDQUFDO1FBQ0gsSUFBSSxZQUFFLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDOUIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFjLENBQUM7UUFDdkUsQ0FBQztJQUNILENBQUM7SUFBQyxNQUFNLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0lBQ3RDLE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBQ3pELENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxLQUFnQjtJQUNsQyxJQUFJLENBQUM7UUFDSCxZQUFFLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDdkUsQ0FBQztJQUFDLE1BQU0sQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLGtCQUFrQjtJQUNoQyxNQUFNLEtBQUssR0FBRyxTQUFTLEVBQUUsQ0FBQztJQUMxQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFFdkIsSUFBSSxLQUFLLENBQUMsV0FBVyxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQzVCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQzVELE9BQU8sZ0RBQWdELE9BQU8sSUFBSSxDQUFDO0lBQ3JFLENBQUM7SUFFRCwrQkFBK0I7SUFDL0IsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLFdBQVcsR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUMxQyxVQUFVLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsaUJBQWlCO0lBQy9CLFVBQVUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixpQkFBaUI7SUFDL0IsTUFBTSxLQUFLLEdBQUcsU0FBUyxFQUFFLENBQUM7SUFDMUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3ZCLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDO0lBQ3BCLEtBQUssQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDO0lBRXhCLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNuQyxLQUFLLENBQUMsV0FBVyxHQUFHLEdBQUcsR0FBRyxXQUFXLENBQUM7SUFDeEMsQ0FBQztJQUVELFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNwQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5cbi8qKlxuICogU2ltcGxlIGZpbGUtYmFzZWQgcmF0ZSBsaW1pdGVyIGZvciBhdXRoIG9wZXJhdGlvbnMuXG4gKiBUcmFja3MgZmFpbGVkIGF0dGVtcHRzIGFuZCBlbmZvcmNlcyBhIGNvb2xkb3duIHBlcmlvZCBhZnRlciB0b28gbWFueSBmYWlsdXJlcy5cbiAqIFN0YXRlIGlzIHBlcnNpc3RlZCBpbiBhIHRlbXAgZmlsZSBzbyBpdCBzdXJ2aXZlcyBhY3Jvc3MgQ0xJIGludm9jYXRpb25zLlxuICovXG5cbmNvbnN0IFNUQVRFX0ZJTEUgPSBwYXRoLmpvaW4ob3MudG1wZGlyKCksICcucGlwZWxpbmUtbWFuYWdlci1hdXRoLXN0YXRlLmpzb24nKTtcbmNvbnN0IE1BWF9GQUlMVVJFUyA9IDU7XG5jb25zdCBDT09MRE9XTl9NUyA9IDYwXzAwMDsgLy8gMSBtaW51dGVcblxuaW50ZXJmYWNlIEF1dGhTdGF0ZSB7XG4gIGZhaWx1cmVzOiBudW1iZXI7XG4gIGxhc3RGYWlsdXJlOiBudW1iZXI7XG4gIGxvY2tlZFVudGlsOiBudW1iZXI7XG59XG5cbmZ1bmN0aW9uIHJlYWRTdGF0ZSgpOiBBdXRoU3RhdGUge1xuICB0cnkge1xuICAgIGlmIChmcy5leGlzdHNTeW5jKFNUQVRFX0ZJTEUpKSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoU1RBVEVfRklMRSwgJ3V0Zi04JykpIGFzIEF1dGhTdGF0ZTtcbiAgICB9XG4gIH0gY2F0Y2ggeyAvKiBpZ25vcmUgY29ycnVwdCBzdGF0ZSAqLyB9XG4gIHJldHVybiB7IGZhaWx1cmVzOiAwLCBsYXN0RmFpbHVyZTogMCwgbG9ja2VkVW50aWw6IDAgfTtcbn1cblxuZnVuY3Rpb24gd3JpdGVTdGF0ZShzdGF0ZTogQXV0aFN0YXRlKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgZnMud3JpdGVGaWxlU3luYyhTVEFURV9GSUxFLCBKU09OLnN0cmluZ2lmeShzdGF0ZSksIHsgbW9kZTogMG82MDAgfSk7XG4gIH0gY2F0Y2ggeyAvKiBiZXN0LWVmZm9ydCAqLyB9XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYXV0aCBhdHRlbXB0cyBhcmUgY3VycmVudGx5IHJhdGUtbGltaXRlZC5cbiAqIEByZXR1cm5zIG51bGwgaWYgYWxsb3dlZCwgb3IgYSBtZXNzYWdlIHN0cmluZyBpZiBibG9ja2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tBdXRoUmF0ZUxpbWl0KCk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBzdGF0ZSA9IHJlYWRTdGF0ZSgpO1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuXG4gIGlmIChzdGF0ZS5sb2NrZWRVbnRpbCA+IG5vdykge1xuICAgIGNvbnN0IHdhaXRTZWMgPSBNYXRoLmNlaWwoKHN0YXRlLmxvY2tlZFVudGlsIC0gbm93KSAvIDEwMDApO1xuICAgIHJldHVybiBgVG9vIG1hbnkgZmFpbGVkIGxvZ2luIGF0dGVtcHRzLiBUcnkgYWdhaW4gaW4gJHt3YWl0U2VjfXMuYDtcbiAgfVxuXG4gIC8vIFJlc2V0IGlmIGNvb2xkb3duIGhhcyBwYXNzZWRcbiAgaWYgKG5vdyAtIHN0YXRlLmxhc3RGYWlsdXJlID4gQ09PTERPV05fTVMpIHtcbiAgICB3cml0ZVN0YXRlKHsgZmFpbHVyZXM6IDAsIGxhc3RGYWlsdXJlOiAwLCBsb2NrZWRVbnRpbDogMCB9KTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFJlY29yZCBhIHN1Y2Nlc3NmdWwgYXV0aCDigJQgcmVzZXRzIHRoZSBmYWlsdXJlIGNvdW50ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBdXRoU3VjY2VzcygpOiB2b2lkIHtcbiAgd3JpdGVTdGF0ZSh7IGZhaWx1cmVzOiAwLCBsYXN0RmFpbHVyZTogMCwgbG9ja2VkVW50aWw6IDAgfSk7XG59XG5cbi8qKlxuICogUmVjb3JkIGEgZmFpbGVkIGF1dGggYXR0ZW1wdC4gQWZ0ZXIgTUFYX0ZBSUxVUkVTLCBsb2NrcyBvdXQgZm9yIENPT0xET1dOX01TLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkQXV0aEZhaWx1cmUoKTogdm9pZCB7XG4gIGNvbnN0IHN0YXRlID0gcmVhZFN0YXRlKCk7XG4gIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gIHN0YXRlLmZhaWx1cmVzICs9IDE7XG4gIHN0YXRlLmxhc3RGYWlsdXJlID0gbm93O1xuXG4gIGlmIChzdGF0ZS5mYWlsdXJlcyA+PSBNQVhfRkFJTFVSRVMpIHtcbiAgICBzdGF0ZS5sb2NrZWRVbnRpbCA9IG5vdyArIENPT0xET1dOX01TO1xuICB9XG5cbiAgd3JpdGVTdGF0ZShzdGF0ZSk7XG59XG4iXX0=
|
package/package.json
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pipeline-builder/pipeline-manager",
|
|
3
|
+
"description": "CLI for Pipeline Builder — self-service AWS CodePipeline platform with 124 reusable containerized plugins, per-org compliance enforcement, and multi-tenant isolation.",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/mwashburn160/pipeline-builder.git"
|
|
7
|
+
},
|
|
8
|
+
"bin": {
|
|
9
|
+
"pipeline-manager": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@stylistic/eslint-plugin": "^2",
|
|
13
|
+
"@types/figlet": "1.7.0",
|
|
14
|
+
"@types/jest": "^30.0.0",
|
|
15
|
+
"@types/node": "^24",
|
|
16
|
+
"@types/progress": "2.0.7",
|
|
17
|
+
"@typescript-eslint/eslint-plugin": "^8",
|
|
18
|
+
"@typescript-eslint/parser": "^8",
|
|
19
|
+
"copyfiles": "2.4.1",
|
|
20
|
+
"eslint": "^9",
|
|
21
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
22
|
+
"eslint-plugin-import": "^2.32.0",
|
|
23
|
+
"jest": "^30.2.0",
|
|
24
|
+
"jest-junit": "^16",
|
|
25
|
+
"ts-jest": "^29.4.6",
|
|
26
|
+
"typescript": "5.9.3"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@aws-sdk/client-cloudformation": "3.821.0",
|
|
30
|
+
"@aws-sdk/client-lambda": "3.821.0",
|
|
31
|
+
"@aws-sdk/client-secrets-manager": "3.821.0",
|
|
32
|
+
"@aws-sdk/client-sts": "3.821.0",
|
|
33
|
+
"aws-cdk-lib": "2.240.0",
|
|
34
|
+
"axios": "1.13.5",
|
|
35
|
+
"commander": "14.0.3",
|
|
36
|
+
"figlet": "1.10.0",
|
|
37
|
+
"form-data": "4.0.5",
|
|
38
|
+
"ora": "9.3.0",
|
|
39
|
+
"picocolors": "1.1.1",
|
|
40
|
+
"progress": "2.0.3",
|
|
41
|
+
"typescript": "5.9.3",
|
|
42
|
+
"yaml": "2.8.2",
|
|
43
|
+
"@pipeline-builder/pipeline-core": "3.1.0"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"aws",
|
|
47
|
+
"codepipeline",
|
|
48
|
+
"codebuild",
|
|
49
|
+
"cicd",
|
|
50
|
+
"ci-cd",
|
|
51
|
+
"devops",
|
|
52
|
+
"cdk",
|
|
53
|
+
"aws-cdk",
|
|
54
|
+
"cloudformation",
|
|
55
|
+
"pipeline",
|
|
56
|
+
"pipeline-as-code",
|
|
57
|
+
"containerized",
|
|
58
|
+
"docker",
|
|
59
|
+
"kubernetes",
|
|
60
|
+
"plugins",
|
|
61
|
+
"typescript",
|
|
62
|
+
"self-service",
|
|
63
|
+
"multi-tenant",
|
|
64
|
+
"compliance",
|
|
65
|
+
"automation",
|
|
66
|
+
"infrastructure-as-code",
|
|
67
|
+
"iac",
|
|
68
|
+
"cli"
|
|
69
|
+
],
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">= 24.14.0"
|
|
72
|
+
},
|
|
73
|
+
"license": "Apache-2.0",
|
|
74
|
+
"homepage": "https://mwashburn160.github.io/pipeline-builder/",
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public",
|
|
77
|
+
"registry": "https://registry.npmjs.org/"
|
|
78
|
+
},
|
|
79
|
+
"version": "3.1.0",
|
|
80
|
+
"bugs": {
|
|
81
|
+
"url": "https://github.com/mwashburn160/pipeline-builder/issues"
|
|
82
|
+
},
|
|
83
|
+
"jest": {
|
|
84
|
+
"coverageProvider": "v8",
|
|
85
|
+
"testMatch": [
|
|
86
|
+
"<rootDir>/@(src|test)/**/*(*.)@(spec|test).[jt]s?(x)",
|
|
87
|
+
"<rootDir>/@(src|test)/**/__tests__/**/*.[jt]s?(x)"
|
|
88
|
+
],
|
|
89
|
+
"clearMocks": true,
|
|
90
|
+
"collectCoverage": true,
|
|
91
|
+
"coverageReporters": [
|
|
92
|
+
"json",
|
|
93
|
+
"lcov",
|
|
94
|
+
"clover",
|
|
95
|
+
"cobertura",
|
|
96
|
+
"text"
|
|
97
|
+
],
|
|
98
|
+
"coverageDirectory": "coverage",
|
|
99
|
+
"coveragePathIgnorePatterns": [
|
|
100
|
+
"/node_modules/"
|
|
101
|
+
],
|
|
102
|
+
"testPathIgnorePatterns": [
|
|
103
|
+
"/node_modules/"
|
|
104
|
+
],
|
|
105
|
+
"watchPathIgnorePatterns": [
|
|
106
|
+
"/node_modules/"
|
|
107
|
+
],
|
|
108
|
+
"reporters": [
|
|
109
|
+
"default",
|
|
110
|
+
[
|
|
111
|
+
"jest-junit",
|
|
112
|
+
{
|
|
113
|
+
"outputDirectory": "test-reports"
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
],
|
|
117
|
+
"transform": {
|
|
118
|
+
"^.+\\.[t]sx?$": [
|
|
119
|
+
"ts-jest",
|
|
120
|
+
{
|
|
121
|
+
"tsconfig": "tsconfig.dev.json"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"moduleNameMapper": {
|
|
126
|
+
"^uuid$": "<rootDir>/../../jest-uuid-stub.js"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"pnpm dlx projen\".",
|
|
130
|
+
"scripts": {
|
|
131
|
+
"audit": "pnpm dlx projen audit",
|
|
132
|
+
"build": "pnpm dlx projen build",
|
|
133
|
+
"compile": "pnpm dlx projen compile",
|
|
134
|
+
"default": "pnpm dlx projen default",
|
|
135
|
+
"eslint": "pnpm dlx projen eslint",
|
|
136
|
+
"package": "pnpm dlx projen package",
|
|
137
|
+
"post-compile": "pnpm dlx projen post-compile",
|
|
138
|
+
"pre-compile": "pnpm dlx projen pre-compile",
|
|
139
|
+
"test": "pnpm dlx projen test",
|
|
140
|
+
"test:watch": "pnpm dlx projen test:watch",
|
|
141
|
+
"watch": "pnpm dlx projen watch",
|
|
142
|
+
"projen": "pnpm dlx projen"
|
|
143
|
+
}
|
|
144
|
+
}
|