@go-to-k/cdkd 0.280.30 → 0.280.32

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/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigObject, $t as AssemblyReader, A as green, At as runDockerForeground, B as disableInstanceApiTermination, Bt as resolveCaptureObservedState, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackTerminationProtectionError, Ct as getBootstrapMarkerKey, D as bold, Dt as buildDockerImage, E as formatResourceLine, Et as validateContainerRepoName, F as clearOnUpdateRemoval, Ft as synthesisStatusMessage, G as WAFv2WebACLProvider, Gt as stateBucketExistenceConfirmed, H as IntrinsicFunctionResolver, Ht as resolveStateBucketWithDefault, I as ProviderRegistry, It as getDefaultStateBucketName, J as assertRegionMatch, Jt as CFN_TEMPLATE_URL_LIMIT, K as normalizeAwsTagsToCfn, Kt as warnDeprecatedNoPrefixCliFlag, L as findActionableSilentDrops, Lt as getLegacyStateBucketName, M as yellow, Mt as AssetManifestLoader, N as IAMRoleProvider, Nt as getDockerImageBySourceHash, O as cyan, On as normalizeAwsError, Ot as formatDockerLoginError, P as collectInlinePolicyNamesManagedBySiblings, Pt as Synthesizer, Q as requireConfigArray, Qt as expectedOwnerParam, R as CloudControlProvider, Rt as resolveApp, S as extractDeploymentEventError, Sn as StackHasActiveImportsError, St as ensureAssetStorage, T as renderStatefulReason, Tt as validateAssetBucketName, U as cfnRefValueFromPhysicalId, Ut as resolveStateBucketWithDefaultAndSource, V as isTerminationProtectionPropagationError, Vt as resolveSkipPrefix, W as refStateLookupFromResource, Wt as resolveUseCdkBootstrapAssets, X as readConfigString, Xt as findLargeInlineResources, Y as configStringRefusal, Yt as MIGRATE_TMP_PREFIX, Z as replayWarn, Zt as uploadCfnTemplate, _ as createPreDeleteFinalSnapshot, _n as NestedStackChildDirectDestroyError, _t as createAssetRedirectResolver, a as DeploymentEventsStore, an as resetAwsClients, at as isRetryableTransientError, b as unsupportedFinalSnapshotError, bn as ResourceTimeoutError, bt as AssetModeResolver, c as replayFailedOperations, cn as CdkdError, ct as TemplateParser, d as IMPLICIT_DELETE_DEPENDENCIES, dn as DeployCancelledError, dt as rebuildClientForBucketRegion, en as processStackMessages, et as requireConfigString, f as computeImplicitDeleteEdges, fn as LocalInvokeBuildError$1, ft as shouldRetainResource, g as ccRoutedFinalSnapshotError, gn as MissingCdkCliError, gt as buildAssetRedirectMap, h as buildFinalSnapshotIdentifier, ht as WorkGraph, i as DeploymentEventsReader, in as getAwsClients, it as withRetry, j as red, jt as runDockerStreaming, k as gray, kn as withErrorHandling, kt as getDockerCmd, l as replayRollback, lt as LockManager, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalStartServiceError, mt as stringifyValue, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resolveBucketRegion, nt as DiffCalculator, o as planFailedOps, on as setAwsClients, ot as isThrottlingError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalMigrateError, pt as AssetPublisher, q as resolveExplicitPhysicalId, qt as CFN_TEMPLATE_BODY_LIMIT, r as DeployEngine, rn as AwsClients, rt as describeTypeWithThrottleRetry, s as planRollback, st as DagBuilder, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as applyRoleArnIfSet, u as withResourceDeadline, ut as S3StateBackend, v as isFinalSnapshotError, vn as PartialFailureError, vt as loadPublishableAssetManifest, w as isStatefulRecreateTargetSync, wt as parseBootstrapMarker, x as makeCanonicalizePropertiesFn, xn as ResourceUpdateNotSupportedError, xt as BOOTSTRAP_MARKER_PREFIX, y as refusesFinalSnapshot, yn as ProvisioningError, yt as rewriteTemplateAssetReferences, z as slowCcOperationTimeoutMs, zt as resolveAutoAssetStorage } from "./deploy-engine-POCXyXPl.js";
3
- import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
4
- import { t as ASGProvider } from "./asg-provider-DZ05yRbJ.js";
2
+ import { $ as requireConfigObject, $t as AssemblyReader, A as green, At as runDockerForeground, B as disableInstanceApiTermination, Bt as resolveCaptureObservedState, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackTerminationProtectionError, Ct as getBootstrapMarkerKey, D as bold, Dt as buildDockerImage, E as formatResourceLine, Et as validateContainerRepoName, F as clearOnUpdateRemoval, Ft as synthesisStatusMessage, G as WAFv2WebACLProvider, Gt as stateBucketExistenceConfirmed, H as IntrinsicFunctionResolver, Ht as resolveStateBucketWithDefault, I as ProviderRegistry, It as getDefaultStateBucketName, J as assertRegionMatch, Jt as CFN_TEMPLATE_URL_LIMIT, K as normalizeAwsTagsToCfn, Kt as warnDeprecatedNoPrefixCliFlag, L as findActionableSilentDrops, Lt as getLegacyStateBucketName, M as yellow, Mt as AssetManifestLoader, N as IAMRoleProvider, Nt as getDockerImageBySourceHash, O as cyan, On as normalizeAwsError, Ot as formatDockerLoginError, P as collectInlinePolicyNamesManagedBySiblings, Pt as Synthesizer, Q as requireConfigArray, Qt as expectedOwnerParam, R as CloudControlProvider, Rt as resolveApp, S as extractDeploymentEventError, Sn as StackHasActiveImportsError, St as ensureAssetStorage, T as renderStatefulReason, Tt as validateAssetBucketName, U as cfnRefValueFromPhysicalId, Ut as resolveStateBucketWithDefaultAndSource, V as isTerminationProtectionPropagationError, Vt as resolveSkipPrefix, W as refStateLookupFromResource, Wt as resolveUseCdkBootstrapAssets, X as readConfigString, Xt as findLargeInlineResources, Y as configStringRefusal, Yt as MIGRATE_TMP_PREFIX, Z as replayWarn, Zt as uploadCfnTemplate, _ as createPreDeleteFinalSnapshot, _n as NestedStackChildDirectDestroyError, _t as createAssetRedirectResolver, a as DeploymentEventsStore, an as resetAwsClients, at as isRetryableTransientError, b as unsupportedFinalSnapshotError, bn as ResourceTimeoutError, bt as AssetModeResolver, c as replayFailedOperations, cn as CdkdError, ct as TemplateParser, d as IMPLICIT_DELETE_DEPENDENCIES, dn as DeployCancelledError, dt as rebuildClientForBucketRegion, en as processStackMessages, et as requireConfigString, f as computeImplicitDeleteEdges, fn as LocalInvokeBuildError$1, ft as shouldRetainResource, g as ccRoutedFinalSnapshotError, gn as MissingCdkCliError, gt as buildAssetRedirectMap, h as buildFinalSnapshotIdentifier, ht as WorkGraph, i as DeploymentEventsReader, in as getAwsClients, it as withRetry, j as red, jt as runDockerStreaming, k as gray, kn as withErrorHandling, kt as getDockerCmd, l as replayRollback, lt as LockManager, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalStartServiceError, mt as stringifyValue, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resolveBucketRegion, nt as DiffCalculator, o as planFailedOps, on as setAwsClients, ot as isThrottlingError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalMigrateError, pt as AssetPublisher, q as resolveExplicitPhysicalId, qt as CFN_TEMPLATE_BODY_LIMIT, r as DeployEngine, rn as AwsClients, rt as describeTypeWithThrottleRetry, s as planRollback, st as DagBuilder, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as applyRoleArnIfSet, u as withResourceDeadline, ut as S3StateBackend, v as isFinalSnapshotError, vn as PartialFailureError, vt as loadPublishableAssetManifest, w as isStatefulRecreateTargetSync, wt as parseBootstrapMarker, x as makeCanonicalizePropertiesFn, xn as ResourceUpdateNotSupportedError, xt as BOOTSTRAP_MARKER_PREFIX, y as refusesFinalSnapshot, yn as ProvisioningError, yt as rewriteTemplateAssetReferences, z as slowCcOperationTimeoutMs, zt as resolveAutoAssetStorage } from "./deploy-engine-REAC5UGa.js";
3
+ import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
4
+ import { t as ASGProvider } from "./asg-provider-l4OlfWQo.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  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";
@@ -52990,7 +52990,7 @@ async function driftCommand(stacks, options) {
52990
52990
  return;
52991
52991
  }
