foundry-dsa41-game/gulpfile.mjs

184 lines
6.8 KiB
JavaScript

import {dest, series, src} from 'gulp';
import process from 'node:process';
import replace from 'gulp-replace';
import jsonModify from 'gulp-json-modify';
import {getRandomValues} from 'node:crypto';
import * as dartSass from 'sass';
import gulpSass from 'gulp-sass';
import {deleteAsync} from 'del';
import {readdirSync, readFileSync, writeFileSync, rmdirSync, existsSync, mkdirSync, statSync} from "fs";
import {join} from 'node:path';
import {compilePack} from '@foundryvtt/foundryvtt-cli';
const sass = gulpSass(dartSass);
/**
* Generate a random alphanumeric string ID of a given requested length using `crypto.getRandomValues()`.
* @param {number} length The length of the random string to generate, which must be at most 16384.
* @returns {string} A string containing random letters (A-Z, a-z) and numbers (0-9).
*/
function randomID(length = 16) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const cutoff = 0x100000000 - (0x100000000 % chars.length);
const random = new Uint32Array(length);
do {
getRandomValues(random);
} while (random.some(x => x >= cutoff));
let id = "";
for (let i = 0; i < length; i++) id += chars[random[i] % chars.length];
return id;
}
const convert = function (from, to, ofType, overwrite = true) {
const SOURCE = from;
const DEST = to;
const TYPE = ofType;
if (overwrite) {
try {
rmdirSync(DEST, {force: true, recursive: true})
} catch (e) {
}
mkdirSync(DEST)
}
const filewalker = (source) => {
console.debug("entering directory", source);
readdirSync(source).forEach(file => {
if (statSync(join(source, file)).isDirectory()) {
filewalker(join(source, file));
} else {
console.debug("processing file", join(source, file))
let originalSource = JSON.parse(readFileSync(join(source, file), {encoding: "utf8"}));
let id = randomID();
let targetSource = {
_id: id,
_key: "!items!" + id,
type: TYPE,
img: originalSource.image,
name: originalSource.name.trim(),
system: {...originalSource},
}
delete targetSource.system.image;
let target = JSON.stringify(targetSource, null, 2);
let newFileName = "./" + join(DEST, id + ".json");
writeFileSync(newFileName, target, {encoding: "utf8"});
}
});
}
filewalker(SOURCE)
}
function cleanDist() {
return deleteAsync(['dist/**']);
}
function buildStyles() {
return src('src/style/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(dest('dist/style/'))
}
function copySource() {
return src(['src/**/*', '!src/assets/**/*', '!src/style/**/*.scss', '!src/packs/**/*'])
.pipe(dest('dist/'));
}
function copyAssets() {
return src(['src/assets/**/*'], {encoding: false})
.pipe(dest('dist/assets/'))
}
function updateManifestFile() {
return src('src/system.json')
.pipe(
jsonModify({
key: "version",
value: process.env.VERSION
})
)
.pipe(
jsonModify({
key: "download",
value: "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/{{VERSION}}/release.zip".replace("{{VERSION}}", process.env.VERSION)
})
)
.pipe(dest('src/'))
}
async function prepareDB() {
try {
if (!existsSync("./src/packs/__source")) {
mkdirSync("./src/packs/__source");
}
convert("./src/packs/_source/talente", "./src/packs/__source/talente", "Skill");
convert("./src/packs/_source/zauber", "./src/packs/__source/zauber", "Spell");
convert("./src/packs/_source/vorteile", "./src/packs/__source/vorteile", "Advantage");
convert("./src/packs/_source/nachteile", "./src/packs/__source/vorteile", "Advantage", false);
convert("./src/packs/_source/sonderfertigkeiten", "./src/packs/__source/sonderfertigkeiten", "SpecialAbility");
convert("./src/packs/_source/waehrungen", "./src/packs/__source/waehrungen", "Equipment");
convert("./src/packs/_source/Gegenstaende/Waffen", "./src/packs/__source/Waffen", "Equipment");
convert("./src/packs/_source/Gegenstaende/Munition", "./src/packs/__source/Munition", "Equipment");
convert("./src/packs/_source/Gegenstaende/Ruestzeug", "./src/packs/__source/Ruestzeug", "Equipment");
convert("./src/packs/_source/Gegenstaende/Behaelter", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Bekleidung", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Beleuchtung", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Buecher", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Essutensilien", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Sonstiges", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Werkzeug", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/Gegenstaende/Seile", "./src/packs/__source/Gegenstaende", "Equipment", false);
convert("./src/packs/_source/liturgien-und-segnungen", "./src/packs/__source/liturgien", "Liturgy");
convert("./src/packs/_source/wunden", "./src/packs/__source/wunden", "ActiveEffect");
convert("./src/packs/_source/kulturen", "./src/packs/__source/kulturen", "Culture");
convert("./src/packs/_source/spezien", "./src/packs/__source/spezien", "Species");
convert("./src/packs/_source/professionen", "./src/packs/__source/professionen", "Profession");
} catch (err) {
console.error(err);
}
}
function buildDB() {
// Determine which source folders to process
const PACK_SRC = "src/packs/__source"
const PACK_DEST = "dist/packs/"
return new Promise(async (resolve, reject) => {
const folders = readdirSync(PACK_SRC, {withFileTypes: true}).filter(file =>
file.isDirectory()
);
for (const folder of folders) {
const src = join(PACK_SRC, folder.name);
const dest = join(PACK_DEST, folder.name);
console.info(`Compiling pack ${folder.name}`);
await compilePack(src, dest, {recursive: true, nedb: false});
}
resolve()
})
}
export default series(
cleanDist,
updateManifestFile,
copySource,
copyAssets,
buildStyles,
prepareDB,
buildDB
)