@jayfong/x-server 1.8.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/README.md +51 -0
  3. package/lib/cli/api_generator.d.ts +44 -0
  4. package/lib/cli/api_generator.js +339 -0
  5. package/lib/cli/build_util.d.ts +9 -0
  6. package/lib/cli/build_util.js +141 -0
  7. package/lib/cli/cli.d.ts +2 -0
  8. package/lib/cli/cli.js +216 -0
  9. package/lib/cli/deploy_util.d.ts +10 -0
  10. package/lib/cli/deploy_util.js +51 -0
  11. package/lib/cli/env_util.d.ts +29 -0
  12. package/lib/cli/env_util.js +139 -0
  13. package/lib/cli/register.d.ts +0 -0
  14. package/lib/cli/register.js +5 -0
  15. package/lib/cli/template_util.d.ts +3 -0
  16. package/lib/cli/template_util.js +18 -0
  17. package/lib/cli/templates/handlers.ts +3 -0
  18. package/lib/cli/templates/hooks.ts +2 -0
  19. package/lib/cli/templates/models.ts +22 -0
  20. package/lib/cli/templates/routes.ts +26 -0
  21. package/lib/cli/templates/tasks.ts +2 -0
  22. package/lib/core/define_bus.d.ts +38 -0
  23. package/lib/core/define_bus.js +15 -0
  24. package/lib/core/define_handler.d.ts +16 -0
  25. package/lib/core/define_handler.js +41 -0
  26. package/lib/core/define_hook.d.ts +2 -0
  27. package/lib/core/define_hook.js +8 -0
  28. package/lib/core/define_server.d.ts +3 -0
  29. package/lib/core/define_server.js +10 -0
  30. package/lib/core/define_task.d.ts +2 -0
  31. package/lib/core/define_task.js +27 -0
  32. package/lib/core/handler.d.ts +10 -0
  33. package/lib/core/handler.js +76 -0
  34. package/lib/core/http_error.d.ts +2 -0
  35. package/lib/core/http_error.js +8 -0
  36. package/lib/core/http_method.d.ts +3 -0
  37. package/lib/core/http_method.js +10 -0
  38. package/lib/core/server.d.ts +16 -0
  39. package/lib/core/server.js +137 -0
  40. package/lib/core/types.d.ts +123 -0
  41. package/lib/core/types.js +2 -0
  42. package/lib/index.d.ts +22 -0
  43. package/lib/index.js +41 -0
  44. package/lib/plugins/base.d.ts +4 -0
  45. package/lib/plugins/base.js +2 -0
  46. package/lib/plugins/cors.d.ts +21 -0
  47. package/lib/plugins/cors.js +39 -0
  48. package/lib/plugins/file_parser.d.ts +13 -0
  49. package/lib/plugins/file_parser.js +19 -0
  50. package/lib/plugins/ws_parser.d.ts +13 -0
  51. package/lib/plugins/ws_parser.js +19 -0
  52. package/lib/plugins/xml_parser.d.ts +19 -0
  53. package/lib/plugins/xml_parser.js +48 -0
  54. package/lib/services/base.d.ts +4 -0
  55. package/lib/services/base.js +2 -0
  56. package/lib/services/cache.d.ts +119 -0
  57. package/lib/services/cache.js +196 -0
  58. package/lib/services/captcha.d.ts +33 -0
  59. package/lib/services/captcha.js +34 -0
  60. package/lib/services/dispose.d.ts +17 -0
  61. package/lib/services/dispose.js +24 -0
  62. package/lib/services/jwt.d.ts +21 -0
  63. package/lib/services/jwt.js +50 -0
  64. package/lib/services/redis.d.ts +10 -0
  65. package/lib/services/redis.js +14 -0
  66. package/lib/x.d.ts +5 -0
  67. package/lib/x.js +11 -0
  68. package/package.json +86 -0
