From 18cc2a544b2d6974f977ba90895dc165ed253db2 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 23 Sep 2024 11:05:07 -0400 Subject: [PATCH] sites: revert using fallback origin --- platform/src/components/aws/analog.ts | 35 ++-- platform/src/components/aws/astro.ts | 15 +- platform/src/components/aws/nuxt.ts | 38 +++-- platform/src/components/aws/solid-start.ts | 38 +++-- platform/src/components/aws/svelte-kit.ts | 189 ++++++++++++--------- 5 files changed, 186 insertions(+), 129 deletions(-) diff --git a/platform/src/components/aws/analog.ts b/platform/src/components/aws/analog.ts index dcf52175f..14de25a3d 100644 --- a/platform/src/components/aws/analog.ts +++ b/platform/src/components/aws/analog.ts @@ -393,9 +393,7 @@ export class Analog extends Component implements Link.Linkable { const outputPath = buildApp(parent, name, args, sitePath); const preset = outputPath.apply((output) => { const nitro = JSON.parse( - fs - .readFileSync(path.join(output, "dist/analog/nitro.json")) - .toString(), + fs.readFileSync(path.join(output, "dist/analog/nitro.json")).toString(), ); if (!["aws-lambda"].includes(nitro.preset)) { throw new VisibleError( @@ -447,9 +445,19 @@ export class Analog extends Component implements Link.Linkable { } function loadBuildMetadata() { - return outputPath.apply(() => ({ - assetsPath: path.join("dist/analog", "public"), - })); + return outputPath.apply((outputPath) => { + const assetsPath = path.join("dist/analog", "public"); + + return { + assetsPath, + // create 1 behaviour for each top level asset file/folder + staticRoutes: fs + .readdirSync(path.join(outputPath, assetsPath), { + withFileTypes: true, + }) + .map((item) => (item.isDirectory() ? `${item.name}/*` : item.name)), + }; + }); } function buildPlan() { @@ -504,13 +512,14 @@ export class Analog extends Component implements Link.Linkable { cfFunction: "serverCfFunction", origin: "server", }, - { - pattern: "*", - cacheType: "server", - cfFunction: "serverCfFunction", - origin: "fallthrough", - allowedMethods: ["GET", "HEAD", "OPTIONS"], - }, + ...buildMeta.staticRoutes.map( + (route) => + ({ + cacheType: "static", + pattern: route, + origin: "s3", + }) as const, + ), ], }); }); diff --git a/platform/src/components/aws/astro.ts b/platform/src/components/aws/astro.ts index cd0db99c8..f8fe7f11b 100644 --- a/platform/src/components/aws/astro.ts +++ b/platform/src/components/aws/astro.ts @@ -550,12 +550,6 @@ export class Astro extends Component implements Link.Linkable { plan.behaviors.push( { - cacheType: "server", - cfFunction: "serverHostOnly", - origin: "regionalServer", - }, - { - pattern: "*", cacheType: "server", cfFunction: "server", origin: "fallthroughServer", @@ -573,6 +567,15 @@ export class Astro extends Component implements Link.Linkable { origin: "regionalServer", allowedMethods: ["GET", "HEAD", "OPTIONS"], }, + ...buildMeta.serverRoutes?.map( + (route) => + ({ + cacheType: "server", + cfFunction: "serverHostOnly", + pattern: route, + origin: "regionalServer", + }) as const, + ), ); } diff --git a/platform/src/components/aws/nuxt.ts b/platform/src/components/aws/nuxt.ts index 05723baab..7f5f2de80 100644 --- a/platform/src/components/aws/nuxt.ts +++ b/platform/src/components/aws/nuxt.ts @@ -438,9 +438,19 @@ export class Nuxt extends Component implements Link.Linkable { } function loadBuildMetadata() { - return outputPath.apply(() => ({ - assetsPath: path.join(".output", "public"), - })); + return outputPath.apply((outputPath) => { + const assetsPath = path.join(".output", "public"); + + return { + assetsPath, + // create 1 behaviour for each top level asset file/folder + staticRoutes: fs + .readdirSync(path.join(outputPath, assetsPath), { + withFileTypes: true, + }) + .map((item) => (item.isDirectory() ? `${item.name}/*` : item.name)), + }; + }); } function buildPlan() { @@ -475,13 +485,6 @@ export class Nuxt extends Component implements Link.Linkable { ], }, }, - fallthrough: { - group: { - primaryOriginName: "s3", - fallbackOriginName: "server", - fallbackStatusCodes: [403, 404], - }, - }, }, behaviors: [ { @@ -495,13 +498,14 @@ export class Nuxt extends Component implements Link.Linkable { cfFunction: "serverCfFunction", origin: "server", }, - { - pattern: "*", - cacheType: "server", - cfFunction: "serverCfFunction", - origin: "fallthrough", - allowedMethods: ["GET", "HEAD", "OPTIONS"], - }, + ...buildMeta.staticRoutes.map( + (route) => + ({ + cacheType: "static", + pattern: route, + origin: "s3", + }) as const, + ), ], }); }); diff --git a/platform/src/components/aws/solid-start.ts b/platform/src/components/aws/solid-start.ts index e293c91e8..5a4d26a91 100644 --- a/platform/src/components/aws/solid-start.ts +++ b/platform/src/components/aws/solid-start.ts @@ -445,9 +445,19 @@ export class SolidStart extends Component implements Link.Linkable { } function loadBuildMetadata() { - return outputPath.apply(() => ({ - assetsPath: path.join(".output", "public"), - })); + return outputPath.apply((outputPath) => { + const assetsPath = path.join(".output", "public"); + + return { + assetsPath, + // create 1 behaviour for each top level asset file/folder + staticRoutes: fs + .readdirSync(path.join(outputPath, assetsPath), { + withFileTypes: true, + }) + .map((item) => (item.isDirectory() ? `${item.name}/*` : item.name)), + }; + }); } function buildPlan() { @@ -484,13 +494,6 @@ export class SolidStart extends Component implements Link.Linkable { ], }, }, - fallthrough: { - group: { - primaryOriginName: "s3", - fallbackOriginName: "server", - fallbackStatusCodes: [403, 404], - }, - }, }, behaviors: [ { @@ -504,13 +507,14 @@ export class SolidStart extends Component implements Link.Linkable { cfFunction: "serverCfFunction", origin: "server", }, - { - pattern: "*", - cacheType: "server", - cfFunction: "serverCfFunction", - origin: "fallthrough", - allowedMethods: ["GET", "HEAD", "OPTIONS"], - }, + ...buildMeta.staticRoutes.map( + (route) => + ({ + cacheType: "static", + pattern: route, + origin: "s3", + }) as const, + ), ], }); }, diff --git a/platform/src/components/aws/svelte-kit.ts b/platform/src/components/aws/svelte-kit.ts index 192dac511..63326fcce 100644 --- a/platform/src/components/aws/svelte-kit.ts +++ b/platform/src/components/aws/svelte-kit.ts @@ -231,6 +231,14 @@ export interface SvelteKitArgs extends SsrSiteArgs { * ``` */ assets?: SsrSiteArgs["assets"]; + /** + * Configure where the [server function](#nodes-server) is deployed. + * + * By default, it's deployed to AWS Lambda in a single region. Enable this option if you want to instead deploy it to Lambda@Edge. + * @default `false` + * @internal + */ + edge?: Input; /** * Configure the [server function](#nodes-server) in your SvelteKit app to connect * to private subnets in a virtual private cloud or VPC. This allows your app to @@ -351,6 +359,7 @@ export class SvelteKit extends Component implements Link.Linkable { super(__pulumiType, name, args, opts); const parent = this; + const edge = normalizeEdge(); const { sitePath, partition } = prepare(parent, args); const dev = normalizeDev(); @@ -361,6 +370,7 @@ export class SvelteKit extends Component implements Link.Linkable { _metadata: { mode: "placeholder", path: sitePath, + edge, server: server.arn, }, _receiver: { @@ -416,6 +426,7 @@ export class SvelteKit extends Component implements Link.Linkable { mode: "deployed", path: sitePath, url: distribution.apply((d) => d.domainUrl ?? d.url), + edge, server: serverFunction.arn, }, }); @@ -433,11 +444,15 @@ export class SvelteKit extends Component implements Link.Linkable { }; } + function normalizeEdge() { + return output(args?.edge).apply((edge) => edge ?? false); + } + function loadBuildMetadata() { const serverPath = ".svelte-kit/svelte-kit-sst/server"; const assetsPath = ".svelte-kit/svelte-kit-sst/client"; - return outputPath.apply(() => { + return outputPath.apply((outputPath) => { let basePath = ""; try { const manifest = fs @@ -457,95 +472,117 @@ export class SvelteKit extends Component implements Link.Linkable { prerenderedPath: ".svelte-kit/svelte-kit-sst/prerendered", assetsPath, assetsVersionedSubDir: "_app", + // create 1 behaviour for each top level asset file/folder + staticRoutes: fs + .readdirSync(path.join(outputPath, assetsPath), { + withFileTypes: true, + }) + .map((item) => + item.isDirectory() + ? `${basePath}${item.name}/*` + : `${basePath}${item.name}`, + ), }; }); } function buildPlan() { - return all([outputPath, buildMeta]).apply(([outputPath, buildMeta]) => { - const serverConfig = { - handler: path.join( - outputPath, - buildMeta.serverPath, - "lambda-handler", - "index.handler", - ), - nodejs: { - esbuild: { - minify: process.env.SST_DEBUG ? false : true, - sourcemap: process.env.SST_DEBUG ? ("inline" as const) : false, - define: { - "process.env.SST_DEBUG": process.env.SST_DEBUG - ? "true" - : "false", - }, - }, - }, - copyFiles: buildMeta.serverFiles - ? [ - { - from: path.join(outputPath, buildMeta.serverFiles), - to: "prerendered", + return all([outputPath, edge, buildMeta]).apply( + ([outputPath, edge, buildMeta]) => { + const serverConfig = { + handler: path.join( + outputPath, + buildMeta.serverPath, + "lambda-handler", + "index.handler", + ), + nodejs: { + esbuild: { + minify: process.env.SST_DEBUG ? false : true, + sourcemap: process.env.SST_DEBUG ? ("inline" as const) : false, + define: { + "process.env.SST_DEBUG": process.env.SST_DEBUG + ? "true" + : "false", }, - ] - : undefined, - }; - - return validatePlan({ - edge: false, - cloudFrontFunctions: { - serverCfFunction: { - injections: [ - useCloudFrontFunctionHostHeaderInjection(), - useCloudFrontFormActionInjection(), - ], - }, - }, - origins: { - server: { - server: { function: serverConfig }, + }, }, - s3: { - s3: { - copy: [ - { - from: buildMeta.assetsPath, - to: buildMeta.basePath, - cached: true, - versionedSubDir: buildMeta.assetsVersionedSubDir, - }, + copyFiles: buildMeta.serverFiles + ? [ { - from: buildMeta.prerenderedPath, - to: buildMeta.basePath, - cached: false, + from: path.join(outputPath, buildMeta.serverFiles), + to: "prerendered", }, + ] + : undefined, + }; + + return validatePlan({ + edge, + cloudFrontFunctions: { + serverCfFunction: { + injections: [ + useCloudFrontFunctionHostHeaderInjection(), + useCloudFrontFormActionInjection(), ], }, }, - fallthrough: { - group: { - primaryOriginName: "s3", - fallbackOriginName: "server", - fallbackStatusCodes: [403, 404], + edgeFunctions: edge + ? { + server: { function: serverConfig }, + } + : undefined, + origins: { + ...(edge + ? {} + : { + server: { + server: { function: serverConfig }, + }, + }), + s3: { + s3: { + copy: [ + { + from: buildMeta.assetsPath, + to: buildMeta.basePath, + cached: true, + versionedSubDir: buildMeta.assetsVersionedSubDir, + }, + { + from: buildMeta.prerenderedPath, + to: buildMeta.basePath, + cached: false, + }, + ], + }, }, }, - }, - behaviors: [ - { - cacheType: "server", - cfFunction: "serverCfFunction", - origin: "server", - }, - { - pattern: "*", - cacheType: "server", - cfFunction: "serverCfFunction", - origin: "fallthrough", - allowedMethods: ["GET", "HEAD", "OPTIONS"], - }, - ], - }); - }); + behaviors: [ + edge + ? { + cacheType: "server", + cfFunction: "serverCfFunction", + edgeFunction: "server", + origin: "s3", + } + : { + cacheType: "server", + cfFunction: "serverCfFunction", + origin: "server", + }, + ...buildMeta.staticRoutes.map( + (route) => + ({ + cacheType: "static", + pattern: route, + origin: "s3", + }) as const, + ), + ], + }); + }, + ); } }