@astrojs/cloudflare 13.5.0 → 13.5.2

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.
@@ -88,7 +88,7 @@ function serverStart({
88
88
  host,
89
89
  base
90
90
  }) {
91
- const version = "13.5.0";
91
+ const version = "13.5.2";
92
92
  const localPrefix = `${colors.dim("\u2503")} Local `;
93
93
  const networkPrefix = `${colors.dim("\u2503")} Network `;
94
94
  const emptyPrefix = " ".repeat(11);
@@ -4,6 +4,12 @@ type ESBuildPlugin = NonNullable<NonNullable<DepOptimizationConfig['esbuildOptio
4
4
  * An esbuild plugin that extracts frontmatter from .astro files during
5
5
  * dependency optimization scanning. This allows Vite to discover imports
6
6
  * in the server-side frontmatter code.
7
+ *
8
+ * This plugin uses an `onResolve` handler to intercept `.astro` files before
9
+ * Vite's built-in `vite:dep-scan` plugin routes them to the `html` namespace.
10
+ * Without this, Vite's scanner only extracts `<script>` tags from `.astro`
11
+ * files, completely missing frontmatter imports (which is where SSR-side
12
+ * dependencies like `zod`, `nanostores`, `astro:transitions`, etc. live).
7
13
  */
8
14
  export declare function astroFrontmatterScanPlugin(): ESBuildPlugin;
9
15
  export {};
@@ -1,4 +1,5 @@
1
1
  import { readFile } from "node:fs/promises";
2
+ import { dirname, isAbsolute, resolve } from "node:path";
2
3
  const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
3
4
  const RETURN_REPLACE_RE = /(\/\/[^\n]*|\/\*[\s\S]*?\*\/|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')|(?<!\.)\breturn(\s*;|\b)/g;
4
5
  function replaceTopLevelReturns(code) {
@@ -7,11 +8,19 @@ function replaceTopLevelReturns(code) {
7
8
  return tail.trim() === ";" ? "throw 0;" : "throw ";
8
9
  });
9
10
  }
11
+ const ASTRO_FRONTMATTER_NAMESPACE = "astro-frontmatter";
10
12
  function astroFrontmatterScanPlugin() {
11
13
  return {
12
14
  name: "astro-frontmatter-scan",
13
15
  setup(build) {
14
- build.onLoad({ filter: /\.astro$/ }, async (args) => {
16
+ build.onResolve({ filter: /\.astro$/ }, (args) => {
17
+ if (args.namespace !== "file" && args.namespace !== "" && args.namespace !== void 0) {
18
+ return void 0;
19
+ }
20
+ const resolvedPath = isAbsolute(args.path) ? args.path : resolve(args.resolveDir, args.path);
21
+ return { path: resolvedPath, namespace: ASTRO_FRONTMATTER_NAMESPACE };
22
+ });
23
+ build.onLoad({ filter: /\.astro$/, namespace: ASTRO_FRONTMATTER_NAMESPACE }, async (args) => {
15
24
  try {
16
25
  const code = await readFile(args.path, "utf-8");
17
26
  const frontmatterMatch = FRONTMATTER_RE.exec(code);
@@ -19,14 +28,16 @@ function astroFrontmatterScanPlugin() {
19
28
  const contents = replaceTopLevelReturns(frontmatterMatch[1]);
20
29
  return {
21
30
  contents: contents + "\nexport default {}",
22
- loader: "ts"
31
+ loader: "ts",
32
+ resolveDir: dirname(args.path)
23
33
  };
24
34
  }
25
35
  } catch {
26
36
  }
27
37
  return {
28
38
  contents: "export default {}",
29
- loader: "ts"
39
+ loader: "ts",
40
+ resolveDir: dirname(args.path)
30
41
  };
31
42
  });
32
43
  }
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createReadStream, existsSync, readFileSync } from "node:fs";
2
- import { appendFile, rename, stat } from "node:fs/promises";
2
+ import { appendFile, readFile, rename, stat } from "node:fs/promises";
3
3
  import { createInterface } from "node:readline/promises";
4
4
  import { removeLeadingForwardSlash } from "@astrojs/internal-helpers/path";
5
5
  import { createRedirectsFromAstroRoutes, printAsRedirects } from "@astrojs/underscore-redirects";
@@ -20,6 +20,7 @@ import {
20
20
  import { parseEnv } from "node:util";
21
21
  import { sessionDrivers } from "astro/config";
22
22
  import { createCloudflarePrerenderer } from "./prerenderer.js";
23
+ import cfPrismPlugin from "./vite-plugin-prism.js";
23
24
  const CLOUDFLARE_KV_SESSION_DRIVER_ENTRYPOINT = sessionDrivers.cloudflareKVBinding().entrypoint;
24
25
  function usesCloudflareKVSessionDriver(session) {
25
26
  const driver = session?.driver;
@@ -66,7 +67,7 @@ function createIntegration({
66
67
  return {
67
68
  name: "@astrojs/cloudflare",
68
69
  hooks: {
69
- "astro:config:setup": ({ command, config, updateConfig, logger, addWatchFile }) => {
70
+ "astro:config:setup": async ({ command, config, updateConfig, logger, addWatchFile }) => {
70
71
  if (!!process.versions.webcontainer) {
71
72
  throw new Error("`workerd` does not run on Stackblitz.");
72
73
  }
@@ -126,6 +127,12 @@ function createIntegration({
126
127
  if (command === "preview") {
127
128
  globalThis.astroCloudflareOptions = cfPluginConfig;
128
129
  }
130
+ const prismFiles = [
131
+ "@astrojs/prism > prismjs",
132
+ "@astrojs/prism > prismjs/components.js",
133
+ "@astrojs/prism > prismjs/dependencies.js"
134
+ ];
135
+ const isAstroPrismPackageInstalled = await getIsAstroPrismInstalled(config.root);
129
136
  updateConfig({
130
137
  build: {
131
138
  redirects: false
@@ -187,7 +194,13 @@ function createIntegration({
187
194
  "astro/compiler-runtime",
188
195
  "astro/jsx-runtime",
189
196
  "astro/app/entrypoint/dev",
190
- "astro/virtual-modules/middleware.js"
197
+ "astro/virtual-modules/middleware.js",
198
+ "astro/virtual-modules/transitions.js",
199
+ "astro/virtual-modules/transitions-router.js",
200
+ "astro/virtual-modules/transitions-types.js",
201
+ "astro/virtual-modules/transitions-events.js",
202
+ "astro/virtual-modules/transitions-swap-functions.js",
203
+ ...isAstroPrismPackageInstalled ? prismFiles : []
191
204
  ],
192
205
  exclude: [
193
206
  "unstorage/drivers/cloudflare-kv-binding",
@@ -197,6 +210,7 @@ function createIntegration({
197
210
  "virtual:@astrojs/*",
198
211
  "@astrojs/starlight"
199
212
  ],
213
+ ignoreOutdatedRequests: true,
200
214
  esbuildOptions: {
201
215
  // Suppress Vite's `createRequire(import.meta.url)` banner to work around
202
216
  // https://github.com/vitejs/vite/issues/22004 — Vite's SSR transform
@@ -239,7 +253,8 @@ function createIntegration({
239
253
  imageServiceEntrypoint: "@astrojs/cloudflare/image-service-workerd",
240
254
  buildAssets: config.build.assets ?? "_astro"
241
255
  } : null
242
- })
256
+ }),
257
+ cfPrismPlugin()
243
258
  ]
244
259
  },
245
260
  image: setImageConfig(imageService, config.image, command, logger)
@@ -306,6 +321,7 @@ function createIntegration({
306
321
  if (prerenderEnvironment === "workerd") {
307
322
  setPrerenderer(
308
323
  createCloudflarePrerenderer({
324
+ cloudflareOptions,
309
325
  root: _config.root,
310
326
  serverDir: _config.build.server,
311
327
  clientDir: _config.build.client,
@@ -399,6 +415,16 @@ function createIntegration({
399
415
  }
400
416
  };
401
417
  }
418
+ async function getIsAstroPrismInstalled(rootURL) {
419
+ try {
420
+ const pkgURL = new URL("./package.json", rootURL);
421
+ const input = await readFile(pkgURL, { encoding: "utf-8" });
422
+ const pkgJson = JSON.parse(input);
423
+ return Object.hasOwn(pkgJson["dependencies"], "@astrojs/prism");
424
+ } catch {
425
+ return false;
426
+ }
427
+ }
402
428
  export {
403
429
  createIntegration as default
404
430
  };
@@ -1,6 +1,7 @@
1
1
  import type { AstroConfig, AstroPrerenderer } from 'astro';
2
2
  import { type PluginConfig } from '@cloudflare/vite-plugin';
3
3
  interface CloudflarePrerendererOptions {
4
+ cloudflareOptions: Partial<PluginConfig>;
4
5
  root: AstroConfig['root'];
5
6
  serverDir: AstroConfig['build']['server'];
6
7
  clientDir: AstroConfig['build']['client'];
@@ -13,5 +14,5 @@ interface CloudflarePrerendererOptions {
13
14
  * Creates a prerenderer that uses Cloudflare's workerd runtime via a preview server.
14
15
  * This allows prerendering to happen in the same runtime that will serve the pages.
15
16
  */
16
- export declare function createCloudflarePrerenderer({ root, serverDir, clientDir, base, trailingSlash, cfPluginConfig, hasCompileImageService, }: CloudflarePrerendererOptions): AstroPrerenderer;
17
+ export declare function createCloudflarePrerenderer({ cloudflareOptions, root, serverDir, clientDir, base, trailingSlash, cfPluginConfig, hasCompileImageService, }: CloudflarePrerendererOptions): AstroPrerenderer;
17
18
  export {};
@@ -9,6 +9,7 @@ import {
9
9
  STATIC_IMAGES_ENDPOINT
10
10
  } from "./utils/prerender-constants.js";
11
11
  function createCloudflarePrerenderer({
12
+ cloudflareOptions,
12
13
  root,
13
14
  serverDir,
14
15
  clientDir,
@@ -48,7 +49,13 @@ function createCloudflarePrerenderer({
48
49
  // Let the OS pick a free port
49
50
  open: false
50
51
  },
51
- plugins: [cfVitePlugin({ ...cfPluginConfig, viteEnvironment: { name: "prerender" } })]
52
+ plugins: [
53
+ cfVitePlugin({
54
+ ...cloudflareOptions,
55
+ ...cfPluginConfig,
56
+ viteEnvironment: { name: "prerender" }
57
+ })
58
+ ]
52
59
  });
53
60
  const address = previewServer.httpServer.address();
54
61
  if (address && typeof address === "object") {
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from 'vite';
2
+ export default function cfPrismPlugin(): Plugin;
@@ -0,0 +1,56 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import components from "prismjs/components.js";
3
+ const MODULE_ID = "virtual:astro-cloudflare:prism";
4
+ const RESOLVED_MODULE_ID = "\0" + MODULE_ID;
5
+ const languages = Object.keys(components.languages).filter((l) => l !== "meta");
6
+ function cfPrismPlugin() {
7
+ return {
8
+ name: "@astrojs/cloudflare:prism",
9
+ configEnvironment(environmentName) {
10
+ if (environmentName === "ssr") {
11
+ return {
12
+ // Because this virtual module adds a large number of dynamic import statements,
13
+ // Vite’s logs will consequently display the message “new dependencies optimized” for all languages.
14
+ // To avoid this, we explicitly specify that the module should be optimized in advance.
15
+ optimizeDeps: {
16
+ include: ["prismjs/components/prism-*.js"]
17
+ }
18
+ };
19
+ }
20
+ },
21
+ resolveId: {
22
+ filter: {
23
+ id: new RegExp(`^${MODULE_ID}$`)
24
+ },
25
+ handler() {
26
+ return RESOLVED_MODULE_ID;
27
+ }
28
+ },
29
+ load: {
30
+ filter: {
31
+ id: new RegExp(`^${RESOLVED_MODULE_ID}$`)
32
+ },
33
+ async handler() {
34
+ const importerPath = fileURLToPath(import.meta.url);
35
+ const resolvedModules = await Promise.all(
36
+ languages.map(async (lang) => {
37
+ const resolvedId = await this.resolve(
38
+ `prismjs/components/prism-${lang}.js`,
39
+ importerPath
40
+ );
41
+ return { resolvedId: resolvedId?.id, lang };
42
+ })
43
+ );
44
+ const prismBundledLanguages = resolvedModules.filter(({ resolvedId }) => resolvedId !== void 0).map(
45
+ ({ resolvedId, lang }) => `${JSON.stringify(lang)}: () => import(${JSON.stringify(resolvedId)})`
46
+ );
47
+ return `
48
+ export const bundledLanguages = { ${prismBundledLanguages.join(",")} };
49
+ `;
50
+ }
51
+ }
52
+ };
53
+ }
54
+ export {
55
+ cfPrismPlugin as default
56
+ };
package/dist/wrangler.js CHANGED
@@ -2,11 +2,6 @@ const DEFAULT_SESSION_KV_BINDING_NAME = "SESSION";
2
2
  const DEFAULT_IMAGES_BINDING_NAME = "IMAGES";
3
3
  const DEFAULT_ASSETS_BINDING_NAME = "ASSETS";
4
4
  const DEFAULT_COMPATIBILITY_DATE = "2026-04-15";
5
- function withSessionKVBinding(existing, sessionBinding) {
6
- const namespaces = existing ? [...existing] : [];
7
- namespaces.push({ binding: sessionBinding });
8
- return namespaces;
9
- }
10
5
  function cloudflareConfigCustomizer(options) {
11
6
  const sessionKVBindingName = options?.sessionKVBindingName ?? DEFAULT_SESSION_KV_BINDING_NAME;
12
7
  const needsSessionKVBinding = options?.needsSessionKVBinding ?? true;
@@ -18,7 +13,7 @@ function cloudflareConfigCustomizer(options) {
18
13
  );
19
14
  const hasImagesBinding = nonInheritableConfig?.images?.binding !== void 0;
20
15
  return {
21
- kv_namespaces: !needsSessionKVBinding || hasSessionBinding ? void 0 : withSessionKVBinding(nonInheritableConfig?.kv_namespaces, sessionKVBindingName),
16
+ kv_namespaces: !needsSessionKVBinding || hasSessionBinding ? void 0 : [{ binding: sessionKVBindingName }],
22
17
  images: hasImagesBinding || !imagesBindingName ? void 0 : {
23
18
  binding: imagesBindingName
24
19
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astrojs/cloudflare",
3
3
  "description": "Deploy your site to Cloudflare Workers",
4
- "version": "13.5.0",
4
+ "version": "13.5.2",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -39,7 +39,7 @@
39
39
  "piccolore": "^0.1.3",
40
40
  "tinyglobby": "^0.2.15",
41
41
  "vite": "^7.3.2",
42
- "@astrojs/internal-helpers": "0.9.0",
42
+ "@astrojs/internal-helpers": "0.9.1",
43
43
  "@astrojs/underscore-redirects": "1.0.3"
44
44
  },
45
45
  "peerDependencies": {
@@ -49,9 +49,11 @@
49
49
  "devDependencies": {
50
50
  "@cloudflare/workers-types": "^4.20260228.0",
51
51
  "@types/node": "^25.2.2",
52
+ "@types/prismjs": "1.26.6",
52
53
  "cheerio": "1.2.0",
53
54
  "devalue": "^5.6.3",
54
- "astro": "6.3.0",
55
+ "prismjs": "^1.30.0",
56
+ "astro": "6.3.4",
55
57
  "astro-scripts": "0.0.14"
56
58
  },
57
59
  "publishConfig": {