@astrojs/cloudflare 13.3.0 → 13.4.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.
@@ -2,6 +2,7 @@ import { imageConfig } from "astro:assets";
2
2
  import { isRemotePath } from "@astrojs/internal-helpers/path";
3
3
  import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
4
4
  import { env } from "cloudflare:workers";
5
+ import { fetchWithRedirects } from "astro/assets";
5
6
  const prerender = false;
6
7
  const GET = async ({ request }) => {
7
8
  try {
@@ -14,7 +15,10 @@ const GET = async ({ request }) => {
14
15
  if (!isRemoteAllowed(href, imageConfig)) {
15
16
  return new Response("Forbidden", { status: 403 });
16
17
  }
17
- response = await fetch(href, { redirect: "manual" });
18
+ response = await fetchWithRedirects({
19
+ url: href,
20
+ imageConfig
21
+ });
18
22
  } else {
19
23
  const sourceUrl = new URL(href, url.origin);
20
24
  if (sourceUrl.origin !== url.origin) {
@@ -88,7 +88,7 @@ function serverStart({
88
88
  host,
89
89
  base
90
90
  }) {
91
- const version = "13.3.0";
91
+ const version = "13.4.0";
92
92
  const localPrefix = `${colors.dim("\u2503")} Local `;
93
93
  const networkPrefix = `${colors.dim("\u2503")} Network `;
94
94
  const emptyPrefix = " ".repeat(11);
@@ -1,5 +1,12 @@
1
1
  import { readFile } from "node:fs/promises";
2
2
  const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
3
+ const RETURN_REPLACE_RE = /(\/\/[^\n]*|\/\*[\s\S]*?\*\/|`(?:[^`\\]|\\.)*`|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')|(?<!\.)\breturn(\s*;|\b)/g;
4
+ function replaceTopLevelReturns(code) {
5
+ return code.replace(RETURN_REPLACE_RE, (_match, skip, tail) => {
6
+ if (skip !== void 0) return skip;
7
+ return tail.trim() === ";" ? "throw 0;" : "throw ";
8
+ });
9
+ }
3
10
  function astroFrontmatterScanPlugin() {
4
11
  return {
5
12
  name: "astro-frontmatter-scan",
@@ -9,7 +16,7 @@ function astroFrontmatterScanPlugin() {
9
16
  const code = await readFile(args.path, "utf-8");
10
17
  const frontmatterMatch = FRONTMATTER_RE.exec(code);
11
18
  if (frontmatterMatch) {
12
- const contents = frontmatterMatch[1].replace(/\breturn\s*;/g, "throw 0;").replace(/\breturn\b/g, "throw ");
19
+ const contents = replaceTopLevelReturns(frontmatterMatch[1]);
13
20
  return {
14
21
  contents: contents + "\nexport default {}",
15
22
  loader: "ts"
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createReadStream, existsSync, readFileSync } from "node:fs";
2
- import { appendFile, stat } from "node:fs/promises";
2
+ import { appendFile, 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";
@@ -57,6 +57,7 @@ function createIntegration({
57
57
  ...cloudflareOptions
58
58
  } = {}) {
59
59
  let _config;
60
+ let _originalClientDir;
60
61
  let _routes;
61
62
  let _isFullyStatic = false;
62
63
  let cfPluginConfig;
@@ -177,6 +178,7 @@ function createIntegration({
177
178
  "astro > piccolore",
178
179
  "astro > picomatch",
179
180
  "astro/app",
181
+ "astro/app/fetch/default-handler",
180
182
  "astro/assets",
181
183
  "astro/assets/runtime",
182
184
  "astro/assets/utils/inferRemoteSize.js",
@@ -256,6 +258,10 @@ function createIntegration({
256
258
  },
257
259
  "astro:config:done": ({ setAdapter, config, injectTypes, logger }) => {
258
260
  _config = config;
261
+ _originalClientDir = new URL(config.build.client.href);
262
+ if (config.base !== "/") {
263
+ config.build.client = new URL("." + config.base + "/", config.build.client);
264
+ }
259
265
  injectTypes({
260
266
  filename: "cloudflare.d.ts",
261
267
  content: '/// <reference types="@astrojs/cloudflare/types.d.ts" />'
@@ -330,9 +336,20 @@ function createIntegration({
330
336
  }
331
337
  },
332
338
  "astro:build:done": async ({ dir, logger, assets }) => {
339
+ if (_config.base !== "/") {
340
+ for (const file of [".assetsignore", "_headers"]) {
341
+ try {
342
+ await rename(
343
+ new URL(`./${file}`, _config.build.client),
344
+ new URL(`./${file}`, _originalClientDir)
345
+ );
346
+ } catch {
347
+ }
348
+ }
349
+ }
333
350
  let redirectsExists = false;
334
351
  try {
335
- const redirectsStat = await stat(new URL("./_redirects", _config.build.client));
352
+ const redirectsStat = await stat(new URL("./_redirects", _originalClientDir));
336
353
  if (redirectsStat.isFile()) {
337
354
  redirectsExists = true;
338
355
  }
@@ -342,7 +359,7 @@ function createIntegration({
342
359
  const redirects = [];
343
360
  if (redirectsExists) {
344
361
  const rl = createInterface({
345
- input: createReadStream(new URL("./_redirects", _config.build.client)),
362
+ input: createReadStream(new URL("./_redirects", _originalClientDir)),
346
363
  crlfDelay: Number.POSITIVE_INFINITY
347
364
  });
348
365
  for await (const line of rl) {
@@ -370,7 +387,7 @@ function createIntegration({
370
387
  if (!trueRedirects.empty()) {
371
388
  try {
372
389
  await appendFile(
373
- new URL("./_redirects", _config.build.client),
390
+ new URL("./_redirects", _originalClientDir),
374
391
  printAsRedirects(trueRedirects)
375
392
  );
376
393
  } catch (_error) {
@@ -1,6 +1,7 @@
1
1
  import { imageConfig } from "astro:assets";
2
2
  import { isRemotePath } from "@astrojs/internal-helpers/path";
3
3
  import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
4
+ import { fetchWithRedirects } from "astro/assets";
4
5
  const qualityTable = {
5
6
  low: 25,
6
7
  mid: 50,
@@ -14,9 +15,21 @@ async function transform(rawUrl, images, assets) {
14
15
  return new Response("Forbidden", { status: 403 });
15
16
  }
16
17
  const imageSrc = new URL(href, url.origin);
17
- const content = await (isRemotePath(href) ? fetch(imageSrc, { redirect: "manual" }) : assets.fetch(imageSrc));
18
- if (content.status >= 300 && content.status < 400) {
19
- return new Response("Not Found", { status: 404 });
18
+ let content;
19
+ if (isRemotePath(href)) {
20
+ try {
21
+ content = await fetchWithRedirects({
22
+ url: imageSrc,
23
+ imageConfig
24
+ });
25
+ if (!isRemoteAllowed(content.url, imageConfig)) {
26
+ return new Response("Forbidden", { status: 403 });
27
+ }
28
+ } catch {
29
+ return new Response("Not Found", { status: 404 });
30
+ }
31
+ } else {
32
+ content = await assets.fetch(imageSrc);
20
33
  }
21
34
  if (!content.body) {
22
35
  return new Response(null, { status: 404 });
@@ -16,6 +16,7 @@ export declare function setImageConfig(service: ImageServiceConfig | undefined,
16
16
  endpoint: {
17
17
  entrypoint: string;
18
18
  };
19
+ dangerouslyProcessSVG: boolean;
19
20
  domains: string[];
20
21
  remotePatterns: {
21
22
  protocol?: string | undefined;
@@ -34,6 +35,7 @@ export declare function setImageConfig(service: ImageServiceConfig | undefined,
34
35
  route: string;
35
36
  entrypoint?: string | undefined;
36
37
  };
38
+ dangerouslyProcessSVG: boolean;
37
39
  domains: string[];
38
40
  remotePatterns: {
39
41
  protocol?: string | undefined;
package/dist/wrangler.js CHANGED
@@ -2,6 +2,11 @@ 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
+ }
5
10
  function cloudflareConfigCustomizer(options) {
6
11
  const sessionKVBindingName = options?.sessionKVBindingName ?? DEFAULT_SESSION_KV_BINDING_NAME;
7
12
  const needsSessionKVBinding = options?.needsSessionKVBinding ?? true;
@@ -13,11 +18,7 @@ function cloudflareConfigCustomizer(options) {
13
18
  );
14
19
  const hasImagesBinding = nonInheritableConfig?.images?.binding !== void 0;
15
20
  return {
16
- kv_namespaces: !needsSessionKVBinding || hasSessionBinding ? void 0 : [
17
- {
18
- binding: sessionKVBindingName
19
- }
20
- ],
21
+ kv_namespaces: !needsSessionKVBinding || hasSessionBinding ? void 0 : withSessionKVBinding(nonInheritableConfig?.kv_namespaces, sessionKVBindingName),
21
22
  images: hasImagesBinding || !imagesBindingName ? void 0 : {
22
23
  binding: imagesBindingName
23
24
  }
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.3.0",
4
+ "version": "13.4.0",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -39,8 +39,8 @@
39
39
  "piccolore": "^0.1.3",
40
40
  "tinyglobby": "^0.2.15",
41
41
  "vite": "^7.3.2",
42
- "@astrojs/underscore-redirects": "1.0.3",
43
- "@astrojs/internal-helpers": "0.9.0"
42
+ "@astrojs/internal-helpers": "0.9.0",
43
+ "@astrojs/underscore-redirects": "1.0.3"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "astro": "^6.0.0",
@@ -51,7 +51,7 @@
51
51
  "@types/node": "^25.2.2",
52
52
  "cheerio": "1.2.0",
53
53
  "devalue": "^5.6.3",
54
- "astro": "6.2.0",
54
+ "astro": "6.3.0",
55
55
  "astro-scripts": "0.0.14"
56
56
  },
57
57
  "publishConfig": {
@@ -59,9 +59,8 @@
59
59
  },
60
60
  "scripts": {
61
61
  "dev": "astro-scripts dev \"src/**/*.ts\"",
62
- "build": "astro-scripts build \"src/**/*.ts\" --clean-dts && tsc",
62
+ "build": "astro-scripts build \"src/**/*.ts\" --clean-dts && tsc -b",
63
63
  "build:ci": "astro-scripts build \"src/**/*.ts\"",
64
- "test": "astro-scripts test --force-exit \"test/**/*.test.ts\"",
65
- "typecheck:tests": "tsc --build tsconfig.test.json"
64
+ "test": "astro-scripts test --force-exit \"test/**/*.test.ts\""
66
65
  }
67
66
  }