@@ -0,0 +1,26 @@
1
+ import * as handlers from './handlers'
2
+ import { Handler, XServer } from '@jayfong/x-server'
3
+
4
+ const basePathWithHandlers: Array<[string, Record<string, Handler>]> = [
5
+ // @index('../../src/handlers/**/*.ts', (f, _) => `['${('/'+_.snake(f.path.replace('handlers', '')).replace(/_/g, '/')+'/').replace(/\/{2,}/g, '/')}', handlers.__${_.pascal(f.path.replace('handlers', ''))}__ as any],`)
6
+ // @endindex
7
+ ]
8
+
9
+ export const routes: XServer.Route[] = basePathWithHandlers.reduce<
10
+ XServer.Route[]
11
+ >((res, item) => {
12
+ const validHandlerNames = Object.keys(item[1]).filter(
13
+ name => !name.startsWith('_') && name !== 'default',
14
+ )
15
+ for (const handlerName of validHandlerNames) {
16
+ const path = item[1][handlerName].options.requestPath || handlerName
17
+ const paths = Array.isArray(path) ? path : [path]
18
+ for (const path of paths) {
19
+ res.push({
20
+ path: `${item[0]}${path}`,
21
+ handler: item[1][handlerName],
22
+ })
23
+ }
24
+ }
25
+ return res
26
+ }, [])
@@ -0,0 +1,2 @@
1
+ // @index('../../src/tasks/**/*.ts', (f, _) => `import '${f.path}'`)
2
+ // @endindex
@@ -0,0 +1,38 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'node:events';
3
+ declare class EventBus extends EventEmitter {
4
+ onReturnOff(event: string, listener: (...args: any[]) => any): () => any;
5
+ }
6
+ export declare function defineBus<T extends Record<string, any>>(): StrictEventEmitter<EventBus, T, T, "addEventListener" | "removeEventListener", "on" | "addListener" | "removeListener" | "once" | "emit" | "off" | "onReturnOff">;
7
+ declare const assignmentCompatibilityHack: unique symbol;
8
+ interface TypeRecord<T, U, V> {
9
+ ' _emitterType'?: T;
10
+ ' _eventsType'?: U;
11
+ ' _emitType'?: V;
12
+ }
13
+ declare type InnerEEMethodReturnType<T, TValue, FValue> = T extends (...args: any[]) => any ? ReturnType<T> extends void | undefined ? FValue : TValue : FValue;
14
+ declare type EEMethodReturnType<T, S extends string, TValue, FValue = void> = S extends keyof T ? InnerEEMethodReturnType<T[S], TValue, FValue> : FValue;
15
+ declare type ListenerType<T> = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T];
16
+ declare type OverriddenMethods<TEmitter, TEventRecord, TEmitRecord = TEventRecord> = {
17
+ on<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'on', T>;
18
+ on(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
19
+ addListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'addListener', T>;
20
+ addListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
21
+ addEventListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'addEventListener', T>;
22
+ addEventListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
23
+ removeListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: any[]) => any): EEMethodReturnType<TEmitter, 'removeListener', T>;
24
+ removeListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
25
+ removeEventListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: any[]) => any): EEMethodReturnType<TEmitter, 'removeEventListener', T>;
26
+ removeEventListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
27
+ once<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'once', T>;
28
+ once(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
29
+ emit<P extends keyof TEmitRecord, T>(this: T, event: P, ...args: ListenerType<TEmitRecord[P]>): EEMethodReturnType<TEmitter, 'emit', T>;
30
+ emit(event: typeof assignmentCompatibilityHack, ...args: any[]): void;
31
+ off<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'off', T>;
32
+ off(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
33
+ onReturnOff<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): () => any;
34
+ onReturnOff(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): () => any;
35
+ };
36
+ declare type OverriddenKeys = keyof OverriddenMethods<any, any, any>;
37
+ declare type StrictEventEmitter<TEmitterType, TEventRecord, TEmitRecord = TEventRecord, UnneededMethods extends Exclude<OverriddenKeys, keyof TEmitterType> = Exclude<OverriddenKeys, keyof TEmitterType>, NeededMethods extends Exclude<OverriddenKeys, UnneededMethods> = Exclude<OverriddenKeys, UnneededMethods>> = TypeRecord<TEmitterType, TEventRecord, TEmitRecord> & Pick<TEmitterType, Exclude<keyof TEmitterType, OverriddenKeys>> & Pick<OverriddenMethods<TEmitterType, TEventRecord, TEmitRecord>, NeededMethods>;
38
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineBus = void 0;
4
+ const node_events_1 = require("node:events");
5
+ class EventBus extends node_events_1.EventEmitter {
6
+ onReturnOff(event, listener) {
7
+ this.on(event, listener);
8
+ return () => this.off(event, listener);
9
+ }
10
+ }
11
+ function defineBus() {
12
+ const eventEmitter = new EventBus();
13
+ return eventEmitter;
14
+ }
15
+ exports.defineBus = defineBus;
@@ -0,0 +1,16 @@
1
+ import { Handler } from './handler';
2
+ import type { XHandler } from './types';
3
+ export declare function defineHandler<TReqData extends any = void, TResData extends any = void>(options: XHandler.Options<TReqData, TResData, 'POST'>): Handler<TReqData, TResData, "POST">;
4
+ export declare namespace defineHandler {
5
+ var POST: typeof defineHandler;
6
+ var GET: <TReqData extends unknown = void, TResData extends unknown = void>(options: XHandler.Options<TReqData, TResData, "GET">) => Handler<TReqData, TResData, "GET">;
7
+ var FILE: <TReqData extends unknown = void, TResData extends unknown = void>(options: XHandler.Options<TReqData, TResData, "FILE">) => Handler<TReqData, TResData, "FILE">;
8
+ var WS: <TReqData extends Record<string, [any, any]>>(options: XHandler.Options<{ [K in keyof TReqData]: {
9
+ request: TReqData[K][0];
10
+ response: TReqData[K][1];
11
+ }; }, void, "WS">) => Handler<{ [K in keyof TReqData]: {
12
+ request: TReqData[K][0];
13
+ response: TReqData[K][1];
14
+ }; }, void, "WS">;
15
+ var XML: <TReqData extends unknown = void, TResData extends unknown = void>(options: XHandler.Options<TReqData, TResData, "XML">) => Handler<TReqData, TResData, "XML">;
16
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineHandler = void 0;
4
+ const handler_1 = require("./handler");
5
+ function defineHandler(options) {
6
+ const handler = new handler_1.Handler({
7
+ ...options,
8
+ requestMethod: 'POST',
9
+ });
10
+ return handler;
11
+ }
12
+ exports.defineHandler = defineHandler;
13
+ defineHandler.POST = defineHandler;
14
+ defineHandler.GET = (options) => {
15
+ const handler = new handler_1.Handler({
16
+ ...options,
17
+ requestMethod: 'GET',
18
+ });
19
+ return handler;
20
+ };
21
+ defineHandler.FILE = (options) => {
22
+ const handler = new handler_1.Handler({
23
+ ...options,
24
+ requestMethod: 'FILE',
25
+ });
26
+ return handler;
27
+ };
28
+ defineHandler.WS = (options) => {
29
+ const handler = new handler_1.Handler({
30
+ ...options,
31
+ requestMethod: 'WS',
32
+ });
33
+ return handler;
34
+ };
35
+ defineHandler.XML = (options) => {
36
+ const handler = new handler_1.Handler({
37
+ ...options,
38
+ requestMethod: 'XML',
39
+ });
40
+ return handler;
41
+ };
@@ -0,0 +1,2 @@
1
+ import type { XHandler } from './types';
2
+ export declare function defineHook(hook: XHandler.Hook): void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineHook = void 0;
4
+ const handler_1 = require("./handler");
5
+ function defineHook(hook) {
6
+ handler_1.Handler.addHook(hook);
7
+ }
8
+ exports.defineHook = defineHook;
@@ -0,0 +1,3 @@
1
+ import { Server } from './server';
2
+ import type { XServer } from './types';
3
+ export declare function defineServer(options: XServer.Options): Promise<Server>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineServer = void 0;
4
+ const server_1 = require("./server");
5
+ async function defineServer(options) {
6
+ const server = new server_1.Server(options);
7
+ await server.start();
8
+ return server;
9
+ }
10
+ exports.defineServer = defineServer;
@@ -0,0 +1,2 @@
1
+ import type { XTask } from './types';
2
+ export declare function defineTask<T>(options: XTask.Options<T>): Promise<XTask.Task<T>>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.defineTask = void 0;
7
+ const bull_1 = __importDefault(require("bull"));
8
+ const server_1 = require("./server");
9
+ const x_1 = require("../x");
10
+ async function defineTask(options) {
11
+ const queue = new bull_1.default(options.name, {
12
+ redis: x_1.x.redis.options,
13
+ prefix: `${server_1.Server.options.name}_task`,
14
+ });
15
+ queue.process(async (job) => {
16
+ return options.handle(job.data);
17
+ });
18
+ if (options.cron) {
19
+ queue.add({}, {
20
+ repeat: {
21
+ cron: options.cron,
22
+ },
23
+ });
24
+ }
25
+ return queue;
26
+ }
27
+ exports.defineTask = defineTask;
@@ -0,0 +1,10 @@
1
+ import type { XHandler } from './types';
2
+ export declare class Handler<TReqData extends any = void, TResData extends any = void, TReqMethod extends XHandler.Method = XHandler.Method> {
3
+ readonly options: XHandler.Options<TReqData, TResData, TReqMethod>;
4
+ constructor(options: XHandler.Options<TReqData, TResData, TReqMethod>);
5
+ handle: XHandler.Handle<TReqData, TResData, TReqMethod>;
6
+ private handleHttp;
7
+ private handleWs;
8
+ private static hooks;
9
+ static addHook(hook: XHandler.Hook): void;
10
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Handler = void 0;
4
+ const vtils_1 = require("vtils");
5
+ const dispose_1 = require("../services/dispose");
6
+ const http_error_1 = require("../core/http_error");
7
+ class Handler {
8
+ constructor(options) {
9
+ this.options = options;
10
+ this.handle = async (data, ctx) => {
11
+ // 前置 hook
12
+ if (Handler.hooks.length) {
13
+ await Promise.all(Handler.hooks.map(hook => hook(this.options, data, ctx)));
14
+ }
15
+ if (this.options.requestMethod === 'WS') {
16
+ return this.handleWs(data, ctx);
17
+ }
18
+ return this.handleHttp(data, ctx);
19
+ };
20
+ this.handleHttp = async (data, ctx) => {
21
+ let res = await this.options.handle(data, ctx);
22
+ // 打包返回数据
23
+ if (this.options.responseDataPack) {
24
+ res = vtils_1.DataPacker.packAsRawType(res);
25
+ }
26
+ return res;
27
+ };
28
+ this.handleWs = async (data, ctx) => {
29
+ const dispose = new dispose_1.DisposeService();
30
+ ctx.ws.socket.on('message', async (payload) => {
31
+ try {
32
+ const _ = JSON.parse(payload.toString('utf8'));
33
+ const send = (data) => {
34
+ ctx.ws.socket.send(JSON.stringify({
35
+ id: _.id,
36
+ data: data,
37
+ }));
38
+ };
39
+ const process = async (type, fn) => {
40
+ if (_.type === type) {
41
+ await fn({
42
+ data: _.data,
43
+ send: send,
44
+ dispose: dispose,
45
+ });
46
+ }
47
+ };
48
+ if (_.type === 'ping') {
49
+ send();
50
+ }
51
+ else {
52
+ await this.options.handle(process, ctx);
53
+ }
54
+ }
55
+ catch (err) {
56
+ const _err = http_error_1.HttpError.isHttpError(err)
57
+ ? err
58
+ : new http_error_1.HttpError.InternalServerError();
59
+ ctx.ws.socket.send(JSON.stringify({
60
+ statusCode: _err.statusCode,
61
+ error: _err.name,
62
+ message: _err.message,
63
+ }));
64
+ }
65
+ });
66
+ ctx.ws.socket.on('close', () => {
67
+ dispose.dispose();
68
+ });
69
+ };
70
+ }
71
+ static addHook(hook) {
72
+ this.hooks.push(hook);
73
+ }
74
+ }
75
+ exports.Handler = Handler;
76
+ Handler.hooks = [];
@@ -0,0 +1,2 @@
1
+ import { default as HttpError } from 'http-errors';
2
+ export { HttpError };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HttpError = void 0;
7
+ const http_errors_1 = __importDefault(require("http-errors"));
8
+ Object.defineProperty(exports, "HttpError", { enumerable: true, get: function () { return http_errors_1.default; } });
@@ -0,0 +1,3 @@
1
+ import { HTTPMethods } from 'fastify';
2
+ import { XHandler } from './types';
3
+ export declare const HandlerMethodToHttpMethod: Record<XHandler.Method, HTTPMethods>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HandlerMethodToHttpMethod = void 0;
4
+ exports.HandlerMethodToHttpMethod = {
5
+ GET: 'GET',
6
+ POST: 'POST',
7
+ FILE: 'POST',
8
+ WS: 'GET',
9
+ XML: 'POST',
10
+ };
@@ -0,0 +1,16 @@
1
+ import { XServer } from './types';
2
+ export declare class Server {
3
+ readonly options: XServer.Options;
4
+ private fastify;
5
+ private routes;
6
+ static options: XServer.Options;
7
+ constructor(options: XServer.Options);
8
+ start(): Promise<void>;
9
+ close(): Promise<void>;
10
+ private prepareFastify;
11
+ private startFastify;
12
+ private applyServices;
13
+ private applyPlugins;
14
+ private applyRoutes;
15
+ private applyAutoClose;
16
+ }
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Server = void 0;
30
+ const fastify_1 = __importDefault(require("fastify"));
31
+ const vtils_1 = require("vtils");
32
+ const dispose_1 = require("../services/dispose");
33
+ const http_method_1 = require("./http_method");
34
+ const x_1 = require("../x");
35
+ // @ts-ignore
36
+ const routes_1 = require(".x/routes");
37
+ class Server {
38
+ constructor(options) {
39
+ this.options = options;
40
+ this.routes = routes_1.routes;
41
+ Server.options = options;
42
+ }
43
+ async start() {
44
+ this.applyServices();
45
+ await this.prepareFastify();
46
+ this.applyPlugins();
47
+ await this.applyRoutes();
48
+ // @ts-ignore
49
+ await Promise.resolve().then(() => __importStar(require('.x/hooks')));
50
+ await this.startFastify();
51
+ // @ts-ignore
52
+ await Promise.resolve().then(() => __importStar(require('.x/tasks')));
53
+ await this.applyAutoClose();
54
+ }
55
+ async close() {
56
+ await this.fastify?.close();
57
+ }
58
+ async prepareFastify() {
59
+ this.fastify = (0, fastify_1.default)({
60
+ logger: process.env.NODE_ENV === 'development'
61
+ ? {
62
+ prettyPrint: true,
63
+ }
64
+ : false,
65
+ });
66
+ }
67
+ async startFastify() {
68
+ await this.fastify.listen({
69
+ host: this.options.host || '0.0.0.0',
70
+ port: this.options.port,
71
+ });
72
+ }
73
+ applyServices() {
74
+ x_1.x.register(new dispose_1.DisposeService({
75
+ disposeOnExit: true,
76
+ }), ...(this.options.services || []));
77
+ }
78
+ applyPlugins() {
79
+ const plugins = this.options.plugins || [];
80
+ for (const plugin of plugins) {
81
+ plugin.register(this.fastify);
82
+ }
83
+ }
84
+ async applyRoutes() {
85
+ for (const item of this.routes) {
86
+ const handlerOptions = item.handler.options;
87
+ const handlerMethod = handlerOptions.requestMethod || 'POST';
88
+ const isWS = handlerMethod === 'WS';
89
+ const serverMethod = isWS
90
+ ? 'GET'
91
+ : http_method_1.HandlerMethodToHttpMethod[handlerMethod];
92
+ this.fastify.route({
93
+ method: serverMethod,
94
+ url: item.path,
95
+ websocket: isWS,
96
+ handler: async (req, res) => {
97
+ if (isWS) {
98
+ await item.handler.handle(undefined, {
99
+ headers: req.headers,
100
+ redirect: undefined,
101
+ ws: req,
102
+ });
103
+ return;
104
+ }
105
+ let files = {};
106
+ if (handlerMethod === 'FILE') {
107
+ const part = await req.file();
108
+ files = Object.keys(part.fields).reduce((res, name) => {
109
+ ;
110
+ res[name] = (0, vtils_1.castArray)(part.fields[name]).map(item => item.file ? item : item.value)[0];
111
+ return res;
112
+ }, {});
113
+ }
114
+ const data = await item.handler.handle({
115
+ // @ts-ignore
116
+ ...req.params,
117
+ // @ts-ignore
118
+ ...req.query,
119
+ // @ts-ignore
120
+ ...req.body,
121
+ ...files,
122
+ }, {
123
+ headers: req.headers,
124
+ redirect: url => res.redirect(url),
125
+ ws: undefined,
126
+ });
127
+ return data;
128
+ },
129
+ });
130
+ }
131
+ }
132
+ async applyAutoClose() {
133
+ x_1.x.dispose.add(() => this.close());
134
+ }
135
+ }
136
+ exports.Server = Server;
137
+ Server.options = {};
@@ -0,0 +1,123 @@
1
+ /// <reference types="node" />
2
+ import { BasePlugin } from '../plugins/base';
3
+ import { BaseService } from '../services/base';
4
+ import type { AsyncOrSync, OneOrMore } from 'vtils/types';
5
+ import type { DisposeService } from '../services/dispose';
6
+ import type { Handler } from './handler';
7
+ import type { IncomingHttpHeaders } from 'http';
8
+ import type { MultipartFile } from 'fastify-multipart';
9
+ import type { Queue } from 'bull';
10
+ import type { SocketStream } from 'fastify-websocket';
11
+ export declare namespace XServer {
12
+ type Mode = 'development' | 'production';
13
+ interface Route {
14
+ /**
15
+ * 路径
16
+ */
17
+ path: string;
18
+ /**
19
+ * 处理器
20
+ */
21
+ handler: Handler;
22
+ }
23
+ interface Options {
24
+ /**
25
+ * 应用名称
26
+ */
27
+ name: string;
28
+ /**
29
+ * 监听主机
30
+ */
31
+ host?: string;
32
+ /**
33
+ * 监听端口
34
+ */
35
+ port: number;
36
+ /**
37
+ * 服务列表
38
+ */
39
+ services?: BaseService[];
40
+ /**
41
+ * 插件列表
42
+ */
43
+ plugins?: BasePlugin[];
44
+ }
45
+ }
46
+ export declare namespace XHandler {
47
+ type Method = 'GET' | 'POST' | 'FILE' | 'WS' | 'XML';
48
+ interface ExtraContext {
49
+ }
50
+ interface Context extends ExtraContext {
51
+ /**
52
+ * 请求头
53
+ */
54
+ headers: IncomingHttpHeaders;
55
+ /**
56
+ * HTTP 跳转
57
+ */
58
+ redirect: (url: string) => void;
59
+ /**
60
+ * WS
61
+ */
62
+ ws: SocketStream;
63
+ }
64
+ type Handle<TReqData extends any = void, TResData extends any = void, TReqMethod extends Method = Method> = (
65
+ /**
66
+ * 请求数据,WS 时为一个处理函数
67
+ */
68
+ data: TReqMethod extends 'WS' ? <T extends keyof TReqData>(type: T, fn: (payload: {
69
+ data: TReqData[T]['request'];
70
+ send: (data: TReqData[T]['response']) => void;
71
+ dispose: DisposeService;
72
+ }) => any) => void : TReqData,
73
+ /**
74
+ * 请求上下文
75
+ */
76
+ ctx: Context) => AsyncOrSync<TResData>;
77
+ interface ExtraOptions {
78
+ }
79
+ interface Options<TReqData extends any = void, TResData extends any = void, TReqMethod extends Method = Method> extends ExtraOptions {
80
+ /**
81
+ * 请求方法
82
+ *
83
+ * @default POST
84
+ */
85
+ requestMethod?: TReqMethod;
86
+ /**
87
+ * 请求路径
88
+ */
89
+ requestPath?: OneOrMore<string>;
90
+ /**
91
+ * 是否打包返回数据
92
+ *
93
+ * @default false
94
+ */
95
+ responseDataPack?: boolean;
96
+ /**
97
+ * 处理器
98
+ */
99
+ handle: Handle<TReqData, TResData, TReqMethod>;
100
+ }
101
+ type Hook = (options: Options, ...args: Parameters<Handle>) => AsyncOrSync<void>;
102
+ }
103
+ export declare namespace XTask {
104
+ interface Options<T> {
105
+ /**
106
+ * 任务名称
107
+ */
108
+ name: string;
109
+ /**
110
+ * 是否作为定时任务
111
+ *
112
+ * @see https://crontab.guru/
113
+ */
114
+ cron?: string;
115
+ /**
116
+ * 处理器
117
+ */
118
+ handle: (data: T) => any;
119
+ }
120
+ interface Task<T> extends Queue<T> {
121
+ }
122
+ }
123
+ export declare type XFile = MultipartFile;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ export * from './core/define_bus';
2
+ export * from './core/define_handler';
3
+ export * from './core/define_hook';
4
+ export * from './core/define_server';
5
+ export * from './core/define_task';
6
+ export * from './core/handler';
7
+ export * from './core/http_error';
8
+ export * from './core/server';
9
+ export * from './core/types';
10
+ export * from './plugins/base';
11
+ export * from './plugins/cors';
12
+ export * from './plugins/file_parser';
13
+ export * from './plugins/ws_parser';
14
+ export * from './plugins/xml_parser';
15
+ export * from './services/base';
16
+ export * from './services/cache';
17
+ export * from './services/captcha';
18
+ export * from './services/dispose';
19
+ export * from './services/jwt';
20
+ export * from './services/redis';
21
+ export * from './x';
22
+ export * from '.x/models';