Skip to content

Commit

Permalink
feat: add config "middlewareRoutes"
Browse files Browse the repository at this point in the history
  • Loading branch information
Ives7 authored Jul 6, 2022
1 parent e38b852 commit 33d58d0
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,23 @@ describe('middleware routes test', () => {
expect(result).toMatchObject({
routes: [
{
path: '/a',
middlewares: ['middleware.js', 'a/middleware.js']
path: '/a/:rest*',
middlewares: ['a/middleware.js']
},
{
path: '/b/b1',
middlewares: [
'middleware.js',
'b/middleware.js',
'b/b1/middleware.js'
]
path: '/b/b1/:rest*',
middlewares: ['b/b1/middleware.js']
},
{
path: '/b/b2',
middlewares: [
'middleware.js',
'b/middleware.js',
'b/b2/middleware.js'
]
path: '/b/b2/:rest*',
middlewares: ['b/b2/middleware.js']
},
{
path: '/b',
middlewares: ['middleware.js', 'b/middleware.js']
path: '/b/:rest*',
middlewares: ['b/middleware.js']
},
{
path: '/c',
middlewares: ['middleware.js']
},
{
path: '/',
path: '/:rest*',
middlewares: ['middleware.js']
}
],
Expand Down
54 changes: 18 additions & 36 deletions packages/platform-shared/src/node/route/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,61 +290,43 @@ export const getMiddlewareRoutes = async (
const _getMiddlewareRoutes = async (
rawRoutes: RawRoute[],
routes: IMiddlewareRouteConfig[],
segment: string,
parentMiddlewares: string[]
segment: string
) => {
segment = segment === '/' ? '' : segment;

const currentLevelMiddleware = rawRoutes.find(
route => route.kind === 'file' && route.type === 'middleware'
);

const middlewares = currentLevelMiddleware
? [...parentMiddlewares, currentLevelMiddleware.filepath]
: parentMiddlewares;

const hasLayout = rawRoutes.some(
route => route.kind === 'file' && route.type === 'layout'
);
const hasPage = rawRoutes.some(
route => route.kind === 'file' && route.type === 'page'
);

for (const rawRoute of rawRoutes) {
if (rawRoute.kind === 'dir') {
await _getMiddlewareRoutes(
rawRoute.children,
routes,
segment + '/' + rawRoute.parentSegment,
middlewares
segment + '/' + rawRoute.parentSegment
);
continue;
}

const isPage = rawRoute.type === 'page';
const isLayout = rawRoute.type === 'layout';
const isMiddleware = rawRoute.type === 'middleware';
const onlyHasPage = isPage && !hasLayout;
const onlyHasMiddleware = isMiddleware && !hasLayout && !hasPage;

if (isLayout || onlyHasPage || onlyHasMiddleware) {
if (middlewares.length) {
let path = segment + '/' + rawRoute.segment;
if (path === '//') {
path = '/';
}
routes.push({
path,
middlewares
});
if (rawRoute.type === 'middleware') {
let path = segment + '/' + rawRoute.segment;
let catchAllOp = '/:rest*';

if (path === '//') {
path = '/';
}

if (path === '/') {
catchAllOp = catchAllOp.slice(1);
}

routes.push({
path: path + catchAllOp,
middlewares: [rawRoute.filepath]
});
}
}

return routes;
};

const routes = await _getMiddlewareRoutes(rawRoutes, [], '', []);
const routes = await _getMiddlewareRoutes(rawRoutes, [], '');
routes.forEach(route => {
if (!route.path.startsWith('/')) {
route.path = `/${route.path}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default createPlugin({
},
addRuntimeFile: async ({ createFile }, context) => {
const {
config: { routes: pageRoutes, apiRoutes },
config: { routes: pageRoutes, middlewareRoutes, apiRoutes },
paths,
pluginRunner
} = context;
Expand Down Expand Up @@ -100,9 +100,9 @@ export default createPlugin({
name: 'middlewareRoutes.js',
content: async () => {
let routes: IMiddlewareRouteConfig[];
const hasConfigRoutes = Array.isArray(pageRoutes);
const hasConfigRoutes = Array.isArray(middlewareRoutes);
if (hasConfigRoutes) {
routes = pageRoutes as IMiddlewareRouteConfig[];
routes = middlewareRoutes;
} else {
const { routes: _routes, warnings } = await getMiddlewareRoutes(
paths.routesDir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ export function middleware(
const { middlewareRoutes = [] } = server;
// match path for get middlewares
let middlewares: IRequestHandlerWithNext[] = [];

for (let i = 0; i < middlewareRoutes.length; i++) {
const middlewareRoute = middlewareRoutes[i];
const match = matchPathname(middlewareRoute.path, req.pathname);
if (match) {
req.params = match.params;
middlewares = middlewareRoutes[i].middlewares || [];
break;
middlewares.unshift(...(middlewareRoutes[i].middlewares || []));
}
}

// run middlewares
let i = 0;
const runNext = () => runMiddleware(middlewares[++i]);
Expand Down
2 changes: 1 addition & 1 deletion packages/service/src/core/apiTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export interface IUserRouteConfig {
children?: IUserRouteConfig[];
name?: string;
component?: string;
middlewares?: string[];
redirect?: string;
path: string;
fullPath?: string;
Expand Down Expand Up @@ -160,6 +159,7 @@ export interface Config {
env?: Record<string, string>;
router?: IRouterConfig;
routes?: IUserRouteConfig[]; // generate by files what under src/pages or user defined
middlewareRoutes?: IMiddlewareRouteConfig[];
apiRoutes?: IApiRouteConfig[]; // generate by files what under src/apis or user defined
apiConfig?: IApiConfig;
runtimeConfig?: IRuntimeConfig;
Expand Down
56 changes: 56 additions & 0 deletions test/e2e/middleware-config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { AppCtx, launchFixture } from 'shuvi-test-utils';
import got from 'got';

jest.setTimeout(5 * 60 * 1000);

describe('Middleware config test', () => {
let ctx: AppCtx;

beforeAll(async () => {
ctx = await launchFixture('middlewares-config');
});

afterAll(async () => {
await ctx.close();
});

it('should get correct headers when visited /', async () => {
const res = await got.get(ctx.url('/'));

const inIndex = res.headers['in-index'];
const inA = res.headers['in-a'];
const inA1 = res.headers['in-a1'];
const correctResult = inIndex && !inA && !inA1;
const mOrder = res.headers['m-order'];

expect(correctResult).toBeTruthy();
expect(mOrder).toBe('-index');
});

it('should get correct headers when visited /a', async () => {
const res = await got.get(ctx.url('/a'));

const inIndex = res.headers['in-index'];
const inA = res.headers['in-a'];
const inA1 = res.headers['in-a1'];
const correctResult = !inIndex && inA && !inA1;
const mOrder = res.headers['m-order'];

expect(correctResult).toBeTruthy();
expect(mOrder).toBe('-a');
});

it('should get correct headers when visited /a/a1', async () => {
const res = await got.get(ctx.url('/a/a1'));

const inIndex = res.headers['in-index'];
const inA = res.headers['in-a'];
const inA1 = res.headers['in-a1'];
const correctResult = !inIndex && inA && inA1;
const mOrder = res.headers['m-order'];

expect(correctResult).toBeTruthy();

expect(mOrder).toBe('-a-a1');
});
});
17 changes: 17 additions & 0 deletions test/fixtures/middlewares-config/shuvi.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export default {
ssr: true,
middlewareRoutes: [
{
path: '/a/:rest*',
middlewares: ['a/m.js']
},
{
path: '/a/a1',
middlewares: ['a/a1/m.js']
},
{
path: '/',
middlewares: ['m.js']
}
]
};
6 changes: 6 additions & 0 deletions test/fixtures/middlewares-config/src/routes/a/a1/m.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function middleware(req, res, next) {
const mOrder = res.getHeader('m-order') || '';
res.setHeader('m-order', mOrder + '-a1');
res.setHeader('in-a1', '1');
next();
}
3 changes: 3 additions & 0 deletions test/fixtures/middlewares-config/src/routes/a/a1/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Index() {
return <div>index</div>;
}
6 changes: 6 additions & 0 deletions test/fixtures/middlewares-config/src/routes/a/m.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function middleware(req, res, next) {
const mOrder = res.getHeader('m-order') || '';
res.setHeader('m-order', mOrder + '-a');
res.setHeader('in-a', '1');
next();
}
3 changes: 3 additions & 0 deletions test/fixtures/middlewares-config/src/routes/a/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Index() {
return <div>index</div>;
}
5 changes: 5 additions & 0 deletions test/fixtures/middlewares-config/src/routes/m.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function middleware(req, res, next) {
res.setHeader('in-index', '1');
res.setHeader('m-order', '-index');
next();
}
3 changes: 3 additions & 0 deletions test/fixtures/middlewares-config/src/routes/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Index() {
return <div>index</div>;
}

0 comments on commit 33d58d0

Please sign in to comment.