@go-to-k/cdkd 0.50.6 → 0.50.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 CHANGED
@@ -8705,10 +8705,10 @@ var IAMRoleProvider = class {
8705
8705
  const updateParams = {
8706
8706
  RoleName: physicalId
8707
8707
  };
8708
- if (properties["Description"]) {
8708
+ if (properties["Description"] !== void 0) {
8709
8709
  updateParams.Description = properties["Description"];
8710
8710
  }
8711
- if (properties["MaxSessionDuration"]) {
8711
+ if (properties["MaxSessionDuration"] !== void 0) {
8712
8712
  updateParams.MaxSessionDuration = properties["MaxSessionDuration"];
8713
8713
  }
8714
8714
  await this.iamClient.send(new UpdateRoleCommand(updateParams));
@@ -12641,6 +12641,14 @@ import {
12641
12641
  } from "@aws-sdk/client-sqs";
12642
12642
  import { GetCallerIdentityCommand as GetCallerIdentityCommand4 } from "@aws-sdk/client-sts";
12643
12643
  init_aws_clients();
12644
+ function serializeRedrivePolicy(value) {
12645
+ if (value === null || value === void 0)
12646
+ return "";
12647
+ if (typeof value === "object" && Object.keys(value).length === 0) {
12648
+ return "";
12649
+ }
12650
+ return JSON.stringify(value);
12651
+ }
12644
12652
  var CDK_TO_SQS_ATTRIBUTES = {
12645
12653
  VisibilityTimeout: "VisibilityTimeout",
12646
12654
  MaximumMessageSize: "MaximumMessageSize",
@@ -12699,7 +12707,7 @@ var SQSQueueProvider = class {
12699
12707
  if (properties[cdkKey] !== void 0) {
12700
12708
  const value = properties[cdkKey];
12701
12709
  if (cdkKey === "RedrivePolicy" && typeof value === "object") {
12702
- attributes[sqsKey] = JSON.stringify(value);
12710
+ attributes[sqsKey] = serializeRedrivePolicy(value);
12703
12711
  } else {
12704
12712
  attributes[sqsKey] = String(value);
12705
12713
  }
@@ -12757,7 +12765,7 @@ var SQSQueueProvider = class {
12757
12765
  if (properties[cdkKey] !== void 0) {
12758
12766
  const value = properties[cdkKey];
12759
12767
  if (cdkKey === "RedrivePolicy" && typeof value === "object") {
12760
- attributes[sqsKey] = JSON.stringify(value);
12768
+ attributes[sqsKey] = serializeRedrivePolicy(value);
12761
12769
  } else {
12762
12770
  attributes[sqsKey] = String(value);
12763
12771
  }
@@ -15469,18 +15477,36 @@ var LambdaUrlProvider = class {
15469
15477
  /**
15470
15478
  * Update a Lambda Function URL
15471
15479
  */
15472
- async update(logicalId, physicalId, _resourceType, properties, _previousProperties) {
15480
+ async update(logicalId, physicalId, _resourceType, properties, previousProperties) {
15473
15481
  this.logger.debug(`Updating Lambda URL ${logicalId}: ${physicalId}`);
15482
+ const handled = this.handledProperties.get("AWS::Lambda::Url") ?? /* @__PURE__ */ new Set();
15483
+ let changed = false;
15484
+ for (const key of handled) {
15485
+ if (JSON.stringify(properties[key] ?? null) !== JSON.stringify(previousProperties[key] ?? null)) {
15486
+ changed = true;
15487
+ break;
15488
+ }
15489
+ }
15490
+ if (!changed) {
15491
+ return {
15492
+ physicalId,
15493
+ wasReplaced: false,
15494
+ attributes: {}
15495
+ };
15496
+ }
15474
15497
  const authType = properties["AuthType"] || "NONE";
15475
15498
  const cors = properties["Cors"];
15476
15499
  const updateParams = {
15477
15500
  FunctionName: physicalId,
15478
15501
  AuthType: authType
15479
15502
  };
15480
- if (properties["InvokeMode"])
15503
+ if (properties["InvokeMode"] !== void 0)
15481
15504
  updateParams.InvokeMode = properties["InvokeMode"];
15482
15505
  if (cors) {
15483
- updateParams.Cors = this.buildCorsConfig(cors);
15506
+ const builtCors = this.buildCorsConfig(cors);
15507
+ if (Object.keys(builtCors).length > 0) {
15508
+ updateParams.Cors = builtCors;
15509
+ }
15484
15510
  }
15485
15511
  const response = await this.lambdaClient.send(new UpdateFunctionUrlConfigCommand(updateParams));
15486
15512
  return {
@@ -15630,19 +15656,36 @@ var LambdaUrlProvider = class {
15630
15656
  return null;
15631
15657
  }
15632
15658
  /**
15633
- * Build CORS configuration from CDK properties
15659
+ * Build CORS configuration from CDK properties.
15660
+ *
15661
+ * Empty arrays from `readCurrentState`'s always-emit placeholder
15662
+ * (`AllowOrigins: []`, `AllowMethods: []`, `AllowHeaders: []`,
15663
+ * `ExposeHeaders: []`) are intentionally dropped here — emitting them
15664
+ * to AWS would configure CORS with empty allowlists instead of
15665
+ * leaving CORS unset. The caller (`update()` / `create()`) treats an
15666
+ * empty `Cors` object as "no CORS configured" and omits it from the
15667
+ * SDK input. `MaxAge` uses `!== undefined` so the valid AWS input
15668
+ * `MaxAge: 0` (= "do not cache preflight responses") is preserved.
15634
15669
  */
15635
15670
  buildCorsConfig(cors) {
15636
15671
  const config = {};
15637
- if (cors["AllowOrigins"])
15638
- config.AllowOrigins = cors["AllowOrigins"];
15639
- if (cors["AllowMethods"])
15640
- config.AllowMethods = cors["AllowMethods"];
15641
- if (cors["AllowHeaders"])
15642
- config.AllowHeaders = cors["AllowHeaders"];
15643
- if (cors["ExposeHeaders"])
15644
- config.ExposeHeaders = cors["ExposeHeaders"];
15645
- if (cors["MaxAge"])
15672
+ const allowOrigins = cors["AllowOrigins"];
15673
+ if (Array.isArray(allowOrigins) && allowOrigins.length > 0) {
15674
+ config.AllowOrigins = allowOrigins;
15675
+ }
15676
+ const allowMethods = cors["AllowMethods"];
15677
+ if (Array.isArray(allowMethods) && allowMethods.length > 0) {
15678
+ config.AllowMethods = allowMethods;
15679
+ }
15680
+ const allowHeaders = cors["AllowHeaders"];
15681
+ if (Array.isArray(allowHeaders) && allowHeaders.length > 0) {
15682
+ config.AllowHeaders = allowHeaders;
15683
+ }
15684
+ const exposeHeaders = cors["ExposeHeaders"];
15685
+ if (Array.isArray(exposeHeaders) && exposeHeaders.length > 0) {
15686
+ config.ExposeHeaders = exposeHeaders;
15687
+ }
15688
+ if (cors["MaxAge"] !== void 0)
15646
15689
  config.MaxAge = cors["MaxAge"];
15647
15690
  if (cors["AllowCredentials"] !== void 0)
15648
15691
  config.AllowCredentials = cors["AllowCredentials"];
@@ -15661,6 +15704,43 @@ import {
15661
15704
  ResourceNotFoundException as ResourceNotFoundException4
15662
15705
  } from "@aws-sdk/client-lambda";
15663
15706
  init_aws_clients();
15707
+ function classifyEventSource(resp) {
15708
+ if (resp.SelfManagedEventSource !== void 0)
15709
+ return "kafka";
15710
+ if (resp.SelfManagedKafkaEventSourceConfig !== void 0)
15711
+ return "kafka";
15712
+ if (resp.AmazonManagedKafkaEventSourceConfig !== void 0)
15713
+ return "kafka";
15714
+ if (resp.DocumentDBEventSourceConfig !== void 0)
15715
+ return "documentdb";
15716
+ const arn = resp.EventSourceArn;
15717
+ if (!arn)
15718
+ return "unknown";
15719
+ if (arn.startsWith("arn:aws:sqs:") || arn.startsWith("arn:aws-cn:sqs:"))
15720
+ return "sqs";
15721
+ if (arn.startsWith("arn:aws:kinesis:") || arn.startsWith("arn:aws-cn:kinesis:"))
15722
+ return "kinesis";
15723
+ if (arn.startsWith("arn:aws:dynamodb:") || arn.startsWith("arn:aws-cn:dynamodb:"))
15724
+ return "dynamodb";
15725
+ if (arn.startsWith("arn:aws:kafka:") || arn.startsWith("arn:aws-cn:kafka:"))
15726
+ return "kafka";
15727
+ if (arn.startsWith("arn:aws:mq:") || arn.startsWith("arn:aws-cn:mq:"))
15728
+ return "mq";
15729
+ if (arn.startsWith("arn:aws:rds:") || arn.startsWith("arn:aws-cn:rds:")) {
15730
+ return "documentdb";
15731
+ }
15732
+ return "unknown";
15733
+ }
15734
+ var KINDS_WITH_FUNCTION_RESPONSE_TYPES = /* @__PURE__ */ new Set([
15735
+ "sqs",
15736
+ "kinesis",
15737
+ "dynamodb"
15738
+ ]);
15739
+ var KINDS_WITH_SOURCE_ACCESS_CONFIGURATIONS = /* @__PURE__ */ new Set([
15740
+ "kafka",
15741
+ "mq",
15742
+ "documentdb"
15743
+ ]);
15664
15744
  var LambdaEventSourceMappingProvider = class {
15665
15745
  lambdaClient;
15666
15746
  logger = getLogger().child("LambdaEventSourceMappingProvider");
@@ -15787,33 +15867,33 @@ var LambdaEventSourceMappingProvider = class {
15787
15867
  UUID: physicalId,
15788
15868
  FunctionName: properties["FunctionName"]
15789
15869
  };
15790
- if (properties["BatchSize"])
15870
+ if (properties["BatchSize"] !== void 0)
15791
15871
  updateParams.BatchSize = properties["BatchSize"];
15792
15872
  if (properties["Enabled"] !== void 0)
15793
15873
  updateParams.Enabled = properties["Enabled"];
15794
- if (properties["MaximumBatchingWindowInSeconds"])
15874
+ if (properties["MaximumBatchingWindowInSeconds"] !== void 0)
15795
15875
  updateParams.MaximumBatchingWindowInSeconds = properties["MaximumBatchingWindowInSeconds"];
15796
15876
  if (properties["MaximumRetryAttempts"] !== void 0)
15797
15877
  updateParams.MaximumRetryAttempts = properties["MaximumRetryAttempts"];
15798
15878
  if (properties["BisectBatchOnFunctionError"] !== void 0)
15799
15879
  updateParams.BisectBatchOnFunctionError = properties["BisectBatchOnFunctionError"];
15800
- if (properties["MaximumRecordAgeInSeconds"])
15880
+ if (properties["MaximumRecordAgeInSeconds"] !== void 0)
15801
15881
  updateParams.MaximumRecordAgeInSeconds = properties["MaximumRecordAgeInSeconds"];
15802
- if (properties["ParallelizationFactor"])
15882
+ if (properties["ParallelizationFactor"] !== void 0)
15803
15883
  updateParams.ParallelizationFactor = properties["ParallelizationFactor"];
15804
- if (properties["FilterCriteria"])
15884
+ if (properties["FilterCriteria"] !== void 0)
15805
15885
  updateParams.FilterCriteria = properties["FilterCriteria"];
15806
- if (properties["DestinationConfig"])
15886
+ if (properties["DestinationConfig"] !== void 0)
15807
15887
  updateParams.DestinationConfig = properties["DestinationConfig"];
15808
- if (properties["TumblingWindowInSeconds"])
15888
+ if (properties["TumblingWindowInSeconds"] !== void 0)
15809
15889
  updateParams.TumblingWindowInSeconds = properties["TumblingWindowInSeconds"];
15810
- if (properties["FunctionResponseTypes"])
15890
+ if (properties["FunctionResponseTypes"] !== void 0)
15811
15891
  updateParams.FunctionResponseTypes = properties["FunctionResponseTypes"];
15812
- if (properties["SourceAccessConfigurations"])
15892
+ if (properties["SourceAccessConfigurations"] !== void 0)
15813
15893
  updateParams.SourceAccessConfigurations = properties["SourceAccessConfigurations"];
15814
- if (properties["ScalingConfig"])
15894
+ if (properties["ScalingConfig"] !== void 0)
15815
15895
  updateParams.ScalingConfig = properties["ScalingConfig"];
15816
- if (properties["DocumentDBEventSourceConfig"])
15896
+ if (properties["DocumentDBEventSourceConfig"] !== void 0)
15817
15897
  updateParams.DocumentDBEventSourceConfig = properties["DocumentDBEventSourceConfig"];
15818
15898
  const updateResp = await this.lambdaClient.send(
15819
15899
  new UpdateEventSourceMappingCommand(updateParams)
@@ -15987,8 +16067,17 @@ var LambdaEventSourceMappingProvider = class {
15987
16067
  if (resp.TumblingWindowInSeconds !== void 0) {
15988
16068
  result["TumblingWindowInSeconds"] = resp.TumblingWindowInSeconds;
15989
16069
  }
15990
- result["FunctionResponseTypes"] = resp.FunctionResponseTypes ? [...resp.FunctionResponseTypes] : [];
15991
- result["SourceAccessConfigurations"] = resp.SourceAccessConfigurations ?? [];
16070
+ const kind = classifyEventSource(resp);
16071
+ if (KINDS_WITH_FUNCTION_RESPONSE_TYPES.has(kind)) {
16072
+ result["FunctionResponseTypes"] = resp.FunctionResponseTypes ? [...resp.FunctionResponseTypes] : [];
16073
+ } else if (resp.FunctionResponseTypes !== void 0) {
16074
+ result["FunctionResponseTypes"] = [...resp.FunctionResponseTypes];
16075
+ }
16076
+ if (KINDS_WITH_SOURCE_ACCESS_CONFIGURATIONS.has(kind)) {
16077
+ result["SourceAccessConfigurations"] = resp.SourceAccessConfigurations ?? [];
16078
+ } else if (resp.SourceAccessConfigurations !== void 0) {
16079
+ result["SourceAccessConfigurations"] = resp.SourceAccessConfigurations;
16080
+ }
15992
16081
  if (resp.SelfManagedEventSource !== void 0) {
15993
16082
  result["SelfManagedEventSource"] = resp.SelfManagedEventSource;
15994
16083
  }
@@ -16116,19 +16205,35 @@ var LambdaLayerVersionProvider = class {
16116
16205
  }
16117
16206
  }
16118
16207
  /**
16119
- * Update a Lambda layer version
16208
+ * Update a Lambda layer version.
16120
16209
  *
16121
- * Lambda layer versions are immutable. An update publishes a new version.
16122
- * The new LayerVersionArn becomes the physical ID.
16210
+ * Lambda layer versions are immutable on AWS there is no API to mutate
16211
+ * `Content` / `CompatibleRuntimes` / `CompatibleArchitectures` /
16212
+ * `Description` / `LicenseInfo` of an existing version. The only path to
16213
+ * a "new value" is publishing a new version (new LayerVersionArn).
16214
+ *
16215
+ * Why this rejects with `ResourceUpdateNotSupportedError` instead of
16216
+ * silently publishing a new version:
16217
+ *
16218
+ * - `cdkd drift --revert` calls `update(observed, observed)` to push
16219
+ * state values back into AWS. For an immutable resource that cannot
16220
+ * have its in-place value changed, the only AWS-side effect of an
16221
+ * "update" is leaking a duplicate version of the same content,
16222
+ * which is never what `--revert` should do.
16223
+ * - On the deploy path, content / runtime / arch changes flow
16224
+ * through CDK's hash-based logical naming, which produces a fresh
16225
+ * logical ID and a CREATE+DELETE in cdkd's diff — `update()` is
16226
+ * not the path taken in practice. Users who hit this on a non-CDK
16227
+ * template should re-deploy with `--replace`.
16123
16228
  */
16124
- async update(logicalId, physicalId, resourceType, properties, _previousProperties) {
16125
- this.logger.debug(`Updating Lambda layer version ${logicalId}: ${physicalId}`);
16126
- const createResult = await this.create(logicalId, resourceType, properties);
16127
- return {
16128
- physicalId: createResult.physicalId,
16129
- wasReplaced: true,
16130
- attributes: createResult.attributes ?? {}
16131
- };
16229
+ async update(logicalId, _physicalId, resourceType, _properties, _previousProperties) {
16230
+ return Promise.reject(
16231
+ new ResourceUpdateNotSupportedError(
16232
+ resourceType,
16233
+ logicalId,
16234
+ "Lambda layer versions are immutable on AWS; re-deploy with cdkd deploy --replace, or change the resource definition to publish a new version"
16235
+ )
16236
+ );
16132
16237
  }
16133
16238
  /**
16134
16239
  * Delete a Lambda layer version
@@ -39824,6 +39929,19 @@ async function runAccept(reports, stateBackend, stateConfig, awsClients, options
39824
39929
  }
39825
39930
  }
39826
39931
  }
39932
+ function buildRevertNewProperties(drifts, desiredProperties, awsProperties) {
39933
+ const result = { ...awsProperties };
39934
+ for (const d of drifts) {
39935
+ const topLevelKey = d.path.split(".", 1)[0];
39936
+ if (!topLevelKey)
39937
+ continue;
39938
+ if (topLevelKey in desiredProperties) {
39939
+ result[topLevelKey] = desiredProperties[topLevelKey];
39940
+ } else {
39941
+ }
39942
+ }
39943
+ return result;
39944
+ }
39827
39945
  async function runRevert(reports, providerRegistry, stateConfig, awsClients, options) {
39828
39946
  const logger = getLogger();
39829
39947
  printRevertPlan(reports);
@@ -39866,13 +39984,18 @@ async function runRevert(reports, providerRegistry, stateConfig, awsClients, opt
39866
39984
  }
39867
39985
  const provider = providerRegistry.getProvider(outcome.resourceType);
39868
39986
  const desiredProperties = stateResource.observedProperties ?? stateResource.properties ?? {};
39987
+ const newProperties = buildRevertNewProperties(
39988
+ outcome.changes,
39989
+ desiredProperties,
39990
+ outcome.awsProperties
39991
+ );
39869
39992
  try {
39870
39993
  await withRetry(
39871
39994
  () => provider.update(
39872
39995
  outcome.logicalId,
39873
39996
  stateResource.physicalId,
39874
39997
  outcome.resourceType,
39875
- desiredProperties,
39998
+ newProperties,
39876
39999
  outcome.awsProperties
39877
40000
  ),
39878
40001
  outcome.logicalId,
@@ -43505,7 +43628,7 @@ function reorderArgs(argv) {
43505
43628
  }
43506
43629
  async function main() {
43507
43630
  const program = new Command14();
43508
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.50.6");
43631
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.50.8");
43509
43632
  program.addCommand(createBootstrapCommand());
43510
43633
  program.addCommand(createSynthCommand());
43511
43634
  program.addCommand(createListCommand());