Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 45 additions & 28 deletions src/presets/vercel/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fsp from "node:fs/promises";
import { defu } from "defu";
import { writeFile } from "nitropack/kit";
import type { Nitro } from "nitropack/types";
import type { Nitro, NitroRouteRules } from "nitropack/types";
import { dirname, relative, resolve } from "pathe";
import { joinURL, withLeadingSlash, withoutLeadingSlash } from "ufo";
import type {
Expand All @@ -10,6 +10,7 @@ import type {
VercelServerlessFunctionConfig,
} from "./types";
import { isTest } from "std-env";
import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";

// https://vercel.com/docs/build-output-api/configuration

Expand Down Expand Up @@ -61,31 +62,6 @@ export async function generateFunctionFiles(nitro: Nitro) {
continue;
}

// Normalize route rule
let isrConfig = value.isr;
if (typeof isrConfig === "number") {
isrConfig = { expiration: isrConfig };
} else if (isrConfig === true) {
isrConfig = { expiration: false };
} else {
isrConfig = { ...isrConfig };
}

// Generate prerender config
const prerenderConfig: PrerenderFunctionConfig = {
expiration: isrConfig.expiration ?? false,
bypassToken: nitro.options.vercel?.config?.bypassToken,
...isrConfig,
};

// Allow query parameter for wildcard routes
if (key.includes("/**") /* wildcard */) {
isrConfig.allowQuery = isrConfig.allowQuery || [];
if (!isrConfig.allowQuery.includes("url")) {
isrConfig.allowQuery.push("url");
}
}

const funcPrefix = resolve(
nitro.options.output.serverDir,
"..",
Expand All @@ -97,13 +73,22 @@ export async function generateFunctionFiles(nitro: Nitro) {
funcPrefix + ".func",
"junction"
);
await writeFile(
await writePrerenderConfig(
funcPrefix + ".prerender-config.json",
JSON.stringify(prerenderConfig, null, 2)
value.isr,
nitro.options.vercel?.config?.bypassToken
);
}

// Write observability routes
if (o11Routes.length === 0) {
return;
}
const _routeRulesMatcher = toRouteMatcher(
createRadixRouter({ routes: nitro.options.routeRules })
);
const _getRouteRules = (path: string) =>
defu({}, ..._routeRulesMatcher.matchAll(path).reverse()) as NitroRouteRules;
for (const route of o11Routes) {
const funcPrefix = resolve(
nitro.options.output.serverDir,
Expand All @@ -116,6 +101,14 @@ export async function generateFunctionFiles(nitro: Nitro) {
funcPrefix + ".func",
"junction"
);
const routeRules = _getRouteRules(route.src);
if (routeRules.isr) {
await writePrerenderConfig(
funcPrefix + ".prerender-config.json",
routeRules.isr,
nitro.options.vercel?.config?.bypassToken
);
}
}
}

Expand Down Expand Up @@ -405,3 +398,27 @@ function normalizeRouteDest(route: string) {
.join("/") || "index"
);
}

async function writePrerenderConfig(
filename: string,
isrConfig: NitroRouteRules["isr"],
bypassToken?: string
) {
// Normalize route rule
if (typeof isrConfig === "number") {
isrConfig = { expiration: isrConfig };
} else if (isrConfig === true) {
isrConfig = { expiration: false };
} else {
isrConfig = { ...isrConfig };
}

// Generate prerender config
const prerenderConfig: PrerenderFunctionConfig = {
expiration: isrConfig.expiration ?? false,
bypassToken,
...isrConfig,
};

await writeFile(filename, JSON.stringify(prerenderConfig, null, 2));
}
2 changes: 1 addition & 1 deletion test/presets/vercel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@
);
expect(JSON.parse(isrRouteConfig)).toMatchObject({
expiration: false,
allowQuery: ["q", "url"],
allowQuery: ["q"],
});
});

