@pipeline-builder/pipeline-core 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +32 -0
- package/lib/config/app-config.d.ts +81 -0
- package/lib/config/app-config.js +151 -0
- package/lib/config/billing-config.d.ts +17 -0
- package/lib/config/billing-config.js +95 -0
- package/lib/config/config-types.d.ts +213 -0
- package/lib/config/config-types.js +5 -0
- package/lib/config/infrastructure-config.d.ts +55 -0
- package/lib/config/infrastructure-config.js +200 -0
- package/lib/config/server-config.d.ts +53 -0
- package/lib/config/server-config.js +180 -0
- package/lib/core/artifact-manager.d.ts +62 -0
- package/lib/core/artifact-manager.js +86 -0
- package/lib/core/id-generator.d.ts +26 -0
- package/lib/core/id-generator.js +44 -0
- package/lib/core/metadata-builder.d.ts +13 -0
- package/lib/core/metadata-builder.js +81 -0
- package/lib/core/network-types.d.ts +200 -0
- package/lib/core/network-types.js +5 -0
- package/lib/core/network.d.ts +20 -0
- package/lib/core/network.js +84 -0
- package/lib/core/pipeline-helpers.d.ts +53 -0
- package/lib/core/pipeline-helpers.js +273 -0
- package/lib/core/pipeline-types.d.ts +136 -0
- package/lib/core/pipeline-types.js +140 -0
- package/lib/core/role-types.d.ts +254 -0
- package/lib/core/role-types.js +5 -0
- package/lib/core/role.d.ts +14 -0
- package/lib/core/role.js +118 -0
- package/lib/core/security-group-types.d.ts +84 -0
- package/lib/core/security-group-types.js +5 -0
- package/lib/core/security-group.d.ts +14 -0
- package/lib/core/security-group.js +34 -0
- package/lib/handlers/plugin-lookup-handler.d.ts +32 -0
- package/lib/handlers/plugin-lookup-handler.js +313 -0
- package/lib/handlers/pnpm-lock.yaml +12 -0
- package/lib/index.d.ts +54 -0
- package/lib/index.js +112 -0
- package/lib/pipeline/pipeline-builder.d.ts +82 -0
- package/lib/pipeline/pipeline-builder.js +292 -0
- package/lib/pipeline/pipeline-configuration.d.ts +72 -0
- package/lib/pipeline/pipeline-configuration.js +196 -0
- package/lib/pipeline/plugin-lookup.d.ts +100 -0
- package/lib/pipeline/plugin-lookup.js +247 -0
- package/lib/pipeline/source-builder.d.ts +47 -0
- package/lib/pipeline/source-builder.js +111 -0
- package/lib/pipeline/source-types.d.ts +191 -0
- package/lib/pipeline/source-types.js +5 -0
- package/lib/pipeline/stage-builder.d.ts +71 -0
- package/lib/pipeline/stage-builder.js +118 -0
- package/lib/pipeline/step-types.d.ts +307 -0
- package/lib/pipeline/step-types.js +5 -0
- package/package.json +137 -0
|
@@ -0,0 +1,313 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.handler = void 0;
|
|
39
|
+
exports._resetCredentialsCache = _resetCredentialsCache;
|
|
40
|
+
const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
|
|
41
|
+
const axios_1 = __importStar(require("axios"));
|
|
42
|
+
const app_config_1 = require("../config/app-config");
|
|
43
|
+
/**
|
|
44
|
+
* Structured logger for Lambda (outputs JSON to CloudWatch).
|
|
45
|
+
* Debug messages only emitted when LOG_LEVEL=debug.
|
|
46
|
+
*/
|
|
47
|
+
function logEntry(level, tag, message, data) {
|
|
48
|
+
const line = JSON.stringify({ level, tag, message, data, ts: new Date().toISOString() });
|
|
49
|
+
switch (level) {
|
|
50
|
+
case 'ERROR':
|
|
51
|
+
console.error(line);
|
|
52
|
+
break;
|
|
53
|
+
case 'DEBUG':
|
|
54
|
+
if (process.env.LOG_LEVEL === 'debug')
|
|
55
|
+
console.debug(line);
|
|
56
|
+
break;
|
|
57
|
+
default: console.log(line);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const lambdaLog = {
|
|
61
|
+
info: (tag, message, data) => logEntry('INFO', tag, message, data),
|
|
62
|
+
error: (tag, message, data) => logEntry('ERROR', tag, message, data),
|
|
63
|
+
debug: (tag, message, data) => logEntry('DEBUG', tag, message, data),
|
|
64
|
+
};
|
|
65
|
+
const RETRYABLE_STATUSES = new Set([429, 502, 503, 504]);
|
|
66
|
+
const RETRYABLE_CODES = new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT']);
|
|
67
|
+
function sleep(ms) {
|
|
68
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
69
|
+
}
|
|
70
|
+
/** Platform secret name — injected as PLATFORM_SECRET_NAME env var by PluginLookup construct. */
|
|
71
|
+
const PLATFORM_SECRET_NAME = process.env.PLATFORM_SECRET_NAME;
|
|
72
|
+
if (!PLATFORM_SECRET_NAME) {
|
|
73
|
+
throw new Error('PLATFORM_SECRET_NAME environment variable is required');
|
|
74
|
+
}
|
|
75
|
+
/** Cached token to avoid repeated Secrets Manager calls within a single invocation. */
|
|
76
|
+
let cachedToken = null;
|
|
77
|
+
/** @internal Reset cached token (for testing only). */
|
|
78
|
+
function _resetCredentialsCache() { cachedToken = null; }
|
|
79
|
+
/**
|
|
80
|
+
* Fetch JWT token from AWS Secrets Manager.
|
|
81
|
+
* Caches the result for the lifetime of the Lambda execution context.
|
|
82
|
+
*
|
|
83
|
+
* The secret name is set via PLATFORM_SECRET_NAME env var (e.g. `{prefix}/{orgId}/platform`)
|
|
84
|
+
* Create it with: `pipeline-manager store-token`
|
|
85
|
+
*/
|
|
86
|
+
async function getToken() {
|
|
87
|
+
if (cachedToken)
|
|
88
|
+
return cachedToken;
|
|
89
|
+
lambdaLog.info('AUTH', `Fetching token from Secrets Manager: ${PLATFORM_SECRET_NAME}`);
|
|
90
|
+
const client = new client_secrets_manager_1.SecretsManagerClient({});
|
|
91
|
+
const response = await client.send(new client_secrets_manager_1.GetSecretValueCommand({ SecretId: PLATFORM_SECRET_NAME }));
|
|
92
|
+
if (!response.SecretString) {
|
|
93
|
+
throw new Error(`Secret "${PLATFORM_SECRET_NAME}" is empty`);
|
|
94
|
+
}
|
|
95
|
+
const parsed = JSON.parse(response.SecretString);
|
|
96
|
+
if (!parsed.accessToken) {
|
|
97
|
+
throw new Error(`Secret "${PLATFORM_SECRET_NAME}" missing accessToken — run "pipeline-manager store-token" to generate`);
|
|
98
|
+
}
|
|
99
|
+
cachedToken = parsed.accessToken;
|
|
100
|
+
lambdaLog.info('AUTH', 'Token retrieved from Secrets Manager');
|
|
101
|
+
return cachedToken;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Creates a pre-configured Axios instance for API requests.
|
|
105
|
+
*
|
|
106
|
+
* @param baseURL - Base URL of the target API
|
|
107
|
+
* @param token - JWT token for authorization
|
|
108
|
+
* @returns Configured Axios instance
|
|
109
|
+
*/
|
|
110
|
+
function create(baseURL, token) {
|
|
111
|
+
return axios_1.default.create({
|
|
112
|
+
baseURL,
|
|
113
|
+
timeout: app_config_1.CoreConstants.HANDLER_TIMEOUT_MS,
|
|
114
|
+
headers: {
|
|
115
|
+
'Content-Type': 'application/json',
|
|
116
|
+
'Authorization': `Bearer ${token}`,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Fetches plugin configuration from the external API with retry logic.
|
|
122
|
+
* Retries on transient failures (429, 502, 503, 504, network errors)
|
|
123
|
+
* with exponential backoff.
|
|
124
|
+
*
|
|
125
|
+
* @param api - Configured Axios instance
|
|
126
|
+
* @param pluginFilter - Filter criteria for the plugin lookup
|
|
127
|
+
* @returns The plugin data returned by the API
|
|
128
|
+
* @throws Error on persistent failure, timeout or invalid response
|
|
129
|
+
*/
|
|
130
|
+
async function fetch(api, pluginFilter) {
|
|
131
|
+
lambdaLog.debug('FETCH', 'Starting plugin fetch', { filter: pluginFilter });
|
|
132
|
+
let lastError;
|
|
133
|
+
for (let attempt = 0; attempt <= app_config_1.CoreConstants.HANDLER_MAX_RETRIES; attempt++) {
|
|
134
|
+
if (attempt > 0) {
|
|
135
|
+
const delay = app_config_1.CoreConstants.HANDLER_RETRY_DELAY_MS * Math.pow(2, attempt - 1);
|
|
136
|
+
lambdaLog.info('RETRY', `Attempt ${attempt + 1}/${app_config_1.CoreConstants.HANDLER_MAX_RETRIES + 1} after ${delay}ms`);
|
|
137
|
+
await sleep(delay);
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const { data, status } = await api.post('/api/plugins/lookup', {
|
|
141
|
+
filter: pluginFilter,
|
|
142
|
+
});
|
|
143
|
+
if (!data) {
|
|
144
|
+
throw new Error('Empty response data from API');
|
|
145
|
+
}
|
|
146
|
+
lambdaLog.info('FETCH', 'Plugin fetched successfully', {
|
|
147
|
+
status,
|
|
148
|
+
plugin: data.name,
|
|
149
|
+
version: data.version,
|
|
150
|
+
id: data.id,
|
|
151
|
+
});
|
|
152
|
+
return data;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error instanceof axios_1.AxiosError) {
|
|
156
|
+
if (error.code === 'ECONNABORTED') {
|
|
157
|
+
lambdaLog.error('FETCH', `Plugin lookup timed out after ${app_config_1.CoreConstants.HANDLER_TIMEOUT_MS}ms`);
|
|
158
|
+
throw new Error(`Plugin lookup timed out after ${app_config_1.CoreConstants.HANDLER_TIMEOUT_MS}ms`);
|
|
159
|
+
}
|
|
160
|
+
const retryable = error.response
|
|
161
|
+
? RETRYABLE_STATUSES.has(error.response.status)
|
|
162
|
+
: RETRYABLE_CODES.has(error.code ?? '');
|
|
163
|
+
const msg = error.response
|
|
164
|
+
? `API error ${error.response.status}: ${error.response.statusText}`
|
|
165
|
+
: error.code || error.message;
|
|
166
|
+
if (retryable && attempt < app_config_1.CoreConstants.HANDLER_MAX_RETRIES) {
|
|
167
|
+
lambdaLog.info('RETRY', `Retryable error: ${msg}`, { attempt: attempt + 1 });
|
|
168
|
+
lastError = new Error(`Failed to fetch plugin: ${msg}`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
lambdaLog.error('FETCH', msg, { responseData: error.response?.data });
|
|
172
|
+
throw new Error(`Failed to fetch plugin: ${msg}`);
|
|
173
|
+
}
|
|
174
|
+
throw error instanceof Error ? error : new Error('Unknown error during plugin fetch');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
throw lastError ?? new Error('Failed to fetch plugin after retries');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Validates the plugin filter object
|
|
181
|
+
*
|
|
182
|
+
* @param pluginFilter - Filter to validate
|
|
183
|
+
* @returns true if valid
|
|
184
|
+
* @throws Error if invalid
|
|
185
|
+
*/
|
|
186
|
+
function validatePluginFilter(pluginFilter) {
|
|
187
|
+
if (!pluginFilter || typeof pluginFilter !== 'object') {
|
|
188
|
+
throw new Error('Missing or invalid pluginFilter');
|
|
189
|
+
}
|
|
190
|
+
const filter = pluginFilter;
|
|
191
|
+
if (!filter.name && !filter.id && !filter.version && !filter.orgId) {
|
|
192
|
+
throw new Error('PluginFilter must have at least one criterion (name, id, version, or orgId)');
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Lambda handler for CloudFormation Custom Resource that performs plugin lookup.
|
|
198
|
+
*
|
|
199
|
+
* Authenticates using JWT token from AWS Secrets Manager (PLATFORM_SECRET_NAME env var).
|
|
200
|
+
* Create the secret with: `pipeline-manager store-token`
|
|
201
|
+
*
|
|
202
|
+
* Request Types:
|
|
203
|
+
* - Create/Update: fetches and returns plugin configuration from API
|
|
204
|
+
* - Delete: no-op (always succeeds)
|
|
205
|
+
*
|
|
206
|
+
* Response:
|
|
207
|
+
* - Success: Returns base64-encoded plugin JSON in Data.ResultValue
|
|
208
|
+
* - Failure: Returns error message in Reason
|
|
209
|
+
*
|
|
210
|
+
* @param event - CloudFormation custom resource event
|
|
211
|
+
* @returns CloudFormation response
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* Custom Resource Properties:
|
|
215
|
+
* ```json
|
|
216
|
+
* {
|
|
217
|
+
* "baseURL": "https://api.example.com",
|
|
218
|
+
* "pluginFilter": {
|
|
219
|
+
* "name": "nodejs-build",
|
|
220
|
+
* "version": "1.0.0",
|
|
221
|
+
* "isActive": true
|
|
222
|
+
* }
|
|
223
|
+
* }
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
const handler = async (event) => {
|
|
227
|
+
lambdaLog.info('START', `${event.RequestType} request received`, {
|
|
228
|
+
logicalResourceId: event.LogicalResourceId,
|
|
229
|
+
requestId: event.RequestId,
|
|
230
|
+
stackId: event.StackId,
|
|
231
|
+
});
|
|
232
|
+
const baseResponse = {
|
|
233
|
+
StackId: event.StackId,
|
|
234
|
+
RequestId: event.RequestId,
|
|
235
|
+
LogicalResourceId: event.LogicalResourceId,
|
|
236
|
+
PhysicalResourceId: event.LogicalResourceId,
|
|
237
|
+
};
|
|
238
|
+
try {
|
|
239
|
+
// Handle Delete - always succeed (no-op)
|
|
240
|
+
if (event.RequestType === 'Delete') {
|
|
241
|
+
lambdaLog.info('DELETE', 'No-op - returning SUCCESS');
|
|
242
|
+
return {
|
|
243
|
+
...baseResponse,
|
|
244
|
+
Status: 'SUCCESS',
|
|
245
|
+
Reason: 'Delete completed (no-op)',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// Extract and validate properties
|
|
249
|
+
const pluginFilter = event.ResourceProperties.pluginFilter;
|
|
250
|
+
const baseURL = event.ResourceProperties.baseURL || app_config_1.CoreConstants.HANDLER_DEFAULT_BASE_URL;
|
|
251
|
+
if (!baseURL.startsWith('https://') && !baseURL.startsWith('http://')) {
|
|
252
|
+
throw new Error(`Invalid baseURL: "${baseURL}" — must start with http:// or https://`);
|
|
253
|
+
}
|
|
254
|
+
lambdaLog.info('CONFIG', 'Configuration loaded', { baseURL, pluginFilter });
|
|
255
|
+
validatePluginFilter(pluginFilter);
|
|
256
|
+
// Get token from Secrets Manager and create API client
|
|
257
|
+
const token = await getToken();
|
|
258
|
+
const api = create(baseURL, token);
|
|
259
|
+
// Fetch plugin
|
|
260
|
+
lambdaLog.info('FETCH', 'Initiating plugin lookup...');
|
|
261
|
+
const plugin = await fetch(api, pluginFilter);
|
|
262
|
+
lambdaLog.info('FETCH', 'Plugin retrieved successfully', {
|
|
263
|
+
name: plugin.name,
|
|
264
|
+
version: plugin.version,
|
|
265
|
+
id: plugin.id,
|
|
266
|
+
});
|
|
267
|
+
// Strip large fields to stay within CloudFormation's 4096-byte Data limit.
|
|
268
|
+
// CDK constructs only need the fields used by createCodeBuildStep().
|
|
269
|
+
const slim = {
|
|
270
|
+
id: plugin.id,
|
|
271
|
+
name: plugin.name,
|
|
272
|
+
version: plugin.version,
|
|
273
|
+
pluginType: plugin.pluginType,
|
|
274
|
+
computeType: plugin.computeType,
|
|
275
|
+
commands: plugin.commands,
|
|
276
|
+
installCommands: plugin.installCommands,
|
|
277
|
+
env: plugin.env,
|
|
278
|
+
metadata: plugin.metadata,
|
|
279
|
+
primaryOutputDirectory: plugin.primaryOutputDirectory,
|
|
280
|
+
secrets: plugin.secrets,
|
|
281
|
+
failureBehavior: plugin.failureBehavior,
|
|
282
|
+
timeout: plugin.timeout,
|
|
283
|
+
imageTag: plugin.imageTag,
|
|
284
|
+
};
|
|
285
|
+
const encoded = Buffer.from(JSON.stringify(slim), 'utf-8').toString('base64');
|
|
286
|
+
lambdaLog.debug('ENCODE', 'Encoded plugin data', { length: encoded.length });
|
|
287
|
+
return {
|
|
288
|
+
...baseResponse,
|
|
289
|
+
Status: 'SUCCESS',
|
|
290
|
+
Reason: `Plugin '${plugin.name}' (v${plugin.version}) retrieved successfully`,
|
|
291
|
+
Data: {
|
|
292
|
+
ResultValue: encoded,
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
const reason = error instanceof Error ? error.message : 'Unexpected error occurred';
|
|
298
|
+
lambdaLog.error('ERROR', 'Handler failed', {
|
|
299
|
+
reason,
|
|
300
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
301
|
+
});
|
|
302
|
+
return {
|
|
303
|
+
...baseResponse,
|
|
304
|
+
Status: 'FAILED',
|
|
305
|
+
Reason: reason,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
finally {
|
|
309
|
+
lambdaLog.info('END', 'Custom resource execution completed');
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
exports.handler = handler;
|
|
313
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWxvb2t1cC1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hhbmRsZXJzL3BsdWdpbi1sb29rdXAtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNEN0Qyx3REFBc0U7QUExQ3RFLDRFQUE4RjtBQUc5RiwrQ0FBeUQ7QUFDekQscURBQXFEO0FBRXJEOzs7R0FHRztBQUNILFNBQVMsUUFBUSxDQUFDLEtBQWEsRUFBRSxHQUFXLEVBQUUsT0FBZSxFQUFFLElBQWM7SUFDM0UsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDekYsUUFBUSxLQUFLLEVBQUUsQ0FBQztRQUNkLEtBQUssT0FBTztZQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFBQyxNQUFNO1FBQ3pDLEtBQUssT0FBTztZQUFFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEtBQUssT0FBTztnQkFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQUMsTUFBTTtRQUNoRixPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxTQUFTLEdBQUc7SUFDaEIsSUFBSSxFQUFFLENBQUMsR0FBVyxFQUFFLE9BQWUsRUFBRSxJQUFjLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUM7SUFDNUYsS0FBSyxFQUFFLENBQUMs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QUMsQ0FBQztRQUM5RSxTQUFTLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxxQkFBcUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUU3RSxPQUFPO1lBQ0wsR0FBRyxZQUFZO1lBQ2YsTUFBTSxFQUFFLFNBQVM7WUFDakIsTUFBTSxFQUFFLFdBQVcsTUFBTSxDQUFDLElBQUksT0FBTyxNQUFNLENBQUMsT0FBTywwQkFBMEI7WUFDN0UsSUFBSSxFQUFFO2dCQUNKLFdBQVcsRUFBRSxPQUFPO2FBQ3JCO1NBQ3NDLENBQUM7SUFDNUMsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixNQUFNLE1BQU0sR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQywyQkFBMkIsQ0FBQztRQUNwRixTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRTtZQUN6QyxNQUFNO1lBQ04sS0FBSyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDeEQsQ0FBQyxDQUFDO1FBRUgsT0FBTztZQUNMLEdBQUcsWUFBWTtZQUNmLE1BQU0sRUFBRSxRQUFRO1lBQ2hCLE1BQU0sRUFBRSxNQUFNO1NBQ3lCLENBQUM7SUFDNUMsQ0FBQztZQUFTLENBQUM7UUFDVCxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxxQ0FBcUMsQ0FBQyxDQUFDO0lBQy9ELENBQUM7QUFDSCxDQUFDLENBQUM7QUFqR1csUUFBQSxPQUFPLFdBaUdsQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBHZXRTZWNyZXRWYWx1ZUNvbW1hbmQsIFNlY3JldHNNYW5hZ2VyQ2xpZW50IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNlY3JldHMtbWFuYWdlcic7XG5pbXBvcnQgeyBQbHVnaW5GaWx0ZXIsIFBsdWdpbiB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWRhdGEnO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LCBDbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2UgfSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCBheGlvcywgeyBBeGlvc0luc3RhbmNlLCBBeGlvc0Vycm9yIH0gZnJvbSAnYXhpb3MnO1xuaW1wb3J0IHsgQ29yZUNvbnN0YW50cyB9IGZyb20gJy4uL2NvbmZpZy9hcHAtY29uZmlnJztcblxuLyoqXG4gKiBTdHJ1Y3R1cmVkIGxvZ2dlciBmb3IgTGFtYmRhIChvdXRwdXRzIEpTT04gdG8gQ2xvdWRXYXRjaCkuXG4gKiBEZWJ1ZyBtZXNzYWdlcyBvbmx5IGVtaXR0ZWQgd2hlbiBMT0dfTEVWRUw9ZGVidWcuXG4gKi9cbmZ1bmN0aW9uIGxvZ0VudHJ5KGxldmVsOiBzdHJpbmcsIHRhZzogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiB1bmtub3duKSB7XG4gIGNvbnN0IGxpbmUgPSBKU09OLnN0cmluZ2lmeSh7IGxldmVsLCB0YWcsIG1lc3NhZ2UsIGRhdGEsIHRzOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfSk7XG4gIHN3aXRjaCAobGV2ZWwpIHtcbiAgICBjYXNlICdFUlJPUic6IGNvbnNvbGUuZXJyb3IobGluZSk7IGJyZWFrO1xuICAgIGNhc2UgJ0RFQlVHJzogaWYgKHByb2Nlc3MuZW52LkxPR19MRVZFTCA9PT0gJ2RlYnVnJykgY29uc29sZS5kZWJ1ZyhsaW5lKTsgYnJlYWs7XG4gICAgZGVmYXVsdDogY29uc29sZS5sb2cobGluZSk7XG4gIH1cbn1cblxuY29uc3QgbGFtYmRhTG9nID0ge1xuICBpbmZvOiAodGFnOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IHVua25vd24pID0+IGxvZ0VudHJ5KCdJTkZPJywgdGFnLCBtZXNzYWdlLCBkYXRhKSxcbiAgZXJyb3I6ICh0YWc6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bikgPT4gbG9nRW50cnkoJ0VSUk9SJywgdGFnLCBtZXNzYWdlLCBkYXRhKSxcbiAgZGVidWc6ICh0YWc6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nLCBkYXRhPzogdW5rbm93bikgPT4gbG9nRW50cnkoJ0RFQlVHJywgdGFnLCBtZXNzYWdlLCBkYXRhKSxcbn07XG5cbmNvbnN0IFJFVFJZQUJMRV9TVEFUVVNFUyA9IG5ldyBTZXQoWzQyOSwgNTAyLCA1MDMsIDUwNF0pO1xuY29uc3QgUkVUUllBQkxFX0NPREVTID0gbmV3IFNldChbJ0VDT05OUkVTRVQnLCAnRUNPTk5SRUZVU0VEJywgJ0VUSU1FRE9VVCddKTtcblxuZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIG1zKSk7XG59XG5cbi8qKiBQbGF0Zm9ybSBzZWNyZXQgbmFtZSDigJQgaW5qZWN0ZWQgYXMgUExBVEZPUk1fU0VDUkVUX05BTUUgZW52IHZhciBieSBQbHVnaW5Mb29rdXAgY29uc3RydWN0LiAqL1xuY29uc3QgUExBVEZPUk1fU0VDUkVUX05BTUUgPSBwcm9jZXNzLmVudi5QTEFURk9STV9TRUNSRVRfTkFNRTtcbmlmICghUExBVEZPUk1fU0VDUkVUX05BTUUpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdQTEFURk9STV9TRUNSRVRfTkFNRSBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyByZXF1aXJlZCcpO1xufVxuXG4vKiogQ2FjaGVkIHRva2VuIHRvIGF2b2lkIHJlcGVhdGVkIFNlY3JldHMgTWFuYWdlciBjYWxscyB3aXRoaW4gYSBzaW5nbGUgaW52b2NhdGlvbi4gKi9cbmxldCBjYWNoZWRUb2tlbjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbi8qKiBAaW50ZXJuYWwgUmVzZXQgY2FjaGVkIHRva2VuIChmb3IgdGVzdGluZyBvbmx5KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfcmVzZXRDcmVkZW50aWFsc0NhY2hlKCk6IHZvaWQgeyBjYWNoZWRUb2tlbiA9IG51bGw7IH1cblxuLyoqXG4gKiBGZXRjaCBKV1QgdG9rZW4gZnJvbSBBV1MgU2VjcmV0cyBNYW5hZ2VyLlxuICogQ2FjaGVzIHRoZSByZXN1bHQgZm9yIHRoZSBsaWZldGltZSBvZiB0aGUgTGFtYmRhIGV4ZWN1dGlvbiBjb250ZXh0LlxuICpcbiAqIFRoZSBzZWNyZXQgbmFtZSBpcyBzZXQgdmlhIFBMQVRGT1JNX1NFQ1JFVF9OQU1FIGVudiB2YXIgKGUuZy4gYHtwcmVmaXh9L3tvcmdJZH0vcGxhdGZvcm1gKVxuICogQ3JlYXRlIGl0IHdpdGg6IGBwaXBlbGluZS1tYW5hZ2VyIHN0b3JlLXRva2VuYFxuICovXG5hc3luYyBmdW5jdGlvbiBnZXRUb2tlbigpOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAoY2FjaGVkVG9rZW4pIHJldHVybiBjYWNoZWRUb2tlbjtcblxuICBsYW1iZGFMb2cuaW5mbygnQVVUSCcsIGBGZXRjaGluZyB0b2tlbiBmcm9tIFNlY3JldHMgTWFuYWdlcjogJHtQTEFURk9STV9TRUNSRVRfTkFNRX1gKTtcblxuICBjb25zdCBjbGllbnQgPSBuZXcgU2VjcmV0c01hbmFnZXJDbGllbnQoe30pO1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5zZW5kKG5ldyBHZXRTZWNyZXRWYWx1ZUNvbW1hbmQoeyBTZWNyZXRJZDogUExBVEZPUk1fU0VDUkVUX05BTUUgfSkpO1xuXG4gIGlmICghcmVzcG9uc2UuU2VjcmV0U3RyaW5nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTZWNyZXQgXCIke1BMQVRGT1JNX1NFQ1JFVF9OQU1FfVwiIGlzIGVtcHR5YCk7XG4gIH1cblxuICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHJlc3BvbnNlLlNlY3JldFN0cmluZykgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgaWYgKCFwYXJzZWQuYWNjZXNzVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFNlY3JldCBcIiR7UExBVEZPUk1fU0VDUkVUX05BTUV9XCIgbWlzc2luZyBhY2Nlc3NUb2tlbiDigJQgcnVuIFwicGlwZWxpbmUtbWFuYWdlciBzdG9yZS10b2tlblwiIHRvIGdlbmVyYXRlYCk7XG4gIH1cblxuICBjYWNoZWRUb2tlbiA9IHBhcnNlZC5hY2Nlc3NUb2tlbjtcbiAgbGFtYmRhTG9nLmluZm8oJ0FVVEgnLCAnVG9rZW4gcmV0cmlldmVkIGZyb20gU2VjcmV0cyBNYW5hZ2VyJyk7XG4gIHJldHVybiBjYWNoZWRUb2tlbjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgcHJlLWNvbmZpZ3VyZWQgQXhpb3MgaW5zdGFuY2UgZm9yIEFQSSByZXF1ZXN0cy5cbiAqXG4gKiBAcGFyYW0gYmFzZVVSTCAtIEJhc2UgVVJMIG9mIHRoZSB0YXJnZXQgQVBJXG4gKiBAcGFyYW0gdG9rZW4gLSBKV1QgdG9rZW4gZm9yIGF1dGhvcml6YXRpb25cbiAqIEByZXR1cm5zIENvbmZpZ3VyZWQgQXhpb3MgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gY3JlYXRlKGJhc2VVUkw6IHN0cmluZywgdG9rZW46IHN0cmluZyk6IEF4aW9zSW5zdGFuY2Uge1xuICByZXR1cm4gYXhpb3MuY3JlYXRlKHtcbiAgICBiYXNlVVJMLFxuICAgIHRpbWVvdXQ6IENvcmVDb25zdGFudHMuSEFORExFUl9USU1FT1VUX01TLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHt0b2tlbn1gLFxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIEZldGNoZXMgcGx1Z2luIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgZXh0ZXJuYWwgQVBJIHdpdGggcmV0cnkgbG9naWMuXG4gKiBSZXRyaWVzIG9uIHRyYW5zaWVudCBmYWlsdXJlcyAoNDI5LCA1MDIsIDUwMywgNTA0LCBuZXR3b3JrIGVycm9ycylcbiAqIHdpdGggZXhwb25lbnRpYWwgYmFja29mZi5cbiAqXG4gKiBAcGFyYW0gYXBpIC0gQ29uZmlndXJlZCBBeGlvcyBpbnN0YW5jZVxuICogQHBhcmFtIHBsdWdpbkZpbHRlciAtIEZpbHRlciBjcml0ZXJpYSBmb3IgdGhlIHBsdWdpbiBsb29rdXBcbiAqIEByZXR1cm5zIFRoZSBwbHVnaW4gZGF0YSByZXR1cm5lZCBieSB0aGUgQVBJXG4gKiBAdGhyb3dzIEVycm9yIG9uIHBlcnNpc3RlbnQgZmFpbHVyZSwgdGltZW91dCBvciBpbnZhbGlkIHJlc3BvbnNlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoKGFwaTogQXhpb3NJbnN0YW5jZSwgcGx1Z2luRmlsdGVyOiBQbHVnaW5GaWx0ZXIpOiBQcm9taXNlPFBsdWdpbj4ge1xuICBsYW1iZGFMb2cuZGVidWcoJ0ZFVENIJywgJ1N0YXJ0aW5nIHBsdWdpbiBmZXRjaCcsIHsgZmlsdGVyOiBwbHVnaW5GaWx0ZXIgfSk7XG5cbiAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG5cbiAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGF0dGVtcHQgPD0gQ29yZUNvbnN0YW50cy5IQU5ETEVSX01BWF9SRVRSSUVTOyBhdHRlbXB0KyspIHtcbiAgICBpZiAoYXR0ZW1wdCA+IDApIHtcbiAgICAgIGNvbnN0IGRlbGF5ID0gQ29yZUNvbnN0YW50cy5IQU5ETEVSX1JFVFJZX0RFTEFZX01TICogTWF0aC5wb3coMiwgYXR0ZW1wdCAtIDEpO1xuICAgICAgbGFtYmRhTG9nLmluZm8oJ1JFVFJZJywgYEF0dGVtcHQgJHthdHRlbXB0ICsgMX0vJHtDb3JlQ29uc3RhbnRzLkhBTkRMRVJfTUFYX1JFVFJJRVMgKyAxfSBhZnRlciAke2RlbGF5fW1zYCk7XG4gICAgICBhd2FpdCBzbGVlcChkZWxheSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgZGF0YSwgc3RhdHVzIH0gPSBhd2FpdCBhcGkucG9zdDxQbHVnaW4+KCcvYXBpL3BsdWdpbnMvbG9va3VwJywge1xuICAgICAgICBmaWx0ZXI6IHBsdWdpbkZpbHRlcixcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbXB0eSByZXNwb25zZSBkYXRhIGZyb20gQVBJJyk7XG4gICAgICB9XG5cbiAgICAgIGxhbWJkYUxvZy5pbmZvKCdGRVRDSCcsICdQbHVnaW4gZmV0Y2hlZCBzdWNjZXNzZnVsbHknLCB7XG4gICAgICAgIHN0YXR1cyxcbiAgICAgICAgcGx1Z2luOiBkYXRhLm5hbWUsXG4gICAgICAgIHZlcnNpb246IGRhdGEudmVyc2lvbixcbiAgICAgICAgaWQ6IGRhdGEuaWQsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEF4aW9zRXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09ICdFQ09OTkFCT1JURUQnKSB7XG4gICAgICAgICAgbGFtYmRhTG9nLmVycm9yKCdGRVRDSCcsIGBQbHVnaW4gbG9va3VwIHRpbWVkIG91dCBhZnRlciAke0NvcmVDb25zdGFudHMuSEFORExFUl9USU1FT1VUX01TfW1zYCk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQbHVnaW4gbG9va3VwIHRpbWVkIG91dCBhZnRlciAke0NvcmVDb25zdGFudHMuSEFORExFUl9USU1FT1VUX01TfW1zYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXRyeWFibGUgPSBlcnJvci5yZXNwb25zZVxuICAgICAgICAgID8gUkVUUllBQkxFX1NUQVRVU0VTLmhhcyhlcnJvci5yZXNwb25zZS5zdGF0dXMpXG4gICAgICAgICAgOiBSRVRSWUFCTEVfQ09ERVMuaGFzKGVycm9yLmNvZGUgPz8gJycpO1xuXG4gICAgICAgIGNvbnN0IG1zZyA9IGVycm9yLnJlc3BvbnNlXG4gICAgICAgICAgPyBgQVBJIGVycm9yICR7ZXJyb3IucmVzcG9uc2Uuc3RhdHVzfTogJHtlcnJvci5yZXNwb25zZS5zdGF0dXNUZXh0fWBcbiAgICAgICAgICA6IGVycm9yLmNvZGUgfHwgZXJyb3IubWVzc2FnZTtcblxuICAgICAgICBpZiAocmV0cnlhYmxlICYmIGF0dGVtcHQgPCBDb3JlQ29uc3RhbnRzLkhBTkRMRVJfTUFYX1JFVFJJRVMpIHtcbiAgICAgICAgICBsYW1iZGFMb2cuaW5mbygnUkVUUlknLCBgUmV0cnlhYmxlIGVycm9yOiAke21zZ31gLCB7IGF0dGVtcHQ6IGF0dGVtcHQgKyAxIH0pO1xuICAgICAgICAgIGxhc3RFcnJvciA9IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIHBsdWdpbjogJHttc2d9YCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBsYW1iZGFMb2cuZXJyb3IoJ0ZFVENIJywgbXNnLCB7IHJlc3BvbnNlRGF0YTogZXJyb3IucmVzcG9uc2U/LmRhdGEgfSk7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGZldGNoIHBsdWdpbjogJHttc2d9YCk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcignVW5rbm93biBlcnJvciBkdXJpbmcgcGx1Z2luIGZldGNoJyk7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbGFzdEVycm9yID8/IG5ldyBFcnJvcignRmFpbGVkIHRvIGZldGNoIHBsdWdpbiBhZnRlciByZXRyaWVzJyk7XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBwbHVnaW4gZmlsdGVyIG9iamVjdFxuICpcbiAqIEBwYXJhbSBwbHVnaW5GaWx0ZXIgLSBGaWx0ZXIgdG8gdmFsaWRhdGVcbiAqIEByZXR1cm5zIHRydWUgaWYgdmFsaWRcbiAqIEB0aHJvd3MgRXJyb3IgaWYgaW52YWxpZFxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVBsdWdpbkZpbHRlcihwbHVnaW5GaWx0ZXI6IHVua25vd24pOiBwbHVnaW5GaWx0ZXIgaXMgUGx1Z2luRmlsdGVyIHtcbiAgaWYgKCFwbHVnaW5GaWx0ZXIgfHwgdHlwZW9mIHBsdWdpbkZpbHRlciAhPT0gJ29iamVjdCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgb3IgaW52YWxpZCBwbHVnaW5GaWx0ZXInKTtcbiAgfVxuXG4gIGNvbnN0IGZpbHRlciA9IHBsdWdpbkZpbHRlciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgaWYgKCFmaWx0ZXIubmFtZSAmJiAhZmlsdGVyLmlkICYmICFmaWx0ZXIudmVyc2lvbiAmJiAhZmlsdGVyLm9yZ0lkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQbHVnaW5GaWx0ZXIgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBjcml0ZXJpb24gKG5hbWUsIGlkLCB2ZXJzaW9uLCBvciBvcmdJZCknKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIExhbWJkYSBoYW5kbGVyIGZvciBDbG91ZEZvcm1hdGlvbiBDdXN0b20gUmVzb3VyY2UgdGhhdCBwZXJmb3JtcyBwbHVnaW4gbG9va3VwLlxuICpcbiAqIEF1dGhlbnRpY2F0ZXMgdXNpbmcgSldUIHRva2VuIGZyb20gQVdTIFNlY3JldHMgTWFuYWdlciAoUExBVEZPUk1fU0VDUkVUX05BTUUgZW52IHZhcikuXG4gKiBDcmVhdGUgdGhlIHNlY3JldCB3aXRoOiBgcGlwZWxpbmUtbWFuYWdlciBzdG9yZS10b2tlbmBcbiAqXG4gKiBSZXF1ZXN0IFR5cGVzOlxuICogLSBDcmVhdGUvVXBkYXRlOiBmZXRjaGVzIGFuZCByZXR1cm5zIHBsdWdpbiBjb25maWd1cmF0aW9uIGZyb20gQVBJXG4gKiAtIERlbGV0ZTogbm8tb3AgKGFsd2F5cyBzdWNjZWVkcylcbiAqXG4gKiBSZXNwb25zZTpcbiAqIC0gU3VjY2VzczogUmV0dXJucyBiYXNlNjQtZW5jb2RlZCBwbHVnaW4gSlNPTiBpbiBEYXRhLlJlc3VsdFZhbHVlXG4gKiAtIEZhaWx1cmU6IFJldHVybnMgZXJyb3IgbWVzc2FnZSBpbiBSZWFzb25cbiAqXG4gKiBAcGFyYW0gZXZlbnQgLSBDbG91ZEZvcm1hdGlvbiBjdXN0b20gcmVzb3VyY2UgZXZlbnRcbiAqIEByZXR1cm5zIENsb3VkRm9ybWF0aW9uIHJlc3BvbnNlXG4gKlxuICogQGV4YW1wbGVcbiAqIEN1c3RvbSBSZXNvdXJjZSBQcm9wZXJ0aWVzOlxuICogYGBganNvblxuICoge1xuICogICBcImJhc2VVUkxcIjogXCJodHRwczovL2FwaS5leGFtcGxlLmNvbVwiLFxuICogICBcInBsdWdpbkZpbHRlclwiOiB7XG4gKiAgICAgXCJuYW1lXCI6IFwibm9kZWpzLWJ1aWxkXCIsXG4gKiAgICAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcbiAqICAgICBcImlzQWN0aXZlXCI6IHRydWVcbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBoYW5kbGVyID0gYXN5bmMgKFxuICBldmVudDogQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50LFxuKTogUHJvbWlzZTxDbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2U+ID0+IHtcbiAgbGFtYmRhTG9nLmluZm8oJ1NUQVJUJywgYCR7ZXZlbnQuUmVxdWVzdFR5cGV9IHJlcXVlc3QgcmVjZWl2ZWRgLCB7XG4gICAgbG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIHJlcXVlc3RJZDogZXZlbnQuUmVxdWVzdElkLFxuICAgIHN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gIH0pO1xuXG4gIGNvbnN0IGJhc2VSZXNwb25zZTogUGFydGlhbDxDbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2U+ID0ge1xuICAgIFN0YWNrSWQ6IGV2ZW50LlN0YWNrSWQsXG4gICAgUmVxdWVzdElkOiBldmVudC5SZXF1ZXN0SWQsXG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGV2ZW50LkxvZ2ljYWxSZXNvdXJjZUlkLFxuICAgIFBoeXNpY2FsUmVzb3VyY2VJZDogZXZlbnQuTG9naWNhbFJlc291cmNlSWQsXG4gIH07XG5cbiAgdHJ5IHtcbiAgICAvLyBIYW5kbGUgRGVsZXRlIC0gYWx3YXlzIHN1Y2NlZWQgKG5vLW9wKVxuICAgIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgIGxhbWJkYUxvZy5pbmZvKCdERUxFVEUnLCAnTm8tb3AgLSByZXR1cm5pbmcgU1VDQ0VTUycpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uYmFzZVJlc3BvbnNlLFxuICAgICAgICBTdGF0dXM6ICdTVUNDRVNTJyxcbiAgICAgICAgUmVhc29uOiAnRGVsZXRlIGNvbXBsZXRlZCAobm8tb3ApJyxcbiAgICAgIH0gYXMgQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZVJlc3BvbnNlO1xuICAgIH1cblxuICAgIC8vIEV4dHJhY3QgYW5kIHZhbGlkYXRlIHByb3BlcnRpZXNcbiAgICBjb25zdCBwbHVnaW5GaWx0ZXIgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMucGx1Z2luRmlsdGVyO1xuICAgIGNvbnN0IGJhc2VVUkwgPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuYmFzZVVSTCB8fCBDb3JlQ29uc3RhbnRzLkhBTkRMRVJfREVGQVVMVF9CQVNFX1VSTDtcblxuICAgIGlmICghYmFzZVVSTC5zdGFydHNXaXRoKCdodHRwczovLycpICYmICFiYXNlVVJMLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGJhc2VVUkw6IFwiJHtiYXNlVVJMfVwiIOKAlCBtdXN0IHN0YXJ0IHdpdGggaHR0cDovLyBvciBodHRwczovL2ApO1xuICAgIH1cblxuICAgIGxhbWJkYUxvZy5pbmZvKCdDT05GSUcnLCAnQ29uZmlndXJhdGlvbiBsb2FkZWQnLCB7IGJhc2VVUkwsIHBsdWdpbkZpbHRlciB9KTtcblxuICAgIHZhbGlkYXRlUGx1Z2luRmlsdGVyKHBsdWdpbkZpbHRlcik7XG5cbiAgICAvLyBHZXQgdG9rZW4gZnJvbSBTZWNyZXRzIE1hbmFnZXIgYW5kIGNyZWF0ZSBBUEkgY2xpZW50XG4gICAgY29uc3QgdG9rZW4gPSBhd2FpdCBnZXRUb2tlbigpO1xuICAgIGNvbnN0IGFwaSA9IGNyZWF0ZShiYXNlVVJMLCB0b2tlbik7XG5cbiAgICAvLyBGZXRjaCBwbHVnaW5cbiAgICBsYW1iZGFMb2cuaW5mbygnRkVUQ0gnLCAnSW5pdGlhdGluZyBwbHVnaW4gbG9va3VwLi4uJyk7XG4gICAgY29uc3QgcGx1Z2luID0gYXdhaXQgZmV0Y2goYXBpLCBwbHVnaW5GaWx0ZXIpO1xuICAgIGxhbWJkYUxvZy5pbmZvKCdGRVRDSCcsICdQbHVnaW4gcmV0cmlldmVkIHN1Y2Nlc3NmdWxseScsIHtcbiAgICAgIG5hbWU6IHBsdWdpbi5uYW1lLFxuICAgICAgdmVyc2lvbjogcGx1Z2luLnZlcnNpb24sXG4gICAgICBpZDogcGx1Z2luLmlkLFxuICAgIH0pO1xuXG4gICAgLy8gU3RyaXAgbGFyZ2UgZmllbGRzIHRvIHN0YXkgd2l0aGluIENsb3VkRm9ybWF0aW9uJ3MgNDA5Ni1ieXRlIERhdGEgbGltaXQuXG4gICAgLy8gQ0RLIGNvbnN0cnVjdHMgb25seSBuZWVkIHRoZSBmaWVsZHMgdXNlZCBieSBjcmVhdGVDb2RlQnVpbGRTdGVwKCkuXG4gICAgY29uc3Qgc2xpbSA9IHtcbiAgICAgIGlkOiBwbHVnaW4uaWQsXG4gICAgICBuYW1lOiBwbHVnaW4ubmFtZSxcbiAgICAgIHZlcnNpb246IHBsdWdpbi52ZXJzaW9uLFxuICAgICAgcGx1Z2luVHlwZTogcGx1Z2luLnBsdWdpblR5cGUsXG4gICAgICBjb21wdXRlVHlwZTogcGx1Z2luLmNvbXB1dGVUeXBlLFxuICAgICAgY29tbWFuZHM6IHBsdWdpbi5jb21tYW5kcyxcbiAgICAgIGluc3RhbGxDb21tYW5kczogcGx1Z2luLmluc3RhbGxDb21tYW5kcyxcbiAgICAgIGVudjogcGx1Z2luLmVudixcbiAgICAgIG1ldGFkYXRhOiBwbHVnaW4ubWV0YWRhdGEsXG4gICAgICBwcmltYXJ5T3V0cHV0RGlyZWN0b3J5OiBwbHVnaW4ucHJpbWFyeU91dHB1dERpcmVjdG9yeSxcbiAgICAgIHNlY3JldHM6IHBsdWdpbi5zZWNyZXRzLFxuICAgICAgZmFpbHVyZUJlaGF2aW9yOiBwbHVnaW4uZmFpbHVyZUJlaGF2aW9yLFxuICAgICAgdGltZW91dDogcGx1Z2luLnRpbWVvdXQsXG4gICAgICBpbWFnZVRhZzogcGx1Z2luLmltYWdlVGFnLFxuICAgIH07XG5cbiAgICBjb25zdCBlbmNvZGVkID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoc2xpbSksICd1dGYtOCcpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICBsYW1iZGFMb2cuZGVidWcoJ0VOQ09ERScsICdFbmNvZGVkIHBsdWdpbiBkYXRhJywgeyBsZW5ndGg6IGVuY29kZWQubGVuZ3RoIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmJhc2VSZXNwb25zZSxcbiAgICAgIFN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgUmVhc29uOiBgUGx1Z2luICcke3BsdWdpbi5uYW1lfScgKHYke3BsdWdpbi52ZXJzaW9ufSkgcmV0cmlldmVkIHN1Y2Nlc3NmdWxseWAsXG4gICAgICBEYXRhOiB7XG4gICAgICAgIFJlc3VsdFZhbHVlOiBlbmNvZGVkLFxuICAgICAgfSxcbiAgICB9IGFzIENsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VSZXNwb25zZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCByZWFzb24gPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmV4cGVjdGVkIGVycm9yIG9jY3VycmVkJztcbiAgICBsYW1iZGFMb2cuZXJyb3IoJ0VSUk9SJywgJ0hhbmRsZXIgZmFpbGVkJywge1xuICAgICAgcmVhc29uLFxuICAgICAgc3RhY2s6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5zdGFjayA6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5iYXNlUmVzcG9uc2UsXG4gICAgICBTdGF0dXM6ICdGQUlMRUQnLFxuICAgICAgUmVhc29uOiByZWFzb24sXG4gICAgfSBhcyBDbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlUmVzcG9uc2U7XG4gIH0gZmluYWxseSB7XG4gICAgbGFtYmRhTG9nLmluZm8oJ0VORCcsICdDdXN0b20gcmVzb3VyY2UgZXhlY3V0aW9uIGNvbXBsZXRlZCcpO1xuICB9XG59O1xuIl19
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @pipeline-builder/pipeline-core
|
|
3
|
+
*
|
|
4
|
+
* Application configuration, pipeline domain types, and CDK constructs.
|
|
5
|
+
*
|
|
6
|
+
* **Config**
|
|
7
|
+
* - Config — application configuration singleton (environment-driven)
|
|
8
|
+
* - ConfigTypes — typed configuration interfaces
|
|
9
|
+
*
|
|
10
|
+
* **Types**
|
|
11
|
+
* - PipelineType, ComputeType, AccessModifier, PluginType — pipeline domain enums
|
|
12
|
+
* - NetworkTypes, RoleTypes, SecurityGroupTypes — infrastructure type definitions
|
|
13
|
+
* - SourceTypes, StepTypes — pipeline source and step configuration types
|
|
14
|
+
* - IdGenerator — deterministic ID generation
|
|
15
|
+
*
|
|
16
|
+
* **CDK Constructs**
|
|
17
|
+
* - PipelineBuilder — top-level CDK pipeline construct
|
|
18
|
+
* - StageBuilder — pipeline stage composition
|
|
19
|
+
* - PipelineConfiguration — pipeline config resolution
|
|
20
|
+
* - PluginLookup — plugin resolution for pipeline steps
|
|
21
|
+
* - ArtifactManager — build artifact management
|
|
22
|
+
*
|
|
23
|
+
* **Helpers**
|
|
24
|
+
* - replaceNonAlphanumeric, extractMetadataEnv — string and metadata utilities
|
|
25
|
+
* - buildConfigFromMetadata, metadataForCodePipeline, etc. — metadata builders
|
|
26
|
+
*
|
|
27
|
+
* **Re-exports from api-core**
|
|
28
|
+
* - ErrorCode, createLogger
|
|
29
|
+
*
|
|
30
|
+
* **Re-exports from pipeline-data**
|
|
31
|
+
* - db, schema, getConnection, closeConnection — database access
|
|
32
|
+
* - CrudService, BaseEntity — CRUD service infrastructure
|
|
33
|
+
* - All query condition builders and filter types
|
|
34
|
+
* - Compliance domain types (RuleSeverity, RuleTarget, etc.)
|
|
35
|
+
* - drizzleRows, drizzleCount — type helpers
|
|
36
|
+
*/
|
|
37
|
+
export * from './config/app-config';
|
|
38
|
+
export * from './config/config-types';
|
|
39
|
+
export * from './core/pipeline-types';
|
|
40
|
+
export * from './core/network-types';
|
|
41
|
+
export * from './core/role-types';
|
|
42
|
+
export * from './core/security-group-types';
|
|
43
|
+
export * from './core/id-generator';
|
|
44
|
+
export { replaceNonAlphanumeric, extractMetadataEnv } from './core/pipeline-helpers';
|
|
45
|
+
export { buildConfigFromMetadata, metadataForCodePipeline, metadataForCodeBuildStep, metadataForShellStep, metadataForBuildEnvironment, } from './core/metadata-builder';
|
|
46
|
+
export * from './core/artifact-manager';
|
|
47
|
+
export { ErrorCode, createLogger, } from '@pipeline-builder/api-core';
|
|
48
|
+
export { db, getConnection, closeConnection, schema, buildPluginConditions, buildPipelineConditions, buildMessageConditions, validateMessageFilter, buildCompliancePolicyConditions, buildComplianceRuleConditions, buildComplianceExemptionConditions, buildComplianceAuditConditions, buildComplianceScanConditions, buildPublishedRuleCatalogConditions, buildComplianceRuleSubscriptionConditions, type PluginFilter, type PipelineFilter, type MessageFilter, type CompliancePolicyFilter, type ComplianceRuleFilter, type ComplianceExemptionFilter, type ComplianceAuditFilter, type ComplianceScanFilter, type ComplianceRuleSubscriptionFilter, type PluginSecret, type RuleSeverity, type RuleTarget, type RuleOperator, type RuleConditionMode, type RuleScope, type RuleCondition, type ComplianceRoleType, CrudService, type BaseEntity, drizzleRows, drizzleCount, } from '@pipeline-builder/pipeline-data';
|
|
49
|
+
export * from './pipeline/source-types';
|
|
50
|
+
export * from './pipeline/step-types';
|
|
51
|
+
export * from './pipeline/stage-builder';
|
|
52
|
+
export * from './pipeline/pipeline-builder';
|
|
53
|
+
export * from './pipeline/plugin-lookup';
|
|
54
|
+
export { PipelineConfiguration } from './pipeline/pipeline-configuration';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.PipelineConfiguration = exports.drizzleCount = exports.drizzleRows = exports.CrudService = exports.buildComplianceRuleSubscriptionConditions = exports.buildPublishedRuleCatalogConditions = exports.buildComplianceScanConditions = exports.buildComplianceAuditConditions = exports.buildComplianceExemptionConditions = exports.buildComplianceRuleConditions = exports.buildCompliancePolicyConditions = exports.validateMessageFilter = exports.buildMessageConditions = exports.buildPipelineConditions = exports.buildPluginConditions = exports.schema = exports.closeConnection = exports.getConnection = exports.db = exports.createLogger = exports.ErrorCode = exports.metadataForBuildEnvironment = exports.metadataForShellStep = exports.metadataForCodeBuildStep = exports.metadataForCodePipeline = exports.buildConfigFromMetadata = exports.extractMetadataEnv = exports.replaceNonAlphanumeric = void 0;
|
|
20
|
+
/**
|
|
21
|
+
* @module @pipeline-builder/pipeline-core
|
|
22
|
+
*
|
|
23
|
+
* Application configuration, pipeline domain types, and CDK constructs.
|
|
24
|
+
*
|
|
25
|
+
* **Config**
|
|
26
|
+
* - Config — application configuration singleton (environment-driven)
|
|
27
|
+
* - ConfigTypes — typed configuration interfaces
|
|
28
|
+
*
|
|
29
|
+
* **Types**
|
|
30
|
+
* - PipelineType, ComputeType, AccessModifier, PluginType — pipeline domain enums
|
|
31
|
+
* - NetworkTypes, RoleTypes, SecurityGroupTypes — infrastructure type definitions
|
|
32
|
+
* - SourceTypes, StepTypes — pipeline source and step configuration types
|
|
33
|
+
* - IdGenerator — deterministic ID generation
|
|
34
|
+
*
|
|
35
|
+
* **CDK Constructs**
|
|
36
|
+
* - PipelineBuilder — top-level CDK pipeline construct
|
|
37
|
+
* - StageBuilder — pipeline stage composition
|
|
38
|
+
* - PipelineConfiguration — pipeline config resolution
|
|
39
|
+
* - PluginLookup — plugin resolution for pipeline steps
|
|
40
|
+
* - ArtifactManager — build artifact management
|
|
41
|
+
*
|
|
42
|
+
* **Helpers**
|
|
43
|
+
* - replaceNonAlphanumeric, extractMetadataEnv — string and metadata utilities
|
|
44
|
+
* - buildConfigFromMetadata, metadataForCodePipeline, etc. — metadata builders
|
|
45
|
+
*
|
|
46
|
+
* **Re-exports from api-core**
|
|
47
|
+
* - ErrorCode, createLogger
|
|
48
|
+
*
|
|
49
|
+
* **Re-exports from pipeline-data**
|
|
50
|
+
* - db, schema, getConnection, closeConnection — database access
|
|
51
|
+
* - CrudService, BaseEntity — CRUD service infrastructure
|
|
52
|
+
* - All query condition builders and filter types
|
|
53
|
+
* - Compliance domain types (RuleSeverity, RuleTarget, etc.)
|
|
54
|
+
* - drizzleRows, drizzleCount — type helpers
|
|
55
|
+
*/
|
|
56
|
+
// Configuration
|
|
57
|
+
__exportStar(require("./config/app-config"), exports);
|
|
58
|
+
__exportStar(require("./config/config-types"), exports);
|
|
59
|
+
// Core types (public surface)
|
|
60
|
+
__exportStar(require("./core/pipeline-types"), exports);
|
|
61
|
+
__exportStar(require("./core/network-types"), exports);
|
|
62
|
+
__exportStar(require("./core/role-types"), exports);
|
|
63
|
+
__exportStar(require("./core/security-group-types"), exports);
|
|
64
|
+
__exportStar(require("./core/id-generator"), exports);
|
|
65
|
+
var pipeline_helpers_1 = require("./core/pipeline-helpers");
|
|
66
|
+
Object.defineProperty(exports, "replaceNonAlphanumeric", { enumerable: true, get: function () { return pipeline_helpers_1.replaceNonAlphanumeric; } });
|
|
67
|
+
Object.defineProperty(exports, "extractMetadataEnv", { enumerable: true, get: function () { return pipeline_helpers_1.extractMetadataEnv; } });
|
|
68
|
+
var metadata_builder_1 = require("./core/metadata-builder");
|
|
69
|
+
Object.defineProperty(exports, "buildConfigFromMetadata", { enumerable: true, get: function () { return metadata_builder_1.buildConfigFromMetadata; } });
|
|
70
|
+
Object.defineProperty(exports, "metadataForCodePipeline", { enumerable: true, get: function () { return metadata_builder_1.metadataForCodePipeline; } });
|
|
71
|
+
Object.defineProperty(exports, "metadataForCodeBuildStep", { enumerable: true, get: function () { return metadata_builder_1.metadataForCodeBuildStep; } });
|
|
72
|
+
Object.defineProperty(exports, "metadataForShellStep", { enumerable: true, get: function () { return metadata_builder_1.metadataForShellStep; } });
|
|
73
|
+
Object.defineProperty(exports, "metadataForBuildEnvironment", { enumerable: true, get: function () { return metadata_builder_1.metadataForBuildEnvironment; } });
|
|
74
|
+
__exportStar(require("./core/artifact-manager"), exports);
|
|
75
|
+
// Re-export from api-core (only items consumed by external packages)
|
|
76
|
+
var api_core_1 = require("@pipeline-builder/api-core");
|
|
77
|
+
Object.defineProperty(exports, "ErrorCode", { enumerable: true, get: function () { return api_core_1.ErrorCode; } });
|
|
78
|
+
Object.defineProperty(exports, "createLogger", { enumerable: true, get: function () { return api_core_1.createLogger; } });
|
|
79
|
+
// Re-export database layer from pipeline-data (only items consumed externally)
|
|
80
|
+
var pipeline_data_1 = require("@pipeline-builder/pipeline-data");
|
|
81
|
+
// Database connection
|
|
82
|
+
Object.defineProperty(exports, "db", { enumerable: true, get: function () { return pipeline_data_1.db; } });
|
|
83
|
+
Object.defineProperty(exports, "getConnection", { enumerable: true, get: function () { return pipeline_data_1.getConnection; } });
|
|
84
|
+
Object.defineProperty(exports, "closeConnection", { enumerable: true, get: function () { return pipeline_data_1.closeConnection; } });
|
|
85
|
+
// Schema & tables
|
|
86
|
+
Object.defineProperty(exports, "schema", { enumerable: true, get: function () { return pipeline_data_1.schema; } });
|
|
87
|
+
// Query builders
|
|
88
|
+
Object.defineProperty(exports, "buildPluginConditions", { enumerable: true, get: function () { return pipeline_data_1.buildPluginConditions; } });
|
|
89
|
+
Object.defineProperty(exports, "buildPipelineConditions", { enumerable: true, get: function () { return pipeline_data_1.buildPipelineConditions; } });
|
|
90
|
+
Object.defineProperty(exports, "buildMessageConditions", { enumerable: true, get: function () { return pipeline_data_1.buildMessageConditions; } });
|
|
91
|
+
Object.defineProperty(exports, "validateMessageFilter", { enumerable: true, get: function () { return pipeline_data_1.validateMessageFilter; } });
|
|
92
|
+
Object.defineProperty(exports, "buildCompliancePolicyConditions", { enumerable: true, get: function () { return pipeline_data_1.buildCompliancePolicyConditions; } });
|
|
93
|
+
Object.defineProperty(exports, "buildComplianceRuleConditions", { enumerable: true, get: function () { return pipeline_data_1.buildComplianceRuleConditions; } });
|
|
94
|
+
Object.defineProperty(exports, "buildComplianceExemptionConditions", { enumerable: true, get: function () { return pipeline_data_1.buildComplianceExemptionConditions; } });
|
|
95
|
+
Object.defineProperty(exports, "buildComplianceAuditConditions", { enumerable: true, get: function () { return pipeline_data_1.buildComplianceAuditConditions; } });
|
|
96
|
+
Object.defineProperty(exports, "buildComplianceScanConditions", { enumerable: true, get: function () { return pipeline_data_1.buildComplianceScanConditions; } });
|
|
97
|
+
Object.defineProperty(exports, "buildPublishedRuleCatalogConditions", { enumerable: true, get: function () { return pipeline_data_1.buildPublishedRuleCatalogConditions; } });
|
|
98
|
+
Object.defineProperty(exports, "buildComplianceRuleSubscriptionConditions", { enumerable: true, get: function () { return pipeline_data_1.buildComplianceRuleSubscriptionConditions; } });
|
|
99
|
+
// CRUD service
|
|
100
|
+
Object.defineProperty(exports, "CrudService", { enumerable: true, get: function () { return pipeline_data_1.CrudService; } });
|
|
101
|
+
// Drizzle type helpers
|
|
102
|
+
Object.defineProperty(exports, "drizzleRows", { enumerable: true, get: function () { return pipeline_data_1.drizzleRows; } });
|
|
103
|
+
Object.defineProperty(exports, "drizzleCount", { enumerable: true, get: function () { return pipeline_data_1.drizzleCount; } });
|
|
104
|
+
// Pipeline (CDK constructs)
|
|
105
|
+
__exportStar(require("./pipeline/source-types"), exports);
|
|
106
|
+
__exportStar(require("./pipeline/step-types"), exports);
|
|
107
|
+
__exportStar(require("./pipeline/stage-builder"), exports);
|
|
108
|
+
__exportStar(require("./pipeline/pipeline-builder"), exports);
|
|
109
|
+
__exportStar(require("./pipeline/plugin-lookup"), exports);
|
|
110
|
+
var pipeline_configuration_1 = require("./pipeline/pipeline-configuration");
|
|
111
|
+
Object.defineProperty(exports, "PipelineConfiguration", { enumerable: true, get: function () { return pipeline_configuration_1.PipelineConfiguration; } });
|
|
112
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRXRDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1DRztBQUVILGdCQUFnQjtBQUNoQixzREFBb0M7QUFDcEMsd0RBQXNDO0FBRXRDLDhCQUE4QjtBQUM5Qix3REFBc0M7QUFDdEMsdURBQXFDO0FBQ3JDLG9EQUFrQztBQUNsQyw4REFBNEM7QUFDNUMsc0RBQW9DO0FBQ3BDLDREQUFxRjtBQUE1RSwwSEFBQSxzQkFBc0IsT0FBQTtBQUFFLHNIQUFBLGtCQUFrQixPQUFBO0FBQ25ELDREQU1pQztBQUwvQiwySEFBQSx1QkFBdUIsT0FBQTtBQUN2QiwySEFBQSx1QkFBdUIsT0FBQTtBQUN2Qiw0SEFBQSx3QkFBd0IsT0FBQTtBQUN4Qix3SEFBQSxvQkFBb0IsT0FBQTtBQUNwQiwrSEFBQSwyQkFBMkIsT0FBQTtBQUU3QiwwREFBd0M7QUFFeEMscUVBQXFFO0FBQ3JFLHVEQUdvQztBQUZsQyxxR0FBQSxTQUFTLE9BQUE7QUFDVCx3R0FBQSxZQUFZLE9BQUE7QUFHZCwrRUFBK0U7QUFDL0UsaUVBb0R5QztBQW5EdkMsc0JBQXNCO0FBQ3RCLG1HQUFBLEVBQUUsT0FBQTtBQUNGLDhHQUFBLGFBQWEsT0FBQTtBQUNiLGdIQUFBLGVBQWUsT0FBQTtBQUVmLGtCQUFrQjtBQUNsQix1R0FBQSxNQUFNLE9BQUE7QUFFTixpQkFBaUI7QUFDakIsc0hBQUEscUJBQXFCLE9BQUE7QUFDckIsd0hBQUEsdUJBQXVCLE9BQUE7QUFDdkIsdUhBQUEsc0JBQXNCLE9BQUE7QUFDdEIsc0hBQUEscUJBQXFCLE9BQUE7QUFDckIsZ0lBQUEsK0JBQStCLE9BQUE7QUFDL0IsOEhBQUEsNkJBQTZCLE9BQUE7QUFDN0IsbUlBQUEsa0NBQWtDLE9BQUE7QUFDbEMsK0hBQUEsOEJBQThCLE9BQUE7QUFDOUIsOEhBQUEsNkJBQTZCLE9BQUE7QUFDN0Isb0lBQUEsbUNBQW1DLE9BQUE7QUFDbkMsMElBQUEseUNBQXlDLE9BQUE7QUF5QnpDLGVBQWU7QUFDZiw0R0FBQSxXQUFXLE9BQUE7QUFHWCx1QkFBdUI7QUFDdkIsNEdBQUEsV0FBVyxPQUFBO0FBQ1gsNkdBQUEsWUFBWSxPQUFBO0FBR2QsNEJBQTRCO0FBQzVCLDBEQUF3QztBQUN4Qyx3REFBc0M7QUFDdEMsMkRBQXlDO0FBQ3pDLDhEQUE0QztBQUM1QywyREFBeUM7QUFDekMsNEVBQTBFO0FBQWpFLCtIQUFBLHFCQUFxQixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogQG1vZHVsZSBAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1jb3JlXG4gKlxuICogQXBwbGljYXRpb24gY29uZmlndXJhdGlvbiwgcGlwZWxpbmUgZG9tYWluIHR5cGVzLCBhbmQgQ0RLIGNvbnN0cnVjdHMuXG4gKlxuICogKipDb25maWcqKlxuICogLSBDb25maWcg4oCUIGFwcGxpY2F0aW9uIGNvbmZpZ3VyYXRpb24gc2luZ2xldG9uIChlbnZpcm9ubWVudC1kcml2ZW4pXG4gKiAtIENvbmZpZ1R5cGVzIOKAlCB0eXBlZCBjb25maWd1cmF0aW9uIGludGVyZmFjZXNcbiAqXG4gKiAqKlR5cGVzKipcbiAqIC0gUGlwZWxpbmVUeXBlLCBDb21wdXRlVHlwZSwgQWNjZXNzTW9kaWZpZXIsIFBsdWdpblR5cGUg4oCUIHBpcGVsaW5lIGRvbWFpbiBlbnVtc1xuICogLSBOZXR3b3JrVHlwZXMsIFJvbGVUeXBlcywgU2VjdXJpdHlHcm91cFR5cGVzIOKAlCBpbmZyYXN0cnVjdHVyZSB0eXBlIGRlZmluaXRpb25zXG4gKiAtIFNvdXJjZVR5cGVzLCBTdGVwVHlwZXMg4oCUIHBpcGVsaW5lIHNvdXJjZSBhbmQgc3RlcCBjb25maWd1cmF0aW9uIHR5cGVzXG4gKiAtIElkR2VuZXJhdG9yIOKAlCBkZXRlcm1pbmlzdGljIElEIGdlbmVyYXRpb25cbiAqXG4gKiAqKkNESyBDb25zdHJ1Y3RzKipcbiAqIC0gUGlwZWxpbmVCdWlsZGVyIOKAlCB0b3AtbGV2ZWwgQ0RLIHBpcGVsaW5lIGNvbnN0cnVjdFxuICogLSBTdGFnZUJ1aWxkZXIg4oCUIHBpcGVsaW5lIHN0YWdlIGNvbXBvc2l0aW9uXG4gKiAtIFBpcGVsaW5lQ29uZmlndXJhdGlvbiDigJQgcGlwZWxpbmUgY29uZmlnIHJlc29sdXRpb25cbiAqIC0gUGx1Z2luTG9va3VwIOKAlCBwbHVnaW4gcmVzb2x1dGlvbiBmb3IgcGlwZWxpbmUgc3RlcHNcbiAqIC0gQXJ0aWZhY3RNYW5hZ2VyIOKAlCBidWlsZCBhcnRpZmFjdCBtYW5hZ2VtZW50XG4gKlxuICogKipIZWxwZXJzKipcbiAqIC0gcmVwbGFjZU5vbkFscGhhbnVtZXJpYywgZXh0cmFjdE1ldGFkYXRhRW52IOKAlCBzdHJpbmcgYW5kIG1ldGFkYXRhIHV0aWxpdGllc1xuICogLSBidWlsZENvbmZpZ0Zyb21NZXRhZGF0YSwgbWV0YWRhdGFGb3JDb2RlUGlwZWxpbmUsIGV0Yy4g4oCUIG1ldGFkYXRhIGJ1aWxkZXJzXG4gKlxuICogKipSZS1leHBvcnRzIGZyb20gYXBpLWNvcmUqKlxuICogLSBFcnJvckNvZGUsIGNyZWF0ZUxvZ2dlclxuICpcbiAqICoqUmUtZXhwb3J0cyBmcm9tIHBpcGVsaW5lLWRhdGEqKlxuICogLSBkYiwgc2NoZW1hLCBnZXRDb25uZWN0aW9uLCBjbG9zZUNvbm5lY3Rpb24g4oCUIGRhdGFiYXNlIGFjY2Vzc1xuICogLSBDcnVkU2VydmljZSwgQmFzZUVudGl0eSDigJQgQ1JVRCBzZXJ2aWNlIGluZnJhc3RydWN0dXJlXG4gKiAtIEFsbCBxdWVyeSBjb25kaXRpb24gYnVpbGRlcnMgYW5kIGZpbHRlciB0eXBlc1xuICogLSBDb21wbGlhbmNlIGRvbWFpbiB0eXBlcyAoUnVsZVNldmVyaXR5LCBSdWxlVGFyZ2V0LCBldGMuKVxuICogLSBkcml6emxlUm93cywgZHJpenpsZUNvdW50IOKAlCB0eXBlIGhlbHBlcnNcbiAqL1xuXG4vLyBDb25maWd1cmF0aW9uXG5leHBvcnQgKiBmcm9tICcuL2NvbmZpZy9hcHAtY29uZmlnJztcbmV4cG9ydCAqIGZyb20gJy4vY29uZmlnL2NvbmZpZy10eXBlcyc7XG5cbi8vIENvcmUgdHlwZXMgKHB1YmxpYyBzdXJmYWNlKVxuZXhwb3J0ICogZnJvbSAnLi9jb3JlL3BpcGVsaW5lLXR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vY29yZS9uZXR3b3JrLXR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vY29yZS9yb2xlLXR5cGVzJztcbmV4cG9ydCAqIGZyb20gJy4vY29yZS9zZWN1cml0eS1ncm91cC10eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL2NvcmUvaWQtZ2VuZXJhdG9yJztcbmV4cG9ydCB7IHJlcGxhY2VOb25BbHBoYW51bWVyaWMsIGV4dHJhY3RNZXRhZGF0YUVudiB9IGZyb20gJy4vY29yZS9waXBlbGluZS1oZWxwZXJzJztcbmV4cG9ydCB7XG4gIGJ1aWxkQ29uZmlnRnJvbU1ldGFkYXRhLFxuICBtZXRhZGF0YUZvckNvZGVQaXBlbGluZSxcbiAgbWV0YWRhdGFGb3JDb2RlQnVpbGRTdGVwLFxuICBtZXRhZGF0YUZvclNoZWxsU3RlcCxcbiAgbWV0YWRhdGFGb3JCdWlsZEVudmlyb25tZW50LFxufSBmcm9tICcuL2NvcmUvbWV0YWRhdGEtYnVpbGRlcic7XG5leHBvcnQgKiBmcm9tICcuL2NvcmUvYXJ0aWZhY3QtbWFuYWdlcic7XG5cbi8vIFJlLWV4cG9ydCBmcm9tIGFwaS1jb3JlIChvbmx5IGl0ZW1zIGNvbnN1bWVkIGJ5IGV4dGVybmFsIHBhY2thZ2VzKVxuZXhwb3J0IHtcbiAgRXJyb3JDb2RlLFxuICBjcmVhdGVMb2dnZXIsXG59IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcblxuLy8gUmUtZXhwb3J0IGRhdGFiYXNlIGxheWVyIGZyb20gcGlwZWxpbmUtZGF0YSAob25seSBpdGVtcyBjb25zdW1lZCBleHRlcm5hbGx5KVxuZXhwb3J0IHtcbiAgLy8gRGF0YWJhc2UgY29ubmVjdGlvblxuICBkYixcbiAgZ2V0Q29ubmVjdGlvbixcbiAgY2xvc2VDb25uZWN0aW9uLFxuXG4gIC8vIFNjaGVtYSAmIHRhYmxlc1xuICBzY2hlbWEsXG5cbiAgLy8gUXVlcnkgYnVpbGRlcnNcbiAgYnVpbGRQbHVnaW5Db25kaXRpb25zLFxuICBidWlsZFBpcGVsaW5lQ29uZGl0aW9ucyxcbiAgYnVpbGRNZXNzYWdlQ29uZGl0aW9ucyxcbiAgdmFsaWRhdGVNZXNzYWdlRmlsdGVyLFxuICBidWlsZENvbXBsaWFuY2VQb2xpY3lDb25kaXRpb25zLFxuICBidWlsZENvbXBsaWFuY2VSdWxlQ29uZGl0aW9ucyxcbiAgYnVpbGRDb21wbGlhbmNlRXhlbXB0aW9uQ29uZGl0aW9ucyxcbiAgYnVpbGRDb21wbGlhbmNlQXVkaXRDb25kaXRpb25zLFxuICBidWlsZENvbXBsaWFuY2VTY2FuQ29uZGl0aW9ucyxcbiAgYnVpbGRQdWJsaXNoZWRSdWxlQ2F0YWxvZ0NvbmRpdGlvbnMsXG4gIGJ1aWxkQ29tcGxpYW5jZVJ1bGVTdWJzY3JpcHRpb25Db25kaXRpb25zLFxuXG4gIC8vIFF1ZXJ5IGZpbHRlciB0eXBlc1xuICB0eXBlIFBsdWdpbkZpbHRlcixcbiAgdHlwZSBQaXBlbGluZUZpbHRlcixcbiAgdHlwZSBNZXNzYWdlRmlsdGVyLFxuICB0eXBlIENvbXBsaWFuY2VQb2xpY3lGaWx0ZXIsXG4gIHR5cGUgQ29tcGxpYW5jZVJ1bGVGaWx0ZXIsXG4gIHR5cGUgQ29tcGxpYW5jZUV4ZW1wdGlvbkZpbHRlcixcbiAgdHlwZSBDb21wbGlhbmNlQXVkaXRGaWx0ZXIsXG4gIHR5cGUgQ29tcGxpYW5jZVNjYW5GaWx0ZXIsXG4gIHR5cGUgQ29tcGxpYW5jZVJ1bGVTdWJzY3JpcHRpb25GaWx0ZXIsXG5cbiAgLy8gUGx1Z2luIHR5cGVzXG4gIHR5cGUgUGx1Z2luU2VjcmV0LFxuXG4gIC8vIENvbXBsaWFuY2UgdHlwZXNcbiAgdHlwZSBSdWxlU2V2ZXJpdHksXG4gIHR5cGUgUnVsZVRhcmdldCxcbiAgdHlwZSBSdWxlT3BlcmF0b3IsXG4gIHR5cGUgUnVsZUNvbmRpdGlvbk1vZGUsXG4gIHR5cGUgUnVsZVNjb3BlLFxuICB0eXBlIFJ1bGVDb25kaXRpb24sXG4gIHR5cGUgQ29tcGxpYW5jZVJvbGVUeXBlLFxuXG4gIC8vIENSVUQgc2VydmljZVxuICBDcnVkU2VydmljZSxcbiAgdHlwZSBCYXNlRW50aXR5LFxuXG4gIC8vIERyaXp6bGUgdHlwZSBoZWxwZXJzXG4gIGRyaXp6bGVSb3dzLFxuICBkcml6emxlQ291bnQsXG59IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL3BpcGVsaW5lLWRhdGEnO1xuXG4vLyBQaXBlbGluZSAoQ0RLIGNvbnN0cnVjdHMpXG5leHBvcnQgKiBmcm9tICcuL3BpcGVsaW5lL3NvdXJjZS10eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL3BpcGVsaW5lL3N0ZXAtdHlwZXMnO1xuZXhwb3J0ICogZnJvbSAnLi9waXBlbGluZS9zdGFnZS1idWlsZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vcGlwZWxpbmUvcGlwZWxpbmUtYnVpbGRlcic7XG5leHBvcnQgKiBmcm9tICcuL3BpcGVsaW5lL3BsdWdpbi1sb29rdXAnO1xuZXhwb3J0IHsgUGlwZWxpbmVDb25maWd1cmF0aW9uIH0gZnJvbSAnLi9waXBlbGluZS9waXBlbGluZS1jb25maWd1cmF0aW9uJztcbiJdfQ==
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { CodePipeline } from 'aws-cdk-lib/pipelines';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { PipelineConfiguration } from './pipeline-configuration';
|
|
4
|
+
import type { StageOptions, SynthOptions } from './step-types';
|
|
5
|
+
import type { CodeBuildDefaults } from '../core/network-types';
|
|
6
|
+
import type { MetaDataType } from '../core/pipeline-types';
|
|
7
|
+
import type { RoleConfig } from '../core/role-types';
|
|
8
|
+
/**
|
|
9
|
+
* Configuration properties for the PipelineBuilder construct
|
|
10
|
+
*/
|
|
11
|
+
export interface BuilderProps {
|
|
12
|
+
/** Project identifier (will be sanitized to lowercase alphanumeric with underscores) */
|
|
13
|
+
readonly project: string;
|
|
14
|
+
/** Organization identifier (will be sanitized to lowercase alphanumeric with underscores) */
|
|
15
|
+
readonly organization: string;
|
|
16
|
+
/** Tenant identifier for resolving per-org secrets from AWS Secrets Manager */
|
|
17
|
+
readonly orgId?: string;
|
|
18
|
+
/** Pipeline database record ID — injected as PIPELINE_ID env var for autonomous synth */
|
|
19
|
+
readonly pipelineId?: string;
|
|
20
|
+
/** Optional custom pipeline name. Defaults to: {organization}-{project}-pipeline */
|
|
21
|
+
readonly pipelineName?: string;
|
|
22
|
+
/** Global metadata inherited by all pipeline steps */
|
|
23
|
+
readonly global?: MetaDataType;
|
|
24
|
+
/**
|
|
25
|
+
* Pipeline-level CodeBuild defaults applied to all CodeBuild actions
|
|
26
|
+
* (synth, self-mutation, asset publishing) via `codeBuildDefaults`.
|
|
27
|
+
*/
|
|
28
|
+
readonly defaults?: CodeBuildDefaults;
|
|
29
|
+
/**
|
|
30
|
+
* Optional IAM role for the CodePipeline.
|
|
31
|
+
* When provided, resolves to a CDK IRole and is passed to the CodePipeline construct.
|
|
32
|
+
* When omitted, CDK auto-creates a role with the correct codepipeline.amazonaws.com principal.
|
|
33
|
+
*/
|
|
34
|
+
readonly role?: RoleConfig;
|
|
35
|
+
/** Synthesis configuration including source and plugin details */
|
|
36
|
+
readonly synth: SynthOptions;
|
|
37
|
+
/**
|
|
38
|
+
* Optional pipeline stages, each containing one or more CodeBuild steps.
|
|
39
|
+
* Stages are added as waves to the CodePipeline after the synth step.
|
|
40
|
+
*/
|
|
41
|
+
readonly stages?: StageOptions[];
|
|
42
|
+
/** Optional cron/rate expression for scheduled pipeline execution. */
|
|
43
|
+
readonly schedule?: string;
|
|
44
|
+
/** Custom tags applied to all pipeline resources. */
|
|
45
|
+
readonly tags?: Record<string, string>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* CDK construct that creates and configures a CodePipeline for continuous deployment.
|
|
49
|
+
*
|
|
50
|
+
* Features:
|
|
51
|
+
* - Multi-source support (S3, GitHub, CodeStar)
|
|
52
|
+
* - Plugin-based build steps
|
|
53
|
+
* - Metadata-driven configuration
|
|
54
|
+
* - Automatic tagging
|
|
55
|
+
* - Automatic sanitization of project and organization names
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* new PipelineBuilder(this, 'MyPipeline', {
|
|
60
|
+
* project: 'my-app',
|
|
61
|
+
* organization: 'my-org',
|
|
62
|
+
* synth: {
|
|
63
|
+
* source: {
|
|
64
|
+
* type: 'github',
|
|
65
|
+
* options: { repo: 'owner/repo', branch: 'main' }
|
|
66
|
+
* },
|
|
67
|
+
* plugin: { name: 'synth' }
|
|
68
|
+
* }
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare class PipelineBuilder extends Construct {
|
|
73
|
+
readonly pipeline: CodePipeline;
|
|
74
|
+
readonly config: PipelineConfiguration;
|
|
75
|
+
constructor(scope: Construct, id: string, props: BuilderProps);
|
|
76
|
+
/**
|
|
77
|
+
* Resolves CodeBuildDefaults into the shape expected by CDK's codeBuildDefaults.
|
|
78
|
+
* Combines network config, security groups, and pipeline-level environment variables
|
|
79
|
+
* (PIPELINE_ID, EXECUTION_ID, PLATFORM_BASE_URL) available to all CodeBuild actions.
|
|
80
|
+
*/
|
|
81
|
+
private resolveDefaults;
|
|
82
|
+
}
|