@go-to-k/cdkd 0.55.0 → 0.56.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.
package/dist/cli.js CHANGED
@@ -24059,18 +24059,23 @@ import {
24059
24059
  ApiGatewayV2Client,
24060
24060
  CreateApiCommand,
24061
24061
  DeleteApiCommand,
24062
+ UpdateApiCommand,
24062
24063
  CreateStageCommand as CreateStageCommand2,
24063
24064
  DeleteStageCommand as DeleteStageCommand2,
24064
24065
  GetStageCommand as GetStageCommand2,
24066
+ UpdateStageCommand as UpdateStageCommand2,
24065
24067
  CreateIntegrationCommand,
24066
24068
  DeleteIntegrationCommand,
24067
24069
  GetIntegrationCommand,
24070
+ UpdateIntegrationCommand,
24068
24071
  CreateRouteCommand as CreateRouteCommand2,
24069
24072
  DeleteRouteCommand as DeleteRouteCommand2,
24070
24073
  GetRouteCommand,
24074
+ UpdateRouteCommand,
24071
24075
  CreateAuthorizerCommand as CreateAuthorizerCommand2,
24072
24076
  DeleteAuthorizerCommand as DeleteAuthorizerCommand2,
24073
24077
  GetAuthorizerCommand as GetAuthorizerCommand2,
24078
+ UpdateAuthorizerCommand as UpdateAuthorizerCommand2,
24074
24079
  GetApiCommand,
24075
24080
  GetApisCommand,
24076
24081
  NotFoundException as NotFoundException4
@@ -24145,22 +24150,59 @@ var ApiGatewayV2Provider = class {
24145
24150
  }
24146
24151
  }
24147
24152
  /**
24148
- * HTTP API resources are treated as immutable by cdkd: the deploy engine
24149
- * recreates them on property changes via the immutable-property
24150
- * replacement path. AWS does expose `UpdateApi` / `UpdateRoute` /
24151
- * `UpdateIntegration` / `UpdateStage` / `UpdateAuthorizer`, but cdkd
24152
- * does not yet plumb them through. `cdkd drift --revert` surfaces a
24153
- * clear "use --replace or re-deploy" message instead of silently
24154
- * no-op'ing the revert.
24153
+ * AWS API Gateway V2 supports in-place updates for every type cdkd
24154
+ * provisions via the matching `Update*Command`. Each command takes the
24155
+ * full Update input shape (NOT JSON Patch that's the v1 surface);
24156
+ * cdkd builds the input by selecting only the fields that differ
24157
+ * between `previousProperties` and `properties`, so unchanged fields
24158
+ * are not echoed back. The few immutable identifiers (`ProtocolType`
24159
+ * on Api; `StageName` on Stage) are not part of the Update input shape
24160
+ * and are handled by the deploy engine's immutable-property
24161
+ * replacement path.
24155
24162
  */
