UNPKG

@ffsm/napi

Version:

Napi - A framework using with Next.js for building APIs.

161 lines (160 loc) 5.36 kB
import { NapiMethod } from "./enums"; import { ucfirst } from "./helpers"; export class NapiController { constructor(targer) { this.targer = targer; this.routes = new Map(); this.params = new Map(); this.response = new Map(); } setPrefix(options = "") { let path = ''; if (typeof options === 'string') { path = options; } else { path = options.path || ''; } this.prefix = path; } getPrefix() { return this.prefix; } setRoute(method, route) { this.routes.set(method, route); return this; } getRoutes(method) { if (method) { return this.routes.get(method); } return this.routes; } setParam(method, payload) { var _a; const existing = ((_a = this.getParams(method)) !== null && _a !== void 0 ? _a : []).filter((param) => param.index !== payload.index); this.params.set(method, [...existing, payload]); return this; } getParams(method) { return this.params.get(method); } setResponse(method, payload) { var _a; const res = Object.assign({}, (_a = this.response.get(method)) !== null && _a !== void 0 ? _a : {}, payload); this.response.set(method, res); return this; } getResponse(method) { return this.response.get(method); } hasPrefix() { return this.prefix !== undefined; } getName() { return this.targer.constructor.name; } hasRoutes() { return !!this.routes.size; } getInstance() { if (!this.instance) { const target = this.targer; this.instance = new target(); } return this.instance; } static from(target) { if (this.decorators.has(target)) { return this.decorators.get(target); } const controller = new NapiController(target); this.decorators.set(target, controller); return controller; } static createControllerDecorator() { return (options) => { return (target) => { const controller = this.from(target); controller.setPrefix(options); return target; }; }; } static createMethodDecorator(handler) { return (options) => { return (target, propertyKey, descriptor) => { const controller = NapiController.from(target.constructor); handler(...[options, { controller, target, propertyKey, descriptor, }]); return descriptor; }; }; } static createParamDecorator(handle) { return (options) => { return (target, methodKey, index) => { if (!methodKey) { return; } const controller = NapiController.from(target.constructor); controller.setParam(String(methodKey), { handle, options, target, index, }); return index; }; }; } static has(controller) { return this.decorators.has(controller); } static get(controller) { return this.decorators.get(controller); } } NapiController.decorators = new Map(); export const Controller = NapiController.createControllerDecorator(); export const createMethodDecorator = NapiController.createMethodDecorator; export const createParamDecorator = NapiController.createParamDecorator; export const { Get, Post, Put, Patch, Delete, Options, Head } = Object .values(NapiMethod) .filter((method) => typeof method === 'string') .reduce((acc, method) => { const capitalized = ucfirst(method); acc[capitalized] = NapiController.createMethodDecorator((data, ctx) => { const path = (typeof data === 'string' ? data : data === null || data === void 0 ? void 0 : data.path) || "/"; ctx.controller.setRoute(`${method}:${path}`, String(ctx.propertyKey)); }); return acc; }, {}); const names = ['body', 'query', 'params', 'headers', 'cookies', 'files', 'session', 'res', 'req']; export const { Body, Query, Params, Headers, Cookies, Files, Session, Res, Req, } = names.reduce((acc, name) => { const capitalized = ucfirst(name); acc[capitalized] = NapiController.createParamDecorator((_, ctx) => { if (name === 'res') { return ctx.getResponse(); } if (name === 'req') { return ctx.getRequest(); } const router = ctx.getRouter(); return router[name]; }); return acc; }, {}); export const HttpText = NapiController.createMethodDecorator((statusText, ctx) => { ctx.controller.setResponse(String(ctx.propertyKey), { statusText }); }); export const HttpStatus = NapiController.createMethodDecorator((status, ctx) => { ctx.controller.setResponse(String(ctx.propertyKey), { status }); }); export const SetHeaders = NapiController.createMethodDecorator((headers, ctx) => { ctx.controller.setResponse(String(ctx.propertyKey), { headers }); });