Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

Commit 83cedad

Browse files
chore: update adapters to better support astro v5 (#454)
Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
1 parent d7e7d5e commit 83cedad

File tree

10 files changed

+609
-468
lines changed

10 files changed

+609
-468
lines changed

.changeset/small-bikes-decide.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@astrojs/cloudflare': patch
3+
'@astrojs/test-utils': patch
4+
'@astrojs/netlify': patch
5+
'@astrojs/vercel': patch
6+
'@astrojs/node': patch
7+
---
8+
9+
Improves Astro 5 support

packages/cloudflare/package.json

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
"@astrojs/internal-helpers": "0.4.2",
3232
"@astrojs/underscore-redirects": "^0.5.0",
3333
"@cloudflare/workers-types": "^4.20241230.0",
34-
"@inox-tools/astro-when": "^1.0.2",
3534
"esbuild": "^0.24.0",
3635
"estree-walker": "^3.0.3",
3736
"magic-string": "^0.30.17",
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,12 @@
1-
import { When, whenAmI } from '@it-astro:when';
21
import type { MiddlewareHandler } from 'astro';
32

4-
const middlewares: Record<When, MiddlewareHandler> = {
5-
[When.Client]: () => {
6-
throw new Error('Client should not run a middleware!');
7-
},
8-
[When.DevServer]: (_, next) => next(),
9-
[When.Server]: (_, next) => next(),
10-
[When.Prerender]: (ctx, next) => {
3+
export const onRequest: MiddlewareHandler = (context, next) => {
4+
if (context.isPrerendered) {
115
// @ts-expect-error
12-
if (ctx.locals.runtime === undefined) {
13-
// @ts-expect-error
14-
ctx.locals.runtime = {
15-
env: process.env,
16-
};
17-
}
18-
return next();
19-
},
20-
[When.StaticBuild]: (_, next) => next(),
21-
};
6+
context.locals.runtime ??= {
7+
env: process.env,
8+
};
9+
}
2210

23-
export const onRequest = middlewares[whenAmI];
11+
return next();
12+
};

packages/cloudflare/src/index.ts

+46-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import type { AstroConfig, AstroIntegration, HookParameters, IntegrationRouteData } from 'astro';
1+
import type {
2+
AstroConfig,
3+
AstroIntegration,
4+
HookParameters,
5+
IntegrationResolvedRoute,
6+
IntegrationRouteData,
7+
} from 'astro';
28
import type { PluginOption } from 'vite';
39

410
import { createReadStream } from 'node:fs';
@@ -10,7 +16,6 @@ import {
1016
removeLeadingForwardSlash,
1117
} from '@astrojs/internal-helpers/path';
1218
import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
13-
import astroWhen from '@inox-tools/astro-when';
1419
import { AstroError } from 'astro/errors';
1520
import { defaultClientConditions } from 'vite';
1621
import { type GetPlatformProxyOptions, getPlatformProxy } from 'wrangler';
@@ -86,6 +91,28 @@ function setProcessEnv(config: AstroConfig, env: Record<string, unknown>) {
8691
}
8792
}
8893

