Skip to content

Commit

Permalink
Fix Netlify adapter and dynamic routes (#3011)
Browse files Browse the repository at this point in the history
* Fix Netlify adapter and dynamic routes

* Changeset
  • Loading branch information
matthewp authored Apr 6, 2022
1 parent 8bd49c9 commit c6f8bce
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 18 deletions.
6 changes: 6 additions & 0 deletions .changeset/nervous-chairs-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'astro': patch
'@astrojs/netlify': patch
---

Fixes dynamic routes in the Netlify adapter
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"build:ci": "turbo run build:ci --no-deps --scope=astro --scope=create-astro --scope=\"@astrojs/*\"",
"build:examples": "turbo run build --scope=\"@example/*\"",
"dev": "turbo run dev --no-deps --no-cache --parallel --scope=astro --scope=create-astro --scope=\"@astrojs/*\"",
"test": "pnpm run test --filter astro --filter @astrojs/webapi --filter @astrojs/deno",
"test": "pnpm run test --filter astro --filter @astrojs/webapi --filter @astrojs/deno --filter @astrojs/netlify",
"test:match": "cd packages/astro && pnpm run test:match",
"test:templates": "pnpm run test --filter create-astro",
"test:smoke": "node scripts/smoke/index.js",
Expand Down
7 changes: 7 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -798,12 +798,19 @@ export interface AstroIntegration {

export type RouteType = 'page' | 'endpoint';

export interface RoutePart {
content: string;
dynamic: boolean;
spread: boolean;
}

export interface RouteData {
component: string;
generate: (data?: any) => string;
params: string[];
pathname?: string;
pattern: RegExp;
segments: RoutePart[][];
type: RouteType;
}

Expand Down
19 changes: 7 additions & 12 deletions packages/astro/src/core/routing/manifest/create.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AstroConfig, ManifestData, RouteData } from '../../../@types/astro';
import type { AstroConfig, ManifestData, RouteData, RoutePart } from '../../../@types/astro';
import type { LogOptions } from '../../logger/core';

import fs from 'fs';
Expand All @@ -9,16 +9,10 @@ import { fileURLToPath } from 'url';
import { warn } from '../../logger/core.js';
import { resolvePages } from '../../util.js';

interface Part {
content: string;
dynamic: boolean;
spread: boolean;
}

interface Item {
basename: string;
ext: string;
parts: Part[];
parts: RoutePart[];
file: string;
isDir: boolean;
isIndex: boolean;
Expand All @@ -35,7 +29,7 @@ function countOccurrences(needle: string, haystack: string) {
}

function getParts(part: string, file: string) {
const result: Part[] = [];
const result: RoutePart[] = [];
part.split(/\[(.+?\(.+?\)|.+?)\]/).map((str, i) => {
if (!str) return;
const dynamic = i % 2 === 1;
Expand All @@ -56,7 +50,7 @@ function getParts(part: string, file: string) {
return result;
}

function getPattern(segments: Part[][], addTrailingSlash: AstroConfig['trailingSlash']) {
function getPattern(segments: RoutePart[][], addTrailingSlash: AstroConfig['trailingSlash']) {
const pathname = segments
.map((segment) => {
return segment[0].spread
Expand Down Expand Up @@ -94,7 +88,7 @@ function getTrailingSlashPattern(addTrailingSlash: AstroConfig['trailingSlash'])
return '\\/?$';
}

function getGenerator(segments: Part[][], addTrailingSlash: AstroConfig['trailingSlash']) {
function getGenerator(segments: RoutePart[][], addTrailingSlash: AstroConfig['trailingSlash']) {
const template = segments
.map((segment) => {
return segment[0].spread
Expand Down Expand Up @@ -181,7 +175,7 @@ export function createRouteManifest(
const validPageExtensions: Set<string> = new Set(['.astro', '.md']);
const validEndpointExtensions: Set<string> = new Set(['.js', '.ts']);

function walk(dir: string, parentSegments: Part[][], parentParams: string[]) {
function walk(dir: string, parentSegments: RoutePart[][], parentParams: string[]) {
let items: Item[] = [];
fs.readdirSync(dir).forEach((basename) => {
const resolved = path.join(dir, basename);
Expand Down Expand Up @@ -285,6 +279,7 @@ export function createRouteManifest(
routes.push({
type: item.isPage ? 'page' : 'endpoint',
pattern,
segments,
params,
component,
generate,
Expand Down
10 changes: 6 additions & 4 deletions packages/astro/src/core/routing/manifest/serialization.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { RouteData, SerializedRouteData } from '../../../@types/astro';
import type { RouteData, SerializedRouteData, RoutePart } from '../../../@types/astro';

function createRouteData(
pattern: RegExp,
params: string[],
component: string,
pathname: string | undefined,
type: 'page' | 'endpoint'
type: 'page' | 'endpoint',
segments: RoutePart[][]
): RouteData {
return {
type,
Expand All @@ -15,6 +16,7 @@ function createRouteData(
// TODO bring back
generate: () => '',
pathname: pathname || undefined,
segments
};
}

Expand All @@ -26,7 +28,7 @@ export function serializeRouteData(routeData: RouteData): SerializedRouteData {
}

export function deserializeRouteData(rawRouteData: SerializedRouteData) {
const { component, params, pathname, type } = rawRouteData;
const { component, params, pathname, type, segments } = rawRouteData;
const pattern = new RegExp(rawRouteData.pattern);
return createRouteData(pattern, params, component, pathname, type);
return createRouteData(pattern, params, component, pathname, type, segments);
}
3 changes: 2 additions & 1 deletion packages/integrations/netlify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
},
"scripts": {
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
"dev": "astro-scripts dev \"src/**/*.ts\""
"dev": "astro-scripts dev \"src/**/*.ts\"",
"test": "mocha --exit --timeout 20000"
},
"dependencies": {
"@astrojs/webapi": "^0.11.0"
Expand Down
4 changes: 4 additions & 0 deletions packages/integrations/netlify/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ function netlifyFunctions({ dist }: NetlifyFunctionsOptions = {}): AstroIntegrat
if (route.pathname) {
_redirects += `
${route.pathname} /.netlify/functions/${entryFile} 200`;
} else {
const pattern = '/' + route.segments.map(([part]) => part.dynamic ? '*' : part.content).join('/');
_redirects += `
${pattern} /.netlify/functions/${entryFile} 200`;
}
}

Expand Down
37 changes: 37 additions & 0 deletions packages/integrations/netlify/test/dynamic-route.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { expect } from 'chai';
import { load as cheerioLoad } from 'cheerio';
import { loadFixture } from '../../../astro/test/test-utils.js';
import netlifyAdapter from '../dist/index.js';
import { fileURLToPath } from 'url';

// Asset bundling
describe('Dynamic pages', () => {
/** @type {import('../../../astro/test/test-utils').Fixture} */
let fixture;

before(async () => {
fixture = await loadFixture({
root: new URL('./fixtures/dynamic-route/', import.meta.url).toString(),
experimental: {
ssr: true,
},
adapter: netlifyAdapter({
dist: new URL('./fixtures/dynamic-route/dist/', import.meta.url)
}),
site: `http://example.com`,
vite: {
resolve: {
alias: {
'@astrojs/netlify/netlify-functions.js': fileURLToPath(new URL('../dist/netlify-functions.js', import.meta.url))
}
}
}
});
await fixture.build();
});

it('Dynamic pages are included in the redirects file', async () => {
const redir = await fixture.readFile('/_redirects');
expect(redir).to.match(/\/products\/\*/);
});
});
1 change: 1 addition & 0 deletions packages/integrations/netlify/test/fixtures/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**/netlify
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
---
<html>
<head>
<title>Testing</title>
</head>
<body>
<h1>Testing</h1>
</body>
</html>

0 comments on commit c6f8bce

Please sign in to comment.