diff --git a/.changeset/heavy-yaks-brake.md b/.changeset/heavy-yaks-brake.md new file mode 100644 index 000000000000..50f2a1f88e3f --- /dev/null +++ b/.changeset/heavy-yaks-brake.md @@ -0,0 +1,5 @@ +--- +'@astrojs/underscore-redirects': minor +--- + +Updates how the output is determined in `createRedirectsFromAstroRoutes`. Since `v0.5.0`, the output would use the `buildOutput` property and `config.output` as a fallback. It no longer uses this fallback. diff --git a/.changeset/tiny-plums-crash.md b/.changeset/tiny-plums-crash.md new file mode 100644 index 000000000000..815a4a354268 --- /dev/null +++ b/.changeset/tiny-plums-crash.md @@ -0,0 +1,40 @@ +--- +'@astrojs/underscore-redirects': minor +--- + +Updates the input requirements of `createRedirectsFromAstroRoutes`: + +- `routeToDynamicTargetMap` keys are `IntegrationResolvedRoute` instead of `IntegrationRouteData` (obtained from the `astro:routes:resolved` hook) +- There's a new `assets` property, that can be obtained from the `astro:build:done` hook + +```js +function myIntegration() { + let routes + let buildOutput + let config + + return { + name: "my-integration", + hooks: { + "astro:routes:resolved": (params) => { + routes = params.routes + }, + "astro:config:done": (params) => { + buildOutput = params.buildOutput + config = params.config + }, + "astro:build:done": (params) => { + const redirects = createRedirectsFromAstroRoutes({ + config, + buildOutput, + routeToDynamicTargetMap: new Map( + routes.map(route => [route, '']) + ), + dir: params.dir, + assets: params.assets + }) + } + } + } +} +``` \ No newline at end of file diff --git a/packages/underscore-redirects/src/astro.ts b/packages/underscore-redirects/src/astro.ts index b76e1b52a672..bd3e3b2ea346 100644 --- a/packages/underscore-redirects/src/astro.ts +++ b/packages/underscore-redirects/src/astro.ts @@ -1,10 +1,15 @@ import { posix } from 'node:path'; -import type { AstroConfig, IntegrationRouteData, ValidRedirectStatus } from 'astro'; +import type { + AstroConfig, + HookParameters, + IntegrationResolvedRoute, + ValidRedirectStatus, +} from 'astro'; import { Redirects } from './redirects.js'; const pathJoin = posix.join; -function getRedirectStatus(route: IntegrationRouteData): ValidRedirectStatus { +function getRedirectStatus(route: IntegrationResolvedRoute): ValidRedirectStatus { if (typeof route.redirect === 'object') { return route.redirect.status; } @@ -16,9 +21,10 @@ interface CreateRedirectsFromAstroRoutesParams { /** * Maps a `RouteData` to a dynamic target */ - routeToDynamicTargetMap: Map; + routeToDynamicTargetMap: Map; dir: URL; buildOutput: 'static' | 'server'; + assets: HookParameters<'astro:build:done'>['assets']; } /** @@ -29,6 +35,7 @@ export function createRedirectsFromAstroRoutes({ routeToDynamicTargetMap, dir, buildOutput, + assets, }: CreateRedirectsFromAstroRoutesParams) { const base = config.base && config.base !== '/' @@ -36,11 +43,10 @@ export function createRedirectsFromAstroRoutes({ ? config.base.slice(0, -1) : config.base : ''; - // TODO: the use of `config.output` is deprecated. We need to update the adapters that use this package to pass the new buildOutput - const output = buildOutput ?? config.output; const _redirects = new Redirects(); for (const [route, dynamicTarget = ''] of routeToDynamicTargetMap) { + const distURL = assets.get(route.pattern); // A route with a `pathname` is as static route. if (route.pathname) { if (route.redirect) { @@ -57,13 +63,13 @@ export function createRedirectsFromAstroRoutes({ } // If this is a static build we don't want to add redirects to the HTML file. - if (output === 'static') { + if (buildOutput === 'static') { continue; - } else if (route.distURL) { + } else if (distURL) { _redirects.add({ dynamic: false, input: `${base}${route.pathname}`, - target: prependForwardSlash(route.distURL.toString().replace(dir.toString(), '')), + target: prependForwardSlash(distURL.toString().replace(dir.toString(), '')), status: 200, weight: 2, }); @@ -76,7 +82,7 @@ export function createRedirectsFromAstroRoutes({ weight: 2, }); - if (route.route === '/404') { + if (route.pattern === '/404') { _redirects.add({ dynamic: true, input: '/*', @@ -92,7 +98,7 @@ export function createRedirectsFromAstroRoutes({ const pattern = generateDynamicPattern(route); // This route was prerendered and should be forwarded to the HTML file. - if (route.distURL) { + if (distURL) { const targetRoute = route.redirectRoute ?? route; const targetPattern = generateDynamicPattern(targetRoute); let target = targetPattern; @@ -128,7 +134,7 @@ export function createRedirectsFromAstroRoutes({ * /team/articles/* * With stars replacing spread and :id syntax replacing [id] */ -function generateDynamicPattern(route: IntegrationRouteData) { +function generateDynamicPattern(route: IntegrationResolvedRoute) { const pattern = '/' + route.segments diff --git a/packages/underscore-redirects/test/astro.test.js b/packages/underscore-redirects/test/astro.test.js index 71ee13f339c4..6a4944dc907a 100644 --- a/packages/underscore-redirects/test/astro.test.js +++ b/packages/underscore-redirects/test/astro.test.js @@ -3,28 +3,24 @@ import { describe, it } from 'node:test'; import { createRedirectsFromAstroRoutes } from '../dist/index.js'; describe('Astro', () => { - const serverConfig = { - output: 'server', - build: { format: 'directory' }, - }; - it('Creates a Redirects object from routes', () => { const routeToDynamicTargetMap = new Map( Array.from([ - [ - { pathname: '/', distURL: new URL('./index.html', import.meta.url), segments: [] }, - './.adapter/dist/entry.mjs', - ], - [ - { pathname: '/one', distURL: new URL('./one/index.html', import.meta.url), segments: [] }, - './.adapter/dist/entry.mjs', - ], + [{ pattern: '/', pathname: '/', segments: [] }, './.adapter/dist/entry.mjs'], + [{ pattern: '/one', pathname: '/one', segments: [] }, './.adapter/dist/entry.mjs'], ]), ); const _redirects = createRedirectsFromAstroRoutes({ - config: serverConfig, + config: { + build: { format: 'directory' }, + }, routeToDynamicTargetMap, dir: new URL(import.meta.url), + buildOutput: 'server', + assets: new Map([ + ['/', new URL('./index.html', import.meta.url)], + ['/one', new URL('./one/index.html', import.meta.url)], + ]), }); assert.equal(_redirects.definitions.length, 2);