@weifuwujs/weifuwu 0.9.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 +605 -0
- package/dist/app.d.ts +122 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +484 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +506 -0
- package/dist/cli.js.map +1 -0
- package/dist/compose.d.ts +12 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +29 -0
- package/dist/compose.js.map +1 -0
- package/dist/env.d.ts +12 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +46 -0
- package/dist/env.js.map +1 -0
- package/dist/group.d.ts +32 -0
- package/dist/group.d.ts.map +1 -0
- package/dist/group.js +66 -0
- package/dist/group.js.map +1 -0
- package/dist/helpers.d.ts +37 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +101 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/ioredis.d.ts +16 -0
- package/dist/ioredis.d.ts.map +1 -0
- package/dist/ioredis.js +42 -0
- package/dist/ioredis.js.map +1 -0
- package/dist/methods.d.ts +3 -0
- package/dist/methods.d.ts.map +1 -0
- package/dist/methods.js +10 -0
- package/dist/methods.js.map +1 -0
- package/dist/middleware/cors.d.ts +24 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +77 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/index.d.ts +7 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +4 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/logger.d.ts +27 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +48 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/static.d.ts +27 -0
- package/dist/middleware/static.d.ts.map +1 -0
- package/dist/middleware/static.js +150 -0
- package/dist/middleware/static.js.map +1 -0
- package/dist/node.d.ts +27 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +193 -0
- package/dist/node.js.map +1 -0
- package/dist/path.d.ts +9 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +31 -0
- package/dist/path.js.map +1 -0
- package/dist/postgres.d.ts +19 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +27 -0
- package/dist/postgres.js.map +1 -0
- package/dist/react-router.d.ts +31 -0
- package/dist/react-router.d.ts.map +1 -0
- package/dist/react-router.js +25 -0
- package/dist/react-router.js.map +1 -0
- package/dist/resources.d.ts +35 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +54 -0
- package/dist/resources.js.map +1 -0
- package/dist/router.d.ts +30 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +122 -0
- package/dist/router.js.map +1 -0
- package/dist/types.d.ts +124 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vite.d.ts +21 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +101 -0
- package/dist/vite.js.map +1 -0
- package/dist/websocket/accept.d.ts +22 -0
- package/dist/websocket/accept.d.ts.map +1 -0
- package/dist/websocket/accept.js +104 -0
- package/dist/websocket/accept.js.map +1 -0
- package/dist/websocket/close-code.d.ts +22 -0
- package/dist/websocket/close-code.d.ts.map +1 -0
- package/dist/websocket/close-code.js +35 -0
- package/dist/websocket/close-code.js.map +1 -0
- package/dist/websocket/connection.d.ts +71 -0
- package/dist/websocket/connection.d.ts.map +1 -0
- package/dist/websocket/connection.js +287 -0
- package/dist/websocket/connection.js.map +1 -0
- package/dist/websocket/index.d.ts +7 -0
- package/dist/websocket/index.d.ts.map +1 -0
- package/dist/websocket/index.js +4 -0
- package/dist/websocket/index.js.map +1 -0
- package/dist/websocket/types.d.ts +66 -0
- package/dist/websocket/types.d.ts.map +1 -0
- package/dist/websocket/types.js +2 -0
- package/dist/websocket/types.js.map +1 -0
- package/docs/ai.md +175 -0
- package/docs/data.md +81 -0
- package/docs/migrating.md +116 -0
- package/docs/react-router.md +187 -0
- package/docs/styling.md +69 -0
- package/package.json +144 -0
- package/templates/react-router/_gitignore +3 -0
- package/templates/react-router/app/app.css +1 -0
- package/templates/react-router/app/context.ts +4 -0
- package/templates/react-router/app/root.tsx +50 -0
- package/templates/react-router/app/routes/home.tsx +17 -0
- package/templates/react-router/app/routes.ts +3 -0
- package/templates/react-router/app/server.ts +29 -0
- package/templates/react-router/package.json +29 -0
- package/templates/react-router/react-router.config.ts +5 -0
- package/templates/react-router/tsconfig.json +19 -0
- package/templates/react-router/vite.config.ts +6 -0
package/dist/group.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { App } from './app.ts';
|
|
2
|
+
import type { Context, MountableApi, MountOptions, OnRegistrar, RouteRegistrar } from './types.ts';
|
|
3
|
+
import type { WsRegistrar } from './websocket/types.ts';
|
|
4
|
+
/**
|
|
5
|
+
* 路由分组:为一组路由统一添加路径前缀。
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* app.group('/api', (api) => {
|
|
9
|
+
* api.get('/users/:id', (req, ctx) => json(ctx.params.id)) // GET /api/users/:id
|
|
10
|
+
* })
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class Group<C extends Context = Context, Prefix extends string = ''> {
|
|
14
|
+
#private;
|
|
15
|
+
constructor(app: App<C>, prefix: string);
|
|
16
|
+
get: RouteRegistrar<C, Prefix, this>;
|
|
17
|
+
post: RouteRegistrar<C, Prefix, this>;
|
|
18
|
+
put: RouteRegistrar<C, Prefix, this>;
|
|
19
|
+
patch: RouteRegistrar<C, Prefix, this>;
|
|
20
|
+
delete: RouteRegistrar<C, Prefix, this>;
|
|
21
|
+
head: RouteRegistrar<C, Prefix, this>;
|
|
22
|
+
options: RouteRegistrar<C, Prefix, this>;
|
|
23
|
+
all: RouteRegistrar<C, Prefix, this>;
|
|
24
|
+
on: OnRegistrar<C, Prefix, this>;
|
|
25
|
+
/** 在分组内注册 WebSocket 路由,前缀同样生效 */
|
|
26
|
+
ws: WsRegistrar<C, Prefix, this>;
|
|
27
|
+
/** 在分组内挂载单源 API,前缀生效 */
|
|
28
|
+
mount(api: MountableApi<C>, options?: MountOptions): this;
|
|
29
|
+
/** 嵌套分组,前缀会继续叠加 */
|
|
30
|
+
group<P extends string>(prefix: P, define: (group: Group<C, `${Prefix}${P}`>) => void): this;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAGnC,OAAO,KAAK,EACV,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvD;;;;;;;;GAQG;AACH,qBAAa,KAAK,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,MAAM,SAAS,MAAM,GAAG,EAAE;;gBAI5D,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM;IAKvC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CACF;IAElC,IAAI,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CACF;IAEnC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CACF;IAElC,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CACF;IAEpC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAGC;IAExC,IAAI,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CACF;IAEnC,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAGC;IAEzC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAGnC;IAED,EAAE,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAIM;IAEtC,iCAAiC;IACjC,EAAE,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAM/B;IAED,wBAAwB;IACxB,KAAK,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,IAAI;IAiB7D,mBAAmB;IACnB,KAAK,CAAC,CAAC,SAAS,MAAM,EACpB,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,KAAK,IAAI,GACjD,IAAI;CAYR"}
|
package/dist/group.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { METHODS } from "./methods.js";
|
|
2
|
+
import { joinPaths } from "./path.js";
|
|
3
|
+
/**
|
|
4
|
+
* 路由分组:为一组路由统一添加路径前缀。
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* app.group('/api', (api) => {
|
|
8
|
+
* api.get('/users/:id', (req, ctx) => json(ctx.params.id)) // GET /api/users/:id
|
|
9
|
+
* })
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export class Group {
|
|
13
|
+
#app;
|
|
14
|
+
#prefix;
|
|
15
|
+
constructor(app, prefix) {
|
|
16
|
+
this.#app = app;
|
|
17
|
+
this.#prefix = prefix;
|
|
18
|
+
}
|
|
19
|
+
get = (path, ...handlers) => this.#add('GET', path, handlers);
|
|
20
|
+
post = (path, ...handlers) => this.#add('POST', path, handlers);
|
|
21
|
+
put = (path, ...handlers) => this.#add('PUT', path, handlers);
|
|
22
|
+
patch = (path, ...handlers) => this.#add('PATCH', path, handlers);
|
|
23
|
+
delete = (path, ...handlers) => this.#add('DELETE', path, handlers);
|
|
24
|
+
head = (path, ...handlers) => this.#add('HEAD', path, handlers);
|
|
25
|
+
options = (path, ...handlers) => this.#add('OPTIONS', path, handlers);
|
|
26
|
+
all = (path, ...handlers) => {
|
|
27
|
+
for (const method of METHODS)
|
|
28
|
+
this.#add(method, path, handlers);
|
|
29
|
+
return this;
|
|
30
|
+
};
|
|
31
|
+
on = (method, path, ...handlers) => this.#add(method, path, handlers);
|
|
32
|
+
/** 在分组内注册 WebSocket 路由,前缀同样生效 */
|
|
33
|
+
ws = (path, ...args) => {
|
|
34
|
+
const app = this.#app;
|
|
35
|
+
app.ws(joinPaths(this.#prefix, path), ...args);
|
|
36
|
+
return this;
|
|
37
|
+
};
|
|
38
|
+
/** 在分组内挂载单源 API,前缀生效 */
|
|
39
|
+
mount(api, options = {}) {
|
|
40
|
+
if (options.rest !== false) {
|
|
41
|
+
for (const route of api.routes()) {
|
|
42
|
+
this.#add(route.method, route.path, [route.handler]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (typeof options.graphql === 'string') {
|
|
46
|
+
if (!api.graphqlHandler) {
|
|
47
|
+
throw new Error('This API does not provide a GraphQL handler');
|
|
48
|
+
}
|
|
49
|
+
const handler = api.graphqlHandler();
|
|
50
|
+
this.#add('GET', options.graphql, [handler]);
|
|
51
|
+
this.#add('POST', options.graphql, [handler]);
|
|
52
|
+
}
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
/** 嵌套分组,前缀会继续叠加 */
|
|
56
|
+
group(prefix, define) {
|
|
57
|
+
define(new Group(this.#app, joinPaths(this.#prefix, prefix)));
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
#add(method, path, handlers) {
|
|
61
|
+
const app = this.#app;
|
|
62
|
+
app.on(method, joinPaths(this.#prefix, path), ...handlers);
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.js","sourceRoot":"","sources":["../src/group.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface HttpErrorOptions {
|
|
2
|
+
/** 是否把 message 暴露给客户端(默认 5xx 不暴露、4xx 暴露) */
|
|
3
|
+
expose?: boolean;
|
|
4
|
+
headers?: ConstructorParameters<typeof Headers>[0];
|
|
5
|
+
cause?: unknown;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 抛出后由框架统一转换为对应的 HTTP 响应。
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* app.get('/users/:id', async (req, ctx) => {
|
|
12
|
+
* const user = await db.find(ctx.params.id)
|
|
13
|
+
* if (!user) throw new HttpError(404, 'User not found')
|
|
14
|
+
* return json(user)
|
|
15
|
+
* })
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare class HttpError extends Error {
|
|
19
|
+
readonly status: number;
|
|
20
|
+
readonly expose: boolean;
|
|
21
|
+
readonly headers: ConstructorParameters<typeof Headers>[0] | undefined;
|
|
22
|
+
constructor(status: number, message?: string, options?: HttpErrorOptions);
|
|
23
|
+
toResponse(): Response;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 可以外发给客户端的错误文案:`expose=false`(默认 5xx)退化为状态文案。
|
|
27
|
+
* HTTP 响应与 GraphQL 错误共用这一条规则。
|
|
28
|
+
*/
|
|
29
|
+
export declare function publicErrorMessage(error: HttpError): string;
|
|
30
|
+
export declare function getStatusText(status: number): string;
|
|
31
|
+
/** `Response.json` 的封装,统一带上 `charset=utf-8` */
|
|
32
|
+
export declare function json(data: unknown, init?: ResponseInit): Response;
|
|
33
|
+
export declare function text(body: string, init?: ResponseInit): Response;
|
|
34
|
+
export declare function html(body: string, init?: ResponseInit): Response;
|
|
35
|
+
export declare function redirect(location: string, status?: 301 | 302 | 303 | 307 | 308): Response;
|
|
36
|
+
export declare function noContent(init?: ResponseInit): Response;
|
|
37
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,qBAAqB,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IAClD,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;gBAE1D,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAW5E,UAAU,IAAI,QAAQ;CAMvB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAE3D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,+CAA+C;AAC/C,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAOrE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAMpE;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAMpE;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAS,GACxC,QAAQ,CAEV;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,YAAiB,GAAG,QAAQ,CAE3D"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const STATUS_TEXT = {
|
|
2
|
+
400: 'Bad Request',
|
|
3
|
+
401: 'Unauthorized',
|
|
4
|
+
402: 'Payment Required',
|
|
5
|
+
403: 'Forbidden',
|
|
6
|
+
404: 'Not Found',
|
|
7
|
+
405: 'Method Not Allowed',
|
|
8
|
+
406: 'Not Acceptable',
|
|
9
|
+
408: 'Request Timeout',
|
|
10
|
+
409: 'Conflict',
|
|
11
|
+
410: 'Gone',
|
|
12
|
+
411: 'Length Required',
|
|
13
|
+
412: 'Precondition Failed',
|
|
14
|
+
413: 'Payload Too Large',
|
|
15
|
+
415: 'Unsupported Media Type',
|
|
16
|
+
418: "I'm a Teapot",
|
|
17
|
+
422: 'Unprocessable Entity',
|
|
18
|
+
423: 'Locked',
|
|
19
|
+
424: 'Failed Dependency',
|
|
20
|
+
425: 'Too Early',
|
|
21
|
+
426: 'Upgrade Required',
|
|
22
|
+
428: 'Precondition Required',
|
|
23
|
+
429: 'Too Many Requests',
|
|
24
|
+
431: 'Request Header Fields Too Large',
|
|
25
|
+
451: 'Unavailable For Legal Reasons',
|
|
26
|
+
500: 'Internal Server Error',
|
|
27
|
+
501: 'Not Implemented',
|
|
28
|
+
502: 'Bad Gateway',
|
|
29
|
+
503: 'Service Unavailable',
|
|
30
|
+
504: 'Gateway Timeout',
|
|
31
|
+
505: 'HTTP Version Not Supported',
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* 抛出后由框架统一转换为对应的 HTTP 响应。
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* app.get('/users/:id', async (req, ctx) => {
|
|
38
|
+
* const user = await db.find(ctx.params.id)
|
|
39
|
+
* if (!user) throw new HttpError(404, 'User not found')
|
|
40
|
+
* return json(user)
|
|
41
|
+
* })
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export class HttpError extends Error {
|
|
45
|
+
status;
|
|
46
|
+
expose;
|
|
47
|
+
headers;
|
|
48
|
+
constructor(status, message, options = {}) {
|
|
49
|
+
super(message ?? STATUS_TEXT[status] ?? `HTTP ${status}`, options.cause === undefined ? undefined : { cause: options.cause });
|
|
50
|
+
this.name = 'HttpError';
|
|
51
|
+
this.status = status;
|
|
52
|
+
this.expose = options.expose ?? status < 500;
|
|
53
|
+
this.headers = options.headers;
|
|
54
|
+
}
|
|
55
|
+
toResponse() {
|
|
56
|
+
return new Response(publicErrorMessage(this), {
|
|
57
|
+
status: this.status,
|
|
58
|
+
headers: this.headers,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 可以外发给客户端的错误文案:`expose=false`(默认 5xx)退化为状态文案。
|
|
64
|
+
* HTTP 响应与 GraphQL 错误共用这一条规则。
|
|
65
|
+
*/
|
|
66
|
+
export function publicErrorMessage(error) {
|
|
67
|
+
return error.expose ? error.message : STATUS_TEXT[error.status] ?? 'Error';
|
|
68
|
+
}
|
|
69
|
+
export function getStatusText(status) {
|
|
70
|
+
return STATUS_TEXT[status] ?? '';
|
|
71
|
+
}
|
|
72
|
+
/** `Response.json` 的封装,统一带上 `charset=utf-8` */
|
|
73
|
+
export function json(data, init = {}) {
|
|
74
|
+
const body = data === undefined ? '' : JSON.stringify(data);
|
|
75
|
+
const headers = new Headers(init.headers);
|
|
76
|
+
if (!headers.has('content-type')) {
|
|
77
|
+
headers.set('content-type', 'application/json; charset=utf-8');
|
|
78
|
+
}
|
|
79
|
+
return new Response(body, { ...init, headers });
|
|
80
|
+
}
|
|
81
|
+
export function text(body, init = {}) {
|
|
82
|
+
const headers = new Headers(init.headers);
|
|
83
|
+
if (!headers.has('content-type')) {
|
|
84
|
+
headers.set('content-type', 'text/plain; charset=utf-8');
|
|
85
|
+
}
|
|
86
|
+
return new Response(body, { ...init, headers });
|
|
87
|
+
}
|
|
88
|
+
export function html(body, init = {}) {
|
|
89
|
+
const headers = new Headers(init.headers);
|
|
90
|
+
if (!headers.has('content-type')) {
|
|
91
|
+
headers.set('content-type', 'text/html; charset=utf-8');
|
|
92
|
+
}
|
|
93
|
+
return new Response(body, { ...init, headers });
|
|
94
|
+
}
|
|
95
|
+
export function redirect(location, status = 302) {
|
|
96
|
+
return new Response(null, { status, headers: { location } });
|
|
97
|
+
}
|
|
98
|
+
export function noContent(init = {}) {
|
|
99
|
+
return new Response(null, { ...init, status: init.status ?? 204 });
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAA2B;IAC1C,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,kBAAkB;IACvB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,gBAAgB;IACrB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,qBAAqB;IAC1B,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,wBAAwB;IAC7B,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,sBAAsB;IAC3B,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,kBAAkB;IACvB,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,mBAAmB;IACxB,GAAG,EAAE,iCAAiC;IACtC,GAAG,EAAE,+BAA+B;IACpC,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,qBAAqB;IAC1B,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,4BAA4B;CAClC,CAAA;AASD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,MAAM,CAAQ;IACd,MAAM,CAAS;IACf,OAAO,CAAsD;IAEtE,YAAY,MAAc,EAAE,OAAgB,EAAE,UAA4B,EAAE;QAC1E,KAAK,CACH,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,QAAQ,MAAM,EAAE,EAClD,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CACnE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,GAAG,GAAG,CAAA;QAC5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;IAChC,CAAC;IAED,UAAU;QACR,OAAO,IAAI,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE;YAC5C,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAA;IACJ,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IACjD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,OAAO,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;AAClC,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,IAAI,CAAC,IAAa,EAAE,OAAqB,EAAE;IACzD,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAC3D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAA;IAChE,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,OAAqB,EAAE;IACxD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAA;IAC1D,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,OAAqB,EAAE;IACxD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,QAAgB,EAChB,SAAsC,GAAG;IAEzC,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAqB,EAAE;IAC/C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,CAAA;AACpE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { App, createApp } from './app.ts';
|
|
2
|
+
export { resource } from './resources.ts';
|
|
3
|
+
export type { Resource, ResourceOptions } from './resources.ts';
|
|
4
|
+
export { Group } from './group.ts';
|
|
5
|
+
export { compose } from './compose.ts';
|
|
6
|
+
export { Router } from './router.ts';
|
|
7
|
+
export type { RouteEntry, RouteMatch } from './router.ts';
|
|
8
|
+
export { HttpError, json, publicErrorMessage, text, html, redirect, noContent, } from './helpers.ts';
|
|
9
|
+
export type { HttpErrorOptions } from './helpers.ts';
|
|
10
|
+
export { serve, toNodeHandler, toUpgradeHandler, attachToServer } from './node.ts';
|
|
11
|
+
export type { FetchApp, NodeHandlerOptions, ServeOptions, UpgradeApp } from './node.ts';
|
|
12
|
+
export { acceptWebSocket, CLOSE_CODE, isValidCloseCode, validateUpgradeRequest, WebSocketConnection, } from './websocket/index.ts';
|
|
13
|
+
export type { AcceptOptions, WebSocketHandler, WebSocketHandlers, WebSocketLifecycle, WebSocketMessage, WebSocketMiddleware, WebSocketNext, WebSocketOptions, WebSocketReadyState, WsRegistrar, } from './websocket/index.ts';
|
|
14
|
+
export type { Context, ContextWithParams, ErrorHandler, Handler, HttpMethod, Middleware, MountableApi, MountableRoute, MountOptions, Next, NotFoundHandler, OnRegistrar, PathParams, RouteHandlers, RouteMiddleware, RouteRegistrar, } from './types.ts';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EACL,SAAS,EACT,IAAI,EACJ,kBAAkB,EAClB,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,SAAS,GACV,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAClF,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACvF,OAAO,EACL,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACZ,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,OAAO,EACP,iBAAiB,EACjB,YAAY,EACZ,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,eAAe,EACf,WAAW,EACX,UAAU,EACV,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { App, createApp } from "./app.js";
|
|
2
|
+
export { resource } from "./resources.js";
|
|
3
|
+
export { Group } from "./group.js";
|
|
4
|
+
export { compose } from "./compose.js";
|
|
5
|
+
export { Router } from "./router.js";
|
|
6
|
+
export { HttpError, json, publicErrorMessage, text, html, redirect, noContent, } from "./helpers.js";
|
|
7
|
+
export { serve, toNodeHandler, toUpgradeHandler, attachToServer } from "./node.js";
|
|
8
|
+
export { acceptWebSocket, CLOSE_CODE, isValidCloseCode, validateUpgradeRequest, WebSocketConnection, } from "./websocket/index.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,OAAO,EACL,SAAS,EACT,IAAI,EACJ,kBAAkB,EAClB,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,SAAS,GACV,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAElF,OAAO,EACL,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Redis, RedisOptions } from 'ioredis';
|
|
2
|
+
import { type Resource } from './resources.ts';
|
|
3
|
+
export type { Redis, RedisOptions };
|
|
4
|
+
/**
|
|
5
|
+
* 注入 `ctx.redis`(ioredis 客户端)的中间件。
|
|
6
|
+
*
|
|
7
|
+
* - 首次请求时懒加载 `ioredis` 并连接
|
|
8
|
+
* - `app.close()` / CLI SIGTERM 时 `quit()`(失败则 `disconnect()`)
|
|
9
|
+
* - 默认连接串:`process.env.REDIS_URL`(缺省时用 ioredis 默认 localhost:6379)
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* app.use(redis()) // ctx.redis: Redis
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare function redis(urlOrOptions?: string | RedisOptions, options?: RedisOptions): Resource<'redis', Redis>;
|
|
16
|
+
//# sourceMappingURL=ioredis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ioredis.d.ts","sourceRoot":"","sources":["../src/ioredis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAExD,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,CAAA;AAEnC;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CACnB,YAAY,CAAC,EAAE,MAAM,GAAG,YAAY,EACpC,OAAO,CAAC,EAAE,YAAY,GACrB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAoC1B"}
|
package/dist/ioredis.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { resource } from "./resources.js";
|
|
2
|
+
/**
|
|
3
|
+
* 注入 `ctx.redis`(ioredis 客户端)的中间件。
|
|
4
|
+
*
|
|
5
|
+
* - 首次请求时懒加载 `ioredis` 并连接
|
|
6
|
+
* - `app.close()` / CLI SIGTERM 时 `quit()`(失败则 `disconnect()`)
|
|
7
|
+
* - 默认连接串:`process.env.REDIS_URL`(缺省时用 ioredis 默认 localhost:6379)
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* app.use(redis()) // ctx.redis: Redis
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export function redis(urlOrOptions, options) {
|
|
14
|
+
return resource('redis', async () => {
|
|
15
|
+
const { default: RedisClient } = (await import('ioredis'));
|
|
16
|
+
if (typeof urlOrOptions === 'string') {
|
|
17
|
+
return new RedisClient(urlOrOptions, options);
|
|
18
|
+
}
|
|
19
|
+
const url = process.env.REDIS_URL;
|
|
20
|
+
if (url)
|
|
21
|
+
return new RedisClient(url, urlOrOptions);
|
|
22
|
+
return new RedisClient(urlOrOptions ?? {});
|
|
23
|
+
}, {
|
|
24
|
+
close: (client) => new Promise((resolveClose) => {
|
|
25
|
+
if (client.status === 'end')
|
|
26
|
+
return resolveClose();
|
|
27
|
+
const timer = setTimeout(resolveClose, 1_000);
|
|
28
|
+
const finish = () => {
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
resolveClose();
|
|
31
|
+
};
|
|
32
|
+
client.once('end', finish);
|
|
33
|
+
// ioredis v6 的 quit() 在 end 事件之前 resolve,所以等事件本身;
|
|
34
|
+
// quit 失败时降级 disconnect。
|
|
35
|
+
client.quit().catch(() => {
|
|
36
|
+
client.disconnect();
|
|
37
|
+
finish();
|
|
38
|
+
});
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=ioredis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ioredis.js","sourceRoot":"","sources":["../src/ioredis.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAiB,MAAM,gBAAgB,CAAA;AAIxD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,KAAK,CACnB,YAAoC,EACpC,OAAsB;IAEtB,OAAO,QAAQ,CACb,OAAO,EACP,KAAK,IAAI,EAAE;QACT,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAKxD,CAAA;QACD,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACrC,OAAO,IAAI,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAC/C,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;QACjC,IAAI,GAAG;YAAE,OAAO,IAAI,WAAW,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;QAClD,OAAO,IAAI,WAAW,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;IAC5C,CAAC,EACD;QACE,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAChB,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,EAAE;YACjC,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK;gBAAE,OAAO,YAAY,EAAE,CAAA;YAClD,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;YAC7C,MAAM,MAAM,GAAG,GAAG,EAAE;gBAClB,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,YAAY,EAAE,CAAA;YAChB,CAAC,CAAA;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;YAC1B,kDAAkD;YAClD,yBAAyB;YACzB,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;gBACvB,MAAM,CAAC,UAAU,EAAE,CAAA;gBACnB,MAAM,EAAE,CAAA;YACV,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC;KACL,CACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,eAAO,MAAM,OAAO,EAAE,SAAS,UAAU,EAQxC,CAAA"}
|
package/dist/methods.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methods.js","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,OAAO,GAA0B;IAC5C,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,SAAS;CACV,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Middleware } from '../types.ts';
|
|
2
|
+
export type CorsOrigin = string | string[] | ((origin: string) => string | null | undefined);
|
|
3
|
+
export interface CorsOptions {
|
|
4
|
+
/**
|
|
5
|
+
* 允许的来源。默认 `'*'`;
|
|
6
|
+
* 当 `credentials: true` 且为 `'*'` 时会回显请求的 Origin。
|
|
7
|
+
*/
|
|
8
|
+
origin?: CorsOrigin;
|
|
9
|
+
methods?: string | string[];
|
|
10
|
+
allowedHeaders?: string | string[];
|
|
11
|
+
exposedHeaders?: string | string[];
|
|
12
|
+
credentials?: boolean;
|
|
13
|
+
/** 预检结果缓存秒数 */
|
|
14
|
+
maxAge?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* CORS 中间件,自动处理预检请求(OPTIONS + Access-Control-Request-Method)。
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* app.use(cors({ origin: ['https://a.com'], credentials: true }))
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function cors(options?: CorsOptions): Middleware;
|
|
24
|
+
//# sourceMappingURL=cors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,MAAM,EAAE,GACR,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAEnD,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,eAAe;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAID;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CA6C1D"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const DEFAULT_METHODS = 'GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS';
|
|
2
|
+
/**
|
|
3
|
+
* CORS 中间件,自动处理预检请求(OPTIONS + Access-Control-Request-Method)。
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* app.use(cors({ origin: ['https://a.com'], credentials: true }))
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export function cors(options = {}) {
|
|
10
|
+
const methods = toHeaderValue(options.methods) ?? DEFAULT_METHODS;
|
|
11
|
+
const allowedHeaders = toHeaderValue(options.allowedHeaders);
|
|
12
|
+
const exposedHeaders = toHeaderValue(options.exposedHeaders);
|
|
13
|
+
const credentials = options.credentials === true;
|
|
14
|
+
const maxAge = options.maxAge;
|
|
15
|
+
return async (req, ctx, next) => {
|
|
16
|
+
const requestOrigin = req.headers.get('origin');
|
|
17
|
+
const allowOrigin = resolveOrigin(options.origin, requestOrigin, credentials);
|
|
18
|
+
const isPreflight = req.method === 'OPTIONS' &&
|
|
19
|
+
req.headers.has('access-control-request-method');
|
|
20
|
+
if (isPreflight) {
|
|
21
|
+
const headers = new Headers();
|
|
22
|
+
if (allowOrigin)
|
|
23
|
+
headers.set('access-control-allow-origin', allowOrigin);
|
|
24
|
+
headers.set('access-control-allow-methods', methods);
|
|
25
|
+
const requestedHeaders = req.headers.get('access-control-request-headers');
|
|
26
|
+
if (allowedHeaders)
|
|
27
|
+
headers.set('access-control-allow-headers', allowedHeaders);
|
|
28
|
+
else if (requestedHeaders)
|
|
29
|
+
headers.set('access-control-allow-headers', requestedHeaders);
|
|
30
|
+
if (exposedHeaders)
|
|
31
|
+
headers.set('access-control-expose-headers', exposedHeaders);
|
|
32
|
+
if (credentials)
|
|
33
|
+
headers.set('access-control-allow-credentials', 'true');
|
|
34
|
+
if (maxAge !== undefined)
|
|
35
|
+
headers.set('access-control-max-age', String(maxAge));
|
|
36
|
+
appendVary(headers, allowOrigin);
|
|
37
|
+
return new Response(null, { status: 204, headers });
|
|
38
|
+
}
|
|
39
|
+
const response = await next(req, ctx);
|
|
40
|
+
if (!allowOrigin)
|
|
41
|
+
return response;
|
|
42
|
+
const headers = new Headers(response.headers);
|
|
43
|
+
headers.set('access-control-allow-origin', allowOrigin);
|
|
44
|
+
if (credentials)
|
|
45
|
+
headers.set('access-control-allow-credentials', 'true');
|
|
46
|
+
if (exposedHeaders)
|
|
47
|
+
headers.set('access-control-expose-headers', exposedHeaders);
|
|
48
|
+
appendVary(headers, allowOrigin);
|
|
49
|
+
return new Response(response.body, {
|
|
50
|
+
status: response.status,
|
|
51
|
+
statusText: response.statusText,
|
|
52
|
+
headers,
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function resolveOrigin(origin, requestOrigin, credentials) {
|
|
57
|
+
if (origin === undefined) {
|
|
58
|
+
return credentials ? requestOrigin : '*';
|
|
59
|
+
}
|
|
60
|
+
if (typeof origin === 'string') {
|
|
61
|
+
if (origin === '*' && credentials)
|
|
62
|
+
return requestOrigin;
|
|
63
|
+
return origin;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(origin)) {
|
|
66
|
+
return requestOrigin && origin.includes(requestOrigin) ? requestOrigin : null;
|
|
67
|
+
}
|
|
68
|
+
return requestOrigin ? origin(requestOrigin) ?? null : null;
|
|
69
|
+
}
|
|
70
|
+
function toHeaderValue(value) {
|
|
71
|
+
return Array.isArray(value) ? value.join(',') : value;
|
|
72
|
+
}
|
|
73
|
+
function appendVary(headers, allowOrigin) {
|
|
74
|
+
if (allowOrigin !== '*')
|
|
75
|
+
headers.append('vary', 'Origin');
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { logger } from './logger.ts';
|
|
2
|
+
export type { LogInfo, LoggerOptions } from './logger.ts';
|
|
3
|
+
export { cors } from './cors.ts';
|
|
4
|
+
export type { CorsOptions, CorsOrigin } from './cors.ts';
|
|
5
|
+
export { serveStatic } from './static.ts';
|
|
6
|
+
export type { ServeStaticOptions } from './static.ts';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Middleware } from '../types.ts';
|
|
2
|
+
export interface LogInfo {
|
|
3
|
+
method: string;
|
|
4
|
+
path: string;
|
|
5
|
+
status: number;
|
|
6
|
+
/** 毫秒 */
|
|
7
|
+
duration: number;
|
|
8
|
+
request: Request;
|
|
9
|
+
response?: Response;
|
|
10
|
+
/** handler 抛出的原始错误(仅失败时有值) */
|
|
11
|
+
error?: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface LoggerOptions {
|
|
14
|
+
/** 输出函数,默认 `console.log` */
|
|
15
|
+
log?: (message: string) => void;
|
|
16
|
+
/** 自定义日志格式 */
|
|
17
|
+
format?: (info: LogInfo) => string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 访问日志中间件。
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* app.use(logger())
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function logger(options?: LoggerOptions): Middleware;
|
|
27
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS;IACT,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,4BAA4B;IAC5B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,cAAc;IACd,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAA;CACnC;AAKD;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,UAAU,CAmC9D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const defaultFormat = (info) => `${info.method} ${info.path} ${info.status} ${info.duration.toFixed(1)}ms`;
|
|
2
|
+
/**
|
|
3
|
+
* 访问日志中间件。
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* app.use(logger())
|
|
7
|
+
* ```
|
|
8
|
+
*/
|
|
9
|
+
export function logger(options = {}) {
|
|
10
|
+
const log = options.log ?? ((message) => console.log(message));
|
|
11
|
+
const format = options.format ?? defaultFormat;
|
|
12
|
+
return async (req, ctx, next) => {
|
|
13
|
+
const start = performance.now();
|
|
14
|
+
const path = pathOf(req.url);
|
|
15
|
+
try {
|
|
16
|
+
const response = await next(req, ctx);
|
|
17
|
+
log(format({
|
|
18
|
+
method: req.method,
|
|
19
|
+
path,
|
|
20
|
+
status: response.status,
|
|
21
|
+
duration: performance.now() - start,
|
|
22
|
+
request: req,
|
|
23
|
+
response,
|
|
24
|
+
}));
|
|
25
|
+
return response;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
log(format({
|
|
29
|
+
method: req.method,
|
|
30
|
+
path,
|
|
31
|
+
status: 500,
|
|
32
|
+
duration: performance.now() - start,
|
|
33
|
+
request: req,
|
|
34
|
+
error,
|
|
35
|
+
}));
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function pathOf(url) {
|
|
41
|
+
try {
|
|
42
|
+
return new URL(url).pathname;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return url;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/middleware/logger.ts"],"names":[],"mappings":"AAqBA,MAAM,aAAa,GAAG,CAAC,IAAa,EAAU,EAAE,CAC9C,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;AAE5E;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,UAAyB,EAAE;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACtE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAA;IAE9C,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAA;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE5B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YACrC,GAAG,CACD,MAAM,CAAC;gBACL,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI;gBACJ,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;gBACnC,OAAO,EAAE,GAAG;gBACZ,QAAQ;aACT,CAAC,CACH,CAAA;YACD,OAAO,QAAQ,CAAA;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CACD,MAAM,CAAC;gBACL,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI;gBACJ,MAAM,EAAE,GAAG;gBACX,QAAQ,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;gBACnC,OAAO,EAAE,GAAG;gBACZ,KAAK;aACN,CAAC,CACH,CAAA;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED,SAAS,MAAM,CAAC,GAAW;IACzB,IAAI,CAAC;QACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAA;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAA;IACZ,CAAC;AACH,CAAC"}
|