52992
52992
  if (options.accept) await runAccept(reports, stateBackend, stateConfig, awsClients, options);
52993
- else await runRevert(reports, providerRegistry, stateConfig, awsClients, options);
52993
+ else await runRevert(reports, providerRegistry, stateBackend, stateConfig, awsClients, options);
52994
52994
  } finally {
52995
52995
  awsClients.destroy();
52996
52996
  }
@@ -53716,6 +53716,69 @@ function buildRevertNewProperties(drifts, desiredProperties, awsProperties, opti
53716
53716
  return result;
53717
53717
  }
53718
53718
  /**
53719
+ * The top-level keys a provider NARROWED on the revert path (issue #1644).
53720
+ *
53721
+ * `provider.update()` may answer with `effectiveProperties` — the bag it
53722
+ * ACTUALLY delivered, which is what AWS now holds. `DeployEngine` records that
53723
+ * in place of the desired bag (`propertiesToRecord`), and `--revert` used to
53724
+ * throw the return value away: state kept the un-narrowed value, so the very
53725
+ * next `cdkd drift` reported the same difference and `--revert` re-issued the
53726
+ * same call — the loop `effectiveProperties` exists to break, still live on
53727
+ * this one command.
53728
+ *
53729
+ * Returns a per-key DELTA rather than the whole bag, and that is the load-
53730
+ * bearing part. The bag handed to `update()` here is
53731
+ * {@link buildRevertNewProperties}'s output — AWS-current values for every
53732
+ * non-drifted key merged with the state baseline for the drifted ones — so
53733
+ * writing it back wholesale would import AWS-authored values into state for
53734
+ * keys nobody reverted, quietly turning `--revert` into `--accept`. Only the
53735
+ * keys the PROVIDER changed between what it was handed and what it delivered
53736
+ * belong in state.
53737
+ *
53738
+ * A key present in `sent` but absent from `effective` is a DROP: the provider
53739
+ * did not deliver it, so AWS does not hold it, and the baseline must lose it
53740
+ * too. That is represented by an explicit `undefined` value, which the caller
53741
+ * turns into a `delete` — a plain `{...baseline, ...delta}` spread would leave
53742
+ * an `undefined`-valued key in the JSON instead. Presence is decided by
53743
+ * `key in effective`, NOT by comparing against `undefined`: a provider that
53744
+ * delivers an explicit `undefined` and one that omits the key both mean "AWS
53745
+ * does not hold it", while a key whose value genuinely IS `null` on both sides
53746
+ * must not read as a drop.
53747
+ *
53748
+ * The comparison is a key-order-INDEPENDENT deep equality rather than
53749
+ * `JSON.stringify`. A provider that rebuilds a nested object while delivering
53750
+ * the same members would otherwise register as a change, and the value written
53751
+ * back for such a key is the one that was SENT — for a non-drifted key that is
53752
+ * the AWS-current value, i.e. the `--accept` behavior this delta exists to
53753
+ * prevent.
53754
+ */
53755
+ function collectNarrowedTopLevelKeys(sent, effective) {
53756
+ const delta = {};
53757
+ for (const key of /* @__PURE__ */ new Set([...Object.keys(sent), ...Object.keys(effective)])) {
53758
+ const inSent = key in sent;
53759
+ const inEffective = key in effective;
53760
+ if (inSent && inEffective && deepEqualUnordered(sent[key], effective[key])) continue;
53761
+ if (!inSent && !inEffective) continue;
53762
+ delta[key] = inEffective ? effective[key] : void 0;
53763
+ }
53764
+ return delta;
53765
+ }
53766
+ /** Deep equality that does not depend on object key ORDER. */
53767
+ function deepEqualUnordered(a, b) {
53768
+ if (a === b) return true;
53769
+ if (a == null || b == null) return a === b;
53770
+ if (typeof a !== "object" || typeof b !== "object") return false;
53771
+ if (Array.isArray(a) || Array.isArray(b)) {
53772
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
53773
+ return a.every((v, i) => deepEqualUnordered(v, b[i]));
53774
+ }
53775
+ const ao = a;
53776
+ const bo = b;
53777
+ const ak = Object.keys(ao);
53778
+ if (ak.length !== Object.keys(bo).length) return false;
53779
+ return ak.every((k) => Object.prototype.hasOwnProperty.call(bo, k) && deepEqualUnordered(ao[k], bo[k]));
53780
+ }
53781
+ /**
53719
53782
  * `--revert`: AWS ← state.
53720
53783
  *
53721
53784
  * For each drifted resource, call `provider.update(logicalId, physicalId,
@@ -53731,13 +53794,15 @@ function buildRevertNewProperties(drifts, desiredProperties, awsProperties, opti
53731
53794
  * truth, captured during the drift read so we don't re-issue it).
53732
53795
  *
53733
53796
  * Per-resource failures are collected and surface as `PartialFailureError`
53734
- * (exit 2) at the end. State is NOT updated by `--revert` — once the
53735
- * update succeeds, AWS values match state by definition.
53797
+ * (exit 2) at the end. State is otherwise NOT updated by `--revert` — once the
53798
+ * update succeeds, AWS values match state by definition. The ONE exception is
53799
+ * a provider-reported NARROWING (issue #1644): see
53800
+ * {@link collectNarrowedTopLevelKeys}.
53736
53801
  *
53737
53802
  * The per-stack lock is acquired before any update so a concurrent
53738
53803
  * `cdkd deploy` cannot race the in-flight property changes.
53739
53804
  */
