@pipeline-builder/pipeline-core 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +32 -0
- package/lib/config/app-config.d.ts +81 -0
- package/lib/config/app-config.js +151 -0
- package/lib/config/billing-config.d.ts +17 -0
- package/lib/config/billing-config.js +95 -0
- package/lib/config/config-types.d.ts +213 -0
- package/lib/config/config-types.js +5 -0
- package/lib/config/infrastructure-config.d.ts +55 -0
- package/lib/config/infrastructure-config.js +200 -0
- package/lib/config/server-config.d.ts +53 -0
- package/lib/config/server-config.js +180 -0
- package/lib/core/artifact-manager.d.ts +62 -0
- package/lib/core/artifact-manager.js +86 -0
- package/lib/core/id-generator.d.ts +26 -0
- package/lib/core/id-generator.js +44 -0
- package/lib/core/metadata-builder.d.ts +13 -0
- package/lib/core/metadata-builder.js +81 -0
- package/lib/core/network-types.d.ts +200 -0
- package/lib/core/network-types.js +5 -0
- package/lib/core/network.d.ts +20 -0
- package/lib/core/network.js +84 -0
- package/lib/core/pipeline-helpers.d.ts +53 -0
- package/lib/core/pipeline-helpers.js +273 -0
- package/lib/core/pipeline-types.d.ts +136 -0
- package/lib/core/pipeline-types.js +140 -0
- package/lib/core/role-types.d.ts +254 -0
- package/lib/core/role-types.js +5 -0
- package/lib/core/role.d.ts +14 -0
- package/lib/core/role.js +118 -0
- package/lib/core/security-group-types.d.ts +84 -0
- package/lib/core/security-group-types.js +5 -0
- package/lib/core/security-group.d.ts +14 -0
- package/lib/core/security-group.js +34 -0
- package/lib/handlers/plugin-lookup-handler.d.ts +32 -0
- package/lib/handlers/plugin-lookup-handler.js +313 -0
- package/lib/handlers/pnpm-lock.yaml +12 -0
- package/lib/index.d.ts +54 -0
- package/lib/index.js +112 -0
- package/lib/pipeline/pipeline-builder.d.ts +82 -0
- package/lib/pipeline/pipeline-builder.js +292 -0
- package/lib/pipeline/pipeline-configuration.d.ts +72 -0
- package/lib/pipeline/pipeline-configuration.js +196 -0
- package/lib/pipeline/plugin-lookup.d.ts +100 -0
- package/lib/pipeline/plugin-lookup.js +247 -0
- package/lib/pipeline/source-builder.d.ts +47 -0
- package/lib/pipeline/source-builder.js +111 -0
- package/lib/pipeline/source-types.d.ts +191 -0
- package/lib/pipeline/source-types.js +5 -0
- package/lib/pipeline/stage-builder.d.ts +71 -0
- package/lib/pipeline/stage-builder.js +118 -0
- package/lib/pipeline/step-types.d.ts +307 -0
- package/lib/pipeline/step-types.js +5 -0
- package/package.json +137 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
+
}) : function(o, v) {
|
|
18
|
+
o["default"] = v;
|
|
19
|
+
});
|
|
20
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
21
|
+
var ownKeys = function(o) {
|
|
22
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
23
|
+
var ar = [];
|
|
24
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
25
|
+
return ar;
|
|
26
|
+
};
|
|
27
|
+
return ownKeys(o);
|
|
28
|
+
};
|
|
29
|
+
return function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.PipelineBuilder = void 0;
|
|
39
|
+
const api_core_1 = require("@pipeline-builder/api-core");
|
|
40
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
41
|
+
const cloudwatch = __importStar(require("aws-cdk-lib/aws-cloudwatch"));
|
|
42
|
+
const aws_codepipeline_1 = require("aws-cdk-lib/aws-codepipeline");
|
|
43
|
+
const events = __importStar(require("aws-cdk-lib/aws-events"));
|
|
44
|
+
const targets = __importStar(require("aws-cdk-lib/aws-events-targets"));
|
|
45
|
+
const kms = __importStar(require("aws-cdk-lib/aws-kms"));
|
|
46
|
+
const sns = __importStar(require("aws-cdk-lib/aws-sns"));
|
|
47
|
+
const pipelines_1 = require("aws-cdk-lib/pipelines");
|
|
48
|
+
const constructs_1 = require("constructs");
|
|
49
|
+
const pipeline_configuration_1 = require("./pipeline-configuration");
|
|
50
|
+
const plugin_lookup_1 = require("./plugin-lookup");
|
|
51
|
+
const source_builder_1 = require("./source-builder");
|
|
52
|
+
const stage_builder_1 = require("./stage-builder");
|
|
53
|
+
const app_config_1 = require("../config/app-config");
|
|
54
|
+
const artifact_manager_1 = require("../core/artifact-manager");
|
|
55
|
+
const id_generator_1 = require("../core/id-generator");
|
|
56
|
+
const metadata_builder_1 = require("../core/metadata-builder");
|
|
57
|
+
const network_1 = require("../core/network");
|
|
58
|
+
const pipeline_helpers_1 = require("../core/pipeline-helpers");
|
|
59
|
+
const pipeline_types_1 = require("../core/pipeline-types");
|
|
60
|
+
const role_1 = require("../core/role");
|
|
61
|
+
const security_group_1 = require("../core/security-group");
|
|
62
|
+
const PIPELINE_EVENT_MAP = {
|
|
63
|
+
FAILED: aws_codepipeline_1.PipelineNotificationEvents.PIPELINE_EXECUTION_FAILED,
|
|
64
|
+
SUCCEEDED: aws_codepipeline_1.PipelineNotificationEvents.PIPELINE_EXECUTION_SUCCEEDED,
|
|
65
|
+
STARTED: aws_codepipeline_1.PipelineNotificationEvents.PIPELINE_EXECUTION_STARTED,
|
|
66
|
+
CANCELED: aws_codepipeline_1.PipelineNotificationEvents.PIPELINE_EXECUTION_CANCELED,
|
|
67
|
+
SUPERSEDED: aws_codepipeline_1.PipelineNotificationEvents.PIPELINE_EXECUTION_SUPERSEDED,
|
|
68
|
+
};
|
|
69
|
+
function parseNotificationEvents(value) {
|
|
70
|
+
if (Array.isArray(value))
|
|
71
|
+
return value;
|
|
72
|
+
if (typeof value === 'string')
|
|
73
|
+
return value.split(',').map(s => s.trim());
|
|
74
|
+
return ['FAILED', 'SUCCEEDED'];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* CDK construct that creates and configures a CodePipeline for continuous deployment.
|
|
78
|
+
*
|
|
79
|
+
* Features:
|
|
80
|
+
* - Multi-source support (S3, GitHub, CodeStar)
|
|
81
|
+
* - Plugin-based build steps
|
|
82
|
+
* - Metadata-driven configuration
|
|
83
|
+
* - Automatic tagging
|
|
84
|
+
* - Automatic sanitization of project and organization names
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* new PipelineBuilder(this, 'MyPipeline', {
|
|
89
|
+
* project: 'my-app',
|
|
90
|
+
* organization: 'my-org',
|
|
91
|
+
* synth: {
|
|
92
|
+
* source: {
|
|
93
|
+
* type: 'github',
|
|
94
|
+
* options: { repo: 'owner/repo', branch: 'main' }
|
|
95
|
+
* },
|
|
96
|
+
* plugin: { name: 'synth' }
|
|
97
|
+
* }
|
|
98
|
+
* });
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
class PipelineBuilder extends constructs_1.Construct {
|
|
102
|
+
pipeline;
|
|
103
|
+
config;
|
|
104
|
+
constructor(scope, id, props) {
|
|
105
|
+
super(scope, id);
|
|
106
|
+
// Use PipelineConfiguration for all business logic (validation, sanitization, metadata merging)
|
|
107
|
+
this.config = new pipeline_configuration_1.PipelineConfiguration(props);
|
|
108
|
+
const serverConfig = app_config_1.Config.get('server');
|
|
109
|
+
const awsConfig = app_config_1.Config.get('aws');
|
|
110
|
+
const uniqueId = new id_generator_1.UniqueId();
|
|
111
|
+
const pluginLookup = new plugin_lookup_1.PluginLookup(this, uniqueId.generate('plugin:lookup'), {
|
|
112
|
+
organization: this.config.organization,
|
|
113
|
+
project: this.config.project,
|
|
114
|
+
platformUrl: serverConfig.platformUrl,
|
|
115
|
+
uniqueId,
|
|
116
|
+
orgId: props.orgId,
|
|
117
|
+
runtime: awsConfig.lambda.runtime,
|
|
118
|
+
timeout: awsConfig.lambda.timeout,
|
|
119
|
+
reservedConcurrentExecutions: awsConfig.lambda.reservedConcurrentExecutions,
|
|
120
|
+
});
|
|
121
|
+
// Create source and build step
|
|
122
|
+
const sourceBuilder = new source_builder_1.SourceBuilder(this, this.config);
|
|
123
|
+
const source = sourceBuilder.create(uniqueId);
|
|
124
|
+
// RESOLVED_SYNTH_PLUGIN=true (CodePipeline): resolve plugin via custom resource Lambda
|
|
125
|
+
// RESOLVED_SYNTH_PLUGIN=false (default/CLI): use fallback with pipeline-manager synth commands
|
|
126
|
+
const plugin = awsConfig.resolvedSynthPlugin
|
|
127
|
+
? pluginLookup.plugin(this.config.plugin)
|
|
128
|
+
: pluginLookup.fallbackSynth();
|
|
129
|
+
const defaultComputeType = awsConfig.codeBuild.computeType;
|
|
130
|
+
const artifactManager = new artifact_manager_1.ArtifactManager();
|
|
131
|
+
const synthAlias = this.config.plugin.alias ?? this.config.plugin.name;
|
|
132
|
+
const synth = (0, pipeline_helpers_1.createCodeBuildStep)({
|
|
133
|
+
...this.config.synthCustomization,
|
|
134
|
+
id: uniqueId.generate('cdk:synth'),
|
|
135
|
+
uniqueId,
|
|
136
|
+
plugin,
|
|
137
|
+
input: source,
|
|
138
|
+
metadata: this.config.metadata.merged,
|
|
139
|
+
network: this.config.network,
|
|
140
|
+
scope: this,
|
|
141
|
+
defaultComputeType,
|
|
142
|
+
artifactManager,
|
|
143
|
+
stageName: 'no-stage',
|
|
144
|
+
stageAlias: 'no-stage-alias',
|
|
145
|
+
pluginAlias: `${synthAlias}-alias`,
|
|
146
|
+
orgId: props.orgId,
|
|
147
|
+
});
|
|
148
|
+
// Resolve pipeline-level defaults into codeBuildDefaults
|
|
149
|
+
// Build the per-org platform secret name for CodeBuild env vars
|
|
150
|
+
const platformSecretName = props.orgId
|
|
151
|
+
? app_config_1.CoreConstants.secretPath(props.orgId, 'platform')
|
|
152
|
+
: undefined;
|
|
153
|
+
const codeBuildDefaults = this.resolveDefaults(this.config.defaults, uniqueId, props.pipelineId, platformSecretName, serverConfig.platformUrl);
|
|
154
|
+
// Resolve IAM role if explicitly provided; otherwise let CDK auto-create
|
|
155
|
+
// the pipeline role with the correct codepipeline.amazonaws.com principal.
|
|
156
|
+
if (props.role?.type === 'codeBuildDefault') {
|
|
157
|
+
(0, api_core_1.createLogger)('PipelineBuilder').warn('codeBuildDefault role type uses codebuild.amazonaws.com trust principal — ' +
|
|
158
|
+
'this is not suitable as the pipeline-level role. Consider using roleArn/roleName ' +
|
|
159
|
+
'or omitting the role to let CDK auto-create one with codepipeline.amazonaws.com.');
|
|
160
|
+
}
|
|
161
|
+
const role = props.role
|
|
162
|
+
? (0, role_1.resolveRole)(this, uniqueId, props.role)
|
|
163
|
+
: undefined;
|
|
164
|
+
// Create CodePipeline construct
|
|
165
|
+
this.pipeline = new pipelines_1.CodePipeline(this, uniqueId.generate('pipelines:codepipeline'), {
|
|
166
|
+
...(codeBuildDefaults && { codeBuildDefaults }),
|
|
167
|
+
...(role && { role }),
|
|
168
|
+
pipelineType: aws_codepipeline_1.PipelineType.V2,
|
|
169
|
+
pipelineName: this.config.pipelineName,
|
|
170
|
+
synth,
|
|
171
|
+
...(0, metadata_builder_1.metadataForCodePipeline)(this.config.metadata.merged),
|
|
172
|
+
});
|
|
173
|
+
// Add stages as waves via StageBuilder
|
|
174
|
+
if (props.stages) {
|
|
175
|
+
const stageBuilder = new stage_builder_1.StageBuilder({
|
|
176
|
+
scope: this,
|
|
177
|
+
pluginLookup,
|
|
178
|
+
uniqueId,
|
|
179
|
+
globalMetadata: this.config.metadata.merged,
|
|
180
|
+
defaultComputeType,
|
|
181
|
+
artifactManager,
|
|
182
|
+
orgId: props.orgId,
|
|
183
|
+
});
|
|
184
|
+
stageBuilder.addStages(this.pipeline, props.stages);
|
|
185
|
+
}
|
|
186
|
+
// ── Tags ──
|
|
187
|
+
aws_cdk_lib_1.Tags.of(this.pipeline).add('project', this.config.project);
|
|
188
|
+
aws_cdk_lib_1.Tags.of(this.pipeline).add('organization', this.config.organization);
|
|
189
|
+
if (props.tags) {
|
|
190
|
+
for (const [key, value] of Object.entries(props.tags)) {
|
|
191
|
+
aws_cdk_lib_1.Tags.of(this.pipeline).add(key, value);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Build the internal pipeline before accessing its properties
|
|
195
|
+
this.pipeline.buildPipeline();
|
|
196
|
+
const cdkPipeline = this.pipeline.pipeline;
|
|
197
|
+
const meta = this.config.metadata.merged;
|
|
198
|
+
// ── SNS Notifications ──
|
|
199
|
+
const notificationTopicArn = meta[pipeline_types_1.MetadataKeys.NOTIFICATION_TOPIC_ARN];
|
|
200
|
+
if (typeof notificationTopicArn === 'string') {
|
|
201
|
+
const topic = sns.Topic.fromTopicArn(this, 'NotificationTopic', notificationTopicArn);
|
|
202
|
+
const notificationEvents = parseNotificationEvents(meta[pipeline_types_1.MetadataKeys.NOTIFICATION_EVENTS])
|
|
203
|
+
.map(e => PIPELINE_EVENT_MAP[e.toUpperCase()])
|
|
204
|
+
.filter(Boolean);
|
|
205
|
+
if (notificationEvents.length > 0) {
|
|
206
|
+
cdkPipeline.notifyOn('PipelineNotification', topic, { events: notificationEvents });
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// ── Scheduled Execution ──
|
|
210
|
+
if (props.synth.source.options?.trigger === pipeline_types_1.TriggerType.SCHEDULE || props.schedule) {
|
|
211
|
+
const expr = props.schedule || props.synth.source.options?.schedule || 'rate(1 day)';
|
|
212
|
+
new events.Rule(this, 'ScheduleRule', {
|
|
213
|
+
schedule: events.Schedule.expression(expr),
|
|
214
|
+
targets: [new targets.CodePipeline(cdkPipeline)],
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
// ── Execution Event Tracking (forward pipeline state changes to SNS) ──
|
|
218
|
+
if (meta[pipeline_types_1.MetadataKeys.ENABLE_EXECUTION_EVENTS] && typeof notificationTopicArn === 'string') {
|
|
219
|
+
new events.Rule(this, 'ExecutionEventRule', {
|
|
220
|
+
eventPattern: {
|
|
221
|
+
source: ['aws.codepipeline'],
|
|
222
|
+
detailType: ['CodePipeline Pipeline Execution State Change'],
|
|
223
|
+
resources: [cdkPipeline.pipelineArn],
|
|
224
|
+
},
|
|
225
|
+
targets: [new targets.SnsTopic(sns.Topic.fromTopicArn(this, 'ExecutionEventTopic', notificationTopicArn))],
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
// ── Artifact Encryption (KMS key) ──
|
|
229
|
+
const kmsKeyArn = this.config.metadata.merged[pipeline_types_1.MetadataKeys.KMS_KEY_ARN];
|
|
230
|
+
if (typeof kmsKeyArn === 'string') {
|
|
231
|
+
const key = kms.Key.fromKeyArn(this, 'ArtifactKey', kmsKeyArn);
|
|
232
|
+
aws_cdk_lib_1.Tags.of(key).add('pipeline', this.config.pipelineName);
|
|
233
|
+
}
|
|
234
|
+
// ── Pipeline Metrics & Alarms ──
|
|
235
|
+
const enableMetrics = this.config.metadata.merged[pipeline_types_1.MetadataKeys.ENABLE_METRICS];
|
|
236
|
+
if (enableMetrics) {
|
|
237
|
+
new cloudwatch.Alarm(this, 'PipelineFailureAlarm', {
|
|
238
|
+
metric: new cloudwatch.Metric({
|
|
239
|
+
namespace: 'AWS/CodePipeline',
|
|
240
|
+
metricName: 'FailedPipelineExecutionCount',
|
|
241
|
+
dimensionsMap: { PipelineName: this.config.pipelineName },
|
|
242
|
+
statistic: 'Sum',
|
|
243
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
244
|
+
}),
|
|
245
|
+
threshold: 1,
|
|
246
|
+
evaluationPeriods: 1,
|
|
247
|
+
alarmDescription: `Pipeline ${this.config.pipelineName} execution failed`,
|
|
248
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
|
249
|
+
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Resolves CodeBuildDefaults into the shape expected by CDK's codeBuildDefaults.
|
|
255
|
+
* Combines network config, security groups, and pipeline-level environment variables
|
|
256
|
+
* (PIPELINE_ID, EXECUTION_ID, PLATFORM_BASE_URL) available to all CodeBuild actions.
|
|
257
|
+
*/
|
|
258
|
+
resolveDefaults(defaults, id, pipelineId, platformSecretName, platformUrl) {
|
|
259
|
+
const networkProps = defaults?.network
|
|
260
|
+
? (0, network_1.resolveNetwork)(this, id, defaults.network)
|
|
261
|
+
: undefined;
|
|
262
|
+
const standaloneSecurityGroups = defaults?.securityGroups
|
|
263
|
+
? (0, security_group_1.resolveSecurityGroup)(this, id, defaults.securityGroups)
|
|
264
|
+
: undefined;
|
|
265
|
+
// Pipeline-level env vars available to all CodeBuild actions
|
|
266
|
+
// Note: #{codepipeline.*} resolved variables must go through CodeBuildStep.env
|
|
267
|
+
// (action-level), not buildEnvironment.environmentVariables (project-level).
|
|
268
|
+
const pipelineEnvVars = {
|
|
269
|
+
PLATFORM_BASE_URL: { value: platformUrl },
|
|
270
|
+
...(pipelineId && { PIPELINE_ID: { value: pipelineId } }),
|
|
271
|
+
...(platformSecretName && { PLATFORM_SECRET_NAME: { value: platformSecretName } }),
|
|
272
|
+
// Enable plugin resolution via custom resource Lambda inside CodePipeline
|
|
273
|
+
RESOLVED_SYNTH_PLUGIN: { value: 'true' },
|
|
274
|
+
// Propagate TLS verification setting so all CodeBuild steps can reach
|
|
275
|
+
// the platform API when using self-signed certificates
|
|
276
|
+
...(process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0' && {
|
|
277
|
+
NODE_TLS_REJECT_UNAUTHORIZED: { value: '0' },
|
|
278
|
+
}),
|
|
279
|
+
};
|
|
280
|
+
const securityGroups = [
|
|
281
|
+
...(networkProps?.securityGroups ?? []),
|
|
282
|
+
...(standaloneSecurityGroups ?? []),
|
|
283
|
+
];
|
|
284
|
+
return {
|
|
285
|
+
...(networkProps && { vpc: networkProps.vpc, subnetSelection: networkProps.subnetSelection }),
|
|
286
|
+
...(securityGroups.length > 0 && { securityGroups }),
|
|
287
|
+
buildEnvironment: { environmentVariables: pipelineEnvVars },
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.PipelineBuilder = PipelineBuilder;
|
|
292
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGlwZWxpbmUtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9waXBlbGluZS9waXBlbGluZS1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFdEMseURBQTBEO0FBQzFELDZDQUE2QztBQUM3Qyx1RUFBeUQ7QUFDekQsbUVBQXdGO0FBQ3hGLCtEQUFpRDtBQUNqRCx3RUFBMEQ7QUFDMUQseURBQTJDO0FBQzNDLHlEQUEyQztBQUMzQyxxREFBNEU7QUFDNUUsMkNBQXVDO0FBQ3ZDLHFFQUFpRTtBQUNqRSxtREFBK0M7QUFDL0MscURBQWlEO0FBQ2pELG1EQUErQztBQUUvQyxxREFBNkQ7QUFDN0QsK0RBQTJEO0FBQzNELHVEQUFnRDtBQUNoRCwrREFBbUU7QUFDbkUsNkNBQWlEO0FBRWpELCtEQUErRDtBQUMvRCwyREFBbUU7QUFFbkUsdUNBQTJDO0FBRTNDLDJEQUE4RDtBQUU5RCxNQUFNLGtCQUFrQixHQUErQztJQUNyRSxNQUFNLEVBQUUsNkNBQTBCLENBQUMseUJBQXlCO0lBQzVELFNBQVMsRUFBRSw2Q0FBMEIsQ0FBQyw0QkFBNEI7SUFDbEUsT0FBTyxFQUFFLDZDQUEwQixDQUFDLDBCQUEwQjtJQUM5RCxRQUFRLEVBQUUsNkNBQTBCLENBQUMsMkJBQTJCO0lBQ2hFLFVBQVUsRUFBRSw2Q0FBMEIsQ0FBQyw2QkFBNkI7Q0FDckUsQ0FBQztBQUVGLFNBQVMsdUJBQXVCLENBQUMsS0FBYztJQUM3QyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDdkMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENB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WUFDcEQsZ0JBQWdCLEVBQUUsRUFBRSxvQkFBb0IsRUFBRSxlQUFlLEVBQUU7U0FDNUQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWpPRCwwQ0FpT0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgRHVyYXRpb24sIFRhZ3MgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBjbG91ZHdhdGNoIGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCB7IFBpcGVsaW5lTm90aWZpY2F0aW9uRXZlbnRzLCBQaXBlbGluZVR5cGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY29kZXBpcGVsaW5lJztcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZXZlbnRzJztcbmltcG9ydCAqIGFzIHRhcmdldHMgZnJvbSAnYXdzLWNkay1saWIvYXdzLWV2ZW50cy10YXJnZXRzJztcbmltcG9ydCAqIGFzIGttcyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mta21zJztcbmltcG9ydCAqIGFzIHNucyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc25zJztcbmltcG9ydCB7IENvZGVQaXBlbGluZSwgdHlwZSBDb2RlQnVpbGRPcHRpb25zIH0gZnJvbSAnYXdzLWNkay1saWIvcGlwZWxpbmVzJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgUGlwZWxpbmVDb25maWd1cmF0aW9uIH0gZnJvbSAnLi9waXBlbGluZS1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFBsdWdpbkxvb2t1cCB9IGZyb20gJy4vcGx1Z2luLWxvb2t1cCc7XG5pbXBvcnQgeyBTb3VyY2VCdWlsZGVyIH0gZnJvbSAnLi9zb3VyY2UtYnVpbGRlcic7XG5pbXBvcnQgeyBTdGFnZUJ1aWxkZXIgfSBmcm9tICcuL3N0YWdlLWJ1aWxkZXInO1xuaW1wb3J0IHR5cGUgeyBTdGFnZU9wdGlvbnMsIFN5bnRoT3B0aW9ucyB9IGZyb20gJy4vc3RlcC10eXBlcyc7XG5pbXBvcnQgeyBDb25maWcsIENvcmVDb25zdGFudHMgfSBmcm9tICcuLi9jb25maWcvYXBwLWNvbmZpZyc7XG5pbXBvcnQgeyBBcnRpZmFjdE1hbmFnZXIgfSBmcm9tICcuLi9jb3JlL2FydGlmYWN0LW1hbmFnZXInO1xuaW1wb3J0IHsgVW5pcXVlSWQgfSBmcm9tICcuLi9jb3JlL2lkLWdlbmVyYXRvcic7XG5pbXBvcnQgeyBtZXRhZGF0YUZvckNvZGVQaXBlbGluZSB9IGZyb20gJy4uL2NvcmUvbWV0YWRhdGEtYnVpbGRlcic7XG5pbXBvcnQgeyByZXNvbHZlTmV0d29yayB9IGZyb20gJy4uL2NvcmUvbmV0d29yayc7XG5pbXBvcnQgdHlwZSB7IENvZGVCdWlsZERlZmF1bHRzIH0gZnJvbSAnLi4vY29yZS9uZXR3b3JrLXR5cGVzJztcbmltcG9ydCB7IGNyZWF0ZUNvZGVCdWlsZFN0ZXAgfSBmcm9tICcuLi9jb3JlL3BpcGVsaW5lLWhlbHBlcnMnO1xuaW1wb3J0IHsgTWV0YWRhdGFLZXlzLCBUcmlnZ2VyVHlwZSB9IGZyb20gJy4uL2NvcmUvcGlwZWxpbmUtdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBNZXRhRGF0YVR5cGUgfSBmcm9tICcuLi9jb3JlL3BpcGVsaW5lLXR5cGVzJztcbmltcG9ydCB7IHJlc29sdmVSb2xlIH0gZnJvbSAnLi4vY29yZS9yb2xlJztcbmltcG9ydCB0eXBlIHsgUm9sZUNvbmZpZyB9IGZyb20gJy4uL2NvcmUvcm9sZS10eXBlcyc7XG5pbXBvcnQgeyByZXNvbHZlU2VjdXJpdHlHcm91cCB9IGZyb20gJy4uL2NvcmUvc2VjdXJpdHktZ3JvdXAnO1xuXG5jb25zdCBQSVBFTElORV9FVkVOVF9NQVA6IFJlY29yZDxzdHJpbmcsIFBpcGVsaW5lTm90aWZpY2F0aW9uRXZlbnRzPiA9IHtcbiAgRkFJTEVEOiBQaXBlbGluZU5vdGlmaWNhdGlvbkV2ZW50cy5QSVBFTElORV9FWEVDVVRJT05fRkFJTEVELFxuICBTVUNDRUVERUQ6IFBpcGVsaW5lTm90aWZpY2F0aW9uRXZlbnRzLlBJUEVMSU5FX0VYRUNVVElPTl9TVUNDRUVERUQsXG4gIFNUQVJURUQ6IFBpcGVsaW5lTm90aWZpY2F0aW9uRXZlbnRzLlBJUEVMSU5FX0VYRUNVVElPTl9TVEFSVEVELFxuICBDQU5DRUxFRDogUGlwZWxpbmVOb3RpZmljYXRpb25FdmVudHMuUElQRUxJTkVfRVhFQ1VUSU9OX0NBTkNFTEVELFxuICBTVVBFUlNFREVEOiBQaXBlbGluZU5vdGlmaWNhdGlvbkV2ZW50cy5QSVBFTElORV9FWEVDVVRJT05fU1VQRVJTRURFRCxcbn07XG5cbmZ1bmN0aW9uIHBhcnNlTm90aWZpY2F0aW9uRXZlbnRzKHZhbHVlOiB1bmtub3duKTogc3RyaW5nW10ge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiB2YWx1ZS5zcGxpdCgnLCcpLm1hcChzID0+IHMudHJpbSgpKTtcbiAgcmV0dXJuIFsnRkFJTEVEJywgJ1NVQ0NFRURFRCddO1xufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gcHJvcGVydGllcyBmb3IgdGhlIFBpcGVsaW5lQnVpbGRlciBjb25zdHJ1Y3RcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCdWlsZGVyUHJvcHMge1xuICAvKiogUHJvamVjdCBpZGVudGlmaWVyICh3aWxsIGJlIHNhbml0aXplZCB0byBsb3dlcmNhc2UgYWxwaGFudW1lcmljIHdpdGggdW5kZXJzY29yZXMpICovXG4gIHJlYWRvbmx5IHByb2plY3Q6IHN0cmluZztcblxuICAvKiogT3JnYW5pemF0aW9uIGlkZW50aWZpZXIgKHdpbGwgYmUgc2FuaXRpemVkIHRvIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgd2l0aCB1bmRlcnNjb3JlcykgKi9cbiAgcmVhZG9ubHkgb3JnYW5pemF0aW9uOiBzdHJpbmc7XG5cbiAgLyoqIFRlbmFudCBpZGVudGlmaWVyIGZvciByZXNvbHZpbmcgcGVyLW9yZyBzZWNyZXRzIGZyb20gQVdTIFNlY3JldHMgTWFuYWdlciAqL1xuICByZWFkb25seSBvcmdJZD86IHN0cmluZztcblxuICAvKiogUGlwZWxpbmUgZGF0YWJhc2UgcmVjb3JkIElEIOKAlCBpbmplY3RlZCBhcyBQSVBFTElORV9JRCBlbnYgdmFyIGZvciBhdXRvbm9tb3VzIHN5bnRoICovXG4gIHJlYWRvbmx5IHBpcGVsaW5lSWQ/OiBzdHJpbmc7XG5cbiAgLyoqIE9wdGlvbmFsIGN1c3RvbSBwaXBlbGluZSBuYW1lLiBEZWZhdWx0cyB0bzoge29yZ2FuaXphdGlvbn0te3Byb2plY3R9LXBpcGVsaW5lICovXG4gIHJlYWRvbmx5IHBpcGVsaW5lTmFtZT86IHN0cmluZztcblxuICAvKiogR2xvYmFsIG1ldGFkYXRhIGluaGVyaXRlZCBieSBhbGwgcGlwZWxpbmUgc3RlcHMgKi9cbiAgcmVhZG9ubHkgZ2xvYmFsPzogTWV0YURhdGFUeXBlO1xuXG4gIC8qKlxuICAgKiBQaXBlbGluZS1sZXZlbCBDb2RlQnVpbGQgZGVmYXVsdHMgYXBwbGllZCB0byBhbGwgQ29kZUJ1aWxkIGFjdGlvbnNcbiAgICogKHN5bnRoLCBzZWxmLW11dGF0aW9uLCBhc3NldCBwdWJsaXNoaW5nKSB2aWEgYGNvZGVCdWlsZERlZmF1bHRzYC5cbiAgICovXG4gIHJlYWRvbmx5IGRlZmF1bHRzPzogQ29kZUJ1aWxkRGVmYXVsdHM7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIElBTSByb2xlIGZvciB0aGUgQ29kZVBpcGVsaW5lLlxuICAgKiBXaGVuIHByb3ZpZGVkLCByZXNvbHZlcyB0byBhIENESyBJUm9sZSBhbmQgaXMgcGFzc2VkIHRvIHRoZSBDb2RlUGlwZWxpbmUgY29uc3RydWN0LlxuICAgKiBXaGVuIG9taXR0ZWQsIENESyBhdXRvLWNyZWF0ZXMgYSByb2xlIHdpdGggdGhlIGNvcnJlY3QgY29kZXBpcGVsaW5lLmFtYXpvbmF3cy5jb20gcHJpbmNpcGFsLlxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZT86IFJvbGVDb25maWc7XG5cbiAgLyoqIFN5bnRoZXNpcyBjb25maWd1cmF0aW9uIGluY2x1ZGluZyBzb3VyY2UgYW5kIHBsdWdpbiBkZXRhaWxzICovXG4gIHJlYWRvbmx5IHN5bnRoOiBTeW50aE9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIHBpcGVsaW5lIHN0YWdlcywgZWFjaCBjb250YWluaW5nIG9uZSBvciBtb3JlIENvZGVCdWlsZCBzdGVwcy5cbiAgICogU3RhZ2VzIGFyZSBhZGRlZCBhcyB3YXZlcyB0byB0aGUgQ29kZVBpcGVsaW5lIGFmdGVyIHRoZSBzeW50aCBzdGVwLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhZ2VzPzogU3RhZ2VPcHRpb25zW107XG5cbiAgLyoqIE9wdGlvbmFsIGNyb24vcmF0ZSBleHByZXNzaW9uIGZvciBzY2hlZHVsZWQgcGlwZWxpbmUgZXhlY3V0aW9uLiAqL1xuICByZWFkb25seSBzY2hlZHVsZT86IHN0cmluZztcblxuICAvKiogQ3VzdG9tIHRhZ3MgYXBwbGllZCB0byBhbGwgcGlwZWxpbmUgcmVzb3VyY2VzLiAqL1xuICByZWFkb25seSB0YWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuLyoqXG4gKiBDREsgY29uc3RydWN0IHRoYXQgY3JlYXRlcyBhbmQgY29uZmlndXJlcyBhIENvZGVQaXBlbGluZSBmb3IgY29udGludW91cyBkZXBsb3ltZW50LlxuICpcbiAqIEZlYXR1cmVzOlxuICogLSBNdWx0aS1zb3VyY2Ugc3VwcG9ydCAoUzMsIEdpdEh1YiwgQ29kZVN0YXIpXG4gKiAtIFBsdWdpbi1iYXNlZCBidWlsZCBzdGVwc1xuICogLSBNZXRhZGF0YS1kcml2ZW4gY29uZmlndXJhdGlvblxuICogLSBBdXRvbWF0aWMgdGFnZ2luZ1xuICogLSBBdXRvbWF0aWMgc2FuaXRpemF0aW9uIG9mIHByb2plY3QgYW5kIG9yZ2FuaXphdGlvbiBuYW1lc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBuZXcgUGlwZWxpbmVCdWlsZGVyKHRoaXMsICdNeVBpcGVsaW5lJywge1xuICogICBwcm9qZWN0OiAnbXktYXBwJyxcbiAqICAgb3JnYW5pemF0aW9uOiAnbXktb3JnJyxcbiAqICAgc3ludGg6IHtcbiAqICAgICBzb3VyY2U6IHtcbiAqICAgICAgIHR5cGU6ICdnaXRodWInLFxuICogICAgICAgb3B0aW9uczogeyByZXBvOiAnb3duZXIvcmVwbycsIGJyYW5jaDogJ21haW4nIH1cbiAqICAgICB9LFxuICogICAgIHBsdWdpbjogeyBuYW1lOiAnc3ludGgnIH1cbiAqICAgfVxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFBpcGVsaW5lQnVpbGRlciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBwaXBlbGluZTogQ29kZVBpcGVsaW5lO1xuICBwdWJsaWMgcmVhZG9ubHkgY29uZmlnOiBQaXBlbGluZUNvbmZpZ3VyYXRpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEJ1aWxkZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICAvLyBVc2UgUGlwZWxpbmVDb25maWd1cmF0aW9uIGZvciBhbGwgYnVzaW5lc3MgbG9naWMgKHZhbGlkYXRpb24sIHNhbml0aXphdGlvbiwgbWV0YWRhdGEgbWVyZ2luZylcbiAgICB0aGlzLmNvbmZpZyA9IG5ldyBQaXBlbGluZUNvbmZpZ3VyYXRpb24ocHJvcHMpO1xuXG4gICAgY29uc3Qgc2VydmVyQ29uZmlnID0gQ29uZmlnLmdldCgnc2VydmVyJyk7XG4gICAgY29uc3QgYXdzQ29uZmlnID0gQ29uZmlnLmdldCgnYXdzJyk7XG4gICAgY29uc3QgdW5pcXVlSWQgPSBuZXcgVW5pcXVlSWQoKTtcbiAgICBjb25zdCBwbHVnaW5Mb29rdXAgPSBuZXcgUGx1Z2luTG9va3VwKFxuICAgICAgdGhpcyxcbiAgICAgIHVuaXF1ZUlkLmdlbmVyYXRlKCdwbHVnaW46bG9va3VwJyksXG4gICAgICB7XG4gICAgICAgIG9yZ2FuaXphdGlvbjogdGhpcy5jb25maWcub3JnYW5pemF0aW9uLFxuICAgICAgICBwcm9qZWN0OiB0aGlzLmNvbmZpZy5wcm9qZWN0LFxuICAgICAgICBwbGF0Zm9ybVVybDogc2VydmVyQ29uZmlnLnBsYXRmb3JtVXJsLFxuICAgICAgICB1bmlxdWVJZCxcbiAgICAgICAgb3JnSWQ6IHByb3BzLm9yZ0lkLFxuICAgICAgICBydW50aW1lOiBhd3NDb25maWcubGFtYmRhLnJ1bnRpbWUsXG4gICAgICAgIHRpbWVvdXQ6IGF3c0NvbmZpZy5sYW1iZGEudGltZW91dCxcbiAgICAgICAgcmVzZXJ2ZWRDb25jdXJyZW50RXhlY3V0aW9uczogYXdzQ29uZmlnLmxhbWJkYS5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zLFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gQ3JlYXRlIHNvdXJjZSBhbmQgYnVpbGQgc3RlcFxuICAgIGNvbnN0IHNvdXJjZUJ1aWxkZXIgPSBuZXcgU291cmNlQnVpbGRlcih0aGlzLCB0aGlzLmNvbmZpZyk7XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlQnVpbGRlci5jcmVhdGUodW5pcXVlSWQpO1xuXG4gICAgLy8gUkVTT0xWRURfU1lOVEhfUExVR0lOPXRydWUgKENvZGVQaXBlbGluZSk6IHJlc29sdmUgcGx1Z2luIHZpYSBjdXN0b20gcmVzb3VyY2UgTGFtYmRhXG4gICAgLy8gUkVTT0xWRURfU1lOVEhfUExVR0lOPWZhbHNlIChkZWZhdWx0L0NMSSk6IHVzZSBmYWxsYmFjayB3aXRoIHBpcGVsaW5lLW1hbmFnZXIgc3ludGggY29tbWFuZHNcbiAgICBjb25zdCBwbHVnaW4gPSBhd3NDb25maWcucmVzb2x2ZWRTeW50aFBsdWdpblxuICAgICAgPyBwbHVnaW5Mb29rdXAucGx1Z2luKHRoaXMuY29uZmlnLnBsdWdpbilcbiAgICAgIDogcGx1Z2luTG9va3VwLmZhbGxiYWNrU3ludGgoKTtcbiAgICBjb25zdCBkZWZhdWx0Q29tcHV0ZVR5cGUgPSBhd3NDb25maWcuY29kZUJ1aWxkLmNvbXB1dGVUeXBlO1xuICAgIGNvbnN0IGFydGlmYWN0TWFuYWdlciA9IG5ldyBBcnRpZmFjdE1hbmFnZXIoKTtcbiAgICBjb25zdCBzeW50aEFsaWFzID0gdGhpcy5jb25maWcucGx1Z2luLmFsaWFzID8/IHRoaXMuY29uZmlnLnBsdWdpbi5uYW1lO1xuICAgIGNvbnN0IHN5bnRoID0gY3JlYXRlQ29kZUJ1aWxkU3RlcCh7XG4gICAgICAuLi50aGlzLmNvbmZpZy5zeW50aEN1c3RvbWl6YXRpb24sXG4gICAgICBpZDogdW5pcXVlSWQuZ2VuZXJhdGUoJ2NkazpzeW50aCcpLFxuICAgICAgdW5pcXVlSWQsXG4gICAgICBwbHVnaW4sXG4gICAgICBpbnB1dDogc291cmNlLFxuICAgICAgbWV0YWRhdGE6IHRoaXMuY29uZmlnLm1ldGFkYXRhLm1lcmdlZCxcbiAgICAgIG5ldHdvcms6IHRoaXMuY29uZmlnLm5ldHdvcmssXG4gICAgICBzY29wZTogdGhpcyxcbiAgICAgIGRlZmF1bHRDb21wdXRlVHlwZSxcbiAgICAgIGFydGlmYWN0TWFuYWdlcixcbiAgICAgIHN0YWdlTmFtZTogJ25vLXN0YWdlJyxcbiAgICAgIHN0YWdlQWxpYXM6ICduby1zdGFnZS1hbGlhcycsXG4gICAgICBwbHVnaW5BbGlhczogYCR7c3ludGhBbGlhc30tYWxpYXNgLFxuICAgICAgb3JnSWQ6IHByb3BzLm9yZ0lkLFxuICAgIH0pO1xuXG4gICAgLy8gUmVzb2x2ZSBwaXBlbGluZS1sZXZlbCBkZWZhdWx0cyBpbnRvIGNvZGVCdWlsZERlZmF1bHRzXG4gICAgLy8gQnVpbGQgdGhlIHBlci1vcmcgcGxhdGZvcm0gc2VjcmV0IG5hbWUgZm9yIENvZGVCdWlsZCBlbnYgdmFyc1xuICAgIGNvbnN0IHBsYXRmb3JtU2VjcmV0TmFtZSA9IHByb3BzLm9yZ0lkXG4gICAgICA/IENvcmVDb25zdGFudHMuc2VjcmV0UGF0aChwcm9wcy5vcmdJZCwgJ3BsYXRmb3JtJylcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgY29kZUJ1aWxkRGVmYXVsdHMgPSB0aGlzLnJlc29sdmVEZWZhdWx0cyh0aGlzLmNvbmZpZy5kZWZhdWx0cywgdW5pcXVlSWQsIHByb3BzLnBpcGVsaW5lSWQsIHBsYXRmb3JtU2VjcmV0TmFtZSwgc2VydmVyQ29uZmlnLnBsYXRmb3JtVXJsKTtcblxuICAgIC8vIFJlc29sdmUgSUFNIHJvbGUgaWYgZXhwbGljaXRseSBwcm92aWRlZDsgb3RoZXJ3aXNlIGxldCBDREsgYXV0by1jcmVhdGVcbiAgICAvLyB0aGUgcGlwZWxpbmUgcm9sZSB3aXRoIHRoZSBjb3JyZWN0IGNvZGVwaXBlbGluZS5hbWF6b25hd3MuY29tIHByaW5jaXBhbC5cbiAgICBpZiAocHJvcHMucm9sZT8udHlwZSA9PT0gJ2NvZGVCdWlsZERlZmF1bHQnKSB7XG4gICAgICBjcmVhdGVMb2dnZXIoJ1BpcGVsaW5lQnVpbGRlcicpLndhcm4oXG4gICAgICAgICdjb2RlQnVpbGREZWZhdWx0IHJvbGUgdHlwZSB1c2VzIGNvZGVidWlsZC5hbWF6b25hd3MuY29tIHRydXN0IHByaW5jaXBhbCDigJQgJyArXG4gICAgICAgICd0aGlzIGlzIG5vdCBzdWl0YWJsZSBhcyB0aGUgcGlwZWxpbmUtbGV2ZWwgcm9sZS4gQ29uc2lkZXIgdXNpbmcgcm9sZUFybi9yb2xlTmFtZSAnICtcbiAgICAgICAgJ29yIG9taXR0aW5nIHRoZSByb2xlIHRvIGxldCBDREsgYXV0by1jcmVhdGUgb25lIHdpdGggY29kZXBpcGVsaW5lLmFtYXpvbmF3cy5jb20uJyxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHJvbGUgPSBwcm9wcy5yb2xlXG4gICAgICA/IHJlc29sdmVSb2xlKHRoaXMsIHVuaXF1ZUlkLCBwcm9wcy5yb2xlKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBDcmVhdGUgQ29kZVBpcGVsaW5lIGNvbnN0cnVjdFxuICAgIHRoaXMucGlwZWxpbmUgPSBuZXcgQ29kZVBpcGVsaW5lKHRoaXMsIHVuaXF1ZUlkLmdlbmVyYXRlKCdwaXBlbGluZXM6Y29kZXBpcGVsaW5lJyksIHtcbiAgICAgIC4uLihjb2RlQnVpbGREZWZhdWx0cyAmJiB7IGNvZGVCdWlsZERlZmF1bHRzIH0pLFxuICAgICAgLi4uKHJvbGUgJiYgeyByb2xlIH0pLFxuICAgICAgcGlwZWxpbmVUeXBlOiBQaXBlbGluZVR5cGUuVjIsXG4gICAgICBwaXBlbGluZU5hbWU6IHRoaXMuY29uZmlnLnBpcGVsaW5lTmFtZSxcbiAgICAgIHN5bnRoLFxuICAgICAgLi4ubWV0YWRhdGFGb3JDb2RlUGlwZWxpbmUodGhpcy5jb25maWcubWV0YWRhdGEubWVyZ2VkKSxcbiAgICB9KTtcblxuICAgIC8vIEFkZCBzdGFnZXMgYXMgd2F2ZXMgdmlhIFN0YWdlQnVpbGRlclxuICAgIGlmIChwcm9wcy5zdGFnZXMpIHtcbiAgICAgIGNvbnN0IHN0YWdlQnVpbGRlciA9IG5ldyBTdGFnZUJ1aWxkZXIoe1xuICAgICAgICBzY29wZTogdGhpcyxcbiAgICAgICAgcGx1Z2luTG9va3VwLFxuICAgICAgICB1bmlxdWVJZCxcbiAgICAgICAgZ2xvYmFsTWV0YWRhdGE6IHRoaXMuY29uZmlnLm1ldGFkYXRhLm1lcmdlZCxcbiAgICAgICAgZGVmYXVsdENvbXB1dGVUeXBlLFxuICAgICAgICBhcnRpZmFjdE1hbmFnZXIsXG4gICAgICAgIG9yZ0lkOiBwcm9wcy5vcmdJZCxcbiAgICAgIH0pO1xuICAgICAgc3RhZ2VCdWlsZGVyLmFkZFN0YWdlcyh0aGlzLnBpcGVsaW5lLCBwcm9wcy5zdGFnZXMpO1xuICAgIH1cblxuICAgIC8vIOKUgOKUgCBUYWdzIOKUgOKUgFxuICAgIFRhZ3Mub2YodGhpcy5waXBlbGluZSkuYWRkKCdwcm9qZWN0JywgdGhpcy5jb25maWcucHJvamVjdCk7XG4gICAgVGFncy5vZih0aGlzLnBpcGVsaW5lKS5hZGQoJ29yZ2FuaXphdGlvbicsIHRoaXMuY29uZmlnLm9yZ2FuaXphdGlvbik7XG4gICAgaWYgKHByb3BzLnRhZ3MpIHtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzLnRhZ3MpKSB7XG4gICAgICAgIFRhZ3Mub2YodGhpcy5waXBlbGluZSkuYWRkKGtleSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEJ1aWxkIHRoZSBpbnRlcm5hbCBwaXBlbGluZSBiZWZvcmUgYWNjZXNzaW5nIGl0cyBwcm9wZXJ0aWVzXG4gICAgdGhpcy5waXBlbGluZS5idWlsZFBpcGVsaW5lKCk7XG4gICAgY29uc3QgY2RrUGlwZWxpbmUgPSB0aGlzLnBpcGVsaW5lLnBpcGVsaW5lO1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmNvbmZpZy5tZXRhZGF0YS5tZXJnZWQ7XG5cbiAgICAvLyDilIDilIAgU05TIE5vdGlmaWNhdGlvbnMg4pSA4pSAXG4gICAgY29uc3Qgbm90aWZpY2F0aW9uVG9waWNBcm4gPSBtZXRhW01ldGFkYXRhS2V5cy5OT1RJRklDQVRJT05fVE9QSUNfQVJOXTtcbiAgICBpZiAodHlwZW9mIG5vdGlmaWNhdGlvblRvcGljQXJuID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgdG9waWMgPSBzbnMuVG9waWMuZnJvbVRvcGljQXJuKHRoaXMsICdOb3RpZmljYXRpb25Ub3BpYycsIG5vdGlmaWNhdGlvblRvcGljQXJuKTtcbiAgICAgIGNvbnN0IG5vdGlmaWNhdGlvbkV2ZW50cyA9IHBhcnNlTm90aWZpY2F0aW9uRXZlbnRzKG1ldGFbTWV0YWRhdGFLZXlzLk5PVElGSUNBVElPTl9FVkVOVFNdKVxuICAgICAgICAubWFwKGUgPT4gUElQRUxJTkVfRVZFTlRfTUFQW2UudG9VcHBlckNhc2UoKV0pXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG4gICAgICBpZiAobm90aWZpY2F0aW9uRXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY2RrUGlwZWxpbmUubm90aWZ5T24oJ1BpcGVsaW5lTm90aWZpY2F0aW9uJywgdG9waWMsIHsgZXZlbnRzOiBub3RpZmljYXRpb25FdmVudHMgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g4pSA4pSAIFNjaGVkdWxlZCBFeGVjdXRpb24g4pSA4pSAXG4gICAgaWYgKHByb3BzLnN5bnRoLnNvdXJjZS5vcHRpb25zPy50cmlnZ2VyID09PSBUcmlnZ2VyVHlwZS5TQ0hFRFVMRSB8fCBwcm9wcy5zY2hlZHVsZSkge1xuICAgICAgY29uc3QgZXhwciA9IHByb3BzLnNjaGVkdWxlIHx8IChwcm9wcy5zeW50aC5zb3VyY2Uub3B0aW9ucyBhcyB7IHNjaGVkdWxlPzogc3RyaW5nIH0pPy5zY2hlZHVsZSB8fCAncmF0ZSgxIGRheSknO1xuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsICdTY2hlZHVsZVJ1bGUnLCB7XG4gICAgICAgIHNjaGVkdWxlOiBldmVudHMuU2NoZWR1bGUuZXhwcmVzc2lvbihleHByKSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkNvZGVQaXBlbGluZShjZGtQaXBlbGluZSldLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8g4pSA4pSAIEV4ZWN1dGlvbiBFdmVudCBUcmFja2luZyAoZm9yd2FyZCBwaXBlbGluZSBzdGF0ZSBjaGFuZ2VzIHRvIFNOUykg4pSA4pSAXG4gICAgaWYgKG1ldGFbTWV0YWRhdGFLZXlzLkVOQUJMRV9FWEVDVVRJT05fRVZFTlRTXSAmJiB0eXBlb2Ygbm90aWZpY2F0aW9uVG9waWNBcm4gPT09ICdzdHJpbmcnKSB7XG4gICAgICBuZXcgZXZlbnRzLlJ1bGUodGhpcywgJ0V4ZWN1dGlvbkV2ZW50UnVsZScsIHtcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgc291cmNlOiBbJ2F3cy5jb2RlcGlwZWxpbmUnXSxcbiAgICAgICAgICBkZXRhaWxUeXBlOiBbJ0NvZGVQaXBlbGluZSBQaXBlbGluZSBFeGVjdXRpb24gU3RhdGUgQ2hhbmdlJ10sXG4gICAgICAgICAgcmVzb3VyY2VzOiBbY2RrUGlwZWxpbmUucGlwZWxpbmVBcm5dLFxuICAgICAgICB9LFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuU25zVG9waWMoXG4gICAgICAgICAgc25zLlRvcGljLmZyb21Ub3BpY0Fybih0aGlzLCAnRXhlY3V0aW9uRXZlbnRUb3BpYycsIG5vdGlmaWNhdGlvblRvcGljQXJuKSxcbiAgICAgICAgKV0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyDilIDilIAgQXJ0aWZhY3QgRW5jcnlwdGlvbiAoS01TIGtleSkg4pSA4pSAXG4gICAgY29uc3Qga21zS2V5QXJuID0gdGhpcy5jb25maWcubWV0YWRhdGEubWVyZ2VkW01ldGFkYXRhS2V5cy5LTVNfS0VZX0FSTl07XG4gICAgaWYgKHR5cGVvZiBrbXNLZXlBcm4gPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBrZXkgPSBrbXMuS2V5LmZyb21LZXlBcm4odGhpcywgJ0FydGlmYWN0S2V5Jywga21zS2V5QXJuKTtcbiAgICAgIFRhZ3Mub2Yoa2V5KS5hZGQoJ3BpcGVsaW5lJywgdGhpcy5jb25maWcucGlwZWxpbmVOYW1lKTtcbiAgICB9XG5cbiAgICAvLyDilIDilIAgUGlwZWxpbmUgTWV0cmljcyAmIEFsYXJtcyDilIDilIBcbiAgICBjb25zdCBlbmFibGVNZXRyaWNzID0gdGhpcy5jb25maWcubWV0YWRhdGEubWVyZ2VkW01ldGFkYXRhS2V5cy5FTkFCTEVfTUVUUklDU107XG4gICAgaWYgKGVuYWJsZU1ldHJpY3MpIHtcbiAgICAgIG5ldyBjbG91ZHdhdGNoLkFsYXJtKHRoaXMsICdQaXBlbGluZUZhaWx1cmVBbGFybScsIHtcbiAgICAgICAgbWV0cmljOiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgICAgICAgIG5hbWVzcGFjZTogJ0FXUy9Db2RlUGlwZWxpbmUnLFxuICAgICAgICAgIG1ldHJpY05hbWU6ICdGYWlsZWRQaXBlbGluZUV4ZWN1dGlvbkNvdW50JyxcbiAgICAgICAgICBkaW1lbnNpb25zTWFwOiB7IFBpcGVsaW5lTmFtZTogdGhpcy5jb25maWcucGlwZWxpbmVOYW1lIH0sXG4gICAgICAgICAgc3RhdGlzdGljOiAnU3VtJyxcbiAgICAgICAgICBwZXJpb2Q6IER1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgIH0pLFxuICAgICAgICB0aHJlc2hvbGQ6IDEsXG4gICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiAxLFxuICAgICAgICBhbGFybURlc2NyaXB0aW9uOiBgUGlwZWxpbmUgJHt0aGlzLmNvbmZpZy5waXBlbGluZU5hbWV9IGV4ZWN1dGlvbiBmYWlsZWRgLFxuICAgICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5OT1RfQlJFQUNISU5HLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIENvZGVCdWlsZERlZmF1bHRzIGludG8gdGhlIHNoYXBlIGV4cGVjdGVkIGJ5IENESydzIGNvZGVCdWlsZERlZmF1bHRzLlxuICAgKiBDb21iaW5lcyBuZXR3b3JrIGNvbmZpZywgc2VjdXJpdHkgZ3JvdXBzLCBhbmQgcGlwZWxpbmUtbGV2ZWwgZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAqIChQSVBFTElORV9JRCwgRVhFQ1VUSU9OX0lELCBQTEFURk9STV9CQVNFX1VSTCkgYXZhaWxhYmxlIHRvIGFsbCBDb2RlQnVpbGQgYWN0aW9ucy5cbiAgICovXG4gIHByaXZhdGUgcmVzb2x2ZURlZmF1bHRzKFxuICAgIGRlZmF1bHRzOiBDb2RlQnVpbGREZWZhdWx0cyB8IHVuZGVmaW5lZCxcbiAgICBpZDogVW5pcXVlSWQsXG4gICAgcGlwZWxpbmVJZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIHBsYXRmb3JtU2VjcmV0TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIHBsYXRmb3JtVXJsOiBzdHJpbmcsXG4gICk6IENvZGVCdWlsZE9wdGlvbnMgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG5ldHdvcmtQcm9wcyA9IGRlZmF1bHRzPy5uZXR3b3JrXG4gICAgICA/IHJlc29sdmVOZXR3b3JrKHRoaXMsIGlkLCBkZWZhdWx0cy5uZXR3b3JrKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBzdGFuZGFsb25lU2VjdXJpdHlHcm91cHMgPSBkZWZhdWx0cz8uc2VjdXJpdHlHcm91cHNcbiAgICAgID8gcmVzb2x2ZVNlY3VyaXR5R3JvdXAodGhpcywgaWQsIGRlZmF1bHRzLnNlY3VyaXR5R3JvdXBzKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBQaXBlbGluZS1sZXZlbCBlbnYgdmFycyBhdmFpbGFibGUgdG8gYWxsIENvZGVCdWlsZCBhY3Rpb25zXG4gICAgLy8gTm90ZTogI3tjb2RlcGlwZWxpbmUuKn0gcmVzb2x2ZWQgdmFyaWFibGVzIG11c3QgZ28gdGhyb3VnaCBDb2RlQnVpbGRTdGVwLmVudlxuICAgIC8vIChhY3Rpb24tbGV2ZWwpLCBub3QgYnVpbGRFbnZpcm9ubWVudC5lbnZpcm9ubWVudFZhcmlhYmxlcyAocHJvamVjdC1sZXZlbCkuXG4gICAgY29uc3QgcGlwZWxpbmVFbnZWYXJzOiBSZWNvcmQ8c3RyaW5nLCB7IHZhbHVlOiBzdHJpbmcgfT4gPSB7XG4gICAgICBQTEFURk9STV9CQVNFX1VSTDogeyB2YWx1ZTogcGxhdGZvcm1VcmwgfSxcbiAgICAgIC4uLihwaXBlbGluZUlkICYmIHsgUElQRUxJTkVfSUQ6IHsgdmFsdWU6IHBpcGVsaW5lSWQgfSB9KSxcbiAgICAgIC4uLihwbGF0Zm9ybVNlY3JldE5hbWUgJiYgeyBQTEFURk9STV9TRUNSRVRfTkFNRTogeyB2YWx1ZTogcGxhdGZvcm1TZWNyZXROYW1lIH0gfSksXG4gICAgICAvLyBFbmFibGUgcGx1Z2luIHJlc29sdXRpb24gdmlhIGN1c3RvbSByZXNvdXJjZSBMYW1iZGEgaW5zaWRlIENvZGVQaXBlbGluZVxuICAgICAgUkVTT0xWRURfU1lOVEhfUExVR0lOOiB7IHZhbHVlOiAndHJ1ZScgfSxcbiAgICAgIC8vIFByb3BhZ2F0ZSBUTFMgdmVyaWZpY2F0aW9uIHNldHRpbmcgc28gYWxsIENvZGVCdWlsZCBzdGVwcyBjYW4gcmVhY2hcbiAgICAgIC8vIHRoZSBwbGF0Zm9ybSBBUEkgd2hlbiB1c2luZyBzZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZXNcbiAgICAgIC4uLihwcm9jZXNzLmVudi5OT0RFX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEID09PSAnMCcgJiYge1xuICAgICAgICBOT0RFX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEOiB7IHZhbHVlOiAnMCcgfSxcbiAgICAgIH0pLFxuICAgIH07XG5cbiAgICBjb25zdCBzZWN1cml0eUdyb3VwcyA9IFtcbiAgICAgIC4uLihuZXR3b3JrUHJvcHM/LnNlY3VyaXR5R3JvdXBzID8/IFtdKSxcbiAgICAgIC4uLihzdGFuZGFsb25lU2VjdXJpdHlHcm91cHMgPz8gW10pLFxuICAgIF07XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uKG5ldHdvcmtQcm9wcyAmJiB7IHZwYzogbmV0d29ya1Byb3BzLnZwYywgc3VibmV0U2VsZWN0aW9uOiBuZXR3b3JrUHJvcHMuc3VibmV0U2VsZWN0aW9uIH0pLFxuICAgICAgLi4uKHNlY3VyaXR5R3JvdXBzLmxlbmd0aCA+IDAgJiYgeyBzZWN1cml0eUdyb3VwcyB9KSxcbiAgICAgIGJ1aWxkRW52aXJvbm1lbnQ6IHsgZW52aXJvbm1lbnRWYXJpYWJsZXM6IHBpcGVsaW5lRW52VmFycyB9LFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { BuilderProps } from './pipeline-builder';
|
|
2
|
+
import type { CodeCommitOptions, CodeStarOptions, GitHubOptions, S3Options } from './source-types';
|
|
3
|
+
import type { PluginOptions, StageOptions, StepCustomization } from './step-types';
|
|
4
|
+
import type { CodeBuildDefaults, NetworkConfig } from '../core/network-types';
|
|
5
|
+
import type { MetaDataType, SourceType } from '../core/pipeline-types';
|
|
6
|
+
/**
|
|
7
|
+
* Validated and processed pipeline configuration (business logic layer).
|
|
8
|
+
* This class handles all non-CDK logic: validation, sanitization, and metadata merging.
|
|
9
|
+
* It can be tested independently without CDK dependencies.
|
|
10
|
+
*
|
|
11
|
+
* ## Metadata merge chain (last wins)
|
|
12
|
+
*
|
|
13
|
+
* 1. `BuilderProps.global` — base metadata inherited by all steps
|
|
14
|
+
* 2. `BuilderProps.defaults.metadata` — pipeline-level CodeBuild defaults metadata
|
|
15
|
+
* 3. `BuilderProps.synth.metadata` or `StageStepOptions.metadata` — per-step metadata
|
|
16
|
+
* 4. `plugin.metadata` — plugin's own metadata (merged in `createCodeBuildStep`)
|
|
17
|
+
* 5. `metadataForXxx()` — extracted CDK props spread last into construct calls
|
|
18
|
+
*
|
|
19
|
+
* Steps 1–3 are merged here into `this.metadata.merged`.
|
|
20
|
+
* Step 4 happens in `createCodeBuildStep` via `merge(metadata, plugin.metadata)`.
|
|
21
|
+
* Step 5 is spread last in the CDK constructor call, giving metadata full override authority.
|
|
22
|
+
*/
|
|
23
|
+
export declare class PipelineConfiguration {
|
|
24
|
+
readonly project: string;
|
|
25
|
+
readonly organization: string;
|
|
26
|
+
readonly pipelineName: string;
|
|
27
|
+
readonly metadata: {
|
|
28
|
+
readonly global: MetaDataType;
|
|
29
|
+
readonly synth: MetaDataType;
|
|
30
|
+
readonly merged: MetaDataType;
|
|
31
|
+
};
|
|
32
|
+
readonly source: SourceType;
|
|
33
|
+
readonly plugin: PluginOptions;
|
|
34
|
+
readonly network: NetworkConfig | undefined;
|
|
35
|
+
readonly defaults: CodeBuildDefaults | undefined;
|
|
36
|
+
readonly synthCustomization: StepCustomization;
|
|
37
|
+
readonly stages: StageOptions[] | undefined;
|
|
38
|
+
constructor(props: BuilderProps);
|
|
39
|
+
/**
|
|
40
|
+
* Validates BuilderProps to ensure all required fields are present.
|
|
41
|
+
* Throws an error with detailed messages if validation fails.
|
|
42
|
+
*/
|
|
43
|
+
private validateProps;
|
|
44
|
+
/**
|
|
45
|
+
* Extracts S3 source options with defaults applied.
|
|
46
|
+
*
|
|
47
|
+
* @returns S3 options with `objectKey` defaulting to `'source.zip'` and `trigger` defaulting to `NONE`
|
|
48
|
+
* @throws {Error} If the configured source type is not `s3`
|
|
49
|
+
*/
|
|
50
|
+
getS3Options(): Required<Pick<S3Options, 'bucketName' | 'objectKey' | 'trigger'>> & Omit<S3Options, 'bucketName' | 'objectKey' | 'trigger'>;
|
|
51
|
+
/**
|
|
52
|
+
* Extracts GitHub source options with defaults applied.
|
|
53
|
+
*
|
|
54
|
+
* @returns GitHub options with `branch` defaulting to `'main'` and `trigger` defaulting to `NONE`
|
|
55
|
+
* @throws {Error} If the configured source type is not `github`
|
|
56
|
+
*/
|
|
57
|
+
getGitHubOptions(): Required<Pick<GitHubOptions, 'repo' | 'branch' | 'trigger'>> & Omit<GitHubOptions, 'repo' | 'branch' | 'trigger'>;
|
|
58
|
+
/**
|
|
59
|
+
* Extracts CodeStar source options with defaults applied.
|
|
60
|
+
*
|
|
61
|
+
* @returns CodeStar options with `branch` defaulting to `'main'`, `trigger` defaulting to `NONE`, and `codeBuildCloneOutput` defaulting to `false`
|
|
62
|
+
* @throws {Error} If the configured source type is not `codestar`
|
|
63
|
+
*/
|
|
64
|
+
getCodeStarOptions(): Required<Pick<CodeStarOptions, 'repo' | 'branch' | 'trigger' | 'codeBuildCloneOutput' | 'connectionArn'>>;
|
|
65
|
+
/**
|
|
66
|
+
* Extracts CodeCommit source options with defaults applied.
|
|
67
|
+
*
|
|
68
|
+
* @returns CodeCommit options with `branch` defaulting to `'main'` and `trigger` defaulting to `NONE`
|
|
69
|
+
* @throws {Error} If the configured source type is not `codecommit`
|
|
70
|
+
*/
|
|
71
|
+
getCodeCommitOptions(): Required<Pick<CodeCommitOptions, 'repositoryName' | 'branch' | 'trigger'>>;
|
|
72
|
+
}
|