@micro.ts/core
Version:
Microservice framework with Typescript
192 lines (191 loc) • 7.52 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getObjectSchema = exports.getAppSchema = exports.schemas = exports.getServerObject = exports.getServerInfo = void 0;
const joi_to_swagger_1 = __importDefault(require("joi-to-swagger"));
const joi_typescript_validator_1 = require("joi-typescript-validator");
const decorators_1 = require("../decorators");
const GlobalMetadata_1 = require("../decorators/GlobalMetadata");
function getServerInfo(title, version, description) {
return { title, version, description };
}
exports.getServerInfo = getServerInfo;
function getServerObject(host, port, protocol = 'http', description = '') {
return {
url: '{protocol}://{host}:{port}',
description,
variables: {
host: { default: host },
port: { default: port.toString() },
protocol: { default: protocol },
},
};
}
exports.getServerObject = getServerObject;
exports.schemas = new Map();
const controllers = (0, GlobalMetadata_1.getGlobalMetadata)();
function buildControllerSchema(metadata) {
const methodSchemas = {};
if (metadata.handlers) {
Object.keys(metadata.handlers).forEach((key) => {
var _a;
const obj = buildHandlerSchema('', ((_a = metadata.options) === null || _a === void 0 ? void 0 : _a.path) || '', metadata.ctor, metadata.handlers[key]);
methodSchemas[obj.path] = methodSchemas[obj.path] || {};
const newObj = Object.assign({}, obj);
delete newObj.path;
Object.assign(methodSchemas[obj.path], newObj);
});
}
return methodSchemas;
}
function extractPath(def) {
let basePart = def.base;
if (basePart && basePart.indexOf('/') !== 0) {
basePart = `/${basePart}`;
}
let controllerPart = def.controller;
if (controllerPart.indexOf('/') !== 0) {
controllerPart = `/${controllerPart}`;
}
let handlerPart = def.handler;
const params = extractParamNames(handlerPart);
handlerPart = params
.map((x) => {
if (x.param) {
return `{${x.name}}`;
}
return x.name;
})
.join('/');
if (handlerPart.indexOf('/') !== 0 && handlerPart.length > 0) {
handlerPart = `/${handlerPart}`;
}
return `${basePart}${controllerPart}${handlerPart}`.replace(/\/\//g, '/');
}
function extractParamNames(path, separator = '/') {
const spl = path.split(separator);
return spl.map((x) => {
const value = { name: x, param: false };
if (x.length > 0 && x[0] === ':') {
value.name = x.substr(1);
value.param = true;
}
return value;
});
}
function buildHandlerSchema(basePath, controllerPath, ctor, description) {
var _a, _b, _c;
const routeDefinition = {
base: basePath,
controller: controllerPath,
controllerCtor: ctor,
handler: ((_a = description.metadata) === null || _a === void 0 ? void 0 : _a.path) || '',
handlerName: description.name || '',
method: ((_b = description.metadata) === null || _b === void 0 ? void 0 : _b.method) || 'get',
queueOptions: description.metadata.queueOptions,
json: true,
timeout: 0,
};
return {
path: extractPath(routeDefinition),
[((_c = description.metadata) === null || _c === void 0 ? void 0 : _c.method) || 'get']: buildMethodParameters(description, ctor.name),
};
}
function buildMethodParameters(method, controller) {
const obj = {
responses: { '200': { description: '' } },
};
obj.tags = [controller];
method.params.forEach((param) => {
var _a, _b, _c, _d;
if ((_a = param.options) === null || _a === void 0 ? void 0 : _a.decoratorType) {
// BODY
if (param.options.decoratorType === decorators_1.ParamDecoratorType.Body) {
obj.requestBody = {
content: {
'application/json': { schema: getObjectSchema(param.type) },
},
required: !!((_b = param.options.bodyOptions) === null || _b === void 0 ? void 0 : _b.required),
};
}
// BODY FIELD
// PATH PARAM
if (param.options.decoratorType === decorators_1.ParamDecoratorType.ParamField) {
obj.parameters = obj.parameters || [];
const name = param.options.name;
if (!obj.parameters.find((x) => x.name === name && x.id === 'path')) {
obj.parameters.push({
name,
in: 'path',
required: true,
schema: {
type: param.type.name.toLowerCase(),
},
});
}
}
// FULL PARAMS OBJECT
// QUERY PARAM
if (param.options.decoratorType === decorators_1.ParamDecoratorType.QueryField) {
obj.parameters = obj.parameters || [];
const name = param.options.name;
if (!obj.parameters.find((x) => x.name === name && x.in === 'query')) {
obj.parameters.push({
name,
in: 'query',
required: !!((_c = param.options.queryParamOptions) === null || _c === void 0 ? void 0 : _c.required),
schema: {
type: param.type.name.toLowerCase(),
},
});
}
}
// FULL QUERY OBJECT
// HEADER PARAM
if (param.options.decoratorType === decorators_1.ParamDecoratorType.HeaderField) {
obj.parameters = obj.parameters || [];
const name = param.options.name;
if (!obj.parameters.find((x) => x.name === name && x.in === 'header')) {
obj.parameters.push({
name,
in: 'header',
required: !!((_d = param.options.queryParamOptions) === null || _d === void 0 ? void 0 : _d.required),
schema: {
type: param.type.name.toLowerCase(),
},
});
}
}
// FULL HEADER OBJECT
}
});
return obj;
}
function getAppSchema() {
const values = {
paths: {},
info: getServerInfo('Test', 'Test', 'Test'),
openapi: '3.0.0',
servers: [
getServerObject('0.0.0.0', 8080, 'http', 'Public'),
getServerObject('0.0.0.0', 8081, 'http', 'Private'),
],
};
controllers.controllers.forEach((ct) => {
const ctorSchema = buildControllerSchema(ct);
Object.assign(values.paths, ctorSchema);
});
return values;
}
exports.getAppSchema = getAppSchema;
function getObjectSchema(obj) {
if (!exports.schemas.has(obj)) {
const joiSchema = (0, joi_typescript_validator_1.getSchema)(obj);
const schema = (0, joi_to_swagger_1.default)(joiSchema);
exports.schemas.set(obj, schema['swagger']);
}
return exports.schemas.get(obj);
}
exports.getObjectSchema = getObjectSchema;