@astrojs/cloudflare 6.6.2 → 6.8.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 CHANGED
@@ -73,12 +73,10 @@ It's then possible to update the preview script in your `package.json` to `"prev
73
73
 
74
74
  ## Access to the Cloudflare runtime
75
75
 
76
- You can access all the Cloudflare bindings and environment variables from Astro components and API routes through the adapter API.
76
+ You can access all the Cloudflare bindings and environment variables from Astro components and API routes through `Astro.locals`.
77
77
 
78
78
  ```js
79
- import { getRuntime } from '@astrojs/cloudflare/runtime';
80
-
81
- getRuntime(Astro.request);
79
+ const env = Astro.locals.runtime.env;
82
80
  ```
83
81
 
84
82
  Depending on your adapter mode (advanced = worker, directory = pages), the runtime object will look a little different due to differences in the Cloudflare API.
@@ -106,7 +104,10 @@ Cloudflare has support for adding custom [headers](https://developers.cloudflare
106
104
 
107
105
  ### Custom `_routes.json`
108
106
 
109
- By default, `@astrojs/cloudflare` will generate a `_routes.json` file that lists all files from your `dist/` folder and redirects from the `_redirects` file in the `exclude` array. 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.
107
+ By default, `@astrojs/cloudflare` will generate a `_routes.json` file with `include` and `exclude` rules based on your applications's dynamic and static routes.
108
+ 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.
109
+
110
+ See [Cloudflare's documentation](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) for more details.
110
111
 
111
112
  ## Troubleshooting
112
113
 
package/dist/index.js CHANGED
@@ -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;
@@ -173,10 +174,20 @@ function createIntegration(args) {
173
174
  }
174
175
  const routesExists = await fs.promises.stat(new URL("./_routes.json", _config.outDir)).then((stat) => stat.isFile()).catch(() => false);
175
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
+ });
176
187
  const staticPathList = (await glob(`${fileURLToPath(_buildConfig.client)}/**/*`, {
177
188
  cwd: fileURLToPath(_config.outDir),
178
189
  filesOnly: true
179
- })).filter((file) => cloudflareSpecialFiles.indexOf(file) < 0).map((file) => `/${file}`);
190
+ })).filter((file) => cloudflareSpecialFiles.indexOf(file) < 0).map((file) => `/${file.replace(/\\/g, "/")}`);
180
191
  for (let page of pages) {
181
192
  let pagePath = prependForwardSlash(page.pathname);
182
193
  if (_config.base !== "/") {
@@ -215,13 +226,30 @@ function createIntegration(args) {
215
226
  trueRedirects.print()
216
227
  );
217
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
+ }
218
246
  await fs.promises.writeFile(
219
247
  new URL("./_routes.json", _config.outDir),
220
248
  JSON.stringify(
221
249
  {
222
250
  version: 1,
223
- include: ["/*"],
224
- exclude: staticPathList
251
+ include,
252
+ exclude
225
253
  },
226
254
  null,
227
255
  2
@@ -235,6 +263,18 @@ function createIntegration(args) {
235
263
  function prependForwardSlash(path) {
236
264
  return path[0] === "/" ? path : "/" + path;
237
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
+ }
238
278
  export {
239
279
  createIntegration as default,
240
280
  getAdapter
package/dist/runtime.d.ts CHANGED
@@ -22,4 +22,14 @@ export type PagesRuntime<T = unknown, U = unknown> = {
22
22
  };
23
23
  cf?: IncomingRequestCfProperties;
24
24
  };
25
+ /**
26
+ * @deprecated since version 6.8.0
27
+ * The `getRuntime` utility has been deprecated and should be updated to the new [`Astro.locals`](https://docs.astro.build/en/guides/middleware/#locals) API.
28
+ * ```diff
29
+ * - import { getRuntime } from '@astrojs/cloudflare/runtime';
30
+ * - getRuntime(Astro.request);
31
+ *
32
+ * + const runtime = Astro.locals.runtime;
33
+ * ```
34
+ */
25
35
  export declare function getRuntime<T = unknown, U = unknown>(request: Request): WorkerRuntime<T> | PagesRuntime<T, U>;
@@ -1,4 +1,4 @@
1
- import type { ExecutionContext, Request as CFRequest } from '@cloudflare/workers-types';
1
+ import type { Request as CFRequest, ExecutionContext } from '@cloudflare/workers-types';
2
2
  import type { SSRManifest } from 'astro';
3
3
  type Env = {
4
4
  ASSETS: {
@@ -28,7 +28,17 @@ function createExports(manifest) {
28
28
  context.waitUntil(promise);
29
29
  }
30
30
  });
31
- let response = await app.render(request, routeData);
31
+ const locals = {
32
+ runtime: {
33
+ waitUntil: (promise) => {
34
+ context.waitUntil(promise);
35
+ },
36
+ env,
37
+ cf: request.cf,
38
+ caches
39
+ }
40
+ };
41
+ let response = await app.render(request, routeData, locals);
32
42
  if (app.setCookieHeaders) {
33
43
  for (const setCookieHeader of app.setCookieHeaders(response)) {
34
44
  response.headers.append("Set-Cookie", setCookieHeader);
@@ -1,10 +1,6 @@
1
- import type { EventContext, Request as CFRequest } from '@cloudflare/workers-types';
1
+ import type { EventContext } from '@cloudflare/workers-types';
2
2
  import type { SSRManifest } from 'astro';
3
3
  export declare function createExports(manifest: SSRManifest): {
4
- onRequest: ({ request, next, ...runtimeEnv }: {
5
- request: Request & CFRequest;
6
- next: (request: Request) => void;
7
- waitUntil: EventContext<unknown, any, unknown>['waitUntil'];
8
- } & Record<string, unknown>) => Promise<import("@cloudflare/workers-types").Response | Response>;
4
+ onRequest: (context: EventContext<unknown, string, unknown>) => Promise<import("@cloudflare/workers-types").Response | Response>;
9
5
  manifest: SSRManifest;
10
6
  };
@@ -5,17 +5,13 @@ if (!isNode) {
5
5
  }
6
6
  function createExports(manifest) {
7
7
  const app = new App(manifest);
8
- const onRequest = async ({
9
- request,
10
- next,
11
- ...runtimeEnv
12
- }) => {
13
- process.env = runtimeEnv.env;
8
+ const onRequest = async (context) => {
9
+ const request = context.request;
10
+ const { next, env } = context;
11
+ process.env = env;
14
12
  const { pathname } = new URL(request.url);
15
13
  if (manifest.assets.has(pathname)) {
16
- return runtimeEnv.env.ASSETS.fetch(
17
- request
18
- );
14
+ return env.ASSETS.fetch(request);
19
15
  }
20
16
  let routeData = app.match(request, { matchNotFound: true });
21
17
  if (routeData) {
@@ -25,16 +21,26 @@ function createExports(manifest) {
25
21
  request.headers.get("cf-connecting-ip")
26
22
  );
27
23
  Reflect.set(request, Symbol.for("runtime"), {
28
- ...runtimeEnv,
24
+ ...context,
29
25
  waitUntil: (promise) => {
30
- runtimeEnv.waitUntil(promise);
26
+ context.waitUntil(promise);
31
27
  },
32
28
  name: "cloudflare",
33
29
  next,
34
30
  caches,
35
31
  cf: request.cf
36
32
  });
37
- let response = await app.render(request, routeData);
33
+ const locals = {
34
+ runtime: {
35
+ waitUntil: (promise) => {
36
+ context.waitUntil(promise);
37
+ },
38
+ env: context.env,
39
+ cf: request.cf,
40
+ caches
41
+ }
42
+ };
43
+ let response = await app.render(request, routeData, locals);
38
44
  if (app.setCookieHeaders) {
39
45
  for (const setCookieHeader of app.setCookieHeaders(response)) {
40
46
  response.headers.append("Set-Cookie", setCookieHeader);
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.6.2",
4
+ "version": "6.8.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.8.4"
41
+ "astro": "^2.10.6"
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.8.4",
48
+ "astro": "2.10.6",
49
49
  "astro-scripts": "0.0.14"
50
50
  },
51
51
  "scripts": {