@go-to-k/cdkd 0.267.5 → 0.267.6

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.
@@ -11612,7 +11612,7 @@ var CloudControlProvider = class {
11612
11612
  this.logger.debug(`Deleting resource ${logicalId} (${resourceType}), physical ID: ${physicalId}`);
11613
11613
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
11614
11614
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
11615
- const { ASGProvider } = await import("./asg-provider-CIZpj4w5.js").then((n) => n.n);
11615
+ const { ASGProvider } = await import("./asg-provider-D5GSbDk-.js").then((n) => n.n);
11616
11616
  await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
11617
11617
  return;
11618
11618
  }
@@ -17315,7 +17315,7 @@ const FLUSH_INTERVAL_MS = 2e3;
17315
17315
  const FLUSH_EVENT_THRESHOLD = 50;
17316
17316
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
17317
17317
  function getCdkdVersion() {
17318
- return "0.267.5";
17318
+ return "0.267.6";
17319
17319
  }
17320
17320
  /**
17321
17321
  * Generate a time-sortable unique run id, e.g.
@@ -18794,6 +18794,35 @@ var DeployEngine = class {
18794
18794
  throw new ProvisioningError(`Unrewritten asset reference on '${logicalId}' (${resourceType}): this region uses cdkd-owned asset storage, but the following resolved properties still point at the CDK bootstrap storage that 'cdk gc' may garbage-collect:\n${findings.map((f) => ` - ${f.path}: still references '${f.source}'`).join("\n")}\nThis is a template shape cdkd's asset-reference rewrite did not cover — deploying it would split-brain the stack (assets in cdkd storage, properties reading the CDK bucket). Please report this at https://github.com/go-to-k/cdkd/issues with the property shape. Workaround: deploy with --use-cdk-bootstrap-assets to pin the legacy destinations for this app.`, resourceType, logicalId);
18795
18795
  }
18796
18796
  /**
18797
+ * `--replace` delete-first fallback for a property-driven replacement of a
18798
+ * custom-named resource: delete the old name holder, then re-create it
18799
+ * under the same name. Shared by the create-first collision catch (issue
18800
+ * #960 follow-up) and the name-idempotent same-id guard (issue #1238) so
18801
+ * the two --replace escape hatches cannot drift apart.
18802
+ */
18803
+ async replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps) {
18804
+ try {
18805
+ await oldDeleteProvider.delete(logicalId, currentResource.physicalId, resourceType, currentResource.properties, { expectedRegion: this.stackRegion });
18806
+ } catch (deleteError) {
18807
+ throw new Error(`Failed to delete old resource ${logicalId} (${currentResource.physicalId}) during the --replace delete-first fallback: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`);
18808
+ }
18809
+ this.logger.info(` ${green("✓")} Old resource deleted`);
18810
+ this.logger.info(` Re-creating ${logicalId}...`);
18811
+ try {
18812
+ return await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps), logicalId, void 0, void 0, replaceProvider), logicalId, {
18813
+ maxRetries: 8,
18814
+ initialDelayMs: 2e3,
18815
+ maxDelayMs: 1e4,
18816
+ logger: this.logger,
18817
+ isInterrupted: () => this.interrupted,
18818
+ onInterrupted: () => new InterruptedError(this.interruptCause ?? "user"),
18819
+ isRetryable: isRecreateRetryableError
18820
+ });
18821
+ } catch (recreateError) {
18822
+ throw new Error(`Failed to re-create ${logicalId} after the --replace delete-first fallback already deleted the old resource (${currentResource.physicalId}): ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. Re-run the deploy to create it fresh.`);
18823
+ }
18824
+ }
18825
+ /**
18797
18826
  * Inner body of provisionResource, extracted so the outer wrapper can
18798
18827
  * apply the per-resource deadline (`withResourceDeadline`) without
18799
18828
  * having the timeout / warn timer code dwarf the real provisioning
@@ -18930,6 +18959,7 @@ var DeployEngine = class {
18930
18959
  onInterrupted: () => new InterruptedError(this.interruptCause ?? "user"),
18931
18960
  isRetryable: isRecreateRetryableError
18932
18961
  });
18962
+ if (updateReplacePolicy === "Retain" && createResult.physicalId === currentResource.physicalId) throw new CdkdError(`${logicalId} (${resourceType}) recreate returned the existing resource (${currentResource.physicalId}) instead of creating a new one — its Create API is name-idempotent — and UpdateReplacePolicy: Retain means the old resource was never destroyed, so the new properties were not applied. Rename the resource in your CDK code (or remove the explicit physical name) so the recreate can produce a genuinely new resource.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
18933
18963
  } else {
18934
18964
  this.logger.info(` Creating new ${logicalId}...`);
18935
18965
  let deletedOldFirst = false;
@@ -18941,27 +18971,15 @@ var DeployEngine = class {
18941
18971
  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");
18942
18972
  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");
18943
18973
  this.logger.info(` Create-first collided with the custom-named resource and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
18944
- try {
18945
- await oldDeleteProvider.delete(logicalId, currentResource.physicalId, resourceType, currentResource.properties, { expectedRegion: this.stackRegion });
18946
- } catch (deleteError) {
18947
- throw new Error(`Failed to delete old resource ${logicalId} (${currentResource.physicalId}) during the --replace delete-first fallback: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`);
18948
- }
18949
- this.logger.info(` ${green("✓")} Old resource deleted`);
18950
18974
  deletedOldFirst = true;
18951
- this.logger.info(` Re-creating ${logicalId}...`);
18952
- try {
18953
- createResult = await withRetry(() => this.withRetry(() => replaceProvider.create(logicalId, resourceType, replaceProps), logicalId, void 0, void 0, replaceProvider), logicalId, {
18954
- maxRetries: 8,
18955
- initialDelayMs: 2e3,
18956
- maxDelayMs: 1e4,
18957
- logger: this.logger,
18958
- isInterrupted: () => this.interrupted,
18959
- onInterrupted: () => new InterruptedError(this.interruptCause ?? "user"),
18960
- isRetryable: isRecreateRetryableError
18961
- });
18962
- } catch (recreateError) {
18963
- throw new Error(`Failed to re-create ${logicalId} after the --replace delete-first fallback already deleted the old resource (${currentResource.physicalId}): ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. Re-run the deploy to create it fresh.`);
18964
- }
18975
+ createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps);
18976
+ }
18977
+ if (!deletedOldFirst && createResult.physicalId === currentResource.physicalId) {
18978
+ 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");
18979
+ 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");
18980
+ this.logger.info(` Create-first returned the existing resource (name-idempotent Create API) and --replace is set — deleting old ${logicalId} (${currentResource.physicalId}) first...`);
18981
+ deletedOldFirst = true;
18982
+ createResult = await this.replaceDeleteFirstAndRecreate(logicalId, resourceType, currentResource, oldDeleteProvider, replaceProvider, replaceProps);
18965
18983
  }
18966
18984
  if (deletedOldFirst) {} else if (updateReplacePolicy === "Retain") this.logger.info(` Retaining old ${logicalId} (${currentResource.physicalId}) - UpdateReplacePolicy: Retain`);
18967
18985
  else {
@@ -19303,4 +19321,4 @@ var DeployEngine = class {
19303
19321
 
19304
19322
  //#endregion
19305
19323
  export { WorkGraph as $, NestedStackChildDirectDestroyError as $t, slowCcOperationTimeoutMs as A, CFN_TEMPLATE_BODY_LIMIT as At, applyRoleArnIfSet as B, AwsClients as Bt, yellow as C, resolveAutoAssetStorage as Ct, ProviderRegistry as D, resolveStateBucketWithDefaultAndSource as Dt, clearOnUpdateRemoval as E, resolveStateBucketWithDefault as Et, refStateLookupFromResource as F, expectedOwnerParam as Ft, DagBuilder as G, CdkdError as Gt, describeTypeWithThrottleRetry as H, resetAwsClients as Ht, WAFv2WebACLProvider as I, AssemblyReader as It, S3StateBackend as J, LocalInvokeBuildError as Jt, TemplateParser as K, ConfigError as Kt, normalizeAwsTagsToCfn as L, processStackMessages as Lt, isTerminationProtectionPropagationError as M, MIGRATE_TMP_PREFIX as Mt, IntrinsicFunctionResolver as N, findLargeInlineResources as Nt, findActionableSilentDrops as O, resolveUseCdkBootstrapAssets as Ot, cfnRefValueFromPhysicalId as P, uploadCfnTemplate as Pt, stringifyValue as Q, MissingCdkCliError as Qt, resolveExplicitPhysicalId as R, clearBucketRegionCache as Rt, red as S, resolveApp as St, collectInlinePolicyNamesManagedBySiblings as T, resolveSkipPrefix as Tt, withRetry as U, setAwsClients as Ut, DiffCalculator as V, getAwsClients as Vt, isRetryableTransientError as W, AssetError as Wt, shouldRetainResource as X, LocalStartServiceError as Xt, rebuildClientForBucketRegion as Y, LocalMigrateError as Yt, AssetPublisher as Z, LockError as Zt, formatResourceLine as _, getDockerImageBySourceHash as _t, DeploymentEventsStore as a, StackTerminationProtectionError as an, BOOTSTRAP_MARKER_PREFIX as at, gray as b, getDefaultStateBucketName as bt, replayFailedOperations as c, formatError as cn, parseBootstrapMarker as ct, IMPLICIT_DELETE_DEPENDENCIES as d, withErrorHandling as dn, buildDockerImage as dt, PartialFailureError as en, buildAssetRedirectMap as et, computeImplicitDeleteEdges as f, __exportAll as fn, formatDockerLoginError as ft, renderStatefulReason as g, AssetManifestLoader as gt, isStatefulRecreateTargetSync as h, runDockerStreaming as ht, DeploymentEventsReader as i, StackHasActiveImportsError as in, AssetModeResolver as it, disableInstanceApiTermination as j, CFN_TEMPLATE_URL_LIMIT as jt, CloudControlProvider as k, warnDeprecatedNoPrefixCliFlag as kt, replayRollback as l, isCdkdError as ln, validateAssetBucketName as lt, MULTI_REGION_RECREATE_BLOCKED_TYPES as m, runDockerForeground as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, ResourceTimeoutError as nn, loadPublishableAssetManifest as nt, planFailedOps as o, StateError as on, ensureAssetStorage as ot, extractDeploymentEventError as p, getDockerCmd as pt, LockManager as q, DependencyError as qt, DeployEngine as r, ResourceUpdateNotSupportedError as rn, rewriteTemplateAssetReferences as rt, planRollback as s, SynthesisError as sn, getBootstrapMarkerKey as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, ProvisioningError as tn, createAssetRedirectResolver as tt, withResourceDeadline as u, normalizeAwsError as un, validateContainerRepoName as ut, bold as v, Synthesizer as vt, IAMRoleProvider as w, resolveCaptureObservedState as wt, green as x, getLegacyStateBucketName as xt, cyan as y, synthesisStatusMessage as yt, assertRegionMatch as z, resolveBucketRegion as zt };
19306
- //# sourceMappingURL=deploy-engine-B7if6--O.js.map
19324
+ //# sourceMappingURL=deploy-engine-COX8YJsC.js.map