@astrojs/cloudflare 6.6.1 → 6.7.0
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/README.md +4 -1
- package/dist/index.js +77 -21
- package/dist/server.advanced.d.ts +1 -1
- package/dist/server.directory.d.ts +2 -2
- package/dist/server.directory.js +3 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -106,7 +106,10 @@ Cloudflare has support for adding custom [headers](https://developers.cloudflare
|
|
|
106
106
|
|
|
107
107
|
### Custom `_routes.json`
|
|
108
108
|
|
|
109
|
-
By default, `@astrojs/cloudflare` will generate a `_routes.json` file
|
|
109
|
+
By default, `@astrojs/cloudflare` will generate a `_routes.json` file with `include` and `exclude` rules based on your applications's dynamic and static routes.
|
|
110
|
+
This will enable Cloudflare to serve files and process static redirects without a function invocation. Creating a custom `_routes.json` will override this automatic optimization and, if not configured manually, cause function invocations that will count against the request limits of your Cloudflare plan.
|
|
111
|
+
|
|
112
|
+
See [Cloudflare's documentation](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) for more details.
|
|
110
113
|
|
|
111
114
|
## Troubleshooting
|
|
112
115
|
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { createRedirectsFromAstroRoutes } from "@astrojs/underscore-redirects";
|
|
2
2
|
import esbuild from "esbuild";
|
|
3
|
-
import * as fs from "fs";
|
|
4
|
-
import * as os from "os";
|
|
5
|
-
import {
|
|
3
|
+
import * as fs from "node:fs";
|
|
4
|
+
import * as os from "node:os";
|
|
5
|
+
import { sep } from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
7
|
import glob from "tiny-glob";
|
|
7
|
-
import { fileURLToPath, pathToFileURL } from "url";
|
|
8
8
|
function getAdapter(isModeDirectory) {
|
|
9
9
|
return isModeDirectory ? {
|
|
10
10
|
name: "@astrojs/cloudflare",
|
|
@@ -21,6 +21,7 @@ const SHIM = `globalThis.process = {
|
|
|
21
21
|
env: {},
|
|
22
22
|
};`;
|
|
23
23
|
const SERVER_BUILD_FOLDER = "/$server_build/";
|
|
24
|
+
const potentialFunctionRouteTypes = ["endpoint", "page"];
|
|
24
25
|
function createIntegration(args) {
|
|
25
26
|
let _config;
|
|
26
27
|
let _buildConfig;
|
|
@@ -68,6 +69,10 @@ function createIntegration(args) {
|
|
|
68
69
|
}
|
|
69
70
|
vite.ssr ||= {};
|
|
70
71
|
vite.ssr.target = "webworker";
|
|
72
|
+
vite.define = {
|
|
73
|
+
"process.env": "process.env",
|
|
74
|
+
...vite.define
|
|
75
|
+
};
|
|
71
76
|
}
|
|
72
77
|
},
|
|
73
78
|
"astro:build:ssr": ({ entryPoints }) => {
|
|
@@ -80,11 +85,11 @@ function createIntegration(args) {
|
|
|
80
85
|
await fs.promises.mkdir(functionsUrl, { recursive: true });
|
|
81
86
|
}
|
|
82
87
|
if (isModeDirectory && _buildConfig.split) {
|
|
83
|
-
const entryPointsRouteData = [..._entryPoints.keys()];
|
|
84
88
|
const entryPointsURL = [..._entryPoints.values()];
|
|
85
89
|
const entryPaths = entryPointsURL.map((entry) => fileURLToPath(entry));
|
|
86
|
-
const
|
|
87
|
-
const
|
|
90
|
+
const outputUrl = new URL("$astro", _buildConfig.server);
|
|
91
|
+
const outputDir = fileURLToPath(outputUrl);
|
|
92
|
+
await esbuild.build({
|
|
88
93
|
target: "es2020",
|
|
89
94
|
platform: "browser",
|
|
90
95
|
conditions: ["workerd", "worker", "browser"],
|
|
@@ -99,19 +104,31 @@ function createIntegration(args) {
|
|
|
99
104
|
},
|
|
100
105
|
logOverride: {
|
|
101
106
|
"ignored-bare-import": "silent"
|
|
102
|
-
}
|
|
103
|
-
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
const outputFiles = await glob(`**/*`, {
|
|
110
|
+
cwd: outputDir,
|
|
111
|
+
filesOnly: true
|
|
104
112
|
});
|
|
105
|
-
for (const
|
|
106
|
-
const
|
|
107
|
-
|
|
113
|
+
for (const outputFile of outputFiles) {
|
|
114
|
+
const path = outputFile.split(sep);
|
|
115
|
+
const finalSegments = path.map(
|
|
116
|
+
(segment) => segment.replace(/(\_)(\w+)(\_)/g, (_, __, prop) => {
|
|
117
|
+
return `[${prop}]`;
|
|
118
|
+
}).replace(/(\_\-\-\-)(\w+)(\_)/g, (_, __, prop) => {
|
|
119
|
+
return `[[${prop}]]`;
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
finalSegments[finalSegments.length - 1] = finalSegments[finalSegments.length - 1].replace("entry.", "").replace(/(.*)\.(\w+)\.(\w+)$/g, (_, fileName, __, newExt) => {
|
|
123
|
+
return `${fileName}.${newExt}`;
|
|
108
124
|
});
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
125
|
+
const finalDirPath = finalSegments.slice(0, -1).join(sep);
|
|
126
|
+
const finalPath = finalSegments.join(sep);
|
|
127
|
+
const newDirUrl = new URL(finalDirPath, functionsUrl);
|
|
128
|
+
await fs.promises.mkdir(newDirUrl, { recursive: true });
|
|
129
|
+
const oldFileUrl = new URL(`$astro/${outputFile}`, outputUrl);
|
|
130
|
+
const newFileUrl = new URL(finalPath, functionsUrl);
|
|
131
|
+
await fs.promises.rename(oldFileUrl, newFileUrl);
|
|
115
132
|
}
|
|
116
133
|
} else {
|
|
117
134
|
const entryPath = fileURLToPath(new URL(_buildConfig.serverEntry, _buildConfig.server));
|
|
@@ -157,10 +174,20 @@ function createIntegration(args) {
|
|
|
157
174
|
}
|
|
158
175
|
const routesExists = await fs.promises.stat(new URL("./_routes.json", _config.outDir)).then((stat) => stat.isFile()).catch(() => false);
|
|
159
176
|
if (!routesExists) {
|
|
177
|
+
const functionEndpoints = routes.filter((route) => potentialFunctionRouteTypes.includes(route.type) && !route.prerender).map((route) => {
|
|
178
|
+
const includePattern = "/" + route.segments.flat().map((segment) => segment.dynamic ? "*" : segment.content).join("/");
|
|
179
|
+
const regexp = new RegExp(
|
|
180
|
+
"^\\/" + route.segments.flat().map((segment) => segment.dynamic ? "(.*)" : segment.content).join("\\/") + "$"
|
|
181
|
+
);
|
|
182
|
+
return {
|
|
183
|
+
includePattern,
|
|
184
|
+
regexp
|
|
185
|
+
};
|
|
186
|
+
});
|
|
160
187
|
const staticPathList = (await glob(`${fileURLToPath(_buildConfig.client)}/**/*`, {
|
|
161
188
|
cwd: fileURLToPath(_config.outDir),
|
|
162
189
|
filesOnly: true
|
|
163
|
-
})).filter((file) => cloudflareSpecialFiles.indexOf(file) < 0).map((file) => `/${file}`);
|
|
190
|
+
})).filter((file) => cloudflareSpecialFiles.indexOf(file) < 0).map((file) => `/${file.replace(/\\/g, "/")}`);
|
|
164
191
|
for (let page of pages) {
|
|
165
192
|
let pagePath = prependForwardSlash(page.pathname);
|
|
166
193
|
if (_config.base !== "/") {
|
|
@@ -199,13 +226,30 @@ function createIntegration(args) {
|
|
|
199
226
|
trueRedirects.print()
|
|
200
227
|
);
|
|
201
228
|
}
|
|
229
|
+
staticPathList.push(...routes.filter((r) => r.type === "redirect").map((r) => r.route));
|
|
230
|
+
let include = deduplicatePatterns(
|
|
231
|
+
functionEndpoints.map((endpoint) => endpoint.includePattern)
|
|
232
|
+
);
|
|
233
|
+
let exclude = deduplicatePatterns(
|
|
234
|
+
staticPathList.filter(
|
|
235
|
+
(file) => functionEndpoints.some((endpoint) => endpoint.regexp.test(file))
|
|
236
|
+
)
|
|
237
|
+
);
|
|
238
|
+
if (include.length === 0) {
|
|
239
|
+
include = ["/"];
|
|
240
|
+
exclude = ["/"];
|
|
241
|
+
}
|
|
242
|
+
if (include.length + exclude.length > staticPathList.length) {
|
|
243
|
+
include = ["/*"];
|
|
244
|
+
exclude = deduplicatePatterns(staticPathList);
|
|
245
|
+
}
|
|
202
246
|
await fs.promises.writeFile(
|
|
203
247
|
new URL("./_routes.json", _config.outDir),
|
|
204
248
|
JSON.stringify(
|
|
205
249
|
{
|
|
206
250
|
version: 1,
|
|
207
|
-
include
|
|
208
|
-
exclude
|
|
251
|
+
include,
|
|
252
|
+
exclude
|
|
209
253
|
},
|
|
210
254
|
null,
|
|
211
255
|
2
|
|
@@ -219,6 +263,18 @@ function createIntegration(args) {
|
|
|
219
263
|
function prependForwardSlash(path) {
|
|
220
264
|
return path[0] === "/" ? path : "/" + path;
|
|
221
265
|
}
|
|
266
|
+
function deduplicatePatterns(patterns) {
|
|
267
|
+
const openPatterns = [];
|
|
268
|
+
return [...new Set(patterns)].sort((a, b) => a.length - b.length).filter((pattern) => {
|
|
269
|
+
if (openPatterns.some((p) => p.test(pattern))) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
if (pattern.endsWith("*")) {
|
|
273
|
+
openPatterns.push(new RegExp(`^${pattern.replace(/(\*\/)*\*$/g, ".*")}`));
|
|
274
|
+
}
|
|
275
|
+
return true;
|
|
276
|
+
});
|
|
277
|
+
}
|
|
222
278
|
export {
|
|
223
279
|
createIntegration as default,
|
|
224
280
|
getAdapter
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Request as CFRequest, EventContext } from '@cloudflare/workers-types';
|
|
2
2
|
import type { SSRManifest } from 'astro';
|
|
3
3
|
export declare function createExports(manifest: SSRManifest): {
|
|
4
4
|
onRequest: ({ request, next, ...runtimeEnv }: {
|
|
5
5
|
request: Request & CFRequest;
|
|
6
6
|
next: (request: Request) => void;
|
|
7
7
|
waitUntil: EventContext<unknown, any, unknown>['waitUntil'];
|
|
8
|
-
} & Record<string, unknown>) => Promise<
|
|
8
|
+
} & Record<string, unknown>) => Promise<import("@cloudflare/workers-types").Response | Response>;
|
|
9
9
|
manifest: SSRManifest;
|
|
10
10
|
};
|
package/dist/server.directory.js
CHANGED
|
@@ -13,7 +13,9 @@ function createExports(manifest) {
|
|
|
13
13
|
process.env = runtimeEnv.env;
|
|
14
14
|
const { pathname } = new URL(request.url);
|
|
15
15
|
if (manifest.assets.has(pathname)) {
|
|
16
|
-
return
|
|
16
|
+
return runtimeEnv.env.ASSETS.fetch(
|
|
17
|
+
request
|
|
18
|
+
);
|
|
17
19
|
}
|
|
18
20
|
let routeData = app.match(request, { matchNotFound: true });
|
|
19
21
|
if (routeData) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/cloudflare",
|
|
3
3
|
"description": "Deploy your site to Cloudflare Workers/Pages",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.7.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"author": "withastro",
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"tiny-glob": "^0.2.9"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"astro": "^2.
|
|
41
|
+
"astro": "^2.10.5"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"chai": "^4.3.7",
|
|
45
45
|
"cheerio": "1.0.0-rc.12",
|
|
46
46
|
"mocha": "^9.2.2",
|
|
47
47
|
"wrangler": "^2.0.23",
|
|
48
|
-
"astro": "2.
|
|
48
|
+
"astro": "2.10.5",
|
|
49
49
|
"astro-scripts": "0.0.14"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|