@datapackjs/core
Version:
Easy to use library for building high-quality Minecraft datapacks in JavaScript or TypeScript.
100 lines • 3.66 kB
JavaScript
import { DatapackJSError } from "./error";
import { MCFunction } from "./mc-function";
import { isSafeDirectoryName } from "./utility";
import { createWriteStream } from "fs";
import ZipStream from "zip-stream";
export class Datapack {
constructor(packFormat, name, description) {
this.packFormat = packFormat;
this.description = description;
this.functions = new Set();
this.transformers = new Set();
this.archive = new ZipStream();
this.loadCommands = [];
this.tickCommands = [];
if (!isSafeDirectoryName(name)) {
throw new DatapackJSError('Datapack name may only contain directory-safe characters.');
}
this.name = name;
}
addFileEntry(path, contents) {
return new Promise((resolve, reject) => {
this.archive.entry(contents, { name: path }, (err) => {
if (err)
return reject(err);
resolve();
});
});
}
async bootstrapFiles() {
await this.addFileEntry('pack.mcmeta', JSON.stringify({
pack: {
pack_format: this.packFormat,
description: this.description
}
}));
await this.addFileEntry('data/minecraft/tags/function/tick.json', JSON.stringify({
values: [
`${this.name}:tick`
]
}));
await this.addFileEntry('data/minecraft/tags/function/load.json', JSON.stringify({
values: [
`${this.name}:load`
]
}));
}
internal_registerFunction(name, commands) {
const functionFactory = MCFunction.define(name, commands);
this.functions.add(functionFactory(this));
}
addTransformationStep(transformer) {
this.transformers.add(transformer);
}
resolveCommand(resolvable) {
if (typeof resolvable === 'function') {
return resolvable(this).commandRef;
}
if (typeof resolvable === 'string') {
return resolvable;
}
throw new DatapackJSError(`Failed to resolve command resolvable.`);
}
insertLoadCommands(...commands) {
this.loadCommands.push(...commands);
}
insertTickCommands(...commands) {
this.tickCommands.push(...commands);
}
registerFunction(functionFactory) {
const mcfunction = functionFactory(this);
if (['load', 'tick'].includes(mcfunction.name)) {
throw new DatapackJSError(`You may not create a function named "${mcfunction.name}", this name is protected.`);
}
this.functions.add(mcfunction);
}
async build({ output: outputPath }) {
const output = createWriteStream(outputPath);
await this.bootstrapFiles();
this.internal_registerFunction('load', this.loadCommands);
this.internal_registerFunction('tick', this.tickCommands);
try {
for (const { name: funcName, commands } of this.functions) {
let contents = commands
.map(this.resolveCommand)
.join('\n');
for (const transformer of this.transformers) {
contents = transformer(contents);
}
await this.addFileEntry(`data/${this.name}/function/${funcName}.mcfunction`, contents);
}
this.archive.finish();
}
catch (err) {
throw new DatapackJSError(`Error building the ZIP: ${err.message}`);
}
this.archive.pipe(output);
return output;
}
}
//# sourceMappingURL=datapack.js.map