diff --git a/config.d.ts b/config.d.ts index 6c3ff0f..8ed1ab4 100644 --- a/config.d.ts +++ b/config.d.ts @@ -1,4 +1,9 @@ -import { Variable } from "./src/types/properties/value.ts" +import { BindingItem, Variable } from "./src/types/properties/value.ts" + +export interface RetBindingValue { + generate_bindings?: Array<{ source_property_name: string; target_property_name: string }> + return_value: string +} export interface Config { compiler?: { @@ -27,4 +32,5 @@ export interface Config { }[] } global_variables?: Record + binding_functions?: Record RetBindingValue> } diff --git a/package.json b/package.json index ba1bea4..acfb461 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "scripts": { "build": "tsc", "dev": "tsc --watch", - "test": "bun test/app.ts --test", + "test": "bun test/app.ts", "prefetch": "bun scripts/prefetch", "vanilla:defs": "bun scripts/vanilladefs", "gen:enums": "bun scripts/enum", diff --git a/resources/asajs.config.js b/resources/asajs.config.js index 018faf9..2d42c27 100644 --- a/resources/asajs.config.js +++ b/resources/asajs.config.js @@ -6,7 +6,7 @@ export const config = { packinfo: { name: "AsaJS", description: "Create your Minecraft JSON-UI resource packs using JavaScript.", - version: [4, 0, 1], + version: [1, 0, 0], }, compiler: { enabled: true, @@ -14,4 +14,19 @@ export const config = { autoEnable: true, importToPreview: false, }, + binding_functions: { + custom_abs: function (number) { + const randomAbs = RandomBindingString(16) + + return { + generate_bindings: [ + { + source_property_name: `[ abs(${number}) ]`, + target_property_name: randomAbs, + }, + ], + return_value: randomAbs, + } + }, + }, } diff --git a/src/compilers/Configuration.ts b/src/compilers/Configuration.ts index af843ee..ea74ec8 100644 --- a/src/compilers/Configuration.ts +++ b/src/compilers/Configuration.ts @@ -1,7 +1,7 @@ import fs from "fs" import path from "path" // @ts-ignore -import { Config } from "../../config.js" +import { Config, RetBindingValue } from "../../config.js" import { createRequire } from "module" const options: Record = {} @@ -10,16 +10,43 @@ for (const arg of process.argv) { if (arg.startsWith("--")) options[arg.slice(2)] = true } -export const isTestMode = options["test"] ?? false +export const isTestMode = !fs.existsSync("node_modules/asajs") if (!fs.existsSync("asajs.config.js")) { if (isTestMode) { fs.writeFileSync( "asajs.config.js", - fs.readFileSync("resources/asajs.config.js", "utf-8").replace("asajs/", "./"), + [ + `export function RandomBindingString(length, base = 32) { + const chars = "0123456789abcdefghijklmnopqrstuvwxyz".slice(0, base) + const out = new Array() + + try { + const buffer = new Uint8Array(length) + crypto.getRandomValues(buffer) + for (let i = 0; i < length; i++) { + out[i] = chars[buffer[i] % base] + } + } catch { + for (let i = 0; i < length; i++) { + out[i] = chars[Math.floor(Math.random() * base)] + } + } + + return \`#$\{out.join("")}\` +}\n`, + + fs.readFileSync("resources/asajs.config.js", "utf-8").replace("asajs/", "./"), + ].join("\n"), ) } else { - fs.copyFileSync("node_modules/asajs/resources/asajs.config.js", "asajs.config.js") + fs.writeFileSync( + "asajs.config.js", + [ + 'import { RandomBindingString } from "asajs"\n', + fs.readFileSync("node_modules/asajs/resources/asajs.config.js", "utf-8"), + ].join("\n"), + ) } } @@ -29,6 +56,8 @@ export const isBuildMode = options["build"] ?? config.compiler?.enabled ?? false export const isLinkMode = options["link"] ?? config.compiler?.autoImport ?? false export const unLinked = options["unlink"] ?? !(config.compiler?.autoImport ?? true) +export const bindingFuntions = config.binding_functions + if (!fs.existsSync(".gitignore")) { fs.writeFileSync(".gitignore", `node_modules`, "utf-8") } diff --git a/src/compilers/bindings/Function.ts b/src/compilers/bindings/Function.ts index 3b99b2e..ae2a050 100644 --- a/src/compilers/bindings/Function.ts +++ b/src/compilers/bindings/Function.ts @@ -1,4 +1,6 @@ -import { RandomBindingString } from "../../components/Utils.js" +import { RandomBindingString, ResolveBinding } from "../../components/Utils.js" +import { BindingItem } from "../../types/properties/value.js" +import { bindingFuntions } from "../Configuration.js" import { Expression, GenBinding } from "./types.js" type CallbackRet = { @@ -198,3 +200,24 @@ export const defaultFunctions = { } satisfies Record Object.entries(defaultFunctions).forEach(([key, value]) => FunctionMap.set(key, value)) +if (bindingFuntions) + Object.entries(bindingFuntions).forEach(([key, value]) => { + // @ts-ignore + FunctionMap.set(key, (...args) => { + const { generate_bindings, return_value } = value(...args) + if (generate_bindings) { + const resolve = ResolveBinding(new Map(), ...(generate_bindings as BindingItem[])) + return { + genBindings: resolve.map(({ source_property_name, target_property_name }) => ({ + source: source_property_name!, + target: target_property_name!, + })), + value: return_value, + } + } + + return { + value: return_value, + } + }) + }) diff --git a/src/compilers/ui/builder.ts b/src/compilers/ui/builder.ts index af6f775..65709dc 100644 --- a/src/compilers/ui/builder.ts +++ b/src/compilers/ui/builder.ts @@ -88,7 +88,10 @@ if (isBuildMode) { console.log("Version:", config.packinfo?.version || [4, 0, 0]) console.log("UUID:", await BuildCache.get<[string, string]>("uuid")) if (gamePath) - console.log("Install Path:", `\x1b[32m"${path.join(gamePath, await getBuildFolderName())}"\x1b[0m`) + console.log( + "Install Path:", + `\x1b[32m"${path.join(gamePath, "development_resource_packs", await getBuildFolderName())}"\x1b[0m`, + ) console.log("=============================================================") } }) diff --git a/src/compilers/ui/linker.ts b/src/compilers/ui/linker.ts index d69e044..19a96bf 100644 --- a/src/compilers/ui/linker.ts +++ b/src/compilers/ui/linker.ts @@ -41,7 +41,7 @@ export async function createBuildFolder() { } export async function getBuildFolderName() { - return await BuildCache.getWithSetDefault("build-key", () => RandomString(16)) + return await BuildCache.getWithSetDefault("build-key", () => `asajs-build-${RandomString(16)}`) } export let gamePath: string | null = null diff --git a/test/app.ts b/test/app.ts index 29a503a..fefcd00 100644 --- a/test/app.ts +++ b/test/app.ts @@ -1,10 +1,16 @@ import { Anchor, Label, Modify } from ".." -const label = Label({ - text: "Hello World from my Custom UI!", - shadow: true, - anchor: Anchor.TOP_MIDDLE, - offset: [0, 10], +const label = Label( + { + text: "Hello World from my Custom UI!", + shadow: true, + anchor: Anchor.TOP_MIDDLE, + offset: [0, 10], + }, + "test", +).addBindings({ + source_property_name: `[ custom_abs(#a) ]`, + target_property_name: "#text", }) Modify("start", "start_screen_content").insertChild(label)