rest-chronicle
Version:
autodocumentate rest api
134 lines (131 loc) • 4.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _url = require("url");
var _myrmidon = require("myrmidon");
var _chronicle = _interopRequireDefault(require("../chronicle"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
function arrayKeyFilter(keys) {
return function (action, actions) {
const dublicate = actions.find(a => keys.every(key => (0, _myrmidon.getProp)(action, key) === (0, _myrmidon.getProp)(a, key)) && a._id !== action._id);
return !dublicate;
};
}
function parseContentTypeHeader(header) {
const [type, charset] = header.split('charset=');
return {
type: type.split(';')[0],
charset
};
}
/* eslint-disable no-param-reassign */
// eslint-disable-next-line sonarjs/cognitive-complexity
function chronicleMiddleware(req, res, next) {
const action = this.chronicle.action(this.context);
const originalWrite = res.write;
const originalEnd = res.end;
const chunks = [];
res.write = function (chunk) {
chunks.push(chunk);
originalWrite.apply(res, arguments);
};
res.end = function (chunk) {
if (chunk) {
chunks.push(chunk);
}
originalEnd.apply(res, arguments);
};
const url = new _url.URL(req.originalUrl, `${req.protocol}://${req.get('host')}`);
if (req.route) {
url.pathname = req.route.path;
}
action.request = {
url,
headers: req.headers,
method: req.method,
body: req._body ? req.body : null
};
res.on('finish', () => {
var _this$config;
const body = Buffer.concat(chunks).toString('utf8');
let parsedBody = body;
const responseInfo = parseContentTypeHeader(res.getHeader('Content-Type'));
if (body && responseInfo.type === 'application/json') {
parsedBody = JSON.parse(body);
}
if (body && responseInfo.type === 'mimetype') {
parsedBody = Buffer.from(body);
}
action.response = {
body: parsedBody,
headers: res.getHeaders(),
http: {
version: res.httpVersion
},
status: {
code: res.statusCode,
message: res.statusMessage
},
...responseInfo
};
const save = (_this$config = this.config) === null || _this$config === void 0 ? void 0 : _this$config.save;
if (save) {
const actions = this.chronicle._actions;
if ((0, _myrmidon.isFunction)(save)) {
save(action, actions, this.chronicle, this.config);
} else {
let isApproved = true;
if (save.uniqueFilter) {
if ((0, _myrmidon.isFunction)(save.uniqueFilter)) isApproved = save.uniqueFilter(action, actions);
if ((0, _myrmidon.isArray)(save.uniqueFilter)) isApproved = arrayKeyFilter(save.uniqueFilter)(action, actions);
}
if (!isApproved) return;
const {
server
} = req.socket;
if (!server._chronicles) server._chronicles = [];
const promises = Promise.all(save.files.map(({
path,
...opts
}) => this.chronicle.save(path, opts)));
server._chronicles.push(promises);
}
}
});
next();
}
class Express {
constructor(chronicle = _chronicle.default, config = {}) {
_defineProperty(this, "generateMiddleWare", (...args) => {
return (...expressArgs) => {
const context = this.getContext(...args, ...expressArgs);
chronicleMiddleware.call({
context,
chronicle: this._chronicle,
config: this._config
}, ...expressArgs);
};
});
this._chronicle = chronicle;
this._config = config;
// eslint-disable-next-line no-constructor-return
return this.generateMiddleWare;
}
getContext(...args) {
if (typeof args[0] === 'function') {
return {
...args[0](...args.slice(1))
};
}
return {
group: args[0],
title: args[1]
};
}
}
exports.default = Express;