@astrojs/cloudflare 12.5.4 → 12.6.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.
@@ -1,4 +1,4 @@
1
- import type { CacheStorage as CLOUDFLARE_CACHESTORAGE, Request as CLOUDFLARE_REQUEST, ExecutionContext } from '@cloudflare/workers-types';
1
+ import type { ExecutionContext, ExportedHandlerFetchHandler } from '@cloudflare/workers-types';
2
2
  import type { SSRManifest } from 'astro';
3
3
  type Env = {
4
4
  [key: string]: unknown;
@@ -7,21 +7,9 @@ type Env = {
7
7
  };
8
8
  ASTRO_STUDIO_APP_TOKEN?: string;
9
9
  };
10
- export interface Runtime<T extends object = object> {
11
- runtime: {
12
- env: Env & T;
13
- cf: CLOUDFLARE_REQUEST['cf'];
14
- caches: CLOUDFLARE_CACHESTORAGE;
15
- ctx: ExecutionContext;
16
- };
17
- }
18
- declare global {
19
- var __ASTRO_SESSION_BINDING_NAME: string;
20
- var __env__: Partial<Env>;
21
- }
22
10
  export declare function createExports(manifest: SSRManifest): {
23
11
  default: {
24
- fetch: (request: Request & CLOUDFLARE_REQUEST, env: Env, context: ExecutionContext) => Promise<Response>;
12
+ fetch: (request: Parameters<ExportedHandlerFetchHandler>[0], env: Env, context: ExecutionContext) => Promise<Response>;
25
13
  };
26
14
  };
27
15
  export {};
@@ -1,61 +1,9 @@
1
- import { env as globalEnv } from "cloudflare:workers";
2
1
  import { App } from "astro/app";
3
- import { setGetEnv } from "astro/env/setup";
4
- import { createGetEnv } from "../utils/env.js";
5
- setGetEnv(createGetEnv(globalEnv));
2
+ import { handle } from "../utils/handler.js";
6
3
  function createExports(manifest) {
7
4
  const app = new App(manifest);
8
5
  const fetch = async (request, env, context) => {
9
- const { pathname } = new URL(request.url);
10
- const bindingName = globalThis.__ASTRO_SESSION_BINDING_NAME;
11
- globalThis.__env__ ??= {};
12
- globalThis.__env__[bindingName] = env[bindingName];
13
- if (manifest.assets.has(pathname)) {
14
- return env.ASSETS.fetch(request.url.replace(/\.html$/, ""));
15
- }
16
- const routeData = app.match(request);
17
- if (!routeData) {
18
- const asset = await env.ASSETS.fetch(
19
- request.url.replace(/index.html$/, "").replace(/\.html$/, "")
20
- );
21
- if (asset.status !== 404) {
22
- return asset;
23
- }
24
- }
25
- Reflect.set(
26
- request,
27
- Symbol.for("astro.clientAddress"),
28
- request.headers.get("cf-connecting-ip")
29
- );
30
- process.env.ASTRO_STUDIO_APP_TOKEN ??= (() => {
31
- if (typeof env.ASTRO_STUDIO_APP_TOKEN === "string") {
32
- return env.ASTRO_STUDIO_APP_TOKEN;
33
- }
34
- })();
35
- const locals = {
36
- runtime: {
37
- env,
38
- cf: request.cf,
39
- caches,
40
- ctx: {
41
- waitUntil: (promise) => context.waitUntil(promise),
42
- // Currently not available: https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions
43
- passThroughOnException: () => {
44
- throw new Error(
45
- "`passThroughOnException` is currently not available in Cloudflare Pages. See https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions."
46
- );
47
- },
48
- props: {}
49
- }
50
- }
51
- };
52
- const response = await app.render(request, { routeData, locals });
53
- if (app.setCookieHeaders) {
54
- for (const setCookieHeader of app.setCookieHeaders(response)) {
55
- response.headers.append("Set-Cookie", setCookieHeader);
56
- }
57
- }
58
- return response;
6
+ return await handle(manifest, app, request, env, context);
59
7
  };
60
8
  return { default: { fetch } };
61
9
  }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { AstroIntegration } from 'astro';
2
2
  import { type GetPlatformProxyOptions } from 'wrangler';
3
3
  import { type ImageService } from './utils/image-config.js';