24156
- update(logicalId, _physicalId, resourceType, _properties, _previousProperties) {
24157
- return Promise.reject(
24158
- new ResourceUpdateNotSupportedError(
24159
- resourceType,
24160
- logicalId,
24161
- "API Gateway V2 (HTTP API) resources are recreated on property changes; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
24162
- )
24163
- );
24163
+ async update(logicalId, physicalId, resourceType, properties, previousProperties) {
24164
+ switch (resourceType) {
24165
+ case "AWS::ApiGatewayV2::Api":
24166
+ return this.updateApi(logicalId, physicalId, resourceType, properties, previousProperties);
24167
+ case "AWS::ApiGatewayV2::Stage":
24168
+ return this.updateStage(
24169
+ logicalId,
24170
+ physicalId,
24171
+ resourceType,
24172
+ properties,
24173
+ previousProperties
24174
+ );
24175
+ case "AWS::ApiGatewayV2::Integration":
24176
+ return this.updateIntegration(
24177
+ logicalId,
24178
+ physicalId,
24179
+ resourceType,
24180
+ properties,
24181
+ previousProperties
24182
+ );
24183
+ case "AWS::ApiGatewayV2::Route":
24184
+ return this.updateRoute(
24185
+ logicalId,
24186
+ physicalId,
24187
+ resourceType,
24188
+ properties,
24189
+ previousProperties
24190
+ );
24191
+ case "AWS::ApiGatewayV2::Authorizer":
24192
+ return this.updateAuthorizer(
24193
+ logicalId,
24194
+ physicalId,
24195
+ resourceType,
24196
+ properties,
24197
+ previousProperties
24198
+ );
24199
+ default:
24200
+ throw new ResourceUpdateNotSupportedError(
24201
+ resourceType,
24202
+ logicalId,
24203
+ "unsupported API Gateway V2 resource type for in-place update; re-deploy with cdkd deploy --replace, or destroy + redeploy the stack"
24204
+ );
24205
+ }
24164
24206
  }
24165
24207
  async delete(logicalId, physicalId, resourceType, properties, context) {
24166
24208
  switch (resourceType) {
@@ -24811,6 +24853,312 @@ var ApiGatewayV2Provider = class {
24811
24853
  } while (nextToken);
24812
24854
  return null;
24813
24855
  }
24856
+ // ─── Update implementations ───────────────────────────────────────
24857
+ /**
24858
+ * `UpdateApi` accepts the full Update input shape (not JSON Patch).
24859
+ * Mutable fields cdkd manages: `Name` / `Description` /
24860
+ * `CorsConfiguration`. `ProtocolType` is immutable — the deploy
24861
+ * engine handles changes via the replacement path; we surface a
24862
+ * `ResourceUpdateNotSupportedError` if it ever reaches us anyway.
24863
+ */
24864
+ async updateApi(logicalId, physicalId, resourceType, properties, previousProperties) {
24865
+ if (properties["ProtocolType"] !== void 0 && previousProperties["ProtocolType"] !== void 0 && properties["ProtocolType"] !== previousProperties["ProtocolType"]) {
24866
+ throw new ResourceUpdateNotSupportedError(
24867
+ resourceType,
24868
+ logicalId,
24869
+ "ProtocolType is immutable on AWS::ApiGatewayV2::Api; re-deploy with cdkd deploy --replace"
24870
+ );
24871
+ }
24872
+ const input = { ApiId: physicalId };
24873
+ let changed = false;
24874
+ if (properties["Name"] !== void 0 && properties["Name"] !== previousProperties["Name"]) {
24875
+ input.Name = properties["Name"];
24876
+ changed = true;
24877
+ }
24878
+ if (properties["Description"] !== void 0 && properties["Description"] !== previousProperties["Description"]) {
24879
+ input.Description = properties["Description"];
24880
+ changed = true;
24881
+ }
24882
+ if (properties["CorsConfiguration"] !== void 0 && !this.deepEqual(properties["CorsConfiguration"], previousProperties["CorsConfiguration"])) {
24883
+ input.CorsConfiguration = properties["CorsConfiguration"];
24884
+ changed = true;
24885
+ }
24886
+ if (!changed) {
24887
+ this.logger.debug(`No mutable Api fields changed for ${logicalId}; skipping UpdateApi`);
24888
+ return { physicalId, wasReplaced: false };
24889
+ }
24890
+ this.logger.debug(`Updating API Gateway V2 Api ${logicalId}: ${physicalId}`);
24891
+ try {
24892
+ await this.getClient().send(new UpdateApiCommand(input));
24893
+ return { physicalId, wasReplaced: false };
24894
+ } catch (error) {
24895
+ const cause = error instanceof Error ? error : void 0;
24896
+ throw new ProvisioningError(
24897
+ `Failed to update API Gateway V2 Api ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
24898
+ resourceType,
24899
+ logicalId,
24900
+ physicalId,
24901
+ cause
24902
+ );
24903
+ }
24904
+ }
24905
+ /**
24906
+ * `UpdateStage` keys on `(ApiId, StageName)` — `StageName` is the
24907
+ * physicalId and immutable. Mutable fields cdkd manages:
24908
+ * `AutoDeploy` / `Description`. `ApiId` is also immutable (a stage
24909
+ * cannot be moved between APIs).
24910
+ */
24911
+ async updateStage(logicalId, physicalId, resourceType, properties, previousProperties) {
24912
+ const apiId = properties["ApiId"] ?? previousProperties["ApiId"];
24913
+ if (!apiId) {
24914
+ throw new ProvisioningError(
24915
+ `ApiId is required to update Stage ${logicalId}`,
24916
+ resourceType,
24917
+ logicalId,
24918
+ physicalId
24919
+ );
24920
+ }
24921
+ if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"]) {
24922
+ throw new ResourceUpdateNotSupportedError(
24923
+ resourceType,
24924
+ logicalId,
24925
+ "ApiId is immutable on AWS::ApiGatewayV2::Stage; re-deploy with cdkd deploy --replace"
24926
+ );
24927
+ }
24928
+ if (properties["StageName"] !== void 0 && previousProperties["StageName"] !== void 0 && properties["StageName"] !== previousProperties["StageName"]) {
24929
+ throw new ResourceUpdateNotSupportedError(
24930
+ resourceType,
24931
+ logicalId,
24932
+ "StageName is immutable on AWS::ApiGatewayV2::Stage; re-deploy with cdkd deploy --replace"
24933
+ );
24934
+ }
24935
+ const input = { ApiId: apiId, StageName: physicalId };
24936
+ let changed = false;
24937
+ if (properties["AutoDeploy"] !== void 0 && properties["AutoDeploy"] !== previousProperties["AutoDeploy"]) {
24938
+ input.AutoDeploy = properties["AutoDeploy"];
24939
+ changed = true;
24940
+ }
24941
+ if (properties["Description"] !== void 0 && properties["Description"] !== previousProperties["Description"]) {
24942
+ input.Description = properties["Description"];
24943
+ changed = true;
24944
+ }
24945
+ if (!changed) {
24946
+ this.logger.debug(`No mutable Stage fields changed for ${logicalId}; skipping UpdateStage`);
24947
+ return { physicalId, wasReplaced: false };
24948
+ }
24949
+ this.logger.debug(`Updating API Gateway V2 Stage ${logicalId}: ${physicalId}`);
24950
+ try {
24951
+ await this.getClient().send(new UpdateStageCommand2(input));
24952
+ return { physicalId, wasReplaced: false };
24953
+ } catch (error) {
24954
+ const cause = error instanceof Error ? error : void 0;
24955
+ throw new ProvisioningError(
24956
+ `Failed to update API Gateway V2 Stage ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
24957
+ resourceType,
24958
+ logicalId,
24959
+ physicalId,
24960
+ cause
24961
+ );
24962
+ }
24963
+ }
24964
+ /**
24965
+ * `UpdateIntegration` keys on `(ApiId, IntegrationId)`. Mutable
24966
+ * fields cdkd manages: `IntegrationType` / `IntegrationUri` /
24967
+ * `IntegrationMethod` / `PayloadFormatVersion`.
24968
+ */
24969
+ async updateIntegration(logicalId, physicalId, resourceType, properties, previousProperties) {
24970
+ const apiId = properties["ApiId"] ?? previousProperties["ApiId"];
24971
+ if (!apiId) {
24972
+ throw new ProvisioningError(
24973
+ `ApiId is required to update Integration ${logicalId}`,
24974
+ resourceType,
24975
+ logicalId,
24976
+ physicalId
24977
+ );
24978
+ }
24979
+ if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"]) {
24980
+ throw new ResourceUpdateNotSupportedError(
24981
+ resourceType,
24982
+ logicalId,
24983
+ "ApiId is immutable on AWS::ApiGatewayV2::Integration; re-deploy with cdkd deploy --replace"
24984
+ );
24985
+ }
24986
+ const input = { ApiId: apiId, IntegrationId: physicalId };
24987
+ let changed = false;
24988
+ if (properties["IntegrationType"] !== void 0 && properties["IntegrationType"] !== previousProperties["IntegrationType"]) {
24989
+ input.IntegrationType = properties["IntegrationType"];
24990
+ changed = true;
24991
+ }
24992
+ if (properties["IntegrationUri"] !== void 0 && properties["IntegrationUri"] !== previousProperties["IntegrationUri"]) {
24993
+ input.IntegrationUri = properties["IntegrationUri"];
24994
+ changed = true;
24995
+ }
24996
+ if (properties["IntegrationMethod"] !== void 0 && properties["IntegrationMethod"] !== previousProperties["IntegrationMethod"]) {
24997
+ input.IntegrationMethod = properties["IntegrationMethod"];
24998
+ changed = true;
24999
+ }
25000
+ if (properties["PayloadFormatVersion"] !== void 0 && properties["PayloadFormatVersion"] !== previousProperties["PayloadFormatVersion"]) {
25001
+ input.PayloadFormatVersion = properties["PayloadFormatVersion"];
25002
+ changed = true;
25003
+ }
25004
+ if (!changed) {
25005
+ this.logger.debug(
25006
+ `No mutable Integration fields changed for ${logicalId}; skipping UpdateIntegration`
25007
+ );
25008
+ return { physicalId, wasReplaced: false };
25009
+ }
25010
+ this.logger.debug(`Updating API Gateway V2 Integration ${logicalId}: ${physicalId}`);
25011
+ try {
25012
+ await this.getClient().send(new UpdateIntegrationCommand(input));
25013
+ return { physicalId, wasReplaced: false };
25014
+ } catch (error) {
25015
+ const cause = error instanceof Error ? error : void 0;
25016
+ throw new ProvisioningError(
25017
+ `Failed to update API Gateway V2 Integration ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
25018
+ resourceType,
25019
+ logicalId,
25020
+ physicalId,
25021
+ cause
25022
+ );
25023
+ }
25024
+ }
25025
+ /**
25026
+ * `UpdateRoute` keys on `(ApiId, RouteId)`. Mutable fields cdkd
25027
+ * manages: `RouteKey` / `Target` / `AuthorizationType` /
25028
+ * `AuthorizerId` / `AuthorizationScopes`.
25029
+ */
25030
+ async updateRoute(logicalId, physicalId, resourceType, properties, previousProperties) {
25031
+ const apiId = properties["ApiId"] ?? previousProperties["ApiId"];
25032
+ if (!apiId) {
25033
+ throw new ProvisioningError(
25034
+ `ApiId is required to update Route ${logicalId}`,
25035
+ resourceType,
25036
+ logicalId,
25037
+ physicalId
25038
+ );
25039
+ }
25040
+ if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"]) {
25041
+ throw new ResourceUpdateNotSupportedError(
25042
+ resourceType,
25043
+ logicalId,
25044
+ "ApiId is immutable on AWS::ApiGatewayV2::Route; re-deploy with cdkd deploy --replace"
25045
+ );
25046
+ }
25047
+ const input = { ApiId: apiId, RouteId: physicalId };
25048
+ let changed = false;
25049
+ if (properties["RouteKey"] !== void 0 && properties["RouteKey"] !== previousProperties["RouteKey"]) {
25050
+ input.RouteKey = properties["RouteKey"];
25051
+ changed = true;
25052
+ }
25053
+ if (properties["Target"] !== void 0 && properties["Target"] !== previousProperties["Target"]) {
25054
+ input.Target = properties["Target"];
25055
+ changed = true;
25056
+ }
25057
+ if (properties["AuthorizationType"] !== void 0 && properties["AuthorizationType"] !== previousProperties["AuthorizationType"]) {
25058
+ input.AuthorizationType = properties["AuthorizationType"];
25059
+ changed = true;
25060
+ }
25061
+ if (properties["AuthorizerId"] !== void 0 && properties["AuthorizerId"] !== previousProperties["AuthorizerId"]) {
25062
+ input.AuthorizerId = properties["AuthorizerId"];
25063
+ changed = true;
25064
+ }
25065
+ if (properties["AuthorizationScopes"] !== void 0 && !this.deepEqual(properties["AuthorizationScopes"], previousProperties["AuthorizationScopes"])) {
25066
+ input.AuthorizationScopes = properties["AuthorizationScopes"];
25067
+ changed = true;
25068
+ }
25069
+ if (!changed) {
25070
+ this.logger.debug(`No mutable Route fields changed for ${logicalId}; skipping UpdateRoute`);
25071
+ return { physicalId, wasReplaced: false };
25072
+ }
25073
+ this.logger.debug(`Updating API Gateway V2 Route ${logicalId}: ${physicalId}`);
25074
+ try {
25075
+ await this.getClient().send(new UpdateRouteCommand(input));
25076
+ return { physicalId, wasReplaced: false };
25077
+ } catch (error) {
25078
+ const cause = error instanceof Error ? error : void 0;
25079
+ throw new ProvisioningError(
25080
+ `Failed to update API Gateway V2 Route ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
25081
+ resourceType,
25082
+ logicalId,
25083
+ physicalId,
25084
+ cause
25085
+ );
25086
+ }
25087
+ }
25088
+ /**
25089
+ * `UpdateAuthorizer` keys on `(ApiId, AuthorizerId)`. Mutable fields
25090
+ * cdkd manages: `AuthorizerType` / `Name` / `IdentitySource` /
25091
+ * `JwtConfiguration` / `AuthorizerUri` /
25092
+ * `AuthorizerPayloadFormatVersion`.
25093
+ */
25094
+ async updateAuthorizer(logicalId, physicalId, resourceType, properties, previousProperties) {
25095
+ const apiId = properties["ApiId"] ?? previousProperties["ApiId"];
25096
+ if (!apiId) {
25097
+ throw new ProvisioningError(
25098
+ `ApiId is required to update Authorizer ${logicalId}`,
25099
+ resourceType,
25100
+ logicalId,
25101
+ physicalId
25102
+ );
25103
+ }
25104
+ if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"]) {
25105
+ throw new ResourceUpdateNotSupportedError(
25106
+ resourceType,
25107
+ logicalId,
25108
+ "ApiId is immutable on AWS::ApiGatewayV2::Authorizer; re-deploy with cdkd deploy --replace"
25109
+ );
25110
+ }
25111
+ const input = { ApiId: apiId, AuthorizerId: physicalId };
25112
+ let changed = false;
25113
+ if (properties["AuthorizerType"] !== void 0 && properties["AuthorizerType"] !== previousProperties["AuthorizerType"]) {
25114
+ input.AuthorizerType = properties["AuthorizerType"];
25115
+ changed = true;
25116
+ }
25117
+ if (properties["Name"] !== void 0 && properties["Name"] !== previousProperties["Name"]) {
25118
+ input.Name = properties["Name"];
25119
+ changed = true;
25120
+ }
25121
+ if (properties["IdentitySource"] !== void 0) {
25122
+ const next = Array.isArray(properties["IdentitySource"]) ? properties["IdentitySource"] : [properties["IdentitySource"]];
25123
+ const prev = Array.isArray(previousProperties["IdentitySource"]) ? previousProperties["IdentitySource"] : previousProperties["IdentitySource"] !== void 0 ? [previousProperties["IdentitySource"]] : void 0;
25124
+ if (!this.deepEqual(next, prev)) {
25125
+ input.IdentitySource = next;
25126
+ changed = true;
25127
+ }
25128
+ }
25129
+ if (properties["JwtConfiguration"] !== void 0 && !this.deepEqual(properties["JwtConfiguration"], previousProperties["JwtConfiguration"])) {
25130
+ input.JwtConfiguration = properties["JwtConfiguration"];
25131
+ changed = true;
25132
+ }
25133
+ if (properties["AuthorizerUri"] !== void 0 && properties["AuthorizerUri"] !== previousProperties["AuthorizerUri"]) {
25134
+ input.AuthorizerUri = properties["AuthorizerUri"];
25135
+ changed = true;
25136
+ }
25137
+ if (properties["AuthorizerPayloadFormatVersion"] !== void 0 && properties["AuthorizerPayloadFormatVersion"] !== previousProperties["AuthorizerPayloadFormatVersion"]) {
25138
+ input.AuthorizerPayloadFormatVersion = properties["AuthorizerPayloadFormatVersion"];
25139
+ changed = true;
25140
+ }
25141
+ if (!changed) {
25142
+ this.logger.debug(
25143
+ `No mutable Authorizer fields changed for ${logicalId}; skipping UpdateAuthorizer`
25144
+ );
25145
+ return { physicalId, wasReplaced: false };
25146
+ }
25147
+ this.logger.debug(`Updating API Gateway V2 Authorizer ${logicalId}: ${physicalId}`);
25148
+ try {
25149
+ await this.getClient().send(new UpdateAuthorizerCommand2(input));
25150
+ return { physicalId, wasReplaced: false };
25151
+ } catch (error) {
25152
+ const cause = error instanceof Error ? error : void 0;
25153
+ throw new ProvisioningError(
25154
+ `Failed to update API Gateway V2 Authorizer ${logicalId}: ${error instanceof Error ? error.message : String(error)}`,
25155
+ resourceType,
25156
+ logicalId,
25157
+ physicalId,
25158
+ cause
25159
+ );
25160
+ }
25161
+ }
24814
25162
  // ─── Helpers ──────────────────────────────────────────────────────
