UNPKG

phecda-server

Version:

server framework that provide IOC/type-reuse/http&rpc-adaptor

542 lines (526 loc) 11.8 kB
import { Factory, Meta, ServerPhecda, defaultServerInject, emitter, phecdaNamespace, useS } from "./chunk-PFPOEZHH.mjs"; import { Addon, ApiDoc, Arg, BaseParam, Body, Controller, Ctx as Ctx2, Define, Delete, Filter, Get, Guard, Head, Header, ManyFiles, OneFile, Param, Patch, Pipe, Post, Put, Query, Queue, Route, Rpc, Search } from "./chunk-FI5756JX.mjs"; import { BadGatewayException, BadRequestException, ConflictException, Context, Exception, ForbiddenException, FrameworkException, InvalidInputException, NotFoundException, PayloadLargeException, ServiceUnavailableException, TimeoutException, TimerException, UnauthorizedException, UndefinedException, UnsupportedMediaTypeException, ValidateException, WorkerException, addAddon, addFilter, addGuard, addPipe, defaultPipe, joinUrl } from "./chunk-BLLRB5DQ.mjs"; import { ERROR_SYMBOL, IS_DEV, IS_ONLY_GENERATE, IS_PURE, IS_STRICT, LOG_LEVEL, Mixin, PS_EXIT_CODE, __name, getLogger, log, runMiddleware, setLogger } from "./chunk-NQ55PA2X.mjs"; // src/types.ts var CustomResponse = class { static { __name(this, "CustomResponse"); } _ps_response; }; // src/modules/base.ts import { Base } from "phecda-core"; function _ts_decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } __name(_ts_decorate, "_ts_decorate"); function _ts_metadata(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } __name(_ts_metadata, "_ts_metadata"); var ServerBase = class extends Base { static { __name(this, "ServerBase"); } emitter = emitter; log(msg, level = "log") { log(msg, level, this.tag); } }; var HttpBase = class extends ServerBase { static { __name(this, "HttpBase"); } context; }; _ts_decorate([ Ctx2, _ts_metadata("design:type", typeof Ctx === "undefined" ? Object : Ctx) ], HttpBase.prototype, "context", void 0); var RpcBase = class extends ServerBase { static { __name(this, "RpcBase"); } context; }; _ts_decorate([ Ctx2, _ts_metadata("design:type", typeof Ctx === "undefined" ? Object : Ctx) ], RpcBase.prototype, "context", void 0); // src/modules/filter.ts import { getTag } from "phecda-core"; var PFilter = class extends ServerBase { static { __name(this, "PFilter"); } key; constructor(tag) { super(); this.key = tag || getTag(this); addFilter(this.key, this.use.bind(this)); this.onUnmount(() => { delete Context.filterRecord[this.key]; }); } }; // src/modules/guard.ts import { getTag as getTag2 } from "phecda-core"; var PGuard = class extends ServerBase { static { __name(this, "PGuard"); } key; priority = 0; constructor(tag) { super(); this.key = tag || getTag2(this); addGuard(this.key, this.use.bind(this), this.priority); this.onUnmount(() => { delete Context.guardRecord[this.key]; }); } }; // src/modules/pipe.ts import { getTag as getTag3 } from "phecda-core"; var PPipe = class extends ServerBase { static { __name(this, "PPipe"); } key; constructor(tag) { super(); this.key = tag || getTag3(this); addPipe(this.key, this.use.bind(this)); this.onUnmount(() => { delete Context.pipeRecord[this.key]; }); } }; // src/modules/addon.ts import { getTag as getTag4 } from "phecda-core"; var PAddon = class extends ServerBase { static { __name(this, "PAddon"); } key; priority = 0; constructor(tag) { super(); this.key = tag || getTag4(this); addAddon(this.key, this.use.bind(this), this.priority); this.onUnmount(() => { delete Context.addonRecord[this.key]; }); } }; // src/modules/extension.ts import { getTag as getTag5 } from "phecda-core"; var PExtension = class extends ServerBase { static { __name(this, "PExtension"); } key; guardPriority; addonPriority; constructor(tag) { super(); const key = this.key = tag || getTag5(this); if (this.pipe) { addPipe(key, this.pipe.bind(this)); this.onUnmount(() => { delete Context.pipeRecord[key]; }); } if (this.addon) { addAddon(key, this.addon.bind(this), this.addonPriority); this.onUnmount(() => { delete Context.addonRecord[key]; }); } if (this.guard) { addGuard(key, this.guard.bind(this), this.guardPriority); this.onUnmount(() => { delete Context.guardRecord[key]; }); } if (this.filter) { addFilter(key, this.filter.bind(this)); this.onUnmount(() => { delete Context.filterRecord[key]; }); } } }; // src/generator/utils.ts import fse from "fs-extra"; var Generator = class { static { __name(this, "Generator"); } _path; constructor(path) { if (path) this._path = path; } ext = ".js"; get path() { return this._path || `.ps/${this.name.toLowerCase()}${this.ext}`; } async output(meta) { await fse.outputFile(this.path, this.generateCode(meta)); } }; // src/generator/rpc.ts var RPCGenerator = class extends Generator { static { __name(this, "RPCGenerator"); } name = "RPC"; classMap = {}; getContent() { let content = ""; for (const name in this.classMap) { content += ` export class ${name}{ ${Object.values(this.classMap[name]).reduce((p, c) => p + c)} }`; } return content; } addMethod(args) { const { rpc, name, method, tag } = args; if (!rpc) return; if (!this.classMap[name]) this.classMap[name] = {}; this.classMap[name][method] = ` ${method}(){ return {tag:'${tag}',method:"${method}",isEvent:${!!rpc.isEvent},queue:"${rpc.queue || ""}"} } `; } generateCode(meta) { meta.forEach(({ data }) => { if (data.controller === "rpc") this.addMethod(data); }); return this.getContent(); } }; // src/generator/http.ts var HTTPGenerator = class extends Generator { static { __name(this, "HTTPGenerator"); } name = "HTTP"; classMap = {}; getContent() { let content = ""; for (const name in this.classMap) { content += ` export class ${name}{ ${Object.values(this.classMap[name]).reduce((p, c) => p + c)} }`; } return content; } addMethod(args) { const { http, name, method, params, tag } = args; if (!http?.method) return; const url = joinUrl(http.prefix, http.route).replace(/\/\:([^\/]*)/g, (_, js) => `/{{${js}}}`); if (!this.classMap[name]) this.classMap[name] = {}; this.classMap[name][method] = ` ${method}(...args){ let url="${url}" const ret={tag:"${tag}",method:"${method}",body:{},headers:{},query:{},params:{}} ${params.reduce((p, c, i) => `${p}ret.${c.type}${c.key ? `['${c.key}']` : ""}=args[${i}] ${c.type === "params" ? `url=url.replace('{{${c.key}}}',args[${i}])` : ""} `, "")} ret.http={method:"${http.method}",url} return ret } `; } generateCode(meta) { meta.forEach(({ data }) => { if (data.controller === "http") this.addMethod(data); }); return this.getContent(); } }; // src/generator/openapi.ts import { getMergedMeta } from "phecda-core"; var OpenAPIGenerator = class extends Generator { static { __name(this, "OpenAPIGenerator"); } ext = ".json"; name = "OpenAPI"; paths = {}; getContent() { return JSON.stringify({ openapi: "3.0.0", info: { title: "API Documentation", version: "1.0.0", description: "API documentation generated by phecda-server" }, paths: this.paths }); } addMethod(args, model) { const { http, tag, method } = args; if (!http?.method) return; const config = getMergedMeta(model, method).openapi; if (!config) return; const path = joinUrl(http.prefix, http.route); if (!this.paths[path]) this.paths[path] = {}; this.paths[path][http.method] = { summary: config.summary, description: config.description, tags: config.tags || [ tag ], deprecated: config.deprecated, parameters: config.parameters, requestBody: config.requestBody, responses: config.responses }; } generateCode(meta) { meta.forEach(({ data, model }) => { if (data.controller === "http") this.addMethod(data, model); }); return this.getContent(); } }; // src/generator/doc.ts var DocGenerator = class extends Generator { static { __name(this, "DocGenerator"); } name = "DOC"; classMap = {}; constructor(path) { super(path || ".ps/doc.json"); } getContent() { return JSON.stringify(this.classMap); } addMethod(data) { const { name, method, meta } = data; if (!meta.doc) return; if (!this.classMap[name]) this.classMap[name] = {}; this.classMap[name][method] = { doc: meta.doc, params: data.params.filter((item) => item.meta.doc).map((item) => { return { doc: item.meta.doc, index: item.index }; }) }; } generateCode(meta) { meta.forEach(({ data }) => { if (data.controller) this.addMethod(data); }); return this.getContent(); } }; // src/generator/graph.ts import { getTag as getTag6 } from "phecda-core"; var GraphGenerator = class extends Generator { static { __name(this, "GraphGenerator"); } ext = ".mmd"; name = "Graph"; generateCode(meta) { const edges = /* @__PURE__ */ new Set(); const nodes = /* @__PURE__ */ new Set(); meta.forEach(({ model }) => { const from = String(getTag6(model)); nodes.add(from); const paramTypes = Reflect.getMetadata("design:paramtypes", model) || []; paramTypes.forEach((dep) => { const to = String(getTag6(dep)); if (to && to !== from) { nodes.add(to); edges.add(`${to} --> ${from}`); } }); }); let result = "graph TD\n"; nodes.forEach((n) => { result += ` ${String(n)} `; }); edges.forEach((e) => { result += ` ${e} `; }); return result; } }; // src/index.ts export * from "phecda-core"; export { Addon, ApiDoc, Arg, BadGatewayException, BadRequestException, BaseParam, Body, ConflictException, Context, Controller, Ctx2 as Ctx, CustomResponse, Define, Delete, DocGenerator, ERROR_SYMBOL, Exception, Factory, Filter, ForbiddenException, FrameworkException, Generator, Get, GraphGenerator, Guard, HTTPGenerator, Head, Header, HttpBase, IS_DEV, IS_ONLY_GENERATE, IS_PURE, IS_STRICT, InvalidInputException, LOG_LEVEL, ManyFiles, Meta, Mixin, NotFoundException, OneFile, OpenAPIGenerator, PAddon, PExtension, PFilter, PGuard, PPipe, PS_EXIT_CODE, Param, Patch, PayloadLargeException, Pipe, Post, Put, Query, Queue, RPCGenerator, Route, Rpc, RpcBase, Search, ServerBase, ServerPhecda, ServiceUnavailableException, TimeoutException, TimerException, UnauthorizedException, UndefinedException, UnsupportedMediaTypeException, ValidateException, WorkerException, addAddon, addFilter, addGuard, addPipe, defaultPipe, defaultServerInject, emitter, getLogger, log, phecdaNamespace, runMiddleware, setLogger, useS };