@go-to-k/cdkd 0.102.0 → 0.102.2

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
@@ -12346,9 +12346,32 @@ var ApiGatewayProvider = class ApiGatewayProvider {
12346
12346
  * when CDK's `LambdaIntegration({ responseTransferMode: STREAM })` was
12347
12347
  * used together with the streaming `response-streaming-invocations` URI.
12348
12348
  *
12349
- * `IntegrationResponses` (the CFn array shape under `Integration`) is
12350
- * applied via per-entry `PutIntegrationResponseCommand` calls after the
12351
- * integration itself is put in place.
12349
+ * `MethodResponses` and `IntegrationResponses` are applied as separate
12350
+ * per-entry calls (`PutMethodResponseCommand` /
12351
+ * `PutIntegrationResponseCommand`). Order matters: every
12352
+ * `MethodResponse` is put BEFORE any `IntegrationResponse`, because AWS
12353
+ * validates that the matching method response already exists when
12354
+ * accepting an integration response (the integration response's
12355
+ * `ResponseParameters` / `ResponseTemplates` map onto headers declared
12356
+ * by the method response). The inverse order surfaces as
12357
+ * `Invalid mapping expression specified: ... [No method response exists
12358
+ * for method.]` — the canonical trigger is a CORS preflight OPTIONS
12359
+ * method emitted by `RestApi({ defaultCorsPreflightOptions: ... })`.
12360
+ *
12361
+ * Partial-failure cleanup: if any AWS call AFTER `PutMethodCommand`
12362
+ * fails, the method has already been created on AWS but cdkd state
12363
+ * does NOT record it (the throw happens before the success return).
12364
+ * A subsequent redeploy would then attempt CREATE again and AWS would
12365
+ * reject with `Method already exists for this resource`. To prevent
12366
+ * this orphan, the post-`PutMethod` block is wrapped in an inner
12367
+ * try/catch that issues a best-effort `DeleteMethodCommand` before
12368
+ * re-throwing the original error. Cleanup failures are logged at warn
12369
+ * (the underlying create failure is what matters; we don't mask it by
12370
+ * promoting a cleanup error). The class of bug — partial AWS-side
12371
+ * commit on `createMethod` failure — was first seen via the
12372
+ * `PutIntegrationResponse`-before-`PutMethodResponse` ordering bug
12373
+ * fixed in PR #373; this cleanup makes any future shape of
12374
+ * post-`PutMethod` failure self-healing on the next redeploy.
12352
12375
  */
12353
12376
  async createMethod(logicalId, resourceType, properties) {
12354
12377
  this.logger.debug(`Creating API Gateway Method ${logicalId}`);
@@ -12378,9 +12401,9 @@ var ApiGatewayProvider = class ApiGatewayProvider {
12378
12401
  requestValidatorId,
12379
12402
  authorizationScopes
12380
12403
  }));
12381
- const integration = properties["Integration"];
12382
- if (integration) {
12383
- await this.apiGatewayClient.send(new PutIntegrationCommand({
12404
+ try {
12405
+ const integration = properties["Integration"];
12406
+ if (integration) await this.apiGatewayClient.send(new PutIntegrationCommand({
12384
12407
  restApiId,
12385
12408
  resourceId,
12386
12409
  httpMethod,
@@ -12400,32 +12423,46 @@ var ApiGatewayProvider = class ApiGatewayProvider {
12400
12423
  tlsConfig: integration["TlsConfig"] ? { insecureSkipVerification: integration["TlsConfig"]["InsecureSkipVerification"] } : void 0,
12401
12424
  responseTransferMode: integration["ResponseTransferMode"]
12402
12425
  }));
12403
- const integrationResponses = integration["IntegrationResponses"];
12404
- if (integrationResponses) for (const ir of integrationResponses) {
12405
- const statusCode = String(ir["StatusCode"]);
12406
- await this.apiGatewayClient.send(new PutIntegrationResponseCommand({
12426
+ const methodResponses = properties["MethodResponses"];
12427
+ if (methodResponses) for (const resp of methodResponses) {
12428
+ const statusCode = String(resp["StatusCode"]);
12429
+ await this.apiGatewayClient.send(new PutMethodResponseCommand({
12407
12430
  restApiId,
12408
12431
  resourceId,
12409
12432
  httpMethod,
12410
12433
  statusCode,
12411
- selectionPattern: ir["SelectionPattern"],
12412
- responseParameters: ir["ResponseParameters"],
12413
- responseTemplates: ir["ResponseTemplates"],
12414
- contentHandling: ir["ContentHandling"]
12434
+ responseModels: resp["ResponseModels"],
12435
+ responseParameters: resp["ResponseParameters"]
12415
12436
  }));
12416
12437
  }
12417
- }
12418
- const methodResponses = properties["MethodResponses"];
12419
- if (methodResponses) for (const resp of methodResponses) {
12420
- const statusCode = String(resp["StatusCode"]);
12421
- await this.apiGatewayClient.send(new PutMethodResponseCommand({
12422
- restApiId,
12423
- resourceId,
12424
- httpMethod,
12425
- statusCode,
12426
- responseModels: resp["ResponseModels"],
12427
- responseParameters: resp["ResponseParameters"]
12428
- }));
12438
+ if (integration) {
12439
+ const integrationResponses = integration["IntegrationResponses"];
12440
+ if (integrationResponses) for (const ir of integrationResponses) {
12441
+ const statusCode = String(ir["StatusCode"]);
12442
+ await this.apiGatewayClient.send(new PutIntegrationResponseCommand({
12443
+ restApiId,
12444
+ resourceId,
12445
+ httpMethod,
12446
+ statusCode,
12447
+ selectionPattern: ir["SelectionPattern"],
12448
+ responseParameters: ir["ResponseParameters"],
12449
+ responseTemplates: ir["ResponseTemplates"],
12450
+ contentHandling: ir["ContentHandling"]
12451
+ }));
12452
+ }
12453
+ }
12454
+ } catch (innerError) {
12455
+ try {
12456
+ await this.apiGatewayClient.send(new DeleteMethodCommand({
12457
+ restApiId,
12458
+ resourceId,
12459
+ httpMethod
12460
+ }));
12461
+ this.logger.debug(`Cleaned up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}) after wiring failure`);
12462
+ } catch (cleanupError) {
12463
+ this.logger.warn(`Failed to clean up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws apigateway delete-method --rest-api-id ${restApiId} --resource-id ${resourceId} --http-method ${httpMethod}`);
12464
+ }
12465
+ throw innerError;
12429
12466
  }
12430
12467
  const physicalId = `${restApiId}|${resourceId}|${httpMethod}`;
12431
12468
  this.logger.debug(`Successfully created API Gateway Method ${logicalId}: ${physicalId}`);
@@ -42701,7 +42738,7 @@ function reorderArgs(argv) {
42701
42738
  */
42702
42739
  async function main() {
42703
42740
  const program = new Command();
42704
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.0");
42741
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.2");
42705
42742
  program.addCommand(createBootstrapCommand());
42706
42743
  program.addCommand(createSynthCommand());
42707
42744
  program.addCommand(createListCommand());