@pipeline-builder/pipeline-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +69 -0
- package/lib/cdk.d.ts +38 -0
- package/lib/cdk.js +44 -0
- package/lib/config/app-config.d.ts +109 -0
- package/lib/config/app-config.js +197 -0
- package/lib/config/aws-config-cdk.d.ts +49 -0
- package/lib/config/aws-config-cdk.js +65 -0
- package/lib/config/billing-config.d.ts +24 -0
- package/lib/config/billing-config.js +497 -0
- package/lib/config/config-types.d.ts +346 -0
- package/lib/config/config-types.js +4 -0
- package/lib/config/entitlements.d.ts +23 -0
- package/lib/config/entitlements.js +46 -0
- package/lib/config/handler-constants.d.ts +10 -0
- package/lib/config/handler-constants.js +39 -0
- package/lib/config/infrastructure-config.d.ts +66 -0
- package/lib/config/infrastructure-config.js +197 -0
- package/lib/config/server-config.d.ts +53 -0
- package/lib/config/server-config.js +175 -0
- package/lib/config/service-client.d.ts +13 -0
- package/lib/config/service-client.js +20 -0
- package/lib/core/artifact-manager.d.ts +62 -0
- package/lib/core/artifact-manager.js +83 -0
- package/lib/core/id-generator.d.ts +50 -0
- package/lib/core/id-generator.js +50 -0
- package/lib/core/metadata-builder.d.ts +48 -0
- package/lib/core/metadata-builder.js +278 -0
- package/lib/core/metadata-helpers.d.ts +31 -0
- package/lib/core/metadata-helpers.js +55 -0
- package/lib/core/network-types.d.ts +200 -0
- package/lib/core/network-types.js +4 -0
- package/lib/core/network.d.ts +33 -0
- package/lib/core/network.js +112 -0
- package/lib/core/pipeline-helpers.d.ts +61 -0
- package/lib/core/pipeline-helpers.js +563 -0
- package/lib/core/pipeline-types.d.ts +118 -0
- package/lib/core/pipeline-types.js +131 -0
- package/lib/core/role-types.d.ts +254 -0
- package/lib/core/role-types.js +4 -0
- package/lib/core/role.d.ts +14 -0
- package/lib/core/role.js +117 -0
- package/lib/core/security-group-types.d.ts +84 -0
- package/lib/core/security-group-types.js +4 -0
- package/lib/core/security-group.d.ts +14 -0
- package/lib/core/security-group.js +33 -0
- package/lib/handlers/plugin-lookup-handler.d.ts +32 -0
- package/lib/handlers/plugin-lookup-handler.js +292 -0
- package/lib/handlers/pnpm-lock.yaml +12 -0
- package/lib/index.d.ts +45 -0
- package/lib/index.js +53 -0
- package/lib/pipeline/pipeline-builder.d.ts +123 -0
- package/lib/pipeline/pipeline-builder.js +476 -0
- package/lib/pipeline/pipeline-configuration.d.ts +81 -0
- package/lib/pipeline/pipeline-configuration.js +214 -0
- package/lib/pipeline/plugin-lookup.d.ts +131 -0
- package/lib/pipeline/plugin-lookup.js +316 -0
- package/lib/pipeline/plugin-spec.d.ts +138 -0
- package/lib/pipeline/plugin-spec.js +4 -0
- package/lib/pipeline/source-builder.d.ts +62 -0
- package/lib/pipeline/source-builder.js +164 -0
- package/lib/pipeline/source-types.d.ts +221 -0
- package/lib/pipeline/source-types.js +4 -0
- package/lib/pipeline/stage-builder.d.ts +78 -0
- package/lib/pipeline/stage-builder.js +129 -0
- package/lib/pipeline/step-types.d.ts +222 -0
- package/lib/pipeline/step-types.js +4 -0
- package/lib/template/evaluator.d.ts +42 -0
- package/lib/template/evaluator.js +164 -0
- package/lib/template/index.d.ts +34 -0
- package/lib/template/index.js +118 -0
- package/lib/template/metrics.d.ts +10 -0
- package/lib/template/metrics.js +43 -0
- package/lib/template/plugin-resolver.d.ts +8 -0
- package/lib/template/plugin-resolver.js +48 -0
- package/lib/template/tokenizer.d.ts +49 -0
- package/lib/template/tokenizer.js +233 -0
- package/lib/template/topo-sort.d.ts +17 -0
- package/lib/template/topo-sort.js +88 -0
- package/lib/template/validate.d.ts +45 -0
- package/lib/template/validate.js +96 -0
- package/lib/template/walker.d.ts +34 -0
- package/lib/template/walker.js +83 -0
- package/package.json +184 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { CodeBuildStep, FileSet, ShellStep } from 'aws-cdk-lib/pipelines';
|
|
4
|
+
/**
|
|
5
|
+
* Manages build step artifacts with hierarchical key-based lookup.
|
|
6
|
+
* Keys follow the pattern: stageName:stageAlias:pluginName:pluginAlias:outputDirectory
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Synth step: "no-stage:no-stage-alias:cdk-synth:cdk-synth-alias:cdk.out"
|
|
11
|
+
* // Build step: "build:build-alias:nodejs-build:nodejs-build-alias:dist"
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export class ArtifactManager {
|
|
15
|
+
artifacts = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Generate a key string from artifact parameters
|
|
18
|
+
*/
|
|
19
|
+
generateKey(key) {
|
|
20
|
+
return `${key.stageName}:${key.stageAlias}:${key.pluginName}:${key.pluginAlias}:${key.outputDirectory}`;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a build step artifact
|
|
24
|
+
* @param key - The hierarchical key identifying this artifact (includes output directory)
|
|
25
|
+
* @param step - The CodeBuildStep or ShellStep to store
|
|
26
|
+
*/
|
|
27
|
+
add(key, step) {
|
|
28
|
+
this.artifacts.set(this.generateKey(key), step);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get a build step by its artifact key
|
|
32
|
+
* @param key - The hierarchical key identifying the artifact
|
|
33
|
+
* @returns The stored step, or undefined if not found
|
|
34
|
+
*/
|
|
35
|
+
get(key) {
|
|
36
|
+
return this.artifacts.get(this.generateKey(key));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the primary output FileSet from a registered step.
|
|
40
|
+
* @param key - The artifact key identifying the step
|
|
41
|
+
* @returns The primary output FileSet
|
|
42
|
+
* @throws Error if the step is not found or has no primary output
|
|
43
|
+
*/
|
|
44
|
+
getOutput(key) {
|
|
45
|
+
const step = this.require(key);
|
|
46
|
+
const output = step.primaryOutput;
|
|
47
|
+
if (!output) {
|
|
48
|
+
throw new Error(`Step '${key.pluginName}' has no primary output`);
|
|
49
|
+
}
|
|
50
|
+
return output;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Register an additional output directory on a stored step and return its FileSet.
|
|
54
|
+
* Calls CDK's addOutputDirectory() to create a named output beyond the primary.
|
|
55
|
+
* @param key - The artifact key identifying the step
|
|
56
|
+
* @param directory - The additional output directory path to register
|
|
57
|
+
* @returns The FileSet for the additional output directory
|
|
58
|
+
* @throws Error if the step is not found
|
|
59
|
+
*/
|
|
60
|
+
addOutput(key, directory) {
|
|
61
|
+
return this.require(key).addOutputDirectory(directory);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get a step by key or throw with a helpful error listing available artifacts.
|
|
65
|
+
*/
|
|
66
|
+
require(key) {
|
|
67
|
+
const step = this.get(key);
|
|
68
|
+
if (!step) {
|
|
69
|
+
const registered = this.list();
|
|
70
|
+
const available = registered.length > 0 ? ` Available: [${registered.join(', ')}]` : ' No artifacts registered.';
|
|
71
|
+
throw new Error(`No artifact registered for "${this.generateKey(key)}".${available}`);
|
|
72
|
+
}
|
|
73
|
+
return step;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* List all artifact keys
|
|
77
|
+
* @returns Array of all stored artifact key strings
|
|
78
|
+
*/
|
|
79
|
+
list() {
|
|
80
|
+
return Array.from(this.artifacts.keys());
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJ0aWZhY3QtbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL2FydGlmYWN0LW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVUxRTs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUNULFNBQVMsR0FBMkMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUUvRTs7T0FFRztJQUNLLFdBQVcsQ0FBQyxHQUFnQjtRQUNsQyxPQUFPLEdBQUcsR0FBRyxDQUFDLFNBQVMsSUFBSSxHQUFHLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDLFdBQVcsSUFBSSxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDMUcsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxHQUFHLENBQUMsR0FBZ0IsRUFBRSxJQUErQjtRQUNuRCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsR0FBRyxDQUFDLEdBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxHQUFnQjtRQUN4QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9CLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxVQUFVLHlCQUF5QixDQUFDLENBQUM7UUFDcEUsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsU0FBUyxDQUFDLEdBQWdCLEVBQUUsU0FBaUI7UUFDM0MsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRDs7T0FFRztJQUNLLE9BQU8sQ0FBQyxHQUFnQjtRQUM5QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMvQixNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsMkJBQTJCLENBQUM7WUFDakgsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3hGLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJO1FBQ0YsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMzQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgQ29kZUJ1aWxkU3RlcCwgRmlsZVNldCwgU2hlbGxTdGVwIH0gZnJvbSAnYXdzLWNkay1saWIvcGlwZWxpbmVzJztcblxuZXhwb3J0IGludGVyZmFjZSBBcnRpZmFjdEtleSB7XG4gIHJlYWRvbmx5IHN0YWdlTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBzdGFnZUFsaWFzOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBsdWdpbk5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcGx1Z2luQWxpYXM6IHN0cmluZztcbiAgcmVhZG9ubHkgb3V0cHV0RGlyZWN0b3J5OiBzdHJpbmc7XG59XG5cbi8qKlxuICogTWFuYWdlcyBidWlsZCBzdGVwIGFydGlmYWN0cyB3aXRoIGhpZXJhcmNoaWNhbCBrZXktYmFzZWQgbG9va3VwLlxuICogS2V5cyBmb2xsb3cgdGhlIHBhdHRlcm46IHN0YWdlTmFtZTpzdGFnZUFsaWFzOnBsdWdpbk5hbWU6cGx1Z2luQWxpYXM6b3V0cHV0RGlyZWN0b3J5XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIFN5bnRoIHN0ZXA6IFwibm8tc3RhZ2U6bm8tc3RhZ2UtYWxpYXM6Y2RrLXN5bnRoOmNkay1zeW50aC1hbGlhczpjZGsub3V0XCJcbiAqIC8vIEJ1aWxkIHN0ZXA6IFwiYnVpbGQ6YnVpbGQtYWxpYXM6bm9kZWpzLWJ1aWxkOm5vZGVqcy1idWlsZC1hbGlhczpkaXN0XCJcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgQXJ0aWZhY3RNYW5hZ2VyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBhcnRpZmFjdHM6IE1hcDxzdHJpbmcsIENvZGVCdWlsZFN0ZXAgfCBTaGVsbFN0ZXA+ID0gbmV3IE1hcCgpO1xuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIGtleSBzdHJpbmcgZnJvbSBhcnRpZmFjdCBwYXJhbWV0ZXJzXG4gICAqL1xuICBwcml2YXRlIGdlbmVyYXRlS2V5KGtleTogQXJ0aWZhY3RLZXkpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtrZXkuc3RhZ2VOYW1lfToke2tleS5zdGFnZUFsaWFzfToke2tleS5wbHVnaW5OYW1lfToke2tleS5wbHVnaW5BbGlhc306JHtrZXkub3V0cHV0RGlyZWN0b3J5fWA7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBidWlsZCBzdGVwIGFydGlmYWN0XG4gICAqIEBwYXJhbSBrZXkgLSBUaGUgaGllcmFyY2hpY2FsIGtleSBpZGVudGlmeWluZyB0aGlzIGFydGlmYWN0IChpbmNsdWRlcyBvdXRwdXQgZGlyZWN0b3J5KVxuICAgKiBAcGFyYW0gc3RlcCAtIFRoZSBDb2RlQnVpbGRTdGVwIG9yIFNoZWxsU3RlcCB0byBzdG9yZVxuICAgKi9cbiAgYWRkKGtleTogQXJ0aWZhY3RLZXksIHN0ZXA6IENvZGVCdWlsZFN0ZXAgfCBTaGVsbFN0ZXApOiB2b2lkIHtcbiAgICB0aGlzLmFydGlmYWN0cy5zZXQodGhpcy5nZW5lcmF0ZUtleShrZXkpLCBzdGVwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBidWlsZCBzdGVwIGJ5IGl0cyBhcnRpZmFjdCBrZXlcbiAgICogQHBhcmFtIGtleSAtIFRoZSBoaWVyYXJjaGljYWwga2V5IGlkZW50aWZ5aW5nIHRoZSBhcnRpZmFjdFxuICAgKiBAcmV0dXJucyBUaGUgc3RvcmVkIHN0ZXAsIG9yIHVuZGVmaW5lZCBpZiBub3QgZm91bmRcbiAgICovXG4gIGdldChrZXk6IEFydGlmYWN0S2V5KTogQ29kZUJ1aWxkU3RlcCB8IFNoZWxsU3RlcCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuYXJ0aWZhY3RzLmdldCh0aGlzLmdlbmVyYXRlS2V5KGtleSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcHJpbWFyeSBvdXRwdXQgRmlsZVNldCBmcm9tIGEgcmVnaXN0ZXJlZCBzdGVwLlxuICAgKiBAcGFyYW0ga2V5IC0gVGhlIGFydGlmYWN0IGtleSBpZGVudGlmeWluZyB0aGUgc3RlcFxuICAgKiBAcmV0dXJucyBUaGUgcHJpbWFyeSBvdXRwdXQgRmlsZVNldFxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBzdGVwIGlzIG5vdCBmb3VuZCBvciBoYXMgbm8gcHJpbWFyeSBvdXRwdXRcbiAgICovXG4gIGdldE91dHB1dChrZXk6IEFydGlmYWN0S2V5KTogRmlsZVNldCB7XG4gICAgY29uc3Qgc3RlcCA9IHRoaXMucmVxdWlyZShrZXkpO1xuICAgIGNvbnN0IG91dHB1dCA9IHN0ZXAucHJpbWFyeU91dHB1dDtcbiAgICBpZiAoIW91dHB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdGVwICcke2tleS5wbHVnaW5OYW1lfScgaGFzIG5vIHByaW1hcnkgb3V0cHV0YCk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgYW4gYWRkaXRpb25hbCBvdXRwdXQgZGlyZWN0b3J5IG9uIGEgc3RvcmVkIHN0ZXAgYW5kIHJldHVybiBpdHMgRmlsZVNldC5cbiAgICogQ2FsbHMgQ0RLJ3MgYWRkT3V0cHV0RGlyZWN0b3J5KCkgdG8gY3JlYXRlIGEgbmFtZWQgb3V0cHV0IGJleW9uZCB0aGUgcHJpbWFyeS5cbiAgICogQHBhcmFtIGtleSAtIFRoZSBhcnRpZmFjdCBrZXkgaWRlbnRpZnlpbmcgdGhlIHN0ZXBcbiAgICogQHBhcmFtIGRpcmVjdG9yeSAtIFRoZSBhZGRpdGlvbmFsIG91dHB1dCBkaXJlY3RvcnkgcGF0aCB0byByZWdpc3RlclxuICAgKiBAcmV0dXJucyBUaGUgRmlsZVNldCBmb3IgdGhlIGFkZGl0aW9uYWwgb3V0cHV0IGRpcmVjdG9yeVxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBzdGVwIGlzIG5vdCBmb3VuZFxuICAgKi9cbiAgYWRkT3V0cHV0KGtleTogQXJ0aWZhY3RLZXksIGRpcmVjdG9yeTogc3RyaW5nKTogRmlsZVNldCB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWlyZShrZXkpLmFkZE91dHB1dERpcmVjdG9yeShkaXJlY3RvcnkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHN0ZXAgYnkga2V5IG9yIHRocm93IHdpdGggYSBoZWxwZnVsIGVycm9yIGxpc3RpbmcgYXZhaWxhYmxlIGFydGlmYWN0cy5cbiAgICovXG4gIHByaXZhdGUgcmVxdWlyZShrZXk6IEFydGlmYWN0S2V5KTogQ29kZUJ1aWxkU3RlcCB8IFNoZWxsU3RlcCB7XG4gICAgY29uc3Qgc3RlcCA9IHRoaXMuZ2V0KGtleSk7XG4gICAgaWYgKCFzdGVwKSB7XG4gICAgICBjb25zdCByZWdpc3RlcmVkID0gdGhpcy5saXN0KCk7XG4gICAgICBjb25zdCBhdmFpbGFibGUgPSByZWdpc3RlcmVkLmxlbmd0aCA+IDAgPyBgIEF2YWlsYWJsZTogWyR7cmVnaXN0ZXJlZC5qb2luKCcsICcpfV1gIDogJyBObyBhcnRpZmFjdHMgcmVnaXN0ZXJlZC4nO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBhcnRpZmFjdCByZWdpc3RlcmVkIGZvciBcIiR7dGhpcy5nZW5lcmF0ZUtleShrZXkpfVwiLiR7YXZhaWxhYmxlfWApO1xuICAgIH1cbiAgICByZXR1cm4gc3RlcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IGFsbCBhcnRpZmFjdCBrZXlzXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIGFsbCBzdG9yZWQgYXJ0aWZhY3Qga2V5IHN0cmluZ3NcbiAgICovXG4gIGxpc3QoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuYXJ0aWZhY3RzLmtleXMoKSk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates unique CDK construct IDs by appending auto-incrementing counters
|
|
3
|
+
* to labels, with an optional stack-identity hash inserted after the first
|
|
4
|
+
* namespace segment to prevent collisions across pipelines/orgs.
|
|
5
|
+
*
|
|
6
|
+
* Why the hash matters:
|
|
7
|
+
* AWS resources with explicit names (CloudWatch log groups, IAM roles)
|
|
8
|
+
* collide if two CDK stacks generate the same name. When org A's
|
|
9
|
+
* spring-boot pipeline and org B's spring-boot pipeline both deploy a
|
|
10
|
+
* `plugin-lookup-1` log group, the second deploy fails with
|
|
11
|
+
* "Resource already exists". The hash makes each (project, org) pair
|
|
12
|
+
* produce a unique stable name without changing the rest of the label.
|
|
13
|
+
*
|
|
14
|
+
* Format with org+project:
|
|
15
|
+
* generate('plugin:lookup') → 'plugin:{hash}:lookup:1'
|
|
16
|
+
* generate('log:group') → 'log:{hash}:group:1'
|
|
17
|
+
* generate('plugin:lookup') → 'plugin:{hash}:lookup:2' (counter inc)
|
|
18
|
+
* generate('cdk:pipeline:1') → 'cdk:pipeline:1' (already counted)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const id = new UniqueId({ organization: 'AcmeCorp', project: 'spring-boot' });
|
|
23
|
+
* id.generate('plugin:lookup'); // "plugin:a1b2c3d4:lookup:1"
|
|
24
|
+
* id.generate('log:group'); // "log:a1b2c3d4:group:1"
|
|
25
|
+
* id.generate('plugin:lookup'); // "plugin:a1b2c3d4:lookup:2"
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export interface UniqueIdOptions {
|
|
29
|
+
/** Organization name — combined with project to form the stack-identity hash. */
|
|
30
|
+
readonly organization: string;
|
|
31
|
+
/** Project name — combined with organization to form the stack-identity hash. */
|
|
32
|
+
readonly project: string;
|
|
33
|
+
}
|
|
34
|
+
export declare class UniqueId {
|
|
35
|
+
private readonly _counters;
|
|
36
|
+
private readonly _stackId;
|
|
37
|
+
constructor(opts: UniqueIdOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Returns a unique construct ID for the given label.
|
|
40
|
+
* If the label already ends with a numeric counter, it is returned as-is.
|
|
41
|
+
* Otherwise, an auto-incrementing counter is appended; if a stack-identity
|
|
42
|
+
* hash was provided at construction, it's inserted after the first segment.
|
|
43
|
+
*
|
|
44
|
+
* @param label - Colon-separated namespace (e.g., 'plugin:lookup')
|
|
45
|
+
* @returns The label with hash + counter inserted
|
|
46
|
+
*/
|
|
47
|
+
generate(label: string): string;
|
|
48
|
+
/** The stack-identity hash derived from organization + project. */
|
|
49
|
+
get stackId(): string;
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { createHash } from 'crypto';
|
|
4
|
+
export class UniqueId {
|
|
5
|
+
_counters = new Map();
|
|
6
|
+
_stackId;
|
|
7
|
+
constructor(opts) {
|
|
8
|
+
// 8 hex chars = 32 bits = 1 in 4 billion collision odds across pipelines.
|
|
9
|
+
// Lowercased for case-insensitive stability ("AcmeCorp" === "acmecorp").
|
|
10
|
+
this._stackId = createHash('sha256')
|
|
11
|
+
.update(`${opts.project}:${opts.organization}`.toLowerCase())
|
|
12
|
+
.digest('hex')
|
|
13
|
+
.slice(0, 8);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Returns a unique construct ID for the given label.
|
|
17
|
+
* If the label already ends with a numeric counter, it is returned as-is.
|
|
18
|
+
* Otherwise, an auto-incrementing counter is appended; if a stack-identity
|
|
19
|
+
* hash was provided at construction, it's inserted after the first segment.
|
|
20
|
+
*
|
|
21
|
+
* @param label - Colon-separated namespace (e.g., 'plugin:lookup')
|
|
22
|
+
* @returns The label with hash + counter inserted
|
|
23
|
+
*/
|
|
24
|
+
generate(label) {
|
|
25
|
+
if (!label || typeof label !== 'string') {
|
|
26
|
+
throw new Error('Label must be a non-empty string');
|
|
27
|
+
}
|
|
28
|
+
// Already counted (e.g., 'cdk:pipeline:1') — pass through.
|
|
29
|
+
if (/:\d+$/.test(label)) {
|
|
30
|
+
return label;
|
|
31
|
+
}
|
|
32
|
+
const count = (this._counters.get(label) ?? 0) + 1;
|
|
33
|
+
this._counters.set(label, count);
|
|
34
|
+
// Insert the stack hash after the first namespace segment so the leading
|
|
35
|
+
// category (`plugin`, `log`, `resource`, etc.) stays human-readable.
|
|
36
|
+
const idx = label.indexOf(':');
|
|
37
|
+
if (idx === -1) {
|
|
38
|
+
// Single-segment label — put the hash before the counter.
|
|
39
|
+
return `${label}:${this._stackId}:${count}`;
|
|
40
|
+
}
|
|
41
|
+
const head = label.slice(0, idx);
|
|
42
|
+
const tail = label.slice(idx + 1);
|
|
43
|
+
return `${head}:${this._stackId}:${tail}:${count}`;
|
|
44
|
+
}
|
|
45
|
+
/** The stack-identity hash derived from organization + project. */
|
|
46
|
+
get stackId() {
|
|
47
|
+
return this._stackId;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWQtZ2VuZXJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvcmUvaWQtZ2VuZXJhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQW9DcEMsTUFBTSxPQUFPLFFBQVE7SUFDRixTQUFTLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDdEMsUUFBUSxDQUFTO0lBRWxDLFlBQVksSUFBcUI7UUFDL0IsMEVBQTBFO1FBQzFFLHlFQUF5RTtRQUN6RSxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7YUFDakMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7YUFDNUQsTUFBTSxDQUFDLEtBQUssQ0FBQzthQUNiLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsUUFBUSxDQUFDLEtBQWE7UUFDcEIsSUFBSSxDQUFDLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN4QyxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELDJEQUEyRDtRQUMzRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFakMseUVBQXlFO1FBQ3pFLHFFQUFxRTtRQUNyRSxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9CLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDZiwwREFBMEQ7WUFDMUQsT0FBTyxHQUFHLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzlDLENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNqQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNsQyxPQUFPLEdBQUcsSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO0lBQ3JELENBQUM7SUFFRCxtRUFBbUU7SUFDbkUsSUFBSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSAnY3J5cHRvJztcblxuLyoqXG4gKiBHZW5lcmF0ZXMgdW5pcXVlIENESyBjb25zdHJ1Y3QgSURzIGJ5IGFwcGVuZGluZyBhdXRvLWluY3JlbWVudGluZyBjb3VudGVyc1xuICogdG8gbGFiZWxzLCB3aXRoIGFuIG9wdGlvbmFsIHN0YWNrLWlkZW50aXR5IGhhc2ggaW5zZXJ0ZWQgYWZ0ZXIgdGhlIGZpcnN0XG4gKiBuYW1lc3BhY2Ugc2VnbWVudCB0byBwcmV2ZW50IGNvbGxpc2lvbnMgYWNyb3NzIHBpcGVsaW5lcy9vcmdzLlxuICpcbiAqIFdoeSB0aGUgaGFzaCBtYXR0ZXJzOlxuICogICBBV1MgcmVzb3VyY2VzIHdpdGggZXhwbGljaXQgbmFtZXMgKENsb3VkV2F0Y2ggbG9nIGdyb3VwcywgSUFNIHJvbGVzKVxuICogICBjb2xsaWRlIGlmIHR3byBDREsgc3RhY2tzIGdlbmVyYXRlIHRoZSBzYW1lIG5hbWUuIFdoZW4gb3JnIEEnc1xuICogICBzcHJpbmctYm9vdCBwaXBlbGluZSBhbmQgb3JnIEIncyBzcHJpbmctYm9vdCBwaXBlbGluZSBib3RoIGRlcGxveSBhXG4gKiAgIGBwbHVnaW4tbG9va3VwLTFgIGxvZyBncm91cCwgdGhlIHNlY29uZCBkZXBsb3kgZmFpbHMgd2l0aFxuICogICBcIlJlc291cmNlIGFscmVhZHkgZXhpc3RzXCIuIFRoZSBoYXNoIG1ha2VzIGVhY2ggKHByb2plY3QsIG9yZykgcGFpclxuICogICBwcm9kdWNlIGEgdW5pcXVlIHN0YWJsZSBuYW1lIHdpdGhvdXQgY2hhbmdpbmcgdGhlIHJlc3Qgb2YgdGhlIGxhYmVsLlxuICpcbiAqIEZvcm1hdCB3aXRoIG9yZytwcm9qZWN0OlxuICogICBnZW5lcmF0ZSgncGx1Z2luOmxvb2t1cCcpICAg4oaSICdwbHVnaW46e2hhc2h9Omxvb2t1cDoxJ1xuICogICBnZW5lcmF0ZSgnbG9nOmdyb3VwJykgICAgICAg4oaSICdsb2c6e2hhc2h9Omdyb3VwOjEnXG4gKiAgIGdlbmVyYXRlKCdwbHVnaW46bG9va3VwJykgICDihpIgJ3BsdWdpbjp7aGFzaH06bG9va3VwOjInICAgKGNvdW50ZXIgaW5jKVxuICogICBnZW5lcmF0ZSgnY2RrOnBpcGVsaW5lOjEnKSAg4oaSICdjZGs6cGlwZWxpbmU6MScgICAgICAgICAgIChhbHJlYWR5IGNvdW50ZWQpXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGlkID0gbmV3IFVuaXF1ZUlkKHsgb3JnYW5pemF0aW9uOiAnQWNtZUNvcnAnLCBwcm9qZWN0OiAnc3ByaW5nLWJvb3QnIH0pO1xuICogaWQuZ2VuZXJhdGUoJ3BsdWdpbjpsb29rdXAnKTsgICAvLyBcInBsdWdpbjphMWIyYzNkNDpsb29rdXA6MVwiXG4gKiBpZC5nZW5lcmF0ZSgnbG9nOmdyb3VwJyk7ICAgICAgIC8vIFwibG9nOmExYjJjM2Q0Omdyb3VwOjFcIlxuICogaWQuZ2VuZXJhdGUoJ3BsdWdpbjpsb29rdXAnKTsgICAvLyBcInBsdWdpbjphMWIyYzNkNDpsb29rdXA6MlwiXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVbmlxdWVJZE9wdGlvbnMge1xuICAvKiogT3JnYW5pemF0aW9uIG5hbWUg4oCUIGNvbWJpbmVkIHdpdGggcHJvamVjdCB0byBmb3JtIHRoZSBzdGFjay1pZGVudGl0eSBoYXNoLiAqL1xuICByZWFkb25seSBvcmdhbml6YXRpb246IHN0cmluZztcbiAgLyoqIFByb2plY3QgbmFtZSDigJQgY29tYmluZWQgd2l0aCBvcmdhbml6YXRpb24gdG8gZm9ybSB0aGUgc3RhY2staWRlbnRpdHkgaGFzaC4gKi9cbiAgcmVhZG9ubHkgcHJvamVjdDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgVW5pcXVlSWQge1xuICBwcml2YXRlIHJlYWRvbmx5IF9jb3VudGVycyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3N0YWNrSWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihvcHRzOiBVbmlxdWVJZE9wdGlvbnMpIHtcbiAgICAvLyA4IGhleCBjaGFycyA9IDMyIGJpdHMgPSAxIGluIDQgYmlsbGlvbiBjb2xsaXNpb24gb2RkcyBhY3Jvc3MgcGlwZWxpbmVzLlxuICAgIC8vIExvd2VyY2FzZWQgZm9yIGNhc2UtaW5zZW5zaXRpdmUgc3RhYmlsaXR5IChcIkFjbWVDb3JwXCIgPT09IFwiYWNtZWNvcnBcIikuXG4gICAgdGhpcy5fc3RhY2tJZCA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpXG4gICAgICAudXBkYXRlKGAke29wdHMucHJvamVjdH06JHtvcHRzLm9yZ2FuaXphdGlvbn1gLnRvTG93ZXJDYXNlKCkpXG4gICAgICAuZGlnZXN0KCdoZXgnKVxuICAgICAgLnNsaWNlKDAsIDgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB1bmlxdWUgY29uc3RydWN0IElEIGZvciB0aGUgZ2l2ZW4gbGFiZWwuXG4gICAqIElmIHRoZSBsYWJlbCBhbHJlYWR5IGVuZHMgd2l0aCBhIG51bWVyaWMgY291bnRlciwgaXQgaXMgcmV0dXJuZWQgYXMtaXMuXG4gICAqIE90aGVyd2lzZSwgYW4gYXV0by1pbmNyZW1lbnRpbmcgY291bnRlciBpcyBhcHBlbmRlZDsgaWYgYSBzdGFjay1pZGVudGl0eVxuICAgKiBoYXNoIHdhcyBwcm92aWRlZCBhdCBjb25zdHJ1Y3Rpb24sIGl0J3MgaW5zZXJ0ZWQgYWZ0ZXIgdGhlIGZpcnN0IHNlZ21lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBsYWJlbCAtIENvbG9uLXNlcGFyYXRlZCBuYW1lc3BhY2UgKGUuZy4sICdwbHVnaW46bG9va3VwJylcbiAgICogQHJldHVybnMgVGhlIGxhYmVsIHdpdGggaGFzaCArIGNvdW50ZXIgaW5zZXJ0ZWRcbiAgICovXG4gIGdlbmVyYXRlKGxhYmVsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghbGFiZWwgfHwgdHlwZW9mIGxhYmVsICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdMYWJlbCBtdXN0IGJlIGEgbm9uLWVtcHR5IHN0cmluZycpO1xuICAgIH1cblxuICAgIC8vIEFscmVhZHkgY291bnRlZCAoZS5nLiwgJ2NkazpwaXBlbGluZToxJykg4oCUIHBhc3MgdGhyb3VnaC5cbiAgICBpZiAoLzpcXGQrJC8udGVzdChsYWJlbCkpIHtcbiAgICAgIHJldHVybiBsYWJlbDtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudCA9ICh0aGlzLl9jb3VudGVycy5nZXQobGFiZWwpID8/IDApICsgMTtcbiAgICB0aGlzLl9jb3VudGVycy5zZXQobGFiZWwsIGNvdW50KTtcblxuICAgIC8vIEluc2VydCB0aGUgc3RhY2sgaGFzaCBhZnRlciB0aGUgZmlyc3QgbmFtZXNwYWNlIHNlZ21lbnQgc28gdGhlIGxlYWRpbmdcbiAgICAvLyBjYXRlZ29yeSAoYHBsdWdpbmAsIGBsb2dgLCBgcmVzb3VyY2VgLCBldGMuKSBzdGF5cyBodW1hbi1yZWFkYWJsZS5cbiAgICBjb25zdCBpZHggPSBsYWJlbC5pbmRleE9mKCc6Jyk7XG4gICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgIC8vIFNpbmdsZS1zZWdtZW50IGxhYmVsIOKAlCBwdXQgdGhlIGhhc2ggYmVmb3JlIHRoZSBjb3VudGVyLlxuICAgICAgcmV0dXJuIGAke2xhYmVsfToke3RoaXMuX3N0YWNrSWR9OiR7Y291bnR9YDtcbiAgICB9XG4gICAgY29uc3QgaGVhZCA9IGxhYmVsLnNsaWNlKDAsIGlkeCk7XG4gICAgY29uc3QgdGFpbCA9IGxhYmVsLnNsaWNlKGlkeCArIDEpO1xuICAgIHJldHVybiBgJHtoZWFkfToke3RoaXMuX3N0YWNrSWR9OiR7dGFpbH06JHtjb3VudH1gO1xuICB9XG5cbiAgLyoqIFRoZSBzdGFjay1pZGVudGl0eSBoYXNoIGRlcml2ZWQgZnJvbSBvcmdhbml6YXRpb24gKyBwcm9qZWN0LiAqL1xuICBnZXQgc3RhY2tJZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zdGFja0lkO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { BuildEnvironment } from 'aws-cdk-lib/aws-codebuild';
|
|
2
|
+
import type { CodeBuildStepProps, CodePipelineProps, ShellStepProps } from 'aws-cdk-lib/pipelines';
|
|
3
|
+
import type { NetworkConfig } from './network-types.js';
|
|
4
|
+
import type { MetaDataType } from './pipeline-types.js';
|
|
5
|
+
import type { RoleConfig } from './role-types.js';
|
|
6
|
+
import type { SecurityGroupConfig } from './security-group-types.js';
|
|
7
|
+
/** Extract CDK construct config from metadata for a given namespace. */
|
|
8
|
+
export declare function buildConfigFromMetadata(metadata: MetaDataType, namespace: string): Record<string, unknown>;
|
|
9
|
+
/** Extract CodePipeline config from metadata. */
|
|
10
|
+
export declare function metadataForCodePipeline(metadata: MetaDataType): Partial<CodePipelineProps>;
|
|
11
|
+
/** Extract CodeBuildStep config from metadata. */
|
|
12
|
+
export declare function metadataForCodeBuildStep(metadata: MetaDataType): Partial<CodeBuildStepProps>;
|
|
13
|
+
/** Extract ShellStep config from metadata. */
|
|
14
|
+
export declare function metadataForShellStep(metadata: MetaDataType): Partial<ShellStepProps>;
|
|
15
|
+
/** Extract BuildEnvironment config from metadata. */
|
|
16
|
+
export declare function metadataForBuildEnvironment(metadata: MetaDataType): Partial<BuildEnvironment>;
|
|
17
|
+
/** Coerce a metadata value to a positive integer; undefined if absent/invalid. */
|
|
18
|
+
export declare function asInt(v: unknown): number | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Build a NetworkConfig from `ec2:network` metadata keys. The variant comes
|
|
21
|
+
* from NETWORK_TYPE, or is inferred (subnetIds -> subnetIds, tags -> vpcLookup,
|
|
22
|
+
* vpcId -> vpcId). Returns undefined when no usable network metadata is present.
|
|
23
|
+
*/
|
|
24
|
+
export declare function networkConfigFromMetadata(metadata: MetaDataType): NetworkConfig | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Build a RoleConfig from `iam:role` metadata keys (roleArn / roleName /
|
|
27
|
+
* codeBuildDefault). The 4 keys can't express the full `oidc` option set, so an
|
|
28
|
+
* `oidc` type from metadata is ignored. Returns undefined when no keys are set.
|
|
29
|
+
*/
|
|
30
|
+
export declare function roleConfigFromMetadata(metadata: MetaDataType): RoleConfig | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Build a SecurityGroupConfig from `ec2:securitygroup` metadata keys
|
|
33
|
+
* (securityGroupIds / securityGroupLookup). Returns undefined when no keys set.
|
|
34
|
+
*/
|
|
35
|
+
export declare function securityGroupConfigFromMetadata(metadata: MetaDataType): SecurityGroupConfig | undefined;
|
|
36
|
+
/** A CodePipeline V2 pipeline-level variable parsed from `operations.variables`. */
|
|
37
|
+
export interface PipelineVariableSpec {
|
|
38
|
+
name: string;
|
|
39
|
+
defaultValue?: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse `operations.variables` metadata into CodePipeline V2 variable specs.
|
|
44
|
+
* Accepts a JSON array (`[{"name":"ENV","default":"prod","description":"..."}]`)
|
|
45
|
+
* or a compact comma-separated `name=default` list (`ENV=prod,REGION=us-east-1`).
|
|
46
|
+
* Entries without a usable name are skipped; returns [] when nothing valid.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parsePipelineVariables(value: unknown): PipelineVariableSpec[];
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { CDK_METADATA_PREFIX, MetadataKeys } from './pipeline-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Type-safe namespace constants for metadata configuration.
|
|
6
|
+
*/
|
|
7
|
+
const NAMESPACE = {
|
|
8
|
+
SHELL_STEP: 'pipelines:shellstep',
|
|
9
|
+
CODE_BUILD_STEP: 'pipelines:codebuildstep',
|
|
10
|
+
BUILD_ENVIRONMENT: 'codebuild:buildenvironment',
|
|
11
|
+
CODE_PIPELINE: 'pipelines:codepipeline',
|
|
12
|
+
};
|
|
13
|
+
const NAMESPACE_KEY_MAP = {
|
|
14
|
+
[NAMESPACE.SHELL_STEP]: {
|
|
15
|
+
booleanKeys: [],
|
|
16
|
+
passthroughKeys: ['additionalInputs', 'commands', 'env', 'envFromCfnOutputs', 'input', 'installCommands', 'primaryOutputDirectory'],
|
|
17
|
+
},
|
|
18
|
+
[NAMESPACE.CODE_BUILD_STEP]: {
|
|
19
|
+
booleanKeys: [],
|
|
20
|
+
passthroughKeys: ['actionRole', 'additionalInputs', 'buildEnvironment', 'cache', 'commands', 'env', 'envFromCfnOutputs', 'fileSystemLocations', 'input', 'installCommands', 'logging', 'partialBuildSpec', 'primaryOutputDirectory', 'projectName', 'role', 'rolePolicyStatements', 'timeout'],
|
|
21
|
+
},
|
|
22
|
+
[NAMESPACE.BUILD_ENVIRONMENT]: {
|
|
23
|
+
booleanKeys: ['privileged'],
|
|
24
|
+
passthroughKeys: ['buildImage', 'certificate', 'computeType', 'dockerServer', 'environmentVariables', 'fleet'],
|
|
25
|
+
},
|
|
26
|
+
[NAMESPACE.CODE_PIPELINE]: {
|
|
27
|
+
booleanKeys: ['crossAccountKeys', 'dockerEnabledForSelfMutation', 'dockerEnabledForSynth', 'enableKeyRotation', 'publishAssetsInParallel', 'reuseCrossRegionSupportStacks', 'selfMutation', 'useChangeSets', 'usePipelineRoleForActions'],
|
|
28
|
+
passthroughKeys: ['artifactBucket', 'assetPublishingCodeBuildDefaults', 'cdkAssetsCliVersion', 'cliVersion', 'codeBuildDefaults', 'codePipeline', 'crossRegionReplicationBuckets', 'dockerCredentials', 'pipelineName', 'pipelineType', 'role', 'selfMutationCodeBuildDefaults', 'synth', 'synthCodeBuildDefaults'],
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const EMPTY_KEY_CONFIG = { booleanKeys: [], passthroughKeys: [] };
|
|
32
|
+
function getCustomKey(prefix, key) {
|
|
33
|
+
return `${CDK_METADATA_PREFIX}${prefix}:${key}`.toLowerCase();
|
|
34
|
+
}
|
|
35
|
+
function isTrue(value) {
|
|
36
|
+
if (typeof value === 'boolean')
|
|
37
|
+
return value;
|
|
38
|
+
if (typeof value === 'string')
|
|
39
|
+
return value.toLowerCase() === 'true';
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
/** Extract CDK construct config from metadata for a given namespace. */
|
|
43
|
+
export function buildConfigFromMetadata(metadata, namespace) {
|
|
44
|
+
const { booleanKeys, passthroughKeys } = NAMESPACE_KEY_MAP[namespace] ?? EMPTY_KEY_CONFIG;
|
|
45
|
+
const result = {};
|
|
46
|
+
for (const key of booleanKeys) {
|
|
47
|
+
const raw = metadata[getCustomKey(namespace, key)];
|
|
48
|
+
if (raw !== undefined)
|
|
49
|
+
result[key] = isTrue(raw);
|
|
50
|
+
}
|
|
51
|
+
for (const key of passthroughKeys) {
|
|
52
|
+
const raw = metadata[getCustomKey(namespace, key)];
|
|
53
|
+
if (raw !== undefined)
|
|
54
|
+
result[key] = raw;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
/** Extract CodePipeline config from metadata. */
|
|
59
|
+
export function metadataForCodePipeline(metadata) {
|
|
60
|
+
return buildConfigFromMetadata(metadata, NAMESPACE.CODE_PIPELINE);
|
|
61
|
+
}
|
|
62
|
+
/** Extract CodeBuildStep config from metadata. */
|
|
63
|
+
export function metadataForCodeBuildStep(metadata) {
|
|
64
|
+
return buildConfigFromMetadata(metadata, NAMESPACE.CODE_BUILD_STEP);
|
|
65
|
+
}
|
|
66
|
+
/** Extract ShellStep config from metadata. */
|
|
67
|
+
export function metadataForShellStep(metadata) {
|
|
68
|
+
return buildConfigFromMetadata(metadata, NAMESPACE.SHELL_STEP);
|
|
69
|
+
}
|
|
70
|
+
/** Extract BuildEnvironment config from metadata. */
|
|
71
|
+
export function metadataForBuildEnvironment(metadata) {
|
|
72
|
+
return buildConfigFromMetadata(metadata, NAMESPACE.BUILD_ENVIRONMENT);
|
|
73
|
+
}
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Typed-config extractors: ec2:network / iam:role / ec2:securitygroup metadata
|
|
76
|
+
// -> the discriminated-union config objects the builder already consumes
|
|
77
|
+
// (NetworkConfig / RoleConfig / SecurityGroupConfig). Unlike the namespaces
|
|
78
|
+
// above (which map 1:1 to CDK construct props), these feed resolveNetwork /
|
|
79
|
+
// resolveRole / resolveSecurityGroup. Each returns undefined when its keys are
|
|
80
|
+
// absent, so callers fall through with `prop ?? metadata ?? env` precedence.
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
function asStr(v) {
|
|
83
|
+
return typeof v === 'string' && v.trim() !== '' ? v : undefined;
|
|
84
|
+
}
|
|
85
|
+
/** Accept a JSON array or a comma-separated string -> string[] (undefined if empty). */
|
|
86
|
+
function asList(v) {
|
|
87
|
+
const items = Array.isArray(v)
|
|
88
|
+
? v.map(String).map(s => s.trim()).filter(Boolean)
|
|
89
|
+
: typeof v === 'string' && v.trim() !== ''
|
|
90
|
+
? v.split(',').map(s => s.trim()).filter(Boolean)
|
|
91
|
+
: [];
|
|
92
|
+
return items.length > 0 ? items : undefined;
|
|
93
|
+
}
|
|
94
|
+
/** Accept a JSON object or a JSON string -> Record<string,string> (undefined if empty). */
|
|
95
|
+
function asTags(v) {
|
|
96
|
+
let obj = v;
|
|
97
|
+
if (typeof v === 'string' && v.trim() !== '') {
|
|
98
|
+
try {
|
|
99
|
+
obj = JSON.parse(v);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
|
|
106
|
+
const entries = Object.entries(obj).map(([k, val]) => [k, String(val)]);
|
|
107
|
+
return entries.length > 0 ? Object.fromEntries(entries) : undefined;
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
/** undefined when the key is absent; otherwise a coerced boolean. */
|
|
112
|
+
function asBool(v) {
|
|
113
|
+
return v === undefined ? undefined : isTrue(v);
|
|
114
|
+
}
|
|
115
|
+
/** Coerce a metadata value to a positive integer; undefined if absent/invalid. */
|
|
116
|
+
export function asInt(v) {
|
|
117
|
+
if (v === undefined || v === null || v === '')
|
|
118
|
+
return undefined;
|
|
119
|
+
const n = typeof v === 'number' ? v : Number(String(v).trim());
|
|
120
|
+
return Number.isInteger(n) && n > 0 ? n : undefined;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Build a NetworkConfig from `ec2:network` metadata keys. The variant comes
|
|
124
|
+
* from NETWORK_TYPE, or is inferred (subnetIds -> subnetIds, tags -> vpcLookup,
|
|
125
|
+
* vpcId -> vpcId). Returns undefined when no usable network metadata is present.
|
|
126
|
+
*/
|
|
127
|
+
export function networkConfigFromMetadata(metadata) {
|
|
128
|
+
const type = asStr(metadata[MetadataKeys.NETWORK_TYPE]);
|
|
129
|
+
const vpcId = asStr(metadata[MetadataKeys.NETWORK_VPC_ID]);
|
|
130
|
+
const subnetIds = asList(metadata[MetadataKeys.NETWORK_SUBNET_IDS]);
|
|
131
|
+
const subnetType = asStr(metadata[MetadataKeys.NETWORK_SUBNET_TYPE]);
|
|
132
|
+
const availabilityZones = asList(metadata[MetadataKeys.NETWORK_AVAILABILITY_ZONES]);
|
|
133
|
+
const subnetGroupName = asStr(metadata[MetadataKeys.NETWORK_SUBNET_GROUP_NAME]);
|
|
134
|
+
const securityGroupIds = asList(metadata[MetadataKeys.NETWORK_SECURITY_GROUP_IDS]);
|
|
135
|
+
const tags = asTags(metadata[MetadataKeys.NETWORK_TAGS]);
|
|
136
|
+
const vpcName = asStr(metadata[MetadataKeys.NETWORK_VPC_NAME]);
|
|
137
|
+
const region = asStr(metadata[MetadataKeys.NETWORK_REGION]);
|
|
138
|
+
const variant = type ?? (subnetIds ? 'subnetIds' : tags ? 'vpcLookup' : vpcId ? 'vpcId' : undefined);
|
|
139
|
+
switch (variant) {
|
|
140
|
+
case 'subnetIds':
|
|
141
|
+
if (!vpcId || !subnetIds)
|
|
142
|
+
return undefined;
|
|
143
|
+
return { type: 'subnetIds', options: { vpcId, subnetIds, ...(securityGroupIds && { securityGroupIds }) } };
|
|
144
|
+
case 'vpcId':
|
|
145
|
+
if (!vpcId)
|
|
146
|
+
return undefined;
|
|
147
|
+
return {
|
|
148
|
+
type: 'vpcId',
|
|
149
|
+
options: {
|
|
150
|
+
vpcId,
|
|
151
|
+
...(subnetType && { subnetType }),
|
|
152
|
+
...(availabilityZones && { availabilityZones }),
|
|
153
|
+
...(subnetGroupName && { subnetGroupName }),
|
|
154
|
+
...(securityGroupIds && { securityGroupIds }),
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
case 'vpcLookup':
|
|
158
|
+
if (!tags)
|
|
159
|
+
return undefined;
|
|
160
|
+
return {
|
|
161
|
+
type: 'vpcLookup',
|
|
162
|
+
options: {
|
|
163
|
+
tags,
|
|
164
|
+
...(subnetType && { subnetType }),
|
|
165
|
+
...(availabilityZones && { availabilityZones }),
|
|
166
|
+
...(subnetGroupName && { subnetGroupName }),
|
|
167
|
+
...(securityGroupIds && { securityGroupIds }),
|
|
168
|
+
...(vpcName && { vpcName }),
|
|
169
|
+
...(region && { region }),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
default:
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Build a RoleConfig from `iam:role` metadata keys (roleArn / roleName /
|
|
178
|
+
* codeBuildDefault). The 4 keys can't express the full `oidc` option set, so an
|
|
179
|
+
* `oidc` type from metadata is ignored. Returns undefined when no keys are set.
|
|
180
|
+
*/
|
|
181
|
+
export function roleConfigFromMetadata(metadata) {
|
|
182
|
+
const type = asStr(metadata[MetadataKeys.ROLE_TYPE]);
|
|
183
|
+
const roleArn = asStr(metadata[MetadataKeys.ROLE_ARN]);
|
|
184
|
+
const roleName = asStr(metadata[MetadataKeys.ROLE_NAME]);
|
|
185
|
+
const mutable = asBool(metadata[MetadataKeys.ROLE_MUTABLE]);
|
|
186
|
+
const variant = type ?? (roleArn ? 'roleArn' : roleName ? 'roleName' : undefined);
|
|
187
|
+
switch (variant) {
|
|
188
|
+
case 'roleArn':
|
|
189
|
+
if (!roleArn)
|
|
190
|
+
return undefined;
|
|
191
|
+
return { type: 'roleArn', options: { roleArn, ...(mutable !== undefined && { mutable }) } };
|
|
192
|
+
case 'roleName':
|
|
193
|
+
if (!roleName)
|
|
194
|
+
return undefined;
|
|
195
|
+
return { type: 'roleName', options: { roleName, ...(mutable !== undefined && { mutable }) } };
|
|
196
|
+
case 'codeBuildDefault':
|
|
197
|
+
return { type: 'codeBuildDefault', options: { ...(roleName && { roleName }) } };
|
|
198
|
+
default:
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Build a SecurityGroupConfig from `ec2:securitygroup` metadata keys
|
|
204
|
+
* (securityGroupIds / securityGroupLookup). Returns undefined when no keys set.
|
|
205
|
+
*/
|
|
206
|
+
export function securityGroupConfigFromMetadata(metadata) {
|
|
207
|
+
const type = asStr(metadata[MetadataKeys.SECURITY_GROUP_TYPE]);
|
|
208
|
+
const ids = asList(metadata[MetadataKeys.SECURITY_GROUP_IDS]);
|
|
209
|
+
const mutable = asBool(metadata[MetadataKeys.SECURITY_GROUP_MUTABLE]);
|
|
210
|
+
const name = asStr(metadata[MetadataKeys.SECURITY_GROUP_NAME]);
|
|
211
|
+
const vpcId = asStr(metadata[MetadataKeys.SECURITY_GROUP_VPC_ID]);
|
|
212
|
+
const variant = type ?? (ids ? 'securityGroupIds' : name ? 'securityGroupLookup' : undefined);
|
|
213
|
+
switch (variant) {
|
|
214
|
+
case 'securityGroupIds':
|
|
215
|
+
if (!ids)
|
|
216
|
+
return undefined;
|
|
217
|
+
return { type: 'securityGroupIds', options: { securityGroupIds: ids, ...(mutable !== undefined && { mutable }) } };
|
|
218
|
+
case 'securityGroupLookup':
|
|
219
|
+
if (!name || !vpcId)
|
|
220
|
+
return undefined;
|
|
221
|
+
return { type: 'securityGroupLookup', options: { securityGroupName: name, vpcId } };
|
|
222
|
+
default:
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Parse `operations.variables` metadata into CodePipeline V2 variable specs.
|
|
228
|
+
* Accepts a JSON array (`[{"name":"ENV","default":"prod","description":"..."}]`)
|
|
229
|
+
* or a compact comma-separated `name=default` list (`ENV=prod,REGION=us-east-1`).
|
|
230
|
+
* Entries without a usable name are skipped; returns [] when nothing valid.
|
|
231
|
+
*/
|
|
232
|
+
export function parsePipelineVariables(value) {
|
|
233
|
+
if (value === undefined || value === null || value === '')
|
|
234
|
+
return [];
|
|
235
|
+
// Already an array (JSON-typed metadata) or a JSON-encoded string.
|
|
236
|
+
let parsed = value;
|
|
237
|
+
if (typeof value === 'string') {
|
|
238
|
+
const trimmed = value.trim();
|
|
239
|
+
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
240
|
+
try {
|
|
241
|
+
parsed = JSON.parse(trimmed);
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
parsed = value;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (Array.isArray(parsed)) {
|
|
249
|
+
const specs = [];
|
|
250
|
+
for (const entry of parsed) {
|
|
251
|
+
if (!entry || typeof entry !== 'object')
|
|
252
|
+
continue;
|
|
253
|
+
const e = entry;
|
|
254
|
+
const name = asStr(e.name);
|
|
255
|
+
if (!name)
|
|
256
|
+
continue;
|
|
257
|
+
const defaultValue = asStr(e.default) ?? asStr(e.defaultValue);
|
|
258
|
+
const description = asStr(e.description);
|
|
259
|
+
specs.push({ name, ...(defaultValue !== undefined && { defaultValue }), ...(description !== undefined && { description }) });
|
|
260
|
+
}
|
|
261
|
+
return specs;
|
|
262
|
+
}
|
|
263
|
+
// Compact `name=default` comma list.
|
|
264
|
+
if (typeof parsed === 'string') {
|
|
265
|
+
const specs = [];
|
|
266
|
+
for (const pair of parsed.split(',')) {
|
|
267
|
+
const idx = pair.indexOf('=');
|
|
268
|
+
const name = (idx === -1 ? pair : pair.slice(0, idx)).trim();
|
|
269
|
+
if (!name)
|
|
270
|
+
continue;
|
|
271
|
+
const defaultValue = idx === -1 ? undefined : pair.slice(idx + 1).trim();
|
|
272
|
+
specs.push({ name, ...(defaultValue ? { defaultValue } : {}) });
|
|
273
|
+
}
|
|
274
|
+
return specs;
|
|
275
|
+
}
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YWRhdGEtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL21ldGFkYXRhLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUt0QyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFLeEU7O0dBRUc7QUFDSCxNQUFNLFNBQVMsR0FBRztJQUNoQixVQUFVLEVBQUUscUJBQXFCO0lBQ2pDLGVBQWUsRUFBRSx5QkFBeUI7SUFDMUMsaUJBQWlCLEVBQUUsNEJBQTRCO0lBQy9DLGFBQWEsRUFBRSx3QkFBd0I7Q0FDL0IsQ0FBQztBQVFYLE1BQU0saUJBQWlCLEdBQTBDO0lBQy9ELENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFO1FBQ3RCLFdBQVcsRUFBRSxFQUFFO1FBQ2YsZUFBZSxFQUFFLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsd0JBQXdCLENBQUM7S0FDcEk7SUFDRCxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsRUFBRTtRQUMzQixXQUFXLEVBQUUsRUFBRTtRQUNmLGVBQWUsRUFBRSxDQUFDLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLHdCQUF3QixFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsc0JBQXNCLEVBQUUsU0FBUyxDQUFDO0tBQy9SO0lBQ0QsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsRUFBRTtRQUM3QixXQUFXLEVBQUUsQ0FBQyxZQUFZLENBQUM7UUFDM0IsZUFBZSxFQUFFLENBQUMsWUFBWSxFQUFFLGFB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QUM7UUFDL0IsTUFBTSxLQUFLLEdBQTJCLEVBQUUsQ0FBQztRQUN6QyxLQUFLLE1BQU0sSUFBSSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDN0QsSUFBSSxDQUFDLElBQUk7Z0JBQUUsU0FBUztZQUNwQixNQUFNLFlBQVksR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDekUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgdHlwZSB7IEJ1aWxkRW52aXJvbm1lbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY29kZWJ1aWxkJztcbmltcG9ydCB0eXBlIHsgQ29kZUJ1aWxkU3RlcFByb3BzLCBDb2RlUGlwZWxpbmVQcm9wcywgU2hlbGxTdGVwUHJvcHMgfSBmcm9tICdhd3MtY2RrLWxpYi9waXBlbGluZXMnO1xuaW1wb3J0IHR5cGUgeyBOZXR3b3JrQ29uZmlnLCBTdWJuZXRUeXBlTmFtZSB9IGZyb20gJy4vbmV0d29yay10eXBlcy5qcyc7XG5pbXBvcnQgeyBDREtfTUVUQURBVEFfUFJFRklYLCBNZXRhZGF0YUtleXMgfSBmcm9tICcuL3BpcGVsaW5lLXR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgTWV0YURhdGFUeXBlIH0gZnJvbSAnLi9waXBlbGluZS10eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFJvbGVDb25maWcgfSBmcm9tICcuL3JvbGUtdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBTZWN1cml0eUdyb3VwQ29uZmlnIH0gZnJvbSAnLi9zZWN1cml0eS1ncm91cC10eXBlcy5qcyc7XG5cbi8qKlxuICogVHlwZS1zYWZlIG5hbWVzcGFjZSBjb25zdGFudHMgZm9yIG1ldGFkYXRhIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmNvbnN0IE5BTUVTUEFDRSA9IHtcbiAgU0hFTExfU1RFUDogJ3BpcGVsaW5lczpzaGVsbHN0ZXAnLFxuICBDT0RFX0JVSUxEX1NURVA6ICdwaXBlbGluZXM6Y29kZWJ1aWxkc3RlcCcsXG4gIEJVSUxEX0VOVklST05NRU5UOiAnY29kZWJ1aWxkOmJ1aWxkZW52aXJvbm1lbnQnLFxuICBDT0RFX1BJUEVMSU5FOiAncGlwZWxpbmVzOmNvZGVwaXBlbGluZScsXG59IGFzIGNvbnN0O1xudHlwZSBOYW1lc3BhY2UgPSAodHlwZW9mIE5BTUVTUEFDRSlba2V5b2YgdHlwZW9mIE5BTUVTUEFDRV07XG5cbmludGVyZmFjZSBOYW1lc3BhY2VLZXlDb25maWcge1xuICBib29sZWFuS2V5czogcmVhZG9ubHkgc3RyaW5nW107XG4gIHBhc3N0aHJvdWdoS2V5czogcmVhZG9ubHkgc3RyaW5nW107XG59XG5cbmNvbnN0IE5BTUVTUEFDRV9LRVlfTUFQOiBSZWNvcmQ8TmFtZXNwYWNlLCBOYW1lc3BhY2VLZXlDb25maWc+ID0ge1xuICBbTkFNRVNQQUNFLlNIRUxMX1NURVBdOiB7XG4gICAgYm9vbGVhbktleXM6IFtdLFxuICAgIHBhc3N0aHJvdWdoS2V5czogWydhZGRpdGlvbmFsSW5wdXRzJywgJ2NvbW1hbmRzJywgJ2VudicsICdlbnZGcm9tQ2ZuT3V0cHV0cycsICdpbnB1dCcsICdpbnN0YWxsQ29tbWFuZHMnLCAncHJpbWFyeU91dHB1dERpcmVjdG9yeSddLFxuICB9LFxuICBbTkFNRVNQQUNFLkNPREVfQlVJTERfU1RFUF06IHtcbiAgICBib29sZWFuS2V5czogW10sXG4gICAgcGFzc3Rocm91Z2hLZXlzOiBbJ2FjdGlvblJvbGUnLCAnYWRkaXRpb25hbElucHV0cycsICdidWlsZEVudmlyb25tZW50JywgJ2NhY2hlJywgJ2NvbW1hbmRzJywgJ2VudicsICdlbnZGcm9tQ2ZuT3V0cHV0cycsICdmaWxlU3lzdGVtTG9jYXRpb25zJywgJ2lucHV0JywgJ2luc3RhbGxDb21tYW5kcycsICdsb2dnaW5nJywgJ3BhcnRpYWxCdWlsZFNwZWMnLCAncHJpbWFyeU91dHB1dERpcmVjdG9yeScsICdwcm9qZWN0TmFtZScsICdyb2xlJywgJ3JvbGVQb2xpY3lTdGF0ZW1lbnRzJywgJ3RpbWVvdXQnXSxcbiAgfSxcbiAgW05BTUVTUEFDRS5CVUlMRF9FTlZJUk9OTUVOVF06IHtcbiAgICBib29sZWFuS2V5czogWydwcml2aWxlZ2VkJ10sXG4gICAgcGFzc3Rocm91Z2hLZXlzOiBbJ2J1aWxkSW1hZ2UnLCAnY2VydGlmaWNhdGUnLCAnY29tcHV0ZVR5cGUnLCAnZG9ja2VyU2VydmVyJywgJ2Vudmlyb25tZW50VmFyaWFibGVzJywgJ2ZsZWV0J10sXG4gIH0sXG4gIFtOQU1FU1BBQ0UuQ09ERV9QSVBFTElORV06IHtcbiAgICBib29sZWFuS2V5czogWydjcm9zc0FjY291bnRLZXlzJywgJ2RvY2tlckVuYWJsZWRGb3JTZWxmTXV0YXRpb24nLCAnZG9ja2VyRW5hYmxlZEZvclN5bnRoJywgJ2VuYWJsZUtleVJvdGF0aW9uJywgJ3B1Ymxpc2hBc3NldHNJblBhcmFsbGVsJywgJ3JldXNlQ3Jvc3NSZWdpb25TdXBwb3J0U3RhY2tzJywgJ3NlbGZNdXRhdGlvbicsICd1c2VDaGFuZ2VTZXRzJywgJ3VzZVBpcGVsaW5lUm9sZUZvckFjdGlvbnMnXSxcbiAgICBwYXNzdGhyb3VnaEtleXM6IFsnYXJ0aWZhY3RCdWNrZXQnLCAnYXNzZXRQdWJsaXNoaW5nQ29kZUJ1aWxkRGVmYXVsdHMnLCAnY2RrQXNzZXRzQ2xpVmVyc2lvbicsICdjbGlWZXJzaW9uJywgJ2NvZGVCdWlsZERlZmF1bHRzJywgJ2NvZGVQaXBlbGluZScsICdjcm9zc1JlZ2lvblJlcGxpY2F0aW9uQnVja2V0cycsICdkb2NrZXJDcmVkZW50aWFscycsICdwaXBlbGluZU5hbWUnLCAncGlwZWxpbmVUeXBlJywgJ3JvbGUnLCAnc2VsZk11dGF0aW9uQ29kZUJ1aWxkRGVmYXVsdHMnLCAnc3ludGgnLCAnc3ludGhDb2RlQnVpbGREZWZhdWx0cyddLFxuICB9LFxufTtcblxuY29uc3QgRU1QVFlfS0VZX0NPTkZJRzogTmFtZXNwYWNlS2V5Q29uZmlnID0geyBib29sZWFuS2V5czogW10sIHBhc3N0aHJvdWdoS2V5czogW10gfTtcblxuZnVuY3Rpb24gZ2V0Q3VzdG9tS2V5KHByZWZpeDogc3RyaW5nLCBrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtDREtfTUVUQURBVEFfUFJFRklYfSR7cHJlZml4fToke2tleX1gLnRvTG93ZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIGlzVHJ1ZSh2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB2YWx1ZS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZSc7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqIEV4dHJhY3QgQ0RLIGNvbnN0cnVjdCBjb25maWcgZnJvbSBtZXRhZGF0YSBmb3IgYSBnaXZlbiBuYW1lc3BhY2UuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb25maWdGcm9tTWV0YWRhdGEoXG4gIG1ldGFkYXRhOiBNZXRhRGF0YVR5cGUsXG4gIG5hbWVzcGFjZTogc3RyaW5nLFxuKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICBjb25zdCB7IGJvb2xlYW5LZXlzLCBwYXNzdGhyb3VnaEtleXMgfSA9XG4gICAgTkFNRVNQQUNFX0tFWV9NQVBbbmFtZXNwYWNlIGFzIE5hbWVzcGFjZV0gPz8gRU1QVFlfS0VZX0NPTkZJRztcblxuICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgZm9yIChjb25zdCBrZXkgb2YgYm9vbGVhbktleXMpIHtcbiAgICBjb25zdCByYXcgPSBtZXRhZGF0YVtnZXRDdXN0b21LZXkobmFtZXNwYWNlLCBrZXkpXTtcbiAgICBpZiAocmF3ICE9PSB1bmRlZmluZWQpIHJlc3VsdFtrZXldID0gaXNUcnVlKHJhdyk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGtleSBvZiBwYXNzdGhyb3VnaEtleXMpIHtcbiAgICBjb25zdCByYXcgPSBtZXRhZGF0YVtnZXRDdXN0b21LZXkobmFtZXNwYWNlLCBrZXkpXTtcbiAgICBpZiAocmF3ICE9PSB1bmRlZmluZWQpIHJlc3VsdFtrZXldID0gcmF3O1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqIEV4dHJhY3QgQ29kZVBpcGVsaW5lIGNvbmZpZyBmcm9tIG1ldGFkYXRhLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ldGFkYXRhRm9yQ29kZVBpcGVsaW5lKG1ldGFkYXRhOiBNZXRhRGF0YVR5cGUpOiBQYXJ0aWFsPENvZGVQaXBlbGluZVByb3BzPiB7XG4gIHJldHVybiBidWlsZENvbmZpZ0Zyb21NZXRhZGF0YShtZXRhZGF0YSwgTkFNRVNQQUNFLkNPREVfUElQRUxJTkUpIGFzIFBhcnRpYWw8Q29kZVBpcGVsaW5lUHJvcHM+O1xufVxuXG4vKiogRXh0cmFjdCBDb2RlQnVpbGRTdGVwIGNvbmZpZyBmcm9tIG1ldGFkYXRhLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1ldGFkYXRhRm9yQ29kZUJ1aWxkU3RlcChtZXRhZGF0YTogTWV0YURhdGFUeXBlKTogUGFydGlhbDxDb2RlQnVpbGRTdGVwUHJvcHM+IHtcbiAgcmV0dXJuIGJ1aWxkQ29uZmlnRnJvbU1ldGFkYXRhKG1ldGFkYXRhLCBOQU1FU1BBQ0UuQ09ERV9CVUlMRF9TVEVQKSBhcyBQYXJ0aWFsPENvZGVCdWlsZFN0ZXBQcm9wcz47XG59XG5cbi8qKiBFeHRyYWN0IFNoZWxsU3RlcCBjb25maWcgZnJvbSBtZXRhZGF0YS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXRhZGF0YUZvclNoZWxsU3RlcChtZXRhZGF0YTogTWV0YURhdGFUeXBlKTogUGFydGlhbDxTaGVsbFN0ZXBQcm9wcz4ge1xuICByZXR1cm4gYnVpbGRDb25maWdGcm9tTWV0YWRhdGEobWV0YWRhdGEsIE5BTUVTUEFDRS5TSEVMTF9TVEVQKSBhcyBQYXJ0aWFsPFNoZWxsU3RlcFByb3BzPjtcbn1cblxuLyoqIEV4dHJhY3QgQnVpbGRFbnZpcm9ubWVudCBjb25maWcgZnJvbSBtZXRhZGF0YS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXRhZGF0YUZvckJ1aWxkRW52aXJvbm1lbnQobWV0YWRhdGE6IE1ldGFEYXRhVHlwZSk6IFBhcnRpYWw8QnVpbGRFbnZpcm9ubWVudD4ge1xuICByZXR1cm4gYnVpbGRDb25maWdGcm9tTWV0YWRhdGEobWV0YWRhdGEsIE5BTUVTUEFDRS5CVUlMRF9FTlZJUk9OTUVOVCkgYXMgUGFydGlhbDxCdWlsZEVudmlyb25tZW50Pjtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUeXBlZC1jb25maWcgZXh0cmFjdG9yczogZWMyOm5ldHdvcmsgLyBpYW06cm9sZSAvIGVjMjpzZWN1cml0eWdyb3VwIG1ldGFkYXRhXG4vLyAtPiB0aGUgZGlzY3JpbWluYXRlZC11bmlvbiBjb25maWcgb2JqZWN0cyB0aGUgYnVpbGRlciBhbHJlYWR5IGNvbnN1bWVzXG4vLyAoTmV0d29ya0NvbmZpZyAvIFJvbGVDb25maWcgLyBTZWN1cml0eUdyb3VwQ29uZmlnKS4gVW5saWtlIHRoZSBuYW1lc3BhY2VzXG4vLyBhYm92ZSAod2hpY2ggbWFwIDE6MSB0byBDREsgY29uc3RydWN0IHByb3BzKSwgdGhlc2UgZmVlZCByZXNvbHZlTmV0d29yayAvXG4vLyByZXNvbHZlUm9sZSAvIHJlc29sdmVTZWN1cml0eUdyb3VwLiBFYWNoIHJldHVybnMgdW5kZWZpbmVkIHdoZW4gaXRzIGtleXMgYXJlXG4vLyBhYnNlbnQsIHNvIGNhbGxlcnMgZmFsbCB0aHJvdWdoIHdpdGggYHByb3AgPz8gbWV0YWRhdGEgPz8gZW52YCBwcmVjZWRlbmNlLlxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIGFzU3RyKHY6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHlwZW9mIHYgPT09ICdzdHJpbmcnICYmIHYudHJpbSgpICE9PSAnJyA/IHYgOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBBY2NlcHQgYSBKU09OIGFycmF5IG9yIGEgY29tbWEtc2VwYXJhdGVkIHN0cmluZyAtPiBzdHJpbmdbXSAodW5kZWZpbmVkIGlmIGVtcHR5KS4gKi9cbmZ1bmN0aW9uIGFzTGlzdCh2OiB1bmtub3duKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICBjb25zdCBpdGVtcyA9IEFycmF5LmlzQXJyYXkodilcbiAgICA/IHYubWFwKFN0cmluZykubWFwKHMgPT4gcy50cmltKCkpLmZpbHRlcihCb29sZWFuKVxuICAgIDogdHlwZW9mIHYgPT09ICdzdHJpbmcnICYmIHYudHJpbSgpICE9PSAnJ1xuICAgICAgPyB2LnNwbGl0KCcsJykubWFwKHMgPT4gcy50cmltKCkpLmZpbHRlcihCb29sZWFuKVxuICAgICAgOiBbXTtcbiAgcmV0dXJuIGl0ZW1zLmxlbmd0aCA+IDAgPyBpdGVtcyA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIEFjY2VwdCBhIEpTT04gb2JqZWN0IG9yIGEgSlNPTiBzdHJpbmcgLT4gUmVjb3JkPHN0cmluZyxzdHJpbmc+ICh1bmRlZmluZWQgaWYgZW1wdHkpLiAqL1xuZnVuY3Rpb24gYXNUYWdzKHY6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgdW5kZWZpbmVkIHtcbiAgbGV0IG9iajogdW5rbm93biA9IHY7XG4gIGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgJiYgdi50cmltKCkgIT09ICcnKSB7XG4gICAgdHJ5IHsgb2JqID0gSlNPTi5wYXJzZSh2KTsgfSBjYXRjaCB7IHJldHVybiB1bmRlZmluZWQ7IH1cbiAgfVxuICBpZiAob2JqICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMob2JqIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5tYXAoKFtrLCB2YWxdKSA9PiBbaywgU3RyaW5nKHZhbCldIGFzIGNvbnN0KTtcbiAgICByZXR1cm4gZW50cmllcy5sZW5ndGggPiAwID8gT2JqZWN0LmZyb21FbnRyaWVzKGVudHJpZXMpIDogdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiB1bmRlZmluZWQgd2hlbiB0aGUga2V5IGlzIGFic2VudDsgb3RoZXJ3aXNlIGEgY29lcmNlZCBib29sZWFuLiAqL1xuZnVuY3Rpb24gYXNCb29sKHY6IHVua25vd24pOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHYgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGlzVHJ1ZSh2KTtcbn1cblxuLyoqIENvZXJjZSBhIG1ldGFkYXRhIHZhbHVlIHRvIGEgcG9zaXRpdmUgaW50ZWdlcjsgdW5kZWZpbmVkIGlmIGFic2VudC9pbnZhbGlkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzSW50KHY6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBpZiAodiA9PT0gdW5kZWZpbmVkIHx8IHYgPT09IG51bGwgfHwgdiA9PT0gJycpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IG4gPSB0eXBlb2YgdiA9PT0gJ251bWJlcicgPyB2IDogTnVtYmVyKFN0cmluZyh2KS50cmltKCkpO1xuICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihuKSAmJiBuID4gMCA/IG4gOiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQnVpbGQgYSBOZXR3b3JrQ29uZmlnIGZyb20gYGVjMjpuZXR3b3JrYCBtZXRhZGF0YSBrZXlzLiBUaGUgdmFyaWFudCBjb21lc1xuICogZnJvbSBORVRXT1JLX1RZUEUsIG9yIGlzIGluZmVycmVkIChzdWJuZXRJZHMgLT4gc3VibmV0SWRzLCB0YWdzIC0+IHZwY0xvb2t1cCxcbiAqIHZwY0lkIC0+IHZwY0lkKS4gUmV0dXJucyB1bmRlZmluZWQgd2hlbiBubyB1c2FibGUgbmV0d29yayBtZXRhZGF0YSBpcyBwcmVzZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmV0d29ya0NvbmZpZ0Zyb21NZXRhZGF0YShtZXRhZGF0YTogTWV0YURhdGFUeXBlKTogTmV0d29ya0NvbmZpZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHR5cGUgPSBhc1N0cihtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19UWVBFXSk7XG4gIGNvbnN0IHZwY0lkID0gYXNTdHIobWV0YWRhdGFbTWV0YWRhdGFLZXlzLk5FVFdPUktfVlBDX0lEXSk7XG4gIGNvbnN0IHN1Ym5ldElkcyA9IGFzTGlzdChtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19TVUJORVRfSURTXSk7XG4gIGNvbnN0IHN1Ym5ldFR5cGUgPSBhc1N0cihtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19TVUJORVRfVFlQRV0pIGFzIFN1Ym5ldFR5cGVOYW1lIHwgdW5kZWZpbmVkO1xuICBjb25zdCBhdmFpbGFiaWxpdHlab25lcyA9IGFzTGlzdChtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19BVkFJTEFCSUxJVFlfWk9ORVNdKTtcbiAgY29uc3Qgc3VibmV0R3JvdXBOYW1lID0gYXNTdHIobWV0YWRhdGFbTWV0YWRhdGFLZXlzLk5FVFdPUktfU1VCTkVUX0dST1VQX05BTUVdKTtcbiAgY29uc3Qgc2VjdXJpdHlHcm91cElkcyA9IGFzTGlzdChtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19TRUNVUklUWV9HUk9VUF9JRFNdKTtcbiAgY29uc3QgdGFncyA9IGFzVGFncyhtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19UQUdTXSk7XG4gIGNvbnN0IHZwY05hbWUgPSBhc1N0cihtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19WUENfTkFNRV0pO1xuICBjb25zdCByZWdpb24gPSBhc1N0cihtZXRhZGF0YVtNZXRhZGF0YUtleXMuTkVUV09SS19SRUdJT05dKTtcblxuICBjb25zdCB2YXJpYW50ID0gdHlwZSA/PyAoc3VibmV0SWRzID8gJ3N1Ym5ldElkcycgOiB0YWdzID8gJ3ZwY0xvb2t1cCcgOiB2cGNJZCA/ICd2cGNJZCcgOiB1bmRlZmluZWQpO1xuXG4gIHN3aXRjaCAodmFyaWFudCkge1xuICAgIGNhc2UgJ3N1Ym5ldElkcyc6XG4gICAgICBpZiAoIXZwY0lkIHx8ICFzdWJuZXRJZHMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4geyB0eXBlOiAnc3VibmV0SWRzJywgb3B0aW9uczogeyB2cGNJZCwgc3VibmV0SWRzLCAuLi4oc2VjdXJpdHlHcm91cElkcyAmJiB7IHNlY3VyaXR5R3JvdXBJZHMgfSkgfSB9O1xuICAgIGNhc2UgJ3ZwY0lkJzpcbiAgICAgIGlmICghdnBjSWQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAndnBjSWQnLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgdnBjSWQsXG4gICAgICAgICAgLi4uKHN1Ym5ldFR5cGUgJiYgeyBzdWJuZXRUeXBlIH0pLFxuICAgICAgICAgIC4uLihhdmFpbGFiaWxpdHlab25lcyAmJiB7IGF2YWlsYWJpbGl0eVpvbmVzIH0pLFxuICAgICAgICAgIC4uLihzdWJuZXRHcm91cE5hbWUgJiYgeyBzdWJuZXRHcm91cE5hbWUgfSksXG4gICAgICAgICAgLi4uKHNlY3VyaXR5R3JvdXBJZHMgJiYgeyBzZWN1cml0eUdyb3VwSWRzIH0pLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICBjYXNlICd2cGNMb29rdXAnOlxuICAgICAgaWYgKCF0YWdzKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3ZwY0xvb2t1cCcsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICB0YWdzLFxuICAgICAgICAgIC4uLihzdWJuZXRUeXBlICYmIHsgc3VibmV0VHlwZSB9KSxcbiAgICAgICAgICAuLi4oYXZhaWxhYmlsaXR5Wm9uZXMgJiYgeyBhdmFpbGFiaWxpdHlab25lcyB9KSxcbiAgICAgICAgICAuLi4oc3VibmV0R3JvdXBOYW1lICYmIHsgc3VibmV0R3JvdXBOYW1lIH0pLFxuICAgICAgICAgIC4uLihzZWN1cml0eUdyb3VwSWRzICYmIHsgc2VjdXJpdHlHcm91cElkcyB9KSxcbiAgICAgICAgICAuLi4odnBjTmFtZSAmJiB7IHZwY05hbWUgfSksXG4gICAgICAgICAgLi4uKHJlZ2lvbiAmJiB7IHJlZ2lvbiB9KSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZCBhIFJvbGVDb25maWcgZnJvbSBgaWFtOnJvbGVgIG1ldGFkYXRhIGtleXMgKHJvbGVBcm4gLyByb2xlTmFtZSAvXG4gKiBjb2RlQnVpbGREZWZhdWx0KS4gVGhlIDQga2V5cyBjYW4ndCBleHByZXNzIHRoZSBmdWxsIGBvaWRjYCBvcHRpb24gc2V0LCBzbyBhblxuICogYG9pZGNgIHR5cGUgZnJvbSBtZXRhZGF0YSBpcyBpZ25vcmVkLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIG5vIGtleXMgYXJlIHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJvbGVDb25maWdGcm9tTWV0YWRhdGEobWV0YWRhdGE6IE1ldGFEYXRhVHlwZSk6IFJvbGVDb25maWcgfCB1bmRlZmluZWQge1xuICBjb25zdCB0eXBlID0gYXNTdHIobWV0YWRhdGFbTWV0YWRhdGFLZXlzLlJPTEVfVFlQRV0pO1xuICBjb25zdCByb2xlQXJuID0gYXNTdHIobWV0YWRhdGFbTWV0YWRhdGFLZXlzLlJPTEVfQVJOXSk7XG4gIGNvbnN0IHJvbGVOYW1lID0gYXNTdHIobWV0YWRhdGFbTWV0YWRhdGFLZXlzLlJPTEVfTkFNRV0pO1xuICBjb25zdCBtdXRhYmxlID0gYXNCb29sKG1ldGFkYXRhW01ldGFkYXRhS2V5cy5ST0xFX01VVEFCTEVdKTtcblxuICBjb25zdCB2YXJpYW50ID0gdHlwZSA/PyAocm9sZUFybiA/ICdyb2xlQXJuJyA6IHJvbGVOYW1lID8gJ3JvbGVOYW1lJyA6IHVuZGVmaW5lZCk7XG5cbiAgc3dpdGNoICh2YXJpYW50KSB7XG4gICAgY2FzZSAncm9sZUFybic6XG4gICAgICBpZiAoIXJvbGVBcm4pIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4geyB0eXBlOiAncm9sZUFybicsIG9wdGlvbnM6IHsgcm9sZUFybiwgLi4uKG11dGFibGUgIT09IHVuZGVmaW5lZCAmJiB7IG11dGFibGUgfSkgfSB9O1xuICAgIGNhc2UgJ3JvbGVOYW1lJzpcbiAgICAgIGlmICghcm9sZU5hbWUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4geyB0eXBlOiAncm9sZU5hbWUnLCBvcHRpb25zOiB7IHJvbGVOYW1lLCAuLi4obXV0YWJsZSAhPT0gdW5kZWZpbmVkICYmIHsgbXV0YWJsZSB9KSB9IH07XG4gICAgY2FzZSAnY29kZUJ1aWxkRGVmYXVsdCc6XG4gICAgICByZXR1cm4geyB0eXBlOiAnY29kZUJ1aWxkRGVmYXVsdCcsIG9wdGlvbnM6IHsgLi4uKHJvbGVOYW1lICYmIHsgcm9sZU5hbWUgfSkgfSB9O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogQnVpbGQgYSBTZWN1cml0eUdyb3VwQ29uZmlnIGZyb20gYGVjMjpzZWN1cml0eWdyb3VwYCBtZXRhZGF0YSBrZXlzXG4gKiAoc2VjdXJpdHlHcm91cElkcyAvIHNlY3VyaXR5R3JvdXBMb29rdXApLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIG5vIGtleXMgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VjdXJpdHlHcm91cENvbmZpZ0Zyb21NZXRhZGF0YShtZXRhZGF0YTogTWV0YURhdGFUeXBlKTogU2VjdXJpdHlHcm91cENvbmZpZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHR5cGUgPSBhc1N0cihtZXRhZGF0YVtNZXRhZGF0YUtleXMuU0VDVVJJVFlfR1JPVVBfVFlQRV0pO1xuICBjb25zdCBpZHMgPSBhc0xpc3QobWV0YWRhdGFbTWV0YWRhdGFLZXlzLlNFQ1VSSVRZX0dST1VQX0lEU10pO1xuICBjb25zdCBtdXRhYmxlID0gYXNCb29sKG1ldGFkYXRhW01ldGFkYXRhS2V5cy5TRUNVUklUWV9HUk9VUF9NVVRBQkxFXSk7XG4gIGNvbnN0IG5hbWUgPSBhc1N0cihtZXRhZGF0YVtNZXRhZGF0YUtleXMuU0VDVVJJVFlfR1JPVVBfTkFNRV0pO1xuICBjb25zdCB2cGNJZCA9IGFzU3RyKG1ldGFkYXRhW01ldGFkYXRhS2V5cy5TRUNVUklUWV9HUk9VUF9WUENfSURdKTtcblxuICBjb25zdCB2YXJpYW50ID0gdHlwZSA/PyAoaWRzID8gJ3NlY3VyaXR5R3JvdXBJZHMnIDogbmFtZSA/ICdzZWN1cml0eUdyb3VwTG9va3VwJyA6IHVuZGVmaW5lZCk7XG5cbiAgc3dpdGNoICh2YXJpYW50KSB7XG4gICAgY2FzZSAnc2VjdXJpdHlHcm91cElkcyc6XG4gICAgICBpZiAoIWlkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIHJldHVybiB7IHR5cGU6ICdzZWN1cml0eUdyb3VwSWRzJywgb3B0aW9uczogeyBzZWN1cml0eUdyb3VwSWRzOiBpZHMsIC4uLihtdXRhYmxlICE9PSB1bmRlZmluZWQgJiYgeyBtdXRhYmxlIH0pIH0gfTtcbiAgICBjYXNlICdzZWN1cml0eUdyb3VwTG9va3VwJzpcbiAgICAgIGlmICghbmFtZSB8fCAhdnBjSWQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4geyB0eXBlOiAnc2VjdXJpdHlHcm91cExvb2t1cCcsIG9wdGlvbnM6IHsgc2VjdXJpdHlHcm91cE5hbWU6IG5hbWUsIHZwY0lkIH0gfTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKiogQSBDb2RlUGlwZWxpbmUgVjIgcGlwZWxpbmUtbGV2ZWwgdmFyaWFibGUgcGFyc2VkIGZyb20gYG9wZXJhdGlvbnMudmFyaWFibGVzYC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmVWYXJpYWJsZVNwZWMge1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlZmF1bHRWYWx1ZT86IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGFyc2UgYG9wZXJhdGlvbnMudmFyaWFibGVzYCBtZXRhZGF0YSBpbnRvIENvZGVQaXBlbGluZSBWMiB2YXJpYWJsZSBzcGVjcy5cbiAqIEFjY2VwdHMgYSBKU09OIGFycmF5IChgW3tcIm5hbWVcIjpcIkVOVlwiLFwiZGVmYXVsdFwiOlwicHJvZFwiLFwiZGVzY3JpcHRpb25cIjpcIi4uLlwifV1gKVxuICogb3IgYSBjb21wYWN0IGNvbW1hLXNlcGFyYXRlZCBgbmFtZT1kZWZhdWx0YCBsaXN0IChgRU5WPXByb2QsUkVHSU9OPXVzLWVhc3QtMWApLlxuICogRW50cmllcyB3aXRob3V0IGEgdXNhYmxlIG5hbWUgYXJlIHNraXBwZWQ7IHJldHVybnMgW10gd2hlbiBub3RoaW5nIHZhbGlkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VQaXBlbGluZVZhcmlhYmxlcyh2YWx1ZTogdW5rbm93bik6IFBpcGVsaW5lVmFyaWFibGVTcGVjW10ge1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gJycpIHJldHVybiBbXTtcblxuICAvLyBBbHJlYWR5IGFuIGFycmF5IChKU09OLXR5cGVkIG1ldGFkYXRhKSBvciBhIEpTT04tZW5jb2RlZCBzdHJpbmcuXG4gIGxldCBwYXJzZWQ6IHVua25vd24gPSB2YWx1ZTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCB0cmltbWVkID0gdmFsdWUudHJpbSgpO1xuICAgIGlmICh0cmltbWVkLnN0YXJ0c1dpdGgoJ1snKSB8fCB0cmltbWVkLnN0YXJ0c1dpdGgoJ3snKSkge1xuICAgICAgdHJ5IHsgcGFyc2VkID0gSlNPTi5wYXJzZSh0cmltbWVkKTsgfSBjYXRjaCB7IHBhcnNlZCA9IHZhbHVlOyB9XG4gICAgfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocGFyc2VkKSkge1xuICAgIGNvbnN0IHNwZWNzOiBQaXBlbGluZVZhcmlhYmxlU3BlY1tdID0gW107XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBwYXJzZWQpIHtcbiAgICAgIGlmICghZW50cnkgfHwgdHlwZW9mIGVudHJ5ICE9PSAnb2JqZWN0JykgY29udGludWU7XG4gICAgICBjb25zdCBlID0gZW50cnkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICBjb25zdCBuYW1lID0gYXNTdHIoZS5uYW1lKTtcbiAgICAgIGlmICghbmFtZSkgY29udGludWU7XG4gICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBhc1N0cihlLmRlZmF1bHQpID8/IGFzU3RyKGUuZGVmYXVsdFZhbHVlKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gYXNTdHIoZS5kZXNjcmlwdGlvbik7XG4gICAgICBzcGVjcy5wdXNoKHsgbmFtZSwgLi4uKGRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHsgZGVmYXVsdFZhbHVlIH0pLCAuLi4oZGVzY3JpcHRpb24gIT09IHVuZGVmaW5lZCAmJiB7IGRlc2NyaXB0aW9uIH0pIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc3BlY3M7XG4gIH1cblxuICAvLyBDb21wYWN0IGBuYW1lPWRlZmF1bHRgIGNvbW1hIGxpc3QuXG4gIGlmICh0eXBlb2YgcGFyc2VkID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IHNwZWNzOiBQaXBlbGluZVZhcmlhYmxlU3BlY1tdID0gW107XG4gICAgZm9yIChjb25zdCBwYWlyIG9mIHBhcnNlZC5zcGxpdCgnLCcpKSB7XG4gICAgICBjb25zdCBpZHggPSBwYWlyLmluZGV4T2YoJz0nKTtcbiAgICAgIGNvbnN0IG5hbWUgPSAoaWR4ID09PSAtMSA/IHBhaXIgOiBwYWlyLnNsaWNlKDAsIGlkeCkpLnRyaW0oKTtcbiAgICAgIGlmICghbmFtZSkgY29udGludWU7XG4gICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBpZHggPT09IC0xID8gdW5kZWZpbmVkIDogcGFpci5zbGljZShpZHggKyAxKS50cmltKCk7XG4gICAgICBzcGVjcy5wdXNoKHsgbmFtZSwgLi4uKGRlZmF1bHRWYWx1ZSA/IHsgZGVmYXVsdFZhbHVlIH0gOiB7fSkgfSk7XG4gICAgfVxuICAgIHJldHVybiBzcGVjcztcbiAgfVxuXG4gIHJldHVybiBbXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata and string helpers that are FREE of `aws-cdk-lib`.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `pipeline-helpers.ts` (which builds CodeBuild steps and therefore
|
|
5
|
+
* pulls in the CDK) so the main `@pipeline-builder/pipeline-core` entry point can
|
|
6
|
+
* export them without putting `aws-cdk-lib` on every consumer's import graph.
|
|
7
|
+
* Anything here that needs a CDK type belongs in `pipeline-helpers.ts` instead.
|
|
8
|
+
*/
|
|
9
|
+
import { type MetaDataType } from './pipeline-types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Merge multiple metadata objects into one. Later sources override earlier ones.
|
|
12
|
+
*/
|
|
13
|
+
export declare function merge(...sources: Array<Partial<MetaDataType>>): MetaDataType;
|
|
14
|
+
/**
|
|
15
|
+
* Extract non-namespaced metadata keys as environment variable strings.
|
|
16
|
+
* Keys starting with 'aws:cdk:' are reserved for CDK construct props
|
|
17
|
+
* (processed by metadata extraction functions) and are excluded here.
|
|
18
|
+
*
|
|
19
|
+
* All values are converted to strings for CodeBuild compatibility.
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractMetadataEnv(metadata: MetaDataType): Record<string, string>;
|
|
22
|
+
/** Resolve the effective failureBehavior: a scan/security-category plugin is pinned
|
|
23
|
+
* to 'fail'; otherwise the authored value (default 'fail'). */
|
|
24
|
+
export declare function resolveFailureBehavior(category?: string, authored?: 'fail' | 'warn' | 'ignore'): 'fail' | 'warn' | 'ignore';
|
|
25
|
+
/**
|
|
26
|
+
* Replaces all characters that are not letters or numbers with the specified value
|
|
27
|
+
* @param input - The string to process
|
|
28
|
+
* @param replaceValue - The character(s) to replace non-alphanumeric characters with (default: '_')
|
|
29
|
+
* @returns The string with non-alphanumeric characters replaced
|
|
30
|
+
*/
|
|
31
|
+
export declare function replaceNonAlphanumeric(input: string, replaceValue?: string): string;
|