@xcrap/parser
Version:
Xcrap Parser is a package of the Xcrap framework, it was developed to take care of the data extraction part of text files (currently supporting only HTML and JSON) using declarative models.
98 lines (97 loc) • 3.84 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonParsingModel = void 0;
const jmespath = __importStar(require("jmespath"));
class JsonParsingModel {
constructor(shape) {
this.shape = shape;
}
async parse(source) {
const root = JSON.parse(source);
const data = {};
for (const key in this.shape) {
const value = this.shape[key];
const isNestedValue = "model" in value;
if (isNestedValue) {
data[key] = await this.parseNestedValue(value, root);
}
else {
data[key] = this.parseValue(value, root);
}
}
return data;
}
parseValue(value, root) {
const extractedData = jmespath.search(root, value.query);
if (extractedData === null && value.default !== undefined) {
return value.default;
}
return extractedData;
}
async parseNestedValue(value, root) {
const extractedData = jmespath.search(root, value.query);
const model = value.model;
const modelIsJsonParser = model.constructor.name === JsonParsingModel.name;
if (extractedData === null && value.default !== undefined) {
return value.default;
}
if (value.multiple) {
if (!Array.isArray(extractedData)) {
throw new Error(`Expected an array for multiple values, but got ${typeof extractedData}`);
}
if (value.limit !== undefined) {
extractedData.splice(value.limit);
}
if (!modelIsJsonParser) {
if (extractedData.some(item => typeof item !== "string")) {
throw new Error(`Expected an array of strings for model parsing, but got ${typeof extractedData[0]}`);
}
return await Promise.all(extractedData.map(item => model.parse(JSON.stringify(item))));
}
}
else {
if (!modelIsJsonParser && typeof extractedData !== "string") {
throw new Error(`Expected a string for model parsing, but got ${typeof extractedData}`);
}
if (!modelIsJsonParser) {
return await model.parse(extractedData);
}
return await model.parse(JSON.stringify(extractedData));
}
return extractedData;
}
}
exports.JsonParsingModel = JsonParsingModel;