chore: replace gulp by a pure rollup based build
This commit is contained in:
parent
294fbefd0a
commit
0d6b89a3ed
16 changed files with 1772 additions and 2573 deletions
|
@ -24,7 +24,7 @@ module.exports = {
|
||||||
|
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ["./*.js"],
|
files: ["./*.cjs", "./*.js"],
|
||||||
rules: {
|
rules: {
|
||||||
"@typescript-eslint/no-var-requires": "off",
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
},
|
},
|
10
README.md
10
README.md
|
@ -27,9 +27,7 @@ https://git.f3l.de/api/v4/projects/dungeonslayers%2Fds4/packages/generic/ds4/lat
|
||||||
|
|
||||||
In order to build this system, recent versions of `node` and `yarn` are
|
In order to build this system, recent versions of `node` and `yarn` are
|
||||||
required. Most likely using `npm` also works but only `yarn` is officially
|
required. Most likely using `npm` also works but only `yarn` is officially
|
||||||
supported. We recommend using the latest lts version of `node`, which is
|
supported. We recommend using the latest lts version of `node`. If you use `nvm` to manage your `node` versions, you can simply run
|
||||||
`v14.17.1` at the time of writing. If you use `nvm` to manage your `node`
|
|
||||||
versions, you can simply run
|
|
||||||
|
|
||||||
```
|
```
|
||||||
nvm install
|
nvm install
|
||||||
|
@ -37,7 +35,7 @@ nvm install
|
||||||
|
|
||||||
in the project's root directory.
|
in the project's root directory.
|
||||||
|
|
||||||
You also need to install the the project's dependencies. To do so, run
|
You also need to install the project's dependencies. To do so, run
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn install
|
yarn install
|
||||||
|
@ -54,7 +52,7 @@ yarn build
|
||||||
Alternatively, you can run
|
Alternatively, you can run
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn build:watch
|
yarn watch
|
||||||
```
|
```
|
||||||
|
|
||||||
to watch for changes and automatically build as necessary.
|
to watch for changes and automatically build as necessary.
|
||||||
|
@ -77,7 +75,7 @@ On platforms other than Linux you need to adjust the path accordingly.
|
||||||
Then run
|
Then run
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn link-project
|
yarn link-package
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the tests
|
### Running the tests
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
const config = require("conventional-changelog-conventionalcommits");
|
|
||||||
|
|
||||||
module.exports = config();
|
|
344
gulpfile.js
344
gulpfile.js
|
@ -1,344 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
const { rollup } = require("rollup");
|
|
||||||
const argv = require("yargs").argv;
|
|
||||||
const fs = require("fs-extra");
|
|
||||||
const gulp = require("gulp");
|
|
||||||
const path = require("path");
|
|
||||||
const rollupConfig = require("./rollup.config");
|
|
||||||
const semver = require("semver");
|
|
||||||
const sass = require("gulp-sass")(require("sass"));
|
|
||||||
const Datastore = require("@seald-io/nedb");
|
|
||||||
const { Transform } = require("stream");
|
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* CONFIGURATION */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
const name = path.basename(path.resolve("."));
|
|
||||||
const sourceDirectory = "./src";
|
|
||||||
const distDirectory = "./dist";
|
|
||||||
const stylesDirectory = path.join(sourceDirectory, "scss");
|
|
||||||
const packsDirectory = path.join(sourceDirectory, "packs");
|
|
||||||
const stylesExtension = ".scss";
|
|
||||||
const sourceFileExtension = ".ts";
|
|
||||||
const staticFiles = ["assets", "fonts", "lang", "templates", "system.json", "template.json"];
|
|
||||||
const getDownloadURL = (version) => `https://git.f3l.de/dungeonslayers/ds4/-/releases/${version}/downloads/ds4.zip`;
|
|
||||||
const getChangelogURL = (version) => `https://git.f3l.de/dungeonslayers/ds4/-/releases/${version}`;
|
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* BUILD */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build the distributable JavaScript code
|
|
||||||
*/
|
|
||||||
async function buildCode() {
|
|
||||||
const build = await rollup({ input: rollupConfig.input, plugins: rollupConfig.plugins });
|
|
||||||
return build.write(rollupConfig.output);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build style sheets
|
|
||||||
*/
|
|
||||||
function buildStyles() {
|
|
||||||
return gulp
|
|
||||||
.src(path.join(stylesDirectory, `${name}${stylesExtension}`))
|
|
||||||
.pipe(sass().on("error", sass.logError))
|
|
||||||
.pipe(gulp.dest(path.join(distDirectory, "css")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a stream of JSON files to NeDB files
|
|
||||||
*/
|
|
||||||
const jsonToNeDB = () =>
|
|
||||||
new Transform({
|
|
||||||
transform(file, _, callback) {
|
|
||||||
try {
|
|
||||||
file.contents = Buffer.from(
|
|
||||||
JSON.parse(file.contents.toString())
|
|
||||||
.map((entry) => cleanPackEntry(entry))
|
|
||||||
.map((entry) => JSON.stringify(entry))
|
|
||||||
.join("\n") + "\n",
|
|
||||||
);
|
|
||||||
file.path = path.join(
|
|
||||||
path.dirname(file.path),
|
|
||||||
path.basename(file.path, path.extname(file.path)) + ".db",
|
|
||||||
);
|
|
||||||
callback(undefined, file);
|
|
||||||
} catch (err) {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
objectMode: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* build compendium packs
|
|
||||||
*/
|
|
||||||
function buildPacks() {
|
|
||||||
return gulp
|
|
||||||
.src(path.join(packsDirectory, "*.json"))
|
|
||||||
.pipe(jsonToNeDB())
|
|
||||||
.pipe(gulp.dest(path.join(distDirectory, "packs")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a stream of NeDB files to JSON files
|
|
||||||
*/
|
|
||||||
const neDBToJSON = () =>
|
|
||||||
new Transform({
|
|
||||||
transform(file, _, callback) {
|
|
||||||
try {
|
|
||||||
const db = new Datastore({ filename: file.path, autoload: true });
|
|
||||||
db.find({}, (err, docs) => {
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
} else {
|
|
||||||
file.contents = Buffer.from(
|
|
||||||
JSON.stringify(
|
|
||||||
docs.map((entry) => cleanPackEntry(entry)),
|
|
||||||
undefined,
|
|
||||||
4,
|
|
||||||
) + "\n",
|
|
||||||
);
|
|
||||||
file.path = path.join(
|
|
||||||
path.dirname(file.path),
|
|
||||||
path.basename(file.path, path.extname(file.path)) + ".json",
|
|
||||||
);
|
|
||||||
callback(undefined, file);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
objectMode: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate JSON files from the compendium packs in the distribution directory
|
|
||||||
*/
|
|
||||||
function generateJSONsFromPacks() {
|
|
||||||
return gulp
|
|
||||||
.src(path.join(distDirectory, "packs", "*.db"))
|
|
||||||
.pipe(neDBToJSON())
|
|
||||||
.pipe(gulp.dest(path.join(packsDirectory)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy static files
|
|
||||||
*/
|
|
||||||
async function copyFiles() {
|
|
||||||
for (const file of staticFiles) {
|
|
||||||
if (fs.existsSync(path.join(sourceDirectory, file))) {
|
|
||||||
await fs.copy(path.join(sourceDirectory, file), path.join(distDirectory, file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Watch for changes for each build step
|
|
||||||
*/
|
|
||||||
function buildWatch() {
|
|
||||||
gulp.watch(
|
|
||||||
path.join(sourceDirectory, "**", `*${sourceFileExtension}`).replace(/\\/g, "/"),
|
|
||||||
{ ignoreInitial: false },
|
|
||||||
buildCode,
|
|
||||||
);
|
|
||||||
gulp.watch(
|
|
||||||
path.join(stylesDirectory, "**", `*${stylesExtension}`).replace(/\\/g, "/"),
|
|
||||||
{ ignoreInitial: false },
|
|
||||||
buildStyles,
|
|
||||||
);
|
|
||||||
gulp.watch(path.join(packsDirectory, "**", "*.json").replace(/\\/g, "/"), { ignoreInitial: false }, buildPacks);
|
|
||||||
gulp.watch(
|
|
||||||
staticFiles.map((file) => path.join(sourceDirectory, file).replace(/\\/g, "/")),
|
|
||||||
{ ignoreInitial: false },
|
|
||||||
copyFiles,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* CLEAN */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove built files from `dist` folder while ignoring source files
|
|
||||||
*/
|
|
||||||
async function clean() {
|
|
||||||
const files = [...staticFiles, "packs", "module"];
|
|
||||||
|
|
||||||
if (fs.existsSync(path.join(stylesDirectory, `${name}${stylesExtension}`))) {
|
|
||||||
files.push("css");
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(" ", "Files to clean:");
|
|
||||||
console.log(" ", files.join("\n "));
|
|
||||||
|
|
||||||
for (const filePath of files) {
|
|
||||||
await fs.remove(path.join(distDirectory, filePath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* LINK */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data path of Foundry VTT based on what is configured in `foundryconfig.json`
|
|
||||||
*/
|
|
||||||
function getDataPath() {
|
|
||||||
const config = fs.readJSONSync("foundryconfig.json");
|
|
||||||
|
|
||||||
if (config?.dataPath) {
|
|
||||||
if (!fs.existsSync(path.resolve(config.dataPath))) {
|
|
||||||
throw new Error("User Data path invalid, no Data directory found");
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.resolve(config.dataPath);
|
|
||||||
} else {
|
|
||||||
throw new Error("No User Data path defined in foundryconfig.json");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Link build to User Data folder
|
|
||||||
*/
|
|
||||||
async function linkUserData() {
|
|
||||||
let destinationDirectory;
|
|
||||||
if (fs.existsSync(path.resolve(".", sourceDirectory, "system.json"))) {
|
|
||||||
destinationDirectory = "systems";
|
|
||||||
} else {
|
|
||||||
throw new Error("Could not find system.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
const linkDirectory = path.resolve(getDataPath(), destinationDirectory, name);
|
|
||||||
|
|
||||||
if (argv.clean || argv.c) {
|
|
||||||
console.log(`Removing build in ${linkDirectory}.`);
|
|
||||||
|
|
||||||
await fs.remove(linkDirectory);
|
|
||||||
} else if (!fs.existsSync(linkDirectory)) {
|
|
||||||
console.log(`Copying build to ${linkDirectory}.`);
|
|
||||||
await fs.ensureDir(path.resolve(linkDirectory, ".."));
|
|
||||||
await fs.symlink(path.resolve(".", distDirectory), linkDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************/
|
|
||||||
/* VERSIONING */
|
|
||||||
/********************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the contents of the manifest file as object.
|
|
||||||
*/
|
|
||||||
function getManifest() {
|
|
||||||
const manifestPath = path.join(sourceDirectory, "system.json");
|
|
||||||
|
|
||||||
if (fs.existsSync(manifestPath)) {
|
|
||||||
return {
|
|
||||||
file: fs.readJSONSync(manifestPath),
|
|
||||||
name: "system.json",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the target version based on on the current version and the argument passed as release.
|
|
||||||
*/
|
|
||||||
function getTargetVersion(currentVersion, release) {
|
|
||||||
if (["major", "premajor", "minor", "preminor", "patch", "prepatch", "prerelease"].includes(release)) {
|
|
||||||
return semver.inc(currentVersion, release);
|
|
||||||
} else {
|
|
||||||
return semver.valid(release);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update version and download URL.
|
|
||||||
*/
|
|
||||||
function bumpVersion(cb) {
|
|
||||||
const packageJson = fs.readJSONSync("package.json");
|
|
||||||
const manifest = getManifest();
|
|
||||||
|
|
||||||
if (!manifest) cb(Error("Manifest JSON not found"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
const release = argv.release || argv.r;
|
|
||||||
|
|
||||||
const currentVersion = packageJson.version;
|
|
||||||
|
|
||||||
if (!release) {
|
|
||||||
return cb(Error("Missing release type"));
|
|
||||||
}
|
|
||||||
|
|
||||||
const targetVersion = getTargetVersion(currentVersion, release);
|
|
||||||
|
|
||||||
if (!targetVersion) {
|
|
||||||
return cb(new Error("Error: Incorrect version arguments"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetVersion === currentVersion) {
|
|
||||||
return cb(new Error("Error: Target version is identical to current version"));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Updating version number to '${targetVersion}'`);
|
|
||||||
|
|
||||||
packageJson.version = targetVersion;
|
|
||||||
fs.writeJSONSync("package.json", packageJson, { spaces: 4 });
|
|
||||||
|
|
||||||
manifest.file.version = targetVersion;
|
|
||||||
manifest.file.download = getDownloadURL(targetVersion);
|
|
||||||
manifest.file.changelog = getChangelogURL(targetVersion);
|
|
||||||
fs.writeJSONSync(path.join(sourceDirectory, manifest.name), manifest.file, { spaces: 4 });
|
|
||||||
|
|
||||||
return cb();
|
|
||||||
} catch (err) {
|
|
||||||
cb(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const execBuild = gulp.parallel(buildCode, buildStyles, buildPacks, copyFiles);
|
|
||||||
|
|
||||||
exports.build = gulp.series(clean, execBuild);
|
|
||||||
exports.watch = buildWatch;
|
|
||||||
exports.clean = clean;
|
|
||||||
exports.link = linkUserData;
|
|
||||||
exports.bumpVersion = bumpVersion;
|
|
||||||
exports.generateJSONsFromPacks = generateJSONsFromPacks;
|
|
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
module.exports = {
|
export default {
|
||||||
preset: "ts-jest",
|
preset: "ts-jest",
|
||||||
globals: {
|
globals: {
|
||||||
"ts-jest": {
|
"ts-jest": {
|
||||||
|
|
32
package.json
32
package.json
|
@ -36,26 +36,31 @@
|
||||||
"name": "Sascha Martens"
|
"name": "Sascha Martens"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "gulp build",
|
"build": "run-s clean:files build:files",
|
||||||
"build:watch": "gulp watch",
|
"build:files": "rollup -c",
|
||||||
"link-project": "gulp link",
|
"watch": "rollup -c -w",
|
||||||
"clean": "gulp clean",
|
"link-package": "node ./tools/link-package.js",
|
||||||
"clean:link": "gulp link --clean",
|
"clean": "run-p clean:files clean:link",
|
||||||
"bump-version": "gulp bumpVersion",
|
"clean:files": "rimraf dist",
|
||||||
"lint": "eslint --ext .ts,.js .",
|
"clean:link": "node ./tools/link-package.js --clean",
|
||||||
"lint:fix": "eslint --ext .ts,.js --fix .",
|
"lint": "eslint --ext .ts,.js,.cjs,.mjs .",
|
||||||
|
"lint:fix": "eslint --ext .ts,.js,.cjs,.mjs --fix .",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test:ci": "jest --ci --reporters=default --reporters=jest-junit",
|
"test:ci": "jest --ci --reporters=default --reporters=jest-junit",
|
||||||
"format": "prettier --write \"./**/*.(ts|js|json|scss|yml)\"",
|
"format": "prettier --write \"./**/*.(ts|js|cjs|mjs|json|scss|yml)\"",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
|
"bump-version": "node ./tools/bump-version.js",
|
||||||
|
"convert-packs-to-json": "node ./tools/convert-packs-to-json.js",
|
||||||
"postinstall": "husky install",
|
"postinstall": "husky install",
|
||||||
"changelog": "conventional-changelog -n changelog.config.js -o CHANGELOG.md -r 2"
|
"changelog": "conventional-changelog -p conventionalcommits -o CHANGELOG.md -r 2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "15.0.0",
|
"@commitlint/cli": "15.0.0",
|
||||||
"@commitlint/config-conventional": "15.0.0",
|
"@commitlint/config-conventional": "15.0.0",
|
||||||
|
"@guanghechen/rollup-plugin-copy": "1.8.4",
|
||||||
"@league-of-foundry-developers/foundry-vtt-types": "0.8.9-7",
|
"@league-of-foundry-developers/foundry-vtt-types": "0.8.9-7",
|
||||||
"@seald-io/nedb": "2.2.0",
|
"@seald-io/nedb": "2.2.0",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
|
@ -69,15 +74,16 @@
|
||||||
"eslint-plugin-jest": "25.3.0",
|
"eslint-plugin-jest": "25.3.0",
|
||||||
"eslint-plugin-prettier": "4.0.0",
|
"eslint-plugin-prettier": "4.0.0",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"gulp": "4.0.2",
|
|
||||||
"gulp-sass": "5.0.0",
|
|
||||||
"husky": "7.0.4",
|
"husky": "7.0.4",
|
||||||
"jest": "27.4.2",
|
"jest": "27.4.2",
|
||||||
"jest-junit": "13.0.0",
|
"jest-junit": "13.0.0",
|
||||||
"lint-staged": "12.1.2",
|
"lint-staged": "12.1.2",
|
||||||
|
"npm-run-all": "4.1.5",
|
||||||
"prettier": "2.5.0",
|
"prettier": "2.5.0",
|
||||||
|
"rimraf": "3.0.2",
|
||||||
"rollup": "2.60.2",
|
"rollup": "2.60.2",
|
||||||
"rollup-plugin-sourcemaps": "0.6.3",
|
"rollup-plugin-sourcemaps": "0.6.3",
|
||||||
|
"rollup-plugin-styles": "3.14.1",
|
||||||
"rollup-plugin-terser": "7.0.2",
|
"rollup-plugin-terser": "7.0.2",
|
||||||
"rollup-plugin-typescript2": "0.31.1",
|
"rollup-plugin-typescript2": "0.31.1",
|
||||||
"sass": "1.44.0",
|
"sass": "1.44.0",
|
||||||
|
@ -88,7 +94,7 @@
|
||||||
"yargs": "17.2.1"
|
"yargs": "17.2.1"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.ts": "eslint --cache --fix",
|
"*.(ts|js|cjs|mjs)": "eslint --cache --fix",
|
||||||
"*.(json|scss|yml)": "prettier --write"
|
"*.(json|scss|yml)": "prettier --write"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,50 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
const typescript = require("rollup-plugin-typescript2");
|
import copy from "@guanghechen/rollup-plugin-copy";
|
||||||
const sourcemaps = require("rollup-plugin-sourcemaps");
|
import typescript from "rollup-plugin-typescript2";
|
||||||
const { terser } = require("rollup-plugin-terser");
|
import sourcemaps from "rollup-plugin-sourcemaps";
|
||||||
|
import styles from "rollup-plugin-styles";
|
||||||
|
import { terser } from "rollup-plugin-terser";
|
||||||
|
import { distDirectory, name, sourceDirectory } from "./tools/const.js";
|
||||||
|
import { convertJSONToPack } from "./tools/json-pack-tools.js";
|
||||||
|
|
||||||
|
const staticFiles = ["template.json", "system.json", "assets", "fonts", "lang", "templates"];
|
||||||
|
const isProduction = process.env.NODE_ENV === "production";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import('rollup').RollupOptions}
|
* @type {import('rollup').RollupOptions}
|
||||||
*/
|
*/
|
||||||
const config = {
|
const config = {
|
||||||
input: "src/module/ds4.ts",
|
input: { [`module/${name}`]: `${sourceDirectory}/module/${name}.ts` },
|
||||||
output: {
|
output: {
|
||||||
dir: "dist/module",
|
dir: distDirectory,
|
||||||
format: "es",
|
format: "es",
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
assetFileNames: "[name].[ext]",
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
sourcemaps(),
|
sourcemaps(),
|
||||||
typescript({}),
|
typescript(),
|
||||||
process.env.NODE_ENV === "production" && terser({ ecma: 2020, keep_fnames: true }),
|
styles({
|
||||||
|
mode: ["extract", `css/${name}.css`],
|
||||||
|
url: false,
|
||||||
|
sourceMap: true,
|
||||||
|
minimize: isProduction,
|
||||||
|
}),
|
||||||
|
copy({
|
||||||
|
targets: [
|
||||||
|
{ src: staticFiles.map((file) => `${sourceDirectory}/${file}`), dest: distDirectory },
|
||||||
|
{
|
||||||
|
src: [`${sourceDirectory}/packs/*.json`],
|
||||||
|
dest: `${distDirectory}/packs`,
|
||||||
|
rename: (name) => `${name}.db`,
|
||||||
|
transform: convertJSONToPack,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
isProduction && terser({ ecma: 2020, keep_fnames: true }),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
export default config;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import "../scss/ds4.scss";
|
||||||
import registerForHooks from "./hooks/hooks";
|
import registerForHooks from "./hooks/hooks";
|
||||||
|
|
||||||
registerForHooks();
|
registerForHooks();
|
||||||
|
|
84
tools/bump-version.js
Normal file
84
tools/bump-version.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import fs from "fs-extra";
|
||||||
|
import path from "node:path";
|
||||||
|
import semver from "semver";
|
||||||
|
import yargs from "yargs";
|
||||||
|
import { hideBin } from "yargs/helpers";
|
||||||
|
|
||||||
|
import { sourceDirectory } from "./const.js";
|
||||||
|
|
||||||
|
const getDownloadURL = (version) => `https://git.f3l.de/dungeonslayers/ds4/-/releases/${version}/downloads/ds4.zip`;
|
||||||
|
const getChangelogURL = (version) => `https://git.f3l.de/dungeonslayers/ds4/-/releases/${version}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the contents of the manifest file as object.
|
||||||
|
* @returns {{file: unknown, name: string}} An object describing the manifest
|
||||||
|
*/
|
||||||
|
function getManifest() {
|
||||||
|
const manifestPath = path.join(sourceDirectory, "system.json");
|
||||||
|
|
||||||
|
if (fs.existsSync(manifestPath)) {
|
||||||
|
return {
|
||||||
|
file: fs.readJSONSync(manifestPath),
|
||||||
|
name: "system.json",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the target version based on on the current version and the argument passed as release.
|
||||||
|
* @param {string} currentVersion The current version
|
||||||
|
* @param {semver.ReleaseType | string} release Either a semver release type or a valid semver version
|
||||||
|
* @returns {string | null} The target version
|
||||||
|
*/
|
||||||
|
function getTargetVersion(currentVersion, release) {
|
||||||
|
if (["major", "premajor", "minor", "preminor", "patch", "prepatch", "prerelease"].includes(release)) {
|
||||||
|
return semver.inc(currentVersion, release);
|
||||||
|
} else {
|
||||||
|
return semver.valid(release);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update version and download URL.
|
||||||
|
* @param {semver.ReleaseType | string} release Either a semver release type or a valid semver version
|
||||||
|
*/
|
||||||
|
function bumpVersion(release) {
|
||||||
|
if (!release) {
|
||||||
|
throw new Error("Missing release type");
|
||||||
|
}
|
||||||
|
|
||||||
|
const packageJson = fs.readJSONSync("package.json");
|
||||||
|
const manifest = getManifest();
|
||||||
|
if (!manifest) throw new Error("Manifest JSON not found");
|
||||||
|
|
||||||
|
const currentVersion = packageJson.version;
|
||||||
|
const targetVersion = getTargetVersion(currentVersion, release);
|
||||||
|
|
||||||
|
if (!targetVersion) {
|
||||||
|
throw new Error("Incorrect version arguments");
|
||||||
|
}
|
||||||
|
if (targetVersion === currentVersion) {
|
||||||
|
throw new Error("Target version is identical to current version");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Bumping version number to '${targetVersion}'`);
|
||||||
|
packageJson.version = targetVersion;
|
||||||
|
fs.writeJSONSync("package.json", packageJson, { spaces: 4 });
|
||||||
|
manifest.file.version = targetVersion;
|
||||||
|
manifest.file.download = getDownloadURL(targetVersion);
|
||||||
|
manifest.file.changelog = getChangelogURL(targetVersion);
|
||||||
|
fs.writeJSONSync(path.join(sourceDirectory, manifest.name), manifest.file, { spaces: 4 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const argv = yargs(hideBin(process.argv)).usage("Usage: $0").option("release", {
|
||||||
|
alias: "r",
|
||||||
|
type: "string",
|
||||||
|
demandOption: true,
|
||||||
|
description: "Either a semver release type or a valid semver version",
|
||||||
|
}).argv;
|
||||||
|
const release = argv.r;
|
||||||
|
bumpVersion(release);
|
9
tools/const.js
Normal file
9
tools/const.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
export const name = "ds4";
|
||||||
|
export const sourceDirectory = "./src";
|
||||||
|
export const distDirectory = "./dist";
|
||||||
|
export const destinationDirectory = "systems";
|
||||||
|
export const foundryconfigFile = "./foundryconfig.json";
|
20
tools/convert-packs-to-json.js
Normal file
20
tools/convert-packs-to-json.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import promises from "node:fs/promises";
|
||||||
|
import path from "node:path";
|
||||||
|
|
||||||
|
import { distDirectory, sourceDirectory } from "./const.js";
|
||||||
|
import { convertPackFileToJSONFile } from "./json-pack-tools.js";
|
||||||
|
|
||||||
|
const packsDistDirectory = path.join(distDirectory, "packs");
|
||||||
|
const packsSourceDirectory = path.join(sourceDirectory, "packs");
|
||||||
|
|
||||||
|
console.log(`Converting pack files in ${packsDistDirectory} to json files in ${packsSourceDirectory}:`);
|
||||||
|
|
||||||
|
const conversionPromises = (await promises.readdir(packsDistDirectory, { withFileTypes: true }))
|
||||||
|
.filter((dirent) => dirent.isFile() && path.extname(dirent.name))
|
||||||
|
.map(async (dirent) => convertPackFileToJSONFile(path.join(packsDistDirectory, dirent.name), packsSourceDirectory));
|
||||||
|
|
||||||
|
await Promise.all(conversionPromises);
|
95
tools/json-pack-tools.js
Normal file
95
tools/json-pack-tools.js
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// 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 a JSON string containing an array to a Pack (NeDB) string.
|
||||||
|
* @param {string} jsonString The input JSON string
|
||||||
|
* @returns {string} The resulting Pack string
|
||||||
|
*/
|
||||||
|
export function convertJSONToPack(jsonString) {
|
||||||
|
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);
|
||||||
|
}
|
55
tools/link-package.js
Normal file
55
tools/link-package.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// SPDX-FileCopyrightText: 2021 Johannes Loher
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import fs from "fs-extra";
|
||||||
|
import path from "node:path";
|
||||||
|
import yargs from "yargs";
|
||||||
|
import { hideBin } from "yargs/helpers";
|
||||||
|
|
||||||
|
import { destinationDirectory, distDirectory, foundryconfigFile, name, sourceDirectory } from "./const.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data path of Foundry VTT based on what is configured in the {@link foundryconfigFile}.
|
||||||
|
*/
|
||||||
|
function getDataPath() {
|
||||||
|
const config = fs.readJSONSync(foundryconfigFile);
|
||||||
|
|
||||||
|
if (config?.dataPath) {
|
||||||
|
if (!fs.existsSync(path.resolve(config.dataPath))) {
|
||||||
|
throw new Error("User data path invalid, no Data directory found");
|
||||||
|
}
|
||||||
|
return path.resolve(config.dataPath);
|
||||||
|
} else {
|
||||||
|
throw new Error(`No user data path defined in ${foundryconfigFile}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Link the built package to the user data folder.
|
||||||
|
* @param {boolean} clean Whether to remove the link instead of creating it
|
||||||
|
*/
|
||||||
|
async function linkPackage(clean) {
|
||||||
|
if (!fs.existsSync(path.resolve(sourceDirectory, "system.json"))) {
|
||||||
|
throw new Error("Could not find system.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
const linkDirectory = path.resolve(getDataPath(), destinationDirectory, name);
|
||||||
|
|
||||||
|
if (clean) {
|
||||||
|
console.log(`Removing link to built package at ${linkDirectory}.`);
|
||||||
|
await fs.remove(linkDirectory);
|
||||||
|
} else if (!fs.existsSync(linkDirectory)) {
|
||||||
|
console.log(`Linking built package to ${linkDirectory}.`);
|
||||||
|
await fs.ensureDir(path.resolve(linkDirectory, ".."));
|
||||||
|
await fs.symlink(path.resolve(".", distDirectory), linkDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const argv = yargs(hideBin(process.argv)).usage("Usage: $0").option("clean", {
|
||||||
|
alias: "c",
|
||||||
|
type: "boolean",
|
||||||
|
default: false,
|
||||||
|
description: "Remove the link instead of creating it",
|
||||||
|
}).argv;
|
||||||
|
const clean = argv.c;
|
||||||
|
await linkPackage(clean);
|
Loading…
Reference in a new issue