jsonweaver
Version:
A simple utility to transform JSON data into CSV, XML, YAML, JSONLines and Markdown table formats.
230 lines (217 loc) • 8 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
jsonweaver: () => jsonweaver
});
module.exports = __toCommonJS(index_exports);
// src/converters/toJsonLines.ts
var import_stream = require("stream");
function toJsonLines(jsonArray, options) {
if (!Array.isArray(jsonArray)) {
throw new Error("Input must be an array of JSON objects.");
}
if (!jsonArray.every((item) => item && typeof item === "object" && !Array.isArray(item))) {
throw new Error("All elements in the array must be valid JSON objects.");
}
const { indent = 0, excludeKeys = [] } = options || {};
return jsonArray.map((obj) => {
const filteredObj = { ...obj };
excludeKeys.forEach((key) => delete filteredObj[key]);
return JSON.stringify(filteredObj, null, indent);
}).join("\n");
}
function toJsonLinesStream(jsonArray) {
if (!Array.isArray(jsonArray)) {
throw new Error("Input must be an array of JSON objects.");
}
return import_stream.Readable.from(jsonArray.map((obj) => JSON.stringify(obj) + "\n"));
}
// src/utils/helpers/createCustomError.ts
function createCustomError(message, code) {
return { message, code };
}
// src/utils/helpers/validateJsonSchema.ts
var import_ajv = __toESM(require("ajv"), 1);
var ajv = new import_ajv.default({ allErrors: true, strict: false });
function validateJsonSchema(json, schema) {
const validate = ajv.compile(schema);
const valid = validate(json);
if (!valid) {
const errors = validate.errors?.map((err) => `${err.instancePath} ${err.message}`).join(", ");
throw createCustomError(`JSON Schema validation error: ${errors}`, 400);
}
}
// src/converters/toMarkdownTable.ts
function toMarkdownTable(json) {
if (json.length === 0) {
throw new Error("Input JSON array is empty.");
}
const headers = Array.from(new Set(json.flatMap(Object.keys)));
const rows = json.map((obj) => headers.map((header) => obj[header] || ""));
const headerRow = `| ${headers.join(" | ")} |`;
const separatorRow = `| ${headers.map(() => "--- ").join("| ")}|`;
const dataRows = rows.map((row) => `| ${row.join(" | ")} |`);
return [headerRow, separatorRow, ...dataRows].join("\n");
}
// src/utils/helpers/batchProcess.ts
function batchProcess(data, batchSize, processor) {
const batches = [];
for (let i = 0; i < data.length; i += batchSize) {
batches.push(data.slice(i, i + batchSize));
}
return Promise.all(
batches.map((batch, index) => processor(batch, index))
);
}
// src/utils/helpers/flattenObject.ts
function flattenObject(obj, prefix = "") {
return Object.entries(obj).reduce((acc, [key, value]) => {
const newKey = prefix ? `${prefix}.${key}` : key;
if (value && typeof value === "object" && !Array.isArray(value)) {
Object.assign(acc, flattenObject(value, newKey));
} else {
acc[newKey] = value;
}
return acc;
}, {});
}
// src/utils/helpers/flattenJson.ts
function flattenJson(Json) {
return Json.map((item) => flattenObject(item));
}
// src/converters/toCSV.ts
var defaultCSVFieldGenerator = (Json) => {
const allKeys = Array.from(new Set(Json.flatMap((item) => Object.keys(item))));
return allKeys.map((key) => ({
label: key,
value: key
}));
};
var toCSV = (Json, fieldGenerator = defaultCSVFieldGenerator) => {
if (Json.length === 0) return "";
const flattenedJson = flattenJson(Json);
const allObjectsEmpty = flattenedJson.every((item) => Object.keys(item).length === 0);
if (allObjectsEmpty) return "";
const fields = fieldGenerator(flattenedJson);
const headers = fields.map((field) => `"${field.label}"`).join(",");
const rows = flattenedJson.map(
(row) => fields.map((field) => {
const value = row[field.value];
if (value === null || value === void 0) {
return "";
} else if (typeof value === "string") {
return `"${value.replace(/"/g, '""')}"`;
} else if (typeof value === "number") {
return `${value}`;
} else {
return `"${String(value).replace(/"/g, '""')}"`;
}
}).join(",")
);
return [headers, ...rows].join("\n");
};
// src/converters/toYaml.ts
var yaml = __toESM(require("js-yaml"), 1);
function toYaml(jsonInput, options) {
const { sortKeys = false, noRefs = true } = options || {};
let jsonData;
try {
if (typeof jsonInput === "string") {
jsonData = JSON.parse(jsonInput);
} else if (typeof jsonInput === "object" && jsonInput !== null) {
jsonData = jsonInput;
} else {
const error = createCustomError("Input must be a valid JSON string or object.", 400);
throw error;
}
return yaml.dump(jsonData, {
noRefs,
sortKeys
});
} catch (error) {
if (error instanceof SyntaxError) {
const customError = createCustomError("Invalid JSON format.", 400);
throw customError;
} else if (error && typeof error.message === "string") {
const customError = createCustomError(`Conversion error: ${error.message}`, 500);
throw customError;
} else {
const customError = createCustomError("An unknown error occurred.", 500);
throw customError;
}
}
}
// src/converters/toXML.ts
var import_xmlbuilder = require("xmlbuilder");
function toXML(json, options = {}) {
if (typeof json !== "object" || Array.isArray(json)) {
throw new Error("Input must be a JSON object (not an array or primitive).");
}
const { maxDepth = Infinity, arrayHandling = "wrap", prettyPrint = true } = options;
const buildXML = (obj, depth = 0) => {
if (depth > maxDepth) return;
if (Array.isArray(obj)) {
if (arrayHandling === "wrap") {
return { item: obj.map((item) => buildXML(item, depth + 1)) };
} else if (arrayHandling === "index") {
return obj.reduce((acc, item, index) => {
acc[`item${index}`] = buildXML(item, depth + 1);
return acc;
}, {});
}
} else if (typeof obj === "object" && obj !== null) {
return Object.entries(obj).reduce((acc, [key, value]) => {
acc[key] = buildXML(value, depth + 1);
return acc;
}, {});
} else if (obj === null || obj === void 0) {
return "";
}
return obj;
};
const wrappedJson = { root: buildXML(json) };
return (0, import_xmlbuilder.create)(wrappedJson, { headless: true }).end({ pretty: prettyPrint });
}
// src/index.ts
var jsonweaver = {
validateJsonSchema,
toJsonLinesStream,
toMarkdownTable,
batchProcess,
toJsonLines,
toYaml,
toCSV,
toXML
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
jsonweaver
});