@x82-softworks/aws-api
Version:
An OpenAPI compatible api system intended for use with AWS Lambda and API Gateway
962 lines (931 loc) • 33.1 kB
JavaScript
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"APIKEY": () => (/* reexport */ APIKEY),
"ARRAY": () => (/* reexport */ ARRAY),
"BINARY": () => (/* reexport */ BINARY),
"BOOLEAN": () => (/* reexport */ BOOLEAN),
"BYTE": () => (/* reexport */ BYTE),
"DATE": () => (/* reexport */ DATE),
"DATETIME": () => (/* reexport */ DATETIME),
"DEFAULT_CORS": () => (/* binding */ DEFAULT_CORS),
"DOUBLE": () => (/* reexport */ DOUBLE),
"EMAIL": () => (/* reexport */ EMAIL),
"FLOAT": () => (/* reexport */ FLOAT),
"FORM_ENCODED": () => (/* binding */ FORM_ENCODED),
"GENERIC_ERROR": () => (/* reexport */ GENERIC_ERROR),
"HEADER": () => (/* reexport */ HEADER),
"INT32": () => (/* reexport */ INT32),
"INT64": () => (/* reexport */ INT64),
"INTEGER": () => (/* reexport */ INTEGER),
"NUMBER": () => (/* reexport */ NUMBER),
"OBJECT": () => (/* reexport */ OBJECT),
"PASSWORD": () => (/* reexport */ PASSWORD),
"STRING": () => (/* reexport */ STRING),
"create": () => (/* binding */ create),
"default": () => (/* binding */ src),
"jsonResponseContent": () => (/* binding */ jsonResponseContent),
"requiredJsonRequest": () => (/* binding */ requiredJsonRequest)
});
;// CONCATENATED MODULE: ./src/types.ts
var Method;
(function (Method) {
Method["GET"] = "get";
Method["POST"] = "post";
Method["PUT"] = "put";
Method["DELETE"] = "delete";
Method["PATCH"] = "patch";
Method["OPTIONS"] = "options";
})(Method || (Method = {}));
;// CONCATENATED MODULE: ./src/constants.ts
const NUMBER = "number";
const BOOLEAN = "boolean";
const INTEGER = "integer";
const INT32 = "int32";
const INT64 = "int64";
const STRING = "string";
const FLOAT = "float";
const DOUBLE = "double";
const OBJECT = "object";
const BYTE = "byte";
const BINARY = "binary";
const DATE = "date";
const DATETIME = "dateTime";
const ARRAY = "array";
const HEADER = "header";
const PASSWORD = "password";
const APIKEY = "apikey";
const EMAIL = "email";
;// CONCATENATED MODULE: ./src/urlPattern.ts
const keyPattern = /({[^}]*})/g;
class URLPattern {
constructor(pattern) {
const keys = [];
let key;
while ((key = keyPattern.exec(pattern))) {
key = key[0].slice(1, -1);
keys.push(key);
}
//We need the inorder value of the keys
this.keys = keys;
pattern = pattern.replace(/({[^}]*})/g, "([a-zA-Z0-9-\\._~ %]+)");
this.regex = new RegExp(pattern);
}
match(test) {
let ret = null, match;
if ((match = this.regex.exec(test))) {
ret = {};
for (let i = 0; i < this.keys.length; i++) {
ret[this.keys[i]] = match[i + 1];
}
//We need to check for the param keys and return it as an object
}
return ret;
}
}
;// CONCATENATED MODULE: ./src/utils.ts
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/**
* The default generic error code
* @public
*/
const GENERIC_ERROR = "GenericError";
const isError = (err) => {
return typeof err === "object" && err.name && err.stack && err.message;
};
/**
* Performs the final toStringing of data in the res body
* @internal
* @param res - The response
* @returns The same response with the stringified version of its body
*/
const returnFinal = (res) => {
if (res.body && typeof res.body !== "string") {
res.body = JSON.stringify(res.body);
}
return res;
};
/**
* Checks to see if the object contains a reference to another in the api doc
* @param obj
*/
const isRef = (obj) => {
return typeof obj === "object" && typeof (obj === null || obj === void 0 ? void 0 : obj.$ref) === "string";
};
const coerce = (schema, val) => {
switch (schema.type) {
case OBJECT:
if (typeof val === "string") {
val = JSON.parse(val);
}
break;
case INTEGER:
case NUMBER:
val = Number(val);
break;
case BOOLEAN:
val = Boolean(val);
break;
default:
break;
}
return val;
};
const returnNotFound = function (res) {
return __awaiter(this, void 0, void 0, function* () {
return returnFinal(Object.assign(Object.assign({}, res), { statusCode: 404 }));
});
};
/**
* Convert a string like /{test}/{param} to a url pattern matching object
* @internal
* @param path
* @returns A URLPattern matcher
*/
const convertToRegex = (path) => {
return new URLPattern(path);
};
const returnInvalid = function (res, reason) {
return __awaiter(this, void 0, void 0, function* () {
if (typeof reason === "string") {
reason = {
code: GENERIC_ERROR,
message: reason,
};
}
if (isError(reason)) {
reason = {
code: reason.code || GENERIC_ERROR,
message: reason.message,
};
}
return returnFinal(Object.assign(Object.assign({}, res), { statusCode: 400, body: reason }));
});
};
;// CONCATENATED MODULE: external "serialize-error"
const external_serialize_error_namespaceObject = require("serialize-error");
;// CONCATENATED MODULE: external "@x82-softworks/clone-merge"
const clone_merge_namespaceObject = require("@x82-softworks/clone-merge");
var clone_merge_default = /*#__PURE__*/__webpack_require__.n(clone_merge_namespaceObject);
;// CONCATENATED MODULE: external "cookie"
const external_cookie_namespaceObject = require("cookie");
var external_cookie_default = /*#__PURE__*/__webpack_require__.n(external_cookie_namespaceObject);
;// CONCATENATED MODULE: external "ajv"
const external_ajv_namespaceObject = require("ajv");
var external_ajv_default = /*#__PURE__*/__webpack_require__.n(external_ajv_namespaceObject);
;// CONCATENATED MODULE: external "is-integer"
const external_is_integer_namespaceObject = require("is-integer");
var external_is_integer_default = /*#__PURE__*/__webpack_require__.n(external_is_integer_namespaceObject);
;// CONCATENATED MODULE: ./src/jsonSchemaValidator.ts
const MAX_INT_32 = 2147483647;
const ajv = new (external_ajv_default())({
useDefaults: true,
coerceTypes: true,
});
ajv.addFormat(INT32, {
validate: function (a) {
return external_is_integer_default()(a) && a <= MAX_INT_32 && a >= -MAX_INT_32;
},
type: NUMBER,
});
ajv.addFormat(INT64, {
validate: function (a) {
return external_is_integer_default()(a);
},
type: NUMBER,
});
/**
* Checks to see if the value matches to the given schema
* @method exports
* @param schema
* @param val
* @internal
* @throws {Error}
*/
/* harmony default export */ const jsonSchemaValidator = ((schema, val) => {
let validate = ajv.compile(schema), err;
if (!validate(val)) {
err = new Error("Validation error");
err.additional = validate.errors;
throw err;
}
});
;// CONCATENATED MODULE: ./src/params.ts
var params_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/* harmony default export */ const params = ((req, controller, api) => params_awaiter(void 0, void 0, void 0, function* () {
(controller.parameters || []).forEach(param => {
let val;
switch (param.in) {
case 'query':
val = (req.queryStringParameters || {})[param.name];
break;
case 'header':
val = req.headers[param.name];
break;
case 'path':
val = decodeURIComponent(req.pathParams[param.name]);
break;
case 'cookie':
val = req.headers.cookie[param.name];
break;
default:
throw new Error('Unknown param type : ' + param.in);
}
if (val === undefined) {
if (param.required) {
throw new Error(`Required parameter "${param.name}" not found`);
}
}
else if (param.schema) {
let schema = param.schema;
if (isRef(schema)) {
schema = api.getRef(schema);
}
val = coerce(schema, val);
jsonSchemaValidator(schema, val);
}
req.params[param.name] = val;
});
}));
;// CONCATENATED MODULE: external "@x82-softworks/aws-api-multipart"
const aws_api_multipart_namespaceObject = require("@x82-softworks/aws-api-multipart");
;// CONCATENATED MODULE: external "query-string"
const external_query_string_namespaceObject = require("query-string");
var external_query_string_default = /*#__PURE__*/__webpack_require__.n(external_query_string_namespaceObject);
;// CONCATENATED MODULE: ./src/requestBody.ts
var requestBody_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/* eslint-disable no-case-declarations */
function validateSchema(req, schema, api) {
if (!schema) {
return;
}
if (isRef(schema)) {
schema = api.getRef(schema);
}
const val = (req.body = coerce(schema, req.body));
jsonSchemaValidator(schema, val);
}
/**
* Handles the request body portion of a request
* @param {Object} req
* @param {?Object} controllerRequestBody
* @param {Object} api
*/
/* harmony default export */ function requestBody(req, controllerRequestBody, api) {
return requestBody_awaiter(this, void 0, void 0, function* () {
let contentSelector, hasNoBody = req.body === null || req.body === undefined, schema, contentType;
if (!controllerRequestBody) {
return;
}
//Check if its a request body reference
if (isRef(controllerRequestBody)) {
controllerRequestBody = api.getRef(controllerRequestBody);
}
//Check to see if required
if (controllerRequestBody.required && hasNoBody) {
throw new Error("Request body must be supplied");
}
//If there is no body to parse and its not required then we're done
if (hasNoBody) {
return;
}
contentType = req.headers["content-type"];
if (!contentType) {
return;
// throw new Error('Request headers do not contain "content-type"');
}
//In the case of multipart/form-data having a boundary
contentType = contentType.split(";")[0];
//Check to see if that controller accepts the content type
if (!(contentSelector = controllerRequestBody.content[contentType])) {
throw new Error(`Content Type "${contentType}" is not supported`);
}
schema = contentSelector.schema;
switch (contentType) {
case "application/json":
try {
req.body = JSON.parse(req.body);
}
catch (err) {
throw new Error("Cannot parse request body");
}
break;
case "application/x-www-form-urlencoded":
req.body = external_query_string_default().parse(req.body);
break;
case "multipart/form-data":
const ret = yield (0,aws_api_multipart_namespaceObject.parse)(req);
const { val, multiparts } = ret.files.reduce((acc, file) => {
acc.val[file.fieldName] = file.data.toString("utf-8");
acc.multiparts[file.fieldName] = file;
return acc;
}, {
val: {},
multiparts: {},
});
//The coercion from the validate schea should handle converting application json,etc for us
req.body = val;
req.multiparts = multiparts;
break;
//Passthrough
default:
break;
}
validateSchema(req, schema, api);
});
}
;// CONCATENATED MODULE: ./src/index.ts
var src_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const FORM_ENCODED = 'application/x-www-form-urlencoded';
const DEFAULT_CORS = {
'Access-Control-Allow-Methods': 'GET,OPTIONS,HEAD',
'Access-Control-Allow-headers': 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
};
const APP_JSON = 'application/json', REQUEST_BODY = 'requestBodies', SCHEMA = 'schemas', CALLBACK = 'callbacks', src_HEADER = 'headers', SECURITY = 'securitySchemes', PARAMETER = 'parameters', RESPONSE = 'responses', EXAMPLE = 'examples', LINK = 'links', src_OBJECT = 'object', CONTENT_TYPE = 'content-type';
const paramRegex = /\{([^}]*)\}/;
/**
* Generates a reference object
* @public
* @param type
* @param name
* @returns A reference object
*/
function ref(type, name) {
return {
$ref: '#/components/' + type + '/' + name
};
}
class API {
constructor(opts, devMode) {
this.devMode = !!devMode;
this.rootDef = clone_merge_default()({
openapi: '3.0.0',
info: {
version: '0.0.0',
description: 'Default API',
termsOfService: 'http://swagger.io/terms/',
title: '',
contact: {
email: 'no-reply@example.com'
},
license: {
name: 'Proprietary'
// url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
}
},
host: 'localhost',
basePath: '/',
paths: {}
}, opts);
this.corsConfig = function (req, res) {
const origin = req.headers.Origin ? req.headers.Origin : '*';
res.headers = clone_merge_default()(res.headers, {
'Access-Control-Allow-Origin': origin
}, DEFAULT_CORS);
};
this.paths = [];
this.defSchema('genericError', {
type: src_OBJECT,
properties: {
code: {
description: 'Error code',
type: STRING
},
message: {
description: 'Human readable message',
type: STRING
}
},
required: ['code', 'message']
});
this.defResponse('genericError', {
description: 'An unexpected error occurred',
content: {
'application/json': {
schema: this.refSchema('genericError')
}
}
});
this._suppressValidationErrors = false;
}
/**
* Sets the validation error suppression
* @param val
*/
suppressValidationErrors(val) {
this._suppressValidationErrors = val;
}
/**
* @public
* @returns The Root API defintion
*/
getRoot() {
return clone_merge_default()(true, this.rootDef);
}
defRoot(def) {
this.rootDef = clone_merge_default()(true, this.rootDef, def);
}
/**
* Define the Cors function
*/
cors(configFunc) {
this.corsConfig = configFunc;
}
defComponent(type, name, val) {
if (!this.rootDef.components) {
this.rootDef.components = {};
}
if (!this.rootDef.components[type]) {
this.rootDef.components[type] = {};
}
if (this.rootDef.components[type][name]) {
throw new Error('Component of type : "' +
type +
'" and name : "' +
name +
'" is already defined');
}
this.rootDef.components[type][name] = val;
return this;
}
defSecurity(name, props) {
return this.defComponent(SECURITY, name, props);
}
defResponse(name, props) {
return this.defComponent(RESPONSE, name, props);
}
ref(type, name) {
return ref(type, name);
}
defSchema(name, props) {
if (!props.title) {
props.title = name;
}
return this.defComponent(SCHEMA, name, props);
}
getHost() {
return this.rootDef.host;
}
/**
* Gets the value from the reference object
* @public
* @param refObj
* @returns The referenced object
*/
getRef(refObj) {
if (!isRef(refObj)) {
throw new Error('Not a valid reference object');
}
//"$ref": "#/components/schemas/Pet"
return refObj.$ref
.split('/')
.slice(1)
.reduce(function (acc, piece) {
return acc[piece];
}, this.rootDef);
}
/**
* Ref requests
*/
refResponse(name) {
return ref(RESPONSE, name);
}
refSchema(name) {
return ref(SCHEMA, name);
}
refRequestBody(name) {
return ref(REQUEST_BODY, name);
}
refSecurity(name) {
return ref(SECURITY, name);
}
refExample(name) {
return ref(EXAMPLE, name);
}
refParameter(name) {
return ref(PARAMETER, name);
}
refHeader(name) {
return ref(src_HEADER, name);
}
refCallback(name) {
return ref(CALLBACK, name);
}
refLink(name) {
return ref(LINK, name);
}
/**
* Adds a route to the router
* @public
* @param path
* @param method
* @param [def]
* @param handler
*/
path(path, method, def, handler) {
if (!handler) {
handler = def;
def = null;
}
def = clone_merge_default()(true, {
summary: '',
description: '',
tags: [],
parameters: [],
requestBody: null,
responses: {
200: {
description: 'Success' // schema: null
},
default: this.refResponse('genericError')
}
}, def);
if (!def.requestBody) {
delete def.requestBody;
}
const methodString = method.toLowerCase();
def.handler = handler;
if (!this.rootDef.paths) {
this.rootDef.paths = {};
}
if (!this.rootDef.paths[path]) {
this.rootDef.paths[path] = {};
}
if (this.rootDef.paths[path][methodString]) {
throw new Error('Redefinition of path : ' + path + ' method : ' + methodString);
}
this.rootDef.paths[path][methodString] = def;
//If it has path params
if (paramRegex.test(path)) {
this.paths.push({
regex: convertToRegex(path),
original: path
});
}
return this;
}
/**
* Adds a GET route
* @public
* @param path
* @param [def]
* @param handler
*/
get(path, def, handler) {
return this.path(path, Method.GET, def, handler);
}
/**
* Adds a POST route
* @public
* @param path
* @param [def]
* @param handler
*/
post(path, def, handler) {
return this.path(path, Method.POST, def, handler);
}
/**
* Adds a PUT route
* @public
* @param path
* @param [def]
* @param handler
*/
put(path, def, handler) {
return this.path(path, Method.PUT, def, handler);
}
/**
* Adds a PATCH route
* @public
* @param path
* @param [def]
* @param handler
*/
patch(path, def, handler) {
return this.path(path, Method.PATCH, def, handler);
}
/**
* Adds a DELETE route
* @public
* @param path
* @param [def]
* @param handler
*/
delete(path, def, handler) {
return this.path(path, Method.DELETE, def, handler);
}
defParameter(name, props) {
return this.defComponent(PARAMETER, name, props);
}
defExample(name, props) {
return this.defComponent(EXAMPLE, name, props);
}
defRequestBody(name, props) {
return this.defComponent(REQUEST_BODY, name, props);
}
defHeader(name, props) {
return this.defComponent(src_HEADER, name, props);
}
defLink(name, props) {
return this.defComponent(LINK, name, props);
}
defCallback(name, props) {
return this.defComponent(CALLBACK, name, props);
}
lambda() {
const self = this;
return function (event) {
return src_awaiter(this, void 0, void 0, function* () {
//Automatically set the correct host
if (event.headers && event.headers.Host) {
let more = '';
if (event.requestContext) {
if (event.requestContext.path.indexOf('/' + event.requestContext.stage) === 0) {
//Then we have some kind of basepath added on
more = '/' + event.requestContext.stage;
}
}
self.defRoot({
host: 'https://' + event.headers.Host + more
});
}
return yield self.dispatch(event);
});
};
}
/**
* @public
* @param event
*/
dispatch(event) {
var _a;
return src_awaiter(this, void 0, void 0, function* () {
const req = Object.assign({ path: '/', rawPath: '/', httpMethod: Method.GET, headers: {
//Incoming request headers
}, rawHeaders: {}, queryStringParameters: {
//query string parameters
}, params: {
//Will be added by the dispatcher
}, stageVariables: {
//Applicable stage variables
}, requestContext: {
//Request context,including authorizer - returned key - value pairs
}, pathParams: {}, body: null, isBase64Encoded: false, rawBody: null }, event);
const self = this;
req.rawPath = req.path;
req.httpMethod = req.httpMethod.toLowerCase();
//Make sure all headers are lower case as according to RFCs it doesn't matter but it does simplify lookup
req.headers = Object.keys(req.headers || {}).reduce((acc, key) => {
acc[key.toLowerCase()] = req.headers[key];
return acc;
}, {});
//In case middleware attempts to overwrite it
req.rawBody = req.body;
req.rawHeaders = req.headers;
if ((_a = req.headers) === null || _a === void 0 ? void 0 : _a.cookie) {
req.headers.cookie = external_cookie_default().parse(req.headers.cookie);
}
if (req.path[0] !== '/') {
//Normalise
req.path = '/' + req.path;
}
if (!req.httpMethod || !req.path) {
throw new Error('Event is not wellformed');
}
const res = {
body: undefined,
headers: {},
statusCode: 200
};
//check this against the base path
if (req.path.indexOf(self.rootDef.basePath) !== 0) {
return returnNotFound(res);
}
self.corsConfig(req, res);
req.path = req.path.slice(self.rootDef.basePath.length);
if (req.path[0] !== '/') {
req.path = '/' + req.path;
}
//Lookup the path directly if possible otherwise use pattern matching
let methods = self.rootDef.paths[req.path], pathParams = null, controller;
if (!methods) {
//Try lookup via path matching
for (let i = 0, c = self.paths.length; i < c; i++) {
if ((pathParams = self.paths[i].regex.match(req.path))) {
methods = self.rootDef.paths[self.paths[i].original];
break;
}
}
}
req.pathParams = pathParams;
if (!methods || !(controller = methods[req.httpMethod])) {
//This allows added options to override the base support
if (req.httpMethod === 'options') {
//Automagic option support
return res;
}
return returnNotFound(res);
}
return (requestBody(req, controller.requestBody, self)
.catch(err => {
//Assume user fuckup
res.statusCode = 400;
throw err;
})
.then(() => src_awaiter(this, void 0, void 0, function* () {
yield params(req, controller, self);
return new Promise((resolve, reject) => {
try {
resolve(controller.handler(req, res));
}
catch (err) {
reject(err);
}
}).catch(err => {
if (!res.body) {
if (self.devMode) {
res.body = err;
}
else {
// eslint-disable-next-line no-console
console.error(err);
res.body = new Error('An internal server error has occurred');
}
res.statusCode = res.body.statusCode ? res.body.statusCode : 500;
}
});
}))
//Errors from params and requestbody should fall through to here
.catch(err => {
res.body = err;
})
.then(() => {
var _a, _b;
//Check if the body is an error in which case we extract only the message to prevent leaking the specifics of the server
if (res.body instanceof Error) {
if (self.devMode) {
res.body = (0,external_serialize_error_namespaceObject.serializeError)(res.body);
}
else {
res.body = {
code: ((_a = res.body) === null || _a === void 0 ? void 0 : _a.code) || GENERIC_ERROR,
message: res.body.message,
additional: self._suppressValidationErrors
? null
: (_b = res.body) === null || _b === void 0 ? void 0 : _b.additional
};
}
if (!res.statusCode) {
res.statusCode = res.body.statusCode || 500;
}
}
if (typeof res.body === 'object' && !res.headers[CONTENT_TYPE]) {
//All other types must be
res.headers[CONTENT_TYPE] = APP_JSON;
}
//Convert the body to a string
return returnFinal(res);
}));
});
}
}
/* harmony default export */ const src = (API);
//Auto generate all the ref functions
// [
// SECURITY,
// EXAMPLE,
// PARAMETER,
// RESPONSE,
// HEADER,
// CALLBACK,
// LINK,
// SCHEMA,
// REQUEST_BODY
// ].forEach(type => {
// let name = type;
// if (name === REQUEST_BODY) {
// //Tiny hack because request body does not have a simple pluralization
// name = 'RequestBodys';
// }
// //We use the -1 to remove the pluralization
// API.prototype['ref' + capitalize(name).slice(0, -1)] = (name) => ref(type, name);
// });
/**
* Factory function to create an API
* @public
* @param init
* @param debug
* @returns The created api
*/
const create = function (init, debug) {
return new API(init, debug);
};
/**
* An easy shorthand to create a required JSON requestBody with provided inner schema
* @public
* @param schema
*/
const requiredJsonRequest = (schema) => ({
required: true,
content: {
'application/json': {
schema: schema
}
}
});
/**
* An easy shorhand to create a json response with the provided schema
* @param schema
* @public
* @returns
*/
const jsonResponseContent = (schema) => ({
'application/json': {
schema: schema
}
});
module.exports = __webpack_exports__;
/******/ })()
;
//# sourceMappingURL=commonjs.cjs.map