[ci] format
This commit is contained in:
parent
57f8d14c02
commit
eb459577f0
33 changed files with 225 additions and 202 deletions
|
@ -453,8 +453,6 @@ export interface AstroUserConfig {
|
|||
*/
|
||||
cacheDir?: string;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @docs
|
||||
* @name redirects (Experimental)
|
||||
|
@ -462,12 +460,12 @@ export interface AstroUserConfig {
|
|||
* @default `{}`
|
||||
* @version 2.6.0
|
||||
* @description Specify a mapping of redirects where the key is the route to match
|
||||
* and the value is the path to redirect to.
|
||||
* and the value is the path to redirect to.
|
||||
*
|
||||
* You can redirect both static and dynamic routes, but only to the same kind of route.
|
||||
* For example you cannot have a `'/article': '/blog/[...slug]'` redirect.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* redirects: {
|
||||
|
@ -477,16 +475,16 @@ export interface AstroUserConfig {
|
|||
* }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
*
|
||||
* For statically-generated sites with no adapter installed, this will produce a client redirect using a [`<meta http-equiv="refresh">` tag](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#http-equiv) and does not support status codes.
|
||||
*
|
||||
* When using SSR or with a static adapter in `output: static`
|
||||
* mode, status codes are supported.
|
||||
* Astro will serve redirected GET requests with a status of `301`
|
||||
* and use a status of `308` for any other request method.
|
||||
*
|
||||
*
|
||||
* You can customize the [redirection status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages) using an object in the redirect config:
|
||||
*
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* redirects: {
|
||||
|
@ -791,8 +789,8 @@ export interface AstroUserConfig {
|
|||
* Specifies whether redirects will be output to HTML during the build.
|
||||
* This option only applies to `output: 'static'` mode; in SSR redirects
|
||||
* are treated the same as all responses.
|
||||
*
|
||||
* This option is mostly meant to be used by adapters that have special
|
||||
*
|
||||
* This option is mostly meant to be used by adapters that have special
|
||||
* configuration files for redirects and do not need/want HTML based redirects.
|
||||
*
|
||||
* ```js
|
||||
|
@ -1270,7 +1268,7 @@ export interface AstroUserConfig {
|
|||
* }
|
||||
* ```
|
||||
*/
|
||||
redirects?: boolean;
|
||||
redirects?: boolean;
|
||||
};
|
||||
|
||||
// Legacy options to be removed
|
||||
|
@ -1924,10 +1922,12 @@ export interface RoutePart {
|
|||
spread: boolean;
|
||||
}
|
||||
|
||||
type RedirectConfig = string | {
|
||||
status: ValidRedirectStatus;
|
||||
destination: string;
|
||||
}
|
||||
type RedirectConfig =
|
||||
| string
|
||||
| {
|
||||
status: ValidRedirectStatus;
|
||||
destination: string;
|
||||
};
|
||||
|
||||
export interface RouteData {
|
||||
route: string;
|
||||
|
@ -1947,7 +1947,7 @@ export interface RouteData {
|
|||
|
||||
export type RedirectRouteData = RouteData & {
|
||||
redirect: string;
|
||||
}
|
||||
};
|
||||
|
||||
export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern'> & {
|
||||
generate: undefined;
|
||||
|
|
|
@ -15,6 +15,7 @@ import { consoleLogDestination } from '../logger/console.js';
|
|||
import { error, type LogOptions } from '../logger/core.js';
|
||||
import { callMiddleware } from '../middleware/callMiddleware.js';
|
||||
import { prependForwardSlash, removeTrailingForwardSlash } from '../path.js';
|
||||
import { RedirectComponentInstance } from '../redirects/index.js';
|
||||
import {
|
||||
createEnvironment,
|
||||
createRenderContext,
|
||||
|
@ -28,7 +29,6 @@ import {
|
|||
createStylesheetElementSet,
|
||||
} from '../render/ssr-element.js';
|
||||
import { matchRoute } from '../routing/match.js';
|
||||
import { RedirectComponentInstance } from '../redirects/index.js';
|
||||
export { deserializeManifest } from './common.js';
|
||||
|
||||
const clientLocalsSymbol = Symbol.for('astro.locals');
|
||||
|
@ -172,12 +172,14 @@ export class App {
|
|||
}
|
||||
|
||||
async #getModuleForRoute(route: RouteData): Promise<ComponentInstance> {
|
||||
if(route.type === 'redirect') {
|
||||
if (route.type === 'redirect') {
|
||||
return RedirectComponentInstance;
|
||||
} else {
|
||||
const importComponentInstance = this.#manifest.pageMap.get(route.component);
|
||||
if(!importComponentInstance) {
|
||||
throw new Error(`Unexpectedly unable to find a component instance for route ${route.route}`);
|
||||
if (!importComponentInstance) {
|
||||
throw new Error(
|
||||
`Unexpectedly unable to find a component instance for route ${route.route}`
|
||||
);
|
||||
}
|
||||
const built = await importComponentInstance();
|
||||
return built.page();
|
||||
|
|
|
@ -12,7 +12,6 @@ import type {
|
|||
EndpointOutput,
|
||||
ImageTransform,
|
||||
MiddlewareResponseHandler,
|
||||
RedirectRouteData,
|
||||
RouteData,
|
||||
RouteType,
|
||||
SSRError,
|
||||
|
@ -24,9 +23,9 @@ import {
|
|||
} from '../../assets/generate.js';
|
||||
import {
|
||||
eachPageDataFromEntryPoint,
|
||||
eachRedirectPageData,
|
||||
hasPrerenderedPages,
|
||||
type BuildInternals,
|
||||
eachRedirectPageData,
|
||||
} from '../../core/build/internal.js';
|
||||
import {
|
||||
prependForwardSlash,
|
||||
|
@ -40,10 +39,14 @@ import { callEndpoint, createAPIContext, throwIfRedirectNotAllowed } from '../en
|
|||
import { AstroError } from '../errors/index.js';
|
||||
import { debug, info } from '../logger/core.js';
|
||||
import { callMiddleware } from '../middleware/callMiddleware.js';
|
||||
import {
|
||||
getRedirectLocationOrThrow,
|
||||
RedirectComponentInstance,
|
||||
routeIsRedirect,
|
||||
} from '../redirects/index.js';
|
||||
import { createEnvironment, createRenderContext, renderPage } from '../render/index.js';
|
||||
import { callGetStaticPaths } from '../render/route-cache.js';
|
||||
import { getRedirectLocationOrThrow, RedirectComponentInstance, routeIsRedirect } from '../redirects/index.js';
|
||||
import {
|
||||
import {
|
||||
createAssetLink,
|
||||
createModuleScriptsSet,
|
||||
createStylesheetElementSet,
|
||||
|
@ -52,7 +55,12 @@ import { createRequest } from '../request.js';
|
|||
import { matchRoute } from '../routing/match.js';
|
||||
import { getOutputFilename } from '../util.js';
|
||||
import { getOutDirWithinCwd, getOutFile, getOutFolder } from './common.js';
|
||||
import { cssOrder, getPageDataByComponent, mergeInlineCss, getEntryFilePathFromComponentPath } from './internal.js';
|
||||
import {
|
||||
cssOrder,
|
||||
getEntryFilePathFromComponentPath,
|
||||
getPageDataByComponent,
|
||||
mergeInlineCss,
|
||||
} from './internal.js';
|
||||
import type {
|
||||
PageBuildData,
|
||||
SinglePageBuiltModule,
|
||||
|
@ -62,24 +70,24 @@ import type {
|
|||
import { getTimeStat } from './util.js';
|
||||
|
||||
const StaticMiddlewareInstance: AstroMiddlewareInstance<unknown> = {
|
||||
onRequest: (ctx, next) => next()
|
||||
onRequest: (ctx, next) => next(),
|
||||
};
|
||||
|
||||
function createEntryURL(filePath: string, outFolder: URL) {
|
||||
return new URL('./' + filePath + `?time=${Date.now()}`, outFolder);
|
||||
}
|
||||
}
|
||||
|
||||
async function getEntryForRedirectRoute(
|
||||
route: RouteData,
|
||||
internals: BuildInternals,
|
||||
outFolder: URL
|
||||
): Promise<SinglePageBuiltModule> {
|
||||
if(route.type !== 'redirect') {
|
||||
if (route.type !== 'redirect') {
|
||||
throw new Error(`Expected a redirect route.`);
|
||||
}
|
||||
if(route.redirectRoute) {
|
||||
if (route.redirectRoute) {
|
||||
const filePath = getEntryFilePathFromComponentPath(internals, route.redirectRoute.component);
|
||||
if(filePath) {
|
||||
if (filePath) {
|
||||
const url = createEntryURL(filePath, outFolder);
|
||||
const ssrEntryPage: SinglePageBuiltModule = await import(url.toString());
|
||||
return ssrEntryPage;
|
||||
|
@ -89,8 +97,8 @@ async function getEntryForRedirectRoute(
|
|||
return {
|
||||
page: () => Promise.resolve(RedirectComponentInstance),
|
||||
middleware: StaticMiddlewareInstance,
|
||||
renderers: []
|
||||
}
|
||||
renderers: [],
|
||||
};
|
||||
}
|
||||
|
||||
function shouldSkipDraft(pageModule: ComponentInstance, settings: AstroSettings): boolean {
|
||||
|
@ -143,13 +151,13 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
|
|||
if (ssr) {
|
||||
for (const [pageData, filePath] of eachPageDataFromEntryPoint(internals)) {
|
||||
if (pageData.route.prerender) {
|
||||
const ssrEntryURLPage =createEntryURL(filePath, outFolder);
|
||||
const ssrEntryURLPage = createEntryURL(filePath, outFolder);
|
||||
const ssrEntryPage: SinglePageBuiltModule = await import(ssrEntryURLPage.toString());
|
||||
|
||||
await generatePage(opts, internals, pageData, ssrEntryPage, builtPaths);
|
||||
}
|
||||
}
|
||||
for(const pageData of eachRedirectPageData(internals)) {
|
||||
for (const pageData of eachRedirectPageData(internals)) {
|
||||
const entry = await getEntryForRedirectRoute(pageData.route, internals, outFolder);
|
||||
await generatePage(opts, internals, pageData, entry, builtPaths);
|
||||
}
|
||||
|
@ -160,7 +168,7 @@ export async function generatePages(opts: StaticBuildOptions, internals: BuildIn
|
|||
|
||||
await generatePage(opts, internals, pageData, ssrEntryPage, builtPaths);
|
||||
}
|
||||
for(const pageData of eachRedirectPageData(internals)) {
|
||||
for (const pageData of eachRedirectPageData(internals)) {
|
||||
const entry = await getEntryForRedirectRoute(pageData.route, internals, outFolder);
|
||||
await generatePage(opts, internals, pageData, entry, builtPaths);
|
||||
}
|
||||
|
@ -208,7 +216,7 @@ async function generatePage(
|
|||
ssrEntry: SinglePageBuiltModule,
|
||||
builtPaths: Set<string>
|
||||
) {
|
||||
if(routeIsRedirect(pageData.route) &&!opts.settings.config.experimental.redirects) {
|
||||
if (routeIsRedirect(pageData.route) && !opts.settings.config.experimental.redirects) {
|
||||
throw new Error(`To use redirects first set experimental.redirects to \`true\``);
|
||||
}
|
||||
|
||||
|
@ -578,9 +586,9 @@ async function generatePath(
|
|||
throw err;
|
||||
}
|
||||
|
||||
if(response.status >= 300 && response.status < 400) {
|
||||
if (response.status >= 300 && response.status < 400) {
|
||||
// If redirects is set to false, don't output the HTML
|
||||
if(!opts.settings.config.build.redirects) {
|
||||
if (!opts.settings.config.build.redirects) {
|
||||
return;
|
||||
}
|
||||
const location = getRedirectLocationOrThrow(response.headers);
|
||||
|
@ -588,7 +596,7 @@ async function generatePath(
|
|||
<title>Redirecting to: ${location}</title>
|
||||
<meta http-equiv="refresh" content="0;url=${location}" />`;
|
||||
// A dynamic redirect, set the location so that integrations know about it.
|
||||
if(pageData.route.type !== 'redirect') {
|
||||
if (pageData.route.type !== 'redirect') {
|
||||
pageData.route.redirect = location;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -3,7 +3,11 @@ import type { SSRResult } from '../../@types/astro';
|
|||
import type { PageOptions } from '../../vite-plugin-astro/types';
|
||||
import { prependForwardSlash, removeFileExtension } from '../path.js';
|
||||
import { viteID } from '../util.js';
|
||||
import { ASTRO_PAGE_EXTENSION_POST_PATTERN, ASTRO_PAGE_MODULE_ID, getVirtualModulePageIdFromPath } from './plugins/plugin-pages.js';
|
||||
import {
|
||||
ASTRO_PAGE_EXTENSION_POST_PATTERN,
|
||||
ASTRO_PAGE_MODULE_ID,
|
||||
getVirtualModulePageIdFromPath,
|
||||
} from './plugins/plugin-pages.js';
|
||||
import type { PageBuildData, StylesheetAsset, ViteID } from './types';
|
||||
|
||||
export interface BuildInternals {
|
||||
|
@ -218,8 +222,8 @@ export function* eachPageData(internals: BuildInternals) {
|
|||
}
|
||||
|
||||
export function* eachRedirectPageData(internals: BuildInternals) {
|
||||
for(const pageData of eachPageData(internals)) {
|
||||
if(pageData.route.type === 'redirect') {
|
||||
for (const pageData of eachPageData(internals)) {
|
||||
if (pageData.route.type === 'redirect') {
|
||||
yield pageData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { extname } from 'node:path';
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import { routeIsRedirect } from '../../redirects/index.js';
|
||||
import { addRollupInput } from '../add-rollup-input.js';
|
||||
import { type BuildInternals } from '../internal.js';
|
||||
import type { AstroBuildPlugin } from '../plugin';
|
||||
import type { StaticBuildOptions } from '../types';
|
||||
import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js';
|
||||
import { routeIsRedirect } from '../../redirects/index.js';
|
||||
import { RENDERERS_MODULE_ID } from './plugin-renderers.js';
|
||||
|
||||
export const ASTRO_PAGE_MODULE_ID = '@astro-page:';
|
||||
|
@ -44,7 +44,7 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V
|
|||
const inputs: Set<string> = new Set();
|
||||
|
||||
for (const [path, pageData] of Object.entries(opts.allPages)) {
|
||||
if(routeIsRedirect(pageData.route)) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
inputs.add(getVirtualModulePageNameFromPath(path));
|
||||
|
|
|
@ -7,6 +7,7 @@ import { isHybridOutput } from '../../../prerender/utils.js';
|
|||
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../../vite-plugin-scripts/index.js';
|
||||
import type { SerializedRouteInfo, SerializedSSRManifest } from '../../app/types';
|
||||
import { joinPaths, prependForwardSlash } from '../../path.js';
|
||||
import { routeIsRedirect } from '../../redirects/index.js';
|
||||
import { serializeRouteData } from '../../routing/index.js';
|
||||
import { addRollupInput } from '../add-rollup-input.js';
|
||||
import { getOutFile, getOutFolder } from '../common.js';
|
||||
|
@ -14,7 +15,6 @@ import { cssOrder, mergeInlineCss, type BuildInternals } from '../internal.js';
|
|||
import type { AstroBuildPlugin } from '../plugin';
|
||||
import type { StaticBuildOptions } from '../types';
|
||||
import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js';
|
||||
import { routeIsRedirect } from '../../redirects/index.js';
|
||||
import { getVirtualModulePageNameFromPath } from './plugin-pages.js';
|
||||
import { RENDERERS_MODULE_ID } from './plugin-renderers.js';
|
||||
|
||||
|
@ -57,7 +57,7 @@ function vitePluginSSR(
|
|||
const pageMap: string[] = [];
|
||||
|
||||
for (const [path, pageData] of Object.entries(allPages)) {
|
||||
if(routeIsRedirect(pageData.route)) {
|
||||
if (routeIsRedirect(pageData.route)) {
|
||||
continue;
|
||||
}
|
||||
const virtualModuleName = getVirtualModulePageNameFromPath(path);
|
||||
|
|
|
@ -107,7 +107,7 @@ export function resolveFlags(flags: Partial<Flags>): CLIFlags {
|
|||
experimentalMiddleware:
|
||||
typeof flags.experimentalMiddleware === 'boolean' ? flags.experimentalMiddleware : undefined,
|
||||
experimentalRedirects:
|
||||
typeof flags.experimentalRedirects === 'boolean' ? flags.experimentalRedirects : undefined
|
||||
typeof flags.experimentalRedirects === 'boolean' ? flags.experimentalRedirects : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -750,12 +750,12 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati
|
|||
`\`Astro.glob(${globStr})\` did not return any matching files. Check the pattern for typos.`,
|
||||
},
|
||||
/**
|
||||
* @docs
|
||||
* @see
|
||||
* - [Astro.redirect](https://docs.astro.build/en/guides/server-side-rendering/#astroredirect)
|
||||
* @description
|
||||
* A redirect must be given a location with the `Location` header.
|
||||
*/
|
||||
* @docs
|
||||
* @see
|
||||
* - [Astro.redirect](https://docs.astro.build/en/guides/server-side-rendering/#astroredirect)
|
||||
* @description
|
||||
* A redirect must be given a location with the `Location` header.
|
||||
*/
|
||||
RedirectWithNoLocation: {
|
||||
title: 'A redirect must be given a location with the `Location` header.',
|
||||
code: 3037,
|
||||
|
|
|
@ -4,7 +4,7 @@ import type { ComponentInstance } from '../../@types/astro';
|
|||
export const RedirectComponentInstance: ComponentInstance = {
|
||||
default() {
|
||||
return new Response(null, {
|
||||
status: 301
|
||||
status: 301,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { RouteData, RedirectRouteData, Params, ValidRedirectStatus } from '../../@types/astro';
|
||||
import type { Params, RedirectRouteData, RouteData, ValidRedirectStatus } from '../../@types/astro';
|
||||
|
||||
export function routeIsRedirect(route: RouteData | undefined): route is RedirectRouteData {
|
||||
return route?.type === 'redirect';
|
||||
|
@ -8,11 +8,11 @@ export function redirectRouteGenerate(redirectRoute: RouteData, data: Params): s
|
|||
const routeData = redirectRoute.redirectRoute;
|
||||
const route = redirectRoute.redirect;
|
||||
|
||||
if(typeof routeData !== 'undefined') {
|
||||
if (typeof routeData !== 'undefined') {
|
||||
return routeData?.generate(data) || routeData?.pathname || '/';
|
||||
} else if(typeof route === 'string') {
|
||||
} else if (typeof route === 'string') {
|
||||
return route;
|
||||
} else if(typeof route === 'undefined') {
|
||||
} else if (typeof route === 'undefined') {
|
||||
return '/';
|
||||
}
|
||||
return route.destination;
|
||||
|
@ -20,9 +20,9 @@ export function redirectRouteGenerate(redirectRoute: RouteData, data: Params): s
|
|||
|
||||
export function redirectRouteStatus(redirectRoute: RouteData, method = 'GET'): ValidRedirectStatus {
|
||||
const routeData = redirectRoute.redirectRoute;
|
||||
if(typeof routeData?.redirect === 'object') {
|
||||
if (typeof routeData?.redirect === 'object') {
|
||||
return routeData.redirect.status;
|
||||
} else if(method !== 'GET') {
|
||||
} else if (method !== 'GET') {
|
||||
return 308;
|
||||
}
|
||||
return 301;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export { getRedirectLocationOrThrow } from './validate.js';
|
||||
export { routeIsRedirect, redirectRouteGenerate, redirectRouteStatus } from './helpers.js';
|
||||
export { RedirectComponentInstance } from './component.js';
|
||||
export { redirectRouteGenerate, redirectRouteStatus, routeIsRedirect } from './helpers.js';
|
||||
export { getRedirectLocationOrThrow } from './validate.js';
|
||||
|
|
|
@ -3,9 +3,9 @@ import { AstroError, AstroErrorData } from '../errors/index.js';
|
|||
export function getRedirectLocationOrThrow(headers: Headers): string {
|
||||
let location = headers.get('location');
|
||||
|
||||
if(!location) {
|
||||
if (!location) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.RedirectWithNoLocation
|
||||
...AstroErrorData.RedirectWithNoLocation,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ import { renderPage as runtimeRenderPage } from '../../runtime/server/index.js';
|
|||
import { attachToResponse } from '../cookies/index.js';
|
||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||
import type { LogOptions } from '../logger/core.js';
|
||||
import { redirectRouteGenerate, redirectRouteStatus, routeIsRedirect } from '../redirects/index.js';
|
||||
import { getParams } from '../routing/params.js';
|
||||
import type { RenderContext } from './context.js';
|
||||
import type { Environment } from './environment.js';
|
||||
import { createResult } from './result.js';
|
||||
import { callGetStaticPaths, findPathItemByKey, RouteCache } from './route-cache.js';
|
||||
import { routeIsRedirect, redirectRouteGenerate, redirectRouteStatus } from '../redirects/index.js';
|
||||
|
||||
interface GetParamsAndPropsOptions {
|
||||
mod: ComponentInstance;
|
||||
|
@ -113,18 +113,18 @@ export type RenderPage = {
|
|||
};
|
||||
|
||||
export async function renderPage({
|
||||
mod,
|
||||
renderContext,
|
||||
env,
|
||||
apiContext,
|
||||
isCompressHTML = false,
|
||||
mod,
|
||||
renderContext,
|
||||
env,
|
||||
apiContext,
|
||||
isCompressHTML = false,
|
||||
}: RenderPage) {
|
||||
if(routeIsRedirect(renderContext.route)) {
|
||||
if (routeIsRedirect(renderContext.route)) {
|
||||
return new Response(null, {
|
||||
status: redirectRouteStatus(renderContext.route, renderContext.request.method),
|
||||
headers: {
|
||||
location: redirectRouteGenerate(renderContext.route, renderContext.params)
|
||||
}
|
||||
location: redirectRouteGenerate(renderContext.route, renderContext.params),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -212,12 +212,12 @@ function injectedRouteToItem(
|
|||
// Seeings if the two routes are siblings of each other, with `b` being the route
|
||||
// in focus. If it is in the same parent folder as `a`, they are siblings.
|
||||
function areSiblings(a: RouteData, b: RouteData) {
|
||||
if(a.segments.length < b.segments.length) return false;
|
||||
for(let i = 0; i < b.segments.length - 1; i++) {
|
||||
if (a.segments.length < b.segments.length) return false;
|
||||
for (let i = 0; i < b.segments.length - 1; i++) {
|
||||
let segment = b.segments[i];
|
||||
if(segment.length === a.segments[i].length) {
|
||||
for(let j = 0; j < segment.length; j++) {
|
||||
if(!areSamePart(segment[j], a.segments[i][j])) {
|
||||
if (segment.length === a.segments[i].length) {
|
||||
for (let j = 0; j < segment.length; j++) {
|
||||
if (!areSamePart(segment[j], a.segments[i][j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -448,12 +448,12 @@ export function createRouteManifest(
|
|||
const trailingSlash = config.trailingSlash;
|
||||
|
||||
const segments = removeLeadingForwardSlash(from)
|
||||
.split(path.posix.sep)
|
||||
.filter(Boolean)
|
||||
.map((s: string) => {
|
||||
validateSegment(s);
|
||||
return getParts(s, from);
|
||||
});
|
||||
.split(path.posix.sep)
|
||||
.filter(Boolean)
|
||||
.map((s: string) => {
|
||||
validateSegment(s);
|
||||
return getParts(s, from);
|
||||
});
|
||||
|
||||
const pattern = getPattern(segments, settings.config.base, trailingSlash);
|
||||
const generate = getRouteGenerator(segments, trailingSlash);
|
||||
|
@ -479,9 +479,9 @@ export function createRouteManifest(
|
|||
pathname: pathname || void 0,
|
||||
prerender: false,
|
||||
redirect: to,
|
||||
redirectRoute: routes.find(r => r.route === to)
|
||||
redirectRoute: routes.find((r) => r.route === to),
|
||||
};
|
||||
|
||||
|
||||
// Push so that redirects are selected last.
|
||||
routes.push(routeData);
|
||||
});
|
||||
|
@ -490,4 +490,3 @@ export function createRouteManifest(
|
|||
routes,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ export function stringifyChunk(
|
|||
return renderAllHeadContent(result);
|
||||
}
|
||||
default: {
|
||||
if(chunk instanceof Response) {
|
||||
if (chunk instanceof Response) {
|
||||
return '';
|
||||
}
|
||||
throw new Error(`Unknown chunk type: ${(chunk as any).type}`);
|
||||
|
@ -108,7 +108,7 @@ export function chunkToByteArray(
|
|||
if (chunk instanceof Uint8Array) {
|
||||
return chunk as Uint8Array;
|
||||
}
|
||||
|
||||
|
||||
// stringify chunk might return a HTMLString
|
||||
let stringified = stringifyChunk(result, chunk);
|
||||
return encoder.encode(stringified.toString());
|
||||
|
|
|
@ -129,10 +129,13 @@ export async function handleRoute(
|
|||
return handle404Response(origin, req, res);
|
||||
}
|
||||
|
||||
if(matchedRoute.route.type === 'redirect' && !settings.config.experimental.redirects) {
|
||||
writeWebResponse(res, new Response(`To enable redirect set experimental.redirects to \`true\`.`, {
|
||||
status: 400
|
||||
}));
|
||||
if (matchedRoute.route.type === 'redirect' && !settings.config.experimental.redirects) {
|
||||
writeWebResponse(
|
||||
res,
|
||||
new Response(`To enable redirect set experimental.redirects to \`true\`.`, {
|
||||
status: 400,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ describe('Astro.redirect', () => {
|
|||
output: 'server',
|
||||
adapter: testAdapter(),
|
||||
redirects: {
|
||||
'/api/redirect': '/'
|
||||
'/api/redirect': '/',
|
||||
},
|
||||
experimental: {
|
||||
redirects: true,
|
||||
|
@ -21,7 +21,7 @@ describe('Astro.redirect', () => {
|
|||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
|
||||
it('Returns a 302 status', async () => {
|
||||
const app = await fixture.loadTestAdapterApp();
|
||||
const request = new Request('http://example.com/secret');
|
||||
|
@ -29,7 +29,7 @@ describe('Astro.redirect', () => {
|
|||
expect(response.status).to.equal(302);
|
||||
expect(response.headers.get('location')).to.equal('/login');
|
||||
});
|
||||
|
||||
|
||||
it('Warns when used inside a component', async () => {
|
||||
const app = await fixture.loadTestAdapterApp();
|
||||
const request = new Request('http://example.com/late');
|
||||
|
@ -56,7 +56,7 @@ describe('Astro.redirect', () => {
|
|||
it('Uses 308 for non-GET methods', async () => {
|
||||
const app = await fixture.loadTestAdapterApp();
|
||||
const request = new Request('http://example.com/api/redirect', {
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
});
|
||||
const response = await app.render(request);
|
||||
expect(response.status).to.equal(308);
|
||||
|
@ -80,13 +80,13 @@ describe('Astro.redirect', () => {
|
|||
'/blog/[...slug]': '/articles/[...slug]',
|
||||
'/three': {
|
||||
status: 302,
|
||||
destination: '/'
|
||||
}
|
||||
}
|
||||
destination: '/',
|
||||
},
|
||||
},
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
||||
|
||||
it('Includes the meta refresh tag in Astro.redirect pages', async () => {
|
||||
const html = await fixture.readFile('/secret/index.html');
|
||||
expect(html).to.include('http-equiv="refresh');
|
||||
|
@ -131,10 +131,10 @@ describe('Astro.redirect', () => {
|
|||
root: './fixtures/ssr-redirect/',
|
||||
output: 'static',
|
||||
redirects: {
|
||||
'/one': '/'
|
||||
'/one': '/',
|
||||
},
|
||||
build: {
|
||||
redirects: false
|
||||
redirects: false,
|
||||
},
|
||||
experimental: {
|
||||
redirects: true,
|
||||
|
@ -149,6 +149,6 @@ describe('Astro.redirect', () => {
|
|||
oneHtml = await fixture.readFile('/one/index.html');
|
||||
} catch {}
|
||||
expect(oneHtml).be.an('undefined');
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('routing - createRouteManifest', () => {
|
|||
redirects: {
|
||||
'/blog/[...slug]': '/',
|
||||
'/blog/contributing': '/another',
|
||||
}
|
||||
},
|
||||
},
|
||||
root
|
||||
);
|
||||
|
@ -56,9 +56,9 @@ describe('routing - createRouteManifest', () => {
|
|||
settings,
|
||||
fsMod: fs,
|
||||
});
|
||||
|
||||
|
||||
expect(manifest.routes[1].route).to.equal('/blog/contributing');
|
||||
expect(manifest.routes[1].type).to.equal('page');
|
||||
expect(manifest.routes[2].route).to.equal('/blog/[...slug]');
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
|
||||
import type { AstroAdapter, AstroConfig, AstroIntegration } from 'astro';
|
||||
import { createRedirectsFromAstroRoutes, type Redirects } from '@astrojs/underscore-redirects';
|
||||
import esbuild from 'esbuild';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
|
@ -199,13 +199,13 @@ export default function createIntegration(args?: Options): AstroIntegration {
|
|||
}
|
||||
}
|
||||
|
||||
const redirectRoutes = routes.filter(r => r.type === 'redirect');
|
||||
const redirectRoutes = routes.filter((r) => r.type === 'redirect');
|
||||
const trueRedirects = createRedirectsFromAstroRoutes({
|
||||
config: _config,
|
||||
routes: redirectRoutes,
|
||||
dir,
|
||||
});
|
||||
if(!trueRedirects.empty()) {
|
||||
if (!trueRedirects.empty()) {
|
||||
await fs.promises.appendFile(
|
||||
new URL('./_redirects', _config.outDir),
|
||||
trueRedirects.print()
|
||||
|
|
|
@ -12,7 +12,7 @@ describe('mode: "directory"', () => {
|
|||
output: 'server',
|
||||
adapter: cloudflare({ mode: 'directory' }),
|
||||
redirects: {
|
||||
'/old': '/'
|
||||
'/old': '/',
|
||||
},
|
||||
experimental: {
|
||||
redirects: true,
|
||||
|
@ -30,9 +30,7 @@ describe('mode: "directory"', () => {
|
|||
try {
|
||||
let _redirects = await fixture.readFile('/_redirects');
|
||||
let parts = _redirects.split(/\s+/);
|
||||
expect(parts).to.deep.equal([
|
||||
'/old', '/', '301'
|
||||
]);
|
||||
expect(parts).to.deep.equal(['/old', '/', '301']);
|
||||
} catch {
|
||||
expect(false).to.equal(true);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'astro';
|
||||
import type { Args } from './netlify-functions.js';
|
||||
import type { AstroIntegration } from 'astro';
|
||||
import { createRedirects } from './shared.js';
|
||||
|
||||
export function netlifyStatic(): AstroIntegration {
|
||||
|
@ -20,7 +19,7 @@ export function netlifyStatic(): AstroIntegration {
|
|||
},
|
||||
'astro:build:done': async ({ dir, routes }) => {
|
||||
await createRedirects(_config, routes, dir, '', 'static');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { AstroConfig, RouteData } from 'astro';
|
||||
import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
|
||||
import type { AstroConfig, RouteData } from 'astro';
|
||||
import fs from 'node:fs';
|
||||
|
||||
export async function createRedirects(
|
||||
|
@ -14,7 +14,10 @@ export async function createRedirects(
|
|||
const _redirectsURL = new URL('./_redirects', dir);
|
||||
|
||||
const _redirects = createRedirectsFromAstroRoutes({
|
||||
config, routes, dir, dynamicTarget
|
||||
config,
|
||||
routes,
|
||||
dir,
|
||||
dynamicTarget,
|
||||
});
|
||||
const content = _redirects.print();
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ describe('SSG - Redirects', () => {
|
|||
site: `http://example.com`,
|
||||
integrations: [testIntegration()],
|
||||
redirects: {
|
||||
'/other': '/'
|
||||
'/other': '/',
|
||||
},
|
||||
experimental: {
|
||||
redirects: true,
|
||||
|
@ -31,14 +31,22 @@ describe('SSG - Redirects', () => {
|
|||
let redirects = await fixture.readFile('/_redirects');
|
||||
let parts = redirects.split(/\s+/);
|
||||
expect(parts).to.deep.equal([
|
||||
'/other', '/', '301',
|
||||
'/other',
|
||||
'/',
|
||||
'301',
|
||||
// This uses the dynamic Astro.redirect, so we don't know that it's a redirect
|
||||
// until runtime. This is correct!
|
||||
'/nope', '/.netlify/functions/entry', '200',
|
||||
'/', '/.netlify/functions/entry', '200',
|
||||
'/nope',
|
||||
'/.netlify/functions/entry',
|
||||
'200',
|
||||
'/',
|
||||
'/.netlify/functions/entry',
|
||||
'200',
|
||||
|
||||
// A real route
|
||||
'/team/articles/*', '/.netlify/functions/entry', '200',
|
||||
'/team/articles/*',
|
||||
'/.netlify/functions/entry',
|
||||
'200',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,10 +20,10 @@ describe('SSG - Redirects', () => {
|
|||
'/other': '/',
|
||||
'/two': {
|
||||
status: 302,
|
||||
destination: '/'
|
||||
destination: '/',
|
||||
},
|
||||
'/blog/[...slug]': '/team/articles/[...slug]'
|
||||
}
|
||||
'/blog/[...slug]': '/team/articles/[...slug]',
|
||||
},
|
||||
});
|
||||
await fixture.build();
|
||||
});
|
||||
|
@ -32,12 +32,22 @@ describe('SSG - Redirects', () => {
|
|||
let redirects = await fixture.readFile('/_redirects');
|
||||
let parts = redirects.split(/\s+/);
|
||||
expect(parts).to.deep.equal([
|
||||
'/two', '/', '302',
|
||||
'/other', '/', '301',
|
||||
'/nope', '/', '301',
|
||||
'/two',
|
||||
'/',
|
||||
'302',
|
||||
'/other',
|
||||
'/',
|
||||
'301',
|
||||
'/nope',
|
||||
'/',
|
||||
'301',
|
||||
|
||||
'/blog/*', '/team/articles/*/index.html', '301',
|
||||
'/team/articles/*', '/team/articles/*/index.html', '200',
|
||||
'/blog/*',
|
||||
'/team/articles/*/index.html',
|
||||
'301',
|
||||
'/team/articles/*',
|
||||
'/team/articles/*/index.html',
|
||||
'200',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import type { AstroConfig, RouteData, RoutePart } from 'astro';
|
||||
import { appendForwardSlash } from '@astrojs/internal-helpers/path';
|
||||
import type { AstroConfig, RouteData, RoutePart } from 'astro';
|
||||
import nodePath from 'node:path';
|
||||
|
||||
const pathJoin = nodePath.posix.join;
|
||||
|
||||
|
||||
// https://vercel.com/docs/project-configuration#legacy/routes
|
||||
interface VercelRoute {
|
||||
src: string;
|
||||
|
@ -60,19 +59,19 @@ function getReplacePattern(segments: RoutePart[][]) {
|
|||
}
|
||||
|
||||
function getRedirectLocation(route: RouteData, config: AstroConfig): string {
|
||||
if(route.redirectRoute) {
|
||||
if (route.redirectRoute) {
|
||||
const pattern = getReplacePattern(route.redirectRoute.segments);
|
||||
const path = (config.trailingSlash === 'always' ? appendForwardSlash(pattern) : pattern);
|
||||
const path = config.trailingSlash === 'always' ? appendForwardSlash(pattern) : pattern;
|
||||
return pathJoin(config.base, path);
|
||||
} else if(typeof route.redirect === 'object') {
|
||||
} else if (typeof route.redirect === 'object') {
|
||||
return pathJoin(config.base, route.redirect.destination);
|
||||
} else {
|
||||
return pathJoin(config.base, route.redirect || '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRedirectStatus(route: RouteData): number {
|
||||
if(typeof route.redirect === 'object') {
|
||||
if (typeof route.redirect === 'object') {
|
||||
return route.redirect.status;
|
||||
}
|
||||
return 301;
|
||||
|
@ -81,14 +80,12 @@ function getRedirectStatus(route: RouteData): number {
|
|||
export function getRedirects(routes: RouteData[], config: AstroConfig): VercelRoute[] {
|
||||
let redirects: VercelRoute[] = [];
|
||||
|
||||
|
||||
|
||||
for(const route of routes) {
|
||||
if(route.type === 'redirect') {
|
||||
for (const route of routes) {
|
||||
if (route.type === 'redirect') {
|
||||
redirects.push({
|
||||
src: config.base + getMatchPattern(route.segments),
|
||||
headers: { Location: getRedirectLocation(route, config) },
|
||||
status: getRedirectStatus(route)
|
||||
status: getRedirectStatus(route),
|
||||
});
|
||||
} else if (route.type === 'page') {
|
||||
if (config.trailingSlash === 'always') {
|
||||
|
|
|
@ -14,7 +14,7 @@ describe('Redirects', () => {
|
|||
'/two': '/',
|
||||
'/three': {
|
||||
status: 302,
|
||||
destination: '/'
|
||||
destination: '/',
|
||||
},
|
||||
'/blog/[...slug]': '/team/articles/[...slug]',
|
||||
},
|
||||
|
@ -35,15 +35,15 @@ describe('Redirects', () => {
|
|||
it('define static routes', async () => {
|
||||
const config = await getConfig();
|
||||
|
||||
const oneRoute = config.routes.find(r => r.src === '/\\/one');
|
||||
const oneRoute = config.routes.find((r) => r.src === '/\\/one');
|
||||
expect(oneRoute.headers.Location).to.equal('/');
|
||||
expect(oneRoute.status).to.equal(301);
|
||||
|
||||
const twoRoute = config.routes.find(r => r.src === '/\\/two');
|
||||
|
||||
const twoRoute = config.routes.find((r) => r.src === '/\\/two');
|
||||
expect(twoRoute.headers.Location).to.equal('/');
|
||||
expect(twoRoute.status).to.equal(301);
|
||||
|
||||
const threeRoute = config.routes.find(r => r.src === '/\\/three');
|
||||
const threeRoute = config.routes.find((r) => r.src === '/\\/three');
|
||||
expect(threeRoute.headers.Location).to.equal('/');
|
||||
expect(threeRoute.status).to.equal(302);
|
||||
});
|
||||
|
@ -51,7 +51,7 @@ describe('Redirects', () => {
|
|||
it('defines dynamic routes', async () => {
|
||||
const config = await getConfig();
|
||||
|
||||
const blogRoute = config.routes.find(r => r.src.startsWith('/\\/blog'));
|
||||
const blogRoute = config.routes.find((r) => r.src.startsWith('/\\/blog'));
|
||||
expect(blogRoute).to.not.be.undefined;
|
||||
expect(blogRoute.headers.Location.startsWith('/team/articles')).to.equal(true);
|
||||
expect(blogRoute.status).to.equal(301);
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type { AstroConfig, RouteData, ValidRedirectStatus } from 'astro';
|
||||
import { Redirects } from './redirects.js';
|
||||
import { posix } from 'node:path';
|
||||
import { Redirects } from './redirects.js';
|
||||
|
||||
const pathJoin = posix.join;
|
||||
|
||||
function getRedirectStatus(route: RouteData): ValidRedirectStatus {
|
||||
if(typeof route.redirect === 'object') {
|
||||
if (typeof route.redirect === 'object') {
|
||||
return route.redirect.status;
|
||||
}
|
||||
return 301;
|
||||
|
@ -33,7 +33,7 @@ export function createRedirectsFromAstroRoutes({
|
|||
for (const route of routes) {
|
||||
// A route with a `pathname` is as static route.
|
||||
if (route.pathname) {
|
||||
if(route.redirect) {
|
||||
if (route.redirect) {
|
||||
// A redirect route without dynamic parts. Get the redirect status
|
||||
// from the user if provided.
|
||||
_redirects.add({
|
||||
|
@ -41,17 +41,15 @@ export function createRedirectsFromAstroRoutes({
|
|||
input: route.pathname,
|
||||
target: typeof route.redirect === 'object' ? route.redirect.destination : route.redirect,
|
||||
status: getRedirectStatus(route),
|
||||
weight: 2
|
||||
weight: 2,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this is a static build we don't want to add redirects to the HTML file.
|
||||
if(output === 'static') {
|
||||
if (output === 'static') {
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (route.distURL) {
|
||||
} else if (route.distURL) {
|
||||
_redirects.add({
|
||||
dynamic: false,
|
||||
input: route.pathname,
|
||||
|
@ -88,7 +86,7 @@ export function createRedirectsFromAstroRoutes({
|
|||
const targetRoute = route.redirectRoute ?? route;
|
||||
const targetPattern = generateDynamicPattern(targetRoute);
|
||||
let target = targetPattern;
|
||||
if(config.build.format === 'directory') {
|
||||
if (config.build.format === 'directory') {
|
||||
target = pathJoin(target, 'index.html');
|
||||
} else {
|
||||
target += '.html';
|
||||
|
|
|
@ -1,8 +1,2 @@
|
|||
export {
|
||||
Redirects,
|
||||
type RedirectDefinition
|
||||
} from './redirects.js';
|
||||
|
||||
export {
|
||||
createRedirectsFromAstroRoutes
|
||||
} from './astro.js';
|
||||
export { createRedirectsFromAstroRoutes } from './astro.js';
|
||||
export { Redirects, type RedirectDefinition } from './redirects.js';
|
||||
|
|
|
@ -17,7 +17,7 @@ export function print(
|
|||
let _redirects = '';
|
||||
|
||||
// Loop over the definitions
|
||||
for(let i = 0; i < definitions.length; i++) {
|
||||
for (let i = 0; i < definitions.length; i++) {
|
||||
let definition = definitions[i];
|
||||
// Figure out the number of spaces to add. We want at least 4 spaces
|
||||
// after the input. This ensure that all targets line up together.
|
||||
|
|
|
@ -46,24 +46,26 @@ export class Redirects {
|
|||
}
|
||||
|
||||
function binaryInsert<T>(sorted: T[], item: T, comparator: (a: T, b: T) => boolean) {
|
||||
if(sorted.length === 0) {
|
||||
sorted.push(item);
|
||||
return 0;
|
||||
}
|
||||
let low = 0, high = sorted.length - 1, mid = 0;
|
||||
while (low <= high) {
|
||||
mid = low + (high - low >> 1);
|
||||
if(comparator(sorted[mid], item)) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid -1;
|
||||
}
|
||||
}
|
||||
if (sorted.length === 0) {
|
||||
sorted.push(item);
|
||||
return 0;
|
||||
}
|
||||
let low = 0,
|
||||
high = sorted.length - 1,
|
||||
mid = 0;
|
||||
while (low <= high) {
|
||||
mid = low + ((high - low) >> 1);
|
||||
if (comparator(sorted[mid], item)) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(comparator(sorted[mid], item)) {
|
||||
mid++;
|
||||
}
|
||||
if (comparator(sorted[mid], item)) {
|
||||
mid++;
|
||||
}
|
||||
|
||||
sorted.splice(mid, 0, item);
|
||||
return mid;
|
||||
sorted.splice(mid, 0, item);
|
||||
return mid;
|
||||
}
|
||||
|
|
|
@ -4,20 +4,20 @@ import { expect } from 'chai';
|
|||
describe('Astro', () => {
|
||||
const serverConfig = {
|
||||
output: 'server',
|
||||
build: { format: 'directory' }
|
||||
build: { format: 'directory' },
|
||||
};
|
||||
|
||||
it('Creates a Redirects object from routes', () => {
|
||||
const routes = [
|
||||
{ pathname: '/', distURL: new URL('./index.html', import.meta.url), segments: [] },
|
||||
{ pathname: '/one', distURL: new URL('./one/index.html', import.meta.url), segments: [] }
|
||||
{ pathname: '/one', distURL: new URL('./one/index.html', import.meta.url), segments: [] },
|
||||
];
|
||||
const dynamicTarget = './.adapter/dist/entry.mjs';
|
||||
const _redirects = createRedirectsFromAstroRoutes({
|
||||
config: serverConfig,
|
||||
routes,
|
||||
dir: new URL(import.meta.url),
|
||||
dynamicTarget
|
||||
dynamicTarget,
|
||||
});
|
||||
|
||||
expect(_redirects.definitions).to.have.a.lengthOf(2);
|
||||
|
|
|
@ -9,17 +9,17 @@ describe('Printing', () => {
|
|||
input: '/a',
|
||||
target: '/b',
|
||||
weight: 0,
|
||||
status: 200
|
||||
status: 200,
|
||||
});
|
||||
_redirects.add({
|
||||
dynamic: false,
|
||||
input: '/some-pretty-long-input-line',
|
||||
target: '/b',
|
||||
weight: 0,
|
||||
status: 200
|
||||
status: 200,
|
||||
});
|
||||
let out = _redirects.print();
|
||||
|
||||
|
||||
let [lineOne, lineTwo] = out.split('\n');
|
||||
|
||||
expect(lineOne.indexOf('/b')).to.equal(lineTwo.indexOf('/b'), 'destinations lined up');
|
||||
|
@ -33,12 +33,10 @@ describe('Printing', () => {
|
|||
input: '/pets/:cat',
|
||||
target: '/pets/:cat/index.html',
|
||||
status: 200,
|
||||
weight: 1
|
||||
weight: 1,
|
||||
});
|
||||
let out = _redirects.print();
|
||||
let parts = out.split(/\s+/);
|
||||
expect(parts).to.deep.equal([
|
||||
'/pets/:cat', '/pets/:cat/index.html', '200',
|
||||
])
|
||||
expect(parts).to.deep.equal(['/pets/:cat', '/pets/:cat/index.html', '200']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,21 +9,21 @@ describe('Weight', () => {
|
|||
input: '/a',
|
||||
target: '/b',
|
||||
weight: 0,
|
||||
status: 200
|
||||
status: 200,
|
||||
});
|
||||
_redirects.add({
|
||||
dynamic: false,
|
||||
input: '/c',
|
||||
target: '/d',
|
||||
weight: 0,
|
||||
status: 200
|
||||
status: 200,
|
||||
});
|
||||
_redirects.add({
|
||||
dynamic: false,
|
||||
input: '/e',
|
||||
target: '/f',
|
||||
weight: 1,
|
||||
status: 200
|
||||
status: 200,
|
||||
});
|
||||
const firstDefn = _redirects.definitions[0];
|
||||
expect(firstDefn.weight).to.equal(1);
|
||||
|
|
Loading…
Reference in a new issue