This commit is contained in:
Asaki Yuki 2026-02-22 13:21:24 +07:00
parent 63315c35c4
commit e162ff9207
8 changed files with 50 additions and 22 deletions

3
config.d.ts vendored
View file

@ -1,4 +1,4 @@
import { BindingItem, Variable } from "./src/types/properties/value.ts" import { Variable } from "./src/types/properties/value.ts"
export interface RetBindingValue { export interface RetBindingValue {
generate_bindings?: Array<{ source_property_name: string; target_property_name: string }> generate_bindings?: Array<{ source_property_name: string; target_property_name: string }>
@ -13,6 +13,7 @@ export interface Config {
autoEnable?: boolean autoEnable?: boolean
gdkUserId?: string gdkUserId?: string
fixInventoryItemRenderer?: boolean fixInventoryItemRenderer?: boolean
buildFolder?: string
} }
packinfo?: { packinfo?: {
name?: string name?: string

View file

@ -1,6 +1,6 @@
{ {
"name": "asajs", "name": "asajs",
"version": "4.0.7-indev", "version": "4.0.9",
"description": "Create your Minecraft JSON-UI resource packs using JavaScript", "description": "Create your Minecraft JSON-UI resource packs using JavaScript",
"keywords": [ "keywords": [
"Minecraft", "Minecraft",

View file

@ -1,6 +1,6 @@
import fs from "fs" import fs from "fs"
import path from "path" import path from "path"
// @ts-ignore import jsonc from "jsonc-parser"
import { Config, RetBindingValue } from "../../config.js" import { Config, RetBindingValue } from "../../config.js"
import { createRequire } from "module" import { createRequire } from "module"
@ -10,7 +10,11 @@ for (const arg of process.argv) {
if (arg.startsWith("--")) options[arg.slice(2)] = true if (arg.startsWith("--")) options[arg.slice(2)] = true
} }
export const isTestMode = !fs.existsSync("node_modules/asajs") export let isTestMode = false
try {
const { name } = jsonc.parse(fs.readFileSync(path.resolve("package.json"), "utf-8"))
if (name === "asajs") isTestMode = true
} catch (error) {}
if (!fs.existsSync("asajs.config.js")) { if (!fs.existsSync("asajs.config.js")) {
if (isTestMode) { if (isTestMode) {
@ -55,6 +59,7 @@ export const config: Config = createRequire(import.meta.url)(path.resolve(proces
export const isBuildMode = options["build"] ?? config.compiler?.enabled ?? false export const isBuildMode = options["build"] ?? config.compiler?.enabled ?? false
export const isLinkMode = options["link"] ?? config.compiler?.autoImport ?? false export const isLinkMode = options["link"] ?? config.compiler?.autoImport ?? false
export const unLinked = options["unlink"] ?? !(config.compiler?.autoImport ?? true) export const unLinked = options["unlink"] ?? !(config.compiler?.autoImport ?? true)
export const buildFolder = config.compiler?.buildFolder || "build"
export const bindingFuntions = config.binding_functions export const bindingFuntions = config.binding_functions

View file

@ -19,12 +19,14 @@ Array.prototype.lastItem = function () {
} }
const now = performance.now() const now = performance.now()
type LogType = "INFO" type LogType = "INFO" | "WARN"
function TypeHighlight(type: LogType) { function TypeHighlight(type: LogType) {
switch (type) { switch (type) {
case "INFO": case "INFO":
return `\x1b[32mINFO\x1b[0m` return `\x1b[32mINFO\x1b[0m`
case "WARN":
return `\x1b[33mWARN\x1b[0m`
default: default:
return type satisfies never return type satisfies never
} }

View file

@ -1,4 +1,5 @@
import fs from "fs/promises" import fs from "fs/promises"
import { buildFolder } from "../Configuration.js"
export class BuildCache { export class BuildCache {
private static queue: Promise<void> = Promise.resolve() private static queue: Promise<void> = Promise.resolve()
@ -14,7 +15,9 @@ export class BuildCache {
static async get<T = unknown>(key: string): Promise<T | null> { static async get<T = unknown>(key: string): Promise<T | null> {
return this.enqueue<T>(async () => { return this.enqueue<T>(async () => {
try { try {
return await fs.readFile("build/cache.json", "utf-8").then(data => JSON.parse(data)[key] ?? null) return await fs
.readFile(`${buildFolder}/cache.json`, "utf-8")
.then(data => JSON.parse(data)[key] ?? null)
} catch (error) { } catch (error) {
return null return null
} }
@ -33,13 +36,13 @@ export class BuildCache {
let data: Record<string, any> = {} let data: Record<string, any> = {}
try { try {
data = JSON.parse(await fs.readFile("build/cache.json", "utf-8")) data = JSON.parse(await fs.readFile(`${buildFolder}/cache.json`, "utf-8"))
} catch {} } catch {}
if (key in data) return data[key] if (key in data) return data[key]
data[key] = outVal data[key] = outVal
await fs.writeFile("build/cache.json", JSON.stringify(data), "utf-8") await fs.writeFile(`${buildFolder}/cache.json`, JSON.stringify(data), "utf-8")
return outVal return outVal
}) })
} }
@ -48,15 +51,15 @@ export class BuildCache {
return this.enqueue(async () => { return this.enqueue(async () => {
try { try {
return fs.writeFile( return fs.writeFile(
"build/cache.json", `${buildFolder}/cache.json`,
JSON.stringify({ JSON.stringify({
...(await fs.readFile("build/cache.json", "utf-8").then(data => JSON.parse(data))), ...(await fs.readFile(`${buildFolder}/cache.json`, "utf-8").then(data => JSON.parse(data))),
[key]: value, [key]: value,
}), }),
"utf-8", "utf-8",
) )
} catch (error) { } catch (error) {
return fs.writeFile("build/cache.json", JSON.stringify({ [key]: value }), "utf-8") return fs.writeFile(`${buildFolder}/cache.json`, JSON.stringify({ [key]: value }), "utf-8")
} }
}) })
} }

View file

@ -1,4 +1,4 @@
import { config, isBuildMode, isLinkMode, isTestMode, unLinked } from "../Configuration.js" import { buildFolder, config, isBuildMode, isLinkMode, isTestMode, unLinked } from "../Configuration.js"
import { Memory } from "../Memory.js" import { Memory } from "../Memory.js"
import { createBuildFolder, gamePath, getBuildFolderName, linkToGame, unlink } from "./linker.js" import { createBuildFolder, gamePath, getBuildFolderName, linkToGame, unlink } from "./linker.js"
import { genManifest, version } from "./manifest.js" import { genManifest, version } from "./manifest.js"
@ -9,6 +9,7 @@ import { BuildCache } from "./buildcache.js"
import { disableRSP, enableRSP } from "./installer.js" import { disableRSP, enableRSP } from "./installer.js"
import { Log } from "../PreCompile.js" import { Log } from "../PreCompile.js"
import path from "path" import path from "path"
import { API_events } from "../../components/API.js"
async function buildUI() { async function buildUI() {
const build = Memory.build() const build = Memory.build()
@ -20,8 +21,8 @@ async function buildUI() {
if (config.global_variables) build.set("ui/_global_variables.json", config.global_variables) if (config.global_variables) build.set("ui/_global_variables.json", config.global_variables)
const out = await Promise.all( const out = await Promise.all(
build.entries().map(async ([file, value]) => { Array.from(build.entries()).map(async ([file, value]) => {
const outFile = `build/${file}` const outFile = `${buildFolder}/${file}`
await fs await fs
.stat(outFile.split(/\\|\//g).slice(0, -1).join("/")) .stat(outFile.split(/\\|\//g).slice(0, -1).join("/"))
.catch(async () => await fs.mkdir(outFile.split(/\\|\//g).slice(0, -1).join("/"), { recursive: true })) .catch(async () => await fs.mkdir(outFile.split(/\\|\//g).slice(0, -1).join("/"), { recursive: true }))
@ -47,23 +48,24 @@ async function buildUI() {
await Promise.all([ await Promise.all([
fs fs
.writeFile("build/manifest.json", await genManifest(), "utf-8") .writeFile(`${buildFolder}/manifest.json`, await genManifest(), "utf-8")
.then(() => Log("INFO", "build/manifest.json created!")), .then(() => Log("INFO", `${buildFolder}/manifest.json created!`)),
fs fs
.writeFile("build/.gitignore", [...out, "manifest.json"].join("\n"), "utf-8") .writeFile(`${buildFolder}/.gitignore`, [...out, "manifest.json"].join("\n"), "utf-8")
.then(() => Log("INFO", "build/.gitignore created!")), .then(() => Log("INFO", `${buildFolder}/.gitignore created!`)),
BuildCache.set("build-files", [...out, "manifest.json"]).then(() => Log("INFO", "build-files set!")), BuildCache.set("build-files", [...out, "manifest.json"]).then(() => Log("INFO", "build-files set!")),
BuildCache.set("version", version).then(() => Log("INFO", "version set!")), BuildCache.set("version", version).then(() => Log("INFO", "version set!")),
fs fs
.stat("build/pack_icon.png") .stat(`${buildFolder}/pack_icon.png`)
.catch(() => .catch(() =>
fs.copyFile( fs.copyFile(
isTestMode ? "resources/pack_icon.png" : "node_modules/asajs/resources/pack_icon.png", isTestMode ? "resources/pack_icon.png" : "node_modules/asajs/resources/pack_icon.png",
"build/pack_icon.png", `${buildFolder}/pack_icon.png`,
), ),
) )
.then(() => Log("INFO", "build/pack_icon.png copied!")), .then(() => Log("INFO", `${buildFolder}/pack_icon.png copied!`))
]) .catch(() => Log("WARN", `cannot copy ${buildFolder}/pack_icon.png!`)),
]).catch(error => console.error(error))
return out.length return out.length
} }
@ -93,6 +95,9 @@ if (isBuildMode) {
`\x1b[32m"${path.join(gamePath, "development_resource_packs", await getBuildFolderName())}"\x1b[0m`, `\x1b[32m"${path.join(gamePath, "development_resource_packs", await getBuildFolderName())}"\x1b[0m`,
) )
console.log("=============================================================") console.log("=============================================================")
// API events
API_events.onBuildFinish.forEach(v => v(config))
} }
}) })
} else if (isLinkMode) linkToGame() } else if (isLinkMode) linkToGame()

11
src/components/API.ts Normal file
View file

@ -0,0 +1,11 @@
import { Config } from "../../config.js"
export const API_events: { onBuildFinish: ((config: Config) => void)[] } = {
onBuildFinish: [],
}
export const API = {
onBuildFinish: function (callback: (config: Config) => void) {
API_events.onBuildFinish.push(callback)
},
}

View file

@ -16,3 +16,4 @@ export { ItemAuxID } from "./types/enums/Items.js"
export { ArrayName, Operation } from "./types/properties/index.js" export { ArrayName, Operation } from "./types/properties/index.js"
export * from "./compilers/bindings/Binary.js" export * from "./compilers/bindings/Binary.js"
export { API } from "./components/API.js"