218 lines
6.1 KiB
JavaScript
218 lines
6.1 KiB
JavaScript
import fs from "node:fs"
|
|
import path from "node:path"
|
|
import crypto from "node:crypto"
|
|
|
|
import { Level } from "level"
|
|
|
|
export const CONTENT_PACK_DEFINITIONS = [
|
|
{ sourceFile: "armes.json", outputFolder: "armes", type: "Item" },
|
|
{ sourceFile: "armures.json", outputFolder: "armures", type: "Item" },
|
|
{ sourceFile: "equipements.json", outputFolder: "equipements", type: "Item" },
|
|
{ sourceFile: "pouvoirs-compagnie.json", outputFolder: "pouvoirs-compagnie", type: "Item" },
|
|
{ sourceFile: "competences.json", outputFolder: "competences", type: "Item" },
|
|
{ sourceFile: "races.json", outputFolder: "races", type: "Item" },
|
|
{ sourceFile: "tribus.json", outputFolder: "tribus", type: "Item" },
|
|
{ sourceFile: "metiers.json", outputFolder: "metiers", type: "Item" },
|
|
{ sourceFile: "sortileges.json", outputFolder: "sortileges", type: "Item" },
|
|
]
|
|
|
|
export const SYSTEM_PACK_DEFINITIONS = [
|
|
...CONTENT_PACK_DEFINITIONS,
|
|
{ sourceFile: "aide-systeme.json", outputFolder: "aide-systeme", type: "JournalEntry" },
|
|
]
|
|
|
|
function slugId(input) {
|
|
const hash = crypto.createHash("sha256").update(input).digest()
|
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
let id = ""
|
|
for (let index = 0; id.length < 16; index += 1) {
|
|
id += alphabet[hash[index % hash.length] % alphabet.length]
|
|
}
|
|
return id
|
|
}
|
|
|
|
function createDocumentStats({
|
|
documentSystemId,
|
|
documentSystemVersion,
|
|
coreVersion,
|
|
createdTime,
|
|
lastModifiedBy = "Copilot",
|
|
} = {}) {
|
|
return {
|
|
systemId: documentSystemId,
|
|
systemVersion: documentSystemVersion,
|
|
coreVersion,
|
|
createdTime,
|
|
modifiedTime: createdTime,
|
|
lastModifiedBy,
|
|
compendiumSource: null,
|
|
duplicateSource: null,
|
|
exportSource: null,
|
|
}
|
|
}
|
|
|
|
function toItemPackDocument(entry, index, options = {}) {
|
|
const docId = slugId(`${entry.type}:${entry.name}`)
|
|
return {
|
|
key: `!items!${docId}`,
|
|
value: {
|
|
name: entry.name,
|
|
type: entry.type,
|
|
img: entry.img ?? "icons/svg/item-bag.svg",
|
|
system: entry.system ?? {},
|
|
effects: Array.isArray(entry.effects) ? entry.effects : [],
|
|
flags: entry.flags ?? {},
|
|
_stats: createDocumentStats(options),
|
|
_id: docId,
|
|
folder: null,
|
|
sort: index * 1000,
|
|
ownership: {
|
|
default: 0,
|
|
},
|
|
},
|
|
embedded: [],
|
|
}
|
|
}
|
|
|
|
function toJournalPageDocument(entry, journalId, page, pageIndex, options = {}) {
|
|
const pageId = slugId(`JournalEntryPage:${entry.name}:${page.name ?? page.title ?? pageIndex}`)
|
|
return {
|
|
_id: pageId,
|
|
name: page.name ?? `Page ${pageIndex + 1}`,
|
|
type: page.type ?? "text",
|
|
title: {
|
|
show: page.title?.show ?? true,
|
|
level: page.title?.level ?? 1,
|
|
},
|
|
text: {
|
|
format: page.text?.format ?? 1,
|
|
content: page.text?.content ?? "",
|
|
},
|
|
system: page.system ?? {},
|
|
image: page.image ?? {},
|
|
video: page.video ?? { controls: true, volume: 0.5 },
|
|
src: page.src ?? null,
|
|
category: page.category ?? null,
|
|
sort: page.sort ?? pageIndex * 1000,
|
|
ownership: page.ownership ?? { default: -1 },
|
|
flags: page.flags ?? {},
|
|
_stats: createDocumentStats(options),
|
|
_key: `!journal.pages!${journalId}.${pageId}`,
|
|
}
|
|
}
|
|
|
|
function toJournalPackDocument(entry, index, options = {}) {
|
|
const docId = slugId(`JournalEntry:${entry.name}`)
|
|
const pages = Array.isArray(entry.pages)
|
|
? entry.pages.map((page, pageIndex) => toJournalPageDocument(entry, docId, page, pageIndex, options))
|
|
: []
|
|
|
|
return {
|
|
key: `!journal!${docId}`,
|
|
value: {
|
|
name: entry.name,
|
|
pages: pages.map((page) => page._id),
|
|
ownership: entry.ownership ?? { default: 0 },
|
|
flags: entry.flags ?? { core: {} },
|
|
_stats: createDocumentStats(options),
|
|
folder: null,
|
|
sort: entry.sort ?? index * 1000,
|
|
_id: docId,
|
|
categories: Array.isArray(entry.categories) ? entry.categories : [],
|
|
},
|
|
embedded: pages.map((page) => ({
|
|
key: page._key,
|
|
value: {
|
|
name: page.name,
|
|
type: page.type,
|
|
title: page.title,
|
|
text: page.text,
|
|
system: page.system,
|
|
image: page.image,
|
|
video: page.video,
|
|
src: page.src,
|
|
category: page.category,
|
|
sort: page.sort,
|
|
ownership: page.ownership,
|
|
flags: page.flags,
|
|
_stats: page._stats,
|
|
_id: page._id,
|
|
},
|
|
})),
|
|
}
|
|
}
|
|
|
|
function toPackDocument(entry, index, options = {}) {
|
|
if (entry.type === "JournalEntry") return toJournalPackDocument(entry, index, options)
|
|
return toItemPackDocument(entry, index, options)
|
|
}
|
|
|
|
async function buildPack({
|
|
sourcePath,
|
|
outputPath,
|
|
type,
|
|
documentSystemId,
|
|
documentSystemVersion,
|
|
coreVersion,
|
|
createdTime,
|
|
lastModifiedBy,
|
|
}) {
|
|
const source = JSON.parse(fs.readFileSync(sourcePath, "utf8"))
|
|
if (!Array.isArray(source)) {
|
|
throw new Error(`Pack source must be an array: ${sourcePath}`)
|
|
}
|
|
|
|
fs.rmSync(outputPath, { recursive: true, force: true })
|
|
fs.mkdirSync(outputPath, { recursive: true })
|
|
|
|
const db = new Level(outputPath, { valueEncoding: "utf8" })
|
|
|
|
try {
|
|
await db.open()
|
|
const batch = db.batch()
|
|
source.forEach((entry, index) => {
|
|
if (!entry.type) {
|
|
throw new Error(`Missing document type in ${sourcePath}: ${entry.name}`)
|
|
}
|
|
const doc = toPackDocument(entry, index, {
|
|
documentSystemId,
|
|
documentSystemVersion,
|
|
coreVersion,
|
|
createdTime,
|
|
lastModifiedBy,
|
|
})
|
|
batch.put(doc.key, JSON.stringify(doc.value))
|
|
for (const embedded of doc.embedded) {
|
|
batch.put(embedded.key, JSON.stringify(embedded.value))
|
|
}
|
|
})
|
|
await batch.write()
|
|
} finally {
|
|
await db.close()
|
|
}
|
|
}
|
|
|
|
export async function buildPacks({
|
|
sourceRoot,
|
|
outputRoot,
|
|
packDefinitions = SYSTEM_PACK_DEFINITIONS,
|
|
documentSystemId,
|
|
documentSystemVersion,
|
|
coreVersion,
|
|
createdTime = Date.now(),
|
|
lastModifiedBy = "Copilot",
|
|
}) {
|
|
for (const pack of packDefinitions) {
|
|
await buildPack({
|
|
sourcePath: path.join(sourceRoot, pack.sourceFile),
|
|
outputPath: path.join(outputRoot, pack.outputFolder),
|
|
type: pack.type,
|
|
documentSystemId,
|
|
documentSystemVersion,
|
|
coreVersion,
|
|
createdTime,
|
|
lastModifiedBy,
|
|
})
|
|
}
|
|
}
|