UNPKG

@httpc/kit

Version:

httpc toolbox for building function-based API with minimal code and end-to-end type safety

50 lines (49 loc) 2.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.httpController = void 0; const server_1 = require("@httpc/server"); const di_1 = require("../di"); function httpController(constructor) { function createMethodCall(methodName) { return (...args) => { const instance = (0, di_1.useInjected)(constructor); const method = instance[methodName]; if (!method) { throw new server_1.HttpCServerError("callNotFound"); } return method.apply(instance, args); }; } const { CALL_MIDDLEWARE: CLASS_MIDDLEWARE = [], ...controllerMetadata } = getAllMetadata(constructor); const calls = new Map(); for (const methodName of getMethods(constructor)) { const { CALL_ACCESS = "write", CALL_MIDDLEWARE = [], ...callMetadata } = getAllMetadata(constructor, methodName); if (!CALL_ACCESS) continue; calls.set(methodName, (0, server_1.httpCall)(CALL_ACCESS, (0, server_1.Metadata)({ ...controllerMetadata, ...callMetadata }), ...CLASS_MIDDLEWARE, ...CALL_MIDDLEWARE, createMethodCall(methodName))); } return Object.fromEntries(calls); } exports.httpController = httpController; function getMethods(constructor) { const methods = Object.entries(Object.getOwnPropertyDescriptors(constructor.prototype)) .filter(([key, descriptor]) => { if (key === "constructor") return false; if (typeof descriptor.value !== "function") return false; const access = Reflect.getMetadata("CALL_ACCESS", constructor.prototype, key) || "write"; if (!access) return false; return true; }); return methods.map(([key]) => key); } function getAllMetadata(target, property) { const metadata = property ? Reflect.getMetadataKeys(target.prototype, property) .map(key => [key, Reflect.getMetadata(key, target.prototype, property)]) : Reflect.getMetadataKeys(target.prototype) .map(key => [key, Reflect.getMetadata(key, target.prototype)]); return Object.fromEntries(metadata); }