Expand Down Expand Up @@ -486,7 +486,7 @@
it("should generated expected functions", async () => {
const functionsDir = resolve(ctx.outDir, "functions");
const functionsFiles = await walkDir(functionsDir);
expect(functionsFiles).toMatchInlineSnapshot(`

Check failure on line 489 in test/presets/vercel.test.ts

View workflow job for this annotation

GitHub Actions / ci (windows-latest)

test/presets/vercel.test.ts > nitro:preset:vercel > should generated expected functions

Error: Snapshot `nitro:preset:vercel > should generated expected functions 1` mismatched - Expected + Received @@ -1,17 +1,7 @@ [ "functions/500.func (symlink)", - "functions/__fallback.func/.vc-config.json", - "functions/__fallback.func/chunks", - "functions/__fallback.func/index.mjs", - "functions/__fallback.func/index.mjs.map", - "functions/__fallback.func/node_modules", - "functions/__fallback.func/package.json", - "functions/__fallback.func/timing.js", - "functions/_openapi.json.func (symlink)", - "functions/_scalar.func (symlink)", - "functions/_swagger.func (symlink)", "functions/api/cached.func (symlink)", "functions/api/db.func (symlink)", "functions/api/echo.func (symlink)", "functions/api/error.func (symlink)", "functions/api/errors.func (symlink)", @@ -36,27 +26,27 @@ "functions/api/serialized/tuple.func (symlink)", "functions/api/serialized/void.func (symlink)", "functions/api/storage/dev.func (symlink)", "functions/api/storage/item.func (symlink)", "functions/api/test/[-]/foo.func (symlink)", - "functions/api/typed/catchall/[slug]/[...another].func (symlink)", + "functions/api/typed/catchall/some/[...test].func (symlink)", - "functions/api/typed/catchall/some/[...test].func (symlink)", + "functions/api/typed/catchall/[slug]/[...another].func (symlink)", "functions/api/typed/todos/[...].func (symlink)", "functions/api/typed/todos/[todoId]/comments/[...commentId].func (symlink)", - "functions/api/typed/user/[userId]/[userExtends].func (symlink)", + "functions/api/typed/user/john/post/coffee.func (symlink)", - "functions/api/typed/user/[userId]/post/[postId].func (symlink)", + "functions/api/typed/user/john/post/[postId].func (symlink)", - "functions/api/typed/user/[userId]/post/firstPost.func (symlink)", + "functions/api/typed/user/john/[johnExtends].func (symlink)", - "functions/api/typed/user/[userId].func (symlink)", + "functions/api/typed/user/john.func (symlink)", - "functions/api/typed/user/john/[johnExtends].func (symlink)", + "functions/api/typed/user/[userId]/post/firstPost.func (symlink)", - "functions/api/typed/user/john/post/[postId].func (symlink)", + "functions/api/typed/user/[userId]/post/[postId].func (symlink)", - "functions/api/typed/user/john/post/coffee.func (symlink)", + "functions/api/typed/user/[userId]/[userExtends].func (symlink)", - "functions/api/typed/user/john.func (symlink)", + "functions/api/typed/user/[userId].func (symlink)", "functions/api/upload.func (symlink)", "functions/api/wildcard/[...param].func (symlink)", - "functions/assets/[id].func (symlink)", + "functions/assets/all.func (symlink)", - "functions/assets/all.func (symlink)", + "functions/assets/md.func (symlink)", - "functions/assets/md.func (symlink)", + "functions/assets/[id].func (symlink)", "functions/config.func (symlink)", "functions/context.func (symlink)", "functions/env.func (symlink)", "functions/error-stack.func (symlink)", "functions/fetch.func (symlink)", @@ -69,25 +59,35 @@ "functions/node-compat.func (symlink)", "functions/prerender-custom.html.func (symlink)", "functions/prerender.func (symlink)", "functions/raw.func (symlink)", "functions/route-group.func (symlink)", - "functions/rules/[...slug].func (symlink)", - "functions/rules/_/cached/[...].isr.func (symlink)", + "functions/rules/isr/[...].isr.func (symlink)", - "functions/rules/_/cached/[...].isr.prerender-config.json", + "functions/rules/isr/[...].isr.prerender-config.json", - "functions/rules/_/noncached/cached.isr.func (symlink)", + "functions/rules/isr-ttl/[...].isr.func (symlink)", - "functions/rules/_/noncached/cached.isr.prerender-config.json", + "functions/rules/isr-ttl/[...].isr.prerender-config.json", - "functions/rules/isr/[...].isr.func (symlink)", + "functions/rules/swr/[...].isr.func (symlink)", - "functions/rules/isr/[...].isr.prerender-config.json", + "functions/rules/swr/[...].isr.prerender-config.json", - "functions/rules/is
[
"functions/500.func (symlink)",
"functions/__fallback.func/.vc-config.json",
Expand Down
Loading