@go-to-k/cdkd 0.162.0 → 0.162.1
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 +139 -3
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -51153,6 +51153,140 @@ function pickStringArray(value) {
|
|
|
51153
51153
|
return out;
|
|
51154
51154
|
}
|
|
51155
51155
|
/**
|
|
51156
|
+
* Build a `fnUrlLogicalId → CorsConfig` map by tracing CloudFront →
|
|
51157
|
+
* Function URL chains in the template (issue #646).
|
|
51158
|
+
*
|
|
51159
|
+
* Production-correct CDK pattern: Function URL fronted by a CloudFront
|
|
51160
|
+
* Distribution where CORS is declared on the CloudFront
|
|
51161
|
+
* `ResponseHeadersPolicy` (NOT on the Function URL itself). Without this
|
|
51162
|
+
* helper, `cdkd local start-api` sees `Cors: null` on the Function URL
|
|
51163
|
+
* and emits no preflight headers — even though the CDK code correctly
|
|
51164
|
+
* declares the allowed origins on the CloudFront side.
|
|
51165
|
+
*
|
|
51166
|
+
* Detection: an `AWS::CloudFront::Distribution` whose `Origins[].DomainName`
|
|
51167
|
+
* matches the canonical CDK 2.x shape
|
|
51168
|
+
* `Fn::Select[2, Fn::Split['/', Fn::GetAtt[<FnUrlLogicalId>, 'FunctionUrl']]]`
|
|
51169
|
+
* is the chain marker. For each such origin, we walk every cache behavior
|
|
51170
|
+
* (`DefaultCacheBehavior` + `CacheBehaviors[]`), resolve their
|
|
51171
|
+
* `ResponseHeadersPolicyId: { Ref: <RhpLogicalId> }` to the
|
|
51172
|
+
* `AWS::CloudFront::ResponseHeadersPolicy` resource, and extract its
|
|
51173
|
+
* `Properties.ResponseHeadersPolicyConfig.CorsConfig`.
|
|
51174
|
+
*
|
|
51175
|
+
* Schema mapping (CloudFront → internal `CorsConfig`):
|
|
51176
|
+
*
|
|
51177
|
+
* AccessControlAllowOrigins.Items → AllowOrigins
|
|
51178
|
+
* AccessControlAllowMethods.Items → AllowMethods
|
|
51179
|
+
* AccessControlAllowHeaders.Items → AllowHeaders
|
|
51180
|
+
* AccessControlExposeHeaders.Items → ExposeHeaders
|
|
51181
|
+
* AccessControlMaxAgeSec → MaxAge
|
|
51182
|
+
* AccessControlAllowCredentials → AllowCredentials
|
|
51183
|
+
* (OriginOverride is ignored — cdkd has only one config slot)
|
|
51184
|
+
*
|
|
51185
|
+
* Multiple distributions fronting the same Function URL: last write
|
|
51186
|
+
* wins (rare in practice). Per-path CORS via `CacheBehaviors[]` is
|
|
51187
|
+
* NOT supported in v1 — the `DefaultCacheBehavior`'s policy applies
|
|
51188
|
+
* to all paths.
|
|
51189
|
+
*/
|
|
51190
|
+
function buildCorsConfigFromCloudFrontChain(template) {
|
|
51191
|
+
const out = /* @__PURE__ */ new Map();
|
|
51192
|
+
const resources = template.Resources ?? {};
|
|
51193
|
+
for (const [, resource] of Object.entries(resources)) {
|
|
51194
|
+
if (resource.Type !== "AWS::CloudFront::Distribution") continue;
|
|
51195
|
+
const distConfig = (resource.Properties ?? {})["DistributionConfig"];
|
|
51196
|
+
if (!distConfig || typeof distConfig !== "object") continue;
|
|
51197
|
+
const dc = distConfig;
|
|
51198
|
+
const origins = Array.isArray(dc["Origins"]) ? dc["Origins"] : [];
|
|
51199
|
+
for (const origin of origins) {
|
|
51200
|
+
if (!origin || typeof origin !== "object") continue;
|
|
51201
|
+
const fnUrlLogicalId = pickFnUrlLogicalIdFromOriginDomainName(origin["DomainName"]);
|
|
51202
|
+
if (!fnUrlLogicalId) continue;
|
|
51203
|
+
const cacheBehaviors = [dc["DefaultCacheBehavior"], ...Array.isArray(dc["CacheBehaviors"]) ? dc["CacheBehaviors"] : []];
|
|
51204
|
+
for (const behavior of cacheBehaviors) {
|
|
51205
|
+
if (!behavior || typeof behavior !== "object") continue;
|
|
51206
|
+
const rhpId = pickRhpRefLogicalId(behavior["ResponseHeadersPolicyId"]);
|
|
51207
|
+
if (!rhpId) continue;
|
|
51208
|
+
const rhpResource = resources[rhpId];
|
|
51209
|
+
if (!rhpResource || rhpResource.Type !== "AWS::CloudFront::ResponseHeadersPolicy") continue;
|
|
51210
|
+
const rhpConfig = (rhpResource.Properties ?? {})["ResponseHeadersPolicyConfig"];
|
|
51211
|
+
if (!rhpConfig || typeof rhpConfig !== "object") continue;
|
|
51212
|
+
const corsConfig = rhpConfig["CorsConfig"];
|
|
51213
|
+
if (!corsConfig || typeof corsConfig !== "object" || Array.isArray(corsConfig)) continue;
|
|
51214
|
+
const parsed = parseCloudFrontCorsConfig(corsConfig);
|
|
51215
|
+
if (parsed) out.set(fnUrlLogicalId, parsed);
|
|
51216
|
+
}
|
|
51217
|
+
}
|
|
51218
|
+
}
|
|
51219
|
+
return out;
|
|
51220
|
+
}
|
|
51221
|
+
/**
|
|
51222
|
+
* Detect the canonical CDK 2.x `DomainName` shape that points a
|
|
51223
|
+
* CloudFront Origin at a Function URL:
|
|
51224
|
+
* {Fn::Select: [2, {Fn::Split: ['/', {Fn::GetAtt: [<id>, 'FunctionUrl']}]}]}
|
|
51225
|
+
* Returns the Function URL's logical ID, or undefined if the shape
|
|
51226
|
+
* doesn't match.
|
|
51227
|
+
*/
|
|
51228
|
+
function pickFnUrlLogicalIdFromOriginDomainName(value) {
|
|
51229
|
+
if (!value || typeof value !== "object") return void 0;
|
|
51230
|
+
const sel = value["Fn::Select"];
|
|
51231
|
+
if (!Array.isArray(sel) || sel.length !== 2 || sel[0] !== 2) return void 0;
|
|
51232
|
+
const split = sel[1];
|
|
51233
|
+
if (!split || typeof split !== "object") return void 0;
|
|
51234
|
+
const splitArgs = split["Fn::Split"];
|
|
51235
|
+
if (!Array.isArray(splitArgs) || splitArgs.length !== 2 || splitArgs[0] !== "/") return void 0;
|
|
51236
|
+
const getAtt = splitArgs[1];
|
|
51237
|
+
if (!getAtt || typeof getAtt !== "object") return void 0;
|
|
51238
|
+
const ga = getAtt["Fn::GetAtt"];
|
|
51239
|
+
if (!Array.isArray(ga) || ga.length !== 2 || typeof ga[0] !== "string" || ga[1] !== "FunctionUrl") return;
|
|
51240
|
+
return ga[0];
|
|
51241
|
+
}
|
|
51242
|
+
/**
|
|
51243
|
+
* Unwrap a `ResponseHeadersPolicyId` value to its referenced logical
|
|
51244
|
+
* ID. CDK 2.x synthesizes this as `{ Ref: <id> }`. Returns undefined
|
|
51245
|
+
* for the AWS-managed-policy ID form (literal UUID string) since
|
|
51246
|
+
* cdkd can't fetch those — and for any non-Ref shape.
|
|
51247
|
+
*/
|
|
51248
|
+
function pickRhpRefLogicalId(value) {
|
|
51249
|
+
if (!value || typeof value !== "object") return void 0;
|
|
51250
|
+
const ref = value["Ref"];
|
|
51251
|
+
if (typeof ref !== "string" || ref.length === 0) return void 0;
|
|
51252
|
+
return ref;
|
|
51253
|
+
}
|
|
51254
|
+
/**
|
|
51255
|
+
* Parse a CloudFront `ResponseHeadersPolicyConfig.CorsConfig` block
|
|
51256
|
+
* into the internal `CorsConfig` shape. Schema differs from Function
|
|
51257
|
+
* URL / HTTP API v2 (`AccessControl*` prefix + nested `Items` wrapper);
|
|
51258
|
+
* see `buildCorsConfigFromCloudFrontChain` JSDoc for the field mapping.
|
|
51259
|
+
*
|
|
51260
|
+
* Returns undefined when every value-bearing field is missing.
|
|
51261
|
+
*/
|
|
51262
|
+
function parseCloudFrontCorsConfig(raw) {
|
|
51263
|
+
const allowOrigins = pickItemsStringArray(raw["AccessControlAllowOrigins"]);
|
|
51264
|
+
const allowMethods = pickItemsStringArray(raw["AccessControlAllowMethods"]);
|
|
51265
|
+
const allowHeaders = pickItemsStringArray(raw["AccessControlAllowHeaders"]);
|
|
51266
|
+
const exposeHeaders = pickItemsStringArray(raw["AccessControlExposeHeaders"]);
|
|
51267
|
+
const maxAgeRaw = raw["AccessControlMaxAgeSec"];
|
|
51268
|
+
const allowCreds = raw["AccessControlAllowCredentials"];
|
|
51269
|
+
if (allowOrigins.length === 0 && allowMethods.length === 0 && allowHeaders.length === 0 && exposeHeaders.length === 0 && maxAgeRaw === void 0 && allowCreds === void 0) return;
|
|
51270
|
+
const config = {
|
|
51271
|
+
AllowOrigins: allowOrigins,
|
|
51272
|
+
AllowMethods: allowMethods,
|
|
51273
|
+
AllowHeaders: allowHeaders,
|
|
51274
|
+
ExposeHeaders: exposeHeaders
|
|
51275
|
+
};
|
|
51276
|
+
if (typeof maxAgeRaw === "number" && Number.isFinite(maxAgeRaw)) config.MaxAge = Math.trunc(maxAgeRaw);
|
|
51277
|
+
if (typeof allowCreds === "boolean") config.AllowCredentials = allowCreds;
|
|
51278
|
+
return config;
|
|
51279
|
+
}
|
|
51280
|
+
/**
|
|
51281
|
+
* CloudFront `AccessControl*Origins/Methods/Headers` use a nested
|
|
51282
|
+
* `Items: string[]` wrapper. Unwrap to a plain `string[]`.
|
|
51283
|
+
*/
|
|
51284
|
+
function pickItemsStringArray(value) {
|
|
51285
|
+
if (!value || typeof value !== "object") return [];
|
|
51286
|
+
const items = value["Items"];
|
|
51287
|
+
return pickStringArray(items);
|
|
51288
|
+
}
|
|
51289
|
+
/**
|
|
51156
51290
|
* Try to match an OPTIONS preflight request against the given CORS
|
|
51157
51291
|
* config. Returns the canonical response when every check passes;
|
|
51158
51292
|
* `null` when the request didn't satisfy AllowOrigins / AllowMethods /
|
|
@@ -54528,8 +54662,10 @@ async function localStartApiCommand(target, options) {
|
|
|
54528
54662
|
}
|
|
54529
54663
|
const corsConfigByApiId = /* @__PURE__ */ new Map();
|
|
54530
54664
|
for (const stack of targetStacks) {
|
|
54531
|
-
const
|
|
54532
|
-
for (const [k, v] of
|
|
54665
|
+
const fromCloudFront = buildCorsConfigFromCloudFrontChain(stack.template);
|
|
54666
|
+
for (const [k, v] of fromCloudFront) corsConfigByApiId.set(k, v);
|
|
54667
|
+
const direct = buildCorsConfigByApiId(stack.template);
|
|
54668
|
+
for (const [k, v] of direct) corsConfigByApiId.set(k, v);
|
|
54533
54669
|
}
|
|
54534
54670
|
const stateByStack = options.fromState || isCfnFlagPresent(options) ? await loadStateForRoutedStacks(targetStacks, routes, routesWithAuth, options) : /* @__PURE__ */ new Map();
|
|
54535
54671
|
const lambdaIds = uniqueLambdaIds(routes, routesWithAuth, webSocketApis);
|
|
@@ -60065,7 +60201,7 @@ function reorderArgs(argv) {
|
|
|
60065
60201
|
*/
|
|
60066
60202
|
async function main() {
|
|
60067
60203
|
const program = new Command();
|
|
60068
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.162.
|
|
60204
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.162.1");
|
|
60069
60205
|
program.addCommand(createBootstrapCommand());
|
|
60070
60206
|
program.addCommand(createSynthCommand());
|
|
60071
60207
|
program.addCommand(createListCommand());
|