@astrojs/cloudflare 14.0.0-beta.3 → 14.0.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.
@@ -0,0 +1,10 @@
1
+ import type { CacheProviderConfig } from 'astro';
2
+ /**
3
+ * Configure the Cloudflare Workers cache provider for Astro route caching.
4
+ *
5
+ * Uses `Cloudflare-CDN-Cache-Control` and `Cache-Tag` headers for
6
+ * Cloudflare's built-in Worker caching layer. Responses are auto-tagged
7
+ * with the request path so that both tag-based and path-based invalidation
8
+ * are implemented via tag purging through the Worker cache API.
9
+ */
10
+ export declare function cacheCloudflare(): CacheProviderConfig;
@@ -0,0 +1,9 @@
1
+ function cacheCloudflare() {
2
+ return {
3
+ name: "cloudflare",
4
+ entrypoint: "@astrojs/cloudflare/cache/provider"
5
+ };
6
+ }
7
+ export {
8
+ cacheCloudflare
9
+ };
@@ -0,0 +1,3 @@
1
+ import type { CacheProviderFactory } from 'astro';
2
+ declare const factory: CacheProviderFactory;
3
+ export default factory;
@@ -0,0 +1,35 @@
1
+ import {
2
+ buildCacheControlDirectives,
3
+ collectInvalidationTags,
4
+ pathTag,
5
+ setConditionalHeaders
6
+ } from "astro/cache/provider-utils";
7
+ const factory = () => {
8
+ return {
9
+ name: "cloudflare",
10
+ setHeaders(options, request) {
11
+ const headers = new Headers();
12
+ const directives = buildCacheControlDirectives(options, ["public"]);
13
+ if (directives) {
14
+ headers.set("Cloudflare-CDN-Cache-Control", directives);
15
+ }
16
+ const tags = [...options.tags ?? []];
17
+ const { pathname } = new URL(request.url);
18
+ tags.push(pathTag(pathname));
19
+ headers.set("Cache-Tag", tags.join(","));
20
+ setConditionalHeaders(headers, options);
21
+ return headers;
22
+ },
23
+ async invalidate(options) {
24
+ const { cache } = await import("cloudflare:workers");
25
+ const tags = collectInvalidationTags(options);
26
+ if (tags.length > 0) {
27
+ await cache.purge({ tags });
28
+ }
29
+ }
30
+ };
31
+ };
32
+ var provider_default = factory;
33
+ export {
34
+ provider_default as default
35
+ };
@@ -88,7 +88,7 @@ function serverStart({
88
88
  host,
89
89
  base
90
90
  }) {
91
- const version = "14.0.0-beta.3";
91
+ const version = "14.0.0";
92
92
  const localPrefix = `${colors.dim("\u2503")} Local `;
93
93
  const networkPrefix = `${colors.dim("\u2503")} Network `;
94
94
  const emptyPrefix = " ".repeat(11);
package/dist/index.js CHANGED
@@ -106,11 +106,13 @@ function createIntegration({
106
106
  const usesContentCollections = hasContentCollectionsConfig(config.srcDir);
107
107
  const prebundleContentRuntime = command === "dev" && usesContentCollections;
108
108
  const isTypeGenPhase = command === "build" || command === "sync";
109
+ const needsWorkerCache = config.cache?.provider?.name === "cloudflare";
109
110
  const adapterPluginConfig = {
110
111
  config: cloudflareConfigCustomizer({
111
112
  needsSessionKVBinding,
112
113
  sessionKVBindingName,
113
- imagesBindingName: needsImagesBinding || needsImagesBindingForDev ? imagesBindingName : false
114
+ imagesBindingName: needsImagesBinding || needsImagesBindingForDev ? imagesBindingName : false,
115
+ needsWorkerCache
114
116
  }),
115
117
  ...prerenderEnvironment === "workerd" && {
116
118
  experimental: {
@@ -270,7 +272,8 @@ function createIntegration({
270
272
  assetsPrefix: typeof config.build.assetsPrefix === "string" ? config.build.assetsPrefix : void 0,
271
273
  imageServiceEntrypoint: "@astrojs/cloudflare/image-service-workerd",
272
274
  buildAssets: config.build.assets ?? "_astro"
273
- } : null
275
+ } : null,
276
+ cacheProviderEnabled: needsWorkerCache
274
277
  }),
275
278
  cfPrismPlugin()
276
279
  ]
@@ -1,5 +1,9 @@
1
1
  import { env as globalEnv } from "cloudflare:workers";
2
- import { compileImageConfig, isPrerender } from "virtual:astro-cloudflare:config";
2
+ import {
3
+ compileImageConfig,
4
+ isPrerender,
5
+ cacheProviderEnabled
6
+ } from "virtual:astro-cloudflare:config";
3
7
  import { createApp } from "astro/app/entrypoint";
4
8
  import { setGetEnv } from "astro/env/setup";
5
9
  import { createGetEnv } from "../utils/env.js";
@@ -67,6 +71,9 @@ async function handle(request, env, context) {
67
71
  response.headers.append("Set-Cookie", setCookieHeader);
68
72
  }
69
73
  }
74
+ if (cacheProviderEnabled && !response.headers.has("Cloudflare-CDN-Cache-Control")) {
75
+ response.headers.set("Cloudflare-CDN-Cache-Control", "no-store");
76
+ }
70
77
  return response;
71
78
  }
72
79
  export {
@@ -9,5 +9,12 @@ export interface Config {
9
9
  sessionKVBindingName: string;
10
10
  compileImageConfig: CompileImageConfig | null;
11
11
  isPrerender: boolean;
12
+ /**
13
+ * True when the user has configured the Cloudflare cache provider.
14
+ * Used by the request handler to default uncached responses to
15
+ * `Cloudflare-CDN-Cache-Control: no-store`, so that opting in to the
16
+ * cache provider never accidentally caches routes that don't use it.
17
+ */
18
+ cacheProviderEnabled: boolean;
12
19
  }
13
20
  export declare function createConfigPlugin(config: Omit<Config, 'isPrerender'>): PluginOption;
@@ -6,6 +6,7 @@ interface CloudflareConfigOptions {
6
6
  sessionKVBindingName?: string | undefined;
7
7
  needsSessionKVBinding?: boolean;
8
8
  imagesBindingName?: string | false | undefined;
9
+ needsWorkerCache?: boolean;
9
10
  }
10
11
  /**
11
12
  * Returns a config customizer that sets up the Astro Cloudflare defaults.
package/dist/wrangler.js CHANGED
@@ -6,6 +6,7 @@ function cloudflareConfigCustomizer(options) {
6
6
  const sessionKVBindingName = options?.sessionKVBindingName ?? DEFAULT_SESSION_KV_BINDING_NAME;
7
7
  const needsSessionKVBinding = options?.needsSessionKVBinding ?? true;
8
8
  const imagesBindingName = options?.imagesBindingName === false ? void 0 : options?.imagesBindingName ?? DEFAULT_IMAGES_BINDING_NAME;
9
+ const needsWorkerCache = options?.needsWorkerCache ?? false;
9
10
  const customizer = (config) => {
10
11
  const getNonInheritableBindings = (nonInheritableConfig) => {
11
12
  const hasSessionBinding = nonInheritableConfig?.kv_namespaces?.some(
@@ -27,6 +28,8 @@ function cloudflareConfigCustomizer(options) {
27
28
  assets: hasAssetsBinding ? void 0 : {
28
29
  binding: DEFAULT_ASSETS_BINDING_NAME
29
30
  },
31
+ // Enable the Worker caching layer when a Cloudflare cache provider is configured
32
+ cache: needsWorkerCache && !config.cache?.enabled ? { enabled: true } : void 0,
30
33
  previews: getNonInheritableBindings(config.previews)
31
34
  };
32
35
  };
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": "14.0.0-beta.3",
4
+ "version": "14.0.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -26,6 +26,8 @@
26
26
  "./image-transform-endpoint": "./dist/entrypoints/image-transform-endpoint.js",
27
27
  "./image-passthrough-endpoint": "./dist/entrypoints/image-passthrough-endpoint.js",
28
28
  "./image-service-workerd": "./dist/entrypoints/image-service-workerd.js",
29
+ "./cache": "./dist/cache/index.js",
30
+ "./cache/provider": "./dist/cache/provider.js",
29
31
  "./handler": "./dist/utils/handler.js",
30
32
  "./fetch": "./dist/fetch.js",
31
33
  "./hono": "./dist/hono.js",
@@ -55,7 +57,7 @@
55
57
  "cheerio": "1.2.0",
56
58
  "devalue": "^5.8.1",
57
59
  "prismjs": "^1.30.0",
58
- "astro": "7.0.0-beta.6",
60
+ "astro": "7.0.0",
59
61
  "astro-scripts": "0.0.14"
60
62
  },
61
63
  "publishConfig": {