@go-to-k/cdkd 0.230.13 → 0.230.15

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
2
  import { A as withErrorHandling, B as generateResourceName, C as StackHasActiveImportsError, F as getLiveRenderer, H as withSkipPrefix, I as PATTERN_B_NAME_OPTIONS, L as PATTERN_B_NAME_PROPERTIES, M as getLogger, P as runStackBuffered, R as PATTERN_B_RESOURCE_TYPES, S as ResourceUpdateNotSupportedError, U as withStackName, V as generateResourceNameWithFallback, _ as MissingCdkCliError, a as assertRegionMatch, b as ProvisioningError, f as LocalInvokeBuildError$1, i as resolveExplicitPhysicalId, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as matchesCdkPath, o as disableInstanceApiTermination, p as LocalMigrateError, r as normalizeAwsTagsToCfn, s as isTerminationProtectionPropagationError, t as CDK_PATH_TAG, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError } from "./import-helpers-DayvBD4T.js";
3
3
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
4
- import { $ as CFN_TEMPLATE_BODY_LIMIT, A as LockManager, B as runDockerForeground, C as findActionableSilentDrops, D as DiffCalculator, E as applyRoleArnIfSet, F as stringifyValue, G as getDefaultStateBucketName, H as AssetManifestLoader, I as WorkGraph, J as resolveCaptureObservedState, K as getLegacyStateBucketName, L as buildDockerImage, M as rebuildClientForBucketRegion, N as shouldRetainResource, O as DagBuilder, P as AssetPublisher, Q as warnDeprecatedNoPrefixCliFlag, R as formatDockerLoginError, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as getDockerImageBySourceHash, V as runDockerStreaming, W as Synthesizer, X as resolveStateBucketWithDefault, Y as resolveSkipPrefix, Z as resolveStateBucketWithDefaultAndSource, _ as green, a as withRetry, b as IAMRoleProvider, c as computeImplicitDeleteEdges, d as isStatefulRecreateTargetSync, et as CFN_TEMPLATE_URL_LIMIT, f as renderStatefulReason, g as gray, h as cyan, i as withResourceDeadline, it as AssemblyReader, j as S3StateBackend, k as TemplateParser, l as extractDeploymentEventError, m as bold, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as findLargeInlineResources, o as isRetryableTransientError, ot as resolveBucketRegion, p as formatResourceLine, q as resolveApp, r as DeployEngine, rt as uploadCfnTemplate, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as MIGRATE_TMP_PREFIX, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, v as red, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, y as yellow, z as getDockerCmd } from "./deploy-engine-B1a6fz6L.js";
4
+ import { $ as CFN_TEMPLATE_BODY_LIMIT, A as LockManager, B as runDockerForeground, C as findActionableSilentDrops, D as DiffCalculator, E as applyRoleArnIfSet, F as stringifyValue, G as getDefaultStateBucketName, H as AssetManifestLoader, I as WorkGraph, J as resolveCaptureObservedState, K as getLegacyStateBucketName, L as buildDockerImage, M as rebuildClientForBucketRegion, N as shouldRetainResource, O as DagBuilder, P as AssetPublisher, Q as warnDeprecatedNoPrefixCliFlag, R as formatDockerLoginError, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as getDockerImageBySourceHash, V as runDockerStreaming, W as Synthesizer, X as resolveStateBucketWithDefault, Y as resolveSkipPrefix, Z as resolveStateBucketWithDefaultAndSource, _ as green, a as withRetry, b as IAMRoleProvider, c as computeImplicitDeleteEdges, d as isStatefulRecreateTargetSync, et as CFN_TEMPLATE_URL_LIMIT, f as renderStatefulReason, g as gray, h as cyan, i as withResourceDeadline, it as AssemblyReader, j as S3StateBackend, k as TemplateParser, l as extractDeploymentEventError, m as bold, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as findLargeInlineResources, o as isRetryableTransientError, ot as resolveBucketRegion, p as formatResourceLine, q as resolveApp, r as DeployEngine, rt as uploadCfnTemplate, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as MIGRATE_TMP_PREFIX, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, v as red, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, y as yellow, z as getDockerCmd } from "./deploy-engine-BqUZUty9.js";
5
5
  import { t as ASGProvider } from "./asg-provider-Dgj3loIG.js";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import { randomBytes, randomUUID } from "node:crypto";
@@ -1445,7 +1445,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1445
1445
  const FLUSH_EVENT_THRESHOLD = 50;
