@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.
@@ -1,4 +1,4 @@
1
- import { a as getLiveRenderer, d as generateResourceNameWithFallback, l as applyDefaultNameForFallback, n as getLogger, p as withStackName, u as generateResourceName } from "./logger-BYMEE-BS.js";
1
+ import { a as getLiveRenderer, d as generateResourceNameWithFallback, f as getCurrentStackName, h as withStackName, l as applyDefaultNameForFallback, n as getLogger, p as looksLikeCdkdGeneratedName, u as generateResourceName } from "./logger-zRrlbaQt.js";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
4
4
  import { CloudControlClient, CreateResourceCommand, DeleteResourceCommand, GetResourceCommand, GetResourceRequestStatusCommand, ListResourcesCommand, UpdateResourceCommand } from "@aws-sdk/client-cloudcontrol";
@@ -12872,7 +12872,7 @@ var CloudControlProvider = class {
12872
12872
  if (context?.finalSnapshotIdentifier !== void 0) throw new ProvisioningError(`${logicalId} (${resourceType}) requires a final snapshot (DeletionPolicy: Snapshot), but the Cloud Control API delete route has no final-snapshot parameter. Re-run with --skip-final-snapshot after snapshotting manually, or retain the resource.`, resourceType, logicalId, physicalId);
12873
12873
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
12874
12874
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
12875
- const { ASGProvider } = await import("./asg-provider-DZ05yRbJ.js").then((n) => n.n);
12875
+ const { ASGProvider } = await import("./asg-provider-l4OlfWQo.js").then((n) => n.n);
12876
12876
  await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
12877
12877
  return;
12878
12878
  }
@@ -19013,13 +19013,16 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
19013
19013
  * - **Interrupt.** `replayRollback` polls interrupts only BETWEEN ops, so an
19014
19014
  * un-threaded `isInterrupted` leaves Ctrl-C dead for the length of the
19015
19015
  * backoff schedule (~47s) per op.
