@alinex/datastore
Version:
Read, work and write data structures from and to differents locations and formats.
109 lines • 3.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.format = exports.parse = void 0;
const path_1 = require("path");
const util_1 = require("util");
const debug_1 = require("debug");
const xml = require("xml2js");
const moment = require("moment");
const parseString = util_1.promisify(xml.parseString);
const debug = debug_1.default('datastore:format:xml');
function cast(obj) {
// @ts-ignore
const defaultFallback = moment.createFromInputFallback;
// @ts-ignore
moment.createFromInputFallback = function (config) {
config._d = new Date(NaN);
};
if (typeof obj !== 'object')
return obj;
Object.keys(obj).forEach(key => {
if (typeof obj[key] == 'string') {
if (obj[key] == 'true')
obj[key] = true;
else if (obj[key] == 'false')
obj[key] = false;
else {
// string -> number
const n = Number(obj[key]);
if (!isNaN(n)) {
obj[key] = n;
return;
}
// string -> date
const d = moment(obj[key]);
if (d.isValid())
obj[key] = d.toDate();
}
}
else if (typeof obj[key] == 'object' && obj[key]) {
// go deeper
cast(obj[key]);
}
});
// @ts-ignore
moment.createFromInputFallback = defaultFallback;
return obj;
}
function preformat(obj) {
if (typeof obj !== 'object')
return obj;
Object.keys(obj).forEach(key => {
if (obj[key] instanceof Date) {
// Date -> string
obj[key] = obj[key].toISOString();
}
else if (typeof obj[key] == 'object' && obj[key]) {
// go deeper
preformat(obj[key]);
}
});
return obj;
}
const parse = async function (parsedUri, buffer) {
if (!parsedUri.pathname)
return Promise.reject(`No pathname given in ${parsedUri.href}`);
const pathname = parsedUri.hash || path_1.basename(parsedUri.pathname);
debug(`parsing ${pathname}`);
let data = await cast(
// @ts-ignore
await parseString(buffer.toString(), {
trim: true,
emptyTag: null,
explicitRoot: false,
explicitArray: false,
normalizeTags: true,
preserveChildrenOrder: true
}).catch(e => {
e.data = buffer.toString();
throw e;
}));
// remove top level object if only containing one array
if (Object.keys(data).length == 1) {
const key = Object.keys(data)[0];
if (Array.isArray(data[key]))
data = data[key];
}
return data;
};
exports.parse = parse;
const format = (function (parsedUri, data, options) {
if (!parsedUri.pathname)
return Promise.reject(`No pathname given in ${parsedUri.href}`);
const pathname = parsedUri.hash || path_1.basename(parsedUri.pathname);
debug(`formatting for ${pathname}`);
// top-level array to object with array
if (Array.isArray(data)) {
data = { entry: data };
}
// format
let rootName = 'data';
if (options && options.rootName)
rootName = options.rootName;
const builder = new xml.Builder({ rootName, cdata: true });
return Promise.resolve(
// @ts-ignore
Buffer.from(builder.buildObject(preformat(Object.assign({}, data)))));
});
exports.format = format;
//# sourceMappingURL=xml.js.map