memepack-builder
Version:
Build memified Minecraft resource pack
18 lines (17 loc) • 11.3 kB
JavaScript
import{resolve as $}from"node:path";import{readJSON as w}from"fs-extra/esm";import{resolve as C,normalize as N}from"node:path";async function x(i){let e={addition:new Map,deletion:new Map};for(let t of i)await D(t,e);return e}async function D(i,e){for(let t of i.manifest.languageModification??[]){let n=N(t.file);if(t.add){let o=await w(C(i.path,t.add));await T(e.addition,n,o)}if(t.remove){let o=await w(C(i.path,t.remove));await I(e.deletion,n,o)}}}async function T(i,e,t){let n=i.get(e);if(!n)i.set(e,new Map(Object.entries(t)));else for(let[o,r]of Object.entries(t))n.set(o,r)}async function I(i,e,t){let n=i.get(e);if(!n)i.set(e,new Set(t));else for(let o of t)n.add(o)}async function E(i){let e=new Map,t=await x(i);i.forEach(n=>{n.files.forEach(o=>{e.set(o,{filePath:$(n.path,o)})})});for(let[n,o]of e)if(M(o))t.addition.has(n)&&(o.patch||(o.patch={}),z(o.patch,t.addition.get(n))),t.deletion.has(n)&&(o.patch||(o.patch={}),G(o.patch,t.deletion.get(n)));else if(t.addition.has(n)||t.deletion.has(n))throw new Error("Cannot patch non-json file");return e}function p(i){return Object.hasOwn(i,"content")}function f(i){return Object.hasOwn(i,"filePath")}function F(i){return f(i)&&(i.filePath.endsWith(".json")||i.filePath.endsWith(".mcmeta"))}function y(i){return f(i)&&i.filePath.endsWith(".lang")}function M(i){return p(i)||F(i)||y(i)}function h(i){return p(i)||F(i)}function z(i,e){if(i.flatKey||(i.flatKey={}),!i.flatKey.addition)i.flatKey.addition=new Map(e);else for(let[t,n]of e)i.flatKey.addition.set(t,n)}function G(i,e){if(i.flatKey||(i.flatKey={}),!i.flatKey.deletion)i.flatKey.deletion=new Set(e);else for(let t of e)i.flatKey.deletion.add(t)}import{resolve as H}from"node:path";import{pathExists as U,readJSON as R}from"fs-extra/esm";import{readFile as Q}from"node:fs/promises";import{ZipFile as X}from"yazl";import{createHash as Y}from"node:crypto";import{readFile as V}from"node:fs/promises";async function _(i){return(await V(i,"utf-8")).replace(/\r\n/g,`
`).split(`
`).map(n=>n.replace(/#.*$/g,"").trim()).filter(n=>n!=="")}function k(i,{resource:e,collection:t}){let n=i.filter(a=>q(a)),o=i.filter(a=>W(a)),r=new Set;for(let a of n)e.includes(a.manifest.name)&&r.add(a);let s=new Set;for(let a of o)t.includes(a.manifest.name)&&s.add(a);for(let{manifest:a}of s)for(let c of n)a.contains?.includes(c.manifest.name)&&r.add(c);return Array.from(r)}function q(i){return i.manifest.type==="resource"}function W(i){return i.manifest.type==="collection"}var d=class{parsedModules;#e=[];priorityFilePath;entries=new Map;constructor(e,t){this.parsedModules=e,this.priorityFilePath=t}get selectedModules(){return this.#e}async sortModules(){let e=await _(this.priorityFilePath),t=[];e.forEach(o=>{let r=this.#e.find(s=>s.manifest.name===o);r&&t.push(r)});let n=this.#e.filter(o=>!e.includes(o.manifest.name));this.#e=[...t,...n]}async getPackEntries(){let e=await E(this.#e);return this.entries=e,e}static getPackHash(e){return Y("sha256").update(e).digest("hex")}decideSelectedModules(e){let t=k(this.parsedModules,e.modules);return this.#e=t,t}};import{readJSON as Z}from"fs-extra/esm";var l=class i{static applyJsonContentPatch(e,t){return t.flatKey&&(e=i.applyJsonFlatKeyPatch(e,t.flatKey)),t.nestedKey&&(e=i.applyJsonNestedKeyPatch(e,t.nestedKey)),e}static async applyJsonFilePatch(e,t){return i.applyJsonContentPatch(await Z(e),t)}static applyJsonFlatKeyPatch(e,t){if(t.addition)for(let[n,o]of t.addition)e[n]=o;if(t.deletion)for(let n of t.deletion)delete e[n];return e}static applyJsonNestedKeyPatch(e,t){if(t.addition)for(let[n,o]of t.addition){let r=n.split(".").filter(c=>c!=="__proto__"),s=r.pop()??"",a=e;for(let c of r)a[c]??={},a=a[c];a[s]=o}if(t.deletion)for(let n of t.deletion){let o=n.split(".").filter(c=>c!=="__proto__"),r=o.pop()??"",s=e,a=!0;for(let c of o)if(s[c])s=s[c];else{a=!1;break}a&&delete s[r]}return e}};var u=class{static parseJavaLang(e){let t=e.replace(/\r\n/g,`
`).split(`
`).map(n=>n.replace(/#.*$/g,"").trimStart()).filter(n=>n!==""&&n.includes("=")).map(n=>n.split("=",2));return Object.fromEntries(t)}static dumpJavaLang(e){return Object.entries(e).map(([t,n])=>`${t}=${n}`).join(`
`)}static parseBedrockLang(e){let t=e.replace(/\r\n/g,`
`).split(`
`).map(n=>n.replace(/(?:##|\t#).*$/g,"").trimStart()).filter(n=>n!==""&&n.includes("=")).map(n=>n.split("=",2));return Object.fromEntries(t)}static dumpBedrockLang(e){return Object.entries(e).map(([t,n])=>`${t}=${n} #`).join(`
`)}};async function ee(i,e){let t={texture_data:{}};return e.forEach(async n=>{let o=H(n.path,"textures",i);await U(o)&&Object.assign(t.texture_data,(await R(o,{encoding:"utf8"})).texture_data)}),t}var O=class extends d{async build(e){this.decideSelectedModules(e),await this.getPackEntries();let t=new X;this.#n(),e.compatible&&this.#o();for(let[n,o]of this.entries){if(y(o)){let r=await this.#e(o),s=u.dumpBedrockLang(r);t.addBuffer(Buffer.from(s),n,{mtime:new Date(0)});continue}if(h(o)){let r=await this.#t(o),s=JSON.stringify(r,null,2);t.addBuffer(Buffer.from(s),n,{mtime:new Date(0)});continue}if(f(o)&&!y(o)){t.addFile(o.filePath,n);continue}}return t.end(),new Promise(n=>{let o=[];t.outputStream.on("data",r=>o.push(Buffer.from(r))).on("end",()=>n(Buffer.concat(o)))})}async#e(e){if(p(e))return e.patch?l.applyJsonContentPatch(structuredClone(e.content),e.patch):e.content;{let t=u.parseBedrockLang(await Q(e.filePath,{encoding:"utf-8"}));return e.patch?l.applyJsonContentPatch(t,e.patch):t}}async#t(e){return p(e)?e.patch?l.applyJsonContentPatch(structuredClone(e.content),e.patch):e.content:e.patch?await l.applyJsonFilePatch(e.filePath,e.patch):await R(e.filePath)}async#n(){["item_texture.json","terrain_texture.json"].forEach(async e=>{let t=await ee(e,this.selectedModules);this.entries.set(`textures/${e}`,{content:t,patch:{}})})}#o(){this.entries.delete("texts/languages.json"),this.entries.delete("texts/language_names.json");let e=new Map;for(let[t,n]of this.entries)e.set(t.replace("zh_ME","zh_CN"),n);this.entries=e}};import{readJSON as B}from"fs-extra/esm";import{ZipFile as te}from"yazl";function J(i){let e=JSON.stringify(i,void 0,4),t=[];for(let n=0;n<e.length;n++)t.push(e[n]<"\xFF"?e[n]:`\\u${e[n].charCodeAt(0).toString(16).padStart(4,"0")}`);return t.join("")}import{normalize as A}from"node:path";var ne={"assets/minecraft/lang/zh_meme\\.(.+)":"assets/minecraft/lang/zh_cn.lang","assets/minecraft/lang/zh_cn\\.(.+)":"assets/minecraft/lang/zh_cn.lang","assets/minecraft/textures/block/(.+)":"assets/minecraft/textures/blocks/$1","assets/minecraft/textures/item/(.+)":"assets/minecraft/textures/items/$1"},oe={"assets/minecraft/lang/zh_cn.lang":{requireLegacyMapping:!0}},ie={"assets/minecraft/lang/zh_meme\\.(.+)":"assets/minecraft/lang/zh_cn.$1"},j=class extends d{#e;constructor(e,t,n){super(e,t),this.#e=n}#t(e){let t=this.entries.get("pack.mcmeta");if(!t)throw new Error("pack.mcmeta does not exist");if(!h(t))throw new Error("pack.mcmeta is not a json file");return t.patch={},t.patch.nestedKey={},e.compatible&&(t.patch.nestedKey.deletion=new Set("language")),t.patch.nestedKey.addition=new Map([["pack.pack_format",e.format]]),this.entries.set("pack.mcmeta",t),t}async#n(e){let t=await B(this.#e),n=Object.keys(e);for(let[o,r]of Object.entries(t))n.includes(o)&&(e[r]=e[o],delete e[o]);return e}#o(){let e=new Map;for(let[t,n]of this.entries){let o=t.replaceAll("\\","/");for(let[r,s]of Object.entries(ie))o=o.replaceAll(new RegExp(`^${r}$`,"g"),s);o=A(o),e.set(o,n)}this.entries=e}async build(e){this.decideSelectedModules(e),await this.getPackEntries();let t=new te;return e.compatible&&this.#o(),await this.#r(t,e),e.type==="legacy"?await this.#a(t):await this.#s(t),t.end(),new Promise(o=>{let r=[];t.outputStream.on("data",s=>r.push(Buffer.from(s))).on("end",()=>o(Buffer.concat(r)))})}async#i(e){return p(e)?e.patch?l.applyJsonContentPatch(structuredClone(e.content),e.patch):e.content:e.patch?await l.applyJsonFilePatch(e.filePath,e.patch):await B(e.filePath)}async#r(e,t){let n=this.entries.get("pack.mcmeta");if(!n)throw new Error("pack.mcmeta does not exist");if(!h(n))throw new Error("pack.mcmeta is not a json file");this.entries.delete("pack.mcmeta"),n.patch={},n.patch.nestedKey={},t.compatible&&(n.patch.nestedKey.deletion=new Set("language")),n.patch.nestedKey.addition=new Map([["pack.pack_format",t.format]]);let o=await this.#i(n),r=JSON.stringify(o,void 0,4);e.addBuffer(Buffer.from(r),"pack.mcmeta",{mtime:new Date(0)})}async#s(e){for(let[t,n]of this.entries){if(M(n)){let o=await this.#i(n),r=J(o);e.addBuffer(Buffer.from(r),t,{mtime:new Date(0)});continue}if(f(n)){e.addFile(n.filePath,t);continue}}}async#a(e){for(let[t,n]of this.entries){let o=t;o=t.replaceAll("\\","/");for(let[r,s]of Object.entries(ne))o=o.replaceAll(new RegExp(`^${r}$`,"g"),s);if(o=A(o),M(n)){let r=await this.#i(n),s=!1;for(let[a,c]of Object.entries(oe))if(A(a)===o&&c.requireLegacyMapping){let L=u.dumpJavaLang(await this.#n(r));e.addBuffer(Buffer.from(L),o,{mtime:new Date(0)}),s=!0;break}if(!s){let a=J(r);e.addBuffer(Buffer.from(a),o,{mtime:new Date(0)})}continue}if(f(n)){e.addFile(n.filePath,o);continue}}}};import{readdir as re}from"node:fs/promises";import{readJSON as se}from"fs-extra/esm";import ae from"klaw";import{resolve as m,relative as ce}from"node:path";function b(i){return i.type==="resource"}var g=class{normalize(e){return e}};var v="module_manifest.json",P=class{#e=[];#t=new g;addSearchPaths(...e){this.#e.push(...e)}async searchModules(){let e=[];for await(let t of this.#e){let n=await re(t,{withFileTypes:!0}).then(o=>o.filter(r=>r.isDirectory()));for await(let o of n){let r=await se(m(t,o.name,v)),s=this.#t.normalize(r);if(b(s)){let a={path:m(t,o.name),manifest:s,files:await le(m(t,o.name),s)};e.push(a)}else{let a={path:m(t,o.name),manifest:s};e.push(a)}}}return e}};async function le(i,e){let t=[m(i,v)],n=[];for(let o of e.languageModification??[])o.add&&t.push(m(i,o.add)),o.remove&&t.push(m(i,o.remove));for await(let o of ae(i))o.stats.isFile()&&!t.includes(o.path)&&n.push(ce(i,o.path));return n}var K=class{#e;constructor(e){this.#e=e}validateOptions(){return this.#e.platform!=="bedrock"?!1:this.#t()}#t(){let e=new Set(["type","compatible","modules"]),t=new Set(Object.keys(this.#e));return e.isSubsetOf(t)}};var et=3,S=class{#e;constructor(e){this.#e=e}validateOptions(){return this.#e.platform!=="java"||!this.#t()?!1:this.#n()}#t(){let e=new Set(["type","modules","mod","format"]),t=new Set(Object.keys(this.#e));return e.isSubsetOf(t)}#n(){let e=this.#e.type==="legacy"&&this.#e.format===3,t=this.#e.type==="normal"&&this.#e.compatible===!1&&this.#e.format>3,n=this.#e.type==="normal"&&this.#e.compatible===!0&&this.#e.format>3;return t||n||e}};export{K as BedrockOptionValidator,O as BedrockPackBuilder,ie as COMPATIBLE_FILENAME_CONFIG,et as JAVA_LEGACY_FORMAT_VERSION,S as JavaOptionValidator,j as JavaPackBuilder,l as JsonPatch,ne as LEGACY_FILENAME_CONFIG,oe as LEGACY_FILE_CONTENT_CONFIG,u as LangFileConverter,v as MODULE_MANIFEST_FILENAME,P as ModuleParser,d as PackBuilder,E as generateArchiveEntries,ee as generateBedrockTextureFile,x as generateJsonModification};
/**
* @name memepack-builder
* @description A resourcepack builder using ts
*
* @author MysticNebula70
* @license Apache-2.0
*/
//# sourceMappingURL=index.js.map