@astrojs/cloudflare 7.0.0-beta.1 → 7.0.0-rc.3

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
@@ -44,23 +44,37 @@ export default defineConfig({
44
44
 
45
45
  default `"advanced"`
46
46
 
47
- Cloudflare Pages has 2 different modes for deploying functions, `advanced` mode which picks up the `_worker.js` in `dist`, or a directory mode where pages will compile the worker out of a functions folder in the project root.
47
+ Cloudflare Pages has 2 different modes for deploying functions, `advanced` mode which picks up the `_worker.js` in `dist`, or a directory mode where pages will compile the worker out of a functions folder in the project root. For most projects the adapter default of `advanced` will be sufficient; the `dist` folder will contain your compiled project.
48
48
 
49
- For most projects the adapter default of `advanced` will be sufficient; the `dist` folder will contain your compiled project. Switching to directory mode allows you to use [pages plugins](https://developers.cloudflare.com/pages/platform/functions/plugins/) such as [Sentry](https://developers.cloudflare.com/pages/platform/functions/plugins/sentry/) or write custom code to enable logging.
49
+ #### `mode:directory`
50
50
 
51
- In directory mode, the adapter will compile the client side part of your app the same way by default, but moves the worker script into a `functions` folder in the project root. In this case, the adapter will only ever place a `[[path]].js` in that folder, allowing you to add additional plugins and pages middleware which can be checked into version control.
52
-
53
- With the build configuration `split: true`, the adapter instead compiles a separate bundle for each page. This option requires some manual maintenance of the `functions` folder. Files emitted by Astro will overwrite existing `functions` files with identical names, so you must choose unique file names for each file you manually add. Additionally, the adapter will never empty the `functions` folder of outdated files, so you must clean up the folder manually when you remove pages.
54
-
55
- Note that this adapter does not support using [Cloudflare Pages Middleware](https://developers.cloudflare.com/pages/platform/functions/middleware/). Astro will bundle the [Astro middleware](https://docs.astro.build/en/guides/middleware/) into each page.
51
+ Switching to directory mode allows you to use [pages plugins](https://developers.cloudflare.com/pages/platform/functions/plugins/) such as [Sentry](https://developers.cloudflare.com/pages/platform/functions/plugins/sentry/) or write custom code to enable logging.
56
52
 
57
53
  ```ts
58
- // directory mode
54
+ // astro.config.mjs
59
55
  export default defineConfig({
60
56
  adapter: cloudflare({ mode: 'directory' }),
61
57
  });
62
58
  ```
63
59
 
60
+ In `directory` mode, the adapter will compile the client-side part of your app the same way as in `advanced` mode by default, but moves the worker script into a `functions` folder in the project root. In this case, the adapter will only ever place a `[[path]].js` in that folder, allowing you to add additional plugins and pages middleware which can be checked into version control.
61
+
62
+ To instead compile a separate bundle for each page, set the `functionPerPath` option in your Cloudflare adapter config. This option requires some manual maintenance of the `functions` folder. Files emitted by Astro will overwrite existing `functions` files with identical names, so you must choose unique file names for each file you manually add. Additionally, the adapter will never empty the `functions` folder of outdated files, so you must clean up the folder manually when you remove pages.
63
+
64
+ ```diff
65
+ import {defineConfig} from "astro/config";
66
+ import cloudflare from '@astrojs/cloudflare';
67
+
68
+ export default defineConfig({
69
+ adapter: cloudflare({
70
+ mode: 'directory',
71
+ + functionPerRoute: true
72
+ })
73
+ })
74
+ ```
75
+
76
+ Note that this adapter does not support using [Cloudflare Pages Middleware](https://developers.cloudflare.com/pages/platform/functions/middleware/). Astro will bundle the [Astro middleware](https://docs.astro.build/en/guides/middleware/) into each page.
77
+
64
78
  ## Enabling Preview
65
79
 
66
80
  In order for preview to work you must install `wrangler`
@@ -73,12 +87,10 @@ It's then possible to update the preview script in your `package.json` to `"prev
73
87
 
74
88
  ## Access to the Cloudflare runtime
75
89
 
76
- You can access all the Cloudflare bindings and environment variables from Astro components and API routes through the adapter API.
90
+ You can access all the Cloudflare bindings and environment variables from Astro components and API routes through `Astro.locals`.
77
91
 
78
92
  ```js
79
- import { getRuntime } from '@astrojs/cloudflare/runtime';
80
-
81
- getRuntime(Astro.request);
93
+ const env = Astro.locals.runtime.env;
82
94
  ```
83
95
 
84
96
  Depending on your adapter mode (advanced = worker, directory = pages), the runtime object will look a little different due to differences in the Cloudflare API.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import type { AstroAdapter, AstroIntegration } from 'astro';
2
2
  type Options = {
3
3
  mode: 'directory' | 'advanced';
4
+ functionPerRoute?: boolean;
4
5
  };
5
- export declare function getAdapter(isModeDirectory: boolean): AstroAdapter;
6
+ export declare function getAdapter({ isModeDirectory, functionPerRoute, }: {
7
+ isModeDirectory: boolean;
8
+ functionPerRoute: boolean;
9
+ }): AstroAdapter;
6
10
  export default function createIntegration(args?: Options): AstroIntegration;
7
11
  export {};
package/dist/index.js CHANGED
@@ -5,17 +5,24 @@ import * as os from "node:os";
5
5
  import { sep } from "node:path";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import glob from "tiny-glob";
8
- function getAdapter(isModeDirectory) {
8
+ function getAdapter({
9
+ isModeDirectory,
10
+ functionPerRoute
11
+ }) {
9
12
  return isModeDirectory ? {
10
13
  name: "@astrojs/cloudflare",
11
14
  serverEntrypoint: "@astrojs/cloudflare/server.directory.js",
12
15
  exports: ["onRequest", "manifest"],
16
+ adapterFeatures: {
17
+ functionPerRoute,
18
+ edgeMiddleware: false
19
+ },
13
20
  supportedAstroFeatures: {
14
21
  hybridOutput: "stable",
15
22
  staticOutput: "unsupported",
16
23
  serverOutput: "stable",
17
24
  assets: {
18
- supportKind: "unsupported",
25
+ supportKind: "stable",
19
26
  isSharpCompatible: false,
20
27
  isSquooshCompatible: false
21
28
  }
@@ -45,8 +52,9 @@ const potentialFunctionRouteTypes = ["endpoint", "page"];
45
52
  function createIntegration(args) {
46
53
  let _config;
47
54
  let _buildConfig;
48
- const isModeDirectory = args?.mode === "directory";
49
55
  let _entryPoints = /* @__PURE__ */ new Map();
56
+ const isModeDirectory = args?.mode === "directory";
57
+ const functionPerRoute = args?.functionPerRoute ?? false;
50
58
  return {
51
59
  name: "@astrojs/cloudflare",
52
60
  hooks: {
@@ -61,7 +69,7 @@ function createIntegration(args) {
61
69
  });
62
70
  },
63
71
  "astro:config:done": ({ setAdapter, config }) => {
64
- setAdapter(getAdapter(isModeDirectory));
72
+ setAdapter(getAdapter({ isModeDirectory, functionPerRoute }));
65
73
  _config = config;
66
74
  _buildConfig = config.build;
67
75
  if (config.output === "static") {
@@ -103,7 +111,7 @@ function createIntegration(args) {
103
111
  if (isModeDirectory) {
104
112
  await fs.promises.mkdir(functionsUrl, { recursive: true });
105
113
  }
106
- if (isModeDirectory && _buildConfig.split) {
114
+ if (isModeDirectory && (_buildConfig.split || functionPerRoute)) {
107
115
  const entryPointsURL = [..._entryPoints.values()];
108
116
  const entryPaths = entryPointsURL.map((entry) => fileURLToPath(entry));
109
117
  const outputUrl = new URL("$astro", _buildConfig.server);
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>;
@@ -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 { Request as CFRequest, EventContext } 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": "7.0.0-beta.1",
4
+ "version": "7.0.0-rc.3",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -35,17 +35,18 @@
35
35
  "@cloudflare/workers-types": "^4.20230518.0",
36
36
  "esbuild": "^0.18.16",
37
37
  "tiny-glob": "^0.2.9",
38
- "@astrojs/underscore-redirects": "0.3.0-beta.0"
38
+ "@astrojs/underscore-redirects": "0.3.0-rc.1"
39
39
  },
40
40
  "peerDependencies": {
41
- "astro": "^3.0.0-beta.1"
41
+ "astro": "^3.0.0-rc.5"
42
42
  },
43
43
  "devDependencies": {
44
44
  "chai": "^4.3.7",
45
45
  "cheerio": "1.0.0-rc.12",
46
+ "kill-port": "^2.0.1",
46
47
  "mocha": "^9.2.2",
47
- "wrangler": "^2.0.23",
48
- "astro": "3.0.0-beta.1",
48
+ "wrangler": "^3.5.0",
49
+ "astro": "3.0.0-rc.5",
49
50
  "astro-scripts": "0.0.14"
50
51
  },
51
52
  "scripts": {