1
0
Fork 0
arangodb/js/server/modules/@arangodb/foxx/swagger.js

113 lines
3.8 KiB
JavaScript

'use strict';
// //////////////////////////////////////////////////////////////////////////////
// / DISCLAIMER
// /
// / Copyright 2016 ArangoDB GmbH, Cologne, Germany
// /
// / Licensed under the Apache License, Version 2.0 (the "License")
// / you may not use this file except in compliance with the License.
// / You may obtain a copy of the License at
// /
// / http://www.apache.org/licenses/LICENSE-2.0
// /
// / Unless required by applicable law or agreed to in writing, software
// / distributed under the License is distributed on an "AS IS" BASIS,
// / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// / See the License for the specific language governing permissions and
// / limitations under the License.
// /
// / Copyright holder is ArangoDB GmbH, Cologne, Germany
// /
// / @author Alan Plum
// //////////////////////////////////////////////////////////////////////////////
const NotFound = require('http-errors').NotFound;
const fs = require('fs');
const joinPath = require('path').join;
const normalizePath = require('path').normalize;
const internal = require('internal');
const errors = require('@arangodb').errors;
const FoxxManager = require('@arangodb/foxx/manager');
const swaggerJson = require('@arangodb/foxx/legacy/swagger').swaggerJson;
const NOT_FOUND = errors.ERROR_SERVICE_NOT_FOUND.code;
const SWAGGER_ROOT = fs.join(internal.startupPath, 'server', 'assets', 'swagger');
module.exports = function createSwaggerRouteHandler (foxxMount, opts) {
if (!opts) {
opts = {};
}
if (typeof opts === 'function') {
opts = {before: opts};
}
if (typeof opts === 'string') {
opts = {swaggerJson: opts};
}
const defaultMount = opts.mount || foxxMount;
const defaultIndexFile = opts.indexFile || 'index.html';
const defaultSwaggerRoot = opts.swaggerRoot || SWAGGER_ROOT;
const defaultSwaggerJsonHandler = opts.swaggerJson || swaggerJson;
return function (req, res) {
let mount = defaultMount;
let indexFile = defaultIndexFile;
let swaggerRoot = defaultSwaggerRoot;
if (typeof opts.before === 'function') {
const result = opts.before.apply(this, arguments);
if (result === false) {
return;
}
if (result.indexFile) {
indexFile = result.indexFile;
}
if (result.mount) {
mount = result.mount;
}
if (result.swaggerRoot) {
swaggerRoot = result.swaggerRoot;
}
}
let path = req.suffix;
if (!path) {
let params = Object.keys(req._raw.parameters || {}).reduce(function (part, name) {
return part + encodeURIComponent(name) + '=' + encodeURIComponent(req._raw.parameters[name]) + '&';
}, '?');
params = params.slice(0, params.length - 1);
res.redirect(req.makeAbsolute(req.path + '/index.html') + params);
return;
}
if (path === 'swagger.json') {
let swaggerJsonHandler = defaultSwaggerJsonHandler;
if (typeof swaggerJsonHandler === 'string') {
path = swaggerJsonHandler;
} else if (typeof swaggerJsonHandler === 'function') {
let foxx;
try {
foxx = FoxxManager.ensureRouted(mount);
} catch (e) {
if (e.isArangoError && e.errorNum === NOT_FOUND) {
throw new NotFound(e.message);
}
throw e;
}
swaggerJsonHandler(req, res, {mount, foxx});
return;
} else if (swaggerJsonHandler && typeof swaggerJsonHandler === 'object') {
res.json(swaggerJsonHandler);
return;
}
} else if (path === 'index.html') {
path = indexFile;
}
path = normalizePath('/' + path);
const filePath = joinPath(swaggerRoot, path);
if (!fs.isFile(filePath)) {
throw new NotFound(`unknown path "${req._raw.url}"`);
}
res.sendFile(filePath);
};
};