@go-to-k/cdkd 0.4.0 → 0.5.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.
- package/README.md +11 -0
- package/dist/cli.js +263 -142
- package/dist/cli.js.map +4 -4
- package/dist/go-to-k-cdkd-0.5.0.tgz +0 -0
- package/dist/index.js +52 -48
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.4.0.tgz +0 -0
package/README.md
CHANGED
|
@@ -342,6 +342,9 @@ alias cdkd="node $(pwd)/dist/cli.js"
|
|
|
342
342
|
# Bootstrap (creates S3 state bucket - only needed once per account/region)
|
|
343
343
|
cdkd bootstrap
|
|
344
344
|
|
|
345
|
+
# List stacks in the CDK app
|
|
346
|
+
cdkd list
|
|
347
|
+
|
|
345
348
|
# Deploy your CDK app
|
|
346
349
|
cdkd deploy
|
|
347
350
|
|
|
@@ -367,6 +370,14 @@ cdkd bootstrap \
|
|
|
367
370
|
# Synthesize only
|
|
368
371
|
cdkd synth --app "npx ts-node app.ts"
|
|
369
372
|
|
|
373
|
+
# List all stacks in the CDK app (alias: ls)
|
|
374
|
+
cdkd list
|
|
375
|
+
cdkd ls
|
|
376
|
+
cdkd list --long # YAML records with id/name/environment
|
|
377
|
+
cdkd list --long --json # same, but JSON
|
|
378
|
+
cdkd list --show-dependencies # id + dependency list per stack
|
|
379
|
+
cdkd list 'MyStage/*' # filter by display path (CDK CLI parity)
|
|
380
|
+
|
|
370
381
|
# Deploy from a pre-synthesized cloud assembly directory
|
|
371
382
|
cdkd deploy --app cdk.out
|
|
372
383
|
|
package/dist/cli.js
CHANGED
|
@@ -447,7 +447,7 @@ var init_aws_clients = __esm({
|
|
|
447
447
|
});
|
|
448
448
|
|
|
449
449
|
// src/cli/index.ts
|
|
450
|
-
import { Command as
|
|
450
|
+
import { Command as Command9 } from "commander";
|
|
451
451
|
|
|
452
452
|
// src/cli/commands/bootstrap.ts
|
|
453
453
|
import { Command } from "commander";
|
|
@@ -2357,6 +2357,62 @@ function setsEqual(a, b) {
|
|
|
2357
2357
|
return true;
|
|
2358
2358
|
}
|
|
2359
2359
|
|
|
2360
|
+
// src/utils/yaml.ts
|
|
2361
|
+
function toYaml(obj, indent = 0) {
|
|
2362
|
+
const prefix = " ".repeat(indent);
|
|
2363
|
+
if (obj === null || obj === void 0)
|
|
2364
|
+
return "null\n";
|
|
2365
|
+
if (typeof obj === "boolean")
|
|
2366
|
+
return `${obj}
|
|
2367
|
+
`;
|
|
2368
|
+
if (typeof obj === "number")
|
|
2369
|
+
return `"${obj}"
|
|
2370
|
+
`;
|
|
2371
|
+
if (typeof obj === "string") {
|
|
2372
|
+
if (obj.includes("\n")) {
|
|
2373
|
+
return `'${obj.replace(/'/g, "''")}'
|
|
2374
|
+
`;
|
|
2375
|
+
}
|
|
2376
|
+
if (obj.startsWith("{") || obj.startsWith("[") || obj.startsWith('"')) {
|
|
2377
|
+
return `'${obj.replace(/'/g, "''")}'
|
|
2378
|
+
`;
|
|
2379
|
+
}
|
|
2380
|
+
if (obj.includes("#") || obj === "" || obj === "true" || obj === "false" || obj === "null") {
|
|
2381
|
+
return `"${obj}"
|
|
2382
|
+
`;
|
|
2383
|
+
}
|
|
2384
|
+
return `${obj}
|
|
2385
|
+
`;
|
|
2386
|
+
}
|
|
2387
|
+
if (Array.isArray(obj)) {
|
|
2388
|
+
if (obj.length === 0)
|
|
2389
|
+
return "[]\n";
|
|
2390
|
+
let result = "\n";
|
|
2391
|
+
for (const item of obj) {
|
|
2392
|
+
const value = toYaml(item, indent + 1).trimStart();
|
|
2393
|
+
result += `${prefix}- ${value}`;
|
|
2394
|
+
}
|
|
2395
|
+
return result;
|
|
2396
|
+
}
|
|
2397
|
+
if (typeof obj === "object") {
|
|
2398
|
+
const entries = Object.entries(obj);
|
|
2399
|
+
if (entries.length === 0)
|
|
2400
|
+
return "{}\n";
|
|
2401
|
+
let result = "\n";
|
|
2402
|
+
for (const [key, value] of entries) {
|
|
2403
|
+
const safeKey = key.includes(" ") ? `"${key}"` : key;
|
|
2404
|
+
if (typeof value === "object" && value !== null) {
|
|
2405
|
+
result += `${prefix}${safeKey}:${toYaml(value, indent + 1)}`;
|
|
2406
|
+
} else {
|
|
2407
|
+
result += `${prefix}${safeKey}: ${toYaml(value, indent + 1).trimStart()}`;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
return result;
|
|
2411
|
+
}
|
|
2412
|
+
return `${String(obj)}
|
|
2413
|
+
`;
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2360
2416
|
// src/cli/commands/synth.ts
|
|
2361
2417
|
async function synthCommand(options) {
|
|
2362
2418
|
const logger = getLogger();
|
|
@@ -2407,68 +2463,158 @@ async function synthCommand(options) {
|
|
|
2407
2463
|
logger.info(`
|
|
2408
2464
|
Output: ${assemblyDir}`);
|
|
2409
2465
|
}
|
|
2410
|
-
function
|
|
2411
|
-
const
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
return `"${obj}"
|
|
2431
|
-
`;
|
|
2466
|
+
function createSynthCommand() {
|
|
2467
|
+
const cmd = new Command2("synth").description("Synthesize CDK app to CloudFormation template").action(withErrorHandling(synthCommand));
|
|
2468
|
+
[...commonOptions, ...appOptions, ...contextOptions].forEach((opt) => cmd.addOption(opt));
|
|
2469
|
+
return cmd;
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
// src/cli/commands/list.ts
|
|
2473
|
+
import { Command as Command3 } from "commander";
|
|
2474
|
+
|
|
2475
|
+
// src/cli/stack-matcher.ts
|
|
2476
|
+
function matchStacks(stacks, patterns) {
|
|
2477
|
+
if (patterns.length === 0)
|
|
2478
|
+
return [];
|
|
2479
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2480
|
+
const result = [];
|
|
2481
|
+
for (const stack of stacks) {
|
|
2482
|
+
const matched = patterns.some((pattern) => stackMatchesPattern(stack, pattern));
|
|
2483
|
+
if (matched && !seen.has(stack.stackName)) {
|
|
2484
|
+
seen.add(stack.stackName);
|
|
2485
|
+
result.push(stack);
|
|
2432
2486
|
}
|
|
2433
|
-
return `${obj}
|
|
2434
|
-
`;
|
|
2435
2487
|
}
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2488
|
+
return result;
|
|
2489
|
+
}
|
|
2490
|
+
function describeStack(stack) {
|
|
2491
|
+
if (stack.displayName && stack.displayName !== stack.stackName) {
|
|
2492
|
+
return `${stack.stackName} (${stack.displayName})`;
|
|
2493
|
+
}
|
|
2494
|
+
return stack.stackName;
|
|
2495
|
+
}
|
|
2496
|
+
function stackMatchesPattern(stack, pattern) {
|
|
2497
|
+
const target = pattern.includes("/") ? stack.displayName ?? stack.stackName : stack.stackName;
|
|
2498
|
+
if (pattern.includes("*")) {
|
|
2499
|
+
const regex = new RegExp("^" + pattern.replace(/\*/g, ".*") + "$");
|
|
2500
|
+
return regex.test(target);
|
|
2501
|
+
}
|
|
2502
|
+
return target === pattern;
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// src/cli/commands/list.ts
|
|
2506
|
+
function sortByDependency(stacks) {
|
|
2507
|
+
const byName = new Map(stacks.map((s) => [s.stackName, s]));
|
|
2508
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2509
|
+
const result = [];
|
|
2510
|
+
const visit = (stack, ancestors) => {
|
|
2511
|
+
if (visited.has(stack.stackName))
|
|
2512
|
+
return;
|
|
2513
|
+
if (ancestors.has(stack.stackName))
|
|
2514
|
+
return;
|
|
2515
|
+
ancestors.add(stack.stackName);
|
|
2516
|
+
for (const depName of stack.dependencyNames) {
|
|
2517
|
+
const dep = byName.get(depName);
|
|
2518
|
+
if (dep)
|
|
2519
|
+
visit(dep, ancestors);
|
|
2520
|
+
}
|
|
2521
|
+
ancestors.delete(stack.stackName);
|
|
2522
|
+
if (!visited.has(stack.stackName)) {
|
|
2523
|
+
visited.add(stack.stackName);
|
|
2524
|
+
result.push(stack);
|
|
2443
2525
|
}
|
|
2444
|
-
|
|
2526
|
+
};
|
|
2527
|
+
for (const stack of stacks) {
|
|
2528
|
+
visit(stack, /* @__PURE__ */ new Set());
|
|
2445
2529
|
}
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
} else {
|
|
2456
|
-
result += `${prefix}${safeKey}: ${toYaml(value, indent + 1).trimStart()}`;
|
|
2457
|
-
}
|
|
2530
|
+
return result;
|
|
2531
|
+
}
|
|
2532
|
+
function toLongRecord(stack, includeDeps) {
|
|
2533
|
+
const record = {
|
|
2534
|
+
id: stack.displayName,
|
|
2535
|
+
name: stack.stackName,
|
|
2536
|
+
environment: {
|
|
2537
|
+
account: stack.account ?? "unknown-account",
|
|
2538
|
+
region: stack.region ?? "unknown-region"
|
|
2458
2539
|
}
|
|
2459
|
-
|
|
2540
|
+
};
|
|
2541
|
+
if (includeDeps) {
|
|
2542
|
+
record.dependencies = [...stack.dependencyNames];
|
|
2460
2543
|
}
|
|
2461
|
-
return
|
|
2462
|
-
`;
|
|
2544
|
+
return record;
|
|
2463
2545
|
}
|
|
2464
|
-
function
|
|
2465
|
-
const
|
|
2546
|
+
async function listCommand(patterns, options) {
|
|
2547
|
+
const logger = getLogger();
|
|
2548
|
+
if (options.verbose) {
|
|
2549
|
+
logger.setLevel("debug");
|
|
2550
|
+
}
|
|
2551
|
+
const app = resolveApp(options.app);
|
|
2552
|
+
if (!app) {
|
|
2553
|
+
throw new Error(
|
|
2554
|
+
'No app command specified. Use --app, set CDKD_APP env var, or add "app" to cdk.json'
|
|
2555
|
+
);
|
|
2556
|
+
}
|
|
2557
|
+
logger.debug("Listing stacks...");
|
|
2558
|
+
logger.debug("App command:", app);
|
|
2559
|
+
const synthesizer = new Synthesizer();
|
|
2560
|
+
const context = parseContextOptions(options.context);
|
|
2561
|
+
const synthOptions = {
|
|
2562
|
+
app,
|
|
2563
|
+
output: options.output,
|
|
2564
|
+
...options.region && { region: options.region },
|
|
2565
|
+
...options.profile && { profile: options.profile },
|
|
2566
|
+
...Object.keys(context).length > 0 && { context }
|
|
2567
|
+
};
|
|
2568
|
+
const result = await synthesizer.synthesize(synthOptions);
|
|
2569
|
+
const allStacks = result.stacks;
|
|
2570
|
+
if (allStacks.length === 0) {
|
|
2571
|
+
throw new Error("No stacks found in assembly");
|
|
2572
|
+
}
|
|
2573
|
+
const selected = patterns.length > 0 ? matchStacks(allStacks, patterns) : allStacks;
|
|
2574
|
+
if (selected.length === 0) {
|
|
2575
|
+
throw new Error(
|
|
2576
|
+
`No stacks matching ${patterns.join(", ")} found in assembly. Available: ${allStacks.map(describeStack).join(", ")}`
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
2579
|
+
const sorted = sortByDependency(selected);
|
|
2580
|
+
if (options.long) {
|
|
2581
|
+
const records = sorted.map((s) => toLongRecord(s, options.showDependencies));
|
|
2582
|
+
emitStructured(records, options.json);
|
|
2583
|
+
return;
|
|
2584
|
+
}
|
|
2585
|
+
if (options.showDependencies) {
|
|
2586
|
+
const records = sorted.map((s) => ({
|
|
2587
|
+
id: s.displayName,
|
|
2588
|
+
dependencies: [...s.dependencyNames]
|
|
2589
|
+
}));
|
|
2590
|
+
emitStructured(records, options.json);
|
|
2591
|
+
return;
|
|
2592
|
+
}
|
|
2593
|
+
for (const stack of sorted) {
|
|
2594
|
+
process.stdout.write(`${stack.displayName}
|
|
2595
|
+
`);
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
function emitStructured(payload, asJson) {
|
|
2599
|
+
if (asJson) {
|
|
2600
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}
|
|
2601
|
+
`);
|
|
2602
|
+
return;
|
|
2603
|
+
}
|
|
2604
|
+
const yaml = toYaml(payload).replace(/^\n/, "");
|
|
2605
|
+
process.stdout.write(yaml);
|
|
2606
|
+
}
|
|
2607
|
+
function createListCommand() {
|
|
2608
|
+
const cmd = new Command3("list").alias("ls").description("List all stacks in the CDK app").argument(
|
|
2609
|
+
"[stacks...]",
|
|
2610
|
+
"Stack name pattern(s). Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*')."
|
|
2611
|
+
).option("-l, --long", "Display environment information for each stack", false).option("-d, --show-dependencies", "Display stack dependency information for each stack", false).option("--json", "Output as JSON instead of YAML for --long / --show-dependencies", false).action(withErrorHandling(listCommand));
|
|
2466
2612
|
[...commonOptions, ...appOptions, ...contextOptions].forEach((opt) => cmd.addOption(opt));
|
|
2467
2613
|
return cmd;
|
|
2468
2614
|
}
|
|
2469
2615
|
|
|
2470
2616
|
// src/cli/commands/deploy.ts
|
|
2471
|
-
import { Command as
|
|
2617
|
+
import { Command as Command4 } from "commander";
|
|
2472
2618
|
|
|
2473
2619
|
// src/assets/asset-publisher.ts
|
|
2474
2620
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
@@ -25979,6 +26125,57 @@ var IMPLICIT_DELETE_DEPENDENCIES = {
|
|
|
25979
26125
|
]
|
|
25980
26126
|
};
|
|
25981
26127
|
|
|
26128
|
+
// src/deployment/retryable-errors.ts
|
|
26129
|
+
var RETRYABLE_ERROR_MESSAGE_PATTERNS = [
|
|
26130
|
+
// IAM propagation
|
|
26131
|
+
"cannot be assumed",
|
|
26132
|
+
"role defined for the function",
|
|
26133
|
+
"not authorized to perform",
|
|
26134
|
+
"execution role",
|
|
26135
|
+
"trust policy",
|
|
26136
|
+
"Role validation failed",
|
|
26137
|
+
"does not have required permissions",
|
|
26138
|
+
"Trusted Entity",
|
|
26139
|
+
"currently in the following state: Pending",
|
|
26140
|
+
// DELETE dependency ordering (parallel deletion race conditions)
|
|
26141
|
+
"has dependencies and cannot be deleted",
|
|
26142
|
+
"can't be deleted since it has",
|
|
26143
|
+
"DependencyViolation",
|
|
26144
|
+
// AWS eventual consistency (dependency just created but not yet visible)
|
|
26145
|
+
// e.g., RDS DBCluster referencing a just-created DBSubnetGroup
|
|
26146
|
+
"does not exist",
|
|
26147
|
+
// AppSync schema is being created asynchronously
|
|
26148
|
+
"Schema is currently being altered",
|
|
26149
|
+
// IAM principal not yet propagated to S3 bucket policy
|
|
26150
|
+
"Invalid principal in policy",
|
|
26151
|
+
// S3 bucket creation/deletion still in progress
|
|
26152
|
+
"conflicting conditional operation",
|
|
26153
|
+
// Secrets Manager: ForceDeleteWithoutRecovery may take a moment to propagate
|
|
26154
|
+
"scheduled for deletion",
|
|
26155
|
+
// DynamoDB Streams / Kinesis: IAM role not yet propagated
|
|
26156
|
+
"Cannot access stream",
|
|
26157
|
+
"Please ensure the role can perform",
|
|
26158
|
+
// KMS: IAM role not yet propagated for CreateGrant
|
|
26159
|
+
"KMS key is invalid for CreateGrant",
|
|
26160
|
+
// CloudWatch Logs SubscriptionFilter: Kinesis stream eventual consistency
|
|
26161
|
+
// or SubscriptionFilter role propagation. CW Logs probes the destination
|
|
26162
|
+
// by delivering a test message; if the stream is freshly ACTIVE or the
|
|
26163
|
+
// assumed role hasn't propagated, the probe fails with "Invalid request".
|
|
26164
|
+
"Could not deliver test message"
|
|
26165
|
+
];
|
|
26166
|
+
var RETRYABLE_HTTP_STATUS_CODES = /* @__PURE__ */ new Set([429, 503]);
|
|
26167
|
+
function isRetryableTransientError(error, message) {
|
|
26168
|
+
const metadata = error.$metadata;
|
|
26169
|
+
const statusCode = metadata?.httpStatusCode;
|
|
26170
|
+
if (statusCode !== void 0 && RETRYABLE_HTTP_STATUS_CODES.has(statusCode))
|
|
26171
|
+
return true;
|
|
26172
|
+
const cause = error.cause;
|
|
26173
|
+
const causeStatus = cause?.$metadata?.httpStatusCode;
|
|
26174
|
+
if (causeStatus !== void 0 && RETRYABLE_HTTP_STATUS_CODES.has(causeStatus))
|
|
26175
|
+
return true;
|
|
26176
|
+
return RETRYABLE_ERROR_MESSAGE_PATTERNS.some((p) => message.includes(p));
|
|
26177
|
+
}
|
|
26178
|
+
|
|
25982
26179
|
// src/deployment/deploy-engine.ts
|
|
25983
26180
|
var InterruptedError = class extends Error {
|
|
25984
26181
|
constructor() {
|
|
@@ -26975,7 +27172,7 @@ var DeployEngine = class {
|
|
|
26975
27172
|
} catch (error) {
|
|
26976
27173
|
lastError = error;
|
|
26977
27174
|
const message = error instanceof Error ? error.message : String(error);
|
|
26978
|
-
const isRetryable =
|
|
27175
|
+
const isRetryable = isRetryableTransientError(error, message);
|
|
26979
27176
|
if (!isRetryable || attempt >= maxRetries) {
|
|
26980
27177
|
throw error;
|
|
26981
27178
|
}
|
|
@@ -26992,53 +27189,6 @@ var DeployEngine = class {
|
|
|
26992
27189
|
}
|
|
26993
27190
|
throw lastError;
|
|
26994
27191
|
}
|
|
26995
|
-
/**
|
|
26996
|
-
* Determine if an error is retryable (transient).
|
|
26997
|
-
* Checks HTTP status codes (429 throttle, 503 unavailable)
|
|
26998
|
-
* and IAM propagation delay message patterns.
|
|
26999
|
-
*/
|
|
27000
|
-
isRetryableError(error, message) {
|
|
27001
|
-
const metadata = error.$metadata;
|
|
27002
|
-
const statusCode = metadata?.httpStatusCode;
|
|
27003
|
-
if (statusCode === 429 || statusCode === 503)
|
|
27004
|
-
return true;
|
|
27005
|
-
const cause = error.cause;
|
|
27006
|
-
const causeStatus = cause?.$metadata?.httpStatusCode;
|
|
27007
|
-
if (causeStatus === 429 || causeStatus === 503)
|
|
27008
|
-
return true;
|
|
27009
|
-
const retryablePatterns = [
|
|
27010
|
-
"cannot be assumed",
|
|
27011
|
-
"role defined for the function",
|
|
27012
|
-
"not authorized to perform",
|
|
27013
|
-
"execution role",
|
|
27014
|
-
"trust policy",
|
|
27015
|
-
"Role validation failed",
|
|
27016
|
-
"does not have required permissions",
|
|
27017
|
-
"Trusted Entity",
|
|
27018
|
-
"currently in the following state: Pending",
|
|
27019
|
-
// DELETE dependency ordering (parallel deletion race conditions)
|
|
27020
|
-
"has dependencies and cannot be deleted",
|
|
27021
|
-
"can't be deleted since it has",
|
|
27022
|
-
"DependencyViolation",
|
|
27023
|
-
// AWS eventual consistency (dependency just created but not yet visible)
|
|
27024
|
-
// e.g., RDS DBCluster referencing a just-created DBSubnetGroup
|
|
27025
|
-
"does not exist",
|
|
27026
|
-
// AppSync schema is being created asynchronously
|
|
27027
|
-
"Schema is currently being altered",
|
|
27028
|
-
// IAM principal not yet propagated to S3 bucket policy
|
|
27029
|
-
"Invalid principal in policy",
|
|
27030
|
-
// S3 bucket creation/deletion still in progress
|
|
27031
|
-
"conflicting conditional operation",
|
|
27032
|
-
// Secrets Manager: ForceDeleteWithoutRecovery may take a moment to propagate
|
|
27033
|
-
"scheduled for deletion",
|
|
27034
|
-
// DynamoDB Streams / Kinesis: IAM role not yet propagated
|
|
27035
|
-
"Cannot access stream",
|
|
27036
|
-
"Please ensure the role can perform",
|
|
27037
|
-
// KMS: IAM role not yet propagated for CreateGrant
|
|
27038
|
-
"KMS key is invalid for CreateGrant"
|
|
27039
|
-
];
|
|
27040
|
-
return retryablePatterns.some((p) => message.includes(p));
|
|
27041
|
-
}
|
|
27042
27192
|
/**
|
|
27043
27193
|
* Resolve stack outputs from template and resource attributes
|
|
27044
27194
|
*
|
|
@@ -27078,38 +27228,6 @@ var DeployEngine = class {
|
|
|
27078
27228
|
|
|
27079
27229
|
// src/cli/commands/deploy.ts
|
|
27080
27230
|
init_aws_clients();
|
|
27081
|
-
|
|
27082
|
-
// src/cli/stack-matcher.ts
|
|
27083
|
-
function matchStacks(stacks, patterns) {
|
|
27084
|
-
if (patterns.length === 0)
|
|
27085
|
-
return [];
|
|
27086
|
-
const seen = /* @__PURE__ */ new Set();
|
|
27087
|
-
const result = [];
|
|
27088
|
-
for (const stack of stacks) {
|
|
27089
|
-
const matched = patterns.some((pattern) => stackMatchesPattern(stack, pattern));
|
|
27090
|
-
if (matched && !seen.has(stack.stackName)) {
|
|
27091
|
-
seen.add(stack.stackName);
|
|
27092
|
-
result.push(stack);
|
|
27093
|
-
}
|
|
27094
|
-
}
|
|
27095
|
-
return result;
|
|
27096
|
-
}
|
|
27097
|
-
function describeStack(stack) {
|
|
27098
|
-
if (stack.displayName && stack.displayName !== stack.stackName) {
|
|
27099
|
-
return `${stack.stackName} (${stack.displayName})`;
|
|
27100
|
-
}
|
|
27101
|
-
return stack.stackName;
|
|
27102
|
-
}
|
|
27103
|
-
function stackMatchesPattern(stack, pattern) {
|
|
27104
|
-
const target = pattern.includes("/") ? stack.displayName ?? stack.stackName : stack.stackName;
|
|
27105
|
-
if (pattern.includes("*")) {
|
|
27106
|
-
const regex = new RegExp("^" + pattern.replace(/\*/g, ".*") + "$");
|
|
27107
|
-
return regex.test(target);
|
|
27108
|
-
}
|
|
27109
|
-
return target === pattern;
|
|
27110
|
-
}
|
|
27111
|
-
|
|
27112
|
-
// src/cli/commands/deploy.ts
|
|
27113
27231
|
async function deployCommand(stacks, options) {
|
|
27114
27232
|
const logger = getLogger();
|
|
27115
27233
|
if (options.verbose) {
|
|
@@ -27343,7 +27461,7 @@ Deploying stack: ${stackInfo.stackName}${stackRegion !== baseRegion ? ` (region:
|
|
|
27343
27461
|
}
|
|
27344
27462
|
}
|
|
27345
27463
|
function createDeployCommand() {
|
|
27346
|
-
const cmd = new
|
|
27464
|
+
const cmd = new Command4("deploy").description("Deploy CDK app using SDK/Cloud Control API").argument(
|
|
27347
27465
|
"[stacks...]",
|
|
27348
27466
|
"Stack name(s) to deploy. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*')."
|
|
27349
27467
|
).option("--all", "Deploy all stacks", false).action(withErrorHandling(deployCommand));
|
|
@@ -27359,7 +27477,7 @@ function createDeployCommand() {
|
|
|
27359
27477
|
}
|
|
27360
27478
|
|
|
27361
27479
|
// src/cli/commands/diff.ts
|
|
27362
|
-
import { Command as
|
|
27480
|
+
import { Command as Command5 } from "commander";
|
|
27363
27481
|
init_aws_clients();
|
|
27364
27482
|
var INTRINSIC_KEYS = /* @__PURE__ */ new Set([
|
|
27365
27483
|
"Ref",
|
|
@@ -27557,7 +27675,7 @@ ${createCount} to create, ${updateCount} to update, ${deleteCount} to delete`);
|
|
|
27557
27675
|
}
|
|
27558
27676
|
}
|
|
27559
27677
|
function createDiffCommand() {
|
|
27560
|
-
const cmd = new
|
|
27678
|
+
const cmd = new Command5("diff").description("Show difference between current state and desired state").argument(
|
|
27561
27679
|
"[stacks...]",
|
|
27562
27680
|
"Stack name(s) to diff. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*')."
|
|
27563
27681
|
).option("--all", "Diff all stacks", false).action(withErrorHandling(diffCommand));
|
|
@@ -27568,7 +27686,7 @@ function createDiffCommand() {
|
|
|
27568
27686
|
}
|
|
27569
27687
|
|
|
27570
27688
|
// src/cli/commands/destroy.ts
|
|
27571
|
-
import { Command as
|
|
27689
|
+
import { Command as Command6 } from "commander";
|
|
27572
27690
|
init_aws_clients();
|
|
27573
27691
|
import * as readline from "node:readline/promises";
|
|
27574
27692
|
async function destroyCommand(stackArgs, options) {
|
|
@@ -27850,7 +27968,7 @@ Acquiring lock for stack ${stackName}...`);
|
|
|
27850
27968
|
}
|
|
27851
27969
|
}
|
|
27852
27970
|
function createDestroyCommand() {
|
|
27853
|
-
const cmd = new
|
|
27971
|
+
const cmd = new Command6("destroy").description("Destroy all resources in the stack").argument(
|
|
27854
27972
|
"[stacks...]",
|
|
27855
27973
|
"Stack name(s) to destroy. Accepts physical CloudFormation names (e.g. 'MyStage-Api') or CDK display paths (e.g. 'MyStage/Api'). Supports wildcards (e.g. 'MyStage/*')."
|
|
27856
27974
|
).option("--all", "Destroy all stacks", false).action(withErrorHandling(destroyCommand));
|
|
@@ -27866,7 +27984,7 @@ function createDestroyCommand() {
|
|
|
27866
27984
|
}
|
|
27867
27985
|
|
|
27868
27986
|
// src/cli/commands/publish-assets.ts
|
|
27869
|
-
import { Option as Option2, Command as
|
|
27987
|
+
import { Option as Option2, Command as Command7 } from "commander";
|
|
27870
27988
|
async function publishAssetsCommand(options) {
|
|
27871
27989
|
const logger = getLogger();
|
|
27872
27990
|
if (options.verbose) {
|
|
@@ -27884,7 +28002,7 @@ async function publishAssetsCommand(options) {
|
|
|
27884
28002
|
logger.info("\u2705 Asset publishing complete");
|
|
27885
28003
|
}
|
|
27886
28004
|
function createPublishAssetsCommand() {
|
|
27887
|
-
const cmd = new
|
|
28005
|
+
const cmd = new Command7("publish-assets").description("Publish assets to S3/ECR from asset manifest").requiredOption("--path <path>", "Path to asset manifest file or directory").addOption(
|
|
27888
28006
|
new Option2(
|
|
27889
28007
|
"--asset-publish-concurrency <number>",
|
|
27890
28008
|
"Maximum concurrent asset publish operations"
|
|
@@ -27897,7 +28015,7 @@ function createPublishAssetsCommand() {
|
|
|
27897
28015
|
}
|
|
27898
28016
|
|
|
27899
28017
|
// src/cli/commands/force-unlock.ts
|
|
27900
|
-
import { Command as
|
|
28018
|
+
import { Command as Command8 } from "commander";
|
|
27901
28019
|
init_aws_clients();
|
|
27902
28020
|
async function forceUnlockCommand(stackArgs, options) {
|
|
27903
28021
|
const logger = getLogger();
|
|
@@ -27940,7 +28058,7 @@ async function forceUnlockCommand(stackArgs, options) {
|
|
|
27940
28058
|
}
|
|
27941
28059
|
}
|
|
27942
28060
|
function createForceUnlockCommand() {
|
|
27943
|
-
const cmd = new
|
|
28061
|
+
const cmd = new Command8("force-unlock").description("Force-release a stale lock on a stack").argument("[stacks...]", "Stack name(s) to unlock").action(withErrorHandling(forceUnlockCommand));
|
|
27944
28062
|
[...commonOptions, ...stateOptions, ...stackOptions].forEach((opt) => cmd.addOption(opt));
|
|
27945
28063
|
return cmd;
|
|
27946
28064
|
}
|
|
@@ -27949,6 +28067,8 @@ function createForceUnlockCommand() {
|
|
|
27949
28067
|
var SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
27950
28068
|
"bootstrap",
|
|
27951
28069
|
"synth",
|
|
28070
|
+
"list",
|
|
28071
|
+
"ls",
|
|
27952
28072
|
"deploy",
|
|
27953
28073
|
"diff",
|
|
27954
28074
|
"destroy",
|
|
@@ -27966,10 +28086,11 @@ function reorderArgs(argv) {
|
|
|
27966
28086
|
return [...prefix, ...cmdAndAfter, ...beforeCmd];
|
|
27967
28087
|
}
|
|
27968
28088
|
async function main() {
|
|
27969
|
-
const program = new
|
|
27970
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
28089
|
+
const program = new Command9();
|
|
28090
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.5.0");
|
|
27971
28091
|
program.addCommand(createBootstrapCommand());
|
|
27972
28092
|
program.addCommand(createSynthCommand());
|
|
28093
|
+
program.addCommand(createListCommand());
|
|
27973
28094
|
program.addCommand(createDeployCommand());
|
|
27974
28095
|
program.addCommand(createDiffCommand());
|
|
27975
28096
|
program.addCommand(createDestroyCommand());
|