1446
1446
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1447
1447
  function getCdkdVersion() {
1448
- return "0.230.13";
1448
+ return "0.230.15";
1449
1449
  }
1450
1450
  /**
1451
1451
  * Generate a time-sortable unique run id, e.g.
@@ -55365,7 +55365,7 @@ function reorderArgs(argv) {
55365
55365
  async function main() {
55366
55366
  installPipeCloseHandler();
55367
55367
  const program = new Command();
55368
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.13");
55368
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.15");
55369
55369
  program.addCommand(createBootstrapCommand());
55370
55370
  program.addCommand(createSynthCommand());
55371
55371
  program.addCommand(createListCommand());
@@ -5146,6 +5146,16 @@ var DiffCalculator = class DiffCalculator {
5146
5146
  this.logger.debug(`Current resources: ${Object.keys(currentResources).length}`);
5147
5147
  this.logger.debug(`Desired resources: ${Object.keys(desiredResources).length}`);
5148
5148
  const processedLogicalIds = /* @__PURE__ */ new Set();
5149
+ const rawGetAttRefs = /* @__PURE__ */ new Map();
5150
+ for (const [logicalId, desiredResource] of Object.entries(desiredResources)) {
5151
+ if (desiredResource.Type === "AWS::CDK::Metadata") continue;
5152
+ const perProp = /* @__PURE__ */ new Map();
5153
+ for (const [propKey, propValue] of Object.entries(desiredResource.Properties ?? {})) {
5154
+ const refs = DiffCalculator.extractGetAttRefs(propValue);
5155
+ if (refs.size > 0) perProp.set(propKey, refs);
5156
+ }
5157
+ if (perProp.size > 0) rawGetAttRefs.set(logicalId, perProp);
5158
+ }
5149
5159
  for (const [logicalId, desiredResource] of Object.entries(desiredResources)) {
5150
5160
  if (desiredResource.Type === "AWS::CDK::Metadata") {
5151
5161
  this.logger.debug(`Skipping metadata resource: ${logicalId}`);
@@ -5216,6 +5226,7 @@ var DiffCalculator = class DiffCalculator {
5216
5226
  this.logger.debug(`DELETE: ${logicalId} (${currentResource.resourceType})`);
5217
5227
  }
5218
5228
  this.promoteReplacementDependents(changes, desiredTemplate);
5229
+ this.promoteInPlaceAttributeDependents(changes, desiredTemplate, rawGetAttRefs);
5219
5230
  const summary = this.getSummary(changes);
5220
5231
  this.logger.debug(`Diff calculated: ${summary.create} CREATE, ${summary.update} UPDATE, ${summary.delete} DELETE, ${summary.noChange} NO_CHANGE`);
5221
5232
  return changes;
@@ -5312,6 +5323,135 @@ var DiffCalculator = class DiffCalculator {
5312
5323
  }
5313
5324
  }
5314
5325
  /**
5326
+ * Promote NO_CHANGE dependents of an IN-PLACE update whose referenced ATTRIBUTE
5327
+ * actually changed (bug-hunt 2026-06-29).
5328
+ *
5329
+ * Distinct from {@link promoteReplacementDependents}: a replacement changes the
5330
+ * physical id, so any reference is affected. An in-place update changes only
5331
+ * specific properties, so a dependent is affected ONLY when it reads (via
5332
+ * `Fn::GetAtt[Up, Attr]` or `Fn::Sub`'s `${Up.Attr}`) an attribute whose NAME
5333
+ * matches a property that changed in `Up`'s update. (`Ref` resolves to the
5334
+ * physical id, which an in-place update never moves, so Ref-only dependents are
5335
+ * left NO_CHANGE; likewise a GetAtt of a computed / unchanged attribute.)
5336
+ *
5337
+ * Promotion is safe even when speculative: the deploy engine re-resolves the
5338
+ * promoted resource against the in-flight state and skips the provider call
5339
+ * when nothing actually changed.
5340
+ *
5341
+ * Single-hop by design (unlike {@link promoteReplacementDependents}, which is
5342
+ * fully transitive via a worklist): `changedPropsByUpstream` is frozen at entry,
5343
+ * so a chain `A(in-place) -> B(reads A's changed attr) -> C(reads B's now-changed
5344
+ * attr)` promotes B but not C. Deep GetAtt-of-a-changed-attr chains are rare in
5345
+ * practice; if one ever needs full transitivity, promote to a worklist that
5346
+ * re-derives changed props as dependents are promoted.
5347
+ */
5348
+ promoteInPlaceAttributeDependents(changes, desiredTemplate, rawGetAttRefs) {
5349
+ const changedPropsByUpstream = /* @__PURE__ */ new Map();
5350
+ for (const [logicalId, change] of changes) {
5351
+ if (change.changeType !== "UPDATE") continue;
5352
+ const props = (change.propertyChanges ?? []).map((pc) => pc.path).filter((p) => typeof p === "string");
5353
+ if (props.length > 0) changedPropsByUpstream.set(logicalId, new Set(props));
5354
+ }
5355
+ if (changedPropsByUpstream.size === 0) return;
5356
+ for (const [dependentId, perProp] of rawGetAttRefs) {
5357
+ const resource = desiredTemplate.Resources[dependentId];
5358
+ if (!resource || resource.Type === "AWS::CDK::Metadata") continue;
5359
+ const change = changes.get(dependentId);
5360
+ if (!change) continue;
5361
+ if (change.changeType !== "NO_CHANGE" && change.changeType !== "UPDATE") continue;
5362
+ const existingPaths = new Set((change.propertyChanges ?? []).map((pc) => pc.path));
5363
+ const syntheticChanges = [];
5364
+ for (const [propKey, getAttRefs] of perProp) {
5365
+ if (existingPaths.has(propKey)) continue;
5366
+ let matched = false;
5367
+ for (const [upstreamId, attrs] of getAttRefs) {
5368
+ if (upstreamId === dependentId) continue;
5369
+ const changedProps = changedPropsByUpstream.get(upstreamId);
5370
+ if (!changedProps) continue;
5371
+ if ([...attrs].some((attr) => changedProps.has(attr))) {
5372
+ matched = true;
5373
+ break;
5374
+ }
5375
+ }
5376
+ if (!matched) continue;
5377
+ syntheticChanges.push({
5378
+ path: propKey,
5379
+ oldValue: change.currentProperties?.[propKey],
5380
+ newValue: change.desiredProperties?.[propKey],
5381
+ requiresReplacement: this.replacementRules.requiresReplacement(change.resourceType, propKey, void 0, void 0)
5382
+ });
5383
+ }
5384
+ if (syntheticChanges.length === 0) continue;
5385
+ if (change.changeType === "NO_CHANGE") {
5386
+ change.changeType = "UPDATE";
5387
+ change.propertyChanges = syntheticChanges;
5388
+ this.logger.debug(`UPDATE (in-place attr propagated): ${dependentId} reads a changed attribute of an updated resource`);
5389
+ } else change.propertyChanges = [...change.propertyChanges ?? [], ...syntheticChanges];
5390
+ }
5391
+ }
5392
+ /**
5393
+ * Extract `Fn::GetAtt` / `Fn::Sub`-`${X.Attr}` references from a property value
5394
+ * as a map of `referencedLogicalId -> set of referenced attribute names`.
5395
+ * Plain `Ref` is intentionally NOT captured: it resolves to the physical id,
5396
+ * which an in-place update never changes. Recurses into arrays / objects so
5397
+ * intrinsics nested inside `Fn::Sub`'s variable map / `Fn::Join` etc. are seen.
5398
+ */
5399
+ static extractGetAttRefs(value) {
5400
+ const refs = /* @__PURE__ */ new Map();
5401
+ const add = (id, attr) => {
5402
+ if (id.startsWith("AWS::")) return;
5403
+ let set = refs.get(id);
5404
+ if (!set) {
5405
+ set = /* @__PURE__ */ new Set();
5406
+ refs.set(id, set);
5407
+ }
5408
+ set.add(attr);
5409
+ };
5410
+ const walk = (v) => {
5411
+ if (v === null || typeof v !== "object") return;
5412
+ if (Array.isArray(v)) {
5413
+ v.forEach(walk);
5414
+ return;
5415
+ }
5416
+ const obj = v;
5417
+ if ("Fn::GetAtt" in obj) {
5418
+ const ga = obj["Fn::GetAtt"];
5419
+ if (Array.isArray(ga) && typeof ga[0] === "string" && typeof ga[1] === "string") add(ga[0], ga[1]);
5420
+ return;
5421
+ }
5422
+ if ("Fn::Sub" in obj) {
5423
+ const sub = obj["Fn::Sub"];
5424
+ let body;
5425
+ let mapKeys;
5426
+ if (typeof sub === "string") body = sub;
5427
+ else if (Array.isArray(sub) && typeof sub[0] === "string") {
5428
+ body = sub[0];
5429
+ const vars = sub[1];
5430
+ if (vars && typeof vars === "object" && !Array.isArray(vars)) {
5431
+ mapKeys = new Set(Object.keys(vars));
5432
+ Object.values(vars).forEach(walk);
5433
+ }
5434
+ }
5435
+ if (body !== void 0) for (const m of body.matchAll(/\$\{(!)?([^}]+)\}/g)) {
5436
+ if (m[1] === "!") continue;
5437
+ const placeholder = m[2];
5438
+ if (!placeholder) continue;
5439
+ const dot = placeholder.indexOf(".");
5440
+ if (dot < 0) continue;
5441
+ const id = placeholder.slice(0, dot);
5442
+ const attr = placeholder.slice(dot + 1);
5443
+ if (!id || mapKeys?.has(id)) continue;
5444
+ add(id, attr);
5445
+ }
5446
+ return;
5447
+ }
5448
+ if ("Ref" in obj && Object.keys(obj).length === 1) return;
5449
+ Object.values(obj).forEach(walk);
5450
+ };
5451
+ walk(value);
5452
+ return refs;
5453
+ }
5454
+ /**
5315
5455
  * Best-effort resolution of template property intrinsics against current state.
5316
5456
  *
5317
5457
  * Iterates top-level properties and resolves each independently: if resolution
@@ -5322,7 +5462,7 @@ var DiffCalculator = class DiffCalculator {
5322
5462
  async resolveBestEffort(properties, resolveFn) {
5323
5463
  const resolved = {};
5324
5464
  for (const [key, value] of Object.entries(properties)) try {
5325
- resolved[key] = await resolveFn(value);
5465
+ resolved[key] = await resolveFn(structuredClone(value));
5326
5466
  } catch {
5327
5467
  resolved[key] = value;
5328
5468
  }
@@ -5446,7 +5586,9 @@ var DiffCalculator = class DiffCalculator {
5446
5586
  if (typeof a === "object" && typeof b === "object") {
5447
5587
  const aObj = a;
5448
5588
  const bObj = b;
5589
+ const aKeys = Object.keys(aObj);
5449
5590
  const bKeys = Object.keys(bObj);
5591
+ if (aKeys.length !== bKeys.length) return false;
5450
5592
  for (const key of bKeys) {
5451
5593
  if (!(key in aObj)) return false;
5452
5594
  if (!this.valuesEqual(aObj[key], bObj[key])) return false;
@@ -13894,4 +14036,4 @@ var DeployEngine = class {
13894
14036
 
13895
14037
  //#endregion
13896
14038
  export { CFN_TEMPLATE_BODY_LIMIT as $, LockManager as A, runDockerForeground as B, findActionableSilentDrops as C, DiffCalculator as D, applyRoleArnIfSet as E, stringifyValue as F, getDefaultStateBucketName as G, AssetManifestLoader as H, WorkGraph as I, resolveCaptureObservedState as J, getLegacyStateBucketName as K, buildDockerImage as L, rebuildClientForBucketRegion as M, shouldRetainResource as N, DagBuilder as O, AssetPublisher as P, warnDeprecatedNoPrefixCliFlag as Q, formatDockerLoginError as R, ProviderRegistry as S, IntrinsicFunctionResolver as T, getDockerImageBySourceHash as U, runDockerStreaming as V, Synthesizer as W, resolveStateBucketWithDefault as X, resolveSkipPrefix as Y, resolveStateBucketWithDefaultAndSource as Z, green as _, withRetry as a, clearBucketRegionCache as at, IAMRoleProvider as b, computeImplicitDeleteEdges as c, isStatefulRecreateTargetSync as d, CFN_TEMPLATE_URL_LIMIT as et, renderStatefulReason as f, gray as g, cyan as h, withResourceDeadline as i, AssemblyReader as it, S3StateBackend as j, TemplateParser as k, extractDeploymentEventError as l, bold as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, findLargeInlineResources as nt, isRetryableTransientError as o, resolveBucketRegion as ot, formatResourceLine as p, resolveApp as q, DeployEngine as r, uploadCfnTemplate as rt, IMPLICIT_DELETE_DEPENDENCIES as s, DEFAULT_RESOURCE_TIMEOUT_MS as t, MIGRATE_TMP_PREFIX as tt, MULTI_REGION_RECREATE_BLOCKED_TYPES as u, red as v, CloudControlProvider as w, collectInlinePolicyNamesManagedBySiblings as x, yellow as y, getDockerCmd as z };
13897
- //# sourceMappingURL=deploy-engine-B1a6fz6L.js.map
14039
+ //# sourceMappingURL=deploy-engine-BqUZUty9.js.map