59 lines
2.0 KiB
TypeScript
59 lines
2.0 KiB
TypeScript
// deno task new-mod <id> ["Display Name"]
|
|
// copies templates/mod into mods/<id>, with the template's placeholder id and name replaced
|
|
import { NAMESPACE_PATTERN, RESERVED_NAMESPACES } from "$/common/mod_data.ts";
|
|
|
|
const TEMPLATE = "templates/mod";
|
|
const PLACEHOLDER_ID = "example_mod";
|
|
const PLACEHOLDER_NAME = "Example Mod";
|
|
const TEXT_FILES = /\.(json|md|ts|js)$/;
|
|
|
|
export function create_mod(id: string, name: string, mods_dir = "mods") {
|
|
if (!NAMESPACE_PATTERN.test(id)) {
|
|
throw new Error(`"${id}" isn't a valid mod id: use 1-32 characters of a-z, 0-9 and _`);
|
|
}
|
|
if (RESERVED_NAMESPACES.includes(id)) {
|
|
throw new Error(`"${id}" is reserved`);
|
|
}
|
|
const target = `${mods_dir}/${id}`;
|
|
try {
|
|
Deno.statSync(target);
|
|
throw new Error(`${target} already exists`);
|
|
} catch (e) {
|
|
if (!(e instanceof Deno.errors.NotFound)) throw e;
|
|
}
|
|
copy_dir(TEMPLATE, target, (text) => text.replaceAll(PLACEHOLDER_ID, id).replaceAll(PLACEHOLDER_NAME, name));
|
|
return target;
|
|
}
|
|
|
|
function copy_dir(from: string, to: string, transform: (text: string) => string) {
|
|
Deno.mkdirSync(to, { recursive: true });
|
|
for (const entry of Deno.readDirSync(from)) {
|
|
const source = `${from}/${entry.name}`;
|
|
const destination = `${to}/${entry.name}`;
|
|
if (entry.isDirectory) {
|
|
copy_dir(source, destination, transform);
|
|
} else if (TEXT_FILES.test(entry.name)) {
|
|
Deno.writeTextFileSync(destination, transform(Deno.readTextFileSync(source)));
|
|
} else {
|
|
Deno.copyFileSync(source, destination);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
const [id, name] = Deno.args;
|
|
if (!id) {
|
|
console.error('Usage: deno task new-mod <id> ["Display Name"]');
|
|
Deno.exit(1);
|
|
}
|
|
const display_name = name ?? id.split("_").map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
|
|
try {
|
|
const path = create_mod(id, display_name);
|
|
console.log(`Created ${path}. Edit its manifest.json, then run deno task check-mods.`);
|
|
console.log("Note: the game can't load mods yet, see the implementation plan in MODS.md.");
|
|
} catch (e) {
|
|
console.error((e as Error).message);
|
|
Deno.exit(1);
|
|
}
|
|
}
|