UNPKG

nodefony

Version:
395 lines (381 loc) 10.4 kB
const spdx = require("spdx"); class openApiSchema extends nodefony.Service { constructor (api, config, entity) { const container = api ? api.container : kernel.container; super("openApiSchema", container, false); this.api = api; this.orm = this.kernel.getORM(); this.ormName = this.orm.name; this.entity = entity; this.obj = { openapi: "3.0.2", security: [], paths: {}, components: { schemas: { NodefonyError: this.getErrorSchema(), Pdu: this.getPduSchema() }, responses: this.getResponseSchema() }, tags: [], externalDocs: {} }; if (config) { this.loadConfig(config); } } loadConfig (config, entity) { this.setConfig(entity); return nodefony.extend(true, this.obj, config); } getConfig () { return this.obj; } setConfig (entity = this.entity) { this.obj.info = this.getInfo(); this.obj.servers = this.getServers(); if (entity) { switch (this.ormName) { case "mongoose": this.setSchema(entity.collection.collectionName, entity); break; default: this.setSchema(entity.name, entity); } } return this.obj; } getInfo () { return { title: this.api.name, version: this.api.version, description: this.api.description, contact: { name: this.kernel.app.settings.App.authorName, url: `https://${this.kernel.domain}`, email: this.kernel.app.settings.App.authorMail }, termsOfService: "", license: this.getLicence() }; } getServers () { const tab = []; const base = { "description": this.kernel.description, "variables": { "port": { "enum": [ `${this.kernel.httpsPort}`, "443" ], "default": `${this.kernel.httpsPort}` }, "basePath": { "default": this.api.basePath || "" } } }; if (this.kernel.domain === "0.0.0.0") { tab.push({ "url": "https://localhost:{port}", ...base }); } tab.push({ "url": `https://${this.kernel.domain}:{port}`, ...base }); return tab; } getLicence (licence = "", url = "") { const {bundle} = this.api; if (bundle) { if (bundle.package && bundle.package.license) { try { if (bundle.package.license !== "UNLICENSED") { spdx.parse(bundle.package.license); return { name: bundle.package.license }; } return { name: bundle.package.license }; } catch (e) { this.log(e, "WARNING"); spdx.licenses.every((element) => { this.log(element, "WARNING"); return typeof element === "string"; }); this.log("licence not valid ", "WARNING"); this.log("Show licence param in package.json and use spdx to valid : https://github.com/kemitchell/spdx.js "); this.log("Or use <UNLICENSED> value"); } } } if (licence) { return { name: licence, url }; } return { name: "UNLICENSED" }; } setSchema (name, entity = this.entity) { try { if (name) { this.obj.components.schemas[name] = {}; } if (entity) { this.obj.components.schemas[name] = this.orm.getOpenApiSchema(entity); for (let ele in this.obj.components.schemas[name].properties) { if (this.obj.components.schemas[ele]) { continue; } const attr = this.obj.components.schemas[name].properties[ele]; if (attr.items && attr.items.$ref) { let entityRef = this.orm.getEntity(ele); if (entityRef) { this.obj.components.schemas[ele] = this.orm.getOpenApiSchema(entityRef); } else if (ele.endsWith("s")) { ele = ele.slice(0, -1); entityRef = this.orm.getEntity(ele); if (entityRef) { this.obj.components.schemas[ele] = this.orm.getOpenApiSchema(entityRef); } } } } } } catch (e) { this.log(e, "WARNING"); return this.obj.components.schemas[name]; } } getResponseSchema () { return { "400": { description: "Bad Request", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "401": { description: "Unauthorized", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "403": { description: "Forbidden", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "404": { description: "Not Found", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "405": { description: "Method Not Allowed", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "406": { description: "Not Acceptable", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "412": { description: "Precondition Failed", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "415": { description: "Unsupported Media Type", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "500": { description: "Internal Server Error", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, "501": { description: "Not Implemented", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } }, default: { description: "nodefony unexpected error", content: { "application/json": { schema: { $ref: "#/components/schemas/NodefonyError" } } } } }; } getErrorSchema () { return { type: "object", properties: { server: { type: "string" }, code: { type: "integer", format: "int32" }, url: { type: "string" }, message: { type: "string" }, pdu: { "$ref": "#/components/schemas/Pdu" } }, example: ` { "server": "nodefony", "code": 401, "pdu": { "timeStamp": 1576059686158, "uid": 866, "severity": 3, "severityName": "ERROR", "typePayload": "object", "payload": { "code": 401, "message": "jwt expired", "bundle": "users", "controller": "api", "action": "", "url": "https://localhost:5152/api/users?limit=2", "stack": "securityError: jwt expired\n at securedArea.handleError (/Users/cci/repository/nodefony-core/src/nodefony/kernel/security/secureArea.es6:86:25)\n at /Users/cci/repository/nodefony-core/src/nodefony/kernel/security/secureArea.es6:240:28\n at tryCallOne (/Users/cci/repository/nodefony-core/src/nodefony/node_modules/promise/lib/core.js:37:12)\n at /Users/cci/repository/nodefony-core/src/nodefony/node_modules/promise/lib/core.js:123:15\n at flush (/Users/cci/repository/nodefony-core/src/nodefony/node_modules/asap/raw.js:50:29)\n at processTicksAndRejections (internal/process/task_queues.js:79:11)" }, "moduleName": "nodefony", "msgid": "", "msg": "" }, "url": "https://localhost:5152/api/users?limit=2", "message": "jwt expired" } ` }; } getPduSchema () { return { type: "object", properties: { timeStamp: { type: "string", format: "date-time" }, uid: { type: "string", format: "uuid" }, severity: { type: "integer", format: "int32", enum: [0, 1, 2, 3, 4, 5, 6, 7] }, severityName: { type: "string", enum: [ "EMERGENCY", "ALERT", "CRITIC", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG" ] }, typePayload: { type: "string" }, payload: { type: "object" } }, example: ` "pdu": { "timeStamp": 1576059686158, "uid": 866, "severity": 3, "severityName": "ERROR", "typePayload": "object", "payload": { "code": 401, "message": "jwt expired", "bundle": "users", "controller": "api", "action": "", "url": "https://localhost:5152/api/users?limit=2", "stack": "securityError: jwt expired\n at securedArea.handleError (/Users/cci/repository/nodefony-core/src/nodefony/kernel/security/secureArea.es6:86:25)\n at /Users/cci/repository/nodefony-core/src/nodefony/kernel/security/secureArea.es6:240:28\n at tryCallOne (/Users/cci/repository/nodefony-core/src/nodefony/node_modules/promise/lib/core.js:37:12)\n at /Users/cci/repository/nodefony-core/src/nodefony/node_modules/promise/lib/core.js:123:15\n at flush (/Users/cci/repository/nodefony-core/src/nodefony/node_modules/asap/raw.js:50:29)\n at processTicksAndRejections (internal/process/task_queues.js:79:11)" } ` }; } } nodefony.openApiSchema = openApiSchema; module.exports = openApiSchema;