@go-to-k/cdkd 0.31.2 → 0.32.0

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.
Binary file
package/dist/index.js CHANGED
@@ -3934,6 +3934,58 @@ function collectRefIds(value, out) {
3934
3934
  }
3935
3935
  }
3936
3936
 
3937
+ // src/analyzer/cdk-defensive-deps.ts
3938
+ var DEFENSIVE_DEPENDS_ON_TYPE_PAIRS = [
3939
+ // VPC Lambda's execution Role (and its inline Policy) get DependsOn'd onto
3940
+ // the route only because CDK assumes the Lambda will run before the route
3941
+ // is up. The Role/Policy create call itself is VPC-agnostic.
3942
+ { fromType: "AWS::IAM::Role", toType: "AWS::EC2::Route" },
3943
+ { fromType: "AWS::IAM::Role", toType: "AWS::EC2::SubnetRouteTableAssociation" },
3944
+ { fromType: "AWS::IAM::Policy", toType: "AWS::EC2::Route" },
3945
+ { fromType: "AWS::IAM::Policy", toType: "AWS::EC2::SubnetRouteTableAssociation" },
3946
+ // VPC Lambda itself: CreateFunction returns synchronously while the
3947
+ // function is still in Pending; the route only matters once the function
3948
+ // is invoked at runtime.
3949
+ { fromType: "AWS::Lambda::Function", toType: "AWS::EC2::Route" },
3950
+ { fromType: "AWS::Lambda::Function", toType: "AWS::EC2::SubnetRouteTableAssociation" },
3951
+ // Lambda::Url is just a deterministic URL derivation off the function; it
3952
+ // doesn't need the function's runtime egress to exist.
3953
+ { fromType: "AWS::Lambda::Url", toType: "AWS::EC2::Route" },
3954
+ { fromType: "AWS::Lambda::Url", toType: "AWS::EC2::SubnetRouteTableAssociation" },
3955
+ // EventSourceMapping just registers the wire-up; AWS handles delivery
3956
+ // async and will retry once the function reaches Active.
3957
+ { fromType: "AWS::Lambda::EventSourceMapping", toType: "AWS::EC2::Route" },
3958
+ {
3959
+ fromType: "AWS::Lambda::EventSourceMapping",
3960
+ toType: "AWS::EC2::SubnetRouteTableAssociation"
3961
+ }
3962
+ ];
3963
+ function defensiveDependsOnToSkip(resource, template) {
3964
+ const skip = /* @__PURE__ */ new Set();
3965
+ if (!resource.DependsOn) {
3966
+ return skip;
3967
+ }
3968
+ const dependsOn = Array.isArray(resource.DependsOn) ? resource.DependsOn : [resource.DependsOn];
3969
+ for (const dep of dependsOn) {
3970
+ if (typeof dep !== "string")
3971
+ continue;
3972
+ const target = template.Resources[dep];
3973
+ if (!target)
3974
+ continue;
3975
+ const fromType = resource.Type;
3976
+ const toType = target.Type;
3977
+ if (!fromType || !toType)
3978
+ continue;
3979
+ const matched = DEFENSIVE_DEPENDS_ON_TYPE_PAIRS.some(
3980
+ (pair) => pair.fromType === fromType && pair.toType === toType
3981
+ );
3982
+ if (matched) {
3983
+ skip.add(dep);
3984
+ }
3985
+ }
3986
+ return skip;
3987
+ }
3988
+
3937
3989
  // src/analyzer/dag-builder.ts
3938
3990
  var { Graph, alg } = graphlib;
3939
3991
  var IAM_ROLE_POLICY_TYPES = /* @__PURE__ */ new Set([
@@ -3944,6 +3996,10 @@ var IAM_ROLE_POLICY_TYPES = /* @__PURE__ */ new Set([
3944
3996
  var DagBuilder = class {
3945
3997
  logger = getLogger().child("DagBuilder");
3946
3998
  parser = new TemplateParser();
3999
+ options;
4000
+ constructor(options = {}) {
4001
+ this.options = options;
4002
+ }
3947
4003
  /**
3948
4004
  * Build dependency graph from CloudFormation template
3949
4005
  *
@@ -3962,13 +4018,22 @@ var DagBuilder = class {
3962
4018
  });
3963
4019
  this.logger.debug(`Total nodes: ${resourceIds.length}`);
3964
4020
  let edgeCount = 0;
4021
+ let relaxedEdgeCount = 0;
3965
4022
  for (const logicalId of resourceIds) {
3966
4023
  const resource = this.parser.getResource(template, logicalId);
3967
4024
  if (!resource) {
3968
4025
  continue;
3969
4026
  }
3970
4027
  const dependencies = this.parser.extractDependencies(resource);
4028
+ const skip = this.options.relaxCdkVpcDefensiveDeps ? defensiveDependsOnToSkip(resource, template) : null;
3971
4029
  for (const depId of dependencies) {
4030
+ if (skip?.has(depId)) {
4031
+ relaxedEdgeCount++;
4032
+ this.logger.debug(
4033
+ `Skipped CDK-defensive DependsOn edge: ${depId} -> ${logicalId} (--aggressive-vpc-parallel)`
4034
+ );
4035
+ continue;
4036
+ }
3972
4037
  if (graph.hasNode(depId)) {
3973
4038
  graph.setEdge(depId, logicalId);
3974
4039
  edgeCount++;
@@ -3980,6 +4045,11 @@ var DagBuilder = class {
3980
4045
  }
3981
4046
  }
3982
4047
  }
4048
+ if (relaxedEdgeCount > 0) {
4049
+ this.logger.info(
4050
+ `[DagBuilder] Relaxed ${relaxedEdgeCount} CDK-defensive DependsOn edge(s) (--aggressive-vpc-parallel)`
4051
+ );
4052
+ }
3983
4053
  this.logger.debug(`Dependency graph built: ${resourceIds.length} nodes, ${edgeCount} edges`);
3984
4054
  edgeCount += this.addCustomResourcePolicyEdges(graph, template);
3985
4055
  edgeCount += this.addLambdaVpcEdges(graph, template);