Merge branch 'main' into test/e2e-hydration
This commit is contained in:
commit
b122cea9f1
23 changed files with 512 additions and 31 deletions
5
.changeset/blue-buckets-attack.md
Normal file
5
.changeset/blue-buckets-attack.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Adds a check during build to make sure routing priority is always enforced in the final dist output
|
5
.changeset/quick-waves-act.md
Normal file
5
.changeset/quick-waves-act.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes a bug in the canonical URL when using `1` as a route parameter in `getStaticPaths()`
|
6
.changeset/serious-vans-smell.md
Normal file
6
.changeset/serious-vans-smell.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'@astrojs/webapi': minor
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix: support FormData object on fetch body
|
|
@ -10,7 +10,9 @@ import { debug } from '../logger/core.js';
|
|||
import { preload as ssrPreload } from '../render/dev/index.js';
|
||||
import { generateRssFunction } from '../render/rss.js';
|
||||
import { callGetStaticPaths, RouteCache, RouteCacheEntry } from '../render/route-cache.js';
|
||||
import { removeTrailingForwardSlash } from '../path.js';
|
||||
import { isBuildingToSSR } from '../util.js';
|
||||
import { matchRoute } from '../routing/match.js';
|
||||
|
||||
export interface CollectPagesDataOptions {
|
||||
astroConfig: AstroConfig;
|
||||
|
@ -35,6 +37,7 @@ export async function collectPagesData(
|
|||
|
||||
const assets: Record<string, string> = {};
|
||||
const allPages: AllPagesData = {};
|
||||
const builtPaths = new Set<string>();
|
||||
|
||||
const buildMode = isBuildingToSSR(astroConfig) ? 'ssr' : 'static';
|
||||
|
||||
|
@ -60,6 +63,7 @@ export async function collectPagesData(
|
|||
);
|
||||
clearInterval(routeCollectionLogTimeout);
|
||||
}, 10000);
|
||||
builtPaths.add(route.pathname);
|
||||
allPages[route.component] = {
|
||||
component: route.component,
|
||||
route,
|
||||
|
@ -138,7 +142,28 @@ export async function collectPagesData(
|
|||
}
|
||||
const finalPaths = result.staticPaths
|
||||
.map((staticPath) => staticPath.params && route.generate(staticPath.params))
|
||||
.filter(Boolean);
|
||||
.filter((staticPath) => {
|
||||
// Remove empty or undefined paths
|
||||
if (!staticPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The path hasn't been built yet, include it
|
||||
if (!builtPaths.has(removeTrailingForwardSlash(staticPath))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The path was already built once. Check the manifest to see if
|
||||
// this route takes priority for the final URL.
|
||||
// NOTE: The same URL may match multiple routes in the manifest.
|
||||
// Routing priority needs to be verified here for any duplicate
|
||||
// paths to ensure routing priority rules are enforced in the final build.
|
||||
const matchedRoute = matchRoute(staticPath, manifest);
|
||||
return matchedRoute === route;
|
||||
});
|
||||
|
||||
finalPaths.map((staticPath) => builtPaths.add(removeTrailingForwardSlash(staticPath)));
|
||||
|
||||
allPages[route.component] = {
|
||||
component: route.component,
|
||||
route,
|
||||
|
|
|
@ -133,6 +133,7 @@ export async function render(
|
|||
markdown,
|
||||
origin,
|
||||
params,
|
||||
props: pageProps,
|
||||
pathname,
|
||||
resolve,
|
||||
renderers,
|
||||
|
|
|
@ -2,7 +2,9 @@ import { bold } from 'kleur/colors';
|
|||
import type {
|
||||
AstroGlobal,
|
||||
AstroGlobalPartial,
|
||||
Page,
|
||||
Params,
|
||||
Props,
|
||||
SSRElement,
|
||||
SSRLoadedRenderer,
|
||||
SSRResult,
|
||||
|
@ -27,6 +29,7 @@ export interface CreateResultArgs {
|
|||
markdown: MarkdownRenderingOptions;
|
||||
params: Params;
|
||||
pathname: string;
|
||||
props: Props;
|
||||
renderers: SSRLoadedRenderer[];
|
||||
resolve: (s: string) => Promise<string>;
|
||||
site: string | undefined;
|
||||
|
@ -99,11 +102,16 @@ class Slots {
|
|||
|
||||
let renderMarkdown: any = null;
|
||||
|
||||
export function createResult(args: CreateResultArgs): SSRResult {
|
||||
const { markdown, params, pathname, renderers, request, resolve, site } = args;
|
||||
function isPaginatedRoute({ page }: { page?: Page }) {
|
||||
return page && 'currentPage' in page;
|
||||
}
|
||||
|
||||
export function createResult(args: CreateResultArgs): SSRResult {
|
||||
const { markdown, params, pathname, props: pageProps, renderers, request, resolve, site } = args;
|
||||
|
||||
const paginated = isPaginatedRoute(pageProps);
|
||||
const url = new URL(request.url);
|
||||
const canonicalURL = createCanonicalURL('.' + pathname, site ?? url.origin);
|
||||
const canonicalURL = createCanonicalURL('.' + pathname, site ?? url.origin, paginated);
|
||||
const response: ResponseInit = {
|
||||
status: 200,
|
||||
statusText: 'OK',
|
||||
|
|
|
@ -3,9 +3,12 @@ import type { ModuleNode, ViteDevServer } from 'vite';
|
|||
import type { Metadata } from '../../runtime/server/metadata.js';
|
||||
|
||||
/** Normalize URL to its canonical form */
|
||||
export function createCanonicalURL(url: string, base?: string): URL {
|
||||
export function createCanonicalURL(url: string, base?: string, paginated?: boolean): URL {
|
||||
let pathname = url.replace(/\/index.html$/, ''); // index.html is not canonical
|
||||
pathname = pathname.replace(/\/1\/?$/, ''); // neither is a trailing /1/ (impl. detail of collections)
|
||||
// Only trim the first page's /1 param if Astro's paginated() was used
|
||||
if (paginated) {
|
||||
pathname = pathname.replace(/\/1\/?$/, ''); // neither is a trailing /1/ (impl. detail of collections)
|
||||
}
|
||||
if (!npath.extname(pathname)) pathname = pathname.replace(/(\/+)?$/, '/'); // add trailing slash if there’s no extension
|
||||
pathname = pathname.replace(/\/+/g, '/'); // remove duplicate slashes (URL() won’t)
|
||||
return new URL(pathname, base);
|
||||
|
|
|
@ -199,13 +199,10 @@ async function handleRequest(
|
|||
const devRoot = site ? site.pathname : '/';
|
||||
const origin = `${viteServer.config.server.https ? 'https' : 'http'}://${req.headers.host}`;
|
||||
const buildingToSSR = isBuildingToSSR(config);
|
||||
// When file-based build format is used, pages will be built to `/blog.html`
|
||||
// rather than `/blog/index.html`. The dev server should handle this as well
|
||||
// to match production deployments.
|
||||
const url =
|
||||
config.build.format === 'file'
|
||||
? new URL(origin + req.url?.replace(/(index)?\.html$/, ''))
|
||||
: new URL(origin + req.url);
|
||||
// Ignore `.html` extensions and `index.html` in request URLS to ensure that
|
||||
// routing behavior matches production builds. This supports both file and directory
|
||||
// build formats, and is necessary based on how the manifest tracks build targets.
|
||||
const url = new URL(origin + req.url?.replace(/(index)?\.html$/, ''));
|
||||
const pathname = decodeURI(url.pathname);
|
||||
const rootRelativeUrl = pathname.substring(devRoot.length - 1);
|
||||
if (!buildingToSSR) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { expect } from 'chai';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
import * as cheerio from 'cheerio';
|
||||
|
||||
describe('getStaticPaths - build calls', () => {
|
||||
before(async () => {
|
||||
|
@ -59,7 +60,7 @@ describe('getStaticPaths - route params type validation', () => {
|
|||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
it('resolves 200 on mathcing static path - string params', async () => {
|
||||
it('resolves 200 on matching static path - string params', async () => {
|
||||
// route provided with { params: { year: "2022", slug: "post-2" }}
|
||||
const res = await fixture.fetch('/blog/2022/post-1');
|
||||
expect(res.status).to.equal(200);
|
||||
|
@ -71,3 +72,37 @@ describe('getStaticPaths - route params type validation', () => {
|
|||
expect(res.status).to.equal(200);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getStaticPaths - numeric route params', () => {
|
||||
let fixture;
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/astro-get-static-paths/',
|
||||
site: 'https://mysite.dev/',
|
||||
});
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
it('resolves 200 on matching static paths', async () => {
|
||||
// routes params provided for pages /posts/1, /posts/2, and /posts/3
|
||||
for (const page of [1, 2, 3]) {
|
||||
let res = await fixture.fetch(`/posts/${page}`);
|
||||
expect(res.status).to.equal(200);
|
||||
|
||||
const html = await res.text();
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
const canonical = $('link[rel=canonical]');
|
||||
expect(canonical.attr('href')).to.equal(
|
||||
`https://mysite.dev/posts/${page}/`,
|
||||
`doesn't trim the /${page}/ route param`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
29
packages/astro/test/fixtures/astro-get-static-paths/src/pages/posts/[page].astro
vendored
Normal file
29
packages/astro/test/fixtures/astro-get-static-paths/src/pages/posts/[page].astro
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
export async function getStaticPaths() {
|
||||
return [
|
||||
{
|
||||
params: { page: 1 },
|
||||
},
|
||||
{
|
||||
params: { page: 2 },
|
||||
},
|
||||
{
|
||||
params: { page: 3 }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const { page } = Astro.params
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Posts Page {page}</title>
|
||||
<link rel="canonical" href={Astro.canonicalURL.href}>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to page {page}</h1>
|
||||
</body>
|
||||
</html>
|
4
packages/astro/test/fixtures/routing-priority/astro.config.mjs
vendored
Normal file
4
packages/astro/test/fixtures/routing-priority/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({});
|
8
packages/astro/test/fixtures/routing-priority/package.json
vendored
Normal file
8
packages/astro/test/fixtures/routing-priority/package.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "@test/routing-priority",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
23
packages/astro/test/fixtures/routing-priority/src/pages/[lang]/[...catchall].astro
vendored
Normal file
23
packages/astro/test/fixtures/routing-priority/src/pages/[lang]/[...catchall].astro
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
export async function getStaticPaths() {
|
||||
return [
|
||||
{ params: { lang: 'de', catchall: '1/2' } },
|
||||
{ params: { lang: 'en', catchall: '1/2' } }
|
||||
]
|
||||
}
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Routing</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>[lang]/[...catchall].astro</h1>
|
||||
<p>{Astro.params.lang} | {Astro.params.catchall}</p>
|
||||
</body>
|
||||
|
||||
</html>
|
23
packages/astro/test/fixtures/routing-priority/src/pages/[lang]/index.astro
vendored
Normal file
23
packages/astro/test/fixtures/routing-priority/src/pages/[lang]/index.astro
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
export async function getStaticPaths() {
|
||||
return [
|
||||
{ params: { lang: 'de' } }, // always shadowed by /de/index.astro
|
||||
{ params: { lang: 'en' } }
|
||||
];
|
||||
}
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Routing</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>[lang]/index.astro</h1>
|
||||
<p>{Astro.params.lang}</p>
|
||||
</body>
|
||||
|
||||
</html>
|
12
packages/astro/test/fixtures/routing-priority/src/pages/de/index.astro
vendored
Normal file
12
packages/astro/test/fixtures/routing-priority/src/pages/de/index.astro
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Routing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>de/index.astro</h1>
|
||||
</body>
|
||||
</html>
|
12
packages/astro/test/fixtures/routing-priority/src/pages/index.astro
vendored
Normal file
12
packages/astro/test/fixtures/routing-priority/src/pages/index.astro
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
---
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Routing</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>index.astro</h1>
|
||||
</body>
|
||||
</html>
|
24
packages/astro/test/fixtures/routing-priority/src/pages/posts/[...slug].astro
vendored
Normal file
24
packages/astro/test/fixtures/routing-priority/src/pages/posts/[...slug].astro
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
export async function getStaticPaths() {
|
||||
return [
|
||||
{
|
||||
params: { slug: "1/2" },
|
||||
}
|
||||
]
|
||||
}
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Routing</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>posts/[...slug].astro</h1>
|
||||
<p>{Astro.params.slug}</p>
|
||||
</body>
|
||||
|
||||
</html>
|
23
packages/astro/test/fixtures/routing-priority/src/pages/posts/[pid].astro
vendored
Normal file
23
packages/astro/test/fixtures/routing-priority/src/pages/posts/[pid].astro
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
export async function getStaticPaths() {
|
||||
return [
|
||||
{ params: { pid: 'post-1' } },
|
||||
{ params: { pid: 'post-2' } }
|
||||
]
|
||||
}
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Routing</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>posts/[pid].astro</h1>
|
||||
<p>{Astro.params.pid}</p>
|
||||
</body>
|
||||
|
||||
</html>
|
236
packages/astro/test/routing-priority.test.js
Normal file
236
packages/astro/test/routing-priority.test.js
Normal file
|
@ -0,0 +1,236 @@
|
|||
import { expect } from 'chai';
|
||||
import { load as cheerioLoad } from 'cheerio';
|
||||
import path from 'path';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
let fixture;
|
||||
|
||||
const routes = [
|
||||
{
|
||||
url: '/',
|
||||
h1: 'index.astro',
|
||||
},
|
||||
{
|
||||
url: '/posts/post-1',
|
||||
h1: 'posts/[pid].astro',
|
||||
p: 'post-1',
|
||||
},
|
||||
{
|
||||
url: '/posts/post-2',
|
||||
h1: 'posts/[pid].astro',
|
||||
p: 'post-2',
|
||||
},
|
||||
{
|
||||
url: '/posts/1/2',
|
||||
h1: 'posts/[...slug].astro',
|
||||
p: '1/2',
|
||||
},
|
||||
{
|
||||
url: '/de',
|
||||
h1: 'de/index.astro',
|
||||
},
|
||||
{
|
||||
url: '/de/',
|
||||
h1: 'de/index.astro',
|
||||
},
|
||||
{
|
||||
url: '/de/index.html',
|
||||
h1: 'de/index.astro',
|
||||
},
|
||||
{
|
||||
url: '/en',
|
||||
h1: '[lang]/index.astro',
|
||||
p: 'en',
|
||||
},
|
||||
{
|
||||
url: '/en/',
|
||||
h1: '[lang]/index.astro',
|
||||
p: 'en',
|
||||
},
|
||||
{
|
||||
url: '/en/index.html',
|
||||
h1: '[lang]/index.astro',
|
||||
p: 'en',
|
||||
},
|
||||
{
|
||||
url: '/de/1/2',
|
||||
h1: '[lang]/[...catchall].astro',
|
||||
p: 'de | 1/2',
|
||||
},
|
||||
{
|
||||
url: '/en/1/2',
|
||||
h1: '[lang]/[...catchall].astro',
|
||||
p: 'en | 1/2',
|
||||
},
|
||||
];
|
||||
|
||||
describe('Routing priority', () => {
|
||||
before(async () => {
|
||||
fixture = await loadFixture({
|
||||
root: './fixtures/routing-priority/',
|
||||
});
|
||||
});
|
||||
|
||||
describe('build', () => {
|
||||
before(async () => {
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
it('matches / to index.astro', async () => {
|
||||
const html = await fixture.readFile('/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('index.astro');
|
||||
});
|
||||
|
||||
it('matches /posts/post-1 to posts/[pid].astro', async () => {
|
||||
const html = await fixture.readFile('/posts/post-1/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('posts/[pid].astro');
|
||||
expect($('p').text()).to.equal('post-1');
|
||||
});
|
||||
|
||||
it('matches /posts/1/2 to posts/[...slug].astro', async () => {
|
||||
const html = await fixture.readFile('/posts/1/2/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('posts/[...slug].astro');
|
||||
expect($('p').text()).to.equal('1/2');
|
||||
});
|
||||
|
||||
it('matches /de to de/index.astro', async () => {
|
||||
const html = await fixture.readFile('/de/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('de/index.astro');
|
||||
});
|
||||
|
||||
it('matches /en to [lang]/index.astro', async () => {
|
||||
const html = await fixture.readFile('/en/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/index.astro');
|
||||
expect($('p').text()).to.equal('en');
|
||||
});
|
||||
|
||||
it('matches /de/1/2 to [lang]/[...catchall].astro', async () => {
|
||||
const html = await fixture.readFile('/de/1/2/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/[...catchall].astro');
|
||||
expect($('p').text()).to.equal('de | 1/2');
|
||||
});
|
||||
|
||||
it('matches /en/1/2 to [lang]/[...catchall].astro', async () => {
|
||||
const html = await fixture.readFile('/en/1/2/index.html');
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/[...catchall].astro');
|
||||
expect($('p').text()).to.equal('en | 1/2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('dev', () => {
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
it('matches / to index.astro', async () => {
|
||||
const html = await fixture.fetch('/').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('index.astro');
|
||||
});
|
||||
|
||||
it('matches /posts/post-1 to /posts/[pid].astro', async () => {
|
||||
const html = await fixture.fetch('/posts/post-1').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('posts/[pid].astro');
|
||||
expect($('p').text()).to.equal('post-1');
|
||||
});
|
||||
|
||||
it('matches /posts/1/2 to /posts/[...slug].astro', async () => {
|
||||
const html = await fixture.fetch('/posts/1/2').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('posts/[...slug].astro');
|
||||
expect($('p').text()).to.equal('1/2');
|
||||
});
|
||||
|
||||
it('matches /de to de/index.astro', async () => {
|
||||
const html = await fixture.fetch('/de').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('de/index.astro');
|
||||
});
|
||||
|
||||
it('matches /de to de/index.astro', async () => {
|
||||
const html = await fixture.fetch('/de').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('de/index.astro');
|
||||
});
|
||||
|
||||
it('matches /de/ to de/index.astro', async () => {
|
||||
const html = await fixture.fetch('/de/').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('de/index.astro');
|
||||
});
|
||||
|
||||
it('matches /de/index.html to de/index.astro', async () => {
|
||||
const html = await fixture.fetch('/de/index.html').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('de/index.astro');
|
||||
});
|
||||
|
||||
it('matches /en to [lang]/index.astro', async () => {
|
||||
const html = await fixture.fetch('/en').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/index.astro');
|
||||
expect($('p').text()).to.equal('en');
|
||||
});
|
||||
|
||||
it('matches /en/ to [lang]/index.astro', async () => {
|
||||
const html = await fixture.fetch('/en/').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/index.astro');
|
||||
expect($('p').text()).to.equal('en');
|
||||
});
|
||||
|
||||
it('matches /en/index.html to de/index.astro', async () => {
|
||||
const html = await fixture.fetch('/en/index.html').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/index.astro');
|
||||
expect($('p').text()).to.equal('en');
|
||||
});
|
||||
|
||||
it('matches /de/1/2 to [lang]/[...catchall].astro', async () => {
|
||||
const html = await fixture.fetch('/de/1/2/index.html').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/[...catchall].astro');
|
||||
expect($('p').text()).to.equal('de | 1/2');
|
||||
});
|
||||
|
||||
it('matches /en/1/2 to [lang]/[...catchall].astro', async () => {
|
||||
const html = await fixture.fetch('/en/1/2/index.html').then((res) => res.text());
|
||||
const $ = cheerioLoad(html);
|
||||
|
||||
expect($('h1').text()).to.equal('[lang]/[...catchall].astro');
|
||||
expect($('p').text()).to.equal('en | 1/2');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -49,6 +49,9 @@
|
|||
],
|
||||
"bugs": "https://github.com/withastro/astro/issues",
|
||||
"homepage": "https://github.com/withastro/astro/tree/main/packages/webapi#readme",
|
||||
"dependencies": {
|
||||
"node-fetch": "^3.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-alias": "^3.1.9",
|
||||
"@rollup/plugin-inject": "^4.0.4",
|
||||
|
@ -65,7 +68,6 @@
|
|||
"formdata-polyfill": "^4.0.10",
|
||||
"magic-string": "^0.25.9",
|
||||
"mocha": "^9.2.2",
|
||||
"node-fetch": "^3.2.4",
|
||||
"rollup": "^2.74.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"tslib": "^2.4.0",
|
||||
|
|
|
@ -178,6 +178,7 @@ async function build() {
|
|||
inputOptions: {
|
||||
input: 'src/polyfill.ts',
|
||||
plugins: plugins,
|
||||
external: ['node-fetch'],
|
||||
onwarn(warning, warn) {
|
||||
if (warning.code !== 'UNRESOLVED_IMPORT') warn(warning)
|
||||
},
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
import {
|
||||
default as nodeFetch,
|
||||
Headers,
|
||||
Request,
|
||||
Response,
|
||||
} from 'node-fetch/src/index.js'
|
||||
import { default as nodeFetch, Headers, Request, Response } from 'node-fetch'
|
||||
import type { RequestInit } from 'node-fetch'
|
||||
import Stream from 'node:stream'
|
||||
import * as _ from './utils'
|
||||
|
||||
|
@ -11,7 +7,7 @@ export { Headers, Request, Response }
|
|||
|
||||
export const fetch = {
|
||||
fetch(
|
||||
resource: string | URL | Request,
|
||||
resource: string | Request,
|
||||
init?: Partial<FetchInit>
|
||||
): Promise<Response> {
|
||||
const resourceURL = new URL(
|
||||
|
@ -62,13 +58,7 @@ export const fetch = {
|
|||
type USVString = {} & string
|
||||
|
||||
interface FetchInit {
|
||||
body:
|
||||
| Blob
|
||||
| BufferSource
|
||||
| FormData
|
||||
| URLSearchParams
|
||||
| ReadableStream
|
||||
| USVString
|
||||
body: RequestInit['body']
|
||||
cache:
|
||||
| 'default'
|
||||
| 'no-store'
|
||||
|
|
|
@ -1225,6 +1225,12 @@ importers:
|
|||
dependencies:
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/routing-priority:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
dependencies:
|
||||
astro: link:../../..
|
||||
|
||||
packages/astro/test/fixtures/sass:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
|
@ -1744,6 +1750,8 @@ importers:
|
|||
typescript: ^4.6.4
|
||||
urlpattern-polyfill: ^1.0.0-rc5
|
||||
web-streams-polyfill: ^3.2.1
|
||||
dependencies:
|
||||
node-fetch: 3.2.4
|
||||
devDependencies:
|
||||
'@rollup/plugin-alias': 3.1.9_rollup@2.74.1
|
||||
'@rollup/plugin-inject': 4.0.4_rollup@2.74.1
|
||||
|
@ -1760,7 +1768,6 @@ importers:
|
|||
formdata-polyfill: 4.0.10
|
||||
magic-string: 0.25.9
|
||||
mocha: 9.2.2
|
||||
node-fetch: 3.2.4
|
||||
rollup: 2.74.1
|
||||
rollup-plugin-terser: 7.0.2_rollup@2.74.1
|
||||
tslib: 2.4.0
|
||||
|
@ -7809,6 +7816,7 @@ packages:
|
|||
/data-uri-to-buffer/4.0.0:
|
||||
resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==}
|
||||
engines: {node: '>= 12'}
|
||||
dev: false
|
||||
|
||||
/dataloader/1.4.0:
|
||||
resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==}
|
||||
|
@ -9674,7 +9682,7 @@ packages:
|
|||
resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
'@types/node': 17.0.32
|
||||
'@types/node': 17.0.35
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
@ -10690,6 +10698,7 @@ packages:
|
|||
data-uri-to-buffer: 4.0.0
|
||||
fetch-blob: 3.1.5
|
||||
formdata-polyfill: 4.0.10
|
||||
dev: false
|
||||
|
||||
/node-gyp-build/4.4.0:
|
||||
resolution: {integrity: sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==}
|
||||
|
|
Loading…
Reference in a new issue