Skip to content

Commit 3e1034b

Browse files
Sequence (#2222)
* feat: allow handle hooks to use middlewares * test: add test for hooks sequence * use lowercase header names (tests appear to fail otherwise?) * fix: always pass request to resolve * rename handles to handlers * use test/apps/basics to test sequence, rather than creating separate app * handles -> handlers Co-authored-by: Maxime LUCE <[email protected]>
1 parent 446c346 commit 3e1034b

File tree

5 files changed

+64
-16
lines changed

5 files changed

+64
-16
lines changed

packages/kit/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@
7171
"./node": {
7272
"import": "./dist/node.js"
7373
},
74+
"./hooks": {
75+
"import": "./dist/hooks.js"
76+
},
7477
"./install-fetch": {
7578
"import": "./dist/install-fetch.js"
7679
},

packages/kit/rollup.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default [
4848
cli: 'src/cli.js',
4949
ssr: 'src/runtime/server/index.js',
5050
node: 'src/core/node/index.js',
51+
hooks: 'src/runtime/hooks.js',
5152
'install-fetch': 'src/install-fetch.js',
5253
'adapter-utils': 'src/core/adapter-utils.js'
5354
},

packages/kit/src/runtime/hooks.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @param {...import('types/hooks').Handle} handlers
3+
* @returns {import('types/hooks').Handle}
4+
*/
5+
export function sequence(...handlers) {
6+
const length = handlers.length;
7+
if (!length) return ({ request, resolve }) => resolve(request);
8+
9+
return ({ request, resolve }) => {
10+
return apply_handle(0, request);
11+
12+
/**
13+
* @param {number} i
14+
* @param {import('types/hooks').ServerRequest} request
15+
* @returns {import('types/helper').MaybePromise<import('types/hooks').ServerResponse>}
16+
*/
17+
function apply_handle(i, request) {
18+
const handle = handlers[i];
19+
20+
return handle({
21+
request,
22+
resolve: i < length - 1 ? (request) => apply_handle(i + 1, request) : resolve
23+
});
24+
}
25+
};
26+
}

packages/kit/test/apps/basics/src/hooks.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
1+
import { sequence } from '../../../../src/runtime/hooks';
12
import cookie from 'cookie';
23

34
/** @type {import('@sveltejs/kit').GetSession} */
45
export function getSession(request) {
56
return request.locals;
67
}
78

8-
/** @type {import('@sveltejs/kit').Handle} */
9-
export async function handle({ request, resolve }) {
10-
const cookies = cookie.parse(request.headers.cookie || '');
9+
export const handle = sequence(
10+
({ request, resolve }) => {
11+
request.locals.answer = 42;
12+
return resolve(request);
13+
},
14+
({ request, resolve }) => {
15+
const cookies = cookie.parse(request.headers.cookie || '');
16+
request.locals.name = cookies.name;
17+
return resolve(request);
18+
},
19+
async ({ request, resolve }) => {
20+
const response = await resolve(request);
1121

12-
request.locals.answer = 42;
13-
request.locals.name = cookies.name;
14-
15-
const response = await resolve(request);
16-
17-
return {
18-
...response,
19-
headers: {
20-
...response.headers,
21-
'Set-Cookie': 'name=SvelteKit; path=/; HttpOnly'
22-
}
23-
};
24-
}
22+
return {
23+
...response,
24+
headers: {
25+
...response.headers,
26+
'Set-Cookie': 'name=SvelteKit; path=/; HttpOnly'
27+
}
28+
};
29+
}
30+
);
2531

2632
/** @type {import('@sveltejs/kit').ServerFetch} */
2733
export async function serverFetch(request) {

packages/kit/types/ambient-modules.d.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,15 @@ declare module '$service-worker' {
129129
*/
130130
export const timestamp: number;
131131
}
132+
133+
declare module '@sveltejs/kit/hooks' {
134+
type Handle = import('@sveltejs/kit').Handle;
135+
136+
/**
137+
* Utility function that allows chaining `handle` functions in a
138+
* middleware-like manner.
139+
*
140+
* @param handlers The chain of `handle` functions
141+
*/
142+
export function sequence(...handlers: Handle[]): Handle;
143+
}

0 commit comments

Comments
 (0)