ds4/tools/json-pack-tools.js

97 lines
3 KiB
JavaScript
Raw Permalink Normal View History

// SPDX-FileCopyrightText: 2021 Johannes Loher
//
// SPDX-License-Identifier: MIT
import promises from "node:fs/promises";
import path from "node:path";
import Datastore from "@seald-io/nedb";
/**
* Removes unwanted data from a pack entry
*/
function cleanPackEntry(entry, cleanSourceId = true) {
if (cleanSourceId) {
delete entry.flags?.core?.sourceId;
}
Object.keys(entry.flags).forEach((scope) => {
if (Object.keys(entry.flags[scope]).length === 0) {
delete entry.flags[scope];
}
});
if (entry.permission) entry.permission = { default: 0 };
const embeddedDocumentCollections = [
"drawings",
"effects",
"items",
"lights",
"notes",
"results",
"sounds",
"templates",
"tiles",
"tokens",
"walls",
];
embeddedDocumentCollections
.flatMap((embeddedDocumentCollection) => entry[embeddedDocumentCollection] ?? [])
.forEach((embeddedEntry) => cleanPackEntry(embeddedEntry, false));
return entry;
}
/**
* Converts JSON content containing an array to a Pack (NeDB) string.
* @param {string | ArrayBuffer} contents The input JSON content
* @returns {Promise<string>} The resulting Pack string
*/
export async function convertJSONToPack(contents) {
const jsonString = contents.toString();
return (
JSON.parse(jsonString)
.map((entry) => cleanPackEntry(entry))
.map((entry) => JSON.stringify(entry))
.join("\n") + "\n"
);
}
/**
* Converts a pack file (NeDB) to a JSON string.
* @param {string} filename The name of the pack file
* @returns {Promise<Array<unknown>>} A promise that resolves to an array of the documents in the pack file
*/
function convertPackFileToJSON(filename) {
const db = new Datastore({ filename, autoload: true });
return new Promise((resolve, reject) => {
db.find({}, (err, docs) => {
if (err) {
reject(err);
} else {
resolve(
JSON.stringify(
docs.map((entry) => cleanPackEntry(entry)),
undefined,
4,
) + "\n",
);
}
});
});
}
/**
* Converts a pack file (NeDB) to a JSON file and puts it in the given directory. If no directory is given, it is put
* into the same directory as the pack file.
* @param {string} filename The name of the pack file
* @param {string} [directory] A directory to put the json file into
* @returns {Promise<void>} A promise that resolves once the JSON file has been written
*/
export async function convertPackFileToJSONFile(filename, directory) {
if (directory === undefined) {
directory = path.dirname(filename);
}
console.log(" ", path.basename(filename));
const jsonFilePath = path.join(directory, `${path.basename(filename, path.extname(filename))}.json`);
const json = await convertPackFileToJSON(filename);
await promises.writeFile(jsonFilePath, json);
}