@go-to-k/cdkd 0.130.0 → 0.131.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,5 @@
1
- import { r as getAwsClients } from "./aws-clients-CuHRHcyW.js";
2
- import { AsyncLocalStorage } from "node:async_hooks";
3
- import { createHash } from "node:crypto";
1
+ import { a as runDockerStreaming, c as getLogger, d as getLiveRenderer, g as generateResourceNameWithFallback, m as applyDefaultNameForFallback, n as formatDockerLoginError, o as spawnStreaming, r as getDockerCmd, v as withStackName } from "./docker-cmd-EtWSTAje.js";
2
+ import { r as getAwsClients } from "./aws-clients-BF03Alpe.js";
4
3
  import { DeleteObjectCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, NoSuchKey, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
5
4
  import { CloudControlClient, CreateResourceCommand, DeleteResourceCommand, GetResourceCommand, GetResourceRequestStatusCommand, ListResourcesCommand, UpdateResourceCommand } from "@aws-sdk/client-cloudcontrol";
6
5
  import { AttachRolePolicyCommand, CreateRoleCommand, DeleteRoleCommand, DeleteRolePermissionsBoundaryCommand, DeleteRolePolicyCommand, DetachRolePolicyCommand, GetRoleCommand, GetRolePolicyCommand, IAMClient, ListAttachedRolePoliciesCommand, ListInstanceProfilesForRoleCommand, ListRolePoliciesCommand, ListRoleTagsCommand, ListRolesCommand, NoSuchEntityException, PutRolePermissionsBoundaryCommand, PutRolePolicyCommand, RemoveRoleFromInstanceProfileCommand, TagRoleCommand, UntagRoleCommand, UpdateAssumeRolePolicyCommand, UpdateRoleCommand } from "@aws-sdk/client-iam";
@@ -26,800 +25,6 @@ import graphlib from "graphlib";
26
25
  import { DescribeDBClustersCommand, RDSClient } from "@aws-sdk/client-rds";
27
26
  import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
28
27
 
29
- //#region src/provisioning/resource-name.ts
30
- /**
31
- * Per-async-context stack name. Resource-name generation reads this so that
32
- * concurrent deploys (`cdkd deploy --all` runs stacks in parallel up to
33
- * `--stack-concurrency`) don't fight over a single shared variable.
34
- *
35
- * History: this was `let currentStackName: string | undefined` until
36
- * 2026-05-01. Two parallel `deploy()` calls would each call
37
- * `setCurrentStackName(...)` and the second would overwrite the first;
38
- * any IAM Role / SQS Queue / etc. created by the first stack while the
39
- * second was active would get the second stack's prefix in its physical
40
- * name, then the second stack's own create attempt for the same logical
41
- * id would collide ("Role with name X already exists"). Switching to
42
- * `AsyncLocalStorage` scopes the value to each deploy's async chain.
43
- */
44
- const stackNameStore = new AsyncLocalStorage();
45
- function withStackName(stackName, fn) {
46
- return stackNameStore.run(stackName, fn);
47
- }
48
- /**
49
- * Read the current async context's stack name, if any.
50
- *
51
- * Returns `undefined` outside any `withStackName` / `setCurrentStackName`
52
- * scope. Used by the live renderer to scope per-stack in-flight task
53
- * entries so concurrent deploys don't clobber each other's tasks (same
54
- * `logicalId` in two stacks would collide on the singleton renderer's
55
- * task Map without this).
56
- */
57
- function getCurrentStackName() {
58
- return stackNameStore.getStore();
59
- }
60
- /**
61
- * Per-async-context "skip the stack-name prefix on user-supplied physical
62
- * names" flag. Read by `generateResourceName` when its caller passes
63
- * `userSupplied: true`; auto-generated-name paths
64
- * (`generateResourceName(logicalId, ...)`) ignore this flag.
65
- *
66
- * Scoped via AsyncLocalStorage so that `--stack-concurrency > 1` runs
67
- * cannot cross-contaminate — each deploy's body is wrapped in its own
68
- * `withSkipPrefix(...)` scope (the deploy CLI plumbs the resolved
69
- * `--no-prefix-user-supplied-names` value through here). Default
70
- * `false` preserves pre-PR behavior when the flag is not set.
71
- */
72
- const skipPrefixStore = new AsyncLocalStorage();
73
- function withSkipPrefix(skip, fn) {
74
- return skipPrefixStore.run(skip, fn);
75
- }
76
- /**
77
- * Read the current async context's skip-prefix flag. Defaults to
78
- * `false` when no `withSkipPrefix` scope is active.
79
- *
80
- * Public for unit tests; `generateResourceName` consumes this
81
- * internally.
82
- */
83
- function getCurrentSkipPrefix() {
84
- return skipPrefixStore.getStore() ?? false;
85
- }
86
- /**
87
- * Resource types whose pre-PR #297 code path ran user-supplied
88
- * physical names through `generateResourceName` (= got the stack-name
89
- * prefix). These are the only types affected by
90
- * `--no-prefix-user-supplied-names`; flipping the flag against an
91
- * existing stack proposes REPLACEMENT on every state resource of
92
- * one of these types whose `physicalId` is still prefixed.
93
- *
94
- * Pattern A providers (Lambda, S3, SNS, SQS, DynamoDB, Logs LogGroup,
95
- * Events Rule, etc.) historically short-circuited user-supplied names
96
- * **out** of `generateResourceName` entirely — those types never got
97
- * the prefix regardless of the flag, so they are NOT included here.
98
- *
99
- * Used by the deploy-time pre-flight migration check in
100
- * `src/cli/commands/prefix-migration-check.ts`. Keep in sync with the
101
- * Pattern B provider call sites that consume
102
- * `generateResourceNameWithFallback(...)`.
103
- */
104
- const PATTERN_B_RESOURCE_TYPES = [
105
- "AWS::IAM::Role",
106
- "AWS::IAM::User",
107
- "AWS::IAM::Group",
108
- "AWS::IAM::InstanceProfile",
109
- "AWS::ElasticLoadBalancingV2::LoadBalancer",
110
- "AWS::ElasticLoadBalancingV2::TargetGroup"
111
- ];
112
- /**
113
- * For each Pattern B resource type, the CFn template `Properties` field
114
- * the user sets to supply a physical name (`new iam.Role(this, 'X',
115
- * { roleName: 'my-role' })` → `Properties.RoleName: 'my-role'`).
116
- *
117
- * Used by the prefix-migration check to distinguish user-supplied
118
- * physical names (which the v0.94.0 default flip would actually
119
- * REPLACE on next deploy) from auto-generated logical-id-fallback
120
- * names (which keep the prefix in BOTH old and new default — no
121
- * REPLACE pending). Without this discriminator, the migration
122
- * check naively flags every prefix-style physicalId regardless of
123
- * its origin, surfacing a false-positive WARNING on auto-generated
124
- * names that won't actually be touched.
125
- *
126
- * Keep in sync with `PATTERN_B_RESOURCE_TYPES` and with each
127
- * provider's `Properties[<NameField>]` lookup in
128
- * `src/provisioning/providers/`.
129
- */
130
- const PATTERN_B_NAME_PROPERTIES = {
131
- "AWS::IAM::Role": "RoleName",
132
- "AWS::IAM::User": "UserName",
133
- "AWS::IAM::Group": "GroupName",
134
- "AWS::IAM::InstanceProfile": "InstanceProfileName",
135
- "AWS::ElasticLoadBalancingV2::LoadBalancer": "Name",
136
- "AWS::ElasticLoadBalancingV2::TargetGroup": "Name"
137
- };
138
- /**
139
- * Generate a unique resource name from the logical ID.
140
- *
141
- * Generates names in CloudFormation-compatible format:
142
- * `{StackName}-{LogicalId}-{Hash}` (truncated to maxLength).
143
- *
144
- * @param name The raw name (from properties or logicalId fallback)
145
- * @param options Length and character constraints
146
- * @returns A sanitized, truncated name that fits the constraints
147
- */
148
- function generateResourceName(name, options) {
149
- const { maxLength, lowercase = false, allowedPattern = /[^a-zA-Z0-9-]/g, userSupplied = false } = options;
150
- const currentStackName = stackNameStore.getStore();
151
- const fullName = currentStackName && !(userSupplied && getCurrentSkipPrefix()) ? `${currentStackName}-${name}` : name;
152
- let sanitized = lowercase ? fullName.toLowerCase() : fullName;
153
- sanitized = sanitized.replace(allowedPattern, "-");
154
- sanitized = sanitized.replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
155
- if (sanitized.length <= maxLength) return sanitized;
156
- const hash = createHash("sha256").update(fullName).digest("hex").substring(0, 8);
157
- const maxPrefixLength = maxLength - hash.length - 1;
158
- return `${sanitized.substring(0, maxPrefixLength).replace(/-+$/, "")}-${hash}`;
159
- }
160
- /**
161
- * Generate a resource name from a user-declared physical name OR
162
- * fall back to the logical id.
163
- *
164
- * Wraps {@link generateResourceName} to express the Pattern B call-site
165
- * shape (`generateResourceName((properties['Name'] as string | undefined)
166
- * || logicalId, opts)`) as a single typed helper. The user-supplied
167
- * branch passes `userSupplied: true`, which makes the per-deploy
168
- * `withSkipPrefix(true)` flag drop the stack-name prefix on that name.
169
- * The fallback (logical-id) branch is `userSupplied: false` and keeps
170
- * the prefix regardless of the flag — auto-generated names rely on
171
- * the prefix for cross-stack uniqueness.
172
- *
173
- * Use at every Pattern B provider call site (currently IAM Role, IAM
174
- * User, IAM Group, IAM InstanceProfile, ELBv2 LoadBalancer, ELBv2
175
- * TargetGroup) so the `--no-prefix-user-supplied-names` flag controls
176
- * those types consistently. Pattern A providers (Lambda, S3, SNS,
177
- * SQS, DynamoDB, etc.) do NOT need this helper — they already
178
- * short-circuit the user-supplied name out of the
179
- * `generateResourceName` call entirely, so the prefix is never
180
- * applied to user-supplied names regardless of the flag.
181
- */
182
- function generateResourceNameWithFallback(userSuppliedName, logicalId, options) {
183
- if (userSuppliedName !== void 0 && userSuppliedName !== "") return generateResourceName(userSuppliedName, {
184
- ...options,
185
- userSupplied: true
186
- });
187
- return generateResourceName(logicalId, {
188
- ...options,
189
- userSupplied: false
190
- });
191
- }
192
- /**
193
- * Default name generation rules for CC API fallback.
194
- *
195
- * When an SDK provider falls back to CC API, the resource may need a
196
- * default name that the SDK provider would have generated. This map
197
- * defines the name property and generation options for each resource type.
198
- *
199
- * Format: resourceType → { nameProperty, options, postProcess? }
200
- */
201
- const FALLBACK_NAME_RULES = {
202
- "AWS::S3::Bucket": {
203
- nameProperty: "BucketName",
204
- options: {
205
- maxLength: 63,
206
- lowercase: true
207
- }
208
- },
209
- "AWS::SQS::Queue": {
210
- nameProperty: "QueueName",
211
- options: { maxLength: 80 }
212
- },
213
- "AWS::SNS::Topic": {
214
- nameProperty: "TopicName",
215
- options: { maxLength: 256 }
216
- },
217
- "AWS::Lambda::Function": {
218
- nameProperty: "FunctionName",
219
- options: { maxLength: 64 }
220
- },
221
- "AWS::Lambda::LayerVersion": {
222
- nameProperty: "LayerName",
223
- options: { maxLength: 64 }
224
- },
225
- "AWS::IAM::Role": {
226
- nameProperty: "RoleName",
227
- options: { maxLength: 64 }
228
- },
229
- "AWS::IAM::Policy": {
230
- nameProperty: "PolicyName",
231
- options: { maxLength: 64 }
232
- },
233
- "AWS::IAM::User": {
234
- nameProperty: "UserName",
235
- options: { maxLength: 64 }
236
- },
237
- "AWS::IAM::Group": {
238
- nameProperty: "GroupName",
239
- options: { maxLength: 128 }
240
- },
241
- "AWS::IAM::InstanceProfile": {
242
- nameProperty: "InstanceProfileName",
243
- options: { maxLength: 128 }
244
- },
245
- "AWS::DynamoDB::Table": {
246
- nameProperty: "TableName",
247
- options: { maxLength: 255 }
248
- },
249
- "AWS::ECR::Repository": {
250
- nameProperty: "RepositoryName",
251
- options: {
252
- maxLength: 256,
253
- lowercase: true
254
- }
255
- },
256
- "AWS::ECS::Cluster": {
257
- nameProperty: "ClusterName",
258
- options: { maxLength: 255 }
259
- },
260
- "AWS::ECS::Service": {
261
- nameProperty: "ServiceName",
262
- options: { maxLength: 255 }
263
- },
264
- "AWS::Logs::LogGroup": {
265
- nameProperty: "LogGroupName",
266
- options: { maxLength: 512 }
267
- },
268
- "AWS::CloudWatch::Alarm": {
269
- nameProperty: "AlarmName",
270
- options: { maxLength: 256 }
271
- },
272
- "AWS::Events::Rule": {
273
- nameProperty: "Name",
274
- options: { maxLength: 64 }
275
- },
276
- "AWS::Events::EventBus": {
277
- nameProperty: "Name",
278
- options: { maxLength: 256 }
279
- },
280
- "AWS::Kinesis::Stream": {
281
- nameProperty: "Name",
282
- options: { maxLength: 128 }
283
- },
284
- "AWS::StepFunctions::StateMachine": {
285
- nameProperty: "StateMachineName",
286
- options: { maxLength: 80 }
287
- },
288
- "AWS::SecretsManager::Secret": {
289
- nameProperty: "Name",
290
- options: {
291
- maxLength: 512,
292
- allowedPattern: /[^a-zA-Z0-9-/_]/g
293
- }
294
- },
295
- "AWS::SSM::Parameter": {
296
- nameProperty: "Name",
297
- options: { maxLength: 2048 }
298
- },
299
- "AWS::Cognito::UserPool": {
300
- nameProperty: "UserPoolName",
301
- options: { maxLength: 128 }
302
- },
303
- "AWS::ElastiCache::SubnetGroup": {
304
- nameProperty: "CacheSubnetGroupName",
305
- options: {
306
- maxLength: 255,
307
- lowercase: true
308
- }
309
- },
310
- "AWS::ElastiCache::CacheCluster": {
311
- nameProperty: "ClusterName",
312
- options: {
313
- maxLength: 40,
314
- lowercase: true
315
- }
316
- },
317
- "AWS::RDS::DBSubnetGroup": {
318
- nameProperty: "DBSubnetGroupName",
319
- options: {
320
- maxLength: 255,
321
- lowercase: true
322
- }
323
- },
324
- "AWS::RDS::DBCluster": {
325
- nameProperty: "DBClusterIdentifier",
326
- options: {
327
- maxLength: 63,
328
- lowercase: true
329
- }
330
- },
331
- "AWS::RDS::DBInstance": {
332
- nameProperty: "DBInstanceIdentifier",
333
- options: {
334
- maxLength: 63,
335
- lowercase: true
336
- }
337
- },
338
- "AWS::DocDB::DBSubnetGroup": {
339
- nameProperty: "DBSubnetGroupName",
340
- options: {
341
- maxLength: 255,
342
- lowercase: true
343
- }
344
- },
345
- "AWS::DocDB::DBCluster": {
346
- nameProperty: "DBClusterIdentifier",
347
- options: {
348
- maxLength: 63,
349
- lowercase: true
350
- }
351
- },
352
- "AWS::DocDB::DBInstance": {
353
- nameProperty: "DBInstanceIdentifier",
354
- options: {
355
- maxLength: 63,
356
- lowercase: true
357
- }
358
- },
359
- "AWS::Neptune::DBSubnetGroup": {
360
- nameProperty: "DBSubnetGroupName",
361
- options: {
362
- maxLength: 255,
363
- lowercase: true
364
- }
365
- },
366
- "AWS::Neptune::DBCluster": {
367
- nameProperty: "DBClusterIdentifier",
368
- options: {
369
- maxLength: 63,
370
- lowercase: true
371
- }
372
- },
373
- "AWS::Neptune::DBInstance": {
374
- nameProperty: "DBInstanceIdentifier",
375
- options: {
376
- maxLength: 63,
377
- lowercase: true
378
- }
379
- },
380
- "AWS::ElasticLoadBalancingV2::LoadBalancer": {
381
- nameProperty: "Name",
382
- options: { maxLength: 32 }
383
- },
384
- "AWS::ElasticLoadBalancingV2::TargetGroup": {
385
- nameProperty: "Name",
386
- options: { maxLength: 32 }
387
- },
388
- "AWS::WAFv2::WebACL": {
389
- nameProperty: "Name",
390
- options: { maxLength: 128 }
391
- },
392
- "AWS::CodeBuild::Project": {
393
- nameProperty: "Name",
394
- options: { maxLength: 255 }
395
- },
396
- "AWS::S3Express::DirectoryBucket": {
397
- nameProperty: "BucketName",
398
- options: {
399
- maxLength: 63,
400
- lowercase: true
401
- }
402
- }
403
- };
404
- /**
405
- * Apply default name generation for CC API fallback.
406
- *
407
- * When a resource doesn't have an explicit name property set,
408
- * generates the same default name that the SDK provider would have created.
409
- * This ensures consistent naming regardless of whether SDK or CC API handles the resource.
410
- *
411
- * @param logicalId Logical ID from the template
412
- * @param resourceType CloudFormation resource type
413
- * @param properties Resource properties (will not be mutated)
414
- * @returns Properties with default name applied if needed, or original properties if no rule exists
415
- */
416
- function applyDefaultNameForFallback(logicalId, resourceType, properties) {
417
- const rule = FALLBACK_NAME_RULES[resourceType];
418
- if (!rule) return properties;
419
- if (properties[rule.nameProperty]) return properties;
420
- const generatedName = generateResourceName(logicalId, rule.options);
421
- return {
422
- ...properties,
423
- [rule.nameProperty]: generatedName
424
- };
425
- }
426
-
427
- //#endregion
428
- //#region src/utils/live-renderer.ts
429
- /**
430
- * Live multi-line progress renderer for the bottom of the terminal.
431
- *
432
- * Maintains a "live area" listing in-flight tasks (Creating MyBucket...),
433
- * redrawn on a spinner timer. Other log output is routed through
434
- * {@link LiveRenderer.printAbove} so it appears above the live area without
435
- * disturbing the currently-displayed in-flight tasks.
436
- *
437
- * Design notes:
438
- * - Multiple resources can be in flight concurrently (cdkd uses parallel DAG
439
- * dispatch), so a single in-place line overwrite is not enough — each
440
- * in-flight resource is its own line in the live area.
441
- * - On non-TTY (CI/log-collection), the renderer stays inactive and
442
- * {@link LiveRenderer.printAbove} falls through to a direct write, so output
443
- * matches the previous append-only behavior.
444
- * - In verbose mode (debug level) the caller should not start the renderer:
445
- * debug logs would interleave too aggressively with the live area.
446
- */
447
- const SPINNER_FRAMES = [
448
- "⠋",
449
- "⠙",
450
- "⠹",
451
- "⠸",
452
- "⠼",
453
- "⠴",
454
- "⠦",
455
- "⠧",
456
- "⠇",
457
- "⠏"
458
- ];
459
- const FRAME_INTERVAL_MS = 80;
460
- const ESC = "\x1B[";
461
- /**
462
- * Scope a task `id` to its calling stack so two stacks running in
463
- * parallel — `cdkd deploy --all` with `--stack-concurrency > 1` — don't
464
- * collide on the same `logicalId` in the renderer's task Map. Without
465
- * this, stack B's `addTask('MyQueue', ...)` would overwrite stack A's
466
- * entry, and stack A's later `removeTask('MyQueue')` would erase
467
- * stack B's.
468
- */
469
- function scopedKey(id, stackName) {
470
- return stackName ? `${stackName}:${id}` : id;
471
- }
472
- var LiveRenderer = class {
473
- tasks = /* @__PURE__ */ new Map();
474
- active = false;
475
- spinnerIndex = 0;
476
- interval = null;
477
- linesDrawn = 0;
478
- cursorHidden = false;
479
- exitListener = null;
480
- stream;
481
- constructor(stream = process.stdout) {
482
- this.stream = stream;
483
- }
484
- isActive() {
485
- return this.active;
486
- }
487
- /**
488
- * Enable the live renderer. No-op if stdout is not a TTY or if
489
- * `CDKD_NO_LIVE=1`. Returns true if successfully enabled.
490
- */
491
- start() {
492
- if (this.active) return true;
493
- if (!this.stream.isTTY) return false;
494
- if (process.env["CDKD_NO_LIVE"] === "1") return false;
495
- this.active = true;
496
- this.hideCursor();
497
- if (!this.exitListener) {
498
- this.exitListener = () => this.showCursor();
499
- process.on("exit", this.exitListener);
500
- }
501
- this.interval = setInterval(() => this.draw(), FRAME_INTERVAL_MS);
502
- if (typeof this.interval.unref === "function") this.interval.unref();
503
- return true;
504
- }
505
- stop() {
506
- if (!this.active) return;
507
- if (this.interval) {
508
- clearInterval(this.interval);
509
- this.interval = null;
510
- }
511
- this.clear();
512
- this.showCursor();
513
- if (this.exitListener) {
514
- process.removeListener("exit", this.exitListener);
515
- this.exitListener = null;
516
- }
517
- this.tasks.clear();
518
- this.active = false;
519
- }
520
- addTask(id, label) {
521
- const stackName = getCurrentStackName();
522
- this.tasks.set(scopedKey(id, stackName), {
523
- label,
524
- startedAt: Date.now(),
525
- stackName
526
- });
527
- if (this.active) this.draw();
528
- }
529
- removeTask(id) {
530
- const stackName = getCurrentStackName();
531
- if (!this.tasks.delete(scopedKey(id, stackName))) return;
532
- if (this.active) this.draw();
533
- }
534
- /**
535
- * Replace the label of a previously-added task in place. No-op if the
536
- * task is not currently tracked (e.g. it already finished). Used by the
537
- * per-resource deadline wrapper to surface a "[taking longer than
538
- * expected, Nm+]" suffix without disturbing the elapsed-time counter
539
- * the renderer tracks via `startedAt`.
540
- */
541
- updateTaskLabel(id, label) {
542
- const stackName = getCurrentStackName();
543
- const task = this.tasks.get(scopedKey(id, stackName));
544
- if (!task) return;
545
- task.label = label;
546
- if (this.active) this.draw();
547
- }
548
- /**
549
- * Print content above the live area. Clears the live area, runs the writer,
550
- * then redraws the live area. When the renderer is inactive, the writer
551
- * runs directly so callers can use this unconditionally.
552
- */
553
- printAbove(write) {
554
- if (!this.active) {
555
- write();
556
- return;
557
- }
558
- this.clear();
559
- write();
560
- this.draw();
561
- }
562
- clear() {
563
- if (this.linesDrawn === 0) return;
564
- this.stream.write("\r");
565
- for (let i = 0; i < this.linesDrawn; i++) this.stream.write(`${ESC}1A${ESC}2K`);
566
- this.linesDrawn = 0;
567
- }
568
- draw() {
569
- if (!this.active) return;
570
- this.clear();
571
- if (this.tasks.size === 0) return;
572
- const frame = SPINNER_FRAMES[this.spinnerIndex % SPINNER_FRAMES.length];
573
- this.spinnerIndex++;
574
- const distinctStacks = /* @__PURE__ */ new Set();
575
- for (const task of this.tasks.values()) distinctStacks.add(task.stackName);
576
- const showStackPrefix = distinctStacks.size > 1;
577
- const cols = this.stream.columns ?? 80;
578
- const lines = [];
579
- for (const task of this.tasks.values()) {
580
- const elapsed = ((Date.now() - task.startedAt) / 1e3).toFixed(1);
581
- const raw = ` ${frame} ${showStackPrefix && task.stackName ? `[${task.stackName}] ` : ""}${task.label} (${elapsed}s)`;
582
- lines.push(this.truncate(raw, cols));
583
- }
584
- this.stream.write(lines.join("\n") + "\n");
585
- this.linesDrawn = lines.length;
586
- }
587
- truncate(s, maxLen) {
588
- if (s.length <= maxLen) return s;
589
- if (maxLen <= 1) return "…";
590
- return s.substring(0, maxLen - 1) + "…";
591
- }
592
- hideCursor() {
593
- if (this.cursorHidden) return;
594
- this.stream.write(`${ESC}?25l`);
595
- this.cursorHidden = true;
596
- }
597
- showCursor() {
598
- if (!this.cursorHidden) return;
599
- this.stream.write(`${ESC}?25h`);
600
- this.cursorHidden = false;
601
- }
602
- };
603
- let globalRenderer = null;
604
- function getLiveRenderer() {
605
- if (!globalRenderer) globalRenderer = new LiveRenderer();
606
- return globalRenderer;
607
- }
608
-
609
- //#endregion
610
- //#region src/utils/stack-context.ts
611
- const outputBufferStore = new AsyncLocalStorage();
612
- /**
613
- * Run `fn` with a fresh log buffer scoped to its async chain. Any
614
- * `logger.info / debug / warn / error` calls inside `fn` (and any
615
- * `await`s) push into the buffer instead of writing to stdout/stderr.
616
- * Returns the buffered lines (and either `result` or `error`) so the
617
- * caller can flush them in one block.
618
- */
619
- async function runStackBuffered(fn) {
620
- const buffer = { lines: [] };
621
- return outputBufferStore.run(buffer, async () => {
622
- try {
623
- return {
624
- ok: true,
625
- result: await fn(),
626
- lines: buffer.lines
627
- };
628
- } catch (error) {
629
- return {
630
- ok: false,
631
- error,
632
- lines: buffer.lines
633
- };
634
- }
635
- });
636
- }
637
- /**
638
- * Get the current async context's stack output buffer, or `undefined`
639
- * if no `runStackBuffered` is active. The logger consults this on every
640
- * call: present → push to buffer; absent → fall through to live
641
- * renderer / console.
642
- */
643
- function getCurrentStackOutputBuffer() {
644
- return outputBufferStore.getStore();
645
- }
646
-
647
- //#endregion
648
- //#region src/utils/logger.ts
649
- /**
650
- * ANSI color codes
651
- *
652
- * Kept internal — `ConsoleLogger.formatMessage` references these for the
653
- * verbose/compact mode level prefixes. For inline color wrapping in
654
- * production code, import from `./colors.js` instead (which lives in a
655
- * separate module so unit tests that mock `logger.ts` don't strip color
656
- * helpers as a side effect).
657
- */
658
- const colors = {
659
- reset: "\x1B[0m",
660
- bright: "\x1B[1m",
661
- dim: "\x1B[2m",
662
- red: "\x1B[31m",
663
- green: "\x1B[32m",
664
- yellow: "\x1B[33m",
665
- blue: "\x1B[34m",
666
- cyan: "\x1B[36m",
667
- gray: "\x1B[90m"
668
- };
669
- /**
670
- * Format timestamp
671
- */
672
- function formatTimestamp() {
673
- return (/* @__PURE__ */ new Date()).toISOString();
674
- }
675
- /**
676
- * Console logger implementation
677
- *
678
- * Supports two output modes:
679
- * - verbose (debug level): timestamps, module prefixes, all details
680
- * - compact (info level): clean output without timestamps or prefixes
681
- */
682
- var ConsoleLogger = class {
683
- level;
684
- useColors;
685
- constructor(level = "info", useColors = true) {
686
- this.level = level;
687
- this.useColors = useColors;
688
- }
689
- shouldLog(level) {
690
- const levels = [
691
- "debug",
692
- "info",
693
- "warn",
694
- "error"
695
- ];
696
- const currentLevelIndex = levels.indexOf(this.level);
697
- return levels.indexOf(level) >= currentLevelIndex;
698
- }
699
- formatMessage(level, message, ...args) {
700
- const formattedArgs = args.length > 0 ? " " + args.map((a) => JSON.stringify(a)).join(" ") : "";
701
- if (this.level === "debug") {
702
- const timestamp = formatTimestamp();
703
- const levelStr = level.toUpperCase().padEnd(5);
704
- if (this.useColors) {
705
- const levelColor = {
706
- debug: colors.gray,
707
- info: colors.blue,
708
- warn: colors.yellow,
709
- error: colors.red
710
- }[level];
711
- return `${colors.dim}${timestamp}${colors.reset} ${levelColor}${levelStr}${colors.reset} ${message}${formattedArgs}`;
712
- }
713
- return `${timestamp} ${levelStr} ${message}${formattedArgs}`;
714
- }
715
- if (this.useColors) {
716
- if (level === "error") return `${colors.red}${message}${formattedArgs}${colors.reset}`;
717
- if (level === "warn") return `${colors.yellow}${message}${formattedArgs}${colors.reset}`;
718
- return `${message}${formattedArgs}`;
719
- }
720
- return `${message}${formattedArgs}`;
721
- }
722
- /**
723
- * Route a formatted log line. When a per-stack output buffer is active in
724
- * the current async context (parallel multi-stack deploy), capture the
725
- * line into the buffer so it can be flushed as one atomic block when the
726
- * stack finishes. Otherwise fall through to the live renderer / console
727
- * as before.
728
- */
729
- emit(level, formatted) {
730
- const buffer = getCurrentStackOutputBuffer();
731
- if (buffer) {
732
- buffer.lines.push(formatted);
733
- return;
734
- }
735
- getLiveRenderer().printAbove(() => {
736
- if (level === "error") console.error(formatted);
737
- else if (level === "warn") console.warn(formatted);
738
- else if (level === "info") console.info(formatted);
739
- else console.debug(formatted);
740
- });
741
- }
742
- debug(message, ...args) {
743
- if (this.shouldLog("debug")) this.emit("debug", this.formatMessage("debug", message, ...args));
744
- }
745
- info(message, ...args) {
746
- if (this.shouldLog("info")) this.emit("info", this.formatMessage("info", message, ...args));
747
- }
748
- warn(message, ...args) {
749
- if (this.shouldLog("warn")) this.emit("warn", this.formatMessage("warn", message, ...args));
750
- }
751
- error(message, ...args) {
752
- if (this.shouldLog("error")) this.emit("error", this.formatMessage("error", message, ...args));
753
- }
754
- /**
755
- * Set log level
756
- */
757
- setLevel(level) {
758
- this.level = level;
759
- }
760
- getLevel() {
761
- return this.level;
762
- }
763
- /**
764
- * Create a child logger with a prefix
765
- *
766
- * In verbose mode, prefix is shown as [Prefix]. In compact mode, prefix is hidden.
767
- */
768
- child(prefix) {
769
- return new ChildLogger(prefix, this.useColors);
770
- }
771
- };
772
- /**
773
- * Child logger that always syncs level from global logger
774
- */
775
- var ChildLogger = class extends ConsoleLogger {
776
- prefix;
777
- constructor(prefix, useColors) {
778
- super("info", useColors);
779
- this.prefix = prefix;
780
- }
781
- syncLevel() {
782
- if (globalLogger) this.setLevel(globalLogger.getLevel());
783
- }
784
- debug(message, ...args) {
785
- this.syncLevel();
786
- super.debug(`[${this.prefix}] ${message}`, ...args);
787
- }
788
- info(message, ...args) {
789
- this.syncLevel();
790
- const msg = this.getLevel() === "debug" ? `[${this.prefix}] ${message}` : message;
791
- super.info(msg, ...args);
792
- }
793
- warn(message, ...args) {
794
- this.syncLevel();
795
- const msg = this.getLevel() === "debug" ? `[${this.prefix}] ${message}` : message;
796
- super.warn(msg, ...args);
797
- }
798
- error(message, ...args) {
799
- this.syncLevel();
800
- const msg = this.getLevel() === "debug" ? `[${this.prefix}] ${message}` : message;
801
- super.error(msg, ...args);
802
- }
803
- };
804
- /**
805
- * Global logger instance
806
- */
807
- let globalLogger = null;
808
- /**
809
- * Get or create global logger
810
- */
811
- function getLogger() {
812
- if (!globalLogger) globalLogger = new ConsoleLogger();
813
- return globalLogger;
814
- }
815
- /**
816
- * Set global logger instance
817
- */
818
- function setLogger(logger) {
819
- globalLogger = logger;
820
- }
821
-
822
- //#endregion
823
28
  //#region src/utils/error-handler.ts
824
29
  /**
825
30
  * Base error class for cdkd
@@ -1137,6 +342,20 @@ var RouteDiscoveryError = class RouteDiscoveryError extends CdkdError {
1137
342
  }
1138
343
  };
1139
344
  /**
345
+ * Signals a `cdkd local start-service` orchestration failure (Phase 2
346
+ * of #262 — `AWS::ECS::Service` emulator). Distinct from
347
+ * `LocalRunTaskError` because the service runner has its own lifecycle
348
+ * (long-running replica pool, restart-on-exit), so a failure inside it
349
+ * carries different operator semantics than a one-shot task failure.
350
+ */
351
+ var LocalStartServiceError = class LocalStartServiceError extends CdkdError {
352
+ constructor(message, cause) {
353
+ super(message, "LOCAL_START_SERVICE_ERROR", cause);
354
+ this.name = "LocalStartServiceError";
355
+ Object.setPrototypeOf(this, LocalStartServiceError.prototype);
356
+ }
357
+ };
358
+ /**
1140
359
  * Check if error is a cdkd error
1141
360
  */
1142
361
  function isCdkdError(error) {
@@ -2526,7 +1745,7 @@ async function resolveStateBucketWithDefaultAndSource(cliBucket, region) {
2526
1745
  logger.debug("No state bucket specified, resolving default from account...");
2527
1746
  const { GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
2528
1747
  const { S3Client } = await import("@aws-sdk/client-s3");
2529
- const { getAwsClients } = await import("./aws-clients-CuHRHcyW.js").then((n) => n.n);
1748
+ const { getAwsClients } = await import("./aws-clients-BF03Alpe.js").then((n) => n.n);
2530
1749
  const accountId = (await getAwsClients().sts.send(new GetCallerIdentityCommand({}))).Account;
2531
1750
  const newName = getDefaultStateBucketName(accountId);
2532
1751
  const legacyName = getLegacyStateBucketName(accountId, region);
@@ -2841,195 +2060,6 @@ var FileAssetPublisher = class {
2841
2060
  }
2842
2061
  };
2843
2062
 
2844
- //#endregion
2845
- //#region src/utils/docker-cmd.ts
2846
- /**
2847
- * Shared helpers for invoking the docker-compatible CLI binary across cdkd.
2848
- *
2849
- * Two parity decisions with `aws-cdk-cli`'s `cdk-assets-lib`:
2850
- * 1. `CDK_DOCKER` env var swaps the binary so podman / finch users can
2851
- * run cdkd without code changes (`CDK_DOCKER=podman cdkd deploy`).
2852
- * 2. `runDockerStreaming` uses streaming spawn rather than `execFile`'s
2853
- * buffered `maxBuffer` ceiling. BuildKit's progress output can run to
2854
- * tens of MB on multi-stage builds with `# syntax=docker/dockerfile:1`
2855
- * frontend downloads + heredoc / `RUN --mount=...` features; the 50 MB
2856
- * `execFile` ceiling cdkd used to set silently killed those builds
2857
- * with `ERR_CHILD_PROCESS_STDIO_MAXBUFFER`.
2858
- *
2859
- * Output handling: stdout/stderr are collected in memory unconditionally so
2860
- * `runDockerStreaming` can return them to the caller for error wrapping.
2861
- * When the logger is at debug level (i.e. the user passed `--verbose`),
2862
- * the chunks are ALSO mirrored to `process.stdout` / `process.stderr` so
2863
- * the user sees live build progress.
2864
- */
2865
- /**
2866
- * Return the docker-compatible CLI binary to invoke. Matches CDK CLI:
2867
- * `CDK_DOCKER` env var overrides the default `docker` so users on
2868
- * podman / finch / nerdctl can swap without changing cdkd code.
2869
- */
2870
- function getDockerCmd() {
2871
- const override = process.env["CDK_DOCKER"];
2872
- return override && override.length > 0 ? override : "docker";
2873
- }
2874
- /**
2875
- * Spawn a docker-compatible CLI binary (resolved via `getDockerCmd`) with
2876
- * streaming I/O. Collects stdout/stderr in memory and resolves with both
2877
- * on exit code 0; rejects with a `SpawnError` carrying both streams on any
2878
- * non-zero exit so the caller can wrap with its own error class without
2879
- * losing the upstream output.
2880
- *
2881
- * No `maxBuffer` ceiling: BuildKit progress output frequently exceeds the
2882
- * `child_process.execFile` default of 1 MB (cdkd previously bumped to 50 MB
2883
- * but BuildKit + frontend pulls can still exceed that on first-time builds).
2884
- */
2885
- async function runDockerStreaming(args, options = {}) {
2886
- return spawnStreaming(getDockerCmd(), args, options);
2887
- }
2888
- /**
2889
- * Generic streaming spawn — used by `runDockerStreaming` AND by the
2890
- * `executable` source mode in `docker-build.ts` (which runs an arbitrary
2891
- * user-supplied build command, not docker).
2892
- */
2893
- async function spawnStreaming(cmd, args, options = {}) {
2894
- const streamLive = options.streamLive ?? getLogger().getLevel() === "debug";
2895
- const env = options.env ? mergeEnv(options.env) : void 0;
2896
- return new Promise((resolve, reject) => {
2897
- const child = spawn(cmd, args, {
2898
- cwd: options.cwd,
2899
- env,
2900
- stdio: [
2901
- options.input ? "pipe" : "ignore",
2902
- "pipe",
2903
- "pipe"
2904
- ]
2905
- });
2906
- const stdoutChunks = [];
2907
- const stderrChunks = [];
2908
- child.stdout.on("data", (chunk) => {
2909
- stdoutChunks.push(chunk);
2910
- if (streamLive) process.stdout.write(chunk);
2911
- });
2912
- child.stderr.on("data", (chunk) => {
2913
- stderrChunks.push(chunk);
2914
- if (streamLive) process.stderr.write(chunk);
2915
- });
2916
- child.once("error", (err) => {
2917
- if (err.code === "ENOENT") {
2918
- const usingOverride = process.env["CDK_DOCKER"] === cmd && cmd !== "docker";
2919
- reject(/* @__PURE__ */ new Error(usingOverride ? `Failed to find and execute '${cmd}' (resolved via CDK_DOCKER). Install '${cmd}' or unset CDK_DOCKER to fall back to 'docker'.` : `Failed to find and execute '${cmd}'. Install Docker (or set the 'CDK_DOCKER' environment variable to a compatible binary such as podman / finch).`));
2920
- } else reject(err);
2921
- });
2922
- child.once("close", (code) => {
2923
- const stdout = Buffer.concat(stdoutChunks).toString("utf-8");
2924
- const stderr = Buffer.concat(stderrChunks).toString("utf-8");
2925
- if (code === 0) resolve({
2926
- stdout,
2927
- stderr
2928
- });
2929
- else {
2930
- const message = stderr.trim() || stdout.trim() || `${cmd} ${args[0] ?? ""} exited with code ${code}`;
2931
- const err = new Error(message);
2932
- err.stderr = stderr;
2933
- err.stdout = stdout;
2934
- err.exitCode = code;
2935
- reject(err);
2936
- }
2937
- });
2938
- if (options.input !== void 0) {
2939
- child.stdin.on("error", () => {});
2940
- child.stdin.write(options.input);
2941
- child.stdin.end();
2942
- }
2943
- });
2944
- }
2945
- /**
2946
- * Spawn a docker-compatible CLI binary (resolved via `getDockerCmd`) attached
2947
- * to the parent process's stdio so the user sees live output (`docker pull`
2948
- * layer progress, `docker login` interactive prompts that should never fire
2949
- * with `--password-stdin` but still safe to inherit, etc.). Resolves on exit
2950
- * code 0; rejects with a plain `Error` carrying the exit code on any non-zero
2951
- * exit, so the caller can wrap with its own error class.
2952
- *
2953
- * Differs from {@link runDockerStreaming} in two ways:
2954
- * 1. `stdio: 'inherit'` — output is NOT captured, so terminal control codes
2955
- * (color, progress bar overwrites) flow through unchanged. This is the
2956
- * load-bearing reason for the split: `docker pull`'s progress bars only
2957
- * animate properly when stdout is a real TTY connected to the parent.
2958
- * 2. No `input` / `streamLive` options — inherit-mode has nothing to
2959
- * capture and nothing to mirror.
2960
- *
2961
- * Used by the `--verbose`-mode `docker pull` plumbing in `docker-runner.ts`
2962
- * and `ecr-puller.ts` (visible layer progress). Non-verbose pulls go through
2963
- * {@link runDockerStreaming} so stderr can be folded into the error message.
2964
- */
2965
- async function runDockerForeground(args, options = {}) {
2966
- return spawnForeground(getDockerCmd(), args, options);
2967
- }
2968
- /**
2969
- * Foreground (stdio-inherit) spawn — the inherit-mode counterpart to
2970
- * {@link spawnStreaming}. Used by {@link runDockerForeground} for docker-CLI
2971
- * subprocesses.
2972
- *
2973
- * The ENOENT branch crafts a docker-specific install hint ("Install Docker
2974
- * (or set CDK_DOCKER ...)"), so non-docker callers reusing this helper
2975
- * would see a misleading error on missing-binary failures. Keep the binary
2976
- * docker-shaped, or update the ENOENT message before adding a non-docker
2977
- * call site.
2978
- */
2979
- async function spawnForeground(cmd, args, options = {}) {
2980
- const env = options.env ? mergeEnv(options.env) : void 0;
2981
- return new Promise((resolve, reject) => {
2982
- const child = spawn(cmd, args, {
2983
- cwd: options.cwd,
2984
- env,
2985
- stdio: "inherit"
2986
- });
2987
- child.once("error", (err) => {
2988
- if (err.code === "ENOENT") {
2989
- const usingOverride = process.env["CDK_DOCKER"] === cmd && cmd !== "docker";
2990
- reject(/* @__PURE__ */ new Error(usingOverride ? `Failed to find and execute '${cmd}' (resolved via CDK_DOCKER). Install '${cmd}' or unset CDK_DOCKER to fall back to 'docker'.` : `Failed to find and execute '${cmd}'. Install Docker (or set the 'CDK_DOCKER' environment variable to a compatible binary such as podman / finch).`));
2991
- } else reject(/* @__PURE__ */ new Error(`${cmd} failed: ${err.message}`));
2992
- });
2993
- child.once("close", (code) => {
2994
- if (code === 0) resolve();
2995
- else reject(/* @__PURE__ */ new Error(`${cmd} exited with code ${code}`));
2996
- });
2997
- });
2998
- }
2999
- /**
3000
- * Format the stderr from a failed `docker login` so the surfaced cdkd
3001
- * error gives the user an actionable workaround when the underlying
3002
- * failure is a credential-helper persistence bug (which has nothing to
3003
- * do with cdkd, AWS, or IAM perms — the docker CLI itself fails to
3004
- * save the auth token to the platform's credential store). The most
3005
- * common shape is `osxkeychain` on macOS rejecting an overwrite for
3006
- * an existing entry, but `wincred` (Windows), `pass` (Linux), and
3007
- * `secretservice` (Linux) hit the same class of `Error saving
3008
- * credentials` failure, so the rewritten message stays platform-
3009
- * agnostic — `docker logout <endpoint>` is the correct recovery on
3010
- * every backend.
3011
- *
3012
- * Detected docker / docker-credential-* output patterns:
3013
- * - `error storing credentials - err: exit status 1, out: \`The
3014
- * specified item already exists in the keychain.\`` (osxkeychain)
3015
- * - `Error saving credentials: ...` (any backend)
3016
- *
3017
- * Non-matching failures (genuine IAM / network / endpoint problems)
3018
- * pass through with just the stderr trimmed — the original message
3019
- * stays load-bearing for diagnosis.
3020
- */
3021
- function formatDockerLoginError(stderr, endpoint) {
3022
- const trimmed = stderr.trim();
3023
- if (trimmed.includes("already exists in the keychain") || trimmed.includes("Error saving credentials")) return `docker's credential helper (osxkeychain on macOS / wincred on Windows / pass / secretservice on Linux) failed to persist the ECR auth token. The "already exists in the keychain" / "Error saving credentials" output is a known docker-credential-helpers issue — unrelated to cdkd, AWS credentials, or IAM perms. Quick fix: run \`docker logout ${endpoint}\` to clear the stale entry, then retry the cdkd command. Permanent fix: edit ~/.docker/config.json and remove (or empty) the platform-specific "credsStore" entry (e.g. "osxkeychain" → "" or "desktop" on macOS Docker Desktop). Original docker stderr: ${trimmed}`;
3024
- return trimmed;
3025
- }
3026
- function mergeEnv(overrides) {
3027
- const merged = { ...process.env };
3028
- for (const [k, v] of Object.entries(overrides)) if (v === void 0) delete merged[k];
3029
- else merged[k] = v;
3030
- return merged;
3031
- }
3032
-
3033
2063
  //#endregion
3034
2064
  //#region src/assets/docker-build.ts
3035
2065
  /**
@@ -10176,5 +9206,5 @@ var DeployEngine = class {
10176
9206
  };
10177
9207
 
10178
9208
  //#endregion
10179
- export { DependencyError as $, AssetPublisher as A, getLegacyStateBucketName as B, applyRoleArnIfSet as C, generateResourceNameWithFallback as Ct, LockManager as D, TemplateParser as E, getDockerCmd as F, resolveStateBucketWithDefaultAndSource as G, resolveCaptureObservedState as H, runDockerForeground as I, clearBucketRegionCache as J, warnDeprecatedNoPrefixCliFlag as K, runDockerStreaming as L, WorkGraph as M, buildDockerImage as N, S3StateBackend as O, formatDockerLoginError as P, ConfigError as Q, Synthesizer as R, IntrinsicFunctionResolver as S, generateResourceName as St, DagBuilder as T, withStackName as Tt, resolveSkipPrefix as U, resolveApp as V, resolveStateBucketWithDefault as W, AssetError as X, resolveBucketRegion as Y, CdkdError as Z, normalizeAwsTagsToCfn as _, setLogger as _t, withRetry as a, ResourceUpdateNotSupportedError as at, CloudControlProvider as b, PATTERN_B_NAME_PROPERTIES as bt, cyan as c, StackTerminationProtectionError as ct, red as d, formatError as dt, LocalInvokeBuildError as et, yellow as f, isCdkdError as ft, matchesCdkPath as g, getLogger as gt, CDK_PATH_TAG as h, ConsoleLogger as ht, withResourceDeadline as i, ResourceTimeoutError as it, stringifyValue as j, shouldRetainResource as k, gray as l, StateError as lt, collectInlinePolicyNamesManagedBySiblings as m, withErrorHandling as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, PartialFailureError as nt, IMPLICIT_DELETE_DEPENDENCIES as o, RouteDiscoveryError as ot, IAMRoleProvider as p, normalizeAwsError as pt, AssemblyReader as q, DeployEngine as r, ProvisioningError as rt, bold as s, StackHasActiveImportsError as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, LockError as tt, green as u, SynthesisError as ut, resolveExplicitPhysicalId as v, runStackBuffered as vt, DiffCalculator as w, withSkipPrefix as wt, assertRegionMatch as x, PATTERN_B_RESOURCE_TYPES as xt, ProviderRegistry as y, getLiveRenderer as yt, getDefaultStateBucketName as z };
10180
- //# sourceMappingURL=deploy-engine-B-w4C_7O.js.map
9209
+ export { PartialFailureError as $, AssetPublisher as A, resolveStateBucketWithDefault as B, applyRoleArnIfSet as C, LockManager as D, TemplateParser as E, getDefaultStateBucketName as F, resolveBucketRegion as G, warnDeprecatedNoPrefixCliFlag as H, getLegacyStateBucketName as I, ConfigError as J, AssetError as K, resolveApp as L, WorkGraph as M, buildDockerImage as N, S3StateBackend as O, Synthesizer as P, LockError as Q, resolveCaptureObservedState as R, IntrinsicFunctionResolver as S, DagBuilder as T, AssemblyReader as U, resolveStateBucketWithDefaultAndSource as V, clearBucketRegionCache as W, LocalInvokeBuildError as X, DependencyError as Y, LocalStartServiceError as Z, normalizeAwsTagsToCfn as _, withRetry as a, StackTerminationProtectionError as at, CloudControlProvider as b, cyan as c, formatError as ct, red as d, withErrorHandling as dt, ProvisioningError as et, yellow as f, matchesCdkPath as g, CDK_PATH_TAG as h, withResourceDeadline as i, StackHasActiveImportsError as it, stringifyValue as j, shouldRetainResource as k, gray as l, isCdkdError as lt, collectInlinePolicyNamesManagedBySiblings as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, ResourceUpdateNotSupportedError as nt, IMPLICIT_DELETE_DEPENDENCIES as o, StateError as ot, IAMRoleProvider as p, CdkdError as q, DeployEngine as r, RouteDiscoveryError as rt, bold as s, SynthesisError as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, ResourceTimeoutError as tt, green as u, normalizeAwsError as ut, resolveExplicitPhysicalId as v, DiffCalculator as w, assertRegionMatch as x, ProviderRegistry as y, resolveSkipPrefix as z };
9210
+ //# sourceMappingURL=deploy-engine-Dn7oV5rA.js.map