UNPKG

@datapackjs/core

Version:

Easy to use library for building high-quality Minecraft datapacks in JavaScript or TypeScript.

100 lines 3.66 kB
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