next-ssr-middleware 0.10.0-rc.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ReadMe.md CHANGED
@@ -1,137 +1,165 @@
1
- # Next SSR middleware
2
-
3
- [Koa][1]-like middlewares for [Next.js][2] **Server Side Rendering**
4
-
5
- [![NPM Dependency](https://img.shields.io/librariesio/github/idea2app/Next-SSR-middleware.svg)][3]
6
- [![CI & CD](https://github.com/idea2app/Next-SSR-middleware/actions/workflows/main.yml/badge.svg)][4]
7
-
8
- [![NPM](https://nodei.co/npm/next-ssr-middleware.png?downloads=true&downloadRank=true&stars=true)][5]
9
-
10
- ## Versions
11
-
12
- | SemVer | status | Next.js | MobX | [MobX i18n][6] |
13
- | :----------: | :----------: | :-------: | :---------: | :------------: |
14
- | `>=0.9` | ✅developing | `>=15` | `>=6.11` | `>=0.5` |
15
- | `>=0.7 <0.9` | ❌deprecated | `>=9 <15` | `>=6.11` | `>=0.5` |
16
- | `<0.7` | ❌deprecated | `>=9 <15` | `>=4 <6.11` | `<0.5` |
17
-
18
- ## Middlewares
19
-
20
- 1. Router
21
- 2. Error logger
22
- 3. JWT verifier
23
- 4. Props cache
24
- 5. i18n loader
25
- 6. OAuth 2 signer (with common providers)
26
- 1. GitHub
27
-
28
- ## Usage
29
-
30
- ### Page router
31
-
32
- #### `pages/user/[id].tsx`
33
-
34
- ```tsx
35
- import {
36
- JWTProps,
37
- RouterProps,
38
- jwtVerifier,
39
- cache,
40
- errorLogger,
41
- router,
42
- translator
43
- } from 'next-ssr-middleware';
44
-
45
- import i18n from '../../model/Translation';
46
- import { User, UserModel } from '../../model/User';
47
-
48
- type UserDetailPageProps = User & JWTProps & RouterProps;
49
-
50
- export const getServerSideProps = compose<{ id: string }, UserDetailPageProps>(
51
- jwtVerifier(), // set `JWT_SECRET` in `.env.local` first
52
- cache(),
53
- errorLogger,
54
- router,
55
- translator(i18n),
56
- async ({ params }) => {
57
- const props = await new UserModel().getOne(params!.id);
58
-
59
- return { notFound: !props, props };
60
- }
61
- );
62
-
63
- export default function UserDetailPage({
64
- jwtPayload,
65
- route,
66
- name,
67
- summary
68
- }: UserDetailPageProps) {
69
- return (
70
- <>
71
- <h1>
72
- {name} - {route.params!.id}
73
- </h1>
74
- <p>{summary}</p>
75
- </>
76
- );
77
- }
78
- ```
79
-
80
- ### App router
81
-
82
- #### `middleware.ts`
83
-
84
- ```ts
85
- import { NextRequest, NextResponse } from 'next/server';
86
- import { parseHeaders } from 'next-ssr-middleware';
87
-
88
- export const config = {
89
- // Matcher ignoring `/_next/`, `/api/` & icons
90
- matcher: [
91
- '/((?!api|_next/static|_next/image|favicon.ico|apple-icon|icon).*)'
92
- ]
93
- };
94
- export const middleware = ({ headers }: NextRequest) =>
95
- NextResponse.next({ headers: parseHeaders(headers) });
96
- ```
97
-
98
- #### `app/page.tsx`
99
-
100
- ```tsx
101
- import { compose, withMiddleware, ServerProps } from 'next-ssr-middleware';
102
-
103
- const getServerSideProps = compose(async () => {
104
- const props = await (
105
- await fetch('https://api.github.com/orgs/idea2app')
106
- ).json();
107
-
108
- return { props };
109
- });
110
-
111
- const HomePage = withMiddleware(getServerSideProps, Home);
112
-
113
- export default HomePage;
114
-
115
- async function Home({ params, searchParams, ...props }: ServerProps) {
116
- return (
117
- <>
118
- <h1>Home</h1>
119
- <pre>{JSON.stringify(props, null, 4)}</pre>
120
- </>
121
- );
122
- }
123
- ```
124
-
125
- ## Cases
126
-
127
- 1. https://github.com/idea2app/Next-Bootstrap-ts
128
- 2. https://github.com/kaiyuanshe/kaiyuanshe.github.io
129
- 3. https://github.com/kaiyuanshe/OpenHackathon-Web
130
- 4. https://github.com/kaiyuanshe/OSS-toolbox
131
-
132
- [1]: https://koajs.com/
133
- [2]: https://nextjs.org/
134
- [3]: https://libraries.io/npm/next-ssr-middleware
135
- [4]: https://github.com/idea2app/Next-SSR-middleware/actions/workflows/main.yml
136
- [5]: https://nodei.co/npm/next-ssr-middleware/
137
- [6]: https://github.com/idea2app/MobX-i18n
1
+ # Next SSR middleware
2
+
3
+ [Koa][1]-like middlewares for [Next.js][2] **Back-end API** & **Server Side Rendering**
4
+
5
+ [![NPM Dependency](https://img.shields.io/librariesio/github/idea2app/Next-SSR-middleware.svg)][3]
6
+ [![CI & CD](https://github.com/idea2app/Next-SSR-middleware/actions/workflows/main.yml/badge.svg)][4]
7
+
8
+ [![NPM](https://nodei.co/npm/next-ssr-middleware.png?downloads=true&downloadRank=true&stars=true)][5]
9
+
10
+ ## Versions
11
+
12
+ | SemVer | status | Next.js | MobX | [MobX i18n][6] |
13
+ | :----------: | :----------: | :-------: | :---------: | :------------: |
14
+ | `>=0.9` | ✅developing | `>=15` | `>=6.11` | `>=0.5` |
15
+ | `>=0.7 <0.9` | ❌deprecated | `>=9 <15` | `>=6.11` | `>=0.5` |
16
+ | `<0.7` | ❌deprecated | `>=9 <15` | `>=4 <6.11` | `<0.5` |
17
+
18
+ ## Middlewares
19
+
20
+ 1. Router
21
+ 2. Error logger
22
+ 3. JWT verifier
23
+ 4. Props cache
24
+ 5. i18n loader
25
+ 6. OAuth 2 signer (with common providers)
26
+ 1. GitHub
27
+
28
+ ## Usage
29
+
30
+ ### Page router
31
+
32
+ #### `pages/user/[id].tsx`
33
+
34
+ ```tsx
35
+ import {
36
+ JWTProps,
37
+ RouterProps,
38
+ jwtVerifier,
39
+ cache,
40
+ errorLogger,
41
+ router,
42
+ translator
43
+ } from 'next-ssr-middleware';
44
+
45
+ import i18n from '../../model/Translation';
46
+ import { User, UserModel } from '../../model/User';
47
+
48
+ type UserDetailPageProps = User & JWTProps & RouterProps;
49
+
50
+ export const getServerSideProps = compose<{ id: string }, UserDetailPageProps>(
51
+ jwtVerifier(), // set `JWT_SECRET` in `.env.local` first
52
+ cache(),
53
+ errorLogger,
54
+ router,
55
+ translator(i18n),
56
+ async ({ params }) => {
57
+ const props = await new UserModel().getOne(params!.id);
58
+
59
+ return { notFound: !props, props };
60
+ }
61
+ );
62
+
63
+ export default function UserDetailPage({
64
+ jwtPayload,
65
+ route,
66
+ name,
67
+ summary
68
+ }: UserDetailPageProps) {
69
+ return (
70
+ <>
71
+ <h1>
72
+ {name} - {route.params!.id}
73
+ </h1>
74
+ <p>{summary}</p>
75
+ </>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ### App router
81
+
82
+ #### `middleware.ts`
83
+
84
+ ```ts
85
+ import { NextRequest, NextResponse } from 'next/server';
86
+ import { parseHeaders } from 'next-ssr-middleware';
87
+
88
+ export const config = {
89
+ // Matcher ignoring `/_next/`, `/api/` & icons
90
+ matcher: [
91
+ '/((?!api|_next/static|_next/image|favicon.ico|apple-icon|icon).*)'
92
+ ]
93
+ };
94
+ export const middleware = ({ headers }: NextRequest) =>
95
+ NextResponse.next({ headers: parseHeaders(headers) });
96
+ ```
97
+
98
+ #### `app/page.tsx`
99
+
100
+ ```tsx
101
+ import { compose, withMiddleware, ServerProps } from 'next-ssr-middleware';
102
+
103
+ const getServerSideProps = compose(async () => {
104
+ const props = await (
105
+ await fetch('https://api.github.com/orgs/idea2app')
106
+ ).json();
107
+
108
+ return { props };
109
+ });
110
+
111
+ const HomePage = withMiddleware(getServerSideProps, Home);
112
+
113
+ export default HomePage;
114
+
115
+ async function Home({ params, searchParams, ...props }: ServerProps) {
116
+ return (
117
+ <>
118
+ <h1>Home</h1>
119
+ <pre>{JSON.stringify(props, null, 4)}</pre>
120
+ </>
121
+ );
122
+ }
123
+ ```
124
+
125
+ ### API router
126
+
127
+ Located in [`pages/api/` of a Next.js project][7] or [`api/` of a Vercel serverless project][8].
128
+
129
+ #### `pages/api/echo.ts`
130
+
131
+ ```ts
132
+ import { createKoaRouter, withKoaRouter } from 'next-ssr-middleware';
133
+
134
+ export const config = { api: { bodyParser: false } };
135
+
136
+ const router = createKoaRouter(import.meta.url);
137
+
138
+ router
139
+ .get('/', async context => {
140
+ context.body = context.request.query;
141
+ })
142
+ .post('/', async context => {
143
+ context.status = 201;
144
+ context.body = Reflect.get(context.request, 'body');
145
+ });
146
+
147
+ export default withKoaRouter(router);
148
+ ```
149
+
150
+ ## Cases
151
+
152
+ 1. https://github.com/idea2app/Next-Bootstrap-ts
153
+ 2. https://github.com/FreeCodeCamp-Chengdu/FreeCodeCamp-Chengdu.github.io
154
+ 3. https://github.com/kaiyuanshe/kaiyuanshe.github.io
155
+ 4. https://github.com/kaiyuanshe/OpenHackathon-Web
156
+ 5. https://github.com/kaiyuanshe/OSS-toolbox
157
+
158
+ [1]: https://koajs.com/
159
+ [2]: https://nextjs.org/
160
+ [3]: https://libraries.io/npm/next-ssr-middleware
161
+ [4]: https://github.com/idea2app/Next-SSR-middleware/actions/workflows/main.yml
162
+ [5]: https://nodei.co/npm/next-ssr-middleware/
163
+ [6]: https://github.com/idea2app/MobX-i18n
164
+ [7]: https://github.com/idea2app/Lark-Next-Bootstrap-ts/tree/main/pages/api
165
+ [8]: https://github.com/idea2app/Vercel-Node-serverless/tree/master/api
package/dist/API.d.ts CHANGED
@@ -5,6 +5,6 @@ export type KoaCallback = ReturnType<(typeof Koa)['prototype']['callback']>;
5
5
  export declare function withKoa<S, C>(...middlewares: Middleware<S, C>[]): KoaCallback;
6
6
  export declare function withKoa<S, C>(option: KoaOption, ...middlewares: Middleware<S, C>[]): KoaCallback;
7
7
  export declare const pageApiRouteOf: (path: string) => string;
8
- export declare const createRouter: <S, C extends RouterParamContext<S>>(moduleURI: string, option?: RouterOptions) => Router<S, C>;
8
+ export declare const createKoaRouter: <S, C extends RouterParamContext<S>>(moduleURI: string, option?: RouterOptions) => Router<S, C>;
9
9
  export declare function withKoaRouter<S, C extends RouterParamContext<S>>(router: Router<S, C>, ...middlewares: Middleware<S, C>[]): KoaCallback;
10
10
  export declare function withKoaRouter<S, C extends RouterParamContext<S>>(option: KoaOption, router: Router<S, C>, ...middlewares: Middleware<S, C>[]): KoaCallback;
package/dist/API.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createRouter = exports.pageApiRouteOf = void 0;
3
+ exports.createKoaRouter = exports.pageApiRouteOf = void 0;
4
4
  exports.withKoa = withKoa;
5
5
  exports.withKoaRouter = withKoaRouter;
6
6
  var tslib_1 = require("tslib");
@@ -39,12 +39,12 @@ function withKoa() {
39
39
  }
40
40
  var pageApiRouteOf = function (path) {
41
41
  var _a, _b, _c;
42
- return (_c = (_b = (_a = path
42
+ return (_c = (_b = (_a = decodeURI(path)
43
43
  .match(/pages(\/api\/.+)\.(j|t)s/)) === null || _a === void 0 ? void 0 : _a[1]) === null || _b === void 0 ? void 0 : _b.split('/[')[0]) === null || _c === void 0 ? void 0 : _c.replace(/\/index$/, '');
44
44
  };
45
45
  exports.pageApiRouteOf = pageApiRouteOf;
46
- var createRouter = function (moduleURI, option) { return new router_1.default(tslib_1.__assign(tslib_1.__assign({}, option), { prefix: (0, exports.pageApiRouteOf)(moduleURI) })); };
47
- exports.createRouter = createRouter;
46
+ var createKoaRouter = function (moduleURI, option) { return new router_1.default(tslib_1.__assign(tslib_1.__assign({}, option), { prefix: (0, exports.pageApiRouteOf)(moduleURI) })); };
47
+ exports.createKoaRouter = createKoaRouter;
48
48
  function withKoaRouter() {
49
49
  var _a, _b;
50
50
  var parameters = [];
package/dist/API.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"API.js","sourceRoot":"","sources":["../source/API.ts"],"names":[],"mappings":";;;AAaA,0BAcC;AAsBD,sCAiBC;;AAlED,uEAAyC;AACzC,+DAAwE;AACxE,oDAAsC;AAWtC,SAAgB,OAAO;;IAAO,oBAAoB;SAApB,UAAoB,EAApB,qBAAoB,EAApB,IAAoB;QAApB,+BAAoB;;IAC9C,IAAI,MAA6B,CAAC;IAClC,IAAI,WAAW,GAAuB,EAAE,CAAC;IAEzC,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,GAAG,SAAS,CAAC;QACnB,WAAW,GAAG,UAAU,CAAC;IAC7B,CAAC;;QAAM,KAAA,eAA2B,UAAU,CAAA,EAApC,MAAM,QAAA,EAAK,WAAW,cAAA,CAAe;IAE7C,IAAM,GAAG,GAAG,IAAI,aAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAA,oBAAU,GAAE,CAAC,CAAC;;QAE9C,KAAyB,IAAA,gBAAA,iBAAA,WAAW,CAAA,wCAAA;YAA/B,IAAM,UAAU,wBAAA;YAAiB,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;SAAA;;;;;;;;;IAE1D,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC1B,CAAC;AAEM,IAAM,cAAc,GAAG,UAAC,IAAY;;IACvC,OAAA,MAAA,MAAA,MAAA,IAAI;SACC,KAAK,CAAC,0BAA0B,CAAC,0CAAG,CAAC,CAAC,0CACrC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,0CACd,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;CAAA,CAAC;AAJrB,QAAA,cAAc,kBAIO;AAE3B,IAAM,YAAY,GAAG,UACxB,SAAiB,EACjB,MAAsB,IACrB,OAAA,IAAI,gBAAM,uCAAY,MAAM,KAAE,MAAM,EAAE,IAAA,sBAAc,EAAC,SAAS,CAAC,IAAG,EAAlE,CAAkE,CAAC;AAH3D,QAAA,YAAY,gBAG+C;AAWxE,SAAgB,aAAa;;IACzB,oBAAoB;SAApB,UAAoB,EAApB,qBAAoB,EAApB,IAAoB;QAApB,+BAAoB;;IAEpB,IAAI,MAA6B,CAAC;IAClC,IAAI,MAAoB,CAAC;IACzB,IAAI,WAAW,GAAuB,EAAE,CAAC;IAEzC,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU;QACnC,KAAA,eAA2B,UAAU,CAAA,EAApC,MAAM,QAAA,EAAK,WAAW,cAAA,CAAe;;QACrC,KAAA,eAAmC,UAAU,CAAA,EAA5C,MAAM,QAAA,EAAE,MAAM,QAAA,EAAK,WAAW,cAAA,CAAe;IAEnD,OAAO,OAAO,sCACV,MAAM;QACN,MAAM,CAAC,MAAM,EAAE;QACf,MAAM,CAAC,cAAc,EAAE,kBACpB,WAAW,WAChB;AACN,CAAC"}
1
+ {"version":3,"file":"API.js","sourceRoot":"","sources":["../source/API.ts"],"names":[],"mappings":";;;AAaA,0BAcC;AAsBD,sCAiBC;;AAlED,uEAAyC;AACzC,+DAAwE;AACxE,oDAAsC;AAWtC,SAAgB,OAAO;;IAAO,oBAAoB;SAApB,UAAoB,EAApB,qBAAoB,EAApB,IAAoB;QAApB,+BAAoB;;IAC9C,IAAI,MAA6B,CAAC;IAClC,IAAI,WAAW,GAAuB,EAAE,CAAC;IAEzC,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,GAAG,SAAS,CAAC;QACnB,WAAW,GAAG,UAAU,CAAC;IAC7B,CAAC;;QAAM,KAAA,eAA2B,UAAU,CAAA,EAApC,MAAM,QAAA,EAAK,WAAW,cAAA,CAAe;IAE7C,IAAM,GAAG,GAAG,IAAI,aAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAA,oBAAU,GAAE,CAAC,CAAC;;QAE9C,KAAyB,IAAA,gBAAA,iBAAA,WAAW,CAAA,wCAAA;YAA/B,IAAM,UAAU,wBAAA;YAAiB,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;SAAA;;;;;;;;;IAE1D,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC1B,CAAC;AAEM,IAAM,cAAc,GAAG,UAAC,IAAY;;IACvC,OAAA,MAAA,MAAA,MAAA,SAAS,CAAC,IAAI,CAAC;SACV,KAAK,CAAC,0BAA0B,CAAC,0CAAG,CAAC,CAAC,0CACrC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,0CACd,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;CAAA,CAAC;AAJrB,QAAA,cAAc,kBAIO;AAE3B,IAAM,eAAe,GAAG,UAC3B,SAAiB,EACjB,MAAsB,IACrB,OAAA,IAAI,gBAAM,uCAAY,MAAM,KAAE,MAAM,EAAE,IAAA,sBAAc,EAAC,SAAS,CAAC,IAAG,EAAlE,CAAkE,CAAC;AAH3D,QAAA,eAAe,mBAG4C;AAWxE,SAAgB,aAAa;;IACzB,oBAAoB;SAApB,UAAoB,EAApB,qBAAoB,EAApB,IAAoB;QAApB,+BAAoB;;IAEpB,IAAI,MAA6B,CAAC;IAClC,IAAI,MAAoB,CAAC;IACzB,IAAI,WAAW,GAAuB,EAAE,CAAC;IAEzC,IAAI,OAAO,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU;QACnC,KAAA,eAA2B,UAAU,CAAA,EAApC,MAAM,QAAA,EAAK,WAAW,cAAA,CAAe;;QACrC,KAAA,eAAmC,UAAU,CAAA,EAA5C,MAAM,QAAA,EAAE,MAAM,QAAA,EAAK,WAAW,cAAA,CAAe;IAEnD,OAAO,OAAO,sCACV,MAAM;QACN,MAAM,CAAC,MAAM,EAAE;QACf,MAAM,CAAC,cAAc,EAAE,kBACpB,WAAW,WAChB;AACN,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "next-ssr-middleware",
3
- "version": "0.10.0-rc.2",
3
+ "version": "0.10.0",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "author": "shiy2008@gmail.com",
6
- "description": "Koa-like middlewares for Next.js Server Side Rendering",
6
+ "description": "Koa-like middlewares for Next.js Back-end API & Server Side Rendering",
7
7
  "keywords": [
8
8
  "koa",
9
9
  "middleware",
package/source/API.ts CHANGED
@@ -28,12 +28,12 @@ export function withKoa<S, C>(...parameters: any[]) {
28
28
  }
29
29
 
30
30
  export const pageApiRouteOf = (path: string) =>
31
- path
31
+ decodeURI(path)
32
32
  .match(/pages(\/api\/.+)\.(j|t)s/)?.[1]
33
33
  ?.split('/[')[0]
34
34
  ?.replace(/\/index$/, '');
35
35
 
36
- export const createRouter = <S, C extends RouterParamContext<S>>(
36
+ export const createKoaRouter = <S, C extends RouterParamContext<S>>(
37
37
  moduleURI: string,
38
38
  option?: RouterOptions
39
39
  ) => new Router<S, C>({ ...option, prefix: pageApiRouteOf(moduleURI) });