@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.
Files changed (84) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +69 -0
  3. package/lib/cdk.d.ts +38 -0
  4. package/lib/cdk.js +44 -0
  5. package/lib/config/app-config.d.ts +109 -0
  6. package/lib/config/app-config.js +197 -0
  7. package/lib/config/aws-config-cdk.d.ts +49 -0
  8. package/lib/config/aws-config-cdk.js +65 -0
  9. package/lib/config/billing-config.d.ts +24 -0
  10. package/lib/config/billing-config.js +497 -0
  11. package/lib/config/config-types.d.ts +346 -0
  12. package/lib/config/config-types.js +4 -0
  13. package/lib/config/entitlements.d.ts +23 -0
  14. package/lib/config/entitlements.js +46 -0
  15. package/lib/config/handler-constants.d.ts +10 -0
  16. package/lib/config/handler-constants.js +39 -0
  17. package/lib/config/infrastructure-config.d.ts +66 -0
  18. package/lib/config/infrastructure-config.js +197 -0
  19. package/lib/config/server-config.d.ts +53 -0
  20. package/lib/config/server-config.js +175 -0
  21. package/lib/config/service-client.d.ts +13 -0
  22. package/lib/config/service-client.js +20 -0
  23. package/lib/core/artifact-manager.d.ts +62 -0
  24. package/lib/core/artifact-manager.js +83 -0
  25. package/lib/core/id-generator.d.ts +50 -0
  26. package/lib/core/id-generator.js +50 -0
  27. package/lib/core/metadata-builder.d.ts +48 -0
  28. package/lib/core/metadata-builder.js +278 -0
  29. package/lib/core/metadata-helpers.d.ts +31 -0
  30. package/lib/core/metadata-helpers.js +55 -0
  31. package/lib/core/network-types.d.ts +200 -0
  32. package/lib/core/network-types.js +4 -0
  33. package/lib/core/network.d.ts +33 -0
  34. package/lib/core/network.js +112 -0
  35. package/lib/core/pipeline-helpers.d.ts +61 -0
  36. package/lib/core/pipeline-helpers.js +563 -0
  37. package/lib/core/pipeline-types.d.ts +118 -0
  38. package/lib/core/pipeline-types.js +131 -0
  39. package/lib/core/role-types.d.ts +254 -0
  40. package/lib/core/role-types.js +4 -0
  41. package/lib/core/role.d.ts +14 -0
  42. package/lib/core/role.js +117 -0
  43. package/lib/core/security-group-types.d.ts +84 -0
  44. package/lib/core/security-group-types.js +4 -0
  45. package/lib/core/security-group.d.ts +14 -0
  46. package/lib/core/security-group.js +33 -0
  47. package/lib/handlers/plugin-lookup-handler.d.ts +32 -0
  48. package/lib/handlers/plugin-lookup-handler.js +292 -0
  49. package/lib/handlers/pnpm-lock.yaml +12 -0
  50. package/lib/index.d.ts +45 -0
  51. package/lib/index.js +53 -0
  52. package/lib/pipeline/pipeline-builder.d.ts +123 -0
  53. package/lib/pipeline/pipeline-builder.js +476 -0
  54. package/lib/pipeline/pipeline-configuration.d.ts +81 -0
  55. package/lib/pipeline/pipeline-configuration.js +214 -0
  56. package/lib/pipeline/plugin-lookup.d.ts +131 -0
  57. package/lib/pipeline/plugin-lookup.js +316 -0
  58. package/lib/pipeline/plugin-spec.d.ts +138 -0
  59. package/lib/pipeline/plugin-spec.js +4 -0
  60. package/lib/pipeline/source-builder.d.ts +62 -0
  61. package/lib/pipeline/source-builder.js +164 -0
  62. package/lib/pipeline/source-types.d.ts +221 -0
  63. package/lib/pipeline/source-types.js +4 -0
  64. package/lib/pipeline/stage-builder.d.ts +78 -0
  65. package/lib/pipeline/stage-builder.js +129 -0
  66. package/lib/pipeline/step-types.d.ts +222 -0
  67. package/lib/pipeline/step-types.js +4 -0
  68. package/lib/template/evaluator.d.ts +42 -0
  69. package/lib/template/evaluator.js +164 -0
  70. package/lib/template/index.d.ts +34 -0
  71. package/lib/template/index.js +118 -0
  72. package/lib/template/metrics.d.ts +10 -0
  73. package/lib/template/metrics.js +43 -0
  74. package/lib/template/plugin-resolver.d.ts +8 -0
  75. package/lib/template/plugin-resolver.js +48 -0
  76. package/lib/template/tokenizer.d.ts +49 -0
  77. package/lib/template/tokenizer.js +233 -0
  78. package/lib/template/topo-sort.d.ts +17 -0
  79. package/lib/template/topo-sort.js +88 -0
  80. package/lib/template/validate.d.ts +45 -0
  81. package/lib/template/validate.js +96 -0
  82. package/lib/template/walker.d.ts +34 -0
  83. package/lib/template/walker.js +83 -0
  84. package/package.json +184 -0