19016
+ *
19017
+ * Returns the provider's result so the caller can honour
19018
+ * `effectiveProperties` (issue #1644) — both revert arms used to write the
19019
+ * previous state record back verbatim, dropping a narrowing the provider had
19020
+ * just announced and leaving the record describing something AWS does not
19021
+ * hold.
19016
19022
  */
19017
19023
  async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted) {
19018
- if (provider.disableOuterRetry) {
19019
- await provider.update(...args);
19020
- return;
19021
- }
19022
- await withRetry(() => provider.update(...args), logicalId, {
19024
+ if (provider.disableOuterRetry) return await provider.update(...args);
19025
+ return await withRetry(() => provider.update(...args), logicalId, {
19023
19026
  logger,
19024
19027
  ...isInterrupted && {
19025
19028
  isInterrupted,
@@ -19027,6 +19030,21 @@ async function updateWithRollbackRetry(provider, args, logicalId, logger, isInte
19027
19030
  }
19028
19031
  });
19029
19032
  }
19033
+ /**
19034
+ * The state record to store after a rollback UPDATE arm (issue #1644).
19035
+ *
19036
+ * The bag handed to `update()` on both arms IS `restored.properties`, so a
19037
+ * returned `effectiveProperties` is its complete replacement — no per-key
19038
+ * delta is needed here (unlike `drift --revert`, which sends a merged bag).
19039
+ * Everything else on the record — physical id, attributes, dependencies,
19040
+ * policies — is the restored resource's and must survive untouched.
19041
+ */
19042
+ function recordAfterRollbackUpdate(restored, result) {
19043
+ return result?.effectiveProperties ? {
19044
+ ...restored,
19045
+ properties: { ...result.effectiveProperties }
19046
+ } : restored;
19047
+ }
19030
19048
  async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds, result, afterOp, isInterrupted) {
19031
19049
  const action = classifyRollbackOp(op, stateResources, orphanLogicalIds);
19032
19050
  const { logger } = ctx;
@@ -19254,14 +19272,14 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
19254
19272
  resourceType: op.resourceType,
19255
19273
  provisionedBy: op.provisionedBy
19256
19274
  });
19257
- await updateWithRollbackRetry(provider, [
19275
+ const revertResult = await updateWithRollbackRetry(provider, [
19258
19276
  op.logicalId,
19259
19277
  current.physicalId,
19260
19278
  op.resourceType,
19261
19279
  previousState.properties,
19262
19280
  current.properties
19263
19281
  ], op.logicalId, logger, isInterrupted);
19264
- stateResources[op.logicalId] = previousState;
19282
+ stateResources[op.logicalId] = recordAfterRollbackUpdate(previousState, revertResult);
19265
19283
  logger.info(` Rollback: ${op.logicalId} restored successfully`);
19266
19284
  await afterOp?.(op.logicalId);
19267
19285
  ctx.recordEvent?.({
@@ -19390,14 +19408,14 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
19390
19408
  resourceType: op.resourceType,
19391
19409
  provisionedBy: op.provisionedBy ?? current.provisionedBy
19392
19410
  });
19393
- await updateWithRollbackRetry(provider, [
19411
+ const revertFailedResult = await updateWithRollbackRetry(provider, [
19394
19412
  op.logicalId,
19395
19413
  current.physicalId,
19396
19414
  op.resourceType,
19397
19415
  prev.properties,
19398
19416
  op.attemptedProperties ?? current.properties
19399
19417
  ], op.logicalId, logger, options.isInterrupted);
19400
- stateResources[op.logicalId] = prev;
19418
+ stateResources[op.logicalId] = recordAfterRollbackUpdate(prev, revertFailedResult);
19401
19419
  logger.info(` Rollback: ${op.logicalId} reverted successfully`);
19402
19420
  await options.afterOp?.(op.logicalId);
19403
19421
  ctx.recordEvent?.({
@@ -19523,7 +19541,7 @@ const FLUSH_INTERVAL_MS = 2e3;
19523
19541
  const FLUSH_EVENT_THRESHOLD = 50;
19524
19542
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
19525
19543
  function getCdkdVersion() {
19526
- return "0.280.30";
19544
+ return "0.280.32";
19527
19545
  }
19528
19546
  /**
19529
19547
  * Generate a time-sortable unique run id, e.g.
@@ -21260,15 +21278,17 @@ var DeployEngine = class {
21260
21278
  } catch (createError) {
21261
21279
  const createMsg = createError instanceof Error ? createError.message : String(createError);
21262
21280
  if (!isNameCollisionError(createMsg)) throw createError;
21263
- if (updateReplacePolicy === "Retain") throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its user-supplied physical name is still held by the existing resource AND UpdateReplacePolicy: Retain pins that resource in place. Rename the resource in your CDK code — with Retain, the old resource keeps the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_COLLISION");
21264
- if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but the create-first attempt collided with the existing resource: ${createMsg}. The resource has a user-supplied physical name, so the CloudFormation-style safe replacement order (create the new resource before deleting the old) cannot reuse the occupied name — CloudFormation refuses this shape with "cannot update a stack when a custom-named resource requires replacing". Either rename the resource in your CDK code (a fresh name lets the safe create-first order proceed), or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated).`, "NAMED_REPLACEMENT_COLLISION");
21265
- this.logger.info(` Create-first collided with the custom-named resource and --replace is set deleting old ${logicalId} (${currentResource.physicalId}) first...`);
21281
+ const nameOrigin = this.replacementNameOrigin(logicalId, currentResource.physicalId);
21282
+ if (updateReplacePolicy === "Retain") throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its physical name is still held by the existing resource AND UpdateReplacePolicy: Retain pins that resource in place. ${nameOrigin.descriptor}. ${nameOrigin.remedy} with Retain, the old resource keeps the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_COLLISION");
21283
+ if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but the create-first attempt collided with the existing resource: ${createMsg}. ${nameOrigin.descriptor}, so the CloudFormation-style safe replacement order (create the new resource before deleting the old) cannot reuse the occupied name — CloudFormation refuses this shape with "cannot update a stack when a custom-named resource requires replacing". ${nameOrigin.remedy}, or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated).`, "NAMED_REPLACEMENT_COLLISION");
21284
+ this.logger.info(` Create-first collided with the existing resource's name and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
21266
21285
  deletedOldFirst = true;
21267
21286
  createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, updateReplacePolicy);
21268
21287
  }
21269
21288
  if (!deletedOldFirst && createResult.physicalId === currentResource.physicalId) {
21270
- if (updateReplacePolicy === "Retain") throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its Create API is name-idempotent: the create-first attempt returned the existing resource (${currentResource.physicalId}) instead of creating a new one, and UpdateReplacePolicy: Retain pins that resource in place. Rename the resource in your CDK code — with Retain, the old resource keeps the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
21271
- if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its Create API is name-idempotent: the create-first attempt returned the EXISTING resource (${currentResource.physicalId}) instead of creating a new one, so deleting the "old" resource would silently destroy the resource the deploy just reported as created. The resource has a user-supplied physical name; either change or remove the explicit name in your CDK code (a fresh or generated name lets the safe create-first order proceed), or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated). Note: this branch is also reached when the old resource was deleted out-of-band and the physical id is name-derived there the create was a genuine fresh create; \`--replace\` converges that case too.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
21289
+ const idempotentNameOrigin = this.replacementNameOrigin(logicalId, currentResource.physicalId);
21290
+ if (updateReplacePolicy === "Retain") throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its Create API is name-idempotent: the create-first attempt returned the existing resource (${currentResource.physicalId}) instead of creating a new one, and UpdateReplacePolicy: Retain pins that resource in place. ${idempotentNameOrigin.descriptor}. ${idempotentNameOrigin.remedy} with Retain, the old resource keeps the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
21291
+ if (this.options.replace !== true) throw new CdkdError(`${logicalId} (${resourceType}) requires replacement, but its Create API is name-idempotent: the create-first attempt returned the EXISTING resource (${currentResource.physicalId}) instead of creating a new one, so deleting the "old" resource would silently destroy the resource the deploy just reported as created. ${idempotentNameOrigin.descriptor}; ${idempotentNameOrigin.remedy}, or re-run with \`cdkd deploy --replace\` to delete the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated). Note: this branch is also reached when the old resource was deleted out-of-band and the physical id is name-derived — there the create was a genuine fresh create; \`--replace\` converges that case too.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
21272
21292
  this.logger.info(` Create-first returned the existing resource (name-idempotent Create API) and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
21273
21293
  deletedOldFirst = true;
21274
21294
  createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps, updateReplacePolicy);
@@ -21468,6 +21488,37 @@ var DeployEngine = class {
21468
21488
  return result.effectiveProperties ?? desiredProperties;
21469
21489
  }
21470
21490
  /**
21491
+ * The name-origin half of the replacement-collision messages (issue #1636).
21492
+ *
21493
+ * Every one of those refusals used to assert that the colliding resource
21494
+ * "has a user-supplied physical name" and prescribe "rename the resource in
21495
+ * your CDK code". For a resource the template never named BOTH halves are
21496
+ * wrong: `generateResourceName` produces `{stackName}-{logicalId}` with no
21497
+ * random component, so the collision is caused by cdkd's OWN naming scheme,
21498
+ * and "rename" there means renaming the CONSTRUCT — a materially different
21499
+ * and more disruptive action. The false half is the part the user is asked
21500
+ * to act on, and a reader who finds no such name in their template cannot
21501
+ * connect the message to their code at all.
21502
+ *
21503
+ * `descriptor` names WHERE the name came from; `remedy` is the accurate
21504
+ * first option. Both callers append the shared `--replace` alternative,
21505
+ * which is identical in either case.
21506
+ *
21507
+ * Classification is best-effort by construction (see
21508
+ * {@link looksLikeCdkdGeneratedName}) and falls back to the pre-#1636
21509
+ * wording, which stays correct for the template-named resource.
21510
+ */
21511
+ replacementNameOrigin(logicalId, physicalId) {
21512
+ if (looksLikeCdkdGeneratedName(physicalId, logicalId, getCurrentStackName())) return {
21513
+ descriptor: `The physical name (${physicalId}) was GENERATED by cdkd from the construct's logical id rather than declared in your template, and that derivation has no random component — so the new resource asks for exactly the name the existing one still holds`,
21514
+ remedy: "Either give the resource an explicit physical name in your CDK code, or rename the CONSTRUCT (its id feeds the generated name — note that this replaces the resource rather than renaming it in place)"
21515
+ };
21516
+ return {
21517
+ descriptor: `The resource has a user-supplied physical name (${physicalId})`,
21518
+ remedy: "Either rename the resource in your CDK code (a fresh name lets the safe create-first order proceed)"
21519
+ };
21520
+ }
21521
+ /**
21471
21522
  * Read `DeletionPolicy` / `UpdateReplacePolicy` from the synth template
21472
21523
  * so they can be persisted in `ResourceState` (schema v5+). Always returns
21473
21524
  * both keys (`undefined` when the template does not carry the attribute)
@@ -21656,4 +21707,4 @@ var DeployEngine = class {
21656
21707
 
21657
21708
  //#endregion
21658
21709
  export { requireConfigObject as $, AssemblyReader as $t, green as A, __exportAll as An, runDockerForeground as At, disableInstanceApiTermination as B, resolveCaptureObservedState as Bt, MULTI_REGION_RECREATE_BLOCKED_TYPES as C, StackTerminationProtectionError as Cn, getBootstrapMarkerKey as Ct, bold as D, isCdkdError as Dn, buildDockerImage as Dt, formatResourceLine as E, formatError as En, validateContainerRepoName as Et, clearOnUpdateRemoval as F, synthesisStatusMessage as Ft, WAFv2WebACLProvider as G, stateBucketExistenceConfirmed as Gt, IntrinsicFunctionResolver as H, resolveStateBucketWithDefault as Ht, ProviderRegistry as I, getDefaultStateBucketName as It, assertRegionMatch as J, CFN_TEMPLATE_URL_LIMIT as Jt, normalizeAwsTagsToCfn as K, warnDeprecatedNoPrefixCliFlag as Kt, findActionableSilentDrops as L, getLegacyStateBucketName as Lt, yellow as M, AssetManifestLoader as Mt, IAMRoleProvider as N, getDockerImageBySourceHash as Nt, cyan as O, normalizeAwsError as On, formatDockerLoginError as Ot, collectInlinePolicyNamesManagedBySiblings as P, Synthesizer as Pt, requireConfigArray as Q, expectedOwnerParam as Qt, CloudControlProvider as R, resolveApp as Rt, extractDeploymentEventError as S, StackHasActiveImportsError as Sn, ensureAssetStorage as St, renderStatefulReason as T, SynthesisError as Tn, validateAssetBucketName as Tt, cfnRefValueFromPhysicalId as U, resolveStateBucketWithDefaultAndSource as Ut, isTerminationProtectionPropagationError as V, resolveSkipPrefix as Vt, refStateLookupFromResource as W, resolveUseCdkBootstrapAssets as Wt, readConfigString as X, findLargeInlineResources as Xt, configStringRefusal as Y, MIGRATE_TMP_PREFIX as Yt, replayWarn as Z, uploadCfnTemplate as Zt, createPreDeleteFinalSnapshot as _, NestedStackChildDirectDestroyError as _n, createAssetRedirectResolver as _t, DeploymentEventsStore as a, resetAwsClients as an, isRetryableTransientError as at, unsupportedFinalSnapshotError as b, ResourceTimeoutError as bn, AssetModeResolver as bt, replayFailedOperations as c, CdkdError as cn, TemplateParser as ct, IMPLICIT_DELETE_DEPENDENCIES as d, DeployCancelledError as dn, rebuildClientForBucketRegion as dt, processStackMessages as en, requireConfigString as et, computeImplicitDeleteEdges as f, LocalInvokeBuildError as fn, shouldRetainResource as ft, ccRoutedFinalSnapshotError as g, MissingCdkCliError as gn, buildAssetRedirectMap as gt, buildFinalSnapshotIdentifier as h, LockError as hn, WorkGraph as ht, DeploymentEventsReader as i, getAwsClients as in, withRetry as it, red as j, runDockerStreaming as jt, gray as k, withErrorHandling as kn, getDockerCmd as kt, replayRollback as l, ConfigError as ln, LockManager as lt, PRE_DELETE_SNAPSHOT_TYPES as m, LocalStartServiceError as mn, stringifyValue as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, resolveBucketRegion as nn, DiffCalculator as nt, planFailedOps as o, setAwsClients as on, isThrottlingError as ot, ATOMIC_FINAL_SNAPSHOT_TYPES as p, LocalMigrateError as pn, AssetPublisher as pt, resolveExplicitPhysicalId as q, CFN_TEMPLATE_BODY_LIMIT as qt, DeployEngine as r, AwsClients as rn, describeTypeWithThrottleRetry as rt, planRollback as s, AssetError as sn, DagBuilder as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, clearBucketRegionCache as tn, applyRoleArnIfSet as tt, withResourceDeadline as u, DependencyError as un, S3StateBackend as ut, isFinalSnapshotError as v, PartialFailureError as vn, loadPublishableAssetManifest as vt, isStatefulRecreateTargetSync as w, StateError as wn, parseBootstrapMarker as wt, makeCanonicalizePropertiesFn as x, ResourceUpdateNotSupportedError as xn, BOOTSTRAP_MARKER_PREFIX as xt, refusesFinalSnapshot as y, ProvisioningError as yn, rewriteTemplateAssetReferences as yt, slowCcOperationTimeoutMs as z, resolveAutoAssetStorage as zt };
21659
- //# sourceMappingURL=deploy-engine-POCXyXPl.js.map
21710
+ //# sourceMappingURL=deploy-engine-REAC5UGa.js.map