UNPKG

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