@astrojs/cloudflare 13.5.4 → 13.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.
@@ -41,7 +41,7 @@ const createPreviewServer = async ({
41
41
  allowedHosts
42
42
  },
43
43
  plugins: [
44
- cfVitePlugin({ ...globalThis.astroCloudflareOptions, viteEnvironment: { name: "ssr" } })
44
+ cfVitePlugin({ ...globalThis.astroCloudflareConfig, viteEnvironment: { name: "ssr" } })
45
45
  ]
46
46
  });
47
47
  } catch (err) {
@@ -88,7 +88,7 @@ function serverStart({
88
88
  host,
89
89
  base
90
90
  }) {
91
- const version = "13.5.4";
91
+ const version = "13.6.0";
92
92
  const localPrefix = `${colors.dim("\u2503")} Local `;
93
93
  const networkPrefix = `${colors.dim("\u2503")} Network `;
94
94
  const emptyPrefix = " ".repeat(11);
@@ -0,0 +1,12 @@
1
+ import type { FetchState } from 'astro/fetch';
2
+ /**
3
+ * Applies Cloudflare-specific setup to a `FetchState`:
4
+ * - Injects the SESSION KV binding
5
+ * - Serves static assets via the ASSETS binding
6
+ * - Sets `locals.cfContext`, client address, `waitUntil`, and error page fetch
7
+ *
8
+ * Returns a `Response` if the request was handled by the ASSETS binding
9
+ * (static file hit). Returns `undefined` when the caller should continue
10
+ * to Astro rendering.
11
+ */
12
+ export declare function cf(state: FetchState, env: Env, ctx: ExecutionContext): Promise<Response | undefined>;
package/dist/fetch.js ADDED
@@ -0,0 +1,31 @@
1
+ import { env as globalEnv } from "cloudflare:workers";
2
+ import { createApp } from "astro/app/entrypoint";
3
+ import { setGetEnv } from "astro/env/setup";
4
+ import { createGetEnv } from "./utils/env.js";
5
+ import {
6
+ injectSessionBinding,
7
+ matchStaticAsset,
8
+ fallbackToAssets,
9
+ createErrorPageFetch,
10
+ createLocals,
11
+ getClientAddress
12
+ } from "./utils/cf.js";
13
+ setGetEnv(createGetEnv(globalEnv));
14
+ const app = createApp();
15
+ async function cf(state, env, ctx) {
16
+ injectSessionBinding(app.manifest, env);
17
+ const staticAsset = matchStaticAsset(app.manifest, state.request.url, env);
18
+ if (staticAsset) return staticAsset;
19
+ if (!state.routeData) {
20
+ const asset = await fallbackToAssets(state.request.url, env);
21
+ if (asset) return asset;
22
+ }
23
+ Object.assign(state.locals, createLocals(ctx));
24
+ state.clientAddress = getClientAddress(state.request);
25
+ state.renderOptions.waitUntil = ctx.waitUntil.bind(ctx);
26
+ state.renderOptions.prerenderedErrorPageFetch = createErrorPageFetch(env);
27
+ return void 0;
28
+ }
29
+ export {
30
+ cf
31
+ };
package/dist/hono.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Duck-typed Hono context — matches Hono's `Context` shape for
3
+ * Cloudflare Workers without importing from `hono` at runtime.
4
+ */
5
+ type HonoCloudflareContextLike = {
6
+ req: {
7
+ raw: Request;
8
+ };
9
+ env: Env;
10
+ executionCtx: ExecutionContext;
11
+ get?: (key: string) => unknown;
12
+ set?: (key: string, value: unknown) => void;
13
+ };
14
+ type HonoMiddlewareHandler = (context: HonoCloudflareContextLike, next: () => Promise<void>) => Promise<Response | void>;
15
+ /**
16
+ * Hono middleware that applies Cloudflare-specific setup.
17
+ *
18
+ * Reads `env` and `executionCtx` from the Hono context (provided
19
+ * automatically by Hono on Cloudflare Workers). Handles static assets
20
+ * via the ASSETS binding, injects the SESSION KV binding, and sets
21
+ * `locals.cfContext`, client address, `waitUntil`, and error page fetch.
22
+ *
23
+ * If the request matches a static asset, returns the asset response
24
+ * directly. Otherwise calls `next()` to continue the middleware chain.
25
+ */
26
+ export declare function cf(): HonoMiddlewareHandler;
27
+ export {};
package/dist/hono.js ADDED
@@ -0,0 +1,21 @@
1
+ import { FetchState } from "astro/fetch";
2
+ import { cf as cfFetch } from "./fetch.js";
3
+ const FETCH_STATE_KEY = "fetchState";
4
+ function getFetchState(context) {
5
+ const state = context.get?.(FETCH_STATE_KEY);
6
+ if (state) return state;
7
+ const nextState = new FetchState(context.req.raw);
8
+ context.set?.(FETCH_STATE_KEY, nextState);
9
+ return nextState;
10
+ }
11
+ function cf() {
12
+ return async (context, next) => {
13
+ const state = getFetchState(context);
14
+ const asset = await cfFetch(state, context.env, context.executionCtx);
15
+ if (asset) return asset;
16
+ await next();
17
+ };
18
+ }
19
+ export {
20
+ cf
21
+ };
package/dist/index.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { createReadStream, existsSync, readFileSync } from "node:fs";
2
- import { appendFile, readFile, rename, stat } from "node:fs/promises";
2
+ import { appendFile, readFile, rename, stat, writeFile } from "node:fs/promises";
3
+ import { relative } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { normalizePath } from "vite";
3
6
  import { createInterface } from "node:readline/promises";
4
7
  import { removeLeadingForwardSlash } from "@astrojs/internal-helpers/path";
5
8
  import { createRedirectsFromAstroRoutes, printAsRedirects } from "@astrojs/underscore-redirects";
@@ -58,9 +61,9 @@ function createIntegration({
58
61
  ...cloudflareOptions
59
62
  } = {}) {
60
63
  let _config;
64
+ let _buildOutput;
61
65
  let _originalClientDir;
62
66
  let _routes;
63
- let _isFullyStatic = false;
64
67
  let cfPluginConfig;
65
68
  const { buildService, runtimeService } = normalizeImageServiceConfig(imageService);
66
69
  const needsImagesBinding = runtimeService === "cloudflare-binding";
@@ -98,7 +101,7 @@ function createIntegration({
98
101
  const needsImagesBindingForDev = isCompile && command === "dev";
99
102
  const usesContentCollections = hasContentCollectionsConfig(config.srcDir);
100
103
  const prebundleContentRuntime = command === "dev" && usesContentCollections;
101
- cfPluginConfig = {
104
+ const adapterPluginConfig = {
102
105
  config: cloudflareConfigCustomizer({
103
106
  needsSessionKVBinding,
104
107
  sessionKVBindingName,
@@ -124,8 +127,9 @@ function createIntegration({
124
127
  }
125
128
  }
126
129
  };
130
+ cfPluginConfig = { ...cloudflareOptions, ...adapterPluginConfig };
127
131
  if (command === "preview") {
128
- globalThis.astroCloudflareOptions = cfPluginConfig;
132
+ globalThis.astroCloudflareConfig = cfPluginConfig;
129
133
  }
130
134
  const prismFiles = [
131
135
  "@astrojs/prism > prismjs",
@@ -143,9 +147,9 @@ function createIntegration({
143
147
  plugins: [
144
148
  ...prerenderEnvironment === "node" && command === "dev" ? [createNodePrerenderPlugin()] : [],
145
149
  cfVitePlugin({
146
- ...cloudflareOptions,
147
150
  ...cfPluginConfig,
148
- viteEnvironment: { name: "ssr" }
151
+ viteEnvironment: { name: "ssr" },
152
+ assetsOnly: () => _buildOutput === "static"
149
153
  }),
150
154
  {
151
155
  name: "@astrojs/cloudflare:cf-imports",
@@ -266,11 +270,10 @@ function createIntegration({
266
270
  },
267
271
  "astro:routes:resolved": ({ routes }) => {
268
272
  _routes = routes;
269
- const nonInternalRoutes = routes.filter((route) => route.origin !== "internal");
270
- _isFullyStatic = nonInternalRoutes.length > 0 && nonInternalRoutes.every((route) => route.isPrerendered);
271
273
  },
272
- "astro:config:done": ({ setAdapter, config, injectTypes, logger }) => {
274
+ "astro:config:done": ({ setAdapter, config, injectTypes, logger, buildOutput }) => {
273
275
  _config = config;
276
+ _buildOutput = buildOutput;
274
277
  _originalClientDir = new URL(config.build.client.href);
275
278
  if (config.base !== "/") {
276
279
  config.build.client = new URL("." + config.base + "/", config.build.client);
@@ -282,9 +285,10 @@ function createIntegration({
282
285
  setAdapter({
283
286
  name: "@astrojs/cloudflare",
284
287
  adapterFeatures: {
285
- buildOutput: "server",
288
+ buildOutput,
286
289
  middlewareMode: "classic",
287
- preserveBuildClientDir: true
290
+ preserveBuildClientDir: true,
291
+ preserveBuildServerDir: true
288
292
  },
289
293
  entrypointResolution: "auto",
290
294
  previewEntrypoint: "@astrojs/cloudflare/entrypoints/preview",
@@ -319,7 +323,6 @@ function createIntegration({
319
323
  if (prerenderEnvironment === "workerd") {
320
324
  setPrerenderer(
321
325
  createCloudflarePrerenderer({
322
- cloudflareOptions,
323
326
  root: _config.root,
324
327
  serverDir: _config.build.server,
325
328
  clientDir: _config.build.client,
@@ -360,6 +363,18 @@ function createIntegration({
360
363
  } catch {
361
364
  }
362
365
  }
366
+ try {
367
+ const wranglerJsonUrl = new URL("./wrangler.json", _config.build.server);
368
+ const raw = await readFile(wranglerJsonUrl, "utf-8");
369
+ const wranglerConfig = JSON.parse(raw);
370
+ if (wranglerConfig.assets?.directory) {
371
+ wranglerConfig.assets.directory = normalizePath(
372
+ relative(fileURLToPath(_config.build.server), fileURLToPath(_originalClientDir))
373
+ );
374
+ await writeFile(wranglerJsonUrl, JSON.stringify(wranglerConfig));
375
+ }
376
+ } catch {
377
+ }
363
378
  }
364
379
  let redirectsExists = false;
365
380
  try {
@@ -395,7 +410,7 @@ function createIntegration({
395
410
  )
396
411
  ),
397
412
  dir,
398
- buildOutput: _isFullyStatic ? "static" : "server",
413
+ buildOutput: _buildOutput,
399
414
  assets
400
415
  });
401
416
  if (!trueRedirects.empty()) {
@@ -1,7 +1,6 @@
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>;
5
4
  root: AstroConfig['root'];
6
5
  serverDir: AstroConfig['build']['server'];
7
6
  clientDir: AstroConfig['build']['client'];
@@ -14,5 +13,5 @@ interface CloudflarePrerendererOptions {
14
13
  * Creates a prerenderer that uses Cloudflare's workerd runtime via a preview server.
15
14
  * This allows prerendering to happen in the same runtime that will serve the pages.
16
15
  */
17
- export declare function createCloudflarePrerenderer({ cloudflareOptions, root, serverDir, clientDir, base, trailingSlash, cfPluginConfig, hasCompileImageService, }: CloudflarePrerendererOptions): AstroPrerenderer;
16
+ export declare function createCloudflarePrerenderer({ root, serverDir, clientDir, base, trailingSlash, cfPluginConfig, hasCompileImageService, }: CloudflarePrerendererOptions): AstroPrerenderer;
18
17
  export {};
@@ -9,7 +9,6 @@ import {
9
9
  STATIC_IMAGES_ENDPOINT
10
10
  } from "./utils/prerender-constants.js";
11
11
  function createCloudflarePrerenderer({
12
- cloudflareOptions,
13
12
  root,
14
13
  serverDir,
15
14
  clientDir,
@@ -49,13 +48,7 @@ function createCloudflarePrerenderer({
49
48
  // Let the OS pick a free port
50
49
  open: false
51
50
  },
52
- plugins: [
53
- cfVitePlugin({
54
- ...cloudflareOptions,
55
- ...cfPluginConfig,
56
- viteEnvironment: { name: "prerender" }
57
- })
58
- ]
51
+ plugins: [cfVitePlugin({ ...cfPluginConfig, viteEnvironment: { name: "prerender" } })]
59
52
  });
60
53
  const address = previewServer.httpServer.address();
61
54
  if (address && typeof address === "object") {
@@ -0,0 +1,33 @@
1
+ export interface Runtime {
2
+ cfContext: ExecutionContext;
3
+ }
4
+ /** Minimal manifest shape needed by the Cloudflare helpers. */
5
+ export interface ManifestLike {
6
+ assets: Set<string>;
7
+ sessionConfig?: {
8
+ options?: Record<string, unknown>;
9
+ } | undefined;
10
+ }
11
+ /**
12
+ * Returns a `Response` from the ASSETS binding if the request pathname
13
+ * is a known static asset. Returns `undefined` otherwise.
14
+ */
15
+ export declare function matchStaticAsset(manifest: ManifestLike, requestUrl: string, env: Env): Response | undefined;
16
+ /**
17
+ * Tries the ASSETS binding as a fallback for an unmatched route.
18
+ * Returns the asset `Response` if found (non-404), `undefined` otherwise.
19
+ */
20
+ export declare function fallbackToAssets(requestUrl: string, env: Env): Promise<Response | undefined>;
21
+ /**
22
+ * Creates a fetch function for prerendered error pages via the ASSETS binding.
23
+ */
24
+ export declare function createErrorPageFetch(env: Env): (url: string) => Promise<Response>;
25
+ /**
26
+ * Creates the Cloudflare-specific locals object with `cfContext`
27
+ * and deprecated `runtime` property getters.
28
+ */
29
+ export declare function createLocals(ctx: ExecutionContext): Runtime;
30
+ /**
31
+ * Extracts the client IP address from the `cf-connecting-ip` header.
32
+ */
33
+ export declare function getClientAddress(request: Request): string | undefined;
@@ -0,0 +1,63 @@
1
+ import { getValidatedIpFromHeader } from "@astrojs/internal-helpers/request";
2
+ function matchStaticAsset(manifest, requestUrl, env) {
3
+ const { pathname } = new URL(requestUrl);
4
+ if (manifest.assets.has(pathname)) {
5
+ return env.ASSETS.fetch(requestUrl.replace(/\.html$/, ""));
6
+ }
7
+ return void 0;
8
+ }
9
+ async function fallbackToAssets(requestUrl, env) {
10
+ const asset = await env.ASSETS.fetch(
11
+ requestUrl.replace(/index.html$/, "").replace(/\.html$/, "")
12
+ );
13
+ if (asset.status !== 404) {
14
+ return asset;
15
+ }
16
+ return void 0;
17
+ }
18
+ function createErrorPageFetch(env) {
19
+ return async (url) => {
20
+ return env.ASSETS.fetch(url.replace(/\.html$/, ""));
21
+ };
22
+ }
23
+ function createLocals(ctx) {
24
+ const locals = {
25
+ cfContext: ctx
26
+ };
27
+ Object.defineProperty(locals, "runtime", {
28
+ enumerable: false,
29
+ value: {
30
+ get env() {
31
+ throw new Error(
32
+ `Astro.locals.runtime.env has been removed in Astro v6. Use 'import { env } from "cloudflare:workers"' instead.`
33
+ );
34
+ },
35
+ get cf() {
36
+ throw new Error(
37
+ `Astro.locals.runtime.cf has been removed in Astro v6. Use 'Astro.request.cf' instead.`
38
+ );
39
+ },
40
+ get caches() {
41
+ throw new Error(
42
+ `Astro.locals.runtime.caches has been removed in Astro v6. Use the global 'caches' object instead.`
43
+ );
44
+ },
45
+ get ctx() {
46
+ throw new Error(
47
+ `Astro.locals.runtime.ctx has been removed in Astro v6. Use 'Astro.locals.cfContext' instead.`
48
+ );
49
+ }
50
+ }
51
+ });
52
+ return locals;
53
+ }
54
+ function getClientAddress(request) {
55
+ return getValidatedIpFromHeader(request.headers.get("cf-connecting-ip"));
56
+ }
57
+ export {
58
+ createErrorPageFetch,
59
+ createLocals,
60
+ fallbackToAssets,
61
+ getClientAddress,
62
+ matchStaticAsset
63
+ };
@@ -0,0 +1,8 @@
1
+ import type { ManifestLike } from './cf-helpers.js';
2
+ export type { Runtime, ManifestLike } from './cf-helpers.js';
3
+ export { matchStaticAsset, fallbackToAssets, createErrorPageFetch, createLocals, getClientAddress, } from './cf-helpers.js';
4
+ /**
5
+ * Injects the SESSION KV binding into the app manifest's session config.
6
+ * Idempotent — safe to call on every request.
7
+ */
8
+ export declare function injectSessionBinding(manifest: ManifestLike, env: Env): void;
@@ -0,0 +1,24 @@
1
+ import { sessionKVBindingName } from "virtual:astro-cloudflare:config";
2
+ import {
3
+ matchStaticAsset,
4
+ fallbackToAssets,
5
+ createErrorPageFetch,
6
+ createLocals,
7
+ getClientAddress
8
+ } from "./cf-helpers.js";
9
+ function injectSessionBinding(manifest, env) {
10
+ if (env[sessionKVBindingName]) {
11
+ const sessionConfigOptions = manifest.sessionConfig?.options ?? {};
12
+ Object.assign(sessionConfigOptions, {
13
+ binding: env[sessionKVBindingName]
14
+ });
15
+ }
16
+ }
17
+ export {
18
+ createErrorPageFetch,
19
+ createLocals,
20
+ fallbackToAssets,
21
+ getClientAddress,
22
+ injectSessionBinding,
23
+ matchStaticAsset
24
+ };
@@ -1,9 +1,7 @@
1
- export interface Runtime {
2
- cfContext: ExecutionContext;
3
- }
1
+ import { type Runtime } from './cf.js';
2
+ export type { Runtime };
4
3
  declare global {
5
4
  var __ASTRO_IMAGES_BINDING_NAME: string;
6
5
  }
7
6
  type CfResponse = Awaited<ReturnType<Required<ExportedHandler<Env>>['fetch']>>;
8
7
  export declare function handle(request: Request, env: Env, context: ExecutionContext): Promise<CfResponse>;
9
- export {};
@@ -1,9 +1,5 @@
1
1
  import { env as globalEnv } from "cloudflare:workers";
2
- import {
3
- sessionKVBindingName,
4
- compileImageConfig,
5
- isPrerender
6
- } from "virtual:astro-cloudflare:config";
2
+ import { compileImageConfig, isPrerender } from "virtual:astro-cloudflare:config";
7
3
  import { createApp } from "astro/app/entrypoint";
8
4
  import { setGetEnv } from "astro/env/setup";
9
5
  import { createGetEnv } from "../utils/env.js";
@@ -15,7 +11,14 @@ import {
15
11
  isStaticImagesRequest,
16
12
  handleStaticImagesRequest
17
13
  } from "./prerender.js";
18
- import { getValidatedIpFromHeader } from "@astrojs/internal-helpers/request";
14
+ import {
15
+ injectSessionBinding,
16
+ matchStaticAsset,
17
+ fallbackToAssets,
18
+ createErrorPageFetch,
19
+ createLocals,
20
+ getClientAddress
21
+ } from "./cf.js";
19
22
  setGetEnv(createGetEnv(globalEnv));
20
23
  const app = createApp();
21
24
  async function handle(request, env, context) {
@@ -34,16 +37,9 @@ async function handle(request, env, context) {
34
37
  return handleStaticImagesRequest();
35
38
  }
36
39
  }
37
- const { pathname: requestPathname } = new URL(request.url);
38
- if (env[sessionKVBindingName]) {
39
- const sessionConfigOptions = app.manifest.sessionConfig?.options ?? {};
40
- Object.assign(sessionConfigOptions, {
41
- binding: env[sessionKVBindingName]
42
- });
43
- }
44
- if (app.manifest.assets.has(requestPathname)) {
45
- return env.ASSETS.fetch(request.url.replace(/\.html$/, ""));
46
- }
40
+ injectSessionBinding(app.manifest, env);
41
+ const staticAsset = matchStaticAsset(app.manifest, request.url, env);
42
+ if (staticAsset) return staticAsset;
47
43
  let routeData = void 0;
48
44
  if (app.isDev()) {
49
45
  const result = await app.devMatch(app.getPathnameFromRequest(request));
@@ -54,50 +50,17 @@ async function handle(request, env, context) {
54
50
  routeData = app.match(request);
55
51
  }
56
52
  if (!routeData) {
57
- const asset = await env.ASSETS.fetch(
58
- request.url.replace(/index.html$/, "").replace(/\.html$/, "")
59
- );
60
- if (asset.status !== 404) {
61
- return asset;
62
- }
53
+ const asset = await fallbackToAssets(request.url, env);
54
+ if (asset) return asset;
63
55
  }
64
- const locals = {
65
- cfContext: context
66
- };
67
- Object.defineProperty(locals, "runtime", {
68
- enumerable: false,
69
- value: {
70
- get env() {
71
- throw new Error(
72
- `Astro.locals.runtime.env has been removed in Astro v6. Use 'import { env } from "cloudflare:workers"' instead.`
73
- );
74
- },
75
- get cf() {
76
- throw new Error(
77
- `Astro.locals.runtime.cf has been removed in Astro v6. Use 'Astro.request.cf' instead.`
78
- );
79
- },
80
- get caches() {
81
- throw new Error(
82
- `Astro.locals.runtime.caches has been removed in Astro v6. Use the global 'caches' object instead.`
83
- );
84
- },
85
- get ctx() {
86
- throw new Error(
87
- `Astro.locals.runtime.ctx has been removed in Astro v6. Use 'Astro.locals.cfContext' instead.`
88
- );
89
- }
90
- }
91
- });
56
+ const locals = createLocals(context);
92
57
  const waitUntil = context.waitUntil.bind(context);
93
58
  const response = await app.render(request, {
94
59
  routeData,
95
60
  locals,
96
61
  waitUntil,
97
- prerenderedErrorPageFetch: async (url) => {
98
- return env.ASSETS.fetch(url.replace(/\.html$/, ""));
99
- },
100
- clientAddress: getValidatedIpFromHeader(request.headers.get("cf-connecting-ip"))
62
+ prerenderedErrorPageFetch: createErrorPageFetch(env),
63
+ clientAddress: getClientAddress(request)
101
64
  });
102
65
  if (app.setCookieHeaders) {
103
66
  for (const setCookieHeader of app.setCookieHeaders(response)) {
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.4",
4
+ "version": "13.6.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -27,6 +27,8 @@
27
27
  "./image-passthrough-endpoint": "./dist/entrypoints/image-passthrough-endpoint.js",
28
28
  "./image-service-workerd": "./dist/entrypoints/image-service-workerd.js",
29
29
  "./handler": "./dist/utils/handler.js",
30
+ "./fetch": "./dist/fetch.js",
31
+ "./hono": "./dist/hono.js",
30
32
  "./types.d.ts": "./types.d.ts",
31
33
  "./package.json": "./package.json"
32
34
  },
@@ -35,11 +37,11 @@
35
37
  "types.d.ts"
36
38
  ],
37
39
  "dependencies": {
38
- "@cloudflare/vite-plugin": "^1.32.3",
40
+ "@cloudflare/vite-plugin": "^1.39.0",
39
41
  "piccolore": "^0.1.3",
40
42
  "tinyglobby": "^0.2.15",
41
43
  "vite": "^7.3.2",
42
- "@astrojs/internal-helpers": "0.9.1",
44
+ "@astrojs/internal-helpers": "0.10.0",
43
45
  "@astrojs/underscore-redirects": "1.0.3"
44
46
  },
45
47
  "peerDependencies": {
@@ -53,7 +55,7 @@
53
55
  "cheerio": "1.2.0",
54
56
  "devalue": "^5.6.3",
55
57
  "prismjs": "^1.30.0",
56
- "astro": "6.3.7",
58
+ "astro": "6.4.0",
57
59
  "astro-scripts": "0.0.14"
58
60
  },
59
61
  "publishConfig": {