53740
- async function runRevert(reports, providerRegistry, stateConfig, awsClients, options) {
53805
+ async function runRevert(reports, providerRegistry, stateBackend, stateConfig, awsClients, options) {
53741
53806
  const logger = getLogger();
53742
53807
  printRevertPlan(reports);
53743
53808
  if (options.dryRun) {
@@ -53760,6 +53825,7 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
53760
53825
  const driftedOutcomes = report.outcomes.filter((o) => o.kind === "drifted");
53761
53826
  if (driftedOutcomes.length === 0) continue;
53762
53827
  await lockManager.acquireLock(report.stackName, report.region, owner, "drift-revert");
53828
+ const narrowedByLogicalId = /* @__PURE__ */ new Map();
53763
53829
  try {
53764
53830
  await runWithConcurrency(driftedOutcomes.map((outcome) => async () => {
53765
53831
  const stateResource = report.state.resources[outcome.logicalId];
@@ -53775,9 +53841,17 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
53775
53841
  const desiredProperties = stateResource.observedProperties ?? stateResource.properties ?? {};
53776
53842
  const newProperties = buildRevertNewProperties(outcome.changes, desiredProperties, outcome.awsProperties, { preserveUntemplated: stateResource.observedProperties === void 0 });
53777
53843
  try {
53778
- await withRetry(() => provider.update(outcome.logicalId, stateResource.physicalId, outcome.resourceType, newProperties, outcome.awsProperties), outcome.logicalId, { logger: { debug: (msg) => logger.debug(msg) } });
53844
+ const updateResult = await withRetry(() => provider.update(outcome.logicalId, stateResource.physicalId, outcome.resourceType, newProperties, outcome.awsProperties), outcome.logicalId, { logger: { debug: (msg) => logger.debug(msg) } });
53779
53845
  totalSucceeded++;
53780
53846
  logger.info(` ✓ ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): reverted.`);
53847
+ try {
53848
+ if (updateResult?.effectiveProperties) {
53849
+ const delta = collectNarrowedTopLevelKeys(newProperties, updateResult.effectiveProperties);
53850
+ if (Object.keys(delta).length > 0) narrowedByLogicalId.set(outcome.logicalId, delta);
53851
+ }
53852
+ } catch (captureErr) {
53853
+ logger.warn(` ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): reverted, but the provider's reported effective properties could not be read — ${captureErr instanceof Error ? captureErr.message : String(captureErr)}`);
53854
+ }
53781
53855
  } catch (err) {
53782
53856
  if (err instanceof ResourceUpdateNotSupportedError) {
53783
53857
  totalUnsupported++;
@@ -53789,6 +53863,52 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
53789
53863
  logger.error(` ✗ ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): AWS update failed — ${msg}`);
53790
53864
  }
53791
53865
  }), concurrency);
53866
+ if (narrowedByLogicalId.size > 0) {
53867
+ const resources = { ...report.state.resources };
53868
+ let recordedCount = 0;
53869
+ for (const [logicalId, delta] of narrowedByLogicalId) {
53870
+ const existing = resources[logicalId];
53871
+ if (!existing) continue;
53872
+ const hasObserved = existing.observedProperties !== void 0;
53873
+ const baselineSource = hasObserved ? existing.observedProperties : existing.properties;
53874
+ const newBaseline = JSON.parse(JSON.stringify(baselineSource ?? {}));
53875
+ let changed = false;
53876
+ for (const [key, value] of Object.entries(delta)) {
53877
+ if (!Object.prototype.hasOwnProperty.call(newBaseline, key)) continue;
53878
+ if (value === void 0) {
53879
+ delete newBaseline[key];
53880
+ changed = true;
53881
+ continue;
53882
+ }
53883
+ if (!hasObserved) continue;
53884
+ newBaseline[key] = value;
53885
+ changed = true;
53886
+ }
53887
+ if (!changed) continue;
53888
+ recordedCount++;
53889
+ resources[logicalId] = hasObserved ? {
53890
+ ...existing,
53891
+ observedProperties: newBaseline
53892
+ } : {
53893
+ ...existing,
53894
+ properties: newBaseline
53895
+ };
53896
+ }
53897
+ if (recordedCount === 0) continue;
53898
+ const newState = {
53899
+ ...report.state,
53900
+ resources,
53901
+ lastModified: Date.now()
53902
+ };
53903
+ const saveOptions = { expectedEtag: report.etag };
53904
+ if (report.migrationPending) saveOptions.migrateLegacy = true;
53905
+ try {
53906
+ await stateBackend.saveState(report.stackName, report.region, newState, saveOptions);
53907
+ logger.info(`✓ State updated for ${report.stackName} (${report.region}): recorded the value the provider actually applied on ${recordedCount} resource(s).`);
53908
+ } catch (err) {
53909
+ logger.warn(`Reverted ${report.stackName} (${report.region}), but could not record the value the provider actually applied: ${err instanceof Error ? err.message : String(err)}. The next 'cdkd drift' will report the same difference — re-run 'cdkd drift ${report.stackName} --revert' once the state write can succeed.`);
53910
+ }
53911
+ }
53792
53912
  } finally {
53793
53913
  await lockManager.releaseLock(report.stackName, report.region).catch((err) => {
53794
53914
  logger.warn(`Failed to release lock for ${report.stackName} (${report.region}): ` + (err instanceof Error ? err.message : String(err)));
@@ -70802,7 +70922,7 @@ function createMigrateCommand() {
70802
70922
  */
70803
70923
  function buildProgram() {
70804
70924
  const program = new Command();
70805
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.30");
70925
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.32");
70806
70926
  program.hook("preAction", (_thisCommand, actionCommand) => {
70807
70927
  const { profile } = actionCommand.optsWithGlobals();
70808
70928
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;