@@ -0,0 +1,55 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Metadata and string helpers that are FREE of `aws-cdk-lib`.
5
+ *
6
+ * Split out of `pipeline-helpers.ts` (which builds CodeBuild steps and therefore
7
+ * pulls in the CDK) so the main `@pipeline-builder/pipeline-core` entry point can
8
+ * export them without putting `aws-cdk-lib` on every consumer's import graph.
9
+ * Anything here that needs a CDK type belongs in `pipeline-helpers.ts` instead.
10
+ */
11
+ import { CDK_METADATA_PREFIX } from './pipeline-types.js';
12
+ /**
13
+ * Merge multiple metadata objects into one. Later sources override earlier ones.
14
+ */
15
+ export function merge(...sources) {
16
+ return Object.assign({}, ...sources);
17
+ }
18
+ /**
19
+ * Extract non-namespaced metadata keys as environment variable strings.
20
+ * Keys starting with 'aws:cdk:' are reserved for CDK construct props
21
+ * (processed by metadata extraction functions) and are excluded here.
22
+ *
23
+ * All values are converted to strings for CodeBuild compatibility.
24
+ */
25
+ export function extractMetadataEnv(metadata) {
26
+ const env = {};
27
+ for (const [key, value] of Object.entries(metadata)) {
28
+ if (!key.startsWith(CDK_METADATA_PREFIX)) {
29
+ env[key] = String(value);
30
+ }
31
+ }
32
+ return env;
33
+ }
34
+ /** Plugin categories whose failure must NEVER be masked. A scan/security step that
35
+ * exits non-zero has to fail the pipeline (repo rule: a failed scan is red, never a
36
+ * false-green `|| true`), so such a plugin's failureBehavior is forced to 'fail'
37
+ * regardless of what the plugin or step authored. */
38
+ const FAIL_FAST_CATEGORIES = /scan|security|sast|dast|vuln|secret/i;
39
+ /** Resolve the effective failureBehavior: a scan/security-category plugin is pinned
40
+ * to 'fail'; otherwise the authored value (default 'fail'). */
41
+ export function resolveFailureBehavior(category, authored) {
42
+ if (category && FAIL_FAST_CATEGORIES.test(category))
43
+ return 'fail';
44
+ return authored ?? 'fail';
45
+ }
46
+ /**
47
+ * Replaces all characters that are not letters or numbers with the specified value
48
+ * @param input - The string to process
49
+ * @param replaceValue - The character(s) to replace non-alphanumeric characters with (default: '_')
50
+ * @returns The string with non-alphanumeric characters replaced
51
+ */
52
+ export function replaceNonAlphanumeric(input, replaceValue = '_') {
53
+ return input.replace(/[^a-zA-Z0-9]/g, replaceValue);
54
+ }
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YWRhdGEtaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL21ldGFkYXRhLWhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7OztHQU9HO0FBRUgsT0FBTyxFQUFFLG1CQUFtQixFQUFxQixNQUFNLHFCQUFxQixDQUFDO0FBRTdFOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEtBQUssQ0FBQyxHQUFHLE9BQXFDO0lBQzVELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQWlCLENBQUM7QUFDdkQsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxRQUFzQjtJQUN2RCxNQUFNLEdBQUcsR0FBMkIsRUFBRSxDQUFDO0lBQ3ZDLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDcEQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDO1lBQ3pDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRDs7O3NEQUdzRDtBQUN0RCxNQUFNLG9CQUFvQixHQUFHLHNDQUFzQyxDQUFDO0FBRXBFO2dFQUNnRTtBQUNoRSxNQUFNLFVBQVUsc0JBQXNCLENBQUMsUUFBaUIsRUFBRSxRQUFxQztJQUM3RixJQUFJLFFBQVEsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFDbkUsT0FBTyxRQUFRLElBQUksTUFBTSxDQUFDO0FBQzVCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxzQkFBc0IsQ0FBQyxLQUFhLEVBQUUsWUFBWSxHQUFXLEdBQUc7SUFDOUUsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxZQUFZLENBQUMsQ0FBQztBQUN0RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogTWV0YWRhdGEgYW5kIHN0cmluZyBoZWxwZXJzIHRoYXQgYXJlIEZSRUUgb2YgYGF3cy1jZGstbGliYC5cbiAqXG4gKiBTcGxpdCBvdXQgb2YgYHBpcGVsaW5lLWhlbHBlcnMudHNgICh3aGljaCBidWlsZHMgQ29kZUJ1aWxkIHN0ZXBzIGFuZCB0aGVyZWZvcmVcbiAqIHB1bGxzIGluIHRoZSBDREspIHNvIHRoZSBtYWluIGBAcGlwZWxpbmUtYnVpbGRlci9waXBlbGluZS1jb3JlYCBlbnRyeSBwb2ludCBjYW5cbiAqIGV4cG9ydCB0aGVtIHdpdGhvdXQgcHV0dGluZyBgYXdzLWNkay1saWJgIG9uIGV2ZXJ5IGNvbnN1bWVyJ3MgaW1wb3J0IGdyYXBoLlxuICogQW55dGhpbmcgaGVyZSB0aGF0IG5lZWRzIGEgQ0RLIHR5cGUgYmVsb25ncyBpbiBgcGlwZWxpbmUtaGVscGVycy50c2AgaW5zdGVhZC5cbiAqL1xuXG5pbXBvcnQgeyBDREtfTUVUQURBVEFfUFJFRklYLCB0eXBlIE1ldGFEYXRhVHlwZSB9IGZyb20gJy4vcGlwZWxpbmUtdHlwZXMuanMnO1xuXG4vKipcbiAqIE1lcmdlIG11bHRpcGxlIG1ldGFkYXRhIG9iamVjdHMgaW50byBvbmUuIExhdGVyIHNvdXJjZXMgb3ZlcnJpZGUgZWFybGllciBvbmVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2UoLi4uc291cmNlczogQXJyYXk8UGFydGlhbDxNZXRhRGF0YVR5cGU+Pik6IE1ldGFEYXRhVHlwZSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCAuLi5zb3VyY2VzKSBhcyBNZXRhRGF0YVR5cGU7XG59XG5cbi8qKlxuICogRXh0cmFjdCBub24tbmFtZXNwYWNlZCBtZXRhZGF0YSBrZXlzIGFzIGVudmlyb25tZW50IHZhcmlhYmxlIHN0cmluZ3MuXG4gKiBLZXlzIHN0YXJ0aW5nIHdpdGggJ2F3czpjZGs6JyBhcmUgcmVzZXJ2ZWQgZm9yIENESyBjb25zdHJ1Y3QgcHJvcHNcbiAqIChwcm9jZXNzZWQgYnkgbWV0YWRhdGEgZXh0cmFjdGlvbiBmdW5jdGlvbnMpIGFuZCBhcmUgZXhjbHVkZWQgaGVyZS5cbiAqXG4gKiBBbGwgdmFsdWVzIGFyZSBjb252ZXJ0ZWQgdG8gc3RyaW5ncyBmb3IgQ29kZUJ1aWxkIGNvbXBhdGliaWxpdHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0TWV0YWRhdGFFbnYobWV0YWRhdGE6IE1ldGFEYXRhVHlwZSk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobWV0YWRhdGEpKSB7XG4gICAgaWYgKCFrZXkuc3RhcnRzV2l0aChDREtfTUVUQURBVEFfUFJFRklYKSkge1xuICAgICAgZW52W2tleV0gPSBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZW52O1xufVxuXG4vKiogUGx1Z2luIGNhdGVnb3JpZXMgd2hvc2UgZmFpbHVyZSBtdXN0IE5FVkVSIGJlIG1hc2tlZC4gQSBzY2FuL3NlY3VyaXR5IHN0ZXAgdGhhdFxuICogIGV4aXRzIG5vbi16ZXJvIGhhcyB0byBmYWlsIHRoZSBwaXBlbGluZSAocmVwbyBydWxlOiBhIGZhaWxlZCBzY2FuIGlzIHJlZCwgbmV2ZXIgYVxuICogIGZhbHNlLWdyZWVuIGB8fCB0cnVlYCksIHNvIHN1Y2ggYSBwbHVnaW4ncyBmYWlsdXJlQmVoYXZpb3IgaXMgZm9yY2VkIHRvICdmYWlsJ1xuICogIHJlZ2FyZGxlc3Mgb2Ygd2hhdCB0aGUgcGx1Z2luIG9yIHN0ZXAgYXV0aG9yZWQuICovXG5jb25zdCBGQUlMX0ZBU1RfQ0FURUdPUklFUyA9IC9zY2FufHNlY3VyaXR5fHNhc3R8ZGFzdHx2dWxufHNlY3JldC9pO1xuXG4vKiogUmVzb2x2ZSB0aGUgZWZmZWN0aXZlIGZhaWx1cmVCZWhhdmlvcjogYSBzY2FuL3NlY3VyaXR5LWNhdGVnb3J5IHBsdWdpbiBpcyBwaW5uZWRcbiAqICB0byAnZmFpbCc7IG90aGVyd2lzZSB0aGUgYXV0aG9yZWQgdmFsdWUgKGRlZmF1bHQgJ2ZhaWwnKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRmFpbHVyZUJlaGF2aW9yKGNhdGVnb3J5Pzogc3RyaW5nLCBhdXRob3JlZD86ICdmYWlsJyB8ICd3YXJuJyB8ICdpZ25vcmUnKTogJ2ZhaWwnIHwgJ3dhcm4nIHwgJ2lnbm9yZScge1xuICBpZiAoY2F0ZWdvcnkgJiYgRkFJTF9GQVNUX0NBVEVHT1JJRVMudGVzdChjYXRlZ29yeSkpIHJldHVybiAnZmFpbCc7XG4gIHJldHVybiBhdXRob3JlZCA/PyAnZmFpbCc7XG59XG5cbi8qKlxuICogUmVwbGFjZXMgYWxsIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IGxldHRlcnMgb3IgbnVtYmVycyB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWVcbiAqIEBwYXJhbSBpbnB1dCAtIFRoZSBzdHJpbmcgdG8gcHJvY2Vzc1xuICogQHBhcmFtIHJlcGxhY2VWYWx1ZSAtIFRoZSBjaGFyYWN0ZXIocykgdG8gcmVwbGFjZSBub24tYWxwaGFudW1lcmljIGNoYXJhY3RlcnMgd2l0aCAoZGVmYXVsdDogJ18nKVxuICogQHJldHVybnMgVGhlIHN0cmluZyB3aXRoIG5vbi1hbHBoYW51bWVyaWMgY2hhcmFjdGVycyByZXBsYWNlZFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZU5vbkFscGhhbnVtZXJpYyhpbnB1dDogc3RyaW5nLCByZXBsYWNlVmFsdWU6IHN0cmluZyA9ICdfJyk6IHN0cmluZyB7XG4gIHJldHVybiBpbnB1dC5yZXBsYWNlKC9bXmEtekEtWjAtOV0vZywgcmVwbGFjZVZhbHVlKTtcbn1cbiJdfQ==
@@ -0,0 +1,200 @@
1
+ import type { SecretValue } from 'aws-cdk-lib';
2
+ import type { MetaDataType } from './pipeline-types.js';
3
+ import type { SecurityGroupConfig } from './security-group-types.js';
4
+ /**
5
+ * Network configuration using explicit subnet IDs
6
+ *
7
+ * Use when you know the exact subnet IDs where CodeBuild should run.
8
+ * Subnets are selected directly by ID; VPC is looked up from the provided vpcId.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const network: SubnetIdsNetwork = {
13
+ * type: 'subnetIds',
14
+ * options: {
15
+ * vpcId: 'vpc-0a1b2c3d4e5f6a7b8',
16
+ * subnetIds: ['subnet-0a1b2c3d', 'subnet-4e5f6a7b'],
17
+ * securityGroupIds: ['sg-12345678']
18
+ * }
19
+ * };
20
+ * ```
21
+ */
22
+ export interface SubnetIdsNetwork {
23
+ readonly type: 'subnetIds';
24
+ readonly options: SubnetIdsNetworkOptions;
25
+ }
26
+ /**
27
+ * Network configuration using VPC lookup by ID
28
+ *
29
+ * Looks up an existing VPC by its ID and resolves subnets via subnetSelection filters.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const network: VpcIdNetwork = {
34
+ * type: 'vpcId',
35
+ * options: {
36
+ * vpcId: 'vpc-0a1b2c3d4e5f6a7b8',
37
+ * subnetType: 'PRIVATE_WITH_EGRESS',
38
+ * securityGroupIds: ['sg-12345678']
39
+ * }
40
+ * };
41
+ * ```
42
+ */
43
+ export interface VpcIdNetwork {
44
+ readonly type: 'vpcId';
45
+ readonly options: VpcIdNetworkOptions;
46
+ }
47
+ /**
48
+ * Network configuration using VPC lookup by tags
49
+ *
50
+ * Looks up an existing VPC by tag filters and resolves subnets via subnetSelection filters.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const network: VpcLookupNetwork = {
55
+ * type: 'vpcLookup',
56
+ * options: {
57
+ * tags: { 'aws:cloudformation:stack-name': 'NetworkStack' },
58
+ * subnetType: 'PRIVATE_WITH_EGRESS',
59
+ * availabilityZones: ['us-east-1a', 'us-east-1b']
60
+ * }
61
+ * };
62
+ * ```
63
+ */
64
+ export interface VpcLookupNetwork {
65
+ readonly type: 'vpcLookup';
66
+ readonly options: VpcLookupNetworkOptions;
67
+ }
68
+ /**
69
+ * Common subnet selection filters shared by VPC-based network options
70
+ */
71
+ interface SubnetSelectionOptions {
72
+ /**
73
+ * Subnet type filter for subnet selection
74
+ * Maps to CDK SubnetType values
75
+ * @default 'PRIVATE_WITH_EGRESS'
76
+ */
77
+ readonly subnetType?: SubnetTypeName;
78
+ /**
79
+ * Filter subnets to specific availability zones
80
+ * @example ['us-east-1a', 'us-east-1b']
81
+ */
82
+ readonly availabilityZones?: string[];
83
+ /**
84
+ * Filter subnets by CDK subnet group name
85
+ * Matches the groupName assigned during VPC creation
86
+ */
87
+ readonly subnetGroupName?: string;
88
+ /**
89
+ * Security group IDs to attach to CodeBuild projects
90
+ * @example ['sg-12345678']
91
+ */
92
+ readonly securityGroupIds?: string[];
93
+ }
94
+ /**
95
+ * Configuration options for explicit subnet ID network
96
+ */
97
+ export interface SubnetIdsNetworkOptions {
98
+ /**
99
+ * VPC ID that contains the subnets.
100
+ * Required because CDK CodeBuildStep needs a vpc reference.
101
+ * Can be a plain string or a SecretValue (e.g. from Secrets Manager).
102
+ * @example 'vpc-0a1b2c3d4e5f6a7b8'
103
+ */
104
+ readonly vpcId: SecretValue | string;
105
+ /**
106
+ * Explicit list of subnet IDs where CodeBuild projects will run
107
+ * @example ['subnet-0a1b2c3d', 'subnet-4e5f6a7b']
108
+ */
109
+ readonly subnetIds: string[];
110
+ /**
111
+ * Security group IDs to attach to CodeBuild projects
112
+ * @example ['sg-12345678']
113
+ */
114
+ readonly securityGroupIds?: string[];
115
+ }
116
+ /**
117
+ * Configuration options for VPC lookup by ID
118
+ */
119
+ export interface VpcIdNetworkOptions extends SubnetSelectionOptions {
120
+ /**
121
+ * VPC ID to look up
122
+ * Can be a plain string or a SecretValue (e.g. from Secrets Manager).
123
+ * @example 'vpc-0a1b2c3d4e5f6a7b8'
124
+ */
125
+ readonly vpcId: SecretValue | string;
126
+ }
127
+ /**
128
+ * Configuration options for VPC lookup by tags
129
+ */
130
+ export interface VpcLookupNetworkOptions extends SubnetSelectionOptions {
131
+ /**
132
+ * Tag key-value pairs to identify the VPC
133
+ * All tags must match for lookup to succeed
134
+ * @example { Environment: 'production', Team: 'platform' }
135
+ */
136
+ readonly tags: Record<string, string>;
137
+ /**
138
+ * Optional VPC name (value of the 'Name' tag) for additional filtering
139
+ */
140
+ readonly vpcName?: string;
141
+ /**
142
+ * Optional AWS region override for cross-region VPC lookup
143
+ * @example 'us-west-2'
144
+ */
145
+ readonly region?: string;
146
+ }
147
+ /**
148
+ * Subnet type names corresponding to CDK SubnetType enum values
149
+ *
150
+ * @see https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.SubnetType.html
151
+ */
152
+ export type SubnetTypeName = 'PRIVATE_WITH_EGRESS' | 'PRIVATE_WITH_NAT' | 'PRIVATE_ISOLATED' | 'PUBLIC';
153
+ /**
154
+ * Union type of all supported network configurations.
155
+ *
156
+ * Used at two independent levels:
157
+ * - Pipeline-level (`defaults.network`) — applies to all CodeBuild actions
158
+ * - Step-level (`synth.network`, `CodeBuildStepOptions.network`) — applies to an individual build step
159
+ *
160
+ * Each variant resolves to vpc, subnetSelection, and optional securityGroups:
161
+ * - SubnetIdsNetwork: VPC looked up by ID, subnets selected explicitly by ID
162
+ * - VpcIdNetwork: VPC looked up by ID, subnets resolved via subnetSelection filters
163
+ * - VpcLookupNetwork: VPC looked up by tags, subnets resolved via subnetSelection filters
164
+ */
165
+ export type NetworkConfig = SubnetIdsNetwork | VpcIdNetwork | VpcLookupNetwork;
166
+ /**
167
+ * Pipeline-level CodeBuild defaults applied to every CodeBuild action
168
+ * (synth, self-mutation, asset publishing) via `codeBuildDefaults`.
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * const defaults: CodeBuildDefaults = {
173
+ * network: {
174
+ * type: 'vpcId',
175
+ * options: { vpcId: 'vpc-abc123', subnetType: 'PRIVATE_WITH_EGRESS' }
176
+ * },
177
+ * metadata: {
178
+ * [MetadataKeys.PRIVILEGED]: true,
179
+ * },
180
+ * };
181
+ * ```
182
+ */
183
+ export interface CodeBuildDefaults {
184
+ /**
185
+ * Network configuration for all CodeBuild actions.
186
+ * Resolves to vpc, subnetSelection, and optional securityGroups.
187
+ */
188
+ readonly network?: NetworkConfig;
189
+ /**
190
+ * Standalone security groups for all CodeBuild actions.
191
+ * Merged with any security groups resolved from network config.
192
+ */
193
+ readonly securityGroups?: SecurityGroupConfig;
194
+ /**
195
+ * Metadata applied to all CodeBuild actions.
196
+ * Merged with step-level metadata; step-level keys take precedence.
197
+ */
198
+ readonly metadata?: MetaDataType;
199
+ }
200
+ export {};
@@ -0,0 +1,4 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ export {};
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay10eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL25ldHdvcmstdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgdHlwZSB7IFNlY3JldFZhbHVlIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHR5cGUgeyBNZXRhRGF0YVR5cGUgfSBmcm9tICcuL3BpcGVsaW5lLXR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgU2VjdXJpdHlHcm91cENvbmZpZyB9IGZyb20gJy4vc2VjdXJpdHktZ3JvdXAtdHlwZXMuanMnO1xuXG4vKipcbiAqIE5ldHdvcmsgY29uZmlndXJhdGlvbiB1c2luZyBleHBsaWNpdCBzdWJuZXQgSURzXG4gKlxuICogVXNlIHdoZW4geW91IGtub3cgdGhlIGV4YWN0IHN1Ym5ldCBJRHMgd2hlcmUgQ29kZUJ1aWxkIHNob3VsZCBydW4uXG4gKiBTdWJuZXRzIGFyZSBzZWxlY3RlZCBkaXJlY3RseSBieSBJRDsgVlBDIGlzIGxvb2tlZCB1cCBmcm9tIHRoZSBwcm92aWRlZCB2cGNJZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmV0d29yazogU3VibmV0SWRzTmV0d29yayA9IHtcbiAqICAgdHlwZTogJ3N1Ym5ldElkcycsXG4gKiAgIG9wdGlvbnM6IHtcbiAqICAgICB2cGNJZDogJ3ZwYy0wYTFiMmMzZDRlNWY2YTdiOCcsXG4gKiAgICAgc3VibmV0SWRzOiBbJ3N1Ym5ldC0wYTFiMmMzZCcsICdzdWJuZXQtNGU1ZjZhN2InXSxcbiAqICAgICBzZWN1cml0eUdyb3VwSWRzOiBbJ3NnLTEyMzQ1Njc4J11cbiAqICAgfVxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN1Ym5ldElkc05ldHdvcmsge1xuICByZWFkb25seSB0eXBlOiAnc3VibmV0SWRzJztcbiAgcmVhZG9ubHkgb3B0aW9uczogU3VibmV0SWRzTmV0d29ya09wdGlvbnM7XG59XG5cbi8qKlxuICogTmV0d29yayBjb25maWd1cmF0aW9uIHVzaW5nIFZQQyBsb29rdXAgYnkgSURcbiAqXG4gKiBMb29rcyB1cCBhbiBleGlzdGluZyBWUEMgYnkgaXRzIElEIGFuZCByZXNvbHZlcyBzdWJuZXRzIHZpYSBzdWJuZXRTZWxlY3Rpb24gZmlsdGVycy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbmV0d29yazogVnBjSWROZXR3b3JrID0ge1xuICogICB0eXBlOiAndnBjSWQnLFxuICogICBvcHRpb25zOiB7XG4gKiAgICAgdnBjSWQ6ICd2cGMtMGExYjJjM2Q0ZTVmNmE3YjgnLFxuICogICAgIHN1Ym5ldFR5cGU6ICdQUklWQVRFX1dJVEhfRUdSRVNTJyxcbiAqICAgICBzZWN1cml0eUdyb3VwSWRzOiBbJ3NnLTEyMzQ1Njc4J11cbiAqICAgfVxuICogfTtcbiAqIGBgYFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZwY0lkTmV0d29yayB7XG4gIHJlYWRvbmx5IHR5cGU6ICd2cGNJZCc7XG4gIHJlYWRvbmx5IG9wdGlvbnM6IFZwY0lkTmV0d29ya09wdGlvbnM7XG59XG5cbi8qKlxuICogTmV0d29yayBjb25maWd1cmF0aW9uIHVzaW5nIFZQQyBsb29rdXAgYnkgdGFnc1xuICpcbiAqIExvb2tzIHVwIGFuIGV4aXN0aW5nIFZQQyBieSB0YWcgZmlsdGVycyBhbmQgcmVzb2x2ZXMgc3VibmV0cyB2aWEgc3VibmV0U2VsZWN0aW9uIGZpbHRlcnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IG5ldHdvcms6IFZwY0xvb2t1cE5ldHdvcmsgPSB7XG4gKiAgIHR5cGU6ICd2cGNMb29rdXAnLFxuICogICBvcHRpb25zOiB7XG4gKiAgICAgdGFnczogeyAnYXdzOmNsb3VkZm9ybWF0aW9uOnN0YWNrLW5hbWUnOiAnTmV0d29ya1N0YWNrJyB9LFxuICogICAgIHN1Ym5ldFR5cGU6ICdQUklWQVRFX1dJVEhfRUdSRVNTJyxcbiAqICAgICBhdmFpbGFiaWxpdHlab25lczogWyd1cy1lYXN0LTFhJywgJ3VzLWVhc3QtMWInXVxuICogICB9XG4gKiB9O1xuICogYGBgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVnBjTG9va3VwTmV0d29yayB7XG4gIHJlYWRvbmx5IHR5cGU6ICd2cGNMb29rdXAnO1xuICByZWFkb25seSBvcHRpb25zOiBWcGNMb29rdXBOZXR3b3JrT3B0aW9ucztcbn1cblxuLyoqXG4gKiBDb21tb24gc3VibmV0IHNlbGVjdGlvbiBmaWx0ZXJzIHNoYXJlZCBieSBWUEMtYmFzZWQgbmV0d29yayBvcHRpb25zXG4gKi9cbmludGVyZmFjZSBTdWJuZXRTZWxlY3Rpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFN1Ym5ldCB0eXBlIGZpbHRlciBmb3Igc3VibmV0IHNlbGVjdGlvblxuICAgKiBNYXBzIHRvIENESyBTdWJuZXRUeXBlIHZhbHVlc1xuICAgKiBAZGVmYXVsdCAnUFJJVkFURV9XSVRIX0VHUkVTUydcbiAgICovXG4gIHJlYWRvbmx5IHN1Ym5ldFR5cGU/OiBTdWJuZXRUeXBlTmFtZTtcblxuICAvKipcbiAgICogRmlsdGVyIHN1Ym5ldHMgdG8gc3BlY2lmaWMgYXZhaWxhYmlsaXR5IHpvbmVzXG4gICAqIEBleGFtcGxlIFsndXMtZWFzdC0xYScsICd1cy1lYXN0LTFiJ11cbiAgICovXG4gIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmVzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEZpbHRlciBzdWJuZXRzIGJ5IENESyBzdWJuZXQgZ3JvdXAgbmFtZVxuICAgKiBNYXRjaGVzIHRoZSBncm91cE5hbWUgYXNzaWduZWQgZHVyaW5nIFZQQyBjcmVhdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgc3VibmV0R3JvdXBOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTZWN1cml0eSBncm91cCBJRHMgdG8gYXR0YWNoIHRvIENvZGVCdWlsZCBwcm9qZWN0c1xuICAgKiBAZXhhbXBsZSBbJ3NnLTEyMzQ1Njc4J11cbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXBJZHM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIGV4cGxpY2l0IHN1Ym5ldCBJRCBuZXR3b3JrXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3VibmV0SWRzTmV0d29ya09wdGlvbnMge1xuICAvKipcbiAgICogVlBDIElEIHRoYXQgY29udGFpbnMgdGhlIHN1Ym5ldHMuXG4gICAqIFJlcXVpcmVkIGJlY2F1c2UgQ0RLIENvZGVCdWlsZFN0ZXAgbmVlZHMgYSB2cGMgcmVmZXJlbmNlLlxuICAgKiBDYW4gYmUgYSBwbGFpbiBzdHJpbmcgb3IgYSBTZWNyZXRWYWx1ZSAoZS5nLiBmcm9tIFNlY3JldHMgTWFuYWdlcikuXG4gICAqIEBleGFtcGxlICd2cGMtMGExYjJjM2Q0ZTVmNmE3YjgnXG4gICAqL1xuICByZWFkb25seSB2cGNJZDogU2VjcmV0VmFsdWUgfCBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEV4cGxpY2l0IGxpc3Qgb2Ygc3VibmV0IElEcyB3aGVyZSBDb2RlQnVpbGQgcHJvamVjdHMgd2lsbCBydW5cbiAgICogQGV4YW1wbGUgWydzdWJuZXQtMGExYjJjM2QnLCAnc3VibmV0LTRlNWY2YTdiJ11cbiAgICovXG4gIHJlYWRvbmx5IHN1Ym5ldElkczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFNlY3VyaXR5IGdyb3VwIElEcyB0byBhdHRhY2ggdG8gQ29kZUJ1aWxkIHByb2plY3RzXG4gICAqIEBleGFtcGxlIFsnc2ctMTIzNDU2NzgnXVxuICAgKi9cbiAgcmVhZG9ubHkgc2VjdXJpdHlHcm91cElkcz86IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgVlBDIGxvb2t1cCBieSBJRFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZwY0lkTmV0d29ya09wdGlvbnMgZXh0ZW5kcyBTdWJuZXRTZWxlY3Rpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFZQQyBJRCB0byBsb29rIHVwXG4gICAqIENhbiBiZSBhIHBsYWluIHN0cmluZyBvciBhIFNlY3JldFZhbHVlIChlLmcuIGZyb20gU2VjcmV0cyBNYW5hZ2VyKS5cbiAgICogQGV4YW1wbGUgJ3ZwYy0wYTFiMmMzZDRlNWY2YTdiOCdcbiAgICovXG4gIHJlYWRvbmx5IHZwY0lkOiBTZWNyZXRWYWx1ZSB8IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIG9wdGlvbnMgZm9yIFZQQyBsb29rdXAgYnkgdGFnc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFZwY0xvb2t1cE5ldHdvcmtPcHRpb25zIGV4dGVuZHMgU3VibmV0U2VsZWN0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUYWcga2V5LXZhbHVlIHBhaXJzIHRvIGlkZW50aWZ5IHRoZSBWUENcbiAgICogQWxsIHRhZ3MgbXVzdCBtYXRjaCBmb3IgbG9va3VwIHRvIHN1Y2NlZWRcbiAgICogQGV4YW1wbGUgeyBFbnZpcm9ubWVudDogJ3Byb2R1Y3Rpb24nLCBUZWFtOiAncGxhdGZvcm0nIH1cbiAgICovXG4gIHJlYWRvbmx5IHRhZ3M6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIFZQQyBuYW1lICh2YWx1ZSBvZiB0aGUgJ05hbWUnIHRhZykgZm9yIGFkZGl0aW9uYWwgZmlsdGVyaW5nXG4gICAqL1xuICByZWFkb25seSB2cGNOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBBV1MgcmVnaW9uIG92ZXJyaWRlIGZvciBjcm9zcy1yZWdpb24gVlBDIGxvb2t1cFxuICAgKiBAZXhhbXBsZSAndXMtd2VzdC0yJ1xuICAgKi9cbiAgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFN1Ym5ldCB0eXBlIG5hbWVzIGNvcnJlc3BvbmRpbmcgdG8gQ0RLIFN1Ym5ldFR5cGUgZW51bSB2YWx1ZXNcbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jZGsvYXBpL3YyL2RvY3MvYXdzLWNkay1saWIuYXdzX2VjMi5TdWJuZXRUeXBlLmh0bWxcbiAqL1xuZXhwb3J0IHR5cGUgU3VibmV0VHlwZU5hbWUgPVxuICB8ICdQUklWQVRFX1dJVEhfRUdSRVNTJ1xuICB8ICdQUklWQVRFX1dJVEhfTkFUJ1xuICB8ICdQUklWQVRFX0lTT0xBVEVEJ1xuICB8ICdQVUJMSUMnO1xuXG4vKipcbiAqIFVuaW9uIHR5cGUgb2YgYWxsIHN1cHBvcnRlZCBuZXR3b3JrIGNvbmZpZ3VyYXRpb25zLlxuICpcbiAqIFVzZWQgYXQgdHdvIGluZGVwZW5kZW50IGxldmVsczpcbiAqIC0gUGlwZWxpbmUtbGV2ZWwgKGBkZWZhdWx0cy5uZXR3b3JrYCkg4oCUIGFwcGxpZXMgdG8gYWxsIENvZGVCdWlsZCBhY3Rpb25zXG4gKiAtIFN0ZXAtbGV2ZWwgKGBzeW50aC5uZXR3b3JrYCwgYENvZGVCdWlsZFN0ZXBPcHRpb25zLm5ldHdvcmtgKSDigJQgYXBwbGllcyB0byBhbiBpbmRpdmlkdWFsIGJ1aWxkIHN0ZXBcbiAqXG4gKiBFYWNoIHZhcmlhbnQgcmVzb2x2ZXMgdG8gdnBjLCBzdWJuZXRTZWxlY3Rpb24sIGFuZCBvcHRpb25hbCBzZWN1cml0eUdyb3VwczpcbiAqIC0gU3VibmV0SWRzTmV0d29yazogVlBDIGxvb2tlZCB1cCBieSBJRCwgc3VibmV0cyBzZWxlY3RlZCBleHBsaWNpdGx5IGJ5IElEXG4gKiAtIFZwY0lkTmV0d29yazogVlBDIGxvb2tlZCB1cCBieSBJRCwgc3VibmV0cyByZXNvbHZlZCB2aWEgc3VibmV0U2VsZWN0aW9uIGZpbHRlcnNcbiAqIC0gVnBjTG9va3VwTmV0d29yazogVlBDIGxvb2tlZCB1cCBieSB0YWdzLCBzdWJuZXRzIHJlc29sdmVkIHZpYSBzdWJuZXRTZWxlY3Rpb24gZmlsdGVyc1xuICovXG5leHBvcnQgdHlwZSBOZXR3b3JrQ29uZmlnID0gU3VibmV0SWRzTmV0d29yayB8IFZwY0lkTmV0d29yayB8IFZwY0xvb2t1cE5ldHdvcms7XG5cbi8qKlxuICogUGlwZWxpbmUtbGV2ZWwgQ29kZUJ1aWxkIGRlZmF1bHRzIGFwcGxpZWQgdG8gZXZlcnkgQ29kZUJ1aWxkIGFjdGlvblxuICogKHN5bnRoLCBzZWxmLW11dGF0aW9uLCBhc3NldCBwdWJsaXNoaW5nKSB2aWEgYGNvZGVCdWlsZERlZmF1bHRzYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgZGVmYXVsdHM6IENvZGVCdWlsZERlZmF1bHRzID0ge1xuICogICBuZXR3b3JrOiB7XG4gKiAgICAgdHlwZTogJ3ZwY0lkJyxcbiAqICAgICBvcHRpb25zOiB7IHZwY0lkOiAndnBjLWFiYzEyMycsIHN1Ym5ldFR5cGU6ICdQUklWQVRFX1dJVEhfRUdSRVNTJyB9XG4gKiAgIH0sXG4gKiAgIG1ldGFkYXRhOiB7XG4gKiAgICAgW01ldGFkYXRhS2V5cy5QUklWSUxFR0VEXTogdHJ1ZSxcbiAqICAgfSxcbiAqIH07XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb2RlQnVpbGREZWZhdWx0cyB7XG4gIC8qKlxuICAgKiBOZXR3b3JrIGNvbmZpZ3VyYXRpb24gZm9yIGFsbCBDb2RlQnVpbGQgYWN0aW9ucy5cbiAgICogUmVzb2x2ZXMgdG8gdnBjLCBzdWJuZXRTZWxlY3Rpb24sIGFuZCBvcHRpb25hbCBzZWN1cml0eUdyb3Vwcy5cbiAgICovXG4gIHJlYWRvbmx5IG5ldHdvcms/OiBOZXR3b3JrQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBTdGFuZGFsb25lIHNlY3VyaXR5IGdyb3VwcyBmb3IgYWxsIENvZGVCdWlsZCBhY3Rpb25zLlxuICAgKiBNZXJnZWQgd2l0aCBhbnkgc2VjdXJpdHkgZ3JvdXBzIHJlc29sdmVkIGZyb20gbmV0d29yayBjb25maWcuXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3Vwcz86IFNlY3VyaXR5R3JvdXBDb25maWc7XG5cbiAgLyoqXG4gICAqIE1ldGFkYXRhIGFwcGxpZWQgdG8gYWxsIENvZGVCdWlsZCBhY3Rpb25zLlxuICAgKiBNZXJnZWQgd2l0aCBzdGVwLWxldmVsIG1ldGFkYXRhOyBzdGVwLWxldmVsIGtleXMgdGFrZSBwcmVjZWRlbmNlLlxuICAgKi9cbiAgcmVhZG9ubHkgbWV0YWRhdGE/OiBNZXRhRGF0YVR5cGU7XG59XG4iXX0=
@@ -0,0 +1,33 @@
1
+ import { type ISecurityGroup, type IVpc, type SubnetSelection } from 'aws-cdk-lib/aws-ec2';
2
+ import { Construct } from 'constructs';
3
+ import { UniqueId } from './id-generator.js';
4
+ import type { NetworkConfig } from './network-types.js';
5
+ /** Resolved CDK network props ready to spread into CodeBuildStep or codeBuildDefaults */
6
+ export interface ResolvedNetwork {
7
+ vpc: IVpc;
8
+ subnetSelection: SubnetSelection;
9
+ securityGroups?: ISecurityGroup[];
10
+ }
11
+ /**
12
+ * Build a NetworkConfig from environment, for deployments that want EVERY
13
+ * synthesized pipeline's CodeBuild to run inside a VPC (the EC2 "internal" /
14
+ * inside-AWS-only mode) without per-pipeline network config. Returns undefined
15
+ * when the env isn't set — public/default deployments run CodeBuild in the
16
+ * AWS-managed network as before.
17
+ *
18
+ * Env (set on the pipeline service in internal mode):
19
+ * PIPELINE_VPC_ID VPC the CodeBuild projects join (required)
20
+ * PIPELINE_SUBNET_IDS comma-separated private subnet IDs (required)
21
+ * PIPELINE_SECURITY_GROUP_IDS comma-separated SG IDs (optional)
22
+ */
23
+ export declare function networkConfigFromEnv(): NetworkConfig | undefined;
24
+ /**
25
+ * Resolve a NetworkConfig into CDK props for CodeBuildStep or codeBuildDefaults.
26
+ * Uses discriminated union narrowing to delegate to the appropriate CDK lookups.
27
+ *
28
+ * @param scope - CDK construct scope
29
+ * @param id - UniqueId instance for generating unique construct IDs
30
+ * @param network - Network configuration to resolve
31
+ * @returns Resolved network props ready to spread into CDK constructs
32
+ */
33
+ export declare function resolveNetwork(scope: Construct, id: UniqueId, network: NetworkConfig): ResolvedNetwork;
@@ -0,0 +1,112 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { SecurityGroup, Subnet, SubnetType, Vpc } from 'aws-cdk-lib/aws-ec2';
4
+ import { Construct } from 'constructs';
5
+ import { UniqueId } from './id-generator.js';
6
+ import { unwrapSecret } from './pipeline-helpers.js';
7
+ /**
8
+ * Mapping from string subnet type names to CDK SubnetType enum values
9
+ */
10
+ const SUBNET_TYPE_MAP = {
11
+ PRIVATE_WITH_EGRESS: SubnetType.PRIVATE_WITH_EGRESS,
12
+ PRIVATE_WITH_NAT: SubnetType.PRIVATE_WITH_NAT,
13
+ PRIVATE_ISOLATED: SubnetType.PRIVATE_ISOLATED,
14
+ PUBLIC: SubnetType.PUBLIC,
15
+ };
16
+ const DEFAULT_SUBNET_TYPE = 'PRIVATE_WITH_EGRESS';
17
+ /**
18
+ * Build a NetworkConfig from environment, for deployments that want EVERY
19
+ * synthesized pipeline's CodeBuild to run inside a VPC (the EC2 "internal" /
20
+ * inside-AWS-only mode) without per-pipeline network config. Returns undefined
21
+ * when the env isn't set — public/default deployments run CodeBuild in the
22
+ * AWS-managed network as before.
23
+ *
24
+ * Env (set on the pipeline service in internal mode):
25
+ * PIPELINE_VPC_ID VPC the CodeBuild projects join (required)
26
+ * PIPELINE_SUBNET_IDS comma-separated private subnet IDs (required)
27
+ * PIPELINE_SECURITY_GROUP_IDS comma-separated SG IDs (optional)
28
+ */
29
+ export function networkConfigFromEnv() {
30
+ const vpcId = (process.env.PIPELINE_VPC_ID || '').trim();
31
+ const subnetIds = (process.env.PIPELINE_SUBNET_IDS || '')
32
+ .split(',').map((s) => s.trim()).filter(Boolean);
33
+ if (!vpcId || subnetIds.length === 0)
34
+ return undefined;
35
+ const securityGroupIds = (process.env.PIPELINE_SECURITY_GROUP_IDS || '')
36
+ .split(',').map((s) => s.trim()).filter(Boolean);
37
+ return {
38
+ type: 'subnetIds',
39
+ options: {
40
+ vpcId,
41
+ subnetIds,
42
+ ...(securityGroupIds.length > 0 && { securityGroupIds }),
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * Resolve a NetworkConfig into CDK props for CodeBuildStep or codeBuildDefaults.
48
+ * Uses discriminated union narrowing to delegate to the appropriate CDK lookups.
49
+ *
50
+ * @param scope - CDK construct scope
51
+ * @param id - UniqueId instance for generating unique construct IDs
52
+ * @param network - Network configuration to resolve
53
+ * @returns Resolved network props ready to spread into CDK constructs
54
+ */
55
+ export function resolveNetwork(scope, id, network) {
56
+ switch (network.type) {
57
+ case 'subnetIds': {
58
+ const vpc = Vpc.fromLookup(scope, id.generate('network:vpc'), {
59
+ vpcId: unwrapSecret(network.options.vpcId),
60
+ });
61
+ const subnets = network.options.subnetIds.map((subnetId) => Subnet.fromSubnetId(scope, id.generate('network:subnet'), subnetId));
62
+ return withSecurityGroups({ vpc, subnetSelection: { subnets } }, scope, id, network.options.securityGroupIds);
63
+ }
64
+ case 'vpcId': {
65
+ const vpc = Vpc.fromLookup(scope, id.generate('network:vpc'), {
66
+ vpcId: unwrapSecret(network.options.vpcId),
67
+ });
68
+ return withSecurityGroups({ vpc, subnetSelection: resolveSubnetSelection(network.options) }, scope, id, network.options.securityGroupIds);
69
+ }
70
+ case 'vpcLookup': {
71
+ const vpc = Vpc.fromLookup(scope, id.generate('network:vpc'), {
72
+ tags: network.options.tags,
73
+ ...(network.options.vpcName && { vpcName: network.options.vpcName }),
74
+ ...(network.options.region && { region: network.options.region }),
75
+ });
76
+ return withSecurityGroups({ vpc, subnetSelection: resolveSubnetSelection(network.options) }, scope, id, network.options.securityGroupIds);
77
+ }
78
+ default: {
79
+ const _exhaustive = network;
80
+ throw new Error(`Unknown network config type: ${_exhaustive.type}`);
81
+ }
82
+ }
83
+ }
84
+ /**
85
+ * Attach resolved security groups to a network result when present.
86
+ */
87
+ function withSecurityGroups(result, scope, id, securityGroupIds) {
88
+ const securityGroups = resolveSecurityGroups(scope, id, securityGroupIds);
89
+ return securityGroups ? { ...result, securityGroups } : result;
90
+ }
91
+ /**
92
+ * Build a SubnetSelection from options that carry subnetType, availabilityZones,
93
+ * and subnetGroupName. Shared by vpcId and vpcLookup branches.
94
+ */
95
+ function resolveSubnetSelection(options) {
96
+ return {
97
+ subnetType: SUBNET_TYPE_MAP[options.subnetType ?? DEFAULT_SUBNET_TYPE],
98
+ ...(options.availabilityZones && { availabilityZones: options.availabilityZones }),
99
+ ...(options.subnetGroupName && { subnetGroupName: options.subnetGroupName }),
100
+ };
101
+ }
102
+ /**
103
+ * Resolve security group IDs into CDK security group references.
104
+ * Returns undefined when no IDs are provided.
105
+ */
106
+ function resolveSecurityGroups(scope, id, securityGroupIds) {
107
+ if (!securityGroupIds?.length) {
108
+ return undefined;
109
+ }
110
+ return securityGroupIds.map((sgId) => SecurityGroup.fromSecurityGroupId(scope, id.generate('network:sg'), sgId));
111
+ }
112
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb3JlL25ldHdvcmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQWtDLGFBQWEsRUFBRSxNQUFNLEVBQXdCLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNuSSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUs3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFckQ7O0dBRUc7QUFDSCxNQUFNLGVBQWUsR0FBdUM7SUFDMUQsbUJBQW1CLEVBQUUsVUFBVSxDQUFDLG1CQUFtQjtJQUNuRCxnQkFBZ0IsRUFBRSxVQUFVLENBQUMsZ0JBQWdCO0lBQzdDLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0I7SUFDN0MsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNO0NBQzFCLENBQUM7QUFFRixNQUFNLG1CQUFtQixHQUFtQixxQkFBcUIsQ0FBQztBQVNsRTs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sVUFBVSxvQkFBb0I7SUFDbEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6RCxNQUFNLFNBQVMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLElBQUksRUFBRSxDQUFDO1NBQ3RELEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuRCxJQUFJLENBQUMsS0FBSyxJQUFJLFNB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QUFHLENBQ3pCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQ3BGLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB7IHR5cGUgSVNlY3VyaXR5R3JvdXAsIHR5cGUgSVZwYywgU2VjdXJpdHlHcm91cCwgU3VibmV0LCB0eXBlIFN1Ym5ldFNlbGVjdGlvbiwgU3VibmV0VHlwZSwgVnBjIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IFVuaXF1ZUlkIH0gZnJvbSAnLi9pZC1nZW5lcmF0b3IuanMnO1xuaW1wb3J0IHR5cGUge1xuICBOZXR3b3JrQ29uZmlnLFxuICBTdWJuZXRUeXBlTmFtZSxcbn0gZnJvbSAnLi9uZXR3b3JrLXR5cGVzLmpzJztcbmltcG9ydCB7IHVud3JhcFNlY3JldCB9IGZyb20gJy4vcGlwZWxpbmUtaGVscGVycy5qcyc7XG5cbi8qKlxuICogTWFwcGluZyBmcm9tIHN0cmluZyBzdWJuZXQgdHlwZSBuYW1lcyB0byBDREsgU3VibmV0VHlwZSBlbnVtIHZhbHVlc1xuICovXG5jb25zdCBTVUJORVRfVFlQRV9NQVA6IFJlY29yZDxTdWJuZXRUeXBlTmFtZSwgU3VibmV0VHlwZT4gPSB7XG4gIFBSSVZBVEVfV0lUSF9FR1JFU1M6IFN1Ym5ldFR5cGUuUFJJVkFURV9XSVRIX0VHUkVTUyxcbiAgUFJJVkFURV9XSVRIX05BVDogU3VibmV0VHlwZS5QUklWQVRFX1dJVEhfTkFULFxuICBQUklWQVRFX0lTT0xBVEVEOiBTdWJuZXRUeXBlLlBSSVZBVEVfSVNPTEFURUQsXG4gIFBVQkxJQzogU3VibmV0VHlwZS5QVUJMSUMsXG59O1xuXG5jb25zdCBERUZBVUxUX1NVQk5FVF9UWVBFOiBTdWJuZXRUeXBlTmFtZSA9ICdQUklWQVRFX1dJVEhfRUdSRVNTJztcblxuLyoqIFJlc29sdmVkIENESyBuZXR3b3JrIHByb3BzIHJlYWR5IHRvIHNwcmVhZCBpbnRvIENvZGVCdWlsZFN0ZXAgb3IgY29kZUJ1aWxkRGVmYXVsdHMgKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWROZXR3b3JrIHtcbiAgdnBjOiBJVnBjO1xuICBzdWJuZXRTZWxlY3Rpb246IFN1Ym5ldFNlbGVjdGlvbjtcbiAgc2VjdXJpdHlHcm91cHM/OiBJU2VjdXJpdHlHcm91cFtdO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgTmV0d29ya0NvbmZpZyBmcm9tIGVudmlyb25tZW50LCBmb3IgZGVwbG95bWVudHMgdGhhdCB3YW50IEVWRVJZXG4gKiBzeW50aGVzaXplZCBwaXBlbGluZSdzIENvZGVCdWlsZCB0byBydW4gaW5zaWRlIGEgVlBDICh0aGUgRUMyIFwiaW50ZXJuYWxcIiAvXG4gKiBpbnNpZGUtQVdTLW9ubHkgbW9kZSkgd2l0aG91dCBwZXItcGlwZWxpbmUgbmV0d29yayBjb25maWcuIFJldHVybnMgdW5kZWZpbmVkXG4gKiB3aGVuIHRoZSBlbnYgaXNuJ3Qgc2V0IOKAlCBwdWJsaWMvZGVmYXVsdCBkZXBsb3ltZW50cyBydW4gQ29kZUJ1aWxkIGluIHRoZVxuICogQVdTLW1hbmFnZWQgbmV0d29yayBhcyBiZWZvcmUuXG4gKlxuICogRW52IChzZXQgb24gdGhlIHBpcGVsaW5lIHNlcnZpY2UgaW4gaW50ZXJuYWwgbW9kZSk6XG4gKiAgIFBJUEVMSU5FX1ZQQ19JRCAgICAgICAgICAgICAgVlBDIHRoZSBDb2RlQnVpbGQgcHJvamVjdHMgam9pbiAocmVxdWlyZWQpXG4gKiAgIFBJUEVMSU5FX1NVQk5FVF9JRFMgICAgICAgICAgY29tbWEtc2VwYXJhdGVkIHByaXZhdGUgc3VibmV0IElEcyAocmVxdWlyZWQpXG4gKiAgIFBJUEVMSU5FX1NFQ1VSSVRZX0dST1VQX0lEUyAgY29tbWEtc2VwYXJhdGVkIFNHIElEcyAob3B0aW9uYWwpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZXR3b3JrQ29uZmlnRnJvbUVudigpOiBOZXR3b3JrQ29uZmlnIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdnBjSWQgPSAocHJvY2Vzcy5lbnYuUElQRUxJTkVfVlBDX0lEIHx8ICcnKS50cmltKCk7XG4gIGNvbnN0IHN1Ym5ldElkcyA9IChwcm9jZXNzLmVudi5QSVBFTElORV9TVUJORVRfSURTIHx8ICcnKVxuICAgIC5zcGxpdCgnLCcpLm1hcCgocykgPT4gcy50cmltKCkpLmZpbHRlcihCb29sZWFuKTtcbiAgaWYgKCF2cGNJZCB8fCBzdWJuZXRJZHMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHNlY3VyaXR5R3JvdXBJZHMgPSAocHJvY2Vzcy5lbnYuUElQRUxJTkVfU0VDVVJJVFlfR1JPVVBfSURTIHx8ICcnKVxuICAgIC5zcGxpdCgnLCcpLm1hcCgocykgPT4gcy50cmltKCkpLmZpbHRlcihCb29sZWFuKTtcblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICdzdWJuZXRJZHMnLFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIHZwY0lkLFxuICAgICAgc3VibmV0SWRzLFxuICAgICAgLi4uKHNlY3VyaXR5R3JvdXBJZHMubGVuZ3RoID4gMCAmJiB7IHNlY3VyaXR5R3JvdXBJZHMgfSksXG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgTmV0d29ya0NvbmZpZyBpbnRvIENESyBwcm9wcyBmb3IgQ29kZUJ1aWxkU3RlcCBvciBjb2RlQnVpbGREZWZhdWx0cy5cbiAqIFVzZXMgZGlzY3JpbWluYXRlZCB1bmlvbiBuYXJyb3dpbmcgdG8gZGVsZWdhdGUgdG8gdGhlIGFwcHJvcHJpYXRlIENESyBsb29rdXBzLlxuICpcbiAqIEBwYXJhbSBzY29wZSAtIENESyBjb25zdHJ1Y3Qgc2NvcGVcbiAqIEBwYXJhbSBpZCAtIFVuaXF1ZUlkIGluc3RhbmNlIGZvciBnZW5lcmF0aW5nIHVuaXF1ZSBjb25zdHJ1Y3QgSURzXG4gKiBAcGFyYW0gbmV0d29yayAtIE5ldHdvcmsgY29uZmlndXJhdGlvbiB0byByZXNvbHZlXG4gKiBAcmV0dXJucyBSZXNvbHZlZCBuZXR3b3JrIHByb3BzIHJlYWR5IHRvIHNwcmVhZCBpbnRvIENESyBjb25zdHJ1Y3RzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTmV0d29yayhcbiAgc2NvcGU6IENvbnN0cnVjdCxcbiAgaWQ6IFVuaXF1ZUlkLFxuICBuZXR3b3JrOiBOZXR3b3JrQ29uZmlnLFxuKTogUmVzb2x2ZWROZXR3b3JrIHtcbiAgc3dpdGNoIChuZXR3b3JrLnR5cGUpIHtcbiAgICBjYXNlICdzdWJuZXRJZHMnOiB7XG4gICAgICBjb25zdCB2cGMgPSBWcGMuZnJvbUxvb2t1cChzY29wZSwgaWQuZ2VuZXJhdGUoJ25ldHdvcms6dnBjJyksIHtcbiAgICAgICAgdnBjSWQ6IHVud3JhcFNlY3JldChuZXR3b3JrLm9wdGlvbnMudnBjSWQpLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN1Ym5ldHMgPSBuZXR3b3JrLm9wdGlvbnMuc3VibmV0SWRzLm1hcChcbiAgICAgICAgKHN1Ym5ldElkKSA9PiBTdWJuZXQuZnJvbVN1Ym5ldElkKHNjb3BlLCBpZC5nZW5lcmF0ZSgnbmV0d29yazpzdWJuZXQnKSwgc3VibmV0SWQpLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHdpdGhTZWN1cml0eUdyb3VwcyhcbiAgICAgICAgeyB2cGMsIHN1Ym5ldFNlbGVjdGlvbjogeyBzdWJuZXRzIH0gfSxcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIGlkLFxuICAgICAgICBuZXR3b3JrLm9wdGlvbnMuc2VjdXJpdHlHcm91cElkcyxcbiAgICAgICk7XG4gICAgfVxuICAgIGNhc2UgJ3ZwY0lkJzoge1xuICAgICAgY29uc3QgdnBjID0gVnBjLmZyb21Mb29rdXAoc2NvcGUsIGlkLmdlbmVyYXRlKCduZXR3b3JrOnZwYycpLCB7XG4gICAgICAgIHZwY0lkOiB1bndyYXBTZWNyZXQobmV0d29yay5vcHRpb25zLnZwY0lkKSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gd2l0aFNlY3VyaXR5R3JvdXBzKFxuICAgICAgICB7IHZwYywgc3VibmV0U2VsZWN0aW9uOiByZXNvbHZlU3VibmV0U2VsZWN0aW9uKG5ldHdvcmsub3B0aW9ucykgfSxcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIGlkLFxuICAgICAgICBuZXR3b3JrLm9wdGlvbnMuc2VjdXJpdHlHcm91cElkcyxcbiAgICAgICk7XG4gICAgfVxuICAgIGNhc2UgJ3ZwY0xvb2t1cCc6IHtcbiAgICAgIGNvbnN0IHZwYyA9IFZwYy5mcm9tTG9va3VwKHNjb3BlLCBpZC5nZW5lcmF0ZSgnbmV0d29yazp2cGMnKSwge1xuICAgICAgICB0YWdzOiBuZXR3b3JrLm9wdGlvbnMudGFncyxcbiAgICAgICAgLi4uKG5ldHdvcmsub3B0aW9ucy52cGNOYW1lICYmIHsgdnBjTmFtZTogbmV0d29yay5vcHRpb25zLnZwY05hbWUgfSksXG4gICAgICAgIC4uLihuZXR3b3JrLm9wdGlvbnMucmVnaW9uICYmIHsgcmVnaW9uOiBuZXR3b3JrLm9wdGlvbnMucmVnaW9uIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB3aXRoU2VjdXJpdHlHcm91cHMoXG4gICAgICAgIHsgdnBjLCBzdWJuZXRTZWxlY3Rpb246IHJlc29sdmVTdWJuZXRTZWxlY3Rpb24obmV0d29yay5vcHRpb25zKSB9LFxuICAgICAgICBzY29wZSxcbiAgICAgICAgaWQsXG4gICAgICAgIG5ldHdvcmsub3B0aW9ucy5zZWN1cml0eUdyb3VwSWRzLFxuICAgICAgKTtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgY29uc3QgX2V4aGF1c3RpdmU6IG5ldmVyID0gbmV0d29yaztcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBuZXR3b3JrIGNvbmZpZyB0eXBlOiAkeyhfZXhoYXVzdGl2ZSBhcyBOZXR3b3JrQ29uZmlnKS50eXBlfWApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEF0dGFjaCByZXNvbHZlZCBzZWN1cml0eSBncm91cHMgdG8gYSBuZXR3b3JrIHJlc3VsdCB3aGVuIHByZXNlbnQuXG4gKi9cbmZ1bmN0aW9uIHdpdGhTZWN1cml0eUdyb3VwcyhcbiAgcmVzdWx0OiBPbWl0PFJlc29sdmVkTmV0d29yaywgJ3NlY3VyaXR5R3JvdXBzJz4sXG4gIHNjb3BlOiBDb25zdHJ1Y3QsXG4gIGlkOiBVbmlxdWVJZCxcbiAgc2VjdXJpdHlHcm91cElkcz86IHN0cmluZ1tdLFxuKTogUmVzb2x2ZWROZXR3b3JrIHtcbiAgY29uc3Qgc2VjdXJpdHlHcm91cHMgPSByZXNvbHZlU2VjdXJpdHlHcm91cHMoc2NvcGUsIGlkLCBzZWN1cml0eUdyb3VwSWRzKTtcbiAgcmV0dXJuIHNlY3VyaXR5R3JvdXBzID8geyAuLi5yZXN1bHQsIHNlY3VyaXR5R3JvdXBzIH0gOiByZXN1bHQ7XG59XG5cbi8qKlxuICogQnVpbGQgYSBTdWJuZXRTZWxlY3Rpb24gZnJvbSBvcHRpb25zIHRoYXQgY2Fycnkgc3VibmV0VHlwZSwgYXZhaWxhYmlsaXR5Wm9uZXMsXG4gKiBhbmQgc3VibmV0R3JvdXBOYW1lLiBTaGFyZWQgYnkgdnBjSWQgYW5kIHZwY0xvb2t1cCBicmFuY2hlcy5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVN1Ym5ldFNlbGVjdGlvbihcbiAgb3B0aW9uczogeyBzdWJuZXRUeXBlPzogU3VibmV0VHlwZU5hbWU7IGF2YWlsYWJpbGl0eVpvbmVzPzogc3RyaW5nW107IHN1Ym5ldEdyb3VwTmFtZT86IHN0cmluZyB9LFxuKTogU3VibmV0U2VsZWN0aW9uIHtcbiAgcmV0dXJuIHtcbiAgICBzdWJuZXRUeXBlOiBTVUJORVRfVFlQRV9NQVBbb3B0aW9ucy5zdWJuZXRUeXBlID8/IERFRkFVTFRfU1VCTkVUX1RZUEVdLFxuICAgIC4uLihvcHRpb25zLmF2YWlsYWJpbGl0eVpvbmVzICYmIHsgYXZhaWxhYmlsaXR5Wm9uZXM6IG9wdGlvbnMuYXZhaWxhYmlsaXR5Wm9uZXMgfSksXG4gICAgLi4uKG9wdGlvbnMuc3VibmV0R3JvdXBOYW1lICYmIHsgc3VibmV0R3JvdXBOYW1lOiBvcHRpb25zLnN1Ym5ldEdyb3VwTmFtZSB9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIHNlY3VyaXR5IGdyb3VwIElEcyBpbnRvIENESyBzZWN1cml0eSBncm91cCByZWZlcmVuY2VzLlxuICogUmV0dXJucyB1bmRlZmluZWQgd2hlbiBubyBJRHMgYXJlIHByb3ZpZGVkLlxuICovXG5mdW5jdGlvbiByZXNvbHZlU2VjdXJpdHlHcm91cHMoXG4gIHNjb3BlOiBDb25zdHJ1Y3QsXG4gIGlkOiBVbmlxdWVJZCxcbiAgc2VjdXJpdHlHcm91cElkcz86IHN0cmluZ1tdLFxuKTogSVNlY3VyaXR5R3JvdXBbXSB8IHVuZGVmaW5lZCB7XG4gIGlmICghc2VjdXJpdHlHcm91cElkcz8ubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4gc2VjdXJpdHlHcm91cElkcy5tYXAoXG4gICAgKHNnSWQpID0+IFNlY3VyaXR5R3JvdXAuZnJvbVNlY3VyaXR5R3JvdXBJZChzY29wZSwgaWQuZ2VuZXJhdGUoJ25ldHdvcms6c2cnKSwgc2dJZCksXG4gICk7XG59XG4iXX0=
@@ -0,0 +1,61 @@
1
+ import type { Plugin } from '@pipeline-builder/pipeline-data';
2
+ import { SecretValue } from 'aws-cdk-lib';
3
+ import { ComputeType as CDKComputeType, type IBuildImage } from 'aws-cdk-lib/aws-codebuild';
4
+ import { CodeBuildStep, ManualApprovalStep, ShellStep } from 'aws-cdk-lib/pipelines';
5
+ import type { Construct } from 'constructs';
6
+ import type { CodeBuildStepOptions } from '../pipeline/step-types.js';
7
+ /**
8
+ * Resolve the CodeBuild image to use for a plugin.
9
+ *
10
+ * Strategy:
11
+ * 1. If the plugin sets `aws:cdk:codebuild:buildenvironment:buildImage`
12
+ * explicitly in metadata, the metadata-builder passthrough handles it
13
+ * (via `metadataForBuildEnvironment`). This function returns
14
+ * `undefined` and the metadata wins.
15
+ * 2. Otherwise, if the plugin has a `name`+`version` AND the registry
16
+ * config is populated, build a `LinuxBuildImage.fromDockerRegistry()`
17
+ * image pointing at `<registry-host>:<port>/<ns>/<name>:<version>`
18
+ * where `<ns>` is `system` or `org-<orgId>`. CodeBuild authenticates by
19
+ * sending the per-org platform Secret as Basic auth to
20
+ * `pipeline-image-registry`'s `/token` endpoint; the JWT in `password`
21
+ * resolves to a registry token scoped to the org.
22
+ * 3. If `metadata_only`, return `undefined` so CodeBuild uses its default
23
+ * (`standard:7.0`).
24
+ *
25
+ * `scope` and `orgId` are required: the per-org platform Secret is named
26
+ * `pipeline-builder/<orgId>/platform`, and `Secret.fromSecretNameV2()`
27
+ * needs a Construct to anchor the imported secret to.
28
+ */
29
+ export declare function resolvePluginImage(scope: Construct | undefined, plugin: Plugin, orgId?: string): IBuildImage | undefined;
30
+ export declare function resolveDefaultBuildImage(scope?: Construct, orgId?: string): IBuildImage;
31
+ /**
32
+ * Create a CodeBuild step or Shell step based on plugin configuration.
33
+ *
34
+ * Metadata merge order (last wins):
35
+ * 1. Plugin metadata (from plugin.metadata in database) — the plugin
36
+ * author's baked-in defaults
37
+ * 2. Step-level metadata (from options.metadata) — the pipeline author's
38
+ * per-step overrides, which are more specific and must win
39
+ *
40
+ * Environment merge order (last wins):
41
+ * 1. Plugin env vars (from plugin.env)
42
+ * 2. Custom env vars (from options.env)
43
+ * 3. WORKDIR from merged metadata
44
+ *
45
+ * CDK prop spread order (last wins):
46
+ * programmatic defaults (input, commands, env, network) → metadata overrides
47
+ *
48
+ * This means metadata keys like `aws:cdk:pipelines:codebuildstep:commands`
49
+ * will override the plugin-derived commands when explicitly set.
50
+ */
51
+ export declare function createCodeBuildStep(options: CodeBuildStepOptions): ShellStep | CodeBuildStep | ManualApprovalStep;
52
+ /**
53
+ * Convert string or ComputeType enum to CDK ComputeType
54
+ */
55
+ export declare function getComputeType(input?: string | CDKComputeType): CDKComputeType;
56
+ /**
57
+ * Unwrap a SecretValue | string into a plain string.
58
+ * When a SecretValue is provided (e.g. from Secrets Manager), calls unsafeUnwrap()
59
+ * to extract the underlying value.
60
+ */
61
+ export declare function unwrapSecret(value: SecretValue | string): string;