24815
25163
  /**
24816
25164
  * Convert CloudFormation Tags (Array<{Key, Value}>) to SDK Tags (Record<string, string>).
@@ -24824,6 +25172,24 @@ var ApiGatewayV2Provider = class {
24824
25172
  }
24825
25173
  return result;
24826
25174
  }
25175
+ /**
25176
+ * Structural equality used to skip Update calls when an object /
25177
+ * array property is unchanged. Stable JSON serialization is fine
25178
+ * here because the API Gateway V2 sub-shapes (`CorsConfiguration`,
25179
+ * `JwtConfiguration`, scope arrays, identity-source arrays) are
25180
+ * small primitive maps with no key-order semantics on the AWS side.
25181
+ */
25182
+ deepEqual(a, b) {
25183
+ if (a === b)
25184
+ return true;
25185
+ if (a === void 0 || b === void 0)
25186
+ return false;
25187
+ try {
25188
+ return JSON.stringify(a) === JSON.stringify(b);
25189
+ } catch {
25190
+ return false;
25191
+ }
25192
+ }
24827
25193
  };
24828
25194
 
24829
25195
  // src/provisioning/providers/cloudfront-oai-provider.ts
@@ -45810,7 +46176,7 @@ function reorderArgs(argv) {
45810
46176
  }
45811
46177
  async function main() {
45812
46178
  const program = new Command14();
45813
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.55.0");
46179
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.56.0");
45814
46180
  program.addCommand(createBootstrapCommand());
45815
46181
  program.addCommand(createSynthCommand());
45816
46182
  program.addCommand(createListCommand());