@jiasuyun/apier-parser-json5
Version:
apier json5 parser
162 lines • 6.05 kB
JavaScript
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const parser = __importStar(require("@jiasuyun/apier-parser-base"));
const apier_comment_1 = require("@jiasuyun/apier-comment");
const apier_utils_1 = require("@jiasuyun/apier-utils");
const JSON5 = __importStar(require("json5"));
const Visitor_1 = require("./Visitor");
const helper_1 = require("./helper");
const set_1 = __importDefault(require("lodash/set"));
const merge_1 = __importDefault(require("lodash/merge"));
// 解析 Route
const RE_ROUTE = /^(get|post|put|delete)\s[:\/A-Za-z0-9_\-]+/i;
// 判断根注释, `// @@@`
const RE_ROOT_COMMENT = /^\s*\/\/\s*@@@/;
class Parser {
constructor() {
this.markResIsSignle = {};
this.metadata = {};
}
parse(input) {
let parsedObj;
try {
parsedObj = JSON5.parse(input);
}
catch (err) {
throw new parser.ContentParserError(err.lineNumber, err.columnNumber, err);
}
const comment = this.parseComment(input);
const apis = {};
for (const name in parsedObj) {
apis[name] = this.parseApi(name, parsedObj[name]);
if (this.markResIsSignle[name]) {
comment.changePaths([name, "res"], [name, "res", "0"]);
}
}
return { apis, comment, metadata: this.metadata };
}
parseApi(name, data) {
if (apier_utils_1.kindOf(data) !== apier_utils_1.ApierKind.OBJECT) {
throw new parser.StructParserError([name], "should be object");
}
let api = { name };
const { route, req, res } = data;
this.parseRoute(api, route);
this.parseReq(api, req);
this.markResIsSignle[name] = this.parseRes(api, res);
return api;
}
parseComment(input) {
const lines = input.split("\n");
const comment = new apier_comment_1.ApierComment();
const beginLineIndex = helper_1.beignLineNum(lines);
this.parserMetadata(lines.slice(0, beginLineIndex));
Visitor_1.visit({
lines,
comment,
kind: "scopeObject",
lineIndex: beginLineIndex + 1,
canCollectMetaComment: false,
paths: []
});
return comment;
}
parserMetadata(lines) {
for (let line of lines) {
const match = RE_ROOT_COMMENT.exec(line);
if (!match) {
continue;
}
merge_1.default(this.metadata, apier_comment_1.ApierComment.parse(line.slice(match[0].length)));
}
}
parseRoute(api, route) {
if (!RE_ROUTE.test(route)) {
throw new parser.StructParserError([api.name, "route"], route);
}
const [method, url] = route.split(" ");
api.method = method.toLowerCase();
api.url = url;
}
parseReq(api, req) {
if (req === undefined)
return;
if (apier_utils_1.kindOf(req) !== apier_utils_1.ApierKind.OBJECT) {
throw new parser.StructParserError([api.name, "req"], "must be object");
}
const { headers, params, query, body } = req;
api.req = {};
if (headers)
this.parseParameters(api, ["req", "headers"], headers);
if (params)
this.parseParameters(api, ["req", "params"], params);
if (query)
this.parseParameters(api, ["req", "query"], query);
if (body)
this.parseBody(api, ["req", "body"], body);
}
parseRes(api, res) {
let isSingleRes = true;
if (res === undefined) {
api.res = [{ status: 200 }];
return isSingleRes;
}
const kind = apier_utils_1.kindOf(res);
if (kind === apier_utils_1.ApierKind.OBJECT) {
this.parseSingleRes(api, res, 0);
}
else if (kind === apier_utils_1.ApierKind.ARRAY) {
res.forEach((v, i) => this.parseSingleRes(api, v, i));
isSingleRes = false;
}
else {
throw new parser.StructParserError([api.name, "res"], "must be array or object");
}
return isSingleRes;
}
parseSingleRes(api, res, index) {
let paths = ["res", "" + index];
if (apier_utils_1.kindOf(res) !== apier_utils_1.ApierKind.OBJECT) {
throw new parser.StructParserError(paths, "must be object");
}
const { status = 200, body } = res;
if (status)
this.parseResStatus(api, paths.concat("status"), status);
if (body)
this.parseBody(api, paths.concat("body"), body);
}
parseParameters(api, paths, obj) {
if (typeof obj !== "object") {
throw new parser.StructParserError([api.name, ...paths], `must be object`);
}
for (const key in obj) {
const value = obj[key];
const valueKind = apier_utils_1.kindOf(value);
if (valueKind === apier_utils_1.ApierKind.ARRAY || valueKind === apier_utils_1.ApierKind.OBJECT) {
throw new parser.StructParserError([api.name, ...paths, key], `must be scalar value`);
}
}
set_1.default(api, paths, obj);
}
parseResStatus(api, paths, status = 200) {
if (typeof status !== "number" && status < 100 && status >= 600) {
throw new parser.StructParserError([api.name, ...paths], `{status}`);
}
set_1.default(api, paths, status);
}
parseBody(api, paths, body) {
set_1.default(api, paths, body);
}
}
exports.default = Parser;
//# sourceMappingURL=index.js.map
;