Skip to content

Commit

Permalink
feat(underscore-redirects): update API to support new hook (#12924)
Browse files Browse the repository at this point in the history
  • Loading branch information
florian-lefebvre authored Jan 8, 2025
1 parent fd12a26 commit 3caa337
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/heavy-yaks-brake.md
Original file line number Diff line number Diff line change
@@ -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.
40 changes: 40 additions & 0 deletions .changeset/tiny-plums-crash.md
Original file line number Diff line number Diff line change
@@ -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
})
}
}
}
}
```
28 changes: 17 additions & 11 deletions packages/underscore-redirects/src/astro.ts
Original file line number Diff line number Diff line change
@@ -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;
}
Expand All @@ -16,9 +21,10 @@ interface CreateRedirectsFromAstroRoutesParams {
/**
* Maps a `RouteData` to a dynamic target
*/
routeToDynamicTargetMap: Map<IntegrationRouteData, string>;
routeToDynamicTargetMap: Map<IntegrationResolvedRoute, string>;
dir: URL;
buildOutput: 'static' | 'server';
assets: HookParameters<'astro:build:done'>['assets'];
}

/**
Expand All @@ -29,18 +35,18 @@ export function createRedirectsFromAstroRoutes({
routeToDynamicTargetMap,
dir,
buildOutput,
assets,
}: CreateRedirectsFromAstroRoutesParams) {
const base =
config.base && config.base !== '/'
? config.base.endsWith('/')
? 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) {
Expand All @@ -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,
});
Expand All @@ -76,7 +82,7 @@ export function createRedirectsFromAstroRoutes({
weight: 2,
});

if (route.route === '/404') {
if (route.pattern === '/404') {
_redirects.add({
dynamic: true,
input: '/*',
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
24 changes: 10 additions & 14 deletions packages/underscore-redirects/test/astro.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 3caa337

Please sign in to comment.