94+
function resolvedRouteToRouteData(
95+
assets: HookParameters<'astro:build:done'>['assets'],
96+
route: IntegrationResolvedRoute
97+
): IntegrationRouteData {
98+
return {
99+
pattern: route.patternRegex,
100+
component: route.entrypoint,
101+
prerender: route.isPrerendered,
102+
route: route.pattern,
103+
generate: route.generate,
104+
params: route.params,
105+
segments: route.segments,
106+
type: route.type,
107+
pathname: route.pathname,
108+
redirect: route.redirect,
109+
distURL: assets.get(route.pattern),
110+
redirectRoute: route.redirectRoute
111+
? resolvedRouteToRouteData(assets, route.redirectRoute)
112+
: undefined,
113+
};
114+
}
115+
89116
export default function createIntegration(args?: Options): AstroIntegration {
90117
let _config: AstroConfig;
91118
let finalBuildOutput: HookParameters<'astro:config:done'>['buildOutput'];
@@ -94,6 +121,8 @@ export default function createIntegration(args?: Options): AstroIntegration {
94121
args?.cloudflareModules ?? true
95122
);
96123

124+
let _routes: IntegrationResolvedRoute[];
125+
97126
return {
98127
name: '@astrojs/cloudflare',
99128
hooks: {
@@ -129,7 +158,6 @@ export default function createIntegration(args?: Options): AstroIntegration {
129158
},
130159
],
131160
},
132-
integrations: [astroWhen()],
133161
image: setImageConfig(args?.imageService ?? 'compile', config.image, command, logger),
134162
});
135163
if (args?.platformProxy?.configPath) {
@@ -144,6 +172,9 @@ export default function createIntegration(args?: Options): AstroIntegration {
144172
order: 'pre',
145173
});
146174
},
175+
'astro:routes:resolved': ({ routes }) => {
176+
_routes = routes;
177+
},
147178
'astro:config:done': ({ setAdapter, config, buildOutput, logger }) => {
148179
if (buildOutput === 'static') {
149180
logger.warn(
@@ -167,7 +198,11 @@ export default function createIntegration(args?: Options): AstroIntegration {
167198
hybridOutput: 'stable',
168199
staticOutput: 'unsupported',
169200
i18nDomains: 'experimental',
170-
sharpImageService: 'limited',
201+
sharpImageService: {
202+
support: 'limited',
203+
message:
204+
'Cloudflare does not support sharp. You can use the `compile` image service to compile images at build time. It will not work for any on-demand rendered images.',
205+
},
171206
envGetSecret: 'stable',
172207
},
173208
});
@@ -260,7 +295,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
260295
};
261296
}
262297
},
263-
'astro:build:done': async ({ pages, routes, dir, logger }) => {
298+
'astro:build:done': async ({ pages, dir, logger, assets }) => {
264299
await cloudflareModulePlugin.afterBuildCompleted(_config);
265300
const PLATFORM_FILES = ['_headers', '_redirects', '_routes.json'];
266301
if (_config.base !== '/') {
@@ -285,7 +320,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
285320
redirectsExists = false;
286321
}
287322

288-
const redirects: IntegrationRouteData['segments'][] = [];
323+
const redirects: IntegrationResolvedRoute['segments'][] = [];
289324
if (redirectsExists) {
290325
const rl = createInterface({
291326
input: createReadStream(new URL('./_redirects', _config.outDir)),
@@ -324,7 +359,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
324359
await createRoutesFile(
325360
_config,
326361
logger,
327-
routes,
362+
_routes,
328363
pages,
329364
redirects,
330365
args?.routes?.extend?.include,
@@ -333,8 +368,10 @@ export default function createIntegration(args?: Options): AstroIntegration {
333368
}
334369

335370
const redirectRoutes: [IntegrationRouteData, string][] = [];
336-
for (const route of routes) {
337-
if (route.type === 'redirect') redirectRoutes.push([route, '']);
371+
for (const route of _routes) {
372+
// TODO: Replace workaround after upstream @astrojs/underscore-redirects is changed, to support new IntegrationResolvedRoute type
373+
if (route.type === 'redirect')
374+
redirectRoutes.push([resolvedRouteToRouteData(assets, route), '']);
338375
}
339376

340377
const trueRedirects = createRedirectsFromAstroRoutes({

packages/cloudflare/src/utils/generate-routes-json.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import type { AstroConfig, AstroIntegrationLogger, IntegrationRouteData, RoutePart } from 'astro';
1+
import type {
2+
AstroConfig,
3+
AstroIntegrationLogger,
4+
IntegrationResolvedRoute,
5+
RoutePart,
6+
} from 'astro';
27

38
import { existsSync } from 'node:fs';
49
import { writeFile } from 'node:fs/promises';
@@ -63,7 +68,7 @@ async function writeRoutesFileToOutDir(
6368
}
6469
}
6570

66-
function segmentsToCfSyntax(segments: IntegrationRouteData['segments'], _config: AstroConfig) {
71+
function segmentsToCfSyntax(segments: IntegrationResolvedRoute['segments'], _config: AstroConfig) {
6772
const pathSegments = [];
6873
if (removeLeadingForwardSlash(removeTrailingForwardSlash(_config.base)).length > 0) {
6974
pathSegments.push(removeLeadingForwardSlash(removeTrailingForwardSlash(_config.base)));
@@ -163,11 +168,11 @@ class PathTrie {
163168
export async function createRoutesFile(
164169
_config: AstroConfig,
165170
logger: AstroIntegrationLogger,
166-
routes: IntegrationRouteData[],
171+
routes: IntegrationResolvedRoute[],
167172
pages: {
168173
pathname: string;
169174
}[],
170-
redirects: IntegrationRouteData['segments'][],
175+
redirects: IntegrationResolvedRoute['segments'][],
171176
includeExtends:
172177
| {
173178
pattern: string;
@@ -223,17 +228,17 @@ export async function createRoutesFile(
223228
let hasPrerendered404 = false;
224229
for (const route of routes) {
225230
const convertedPath = segmentsToCfSyntax(route.segments, _config);
226-
if (route.pathname === '/404' && route.prerender === true) hasPrerendered404 = true;
231+
if (route.pathname === '/404' && route.isPrerendered === true) hasPrerendered404 = true;
227232

228233
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
229234
switch (route.type) {
230235
case 'page':
231-
if (route.prerender === false) includePaths.push(convertedPath);
236+
if (route.isPrerendered === false) includePaths.push(convertedPath);
232237

233238
break;
234239

235240
case 'endpoint':
236-
if (route.prerender === false) includePaths.push(convertedPath);
241+
if (route.isPrerendered === false) includePaths.push(convertedPath);
237242
else excludePaths.push(convertedPath);
238243

239244
break;

packages/cloudflare/test/routes-json.test.js

+106-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ describe('_routes.json generation', () => {
2323

2424
assert.deepEqual(routes, {
2525
version: 1,
26-
include: ['/_image', '/a/*'],
26+
include: ['/_server-islands/*', '/_image', '/a/*'],
2727
exclude: ['/_astro/*', '/redirectme', '/public.txt', '/a', '/a/redirect', '/404', '/b'],
2828
});
2929
});
@@ -101,7 +101,7 @@ describe('_routes.json generation', () => {
101101

102102
assert.deepEqual(routes, {
103103
version: 1,
104-
include: ['/_image', '/a/*', '/another'],
104+
include: ['/_server-islands/*', '/_image', '/a/*', '/another'],
105105
exclude: ['/_astro/*', '/redirectme', '/public.txt', '/a', '/a/redirect', '/404', '/b'],
106106
});
107107
});
@@ -131,7 +131,7 @@ describe('_routes.json generation', () => {
131131

132132
assert.deepEqual(routes, {
133133
version: 1,
134-
include: ['/_image', '/a/*'],
134+
include: ['/_server-islands/*', '/_image', '/a/*'],
135135
exclude: [
136136
'/_astro/*',
137137
'/redirectme',
@@ -167,6 +167,7 @@ describe('_routes.json generation', () => {
167167
version: 1,
168168
include: [
169169
'/',
170+
'/_server-islands/*',
170171
'/_image',
171172
'/dynamicPages/*',
172173
'/mixedPages/dynamic',
@@ -234,8 +235,108 @@ describe('_routes.json generation', () => {
234235

235236
assert.deepEqual(routes, {
236237
version: 1,
237-
include: ['/_image', '/dynamic'],
238-
exclude: [],
238+
include: ['/*'],
239+
exclude: [
240+
'/_astro/*',
241+
'/redirectme',
242+
'/public.txt',
243+
'/a/*',
244+
'/404',
245+
'/0',
246+
'/1',
247+
'/2',
248+
'/3',
249+
'/4',
250+
'/5',
251+
'/6',
252+
'/7',
253+
'/8',
254+
'/9',
255+
'/10',
256+
'/11',
257+
'/12',
258+
'/13',
259+
'/14',
260+
'/15',
261+
'/16',
262+
'/17',
263+
'/18',
264+
'/19',
265+
'/20',
266+
'/21',
267+
'/22',
268+
'/23',
269+
'/24',
270+
'/25',
271+
'/26',
272+
'/27',
273+
'/28',
274+
'/29',
275+
'/30',
276+
'/31',
277+
'/32',
278+
'/33',
279+
'/34',
280+
'/35',
281+
'/36',
282+
'/37',
283+
'/38',
284+
'/39',
285+
'/40',
286+
'/41',
287+
'/42',
288+
'/43',
289+
'/44',
290+
'/45',
291+
'/46',
292+
'/47',
293+
'/48',
294+
'/49',
295+
'/50',
296+
'/51',
297+
'/52',
298+
'/53',
299+
'/54',
300+
'/55',
301+
'/56',
302+
'/57',
303+
'/58',
304+
'/59',
305+
'/60',
306+
'/61',
307+
'/62',
308+
'/63',
309+
'/64',
310+
'/65',
311+
'/66',
312+
'/67',
313+
'/68',
314+
'/69',
315+
'/70',
316+
'/71',
317+
'/72',
318+
'/73',
319+
'/74',
320+
'/75',
321+
'/76',
322+
'/77',
323+
'/78',
324+
'/79',
325+
'/80',
326+
'/81',
327+
'/82',
328+
'/83',
329+
'/84',
330+
'/85',
331+
'/86',
332+
'/87',
333+
'/88',
334+
'/89',
335+
'/90',
336+
'/91',
337+
'/92',
338+
'/93',
339+
],
239340
});
240341
});
241342
});

0 commit comments

Comments
 (0)