@go-to-k/cdkd 0.285.14 → 0.285.16
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/dist/{asg-provider-BvIH9Ivw.js → asg-provider-DoP-32eU.js} +2 -2
- package/dist/{asg-provider-BvIH9Ivw.js.map → asg-provider-DoP-32eU.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-CA50haPO.js → deploy-engine-DuFUy9D0.js} +446 -76
- package/dist/deploy-engine-DuFUy9D0.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-BSanOkkV.js → program-C-xfsrSP.js} +112 -140
- package/dist/{program-BSanOkkV.js.map → program-C-xfsrSP.js.map} +1 -1
- package/dist/{version-DP5kGlzj.js → version-C_ZRHikq.js} +2 -2
- package/dist/{version-DP5kGlzj.js.map → version-C_ZRHikq.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-CA50haPO.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as endCommandInterruptScope, $n as resolveCaptureObservedState, $r as isThrottlingError, $t as maskSecretsInText, A as bold, An as getBootstrapMarkerKey, Ar as DeployCancelledError, At as classifyReplaySecretRegion, B as secretBearingStateKeyWarning, Bn as formatDockerLoginError, Br as ProvisioningError, Bt as describeTypeWithThrottleRetry, C as unsupportedFinalSnapshotError, Cn as rewriteTemplateAssetReferences, Cr as resetAwsClients, Ct as configBooleanRefusal, D as isStatefulRecreateTargetSync, Dn as BOOTSTRAP_MARKER_PREFIX, Dt as requireConfigArray, E as MULTI_REGION_RECREATE_BLOCKED_TYPES, En as AssetModeResolver, Er as CdkdError, Et as replayWarn, F as yellow, Fn as validateContainerRepoName, Fr as LocalStartServiceError, Ft as s3BucketRegionalDomainName, G as clearOnUpdateRemoval, Gn as AssetManifestLoader, Gt as STATE_SOURCED_READBACK_RULES, H as getCurrentResourceSecrets, Hn as partitionSensitiveEnv, Hr as ResourceUpdateNotSupportedError, Ht as DagBuilder, I as collectDeclaredOutputNames, In as buildDenyExternalAccessPolicy, It as s3BucketWebsiteUrl, J as findSilentDropProperties, Jn as synthesisStatusMessage, Jt as createSecretMasker, K as ProviderRegistry, Kn as getDockerImageBySourceHash, Kt as TEMPLATE_SOURCED_RULES, L as collectPublishedOutputNames, Ln as describeAwsFailure, Lr as MissingCdkCliError, Lt as applyRoleArnIfSet, M as gray, Mn as parseBootstrapMarker, Mr as IntrinsicResolutionRefusalError, Mt as s3BucketArn, N as green, Nn as readBootstrapMarkerBody, Nr as LocalInvokeBuildError$1, Nt as s3BucketDomainName, O as renderStatefulReason, On as assertAssetBucketRegion, Or as CrossAccountSecretRefusalError, Ot as requireConfigObject, P as red, Pn as validateAssetBucketName, Pr as LocalMigrateError, Pt as s3BucketDualStackDomainName, Q as beginCommandInterruptScope, Qn as resolveAutoAssetStorage, Qr as isRetryableTransientError, Qt as maskSecretsInError, R as exportAliasCollisionScrubWarning, Rn as buildDockerImage, Rr as NestedStackChildDirectDestroyError, Rt as DiffCalculator, S as refusesFinalSnapshot, Sn as loadPublishableAssetManifest, Sr as getAwsClients, St as coerceCfnBoolean, T as extractDeploymentEventError, Tn as stripControlChars, Tt as readConfigString, U as IAMRoleProvider, Un as runDockerForeground, Ur as StackHasActiveImportsError, Ut as TemplateParser, V as stateKeySecretExposure, Vn as getDockerCmd, Vr as ResourceTimeoutError, Vt as withRetry, W as collectInlinePolicyNamesManagedBySiblings, Wn as runDockerStreaming, Wr as StackTerminationProtectionError, Wt as STATE_SOURCED_CROSS_GENERATION_RULES, X as maskDeep, Xn as getLegacyStateBucketName, Xr as withErrorHandling, Xt as errorCauseChain, Y as createMaskedRetryLogger, Yn as getDefaultStateBucketName, Yr as normalizeAwsError, Yt as dynamicReferenceTokens, Z as maskerOrIdentity, Zn as resolveApp, Zr as isMarkedNonRetryable, Zt as isSingleDynamicReferenceToken, _ as PRE_DELETE_SNAPSHOT_TYPES, _n as AssetPublisher, _r as AssemblyReader, _t as refStateLookupFromResource, a as DeploymentEventsStore, an as S3StateBackend, ar as warnDeprecatedNoPrefixCliFlag, at as UNSPECIFIED_SKIP_REASON, b as createPreDeleteFinalSnapshot, bn as buildAssetRedirectMap, br as resolveBucketRegion, bt as resolveExplicitPhysicalId, c as replayFailedOperations, cn as buildForceUnlockCommand, cr as MIGRATE_TMP_PREFIX, ct as disableInstanceApiTermination, d as updatePartialReason, dn as CUSTOM_RESOURCE_RESPONSE_PREFIX, dr as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, dt as carriesDynamicReference, ei as isTransientServerError, en as recordMaskOnlyValue, er as resolveSkipPrefix, et as interruptWatchListenerCount, f as withResourceDeadline, fn as DEFAULT_STATE_PREFIX, fr as displaySafe, ft as cfnRefValueFromPhysicalId, g as ATOMIC_FINAL_SNAPSHOT_TYPES, gn as shouldRetainResource, gr as derivePartitionAndUrlSuffix, gt as parameterTypeMayLoseSecretIdentity, h as computeImplicitDeleteEdges, hn as importableOutputs, hr as canonicalizeRegion, ht as isUnboundTemplateParameter, i as DeploymentEventsReader, in as LockManager, ir as stateBucketExistenceConfirmed, it as slowCcOperationTimeoutMs, j as cyan, jn as isCrossRegionRedirect, jr as DynamicReferenceRegionAmbiguousError, jt as producerRegionsFromState, k as formatResourceLine, kn as ensureAssetStorage, kt as requireConfigString, l as replayRollback, ln as buildLockContentionMessage, lr as findLargeInlineResources, lt as isTerminationProtectionPropagationError, m as IMPLICIT_DELETE_DEPENDENCIES, mn as importableOutputKeys, mr as PARTITION_TABLE, mt as getAccountInfo, n as DEFAULT_RESOURCE_WARN_AFTER_MS, ni as markRedactedCause, nn as redactSecretsForState, nr as resolveStateBucketWithDefaultAndSource, nt as startInterruptWatch, o as planFailedOps, on as rebuildClientForBucketRegion, or as CFN_TEMPLATE_BODY_LIMIT, ot as deleteIndeterminateGuards, p as maskingRetryLogger, pn as exportNamesCarriedFrom, pr as expectedOwnerParam, pt as coerceParameterTypedValue, q as findActionableSilentDrops, qn as Synthesizer, qt as carriesSecretMask, r as DeployEngine, ri as retryClassificationText, rn as scrubResourceRecord, rr as resolveUseCdkBootstrapAssets, rt as CloudControlProvider, s as planRollback, sn as UNRENDERABLE, sr as CFN_TEMPLATE_URL_LIMIT, st as deleteSkipReason, t as DEFAULT_RESOURCE_TIMEOUT_MS, ti as markNonRetryable, tn as recoverMaskedOutput, tr as resolveStateBucketWithDefault, tt as isInterruptedWaitError, u as updatePartialMessage, un as forceQuitRecoveryClause, ur as uploadCfnTemplate, ut as IntrinsicFunctionResolver, v as buildFinalSnapshotIdentifier, vn as stringifyValue, vr as processStackMessages, vt as WAFv2WebACLProvider, w as makeCanonicalizePropertiesFn, wn as escapeRegExp, wr as setAwsClients, wt as configStringRefusal, x as isFinalSnapshotError, xn as createAssetRedirectResolver, xr as AwsClients, xt as assertRegionMatch, y as ccRoutedFinalSnapshotError, yn as WorkGraph, yt as normalizeAwsTagsToCfn, z as isExportAliasCollision, zn as dockerSpawnEnvWithSensitive, zr as PartialFailureError, zt as INTRINSIC_KEYS } from "./deploy-engine-DuFUy9D0.js";
|
|
2
2
|
import { _ as withStackName, c as PATTERN_B_NAME_OPTIONS, f as generateResourceName, g as withSkipPrefix, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as getCurrentStackName, n as getLogger, o as runStackBuffered, p as generateResourceNameWithFallback, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES } from "./logger-Dw-3y48G.js";
|
|
3
3
|
import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
|
|
4
|
-
import { t as getCdkdVersion } from "./version-
|
|
5
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as getCdkdVersion } from "./version-C_ZRHikq.js";
|
|
5
|
+
import { t as ASGProvider } from "./asg-provider-DoP-32eU.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
8
8
|
import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -38,7 +38,7 @@ import { join as join$1 } from "path";
|
|
|
38
38
|
import { BatchDeleteImageCommand, CreateRepositoryCommand, DeleteLifecyclePolicyCommand, DeleteRepositoryCommand, DeleteRepositoryPolicyCommand, DescribeImagesCommand as DescribeImagesCommand$1, DescribeRepositoriesCommand, ECRClient, GetAuthorizationTokenCommand, GetLifecyclePolicyCommand, LifecyclePolicyNotFoundException, ListTagsForResourceCommand as ListTagsForResourceCommand$9, PutImageScanningConfigurationCommand, PutImageTagMutabilityCommand, PutLifecyclePolicyCommand, RepositoryNotEmptyException, RepositoryNotFoundException, SetRepositoryPolicyCommand, TagResourceCommand as TagResourceCommand$12, UntagResourceCommand as UntagResourceCommand$12 } from "@aws-sdk/client-ecr";
|
|
39
39
|
import graphlib from "graphlib";
|
|
40
40
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$2, CreateDBClusterCommand, CreateDBInstanceCommand, CreateDBProxyCommand, CreateDBProxyEndpointCommand, CreateDBSubnetGroupCommand, DBProxyEndpointNotFoundFault, DBProxyNotFoundFault, DBProxyTargetGroupNotFoundFault, DBProxyTargetNotFoundFault, DeleteDBClusterCommand, DeleteDBInstanceCommand, DeleteDBProxyCommand, DeleteDBProxyEndpointCommand, DeleteDBSubnetGroupCommand, DeregisterDBProxyTargetsCommand, DescribeDBClustersCommand, DescribeDBInstancesCommand, DescribeDBProxiesCommand, DescribeDBProxyEndpointsCommand, DescribeDBProxyTargetGroupsCommand, DescribeDBProxyTargetsCommand, DescribeDBSubnetGroupsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$10, ModifyDBClusterCommand, ModifyDBInstanceCommand, ModifyDBProxyCommand, ModifyDBProxyEndpointCommand, ModifyDBProxyTargetGroupCommand, ModifyDBSubnetGroupCommand, RDSClient, RegisterDBProxyTargetsCommand, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$2 } from "@aws-sdk/client-rds";
|
|
41
|
-
import { Command, Option } from "commander";
|
|
41
|
+
import { Command, InvalidArgumentError, Option } from "commander";
|
|
42
42
|
import * as readline$1 from "node:readline/promises";
|
|
43
43
|
import readline from "node:readline/promises";
|
|
44
44
|
import { writeFileSync as writeFileSync$1 } from "fs";
|
|
@@ -324,6 +324,50 @@ function parseDuration(value) {
|
|
|
324
324
|
return Math.round(num * (unit === "s" ? 1e3 : unit === "m" ? 6e4 : 36e5));
|
|
325
325
|
}
|
|
326
326
|
/**
|
|
327
|
+
* Commander `argParser` for `--stack-region` (issue #2556).
|
|
328
|
+
*
|
|
329
|
+
* Refuses a value carrying no region name at all, at PARSE time rather than
|
|
330
|
+
* in each consumer. `--stack-region ''` is falsy, so every consumer that
|
|
331
|
+
* tested the option for truthiness read it as ABSENT — and absent means "all
|
|
332
|
+
* regions" on the commands that take `--all`, so a flag passed to NARROW a
|
|
333
|
+
* destructive operation silently WIDENED it. `drift --all --revert
|
|
334
|
+
* --stack-region ''` wrote cdkd state values into AWS across every stack in
|
|
335
|
+
* every region.
|
|
336
|
+
*
|
|
337
|
+
* Here rather than in the consumers because there are more consumers than
|
|
338
|
+
* declarations, the value is threaded through helpers that cannot see how it
|
|
339
|
+
* was spelled, and the empty value has no legitimate meaning — so it never
|
|
340
|
+
* needs to reach them. `guardStackRegionOptions` extends the same guard to
|
|
341
|
+
* declarations cdkd does not own.
|
|
342
|
+
*
|
|
343
|
+
* The rule is only "this is not a name": empty and whitespace-only are
|
|
344
|
+
* refused, and everything else is passed through UNCHANGED — cdkd keeps no
|
|
345
|
+
* list of region names, so a value that looks wrong is the caller's to own,
|
|
346
|
+
* and trimming one would be the silent reinterpretation this whole class
|
|
347
|
+
* started as.
|
|
348
|
+
*/
|
|
349
|
+
function parseStackRegion(value) {
|
|
350
|
+
if (value.trim() === "") throw new InvalidArgumentError(`expected a region name (e.g. us-east-1), got ${value === "" ? "an empty value" : "whitespace only"}. Omit the flag entirely to operate on every region a stack has state in.`);
|
|
351
|
+
return value;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Attach {@link parseStackRegion} to every `--stack-region` the command tree
|
|
355
|
+
* carries, including ones cdkd never declared.
|
|
356
|
+
*
|
|
357
|
+
* `cdkd local start-{service,alb,cloudfront,agentcore}` inherit the option
|
|
358
|
+
* from cdk-local, so there is no declaration in this repo to hang a parser on
|
|
359
|
+
* and a grep for the flag string does not find them. They are the worst place
|
|
360
|
+
* to miss it: cdk-local resolves the CloudFormation client's region with
|
|
361
|
+
* `options.stackRegion ?? options.region ?? AWS_REGION`, and `''` is not
|
|
362
|
+
* nullish — so an empty value WINS over both fallbacks and reaches the client.
|
|
363
|
+
*
|
|
364
|
+
* Idempotent, and it never replaces a parser a declaration already set.
|
|
365
|
+
*/
|
|
366
|
+
function guardStackRegionOptions(cmd) {
|
|
367
|
+
for (const option of cmd.options) if (option.long === "--stack-region" && option.parseArg === void 0) option.argParser(parseStackRegion);
|
|
368
|
+
for (const sub of cmd.commands) guardStackRegionOptions(sub);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
327
371
|
* Validate that a token's left-hand side looks like a CloudFormation
|
|
328
372
|
* resource type (e.g. `AWS::S3::Bucket`). The check is intentionally
|
|
329
373
|
* loose — we don't maintain a closed list of types — but it does reject
|
|
@@ -703,21 +747,39 @@ function parseRecreateViaSdkProviderToken(value, previous) {
|
|
|
703
747
|
}
|
|
704
748
|
const recreateViaSdkProviderOption = new Option("--recreate-via-sdk-provider <logicalId>", "Destroy + recreate the named resource (by CloudFormation logical id) via cdkd's SDK Provider in this deploy, so a resource currently sticky on provisionedBy: cc-api flips back to provisionedBy: sdk. Used after a #609 backfill release adds SDK coverage for a type the user originally needed CC for (e.g. Lambda LoggingConfig). Repeatable — pass the flag once per resource. Per-resource opt-in. Stateful resource types refuse unless --force-stateful-recreation is ALSO passed.").argParser(parseRecreateViaSdkProviderToken);
|
|
705
749
|
/**
|
|
706
|
-
* Issue [#615] — `--force-stateful-recreation` (boolean)
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
750
|
+
* Issue [#615] — `--force-stateful-recreation` (boolean) confirms a
|
|
751
|
+
* data-losing destroy + recreate of a stateful resource (RDS / DynamoDB /
|
|
752
|
+
* EFS / S3 with data / etc.).
|
|
753
|
+
*
|
|
754
|
+
* It started as the second flag `--recreate-via-cc-api` needs, and that
|
|
755
|
+
* two-flag shape still holds for the `--recreate-via-*` / `--replace`
|
|
756
|
+
* opt-ins. But the guard now runs on the mid-deploy replacement paths
|
|
757
|
+
* too — not only the flag-gated ones, and with its own exemptions (a
|
|
758
|
+
* property-driven replacement under `UpdateReplacePolicy: Retain` creates
|
|
759
|
+
* first, so it is skipped there) (see
|
|
760
|
+
* `docs/cli-deploy-safety.md#stateful-resource-guard`), and some of them
|
|
761
|
+
* reach a replacement with NO flag at all: a property-driven replacement
|
|
762
|
+
* (an immutable / createOnly property changed in the template) and the
|
|
763
|
+
* update-failure fallback's Cloud Control trigger (issue [#2514]). On
|
|
764
|
+
* those, a plain `cdkd deploy` asks for this flag on its own — so the
|
|
765
|
+
* help text must not describe it as scoped to `--recreate-via-cc-api`
|
|
766
|
+
* targets.
|
|
710
767
|
*
|
|
711
768
|
* The guard list of "stateful" types lives in
|
|
712
769
|
* `src/provisioning/stateful-types.ts` so it can be queried from both
|
|
713
|
-
* the CLI pre-flight and the deploy engine
|
|
770
|
+
* the CLI pre-flight and the deploy engine, and it is published — as the
|
|
771
|
+
* only enumeration users read — in `docs/cli-deploy-safety.md`, which a
|
|
772
|
+
* set-equality fence keeps in step with the source. Prose elsewhere
|
|
773
|
+
* (this help string included) names EXAMPLES and points there; it must
|
|
774
|
+
* not read as exhaustive, because a widened guard would silently make it
|
|
775
|
+
* wrong.
|
|
714
776
|
*
|
|
715
777
|
* There is no per-resource granularity on the force flag — when set,
|
|
716
778
|
* EVERY named recreate target bypasses the stateful guard. Per-resource
|
|
717
779
|
* force would create a false sense of granularity (the user is opting
|
|
718
780
|
* into a footgun; pretending to scope it per-resource is misleading).
|
|
719
781
|
*/
|
|
720
|
-
const forceStatefulRecreationOption = new Option("--force-stateful-recreation", "
|
|
782
|
+
const forceStatefulRecreationOption = new Option("--force-stateful-recreation", "Confirm a data-losing destroy + recreate of a stateful resource. Required whenever a replacement target is a stateful type — databases, filesystems, KMS keys, table / vector storage, source repositories, log groups with retention, and more; docs/cli-deploy-safety.md carries the full list, and S3 is the special case (a non-empty bucket at pre-flight, ANY bucket mid-deploy, where the emptiness probe cannot run) — on the --recreate-via-cc-api / --recreate-via-sdk-provider pre-flight, with --replace, AND on the paths a plain deploy reaches with no flag: a template immutable-property change, and an in-place update the provisioning layer rejects. Destroy + recreate loses ALL data in the resource — no automatic data migration. Full opt-in for CI use: --recreate-via-cc-api <id> --force-stateful-recreation --yes.").default(false);
|
|
721
783
|
const replaceOption = new Option("--replace", "Replace (DELETE + CREATE) a resource whose in-place update is rejected because an immutable property changed and AWS exposes no update API for it (e.g. Lambda LayerVersion content, EFS AccessPoint, ECS TaskDefinition, ApiGatewayV2 immutable fields). Without this flag such a change fails the deploy. Stateful types (RDS / DynamoDB / EFS / S3 with data / Logs with retention / etc.) ALSO require --force-stateful-recreation since the replacement is a data-losing DELETE + CREATE.").default(false);
|
|
722
784
|
/**
|
|
723
785
|
* Issue #1002 PR 2 — per-invocation legacy pin for asset destinations
|
|
@@ -2437,7 +2499,7 @@ function isPromptAbortError(error) {
|
|
|
2437
2499
|
* bucket with objects, LogGroup with retention) MUST be matched
|
|
2438
2500
|
* by an explicit `--force-stateful-recreation` flag. The sync
|
|
2439
2501
|
* first-cut runs from the recorded properties alone; the live
|
|
2440
|
-
* `s3:
|
|
2502
|
+
* `s3:ListObjectVersions` probe (issue [#648]) promotes a `null`
|
|
2441
2503
|
* reason to `'has-objects'` when a bucket actually contains data.
|
|
2442
2504
|
* 4. Multi-region refusal: every named target whose resource type
|
|
2443
2505
|
* is in {@link MULTI_REGION_RECREATE_BLOCKED_TYPES} (e.g.
|
|
@@ -2456,7 +2518,7 @@ function isPromptAbortError(error) {
|
|
|
2456
2518
|
*
|
|
2457
2519
|
* Pure with respect to AWS — does NOT probe S3 bucket emptiness. Wrap
|
|
2458
2520
|
* the result with {@link probeAndRevalidateStateful} to promote S3
|
|
2459
|
-
* targets' `statefulReason` via a live `s3:
|
|
2521
|
+
* targets' `statefulReason` via a live `s3:ListObjectVersions` round-trip
|
|
2460
2522
|
* before rendering errors. The deploy command does this; the validator
|
|
2461
2523
|
* itself stays sync so unit tests don't need an S3 mock.
|
|
2462
2524
|
*
|
|
@@ -2792,7 +2854,7 @@ function renderDownstreamConsumers(producerStack, consumers) {
|
|
|
2792
2854
|
*
|
|
2793
2855
|
* The per-target plan surfaces a **DATA LOSS** prefix for stateful
|
|
2794
2856
|
* targets (those with a non-null `statefulReason` after the live
|
|
2795
|
-
* `s3:
|
|
2857
|
+
* `s3:ListObjectVersions` probe — see issue [#648]); these reached pre-flight
|
|
2796
2858
|
* only because the user opted in with `--force-stateful-recreation`,
|
|
2797
2859
|
* so the prompt's **DATA LOSS** wording is the third "stop and think"
|
|
2798
2860
|
* moment.
|
|
@@ -9590,7 +9652,7 @@ var S3BucketProvider = class S3BucketProvider {
|
|
|
9590
9652
|
* `ServerSideEncryptionConfigurationNotFoundError`, `NoSuchTagSet`,
|
|
9591
9653
|
* `NoSuchPublicAccessBlockConfiguration`, etc.) — those are caught
|
|
9592
9654
|
* individually and the corresponding key is emitted as a CFn-shape
|
|
9593
|
-
* placeholder (per docs/provider-
|
|
9655
|
+
* placeholder (per docs/provider-rules.md#readcurrentstate-for-drift-detection: always-emit
|
|
9594
9656
|
* user-controllable top-level keys), NOT treated as the bucket being
|
|
9595
9657
|
* absent.
|
|
9596
9658
|
*
|
|
@@ -32319,7 +32381,7 @@ var CloudFrontOACProvider = class {
|
|
|
32319
32381
|
* identical, so the reverse mapping is a straight per-field copy.
|
|
32320
32382
|
*
|
|
32321
32383
|
* Every field is emitted unconditionally, with `?? ''` standing in for an
|
|
32322
|
-
* AWS response that omits it (docs/provider-
|
|
32384
|
+
* AWS response that omits it (docs/provider-rules.md#readcurrentstate-for-drift-detection): the
|
|
32323
32385
|
* optional `Description` is user-controllable and mutable, so dropping the
|
|
32324
32386
|
* key when AWS returns nothing would leave it out of `observedProperties`
|
|
32325
32387
|
* on a stack that never templated it — and the drift comparator's
|
|
@@ -47566,12 +47628,13 @@ var GlueProvider = class {
|
|
|
47566
47628
|
* | no | no | AWS-AUTHORED -> preserved from live |
|
|
47567
47629
|
*
|
|
47568
47630
|
* That keeps this provider on the repo's established clear-on-removal
|
|
47569
|
-
* position (docs/provider-
|
|
47631
|
+
* position (docs/provider-rules.md#update-removal-semantics-clear-on-removal, issue #1155): a removal the
|
|
47570
47632
|
* user expressed in the template still reaches AWS. Glue's update APIs are
|
|
47571
47633
|
* full-replace, so removal needs no explicit reset sentinel — omitting the
|
|
47572
47634
|
* key IS the reset, and the only thing this helper adds back is the set of
|
|
47573
47635
|
* keys the user never authored in the first place. The generalized rule for
|
|
47574
|
-
* any full-replace update API lives in
|
|
47636
|
+
* any full-replace update API lives in
|
|
47637
|
+
* docs/provider-rules.md#full-replace-update-apis-erase-aws-authored-values.
|
|
47575
47638
|
*
|
|
47576
47639
|
* Audited siblings that do NOT get this treatment: `JobUpdate`'s
|
|
47577
47640
|
* `DefaultArguments` / `NonOverridableArguments`, `ConnectionInput`'s
|
|
@@ -53664,7 +53727,7 @@ var FSxFileSystemProvider = class {
|
|
|
53664
53727
|
* by their respective `read*Configuration` helpers; the few inputs AWS
|
|
53665
53728
|
* never returns stay listed in {@link getDriftUnknownPaths}.
|
|
53666
53729
|
*
|
|
53667
|
-
* Emission follows `docs/provider-
|
|
53730
|
+
* Emission follows `docs/provider-rules.md#readcurrentstate-for-drift-detection`: every top-level
|
|
53668
53731
|
* property `update()` can mutate is emitted unconditionally with a
|
|
53669
53732
|
* placeholder, registry-createOnly properties keep their guard, and the
|
|
53670
53733
|
* `<Variant>Configuration` blocks take the Class 1 type-discriminator
|
|
@@ -57806,7 +57869,7 @@ var CodeCommitRepositoryProvider = class {
|
|
|
57806
57869
|
*
|
|
57807
57870
|
* Every user-controllable top-level key `update()` can mutate is emitted
|
|
57808
57871
|
* ALWAYS — with a `?? ''` / `?? []` placeholder when AWS returns the field
|
|
57809
|
-
* as undefined / empty (docs/provider-
|
|
57872
|
+
* as undefined / empty (docs/provider-rules.md#readcurrentstate-for-drift-detection). Omitting the key
|
|
57810
57873
|
* on the empty path would let a resource deployed WITHOUT a description
|
|
57811
57874
|
* never carry `RepositoryDescription` in `observedProperties`, making a
|
|
57812
57875
|
* console-side ADD of a description invisible to drift forever. `Tags` are
|
|
@@ -60122,104 +60185,6 @@ var ECRProvider = class {
|
|
|
60122
60185
|
}
|
|
60123
60186
|
};
|
|
60124
60187
|
|
|
60125
|
-
//#endregion
|
|
60126
|
-
//#region src/state/lock-contention-message.ts
|
|
60127
|
-
/**
|
|
60128
|
-
* The message every fail-fast lock-contention site raises.
|
|
60129
|
-
*
|
|
60130
|
-
* Issue #2161 made six commands throw on `acquireLock` returning `false`
|
|
60131
|
-
* instead of running under a foreign lock. Issue #2170 is the follow-up: the
|
|
60132
|
-
* message those sites raise asked the user to decide "is another process
|
|
60133
|
-
* active?" while printing none of the evidence that would answer it, and the
|
|
60134
|
-
* recovery command it suggested could resolve against the wrong AWS account.
|
|
60135
|
-
*
|
|
60136
|
-
* Both matter more than they look, because of WHICH locks reach this message.
|
|
60137
|
-
* `LockManager.acquireLock` reaps an EXPIRED foreign lock and retries, so a
|
|
60138
|
-
* `false` return means the lock is LIVE — in practice a running `cdkd deploy`.
|
|
60139
|
-
* The user who follows a bare `cdkd force-unlock <stack>` suggestion therefore
|
|
60140
|
-
* deletes a live owner's lock and reproduces issue #2161's harm by hand, which
|
|
60141
|
-
* is the outcome #2161 exists to prevent.
|
|
60142
|
-
*
|
|
60143
|
-
* Centralising the text here also settles the third finding: the nine sites
|
|
60144
|
-
* had drifted to three spellings (`for stack` / `for nested stack` /
|
|
60145
|
-
* `for nested-stack child`), so a user grepping CI logs for one of them found
|
|
60146
|
-
* two of three. `subject` now varies only the noun.
|
|
60147
|
-
*/
|
|
60148
|
-
/**
|
|
60149
|
-
* Stand-in for a value with nothing renderable left after sanitization. Named
|
|
60150
|
-
* rather than inlined so the message and the command-suppression branch cannot
|
|
60151
|
-
* disagree about what "unrenderable" looks like.
|
|
60152
|
-
*/
|
|
60153
|
-
const UNRENDERABLE = "<unrenderable>";
|
|
60154
|
-
/** Render `expiresIn` without implying more precision than a clock skew allows. */
|
|
60155
|
-
function formatRemaining(ms) {
|
|
60156
|
-
if (!Number.isFinite(ms)) return "at an unknown time";
|
|
60157
|
-
if (ms <= 0) return "already expired";
|
|
60158
|
-
const minutes = Math.round(ms / 6e4);
|
|
60159
|
-
if (minutes < 1) return "in under a minute";
|
|
60160
|
-
return `in ~${minutes}m`;
|
|
60161
|
-
}
|
|
60162
|
-
function shellQuote(value) {
|
|
60163
|
-
return /^[A-Za-z0-9._/@:+-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
|
|
60164
|
-
}
|
|
60165
|
-
/**
|
|
60166
|
-
* The `cdkd force-unlock ...` line, carrying every flag that decides which
|
|
60167
|
-
* lock object it resolves to.
|
|
60168
|
-
*/
|
|
60169
|
-
function buildForceUnlockCommand(stackName, region, recovery) {
|
|
60170
|
-
const safeStack = displaySafe(stackName, { asciiOnly: true });
|
|
60171
|
-
const stackIsExact = safeStack === stackName;
|
|
60172
|
-
const safeRegion = region === void 0 ? void 0 : displaySafe(region, { asciiOnly: true });
|
|
60173
|
-
if (!safeStack || safeRegion === "" || !stackIsExact || !(region === void 0 || safeRegion === region)) return "";
|
|
60174
|
-
const parts = [safeRegion === void 0 ? `cdkd force-unlock ${shellQuote(safeStack)}` : `cdkd force-unlock ${shellQuote(safeStack)} --stack-region ${shellQuote(safeRegion)}`];
|
|
60175
|
-
if (recovery?.profile) parts.push(`--profile ${shellQuote(recovery.profile)}`);
|
|
60176
|
-
if (recovery?.stateBucket) parts.push(`--state-bucket ${shellQuote(recovery.stateBucket)}`);
|
|
60177
|
-
if (recovery?.statePrefix && recovery.statePrefix !== "cdkd") parts.push(`--state-prefix ${shellQuote(recovery.statePrefix)}`);
|
|
60178
|
-
return parts.join(" ");
|
|
60179
|
-
}
|
|
60180
|
-
/**
|
|
60181
|
-
* The force-quit banner's recovery sentence.
|
|
60182
|
-
*
|
|
60183
|
-
* Exported so the two `destroy-runner.ts` banners do not each decide what to
|
|
60184
|
-
* say when {@link buildForceUnlockCommand} suppresses — a banner ending in a
|
|
60185
|
-
* bare `run: ` is the shape the review found, and two copies of the branch is
|
|
60186
|
-
* how the next one drifts. Returns a leading-space clause so the caller can
|
|
60187
|
-
* concatenate it unconditionally.
|
|
60188
|
-
*/
|
|
60189
|
-
function forceQuitRecoveryClause(stackName, region, recovery) {
|
|
60190
|
-
const command = buildForceUnlockCommand(stackName, region, recovery);
|
|
60191
|
-
return command ? ` If the next run reports a lock, run: ${command}` : " Inspect the lock object directly: the name or region recorded for this stack cannot be reproduced safely on a command line, so any command shown here would address a different lock.";
|
|
60192
|
-
}
|
|
60193
|
-
/**
|
|
60194
|
-
* Build the contention message, reading the holder's identity best-effort.
|
|
60195
|
-
*
|
|
60196
|
-
* The `getLockInfo` read is one GetObject and is deliberately NOT allowed to
|
|
60197
|
-
* fail the command: the caller is already on its way to throwing, and turning
|
|
60198
|
-
* a contention refusal into an S3 error would lose the reason. A failed or
|
|
60199
|
-
* absent read degrades to the evidence-free wording rather than to a crash.
|
|
60200
|
-
*/
|
|
60201
|
-
async function buildLockContentionMessage(args) {
|
|
60202
|
-
const { lockManager, stackName, region, subject = "stack", recovery, heldClause, suffix } = args;
|
|
60203
|
-
let held = heldClause ?? "another cdkd process holds it";
|
|
60204
|
-
let sawHolder = false;
|
|
60205
|
-
try {
|
|
60206
|
-
const info = await lockManager.getLockInfo(stackName, region);
|
|
60207
|
-
if (info) {
|
|
60208
|
-
const operation = info.operation ? `, operation: ${displaySafe(info.operation)}` : "";
|
|
60209
|
-
const expires = formatRemaining(info.expiresAt - Date.now());
|
|
60210
|
-
const owner = displaySafe(info.owner);
|
|
60211
|
-
const holder = owner ? `held by ${owner}${operation}` : `held by an unnamed holder`;
|
|
60212
|
-
held = `${heldClause ? `${heldClause} — ` : ""}${holder}, expires ${expires}`;
|
|
60213
|
-
if (owner) sawHolder = true;
|
|
60214
|
-
}
|
|
60215
|
-
} catch {}
|
|
60216
|
-
const advice = sawHolder ? `That process is still running — wait for it to finish. Only if you are certain it is gone` : `Wait for it to finish, or if you are certain no other process is active`;
|
|
60217
|
-
const recoveryCommand = buildForceUnlockCommand(stackName, region, recovery);
|
|
60218
|
-
const head = `Could not acquire lock for ${subject} '${displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>"}' (${displaySafe(region, { asciiOnly: true }) || "<unrenderable>"}) — ${held}.` + (suffix ? ` ${suffix}` : "");
|
|
60219
|
-
if (!recoveryCommand) return `${head} ${advice}. No recovery command can be shown: the name or region recorded for this lock contains characters that cannot be reproduced safely on a command line, so any command shown here would address a different lock — inspect the lock object directly.`;
|
|
60220
|
-
return `${head} ${advice}, run: ${recoveryCommand}`;
|
|
60221
|
-
}
|
|
60222
|
-
|
|
60223
60188
|
//#endregion
|
|
60224
60189
|
//#region src/cli/commands/destroy-runner.ts
|
|
60225
60190
|
/**
|
|
@@ -70228,7 +70193,7 @@ function formatScalar(value) {
|
|
|
70228
70193
|
* Reusable `--stack-region <region>` option (mirrors `state show`).
|
|
70229
70194
|
*/
|
|
70230
70195
|
function stackRegionOption$2() {
|
|
70231
|
-
return new Option("--stack-region <region>", "Region of the stack record to inspect. Required when the same stack name has state in multiple regions.");
|
|
70196
|
+
return new Option("--stack-region <region>", "Region of the stack record to inspect. Required when the same stack name has state in multiple regions.").argParser(parseStackRegion);
|
|
70232
70197
|
}
|
|
70233
70198
|
/**
|
|
70234
70199
|
* Create the `drift` command.
|
|
@@ -70667,6 +70632,11 @@ async function stateMigrateCommand(options) {
|
|
|
70667
70632
|
const sourceObjects = await listAllObjects(legacyS3, legacyBucket);
|
|
70668
70633
|
logger.info(` source object count: ${sourceObjects.length}`);
|
|
70669
70634
|
if (sourceObjects.length === 0) logger.info("Source bucket is empty — no objects to copy.");
|
|
70635
|
+
if (options.dryRun) {
|
|
70636
|
+
if (options.removeLegacy) logger.info(`--remove-legacy: '${legacyBucket}' would then be emptied (every object version and delete marker) and deleted.`);
|
|
70637
|
+
logger.info("--dry-run: no changes will be made. Stopping here.");
|
|
70638
|
+
return;
|
|
70639
|
+
}
|
|
70670
70640
|
if (!options.yes) {
|
|
70671
70641
|
const action = options.removeLegacy ? "and DELETE the source bucket" : "(source bucket will be kept)";
|
|
70672
70642
|
if (!await confirmPrompt$4(`Copy ${sourceObjects.length} object(s) from ${legacyBucket} -> ${newBucket} ${action}?`)) {
|
|
@@ -70674,10 +70644,6 @@ async function stateMigrateCommand(options) {
|
|
|
70674
70644
|
return;
|
|
70675
70645
|
}
|
|
70676
70646
|
}
|
|
70677
|
-
if (options.dryRun) {
|
|
70678
|
-
logger.info("--dry-run: no changes will be made. Stopping here.");
|
|
70679
|
-
return;
|
|
70680
|
-
}
|
|
70681
70647
|
const newS3 = await ensureDestinationBucket(newBucket, legacyRegion, accountId, logger);
|
|
70682
70648
|
try {
|
|
70683
70649
|
let copied = 0;
|
|
@@ -70852,7 +70818,11 @@ async function emptyBucketAllVersions(s3, bucket) {
|
|
|
70852
70818
|
/**
|
|
70853
70819
|
* `cdkd state migrate`'s confirmation prompt. Its only call site is inside the
|
|
70854
70820
|
* `if (!options.yes)` block above, which is what keeps `confirmOrRefuse`'s
|
|
70855
|
-
* non-interactive refusal (issue #2275) from firing on a `--yes` run
|
|
70821
|
+
* non-interactive refusal (issue #2275) from firing on a `--yes` run — and it
|
|
70822
|
+
* sits BELOW the `--dry-run` bail (issue #2538), so a preview never reaches it
|
|
70823
|
+
* either. Together those are the two ways not to be asked, matching
|
|
70824
|
+
* `state refresh-observed`, whose prompt condition spells both:
|
|
70825
|
+
* `!options.yes && !options.dryRun`.
|
|
70856
70826
|
*
|
|
70857
70827
|
* Exported for unit testing — internal to the command flow otherwise.
|
|
70858
70828
|
*/
|
|
@@ -74491,7 +74461,7 @@ async function confirmPrompt$3(prompt) {
|
|
|
74491
74461
|
return confirmOrRefuse(prompt, { refusal: "The cdkd export confirmation prompt cannot run in a non-interactive environment. Pass -y / --yes to confirm, or run the command from a real terminal." });
|
|
74492
74462
|
}
|
|
74493
74463
|
function createExportCommand() {
|
|
74494
|
-
const cmd = new Command("export").description("Hand a cdkd-managed stack over to CloudFormation via CFn IMPORT (changeset). AWS resources are unchanged; cdkd state for the stack is deleted on success. Mirror of `cdkd import` (AWS → cdkd) in the reverse direction (cdkd → CFn). Accepts JSON and YAML templates (YAML via a CFn-aware codec that preserves !Ref / !GetAtt / !Sub shorthand). Aborts if any resource is not CFn-importable.").argument("[stack]", "Stack name to export (auto-detected for single-stack apps)").option("--cfn-stack-name <name>", "Name of the destination CloudFormation stack for the root stack. Defaults to the cdkd stack name (or the cdkd2cfnStackName mapping when the name contains '~'). For per-nested-child overrides, use --cfn-child-stack-name.").option("--cfn-child-stack-name <pair...>", "Per-nested-child CFn stack-name override. Repeatable. Format: '<cdkdName>=<cfnName>' (e.g. --cfn-child-stack-name 'MyApp~Database=my-app-db'). The cdkd stack name for a nested child is '<parent>~<childLogicalId>' (v6 state-key form). Without an override the CFn name is derived by replacing '~' with '-'. Only consulted when the exported stack tree contains nested children; ignored for flat stacks.").option("--template <path>", "Path to a pre-rendered CloudFormation template (JSON or YAML — format auto-detected). Skips synth.").option("--stack-region <region>", "Region of the cdkd state record to operate on. Required when the same stack name has state in multiple regions.").option("--dry-run", "Print the import plan without creating a changeset.", false).option("--accept-transient-context", "Allow CLI -c key=value overrides at export time even though they are not persisted to cdk.json / cdk.context.json (default: refuse). When set, the user is responsible for passing the same -c flags to every future cdk deploy.", false).option("--include-non-importable", "Run a 2-phase migration when the stack contains non-importable resources (Custom::*). Phase 1 imports the importable resources; phase 2 CFn-CREATEs the non-importable ones, which re-invokes each Custom Resource's onCreate handler. Make sure onCreate is idempotent before enabling.", false).option("--parameter <key=value...>", "CFn template Parameter override, repeatable. Required when the synthesized template has Parameters without Default values; otherwise overrides the template's default value. Format: --parameter Key=Value.").option("--strict-cross-stack", "Refuse to export when sibling cdkd stacks in the same CDK app reference the exporting stack via Fn::GetStackOutput. Without the flag, cdkd warns and proceeds — the consumers keep resolving via the CloudFormation fallback (weak reference) unless they deploy with --no-cfn-fallback.", false).option("--skip-import-support-preflight", "Skip the pre-flight that refuses resource types whose CloudFormation registry schema says CFn cannot IMPORT them (no read handler AND NON_PROVISIONABLE), and let CreateChangeSet answer instead. The pre-flight is a registry HEURISTIC, not AWS's supported-for-import list, so this is the escape hatch for a type AWS has since made importable. Expect the changeset to be rejected if the heuristic was right.", false).option("--no-recreate-import-unsupported", "Block instead of auto-handling resource types AWS does NOT support in IMPORT changesets (AWS::ApiGatewayV2::Stage and AWS::IAM::Policy). Default behavior: cdkd skips these from phase 1, deletes the AWS-side resource between phases, and lets CFn re-CREATE in phase 2 (brief unavailability window). With this flag, the export aborts with a clear error instead.").action(withErrorHandling(exportCommand));
|
|
74464
|
+
const cmd = new Command("export").description("Hand a cdkd-managed stack over to CloudFormation via CFn IMPORT (changeset). AWS resources are unchanged; cdkd state for the stack is deleted on success. Mirror of `cdkd import` (AWS → cdkd) in the reverse direction (cdkd → CFn). Accepts JSON and YAML templates (YAML via a CFn-aware codec that preserves !Ref / !GetAtt / !Sub shorthand). Aborts if any resource is not CFn-importable.").argument("[stack]", "Stack name to export (auto-detected for single-stack apps)").option("--cfn-stack-name <name>", "Name of the destination CloudFormation stack for the root stack. Defaults to the cdkd stack name (or the cdkd2cfnStackName mapping when the name contains '~'). For per-nested-child overrides, use --cfn-child-stack-name.").option("--cfn-child-stack-name <pair...>", "Per-nested-child CFn stack-name override. Repeatable. Format: '<cdkdName>=<cfnName>' (e.g. --cfn-child-stack-name 'MyApp~Database=my-app-db'). The cdkd stack name for a nested child is '<parent>~<childLogicalId>' (v6 state-key form). Without an override the CFn name is derived by replacing '~' with '-'. Only consulted when the exported stack tree contains nested children; ignored for flat stacks.").option("--template <path>", "Path to a pre-rendered CloudFormation template (JSON or YAML — format auto-detected). Skips synth.").option("--stack-region <region>", "Region of the cdkd state record to operate on. Required when the same stack name has state in multiple regions.", parseStackRegion).option("--dry-run", "Print the import plan without creating a changeset.", false).option("--accept-transient-context", "Allow CLI -c key=value overrides at export time even though they are not persisted to cdk.json / cdk.context.json (default: refuse). When set, the user is responsible for passing the same -c flags to every future cdk deploy.", false).option("--include-non-importable", "Run a 2-phase migration when the stack contains non-importable resources (Custom::*). Phase 1 imports the importable resources; phase 2 CFn-CREATEs the non-importable ones, which re-invokes each Custom Resource's onCreate handler. Make sure onCreate is idempotent before enabling.", false).option("--parameter <key=value...>", "CFn template Parameter override, repeatable. Required when the synthesized template has Parameters without Default values; otherwise overrides the template's default value. Format: --parameter Key=Value.").option("--strict-cross-stack", "Refuse to export when sibling cdkd stacks in the same CDK app reference the exporting stack via Fn::GetStackOutput. Without the flag, cdkd warns and proceeds — the consumers keep resolving via the CloudFormation fallback (weak reference) unless they deploy with --no-cfn-fallback.", false).option("--skip-import-support-preflight", "Skip the pre-flight that refuses resource types whose CloudFormation registry schema says CFn cannot IMPORT them (no read handler AND NON_PROVISIONABLE), and let CreateChangeSet answer instead. The pre-flight is a registry HEURISTIC, not AWS's supported-for-import list, so this is the escape hatch for a type AWS has since made importable. Expect the changeset to be rejected if the heuristic was right.", false).option("--no-recreate-import-unsupported", "Block instead of auto-handling resource types AWS does NOT support in IMPORT changesets (AWS::ApiGatewayV2::Stage and AWS::IAM::Policy). Default behavior: cdkd skips these from phase 1, deletes the AWS-side resource between phases, and lets CFn re-CREATE in phase 2 (brief unavailability window). With this flag, the export aborts with a clear error instead.").action(withErrorHandling(exportCommand));
|
|
74495
74465
|
[
|
|
74496
74466
|
...commonOptions,
|
|
74497
74467
|
...appOptions,
|
|
@@ -75088,14 +75058,14 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
75088
75058
|
logger.info(`No state found for stack: ${stackName}, skipping`);
|
|
75089
75059
|
continue;
|
|
75090
75060
|
}
|
|
75091
|
-
const targets = options.stackRegion ? stackRefs.filter((r) => r.region === options.stackRegion) : stackRefs;
|
|
75061
|
+
const targets = options.stackRegion !== void 0 ? stackRefs.filter((r) => r.region === options.stackRegion) : stackRefs;
|
|
75092
75062
|
if (targets.length === 0) {
|
|
75093
|
-
const seen = stackRefs.map((r) => r.region
|
|
75094
|
-
throw new Error(`No state found for stack '${stackName}' in region '${options.stackRegion}'. Available regions: ${seen}.`);
|
|
75063
|
+
const seen = stackRefs.map((r) => r.region ? displaySafe(r.region, { asciiOnly: true }) || "<unrenderable>" : "(legacy)").join(", ");
|
|
75064
|
+
throw new Error(`No state found for stack '${displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>"}' in region '${displaySafe(options.stackRegion ?? "", { asciiOnly: true })}'. Available regions: ${seen}.`);
|
|
75095
75065
|
}
|
|
75096
75066
|
if (!options.force) {
|
|
75097
75067
|
for (const target of targets) if (await setup.lockManager.isLocked(stackName, target.region)) {
|
|
75098
|
-
const where = target.region ? displaySafe(target.region, { asciiOnly: true }) || "<unrenderable>" : "
|
|
75068
|
+
const where = target.region ? displaySafe(target.region, { asciiOnly: true }) || "<unrenderable>" : "legacy";
|
|
75099
75069
|
throw new Error(`Stack '${displaySafe(stackName, { asciiOnly: true })}' (${where}) is locked. Run: ${buildForceUnlockCommand(stackName, target.region, {
|
|
75100
75070
|
profile: options.profile,
|
|
75101
75071
|
stateBucket: setup.bucket,
|
|
@@ -75105,7 +75075,7 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
75105
75075
|
}
|
|
75106
75076
|
if (!options.yes && !options.force) {
|
|
75107
75077
|
const targetList = targets.map((t) => formatStackRefSafe(t)).join(", ");
|
|
75108
|
-
process.stdout.write(`\nWARNING: This removes cdkd's state record for [${targetList}] only. AWS resources will NOT be deleted.\nUse 'cdkd destroy ${stackName}' if you want to delete the actual resources.\n\n`);
|
|
75078
|
+
process.stdout.write(`\nWARNING: This removes cdkd's state record for [${targetList}] only. AWS resources will NOT be deleted.\nUse 'cdkd destroy ${displaySafe(stackName, { asciiOnly: true }) || "<unrenderable>"}' if you want to delete the actual resources.\n\n`);
|
|
75109
75079
|
if (!await confirmStateOrphanRemoval(`Remove state for ${targetList} from s3://${setup.bucket}/${setup.prefix}/?`)) {
|
|
75110
75080
|
logger.info(`Cancelled removal of state for stack: ${stackName}`);
|
|
75111
75081
|
continue;
|
|
@@ -75118,9 +75088,10 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
75118
75088
|
await setup.lockManager.forceReleaseLock(stackName, target.region);
|
|
75119
75089
|
} else {
|
|
75120
75090
|
await warnOnLiveForeignLock(setup.lockManager, stackName, void 0, logger);
|
|
75091
|
+
await setup.stateBackend.deleteLegacyState(stackName);
|
|
75121
75092
|
await setup.lockManager.forceReleaseLock(stackName, void 0);
|
|
75122
75093
|
}
|
|
75123
|
-
logger.info(`✓ Removed state for stack: ${
|
|
75094
|
+
logger.info(`✓ Removed state for stack: ${formatStackRefSafe(target)}`);
|
|
75124
75095
|
}
|
|
75125
75096
|
}
|
|
75126
75097
|
} finally {
|
|
@@ -75133,7 +75104,7 @@ async function stateOrphanCommand(stackArgs, options) {
|
|
|
75133
75104
|
* `--region` (AWS profile region) defined in `commonOptions`.
|
|
75134
75105
|
*/
|
|
75135
75106
|
function stackRegionOption$1() {
|
|
75136
|
-
return new Option("--stack-region <region>", "Region of the stack record to operate on. Required when the same stack name has state in multiple regions.");
|
|
75107
|
+
return new Option("--stack-region <region>", "Region of the stack record to operate on. Required when the same stack name has state in multiple regions.").argParser(parseStackRegion);
|
|
75137
75108
|
}
|
|
75138
75109
|
/**
|
|
75139
75110
|
* Create the `state orphan` subcommand.
|
|
@@ -75927,7 +75898,7 @@ function createStateCommand() {
|
|
|
75927
75898
|
* in multiple regions (same pattern + messages as the `state` subcommands).
|
|
75928
75899
|
*/
|
|
75929
75900
|
function stackRegionOption() {
|
|
75930
|
-
return new Option("--stack-region <region>", "Region of the target stack when the same name has state in multiple regions");
|
|
75901
|
+
return new Option("--stack-region <region>", "Region of the target stack when the same name has state in multiple regions").argParser(parseStackRegion);
|
|
75931
75902
|
}
|
|
75932
75903
|
/**
|
|
75933
75904
|
* Discover every stack that currently has a rollback journal. One raw key
|
|
@@ -76541,7 +76512,7 @@ function colorizeEventType(eventType) {
|
|
|
76541
76512
|
* Create the `cdkd events` command.
|
|
76542
76513
|
*/
|
|
76543
76514
|
function createEventsCommand() {
|
|
76544
|
-
const cmd = new Command("events").description("Read back structured deployment events (cdkd's DescribeStackEvents equivalent, issue #808)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--run <runId>", "Read a single run's full event stream instead of the run listing").option("--stack-region <region>", "Disambiguate a stack with event history in multiple regions").option("--json", "Output as JSON", false).option("--format <format>", "Output format ('json' is equivalent to --json)").action(withErrorHandling((stack, options) => {
|
|
76515
|
+
const cmd = new Command("events").description("Read back structured deployment events (cdkd's DescribeStackEvents equivalent, issue #808)").argument("<stack>", "Stack name (physical CloudFormation name)").option("--run <runId>", "Read a single run's full event stream instead of the run listing").option("--stack-region <region>", "Disambiguate a stack with event history in multiple regions", parseStackRegion).option("--json", "Output as JSON", false).option("--format <format>", "Output format ('json' is equivalent to --json)").action(withErrorHandling((stack, options) => {
|
|
76545
76516
|
return eventsCommand(stack, {
|
|
76546
76517
|
...options,
|
|
76547
76518
|
json: options.json === true || options.format === "json"
|
|
@@ -78508,7 +78479,7 @@ async function confirmPrompt$1(prompt) {
|
|
|
78508
78479
|
* Create the top-level `cdkd orphan` command.
|
|
78509
78480
|
*/
|
|
78510
78481
|
function createOrphanCommand() {
|
|
78511
|
-
const cmd = new Command("orphan").description("Remove one or more resources from cdkd state by construct path (does NOT delete AWS resources). Mirrors aws-cdk-cli's 'cdk orphan --unstable=orphan'. Synth-driven; for the previous whole-stack-orphan behavior, use 'cdkd state orphan <stack>'.").argument("<paths...>", "Construct paths to orphan, e.g. 'MyStack/MyTable'. Multiple paths must reference the same stack.").option("--stack-region <region>", "Region of the stack record to operate on. Required when the same stack name has state in multiple regions.").option("--dry-run", "Compute and print the rewrite audit table without acquiring a lock or saving state.", false).action(withErrorHandling(orphanCommand));
|
|
78482
|
+
const cmd = new Command("orphan").description("Remove one or more resources from cdkd state by construct path (does NOT delete AWS resources). Mirrors aws-cdk-cli's 'cdk orphan --unstable=orphan'. Synth-driven; for the previous whole-stack-orphan behavior, use 'cdkd state orphan <stack>'.").argument("<paths...>", "Construct paths to orphan, e.g. 'MyStack/MyTable'. Multiple paths must reference the same stack.").option("--stack-region <region>", "Region of the stack record to operate on. Required when the same stack name has state in multiple regions.", parseStackRegion).option("--dry-run", "Compute and print the rewrite audit table without acquiring a lock or saving state.", false).action(withErrorHandling(orphanCommand));
|
|
78512
78483
|
[
|
|
78513
78484
|
...commonOptions,
|
|
78514
78485
|
...appOptions,
|
|
@@ -78797,7 +78768,7 @@ async function forceUnlockCommand(stackArgs, options) {
|
|
|
78797
78768
|
* Create force-unlock command
|
|
78798
78769
|
*/
|
|
78799
78770
|
function createForceUnlockCommand() {
|
|
78800
|
-
const cmd = new Command("force-unlock").description("Force-release a stale lock on a stack").argument("[stacks...]", "Stack name(s) to unlock").addOption(new Option("--stack-region <region>", "Stack region whose lock to release (use when the same stack name has locks in multiple regions). Defaults to all regions where the stack has state.")).action(withErrorHandling(forceUnlockCommand));
|
|
78771
|
+
const cmd = new Command("force-unlock").description("Force-release a stale lock on a stack").argument("[stacks...]", "Stack name(s) to unlock").addOption(new Option("--stack-region <region>", "Stack region whose lock to release (use when the same stack name has locks in multiple regions). Defaults to all regions where the stack has state.").argParser(parseStackRegion)).action(withErrorHandling(forceUnlockCommand));
|
|
78801
78772
|
[
|
|
78802
78773
|
...commonOptions,
|
|
78803
78774
|
...stateOptions,
|
|
@@ -85083,7 +85054,7 @@ function resolveMtlsConfig(options) {
|
|
|
85083
85054
|
* Builder for the `start-api` subcommand. Wired up by `local.ts`.
|
|
85084
85055
|
*/
|
|
85085
85056
|
function createLocalStartApiCommand() {
|
|
85086
|
-
const startApi = new Command("start-api").description("Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required). Supports Lambda TOKEN/REQUEST authorizers, Cognito User Pool / HTTP v2 JWT authorizers, and AWS_IAM auth (REST v1 `AuthorizationType: AWS_IAM` and Function URL `AuthType: AWS_IAM` — SigV4 signature verification only; IAM policy evaluation is NOT emulated; see https://github.com/go-to-k/cdkd/blob/main/docs/local-emulation.md). When JWKS is unreachable, JWT authorizers fall back to pass-through (every token accepted) with a warn line — local dev fallback. VPC-config Lambdas run locally and surface a warn line at startup; their containers do NOT get attached to the deployed VPC subnets, so calls to private RDS / ElastiCache will fail.").argument("[target]", "Optional API filter. Accepts the bare CDK logical id ('MyHttpApi'; single-stack apps only), stack-qualified logical id ('MyStack:MyHttpApi'), full CDK Construct path ('MyStack/MyHttpApi/Resource'), or an ancestor Construct path that prefix-matches ('MyStack/MyHttpApi'). When omitted, every discovered API gets its own server. Mirrors `cdkd local invoke` / `cdkd local run-task` target syntax.").addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(new Option("--warm", "Pre-start one container per Lambda at server boot").default(false)).addOption(new Option("--per-lambda-concurrency <n>", "Pool size cap per Lambda (default 2, max 4)").default("2")).addOption(new Option("--no-pull", "Skip docker pull (cached image)")).addOption(new Option("--container-host <host>", "IP the host uses to bind/probe the RIE port (must be a numeric IP — `docker run -p <ip>:<port>:8080` rejects hostnames). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--debug-port-base <port>", "Reserve a contiguous --debug-port range (one per Lambda)")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--assume-role <arn-or-pair>", "Assume the Lambda's execution role and forward STS-issued temp creds. Two forms: (1) `--assume-role <arn>` sets a single global default ARN used for every routed Lambda; (2) `--assume-role <LogicalId>=<arn>` (repeatable) is a per-Lambda override (wins over the global default and over --assume-role-auto for the named Lambda). Pair with --assume-role-auto to auto-resolve every other Lambda. Precedence: per-Lambda > (--assume-role-auto OR global default) > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--assume-role-auto", "Auto-resolve EACH routed Lambda's own execution role per-Lambda (literal ARN / Fn::GetAtt against template / --from-cfn-stack state). Slower boot — one STS call per Lambda — but the right shape when each Lambda's deployed role differs. Mutually exclusive with `--assume-role <arn>` (global default); errors at boot. Compatible with `--assume-role <LogicalId>=<arn>` per-Lambda overrides — the map wins for named Lambdas, auto-resolve handles the rest.").default(false)).addOption(new Option("--watch", "Hot-reload: watch the CDK app source tree and re-synth + re-discover routes on a source edit (cdk.out / node_modules / .git excluded; honors cdk.json watch.include / watch.exclude). Off by default; the server keeps the previous version serving when synth fails mid-reload.").default(false)).addOption(new Option("--stage <name>", "Select an API Gateway Stage by its 'StageName'. Default: the first Stage attached to each API. Drives event.stageVariables for both REST v1 and HTTP API v2. NOTE: For HTTP API v2 routes, requestContext.stage is always '$default' regardless of this flag (AWS-side limitation — HTTP API only exposes one stage to the integration event); only event.stageVariables is affected for v2 routes. For REST v1 routes the selected StageName is also threaded into requestContext.stage.")).addOption(new Option("--api <id>", "DEPRECATED — use the positional <target> argument instead. Same accepted forms (bare logical id, stack-qualified, Construct path, ancestor prefix). Will be removed in a future major release.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--from-state", "Read cdkd S3 state for every routed stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::Join (and AWS pseudo parameters) in Lambda env vars with the deployed physical IDs / attributes. Off by default — pre-PR warn-and-drop semantics are preserved. Turn on for stacks already deployed via cdkd deploy. Mirrors `cdkd local invoke --from-state` / `cdkd local run-task --from-state`. Re-runs against fresh state on every hot-reload firing (--watch).").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in Lambda env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name per routed stack; pass an explicit value when a single CFn stack should serve every routed stack. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn DescribeStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).")).addOption(new Option("--mtls-truststore <path>", "PEM-encoded CA bundle for client-certificate verification (mutual TLS). When set, the local server switches from HTTP to HTTPS and the TLS handshake rejects clients whose certificate doesn't chain to one of these CAs. Verified certs are surfaced on the Lambda event under requestContext.identity.clientCert (REST v1) / requestContext.authentication.clientCert (HTTP API v2). Must be set together with --mtls-cert + --mtls-key; partial flag sets are rejected. Generate a CA + server + client cert for local dev: openssl req -x509 -newkey rsa:2048 -nodes -keyout ca-key.pem -out ca.pem -subj \"/CN=cdkd-local-ca\" -days 365; openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-csr.pem -subj \"/CN=localhost\"; openssl x509 -req -in server-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365; openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-csr.pem -subj \"/CN=client\"; openssl x509 -req -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365; curl --cacert ca.pem --cert client-cert.pem --key client-key.pem https://localhost:<port>/...")).addOption(new Option("--mtls-cert <path>", "PEM-encoded server certificate for mutual TLS. Self-signed is fine for local dev. Must be set together with --mtls-truststore + --mtls-key.")).addOption(new Option("--mtls-key <path>", "PEM-encoded server private key matching --mtls-cert. Must be set together with --mtls-truststore + --mtls-cert.")).addOption(new Option("--strict-sigv4", "Opt-in: enforce strict AWS_IAM SigV4 verification. When set, requests whose signature cannot be cryptographically verified (foreign access-key-id, OR no local AWS credentials configured) are denied. DEFAULT off — warn-and-pass with a placeholder principalId, matching cdk-local's `cdkl start-api`. Enable this when you want local parity with the deployed API Gateway's signature enforcement.").default(false)).action(withErrorHandling(localStartApiCommand));
|
|
85057
|
+
const startApi = new Command("start-api").description("Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required). Supports Lambda TOKEN/REQUEST authorizers, Cognito User Pool / HTTP v2 JWT authorizers, and AWS_IAM auth (REST v1 `AuthorizationType: AWS_IAM` and Function URL `AuthType: AWS_IAM` — SigV4 signature verification only; IAM policy evaluation is NOT emulated; see https://github.com/go-to-k/cdkd/blob/main/docs/local-emulation.md). When JWKS is unreachable, JWT authorizers fall back to pass-through (every token accepted) with a warn line — local dev fallback. VPC-config Lambdas run locally and surface a warn line at startup; their containers do NOT get attached to the deployed VPC subnets, so calls to private RDS / ElastiCache will fail.").argument("[target]", "Optional API filter. Accepts the bare CDK logical id ('MyHttpApi'; single-stack apps only), stack-qualified logical id ('MyStack:MyHttpApi'), full CDK Construct path ('MyStack/MyHttpApi/Resource'), or an ancestor Construct path that prefix-matches ('MyStack/MyHttpApi'). When omitted, every discovered API gets its own server. Mirrors `cdkd local invoke` / `cdkd local run-task` target syntax.").addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(new Option("--warm", "Pre-start one container per Lambda at server boot").default(false)).addOption(new Option("--per-lambda-concurrency <n>", "Pool size cap per Lambda (default 2, max 4)").default("2")).addOption(new Option("--no-pull", "Skip docker pull (cached image)")).addOption(new Option("--container-host <host>", "IP the host uses to bind/probe the RIE port (must be a numeric IP — `docker run -p <ip>:<port>:8080` rejects hostnames). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--debug-port-base <port>", "Reserve a contiguous --debug-port range (one per Lambda)")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--assume-role <arn-or-pair>", "Assume the Lambda's execution role and forward STS-issued temp creds. Two forms: (1) `--assume-role <arn>` sets a single global default ARN used for every routed Lambda; (2) `--assume-role <LogicalId>=<arn>` (repeatable) is a per-Lambda override (wins over the global default and over --assume-role-auto for the named Lambda). Pair with --assume-role-auto to auto-resolve every other Lambda. Precedence: per-Lambda > (--assume-role-auto OR global default) > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--assume-role-auto", "Auto-resolve EACH routed Lambda's own execution role per-Lambda (literal ARN / Fn::GetAtt against template / --from-cfn-stack state). Slower boot — one STS call per Lambda — but the right shape when each Lambda's deployed role differs. Mutually exclusive with `--assume-role <arn>` (global default); errors at boot. Compatible with `--assume-role <LogicalId>=<arn>` per-Lambda overrides — the map wins for named Lambdas, auto-resolve handles the rest.").default(false)).addOption(new Option("--watch", "Hot-reload: watch the CDK app source tree and re-synth + re-discover routes on a source edit (cdk.out / node_modules / .git excluded; honors cdk.json watch.include / watch.exclude). Off by default; the server keeps the previous version serving when synth fails mid-reload.").default(false)).addOption(new Option("--stage <name>", "Select an API Gateway Stage by its 'StageName'. Default: the first Stage attached to each API. Drives event.stageVariables for both REST v1 and HTTP API v2. NOTE: For HTTP API v2 routes, requestContext.stage is always '$default' regardless of this flag (AWS-side limitation — HTTP API only exposes one stage to the integration event); only event.stageVariables is affected for v2 routes. For REST v1 routes the selected StageName is also threaded into requestContext.stage.")).addOption(new Option("--api <id>", "DEPRECATED — use the positional <target> argument instead. Same accepted forms (bare logical id, stack-qualified, Construct path, ancestor prefix). Will be removed in a future major release.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--from-state", "Read cdkd S3 state for every routed stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::Join (and AWS pseudo parameters) in Lambda env vars with the deployed physical IDs / attributes. Off by default — pre-PR warn-and-drop semantics are preserved. Turn on for stacks already deployed via cdkd deploy. Mirrors `cdkd local invoke --from-state` / `cdkd local run-task --from-state`. Re-runs against fresh state on every hot-reload firing (--watch).").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in Lambda env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name per routed stack; pass an explicit value when a single CFn stack should serve every routed stack. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn DescribeStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).addOption(new Option("--mtls-truststore <path>", "PEM-encoded CA bundle for client-certificate verification (mutual TLS). When set, the local server switches from HTTP to HTTPS and the TLS handshake rejects clients whose certificate doesn't chain to one of these CAs. Verified certs are surfaced on the Lambda event under requestContext.identity.clientCert (REST v1) / requestContext.authentication.clientCert (HTTP API v2). Must be set together with --mtls-cert + --mtls-key; partial flag sets are rejected. Generate a CA + server + client cert for local dev: openssl req -x509 -newkey rsa:2048 -nodes -keyout ca-key.pem -out ca.pem -subj \"/CN=cdkd-local-ca\" -days 365; openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-csr.pem -subj \"/CN=localhost\"; openssl x509 -req -in server-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365; openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-csr.pem -subj \"/CN=client\"; openssl x509 -req -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365; curl --cacert ca.pem --cert client-cert.pem --key client-key.pem https://localhost:<port>/...")).addOption(new Option("--mtls-cert <path>", "PEM-encoded server certificate for mutual TLS. Self-signed is fine for local dev. Must be set together with --mtls-truststore + --mtls-key.")).addOption(new Option("--mtls-key <path>", "PEM-encoded server private key matching --mtls-cert. Must be set together with --mtls-truststore + --mtls-cert.")).addOption(new Option("--strict-sigv4", "Opt-in: enforce strict AWS_IAM SigV4 verification. When set, requests whose signature cannot be cryptographically verified (foreign access-key-id, OR no local AWS credentials configured) are denied. DEFAULT off — warn-and-pass with a placeholder principalId, matching cdk-local's `cdkl start-api`. Enable this when you want local parity with the deployed API Gateway's signature enforcement.").default(false)).action(withErrorHandling(localStartApiCommand));
|
|
85087
85058
|
[
|
|
85088
85059
|
...commonOptions,
|
|
85089
85060
|
...appOptions,
|
|
@@ -86319,7 +86290,7 @@ async function resolveSidecarCredentials(options, assumedCredentials) {
|
|
|
86319
86290
|
if (options.profile) return resolveProfileCredentials(options.profile);
|
|
86320
86291
|
}
|
|
86321
86292
|
function createLocalRunTaskCommand() {
|
|
86322
|
-
const cmd = new Command("run-task").description("Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID (MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run").addOption(new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default("cdkd-local")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})")).addOption(new Option("--container-host <ip>", "Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)").default("127.0.0.1")).addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed function role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.")).addOption(new Option("--no-pull", "Skip docker pull for every container image and the metadata sidecar")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries (#455). Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--platform <platform>", "Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture")).addOption(new Option("--keep-running", "Don't docker rm -f the user containers on task exit (network + sidecar are still torn down). Use when you want to docker exec into a stopped container for post-mortems.").default(false)).addOption(new Option("--detach", "Start the containers in the background and exit (skip log streaming + auto teardown). Useful in CI smoke tests; caller manages container lifecycle.").default(false)).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Fn::Sub / Fn::GetAtt references to same-stack AWS::ECR::Repository resources with the deployed URI. Off by default — only the AWS pseudo-parameter tier (${AWS::AccountId} / ${AWS::Region}) is resolved without this flag.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in container env vars / secrets / image URIs with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn DescribeStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).")).action(withErrorHandling(localRunTaskCommand));
|
|
86293
|
+
const cmd = new Command("run-task").description("Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID (MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run").addOption(new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default("cdkd-local")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})")).addOption(new Option("--container-host <ip>", "Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)").default("127.0.0.1")).addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed function role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.")).addOption(new Option("--no-pull", "Skip docker pull for every container image and the metadata sidecar")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries (#455). Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--platform <platform>", "Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture")).addOption(new Option("--keep-running", "Don't docker rm -f the user containers on task exit (network + sidecar are still torn down). Use when you want to docker exec into a stopped container for post-mortems.").default(false)).addOption(new Option("--detach", "Start the containers in the background and exit (skip log streaming + auto teardown). Useful in CI smoke tests; caller manages container lifecycle.").default(false)).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Fn::Sub / Fn::GetAtt references to same-stack AWS::ECR::Repository resources with the deployed URI. Off by default — only the AWS pseudo-parameter tier (${AWS::AccountId} / ${AWS::Region}) is resolved without this flag.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in container env vars / secrets / image URIs with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn DescribeStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).action(withErrorHandling(localRunTaskCommand));
|
|
86323
86294
|
[
|
|
86324
86295
|
...commonOptions,
|
|
86325
86296
|
...appOptions,
|
|
@@ -87743,7 +87714,7 @@ function readEnvOverridesFile$1(filePath) {
|
|
|
87743
87714
|
return parsed;
|
|
87744
87715
|
}
|
|
87745
87716
|
function createLocalInvokeAgentCoreCommand() {
|
|
87746
|
-
const cmd = new Command("invoke-agentcore").description("Run a Bedrock AgentCore Runtime container locally and invoke it once over its protocol contract: HTTP (POST /invocations + GET /ping on 8080) or MCP (POST /mcp Streamable HTTP on 8000). Resolves the AWS::BedrockAgentCore::Runtime, pulls/builds its container, injects env vars + AWS credentials, and prints the response. For an MCP runtime, runs the session handshake then sends one JSON-RPC request (tools/list by default, or the method/params from --event). Target accepts a CDK display path (MyStack/MyAgent) or stack-qualified logical ID (MyStack:MyAgentRuntime1234). Single-stack apps may omit the stack prefix. Omit <target> in an interactive terminal to pick from a list. Supports the container artifact and the CodeConfiguration managed-runtime artifact (fromCodeAsset, built from source) on the HTTP + MCP protocols; the agent calls real AWS for managed services.").argument("[target]", "CDK display path or stack-qualified logical ID of the AgentCore Runtime to invoke (omit to pick interactively in a TTY)").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. When stdin is a TTY, auto-enters a REPL — each typed line is sent as a follow-up text frame until Ctrl-D / agent close; pipe from /dev/null to force one-shot in a TTY. Ignored for an MCP runtime.").default(false)).addOption(new Option("--watch", "Re-synth and reload the agent container on CDK source changes (follows cdk-local #270). Supported on the HTTP / AGUI protocols, both the --ws session AND the default one-shot POST /invocations (the reload re-runs the single shot). An interpreted-language source edit inside a CodeConfiguration source tree takes a soft-reload fast path (docker cp + docker restart, no rebuild); Dockerfile / compiled-source / asset-hash-changed / ambiguous edits force a full rebuild. For MCP / A2A runtimes --watch is a no-op WARN and the single shot proceeds.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64)").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host to bind the agent port to").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-state", "Load cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue in env vars with the deployed physical IDs / cross-stack exports. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. For CDK apps deployed via the upstream CDK CLI. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).action(withErrorHandling(async (target, options) => {
|
|
87717
|
+
const cmd = new Command("invoke-agentcore").description("Run a Bedrock AgentCore Runtime container locally and invoke it once over its protocol contract: HTTP (POST /invocations + GET /ping on 8080) or MCP (POST /mcp Streamable HTTP on 8000). Resolves the AWS::BedrockAgentCore::Runtime, pulls/builds its container, injects env vars + AWS credentials, and prints the response. For an MCP runtime, runs the session handshake then sends one JSON-RPC request (tools/list by default, or the method/params from --event). Target accepts a CDK display path (MyStack/MyAgent) or stack-qualified logical ID (MyStack:MyAgentRuntime1234). Single-stack apps may omit the stack prefix. Omit <target> in an interactive terminal to pick from a list. Supports the container artifact and the CodeConfiguration managed-runtime artifact (fromCodeAsset, built from source) on the HTTP + MCP protocols; the agent calls real AWS for managed services.").argument("[target]", "CDK display path or stack-qualified logical ID of the AgentCore Runtime to invoke (omit to pick interactively in a TTY)").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. When stdin is a TTY, auto-enters a REPL — each typed line is sent as a follow-up text frame until Ctrl-D / agent close; pipe from /dev/null to force one-shot in a TTY. Ignored for an MCP runtime.").default(false)).addOption(new Option("--watch", "Re-synth and reload the agent container on CDK source changes (follows cdk-local #270). Supported on the HTTP / AGUI protocols, both the --ws session AND the default one-shot POST /invocations (the reload re-runs the single shot). An interpreted-language source edit inside a CodeConfiguration source tree takes a soft-reload fast path (docker cp + docker restart, no rebuild); Dockerfile / compiled-source / asset-hash-changed / ambiguous edits force a full rebuild. For MCP / A2A runtimes --watch is a no-op WARN and the single shot proceeds.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64)").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host to bind the agent port to").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-state", "Load cdkd's S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub / Fn::ImportValue in env vars with the deployed physical IDs / cross-stack exports. Mutually exclusive with --from-cfn-stack.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. For CDK apps deployed via the upstream CDK CLI. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs. Mutually exclusive with --from-state.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.").argParser(parseStackRegion)).action(withErrorHandling(async (target, options) => {
|
|
87747
87718
|
await localInvokeAgentCoreCommand(target, options);
|
|
87748
87719
|
}));
|
|
87749
87720
|
[
|
|
@@ -88743,7 +88714,7 @@ function pickReferencedLogicalId(intrinsic) {
|
|
|
88743
88714
|
function createLocalCommand() {
|
|
88744
88715
|
setEmbedConfig(CDKD_EMBED_CONFIG);
|
|
88745
88716
|
const local = new Command("local").description("Local execution of Lambda functions (RIE) and ECS task definitions (Docker required)");
|
|
88746
|
-
const invoke = new Command("invoke").description("Run a Lambda function locally in a Docker container (RIE-backed). Target accepts a CDK display path (MyStack/MyApi/Handler) or stack-qualified logical ID (MyStack:MyApiHandler1234ABCD). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the Lambda to invoke").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for IMAGE local-build path; `docker build` does not pull base layers by default")).addOption(new Option("--no-build", "Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(new Option("--container-host <host>", "Host to bind the RIE port to").default("127.0.0.1")).addOption(new Option("--assume-role [arn]", "Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions (closes the \"developer admin / function narrow\" skew). Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) auto-resolves the function's execution role ARN from cdkd state (requires --from-state); (3) `--no-assume-role` explicitly opts out (forces dev creds even with --from-state). Off by default — when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries (#455). Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub in env vars with the deployed physical IDs / attributes. Off by default — keep PR 1 warn-and-drop semantics; turn on for stacks already deployed via cdkd deploy.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn DescribeStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).")).action(withErrorHandling(localInvokeCommand));
|
|
88717
|
+
const invoke = new Command("invoke").description("Run a Lambda function locally in a Docker container (RIE-backed). Target accepts a CDK display path (MyStack/MyApi/Handler) or stack-qualified logical ID (MyStack:MyApiHandler1234ABCD). Single-stack apps may omit the stack prefix.").argument("<target>", "CDK display path or stack-qualified logical ID of the Lambda to invoke").addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for IMAGE local-build path; `docker build` does not pull base layers by default")).addOption(new Option("--no-build", "Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(new Option("--container-host <host>", "Host to bind the RIE port to").default("127.0.0.1")).addOption(new Option("--assume-role [arn]", "Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions (closes the \"developer admin / function narrow\" skew). Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) auto-resolves the function's execution role ARN from cdkd state (requires --from-state); (3) `--no-assume-role` explicitly opts out (forces dev creds even with --from-state). Off by default — when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries (#455). Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-state", "Read cdkd S3 state for the target stack and substitute Ref / Fn::GetAtt / Fn::Sub in env vars with the deployed physical IDs / attributes. Off by default — keep PR 1 warn-and-drop semantics; turn on for stacks already deployed via cdkd deploy.").default(false)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via DescribeStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the cdkd stack name; pass an explicit value when CFn stack name differs. Mutually exclusive with --from-state. Fn::GetAtt is warn-and-dropped in v1 (CFn DescribeStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-state when the same stack name has state in multiple regions, and with --from-cfn-stack as the CFn client region (cdkd does not have a separate --cfn-stack-region flag).").argParser(parseStackRegion)).action(withErrorHandling(localInvokeCommand));
|
|
88747
88718
|
[
|
|
88748
88719
|
...commonOptions,
|
|
88749
88720
|
...appOptions,
|
|
@@ -89876,9 +89847,10 @@ function buildProgram() {
|
|
|
89876
89847
|
program.addCommand(createLocalCommand());
|
|
89877
89848
|
program.addCommand(createExportCommand());
|
|
89878
89849
|
program.addCommand(createMigrateCommand());
|
|
89850
|
+
guardStackRegionOptions(program);
|
|
89879
89851
|
return program;
|
|
89880
89852
|
}
|
|
89881
89853
|
|
|
89882
89854
|
//#endregion
|
|
89883
89855
|
export { buildProgram };
|
|
89884
|
-
//# sourceMappingURL=program-
|
|
89856
|
+
//# sourceMappingURL=program-C-xfsrSP.js.map
|