UNPKG

8.29 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.Routes = void 0;
7const app_1 = __importDefault(require("./app"));
8const _ = require("lodash");
9const fs = require("fs");
10const jaul = require("jaul");
11const logger = require("anyhow");
12const settings = require("setmeup").settings;
13class Routes {
14 constructor() {
15 this.load = (options) => {
16 let specs;
17 if (!options || !options.handlers) {
18 throw new Error(`Missing options.handlers with the routing functions`);
19 }
20 logger.debug("Routes.load", options.filename, Object.keys(options.handlers));
21 if (options.specs) {
22 specs = options.specs;
23 }
24 else {
25 if (options.filename == null || options.filename == "") {
26 options.filename = settings.routes.filename;
27 }
28 try {
29 const filename = jaul.io.getFilePath(options.filename);
30 if (filename == null || !fs.existsSync(filename)) {
31 throw new Error(`File ${options.filename} not found.`);
32 }
33 specs = fs.readFileSync(filename, { encoding: settings.general.encoding }).toString();
34 specs = JSON.parse(specs);
35 }
36 catch (ex) {
37 logger.error("Routes.load", options.filename, ex);
38 throw ex;
39 }
40 }
41 for (let [route, spec] of Object.entries(specs)) {
42 if (_.isString(spec)) {
43 spec = { get: spec };
44 }
45 for (let [method, handlerKey] of Object.entries(spec)) {
46 const handler = options.handlers[handlerKey];
47 if (app_1.default[method] == null) {
48 logger.error("Routes.load", options.filename, route, `Invalid method: ${method}`);
49 throw new Error(`Invalid method: ${method}`);
50 }
51 else if (handler == null) {
52 logger.error("Routes.load", options.filename, route, `Invalid handler: ${handlerKey}`);
53 throw new Error(`Invalid handler: ${handlerKey}`);
54 }
55 else {
56 app_1.default[method](route, handler);
57 logger.info("Routes.load", options.filename, route, method, handlerKey);
58 }
59 }
60 }
61 };
62 this.loadSwagger = (options) => {
63 let specs;
64 if (!options || !options.handlers) {
65 throw new Error(`Missing options.handlers with the routing functions`);
66 }
67 logger.debug("Routes.loadSwagger", options.filename, Object.keys(options.handlers));
68 if (options.specs) {
69 specs = options.specs;
70 }
71 else {
72 if (options.filename == null || options.filename == "") {
73 options.filename = settings.routes.swagger.filename;
74 }
75 try {
76 const filename = jaul.io.getFilePath(options.filename);
77 if (filename == null || !fs.existsSync(filename)) {
78 throw new Error(`File ${options.filename} not found.`);
79 }
80 specs = fs.readFileSync(filename, { encoding: settings.general.encoding }).toString();
81 specs = JSON.parse(specs);
82 }
83 catch (ex) {
84 logger.error("Routes.loadSwagger", options.filename, ex);
85 throw ex;
86 }
87 }
88 if (options.version != null) {
89 specs.info.version = options.version;
90 }
91 for (let [path, pathSpec] of Object.entries(specs.paths)) {
92 path = path.toString().replace(/\/{/g, "/:");
93 path = path.replace(/\}/g, "");
94 for (let [method, methodSpec] of Object.entries(pathSpec)) {
95 if (methodSpec == null) {
96 throw new Error(`Missing method spec for ${method} ${path}`);
97 }
98 if (options.handlers[methodSpec.operationId] == null) {
99 throw new Error(`Missing route handler for ${methodSpec.operationId}`);
100 }
101 if (methodSpec.parameters == null) {
102 methodSpec.parameters = [];
103 }
104 logger.info("Routes.loadSwagger", options.filename, method, path, methodSpec.operationId);
105 app_1.default[method](path, (req, res, next) => {
106 try {
107 if (!req.swagger) {
108 req.swagger = {};
109 }
110 for (let parameterSpec of methodSpec.parameters) {
111 this.castParameter(req, parameterSpec);
112 }
113 options.handlers[methodSpec.operationId](req, res, next);
114 }
115 catch (ex) {
116 logger.error("Routes", method, path, methodSpec.operationId, ex);
117 }
118 });
119 }
120 }
121 if (settings.routes.swagger.exposeJson) {
122 app_1.default.get("/swagger.json", (_req, res) => res.json(specs));
123 }
124 };
125 this.castParameter = function (req, spec) {
126 try {
127 const { name } = spec;
128 let scope, separator;
129 switch (spec.in) {
130 case "query":
131 scope = "query";
132 break;
133 case "header":
134 scope = "header";
135 break;
136 case "path":
137 scope = "params";
138 break;
139 }
140 if (scope == null) {
141 return;
142 }
143 req.swagger[scope] = req.swagger[scope] || {};
144 const param = req[scope][name];
145 if (param == null) {
146 return;
147 }
148 if (spec.type == "string") {
149 if (spec.format == "date" || spec.format == "datetime" || spec.format == "date-time") {
150 req.swagger[scope][name] = new Date(param);
151 }
152 else {
153 req.swagger[scope][name] = param;
154 }
155 }
156 else if (spec.type == "number") {
157 req.swagger[scope][name] = parseFloat(param);
158 }
159 else if (spec.type == "integer") {
160 req.swagger[scope][name] = parseInt(param);
161 }
162 else if (spec.type == "boolean") {
163 req.swagger[scope][name] = param;
164 }
165 else if (spec.type == "array") {
166 switch (spec.collectionFormat) {
167 case "csv":
168 separator = ",";
169 break;
170 case "ssv":
171 separator = " ";
172 break;
173 case "pipes":
174 separator = "|";
175 break;
176 }
177 if (separator == null) {
178 return;
179 }
180 req.swagger[scope][name] = param.split(separator);
181 }
182 }
183 catch (ex) {
184 logger.error("Routes.castParameter", spec, ex);
185 }
186 };
187 }
188 static get Instance() {
189 return this._instance || (this._instance = new this());
190 }
191}
192exports.Routes = Routes;
193exports.default = Routes.Instance;