4
- export type { Runtime } from './entrypoints/server.js';
4
+ export type { Runtime } from './utils/handler.js';
5
5
  export type Options = {
6
6
  /** Options for handling images. */
7
7
  imageService?: ImageService;
@@ -70,5 +70,25 @@ export type Options = {
70
70
  *
71
71
  */
72
72
  sessionKVBindingName?: string;
73
+ /**
74
+ * This configuration option allows you to specify a custom entryPoint for your Cloudflare Worker.
75
+ * The entry point is the file that will be executed when your Worker is invoked.
76
+ * By default, this is set to `@astrojs/cloudflare/entrypoints/server.js` and `['default']`.
77
+ * @docs https://docs.astro.build/en/guides/integrations-guide/cloudflare/#workerEntryPoint
78
+ */
79
+ workerEntryPoint?: {
80
+ /**
81
+ * The path to the entry file. This should be a relative path from the root of your Astro project.
82
+ * @example`'src/worker.ts'`
83
+ * @docs https://docs.astro.build/en/guides/integrations-guide/cloudflare/#workerentrypointpath
84
+ */
85
+ path: string | URL;
86
+ /**
87
+ * Additional named exports to use for the entry file. Astro always includes the default export (`['default']`). If you need to have other top level named exports use this option.
88
+ * @example ['MyDurableObject', 'namedExport']
89
+ * @docs https://docs.astro.build/en/guides/integrations-guide/cloudflare/#workerentrypointnamedexports
90
+ */
91
+ namedExports?: string[];
92
+ };
73
93
  };
74
94
  export default function createIntegration(args?: Options): AstroIntegration;
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { createReadStream } from "node:fs";
2
2
  import { appendFile, stat } from "node:fs/promises";
3
+ import { createRequire } from "node:module";
3
4
  import { createInterface } from "node:readline/promises";
4
- import { fileURLToPath } from "node:url";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
6
  import {
6
7
  appendForwardSlash,
7
8
  prependForwardSlash,
8
9
  removeLeadingForwardSlash
9
10
  } from "@astrojs/internal-helpers/path";
10
- import { createRedirectsFromAstroRoutes } from "@astrojs/underscore-redirects";
11
+ import { createRedirectsFromAstroRoutes, printAsRedirects } from "@astrojs/underscore-redirects";
11
12
  import { AstroError } from "astro/errors";
12
13
  import { defaultClientConditions } from "vite";
13
14
  import { getPlatformProxy } from "wrangler";
@@ -129,10 +130,19 @@ function createIntegration(args) {
129
130
  }
130
131
  _config = config;
131
132
  finalBuildOutput = buildOutput;
133
+ let customWorkerEntryPoint;
134
+ if (args?.workerEntryPoint && typeof args.workerEntryPoint.path === "string") {
135
+ const require2 = createRequire(config.root);
136
+ try {
137
+ customWorkerEntryPoint = pathToFileURL(require2.resolve(args.workerEntryPoint.path));
138
+ } catch {
139
+ customWorkerEntryPoint = new URL(args.workerEntryPoint.path, config.root);
140
+ }
141
+ }
132
142
  setAdapter({
133
143
  name: "@astrojs/cloudflare",
134
- serverEntrypoint: "@astrojs/cloudflare/entrypoints/server.js",
135
- exports: ["default"],
144
+ serverEntrypoint: customWorkerEntryPoint ?? "@astrojs/cloudflare/entrypoints/server.js",
145
+ exports: args?.workerEntryPoint?.namedExports ? ["default", ...args.workerEntryPoint.namedExports] : ["default"],
136
146
  adapterFeatures: {
137
147
  edgeMiddleware: false,
138
148
  buildOutput: "server"
@@ -156,6 +166,9 @@ function createIntegration(args) {
156
166
  "astro:server:setup": async ({ server }) => {
157
167
  if ((args?.platformProxy?.enabled ?? true) === true) {
158
168
  const platformProxy = await getPlatformProxy(args?.platformProxy);
169
+ server.httpServer?.on("close", async () => {
170
+ await platformProxy.dispose();
171
+ });
159
172
  setProcessEnv(_config, platformProxy.env);
160
173
  const clientLocalsSymbol = Symbol.for("astro.locals");
161
174
  server.middlewares.use(async function middleware(req, _res, next) {
@@ -277,7 +290,10 @@ function createIntegration(args) {
277
290
  });
278
291
  if (!trueRedirects.empty()) {
279
292
  try {
280
- await appendFile(new URL("./_redirects", _config.outDir), trueRedirects.print());
293
+ await appendFile(
294
+ new URL("./_redirects", _config.outDir),
295
+ printAsRedirects(trueRedirects)
296
+ );
281
297
  } catch (_error) {
282
298
  logger.error("Failed to write _redirects file");
283
299
  }
@@ -0,0 +1,24 @@
1
+ import type { CacheStorage as CloudflareCacheStorage, ExecutionContext, ExportedHandlerFetchHandler } from '@cloudflare/workers-types';
2
+ import type { SSRManifest } from 'astro';
3
+ import type { App } from 'astro/app';
4
+ type Env = {
5
+ [key: string]: unknown;
6
+ ASSETS: {
7
+ fetch: (req: Request | string) => Promise<Response>;
8
+ };
9
+ ASTRO_STUDIO_APP_TOKEN?: string;
10
+ };
11
+ export interface Runtime<T extends object = object> {
12
+ runtime: {
13
+ env: Env & T;
14
+ cf: Parameters<ExportedHandlerFetchHandler>[0]['cf'];
15
+ caches: CloudflareCacheStorage;
16
+ ctx: ExecutionContext;
17
+ };
18
+ }
19
+ declare global {
20
+ var __ASTRO_SESSION_BINDING_NAME: string;
21
+ var __env__: Partial<Env>;
22
+ }
23
+ export declare function handle(manifest: SSRManifest, app: App, request: Parameters<ExportedHandlerFetchHandler>[0], env: Env, context: ExecutionContext): Promise<Response>;
24
+ export {};
@@ -0,0 +1,64 @@
1
+ import { env as globalEnv } from "cloudflare:workers";
2
+ import { setGetEnv } from "astro/env/setup";
3
+ import { createGetEnv } from "../utils/env.js";
4
+ setGetEnv(createGetEnv(globalEnv));
5
+ async function handle(manifest, app, request, env, context) {
6
+ const { pathname } = new URL(request.url);
7
+ const bindingName = globalThis.__ASTRO_SESSION_BINDING_NAME;
8
+ globalThis.__env__ ??= {};
9
+ globalThis.__env__[bindingName] = env[bindingName];
10
+ if (manifest.assets.has(pathname)) {
11
+ return env.ASSETS.fetch(request.url.replace(/\.html$/, ""));
12
+ }
13
+ const routeData = app.match(request);
14
+ if (!routeData) {
15
+ const asset = await env.ASSETS.fetch(
16
+ request.url.replace(/index.html$/, "").replace(/\.html$/, "")
17
+ );
18
+ if (asset.status !== 404) {
19
+ return asset;
20
+ }
21
+ }
22
+ Reflect.set(request, Symbol.for("astro.clientAddress"), request.headers.get("cf-connecting-ip"));
23
+ process.env.ASTRO_STUDIO_APP_TOKEN ??= (() => {
24
+ if (typeof env.ASTRO_STUDIO_APP_TOKEN === "string") {
25
+ return env.ASTRO_STUDIO_APP_TOKEN;
26
+ }
27
+ })();
28
+ const locals = {
29
+ runtime: {
30
+ env,
31
+ cf: request.cf,
32
+ caches,
33
+ ctx: {
34
+ waitUntil: (promise) => context.waitUntil(promise),
35
+ // Currently not available: https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions
36
+ passThroughOnException: () => {
37
+ throw new Error(
38
+ "`passThroughOnException` is currently not available in Cloudflare Pages. See https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions."
39
+ );
40
+ },
41
+ props: {}
42
+ }
43
+ }
44
+ };
45
+ const response = await app.render(
46
+ request,
47
+ {
48
+ routeData,
49
+ locals,
50
+ prerenderedErrorPageFetch: async (url) => {
51
+ return env.ASSETS.fetch(url.replace(/\.html$/, ""));
52
+ }
53
+ }
54
+ );
55
+ if (app.setCookieHeaders) {
56
+ for (const setCookieHeader of app.setCookieHeaders(response)) {
57
+ response.headers.append("Set-Cookie", setCookieHeader);
58
+ }
59
+ }
60
+ return response;
61
+ }
62
+ export {
63
+ handle
64
+ };
@@ -2,7 +2,7 @@ import type { AstroConfig, AstroIntegrationLogger, HookParameters } from 'astro'
2
2
  export type ImageService = 'passthrough' | 'cloudflare' | 'compile' | 'custom';
3
3
  export declare function setImageConfig(service: ImageService, config: AstroConfig['image'], command: HookParameters<'astro:config:setup'>['command'], logger: AstroIntegrationLogger): {
4
4
  service: import("astro").ImageServiceConfig<Record<string, any>>;
5
- experimentalDefaultStyles: boolean;
5
+ responsiveStyles: boolean;
6
6
  endpoint: {
7
7
  route: string;
8
8
  entrypoint?: string | undefined;
@@ -14,16 +14,16 @@ export declare function setImageConfig(service: ImageService, config: AstroConfi
14
14
  hostname?: string | undefined;
15
15
  pathname?: string | undefined;
16
16
  }[];
17
- experimentalLayout?: "fixed" | "constrained" | "full-width" | "none" | undefined;
18
- experimentalObjectFit?: string | undefined;
19
- experimentalObjectPosition?: string | undefined;
20
- experimentalBreakpoints?: number[] | undefined;
17
+ layout?: "fixed" | "constrained" | "full-width" | "none" | undefined;
18
+ objectFit?: string | undefined;
19
+ objectPosition?: string | undefined;
20
+ breakpoints?: number[] | undefined;
21
21
  } | {
22
22
  service: import("astro").ImageServiceConfig<Record<string, any>>;
23
23
  endpoint: {
24
24
  entrypoint: string | undefined;
25
25
  };
26
- experimentalDefaultStyles: boolean;
26
+ responsiveStyles: boolean;
27
27
  domains: string[];
28
28
  remotePatterns: {
29
29
  port?: string | undefined;
@@ -31,8 +31,8 @@ export declare function setImageConfig(service: ImageService, config: AstroConfi
31
31
  hostname?: string | undefined;
32
32
  pathname?: string | undefined;
33
33
  }[];
34
- experimentalLayout?: "fixed" | "constrained" | "full-width" | "none" | undefined;
35
- experimentalObjectFit?: string | undefined;
36
- experimentalObjectPosition?: string | undefined;
37
- experimentalBreakpoints?: number[] | undefined;
34
+ layout?: "fixed" | "constrained" | "full-width" | "none" | undefined;
35
+ objectFit?: string | undefined;
36
+ objectPosition?: string | undefined;
37
+ breakpoints?: number[] | undefined;
38
38
  };
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": "12.5.4",
4
+ "version": "12.6.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -23,6 +23,7 @@
23
23
  "./entrypoints/middleware.js": "./dist/entrypoints/middleware.js",
24
24
  "./image-service": "./dist/entrypoints/image-service.js",
25
25
  "./image-endpoint": "./dist/entrypoints/image-endpoint.js",
26
+ "./handler": "./dist/utils/handler.js",
26
27
  "./package.json": "./package.json"
27
28
  },
28
29
  "files": [
@@ -33,8 +34,8 @@
33
34
  "tinyglobby": "^0.2.13",
34
35
  "vite": "^6.3.5",
35
36
  "wrangler": "^4.14.1",
36
- "@astrojs/internal-helpers": "0.6.1",
37
- "@astrojs/underscore-redirects": "0.6.1"
37
+ "@astrojs/underscore-redirects": "1.0.0",
38
+ "@astrojs/internal-helpers": "0.6.1"
38
39
  },
39
40
  "peerDependencies": {
40
41
  "astro": "^5.0.0"
@@ -44,13 +45,14 @@
44
45
  "devalue": "^5.1.1",
45
46
  "execa": "^8.0.1",
46
47
  "rollup": "^4.40.2",
47
- "astro-scripts": "0.0.14",
48
- "astro": "5.9.0"
48
+ "astro": "5.10.0",
49
+ "astro-scripts": "0.0.14"
49
50
  },
50
51
  "publishConfig": {
51
52
  "provenance": true
52
53
  },
53
54
  "scripts": {
55
+ "dev": "astro-scripts dev \"src/**/*.ts\"",
54
56
  "build": "astro-scripts build \"src/**/*.ts\" && tsc",
55
57
  "build:ci": "astro-scripts build \"src/**/*.ts\"",
56
58
  "test": "astro-scripts test \"test/**/*.test.js\""