@go-to-k/cdkd 0.219.7 → 0.219.8
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 +4 -3
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-BWfGeCMs.js → deploy-engine-Bl8wyosc.js} +110 -1
- package/dist/deploy-engine-Bl8wyosc.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BWfGeCMs.js.map +0 -1
|
@@ -3763,6 +3763,22 @@ var TemplateParser = class {
|
|
|
3763
3763
|
return dependencies;
|
|
3764
3764
|
}
|
|
3765
3765
|
/**
|
|
3766
|
+
* Extract resource references (Ref / Fn::GetAtt / Fn::Sub / Fn::Join /
|
|
3767
|
+
* Fn::Select / Fn::Split) from an arbitrary template value.
|
|
3768
|
+
*
|
|
3769
|
+
* Public wrapper over the same recursive extraction `extractDependencies`
|
|
3770
|
+
* uses for Properties — exposed so the diff phase can compute
|
|
3771
|
+
* per-property reference edges (issue #807 replacement propagation)
|
|
3772
|
+
* without duplicating the intrinsic walk. Unlike `extractDependencies`
|
|
3773
|
+
* this does NOT include `DependsOn` (which is pure ordering, not a data
|
|
3774
|
+
* reference — a replaced dependency carries no new value to propagate).
|
|
3775
|
+
*/
|
|
3776
|
+
extractReferences(value) {
|
|
3777
|
+
const references = /* @__PURE__ */ new Set();
|
|
3778
|
+
this.extractRefsFromValue(value, references);
|
|
3779
|
+
return references;
|
|
3780
|
+
}
|
|
3781
|
+
/**
|
|
3766
3782
|
* Recursively extract Ref and Fn::GetAtt from a value
|
|
3767
3783
|
*/
|
|
3768
3784
|
extractRefsFromValue(value, dependencies) {
|
|
@@ -4585,6 +4601,7 @@ var ReplacementRulesRegistry = class {
|
|
|
4585
4601
|
var DiffCalculator = class DiffCalculator {
|
|
4586
4602
|
logger = getLogger().child("DiffCalculator");
|
|
4587
4603
|
replacementRules = new ReplacementRulesRegistry();
|
|
4604
|
+
parser = new TemplateParser();
|
|
4588
4605
|
/**
|
|
4589
4606
|
* Calculate changes needed to reach desired state
|
|
4590
4607
|
*
|
|
@@ -4674,11 +4691,103 @@ var DiffCalculator = class DiffCalculator {
|
|
|
4674
4691
|
});
|
|
4675
4692
|
this.logger.debug(`DELETE: ${logicalId} (${currentResource.resourceType})`);
|
|
4676
4693
|
}
|
|
4694
|
+
this.promoteReplacementDependents(changes, desiredTemplate);
|
|
4677
4695
|
const summary = this.getSummary(changes);
|
|
4678
4696
|
this.logger.debug(`Diff calculated: ${summary.create} CREATE, ${summary.update} UPDATE, ${summary.delete} DELETE, ${summary.noChange} NO_CHANGE`);
|
|
4679
4697
|
return changes;
|
|
4680
4698
|
}
|
|
4681
4699
|
/**
|
|
4700
|
+
* Promote transitive dependents of to-be-replaced resources from
|
|
4701
|
+
* NO_CHANGE to UPDATE (issue #807).
|
|
4702
|
+
*
|
|
4703
|
+
* Diff-time intrinsic resolution runs against the CURRENT state, so a
|
|
4704
|
+
* dependent referencing a resource that will be REPLACED (new physical
|
|
4705
|
+
* ID — e.g. an `AWS::ECS::TaskDefinition` revision) compares equal and
|
|
4706
|
+
* stays NO_CHANGE; the deploy engine then never re-points it at the new
|
|
4707
|
+
* physical resource (for ECS: `UpdateService` is never issued and the
|
|
4708
|
+
* service keeps running the old, now-deregistered revision).
|
|
4709
|
+
* CloudFormation propagates the new physical ID to dependents — mirror
|
|
4710
|
+
* that here by walking reverse reference edges (`Ref` / `Fn::GetAtt` /
|
|
4711
|
+
* `Fn::Sub` and intrinsics nesting them — the same extraction the DAG
|
|
4712
|
+
* builder uses) from every replacement-triggering UPDATE and promoting
|
|
4713
|
+
* NO_CHANGE dependents to UPDATE.
|
|
4714
|
+
*
|
|
4715
|
+
* Promotion is safe even when speculative: the deploy engine re-resolves
|
|
4716
|
+
* the promoted resource's properties against the in-flight state map
|
|
4717
|
+
* (which the DAG guarantees already carries the dependency's new
|
|
4718
|
+
* physical ID) and skips the provider call if nothing actually changed.
|
|
4719
|
+
*
|
|
4720
|
+
* Promotion is transitive: each referencing property of a promoted
|
|
4721
|
+
* dependent is re-evaluated against the replacement rules, and if the
|
|
4722
|
+
* dependent is itself replacement-triggering (the referencing property
|
|
4723
|
+
* is immutable for its type), its own dependents are promoted in turn.
|
|
4724
|
+
* The same re-evaluation also applies to dependents that already had
|
|
4725
|
+
* their own (non-replacement) property changes — their referencing
|
|
4726
|
+
* property gains a synthetic PropertyChange so a replacement cascade is
|
|
4727
|
+
* not masked by an unrelated in-place change.
|
|
4728
|
+
*/
|
|
4729
|
+
promoteReplacementDependents(changes, desiredTemplate) {
|
|
4730
|
+
const queue = [];
|
|
4731
|
+
for (const [logicalId, change] of changes) if (change.changeType === "UPDATE" && change.propertyChanges?.some((pc) => pc.requiresReplacement)) queue.push(logicalId);
|
|
4732
|
+
if (queue.length === 0) return;
|
|
4733
|
+
const dependentsOf = /* @__PURE__ */ new Map();
|
|
4734
|
+
for (const [logicalId, resource] of Object.entries(desiredTemplate.Resources)) {
|
|
4735
|
+
if (resource.Type === "AWS::CDK::Metadata") continue;
|
|
4736
|
+
for (const [propKey, propValue] of Object.entries(resource.Properties ?? {})) for (const referencedId of this.parser.extractReferences(propValue)) {
|
|
4737
|
+
if (referencedId === logicalId) continue;
|
|
4738
|
+
let dependents = dependentsOf.get(referencedId);
|
|
4739
|
+
if (!dependents) {
|
|
4740
|
+
dependents = /* @__PURE__ */ new Map();
|
|
4741
|
+
dependentsOf.set(referencedId, dependents);
|
|
4742
|
+
}
|
|
4743
|
+
let propKeys = dependents.get(logicalId);
|
|
4744
|
+
if (!propKeys) {
|
|
4745
|
+
propKeys = /* @__PURE__ */ new Set();
|
|
4746
|
+
dependents.set(logicalId, propKeys);
|
|
4747
|
+
}
|
|
4748
|
+
propKeys.add(propKey);
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
const enqueued = new Set(queue);
|
|
4752
|
+
while (queue.length > 0) {
|
|
4753
|
+
const replacedId = queue.shift();
|
|
4754
|
+
const dependents = dependentsOf.get(replacedId);
|
|
4755
|
+
if (!dependents) continue;
|
|
4756
|
+
for (const [dependentId, refPropKeys] of dependents) {
|
|
4757
|
+
const change = changes.get(dependentId);
|
|
4758
|
+
if (!change) continue;
|
|
4759
|
+
if (change.changeType !== "NO_CHANGE" && change.changeType !== "UPDATE") continue;
|
|
4760
|
+
const existingPaths = new Set((change.propertyChanges ?? []).map((pc) => pc.path));
|
|
4761
|
+
const syntheticChanges = [];
|
|
4762
|
+
for (const propKey of refPropKeys) {
|
|
4763
|
+
if (existingPaths.has(propKey)) continue;
|
|
4764
|
+
const oldValue = change.currentProperties?.[propKey];
|
|
4765
|
+
const newValue = change.desiredProperties?.[propKey];
|
|
4766
|
+
syntheticChanges.push({
|
|
4767
|
+
path: propKey,
|
|
4768
|
+
oldValue,
|
|
4769
|
+
newValue,
|
|
4770
|
+
replacementPropagated: true,
|
|
4771
|
+
requiresReplacement: this.replacementRules.requiresReplacement(change.resourceType, propKey, void 0, void 0)
|
|
4772
|
+
});
|
|
4773
|
+
}
|
|
4774
|
+
if (syntheticChanges.length === 0) continue;
|
|
4775
|
+
if (change.changeType === "NO_CHANGE") {
|
|
4776
|
+
change.changeType = "UPDATE";
|
|
4777
|
+
change.propertyChanges = syntheticChanges;
|
|
4778
|
+
this.logger.debug(`UPDATE (promoted): ${dependentId} references replaced resource ${replacedId} via ${[...refPropKeys].join(", ")}`);
|
|
4779
|
+
} else {
|
|
4780
|
+
change.propertyChanges = [...change.propertyChanges ?? [], ...syntheticChanges];
|
|
4781
|
+
this.logger.debug(`UPDATE (augmented): ${dependentId} references replaced resource ${replacedId} via ${[...refPropKeys].join(", ")}`);
|
|
4782
|
+
}
|
|
4783
|
+
if (!enqueued.has(dependentId) && change.propertyChanges.some((pc) => pc.requiresReplacement)) {
|
|
4784
|
+
enqueued.add(dependentId);
|
|
4785
|
+
queue.push(dependentId);
|
|
4786
|
+
}
|
|
4787
|
+
}
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
/**
|
|
4682
4791
|
* Best-effort resolution of template property intrinsics against current state.
|
|
4683
4792
|
*
|
|
4684
4793
|
* Iterates top-level properties and resolves each independently: if resolution
|
|
@@ -12379,4 +12488,4 @@ var DeployEngine = class {
|
|
|
12379
12488
|
|
|
12380
12489
|
//#endregion
|
|
12381
12490
|
export { WorkGraph as A, resolveCaptureObservedState as B, DagBuilder as C, shouldRetainResource as D, S3StateBackend as E, runDockerStreaming as F, CFN_TEMPLATE_BODY_LIMIT as G, resolveStateBucketWithDefault as H, Synthesizer as I, findLargeInlineResources as J, CFN_TEMPLATE_URL_LIMIT as K, getDefaultStateBucketName as L, formatDockerLoginError as M, getDockerCmd as N, AssetPublisher as O, runDockerForeground as P, resolveBucketRegion as Q, getLegacyStateBucketName as R, DiffCalculator as S, LockManager as T, resolveStateBucketWithDefaultAndSource as U, resolveSkipPrefix as V, warnDeprecatedNoPrefixCliFlag as W, AssemblyReader as X, uploadCfnTemplate as Y, clearBucketRegionCache as Z, ProviderRegistry as _, withRetry as a, IntrinsicFunctionResolver as b, formatResourceLine as c, gray as d, green as f, collectInlinePolicyNamesManagedBySiblings as g, IAMRoleProvider as h, withResourceDeadline as i, buildDockerImage as j, stringifyValue as k, bold as l, yellow as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, isRetryableTransientError as o, red as p, MIGRATE_TMP_PREFIX as q, DeployEngine as r, IMPLICIT_DELETE_DEPENDENCIES as s, DEFAULT_RESOURCE_TIMEOUT_MS as t, cyan as u, findActionableSilentDrops as v, TemplateParser as w, applyRoleArnIfSet as x, CloudControlProvider as y, resolveApp as z };
|
|
12382
|
-
//# sourceMappingURL=deploy-engine-
|
|
12491
|
+
//# sourceMappingURL=deploy-engine-Bl8wyosc.js.map
|