rest-chronicle
Version:
autodocumentate rest api
154 lines (153 loc) • 4.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _fsExtra = _interopRequireDefault(require("fs-extra"));
var _dotProp = _interopRequireDefault(require("dot-prop"));
var _myrmidon = require("myrmidon");
var _jsYaml = _interopRequireDefault(require("js-yaml"));
var _constants = require("../constants");
var _utils = require("./utils");
var _Base = _interopRequireDefault(require("./Base"));
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 dictionary(obj, prefix = []) {
return (0, _myrmidon.flatten)(Object.entries(obj).map(([key, value]) => {
if ((0, _myrmidon.isObject)(value)) return dictionary(value, [...prefix, key]);
return {
key: [...prefix, key],
value
};
}));
}
const types = {
null: 'nil'
};
class RamlReporter extends _Base.default {
constructor(file, {
hash
} = {}) {
super(file);
_defineProperty(this, "mergeArray", true);
if (hash) this.getHash = hash;
}
_build(actions) {
const map = new Map();
const groups = {};
for (const a of actions) {
const {
path,
method
} = a.request;
const resources = path.split('/').filter(i => i).map(i => `/${i}`);
const groupValues = [...resources, method.toLowerCase()];
_utils.findGroup.call(this, groups, groupValues, a.id);
map.set(a.id, a);
}
return {
groups,
map
};
}
_renderHeaders(headers) {
return Object.entries(headers)
// eslint-disable-next-line unicorn/no-array-reduce
.reduce((prev, [name, value]) => ({
...prev,
[name]: {
example: value,
type: (0, _utils.detectType)(value, types)
}
}), {});
}
_renderBody(body) {
const result = {
type: (0, _utils.detectType)(body, types),
example: (0, _myrmidon.isEmpty)(body) ? body : JSON.stringify(body, null, _constants.DEFAULT_JSON_OFFSET)
};
if (body && result.type === 'object') {
for (const [key, value] of Object.entries(body)) {
_dotProp.default.set(result, `properties.${key}`, {
type: (0, _utils.detectType)(value, types)
});
}
}
return result;
}
_renderAction({
context: {
group,
title
},
request,
response
}) {
return {
'(group)': group,
description: title,
headers: this._renderHeaders(request.headers),
responses: {
[response.status.code]: {
body: {
[response.info.type]: this._renderBody(response.body)
}
}
}
};
}
_generate(groups, map, actions) {
const dict = dictionary(groups);
const hashed = [];
for (const item of dict) {
if (item.value.length === 1) {
hashed.push({
key: item.key,
value: item.value[0]
});
continue;
}
const [original, ...dublicates] = item.value;
hashed.push({
key: item.key,
value: original
});
for (const actionId of dublicates) {
const action = map.get(actionId);
const hash = this.getHash(action);
const [method, lastPath, ...pathRev] = [...item.key].reverse();
hashed.push({
key: [...pathRev.reverse(), `${lastPath}#${hash}`, method],
value: actionId
});
}
}
const paths = {};
const origins = [...new Set(actions.map(a => a.request.origin))];
for (const item of hashed) {
const action = map.get(item.value);
_dotProp.default.set(paths, item.key.join('.'), this._renderAction(action));
}
const content = {
title: 'Raml report',
baseUri: origins[0],
version: '1.0.0',
annotationTypes: {
group: 'string'
},
...paths
};
return `#%RAML 1.0\n${_jsYaml.default.dump(content)}`;
}
async write(actions) {
const {
groups,
map
} = this._build(actions);
const content = this._generate(groups, map, actions);
await _fsExtra.default.writeFile(this.file, content);
}
}
exports.default = RamlReporter;