-
Notifications
You must be signed in to change notification settings - Fork 492
/
cloudflare-pages.ts
95 lines (86 loc) · 2.43 KB
/
cloudflare-pages.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { promises as fsp } from "node:fs";
import { resolve } from "pathe";
import { joinURL, withLeadingSlash, withoutLeadingSlash } from "ufo";
import { globby } from "globby";
import { defineNitroPreset } from "../preset";
import type { Nitro } from "../types";
export const cloudflarePages = defineNitroPreset({
extends: "cloudflare",
entry: "#internal/nitro/entries/cloudflare-pages",
commands: {
preview: "npx wrangler pages dev ./",
deploy: "npx wrangler pages publish ./",
},
output: {
dir: "{{ rootDir }}/dist",
publicDir: "{{ output.dir }}",
serverDir: "{{ output.dir }}",
},
alias: {
// Hotfix: Cloudflare appends /index.html if mime is not found and things like ico are not in standard lite.js!
// https://github.com/unjs/nitro/pull/933
_mime: "mime/index.js",
},
rollupConfig: {
output: {
entryFileNames: "_worker.js",
format: "esm",
},
},
hooks: {
async compiled(nitro: Nitro) {
await writeCFRoutes(nitro);
},
},
});
/**
* https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes
*/
interface CloudflarePagesRoutes {
version: 1;
include: string[];
exclude: string[];
}
async function writeCFRoutes(nitro: Nitro) {
const routes: CloudflarePagesRoutes = {
version: 1,
include: ["/*"],
exclude: [],
};
// Exclude public assets from hitting the worker
const explicitPublicAssets = nitro.options.publicAssets.filter(
(i) => !i.fallthrough
);
// Explicit prefixes
routes.exclude.push(
...explicitPublicAssets
.map((dir) => joinURL(dir.baseURL, "*"))
.sort(comparePaths)
);
// Unprefixed assets
const publicAssetFiles = await globby("**", {
cwd: nitro.options.output.publicDir,
absolute: false,
dot: true,
ignore: [
"_worker.js",
"_worker.js.map",
"nitro.json",
...explicitPublicAssets.map((dir) =>
withoutLeadingSlash(joinURL(dir.baseURL, "**"))
),
],
});
routes.exclude.push(
...publicAssetFiles.map((i) => withLeadingSlash(i)).sort(comparePaths)
);
// Only allow 100 rules in total (include + exclude)
routes.exclude.splice(100 - routes.include.length);
await fsp.writeFile(
resolve(nitro.options.output.publicDir, "_routes.json"),
JSON.stringify(routes, undefined, 2)
);
}
function comparePaths(a: string, b: string) {
return a.split("/").length - b.split("/").length || a.localeCompare(b);
}