@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
JavaScript
;
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);
}