asajs 4.0.0-indev-3 → 4.0.0-indev-4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +56 -2
  2. package/config.d.ts +4 -1
  3. package/dist/js/compilers/Configuration.js +2 -2
  4. package/dist/js/compilers/Memory.js +1 -1
  5. package/dist/js/compilers/PreCompile.js +12 -1
  6. package/dist/js/compilers/ui/builder.js +32 -8
  7. package/dist/js/compilers/ui/installer.js +139 -4
  8. package/dist/js/compilers/ui/linker.js +28 -10
  9. package/dist/js/compilers/ui/manifest.js +3 -2
  10. package/dist/types/compilers/PreCompile.d.ts +2 -0
  11. package/dist/types/compilers/ui/installer.d.ts +11 -1
  12. package/dist/types/compilers/ui/linker.d.ts +1 -0
  13. package/dist/types/compilers/ui/manifest.d.ts +1 -0
  14. package/dist/types/types/vanilla/intellisense.d.ts +11194 -11194
  15. package/package.json +1 -1
  16. package/resources/asajs.config.cjs +5 -2
  17. package/dist/js/compilers/RunEnd.js +0 -7
  18. package/dist/js/compilers/bindings/Funtion.js +0 -71
  19. package/dist/js/compilers/ui/builddata.js +0 -4
  20. package/dist/js/compilers/ui/config.js +0 -1
  21. package/dist/js/compilers/ui/prevdata.js +0 -8
  22. package/dist/js/config..js +0 -1
  23. package/dist/js/config.js +0 -1
  24. package/dist/js/types/config.js +0 -1
  25. package/dist/js/types/enums/SmartAnimationType.js +0 -3
  26. package/dist/types/compilers/RunEnd.d.ts +0 -1
  27. package/dist/types/compilers/bindings/Funtion.d.ts +0 -7
  28. package/dist/types/compilers/ui/builddata.d.ts +0 -1
  29. package/dist/types/compilers/ui/config.d.ts +0 -1
  30. package/dist/types/compilers/ui/prevdata.d.ts +0 -3
  31. package/dist/types/config..d.ts +0 -2
  32. package/dist/types/config.d.ts +0 -13
  33. package/dist/types/types/config.d.ts +0 -13
  34. package/dist/types/types/enums/SmartAnimationType.d.ts +0 -2
package/README.md CHANGED
@@ -1,3 +1,57 @@
1
- AsaJS Logo made by [Kammasy](https://www.youtube.com/channel/UCrmjDWdM8-ZSeekzLeCnftg) a.k.a **[E.G.G](https://www.youtube.com/channel/UCrmjDWdM8-ZSeekzLeCnftg)**
1
+ <div align="center">
2
+ <img src="./resources/logo.png" />
2
3
 
3
- ![image](/resources/logo.png)
4
+ <h2 align="center">
5
+ <a href="https://asajs.asakiyuki.com/">AsaJS</a> - The <a href="https://www.minecraft.net/en-us">Minecraft: Bedrock Edition</a> JSON-UI Framework
6
+ </h2>
7
+
8
+ [![asajs version](https://img.shields.io/npm/v/asajs.svg?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/asajs)
9
+ [![asajs license](https://img.shields.io/npm/l/asajs.svg?style=for-the-badge&labelColor=000000)](https://github.com/AsakiYuki/AsaJS/blob/main/README.md)
10
+ [![asajs downloads](https://img.shields.io/npm/dm/asajs.svg?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/asajs)
11
+ </div>
12
+
13
+ **AsaJS** is a NodeJS library designed to empower developers to create **JSON-UI** packages for Minecraft: Bedrock Edition using **JavaScript** or **TypeScript**.
14
+
15
+ Say goodbye to the tedious and repetitive nature of manual JSON editing. AsaJS streamlines your workflow by bringing the programmatic flexibility to Minecraft UI development.
16
+
17
+ ## 🛠 Installation
18
+
19
+ To use AsaJS, ensure you have **[Node.js](https://nodejs.org/en)** installed on your system.
20
+
21
+ **Latest stable version:**
22
+
23
+ ```bash
24
+ npm install asajs
25
+ ```
26
+
27
+ **For our nightly builds:**
28
+
29
+ ```
30
+ npm install asajs@indev
31
+ ```
32
+
33
+ ## 📖 "Hello World!" Example
34
+
35
+ Creating a custom UI with AsaJS is straightforward. Here is how you can insert a custom label onto the Minecraft Start Screen:
36
+
37
+ ```javascript
38
+ import { Anchor, Label, Modify } from "asajs"
39
+
40
+ const label = Label({
41
+ text: "Hello World from my Custom UI!",
42
+ shadow: true,
43
+ anchor: Anchor.TOP_MIDDLE,
44
+ offset: [0, 10],
45
+ })
46
+
47
+ // This code injects the label into the top of the start screen
48
+ Modify("start", "start_screen_content").insertChild(label)
49
+ ```
50
+
51
+ ## 📚 Documentation
52
+
53
+ Detailed guides and API references are available at: 👉 https://asajs.asakiyuki.com/
54
+
55
+ ## 🤝 Contributing
56
+
57
+ Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
package/config.d.ts CHANGED
@@ -3,7 +3,10 @@ import { Variable } from "./src/types/properties/value.ts"
3
3
  export interface Config {
4
4
  compiler?: {
5
5
  enabled?: boolean
6
- linked?: boolean
6
+ autoImport?: boolean
7
+ importToPreview?: boolean
8
+ autoEnable?: boolean
9
+ gdkUserId?: string
7
10
  }
8
11
  packinfo?: {
9
12
  name?: string
@@ -8,8 +8,8 @@ if (!fs.existsSync(".gitignore")) {
8
8
  }
9
9
  export const config = require(path.resolve(process.cwd(), "asajs.config.cjs")).config;
10
10
  export let isBuildMode = config.compiler?.enabled ?? false;
11
- export let isLinkMode = config.compiler?.linked ?? false;
12
- export let unLinked = !(config.compiler?.linked ?? true);
11
+ export let isLinkMode = config.compiler?.autoImport ?? false;
12
+ export let unLinked = !(config.compiler?.autoImport ?? true);
13
13
  for (const arg of process.argv) {
14
14
  if (arg === "--build")
15
15
  isBuildMode = true;
@@ -20,7 +20,7 @@ export class Memory extends Class {
20
20
  }
21
21
  static build() {
22
22
  const data = new Map();
23
- Memory.files.entries().forEach(([path, { elements, namespace }]) => {
23
+ Array.from(Memory.files.entries()).forEach(([path, { elements, namespace }]) => {
24
24
  const record = {};
25
25
  elements.forEach(element => (record[element.name] = element));
26
26
  data.set(path, {
@@ -6,4 +6,15 @@ Map.prototype.toJSON = function () {
6
6
  Array.prototype.lastItem = function () {
7
7
  return this[this.length - 1];
8
8
  };
9
- export {};
9
+ const now = performance.now();
10
+ function TypeHighlight(type) {
11
+ switch (type) {
12
+ case "INFO":
13
+ return `\x1b[32mINFO\x1b[0m`;
14
+ default:
15
+ return type;
16
+ }
17
+ }
18
+ export function Log(type, message) {
19
+ console.log(`\x1b[90m[${(performance.now() - now).toFixed(2)}ms]\x1b[0m`, `[${TypeHighlight(type)}]`, message, "\x1b[0m");
20
+ }
@@ -1,9 +1,12 @@
1
1
  import { config, isBuildMode, isLinkMode, unLinked } from "../Configuration.js";
2
2
  import { Memory } from "../Memory.js";
3
- import { createBuildFolder, linkToGame, unlink } from "./linker.js";
4
- import { genManifest } from "./manifest.js";
3
+ import { createBuildFolder, gamePath, getBuildFolderName, linkToGame, unlink } from "./linker.js";
4
+ import { genManifest, version } from "./manifest.js";
5
5
  import fs from "fs/promises";
6
6
  import { BuildCache } from "./buildcache.js";
7
+ import { disableRSP, enableRSP } from "./installer.js";
8
+ import { Log } from "../PreCompile.js";
9
+ import path from "path";
7
10
  async function buildUI() {
8
11
  const build = Memory.build();
9
12
  build.set("ui/_ui_defs.json", {
@@ -16,20 +19,28 @@ async function buildUI() {
16
19
  await fs
17
20
  .stat(outFile.split(/\\|\//g).slice(0, -1).join("/"))
18
21
  .catch(async () => await fs.mkdir(outFile.split(/\\|\//g).slice(0, -1).join("/"), { recursive: true }));
19
- await fs.writeFile(outFile, JSON.stringify(Object.fromEntries(Object.entries(value).map(([key, value]) => {
22
+ await fs
23
+ .writeFile(outFile, JSON.stringify(Object.fromEntries(Object.entries(value).map(([key, value]) => {
20
24
  const extend = value.extend;
21
25
  return [extend ? key + String(extend) : key, value];
22
- }))), "utf-8");
26
+ }))), "utf-8")
27
+ .then(() => Log("INFO", `${outFile} with ${Object.keys(value).length} elements created!`));
23
28
  build.delete(file);
24
29
  return file;
25
30
  }));
26
31
  await Promise.all([
27
- fs.writeFile("build/manifest.json", await genManifest(), "utf-8"),
28
- fs.writeFile("build/.gitignore", [...out, "manifest.json"].join("\n"), "utf-8"),
29
- BuildCache.set("build-files", [...out, "manifest.json"]),
32
+ fs
33
+ .writeFile("build/manifest.json", await genManifest(), "utf-8")
34
+ .then(() => Log("INFO", "build/manifest.json created!")),
35
+ fs
36
+ .writeFile("build/.gitignore", [...out, "manifest.json"].join("\n"), "utf-8")
37
+ .then(() => Log("INFO", "build/.gitignore created!")),
38
+ BuildCache.set("build-files", [...out, "manifest.json"]).then(() => Log("INFO", "build-files set!")),
39
+ BuildCache.set("version", version).then(() => Log("INFO", "version set!")),
30
40
  fs
31
41
  .stat("build/pack_icon.png")
32
- .catch(() => fs.copyFile("node_modules/asajs/resources/pack_icon.png", "build/pack_icon.png")),
42
+ .catch(() => fs.copyFile("node_modules/asajs/resources/pack_icon.png", "build/pack_icon.png"))
43
+ .then(() => Log("INFO", "build/pack_icon.png copied!")),
33
44
  ]);
34
45
  return out.length;
35
46
  }
@@ -41,6 +52,19 @@ if (isBuildMode) {
41
52
  await buildUI();
42
53
  if (isLinkMode)
43
54
  await linkToGame();
55
+ if (config.compiler?.autoEnable)
56
+ await enableRSP();
57
+ else
58
+ await disableRSP();
59
+ Log("INFO", "Build completed!");
60
+ console.log("========================= PACK INFO =========================");
61
+ console.log("Name:", `\x1b[32m${config.packinfo?.name || "MyPack"}\x1b[0m`);
62
+ console.log("Description:", `\x1b[32m${config.packinfo?.description || "Create your Minecraft JSON-UI resource packs using JavaScript."}\x1b[0m`);
63
+ console.log("Version:", config.packinfo?.version || [4, 0, 0]);
64
+ console.log("UUID:", await BuildCache.get("uuid"));
65
+ if (gamePath)
66
+ console.log("Install Path:", `\x1b[32m"${path.join(gamePath, await getBuildFolderName())}"\x1b[0m`);
67
+ console.log("=============================================================");
44
68
  }
45
69
  first = false;
46
70
  });
@@ -1,15 +1,150 @@
1
1
  import os from "os";
2
2
  import path from "path";
3
+ import fs from "fs";
4
+ import fsp from "fs/promises";
5
+ import { config } from "../Configuration.js";
6
+ import { BuildCache } from "./buildcache.js";
7
+ import { version } from "./manifest.js";
8
+ import { Log } from "../PreCompile.js";
9
+ export const pathinfo = {
10
+ os: os.platform(),
11
+ isGdk: false,
12
+ gamepath: null,
13
+ };
14
+ function getGlobalResourcePackFile(gamepath) {
15
+ return path.join(gamepath, "minecraftpe/global_resource_packs.json");
16
+ }
17
+ async function readGlobalRspFile(filepath) {
18
+ try {
19
+ if (await fsp.stat(filepath)) {
20
+ return JSON.parse(await fsp.readFile(filepath, "utf-8"));
21
+ }
22
+ }
23
+ catch (error) {
24
+ return null;
25
+ }
26
+ }
27
+ async function writeGlobalRspFile(filepath, data) {
28
+ try {
29
+ await fsp.writeFile(filepath, JSON.stringify(data), "utf-8");
30
+ }
31
+ catch (error) {
32
+ return null;
33
+ }
34
+ }
35
+ export async function enable(uuid, version, filepath) {
36
+ try {
37
+ const globalRsp = await readGlobalRspFile(filepath);
38
+ if (!globalRsp)
39
+ return null;
40
+ const index = globalRsp.findIndex(data => data.pack_id === uuid);
41
+ if (index === -1) {
42
+ globalRsp.push({ pack_id: uuid, version });
43
+ await writeGlobalRspFile(filepath, globalRsp);
44
+ return true;
45
+ }
46
+ else if (globalRsp[index].version.join(".") !== version.join(".")) {
47
+ globalRsp[index].version = version;
48
+ await writeGlobalRspFile(filepath, globalRsp);
49
+ return true;
50
+ }
51
+ return false;
52
+ }
53
+ catch (error) {
54
+ return null;
55
+ }
56
+ }
57
+ export async function disable(uuid, filepath) {
58
+ try {
59
+ let globalRsp = await readGlobalRspFile(filepath);
60
+ if (!globalRsp)
61
+ return null;
62
+ let isWrite = false;
63
+ globalRsp = globalRsp.filter(data => {
64
+ if (data.pack_id === uuid)
65
+ isWrite = true;
66
+ return data.pack_id !== uuid;
67
+ });
68
+ if (isWrite) {
69
+ await writeGlobalRspFile(filepath, globalRsp);
70
+ return true;
71
+ }
72
+ else
73
+ return false;
74
+ }
75
+ catch (error) {
76
+ return null;
77
+ }
78
+ }
79
+ export async function enableRSP() {
80
+ if (pathinfo.isGdk && pathinfo.gamepath) {
81
+ const ids = [], gamepath = path.join(pathinfo.gamepath, "../../..");
82
+ if (config.compiler?.gdkUserId && /^\d+$/.test(config.compiler.gdkUserId))
83
+ ids.push(config.compiler.gdkUserId);
84
+ else
85
+ ids.push(...(await fsp.readdir(gamepath, { withFileTypes: false })).filter((id) => id !== "Shared"));
86
+ const [uuid] = await Promise.all([BuildCache.get("uuid")]);
87
+ if (!uuid)
88
+ return;
89
+ await Promise.all(ids.map(async (id) => enable(uuid[0], version, getGlobalResourcePackFile(path.join(gamepath, id, "games/com.mojang"))).then(v => {
90
+ if (v) {
91
+ Log("INFO", "Resource Pack enabled automaticly for " + id);
92
+ }
93
+ })));
94
+ }
95
+ else if (pathinfo.gamepath) {
96
+ const [uuid] = await Promise.all([BuildCache.get("uuid")]);
97
+ if (!uuid)
98
+ return;
99
+ await enable(uuid[0], version, getGlobalResourcePackFile(pathinfo.gamepath)).then(v => {
100
+ if (v) {
101
+ Log("INFO", "Resource Pack enabled automaticly");
102
+ }
103
+ });
104
+ }
105
+ }
106
+ export async function disableRSP() {
107
+ if (pathinfo.isGdk && pathinfo.gamepath) {
108
+ const gamepath = path.join(pathinfo.gamepath, "../../..");
109
+ const [uuid] = await Promise.all([BuildCache.get("uuid")]);
110
+ if (!uuid)
111
+ return;
112
+ await Promise.all((await fsp.readdir(gamepath, { withFileTypes: false })).map(async (id) => disable(uuid[0], getGlobalResourcePackFile(path.join(gamepath, id, "games/com.mojang"))).then(v => {
113
+ if (v) {
114
+ Log("INFO", "Resource Pack disabled automaticly for " + id);
115
+ }
116
+ })));
117
+ }
118
+ else if (pathinfo.gamepath) {
119
+ const [uuid] = await Promise.all([BuildCache.get("uuid")]);
120
+ if (!uuid)
121
+ return;
122
+ await disable(uuid[0], getGlobalResourcePackFile(pathinfo.gamepath)).then(v => {
123
+ if (v) {
124
+ Log("INFO", "Resource Pack disabled automaticly");
125
+ }
126
+ });
127
+ }
128
+ }
3
129
  export function getGamedataPath() {
4
- switch (os.platform()) {
130
+ switch (pathinfo.os) {
5
131
  case "win32": {
6
132
  if (/Windows (10|11)/.test(os.version())) {
7
- return path.join(process.env.APPDATA, "Minecraft Bedrock\\Users\\Shared\\games\\com.mojang");
133
+ let gamedata = path.join(process.env.APPDATA, config.compiler?.importToPreview ? "Minecraft Bedrock Preview" : "Minecraft Bedrock", "\\Users\\Shared\\games\\com.mojang");
134
+ if (fs.existsSync(gamedata)) {
135
+ pathinfo.isGdk = true;
136
+ return (pathinfo.gamepath = gamedata);
137
+ }
138
+ gamedata = path.join(process.env.LOCALAPPDATA, "Packages", config.compiler?.importToPreview
139
+ ? "Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe"
140
+ : "Microsoft.MinecraftUWP_8wekyb3d8bbwe", "LocalState\\games\\com.mojang");
141
+ if (fs.existsSync(gamedata)) {
142
+ return (pathinfo.gamepath = gamedata);
143
+ }
8
144
  }
9
145
  }
10
146
  default: {
11
- console.error(`Your platform is not supported the install feature yet! \nYour OS version: ${os.version()}`);
12
- process.exit(1);
147
+ console.warn(`Your platform is not supported the install feature yet! \nYour OS version: ${os.version()}`);
13
148
  }
14
149
  }
15
150
  }
@@ -2,7 +2,8 @@ import fs from "fs/promises";
2
2
  import { BuildCache } from "./buildcache.js";
3
3
  import { RandomString } from "../../components/Utils.js";
4
4
  import path from "path";
5
- import { getGamedataPath } from "./installer.js";
5
+ import { getGamedataPath, pathinfo } from "./installer.js";
6
+ import { Log } from "../PreCompile.js";
6
7
  const HEX = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
7
8
  function genUUID() {
8
9
  const b = Array.from({ length: 16 }, () => Math.floor(Math.random() * 256));
@@ -18,28 +19,45 @@ function genUUID() {
18
19
  }
19
20
  export async function clearBuild() {
20
21
  const files = (await BuildCache.get("build-files")) || [];
21
- await Promise.all(files.map(file => fs.rm(`build/${file}`).catch(() => null)));
22
+ await Promise.all(files.map(file => fs.rm(`build/${file}`).catch(() => null))).then(() => {
23
+ if (files.length) {
24
+ Log("INFO", `Build folder cleared (${files.length} files removed)!`);
25
+ }
26
+ });
22
27
  }
23
28
  export async function createBuildFolder() {
24
29
  return fs
25
30
  .stat("build")
26
- .catch(() => fs.mkdir("build"))
31
+ .catch(() => fs.mkdir("build").then(() => Log("INFO", "Build folder created!")))
27
32
  .then(() => clearBuild());
28
33
  }
29
34
  export async function getBuildFolderName() {
30
35
  return await BuildCache.getWithSetDefault("build-key", () => RandomString(16));
31
36
  }
37
+ export let gamePath = null;
32
38
  export async function linkToGame() {
33
- const sourcePath = path.resolve("build");
34
- const targetPath = path.resolve(getGamedataPath(), "development_resource_packs", await getBuildFolderName());
35
- await fs.stat(targetPath).catch(async () => {
36
- await fs.symlink(sourcePath, targetPath, "junction");
37
- });
39
+ const gamedataPath = getGamedataPath();
40
+ await BuildCache.set("last-gamedata-path", pathinfo);
41
+ if (gamedataPath) {
42
+ const sourcePath = path.resolve("build");
43
+ const targetPath = path.resolve(gamedataPath, "development_resource_packs", await getBuildFolderName());
44
+ await fs.stat(targetPath).catch(async () => {
45
+ await fs
46
+ .symlink(sourcePath, targetPath, "junction")
47
+ .then(() => Log("INFO", "Linked build folder to gamedata!"));
48
+ });
49
+ gamePath = gamedataPath;
50
+ }
51
+ else
52
+ console.warn("No gamedata path found, cannot link!");
38
53
  }
39
54
  export async function unlink() {
40
- const targetPath = path.resolve(getGamedataPath(), "development_resource_packs", await getBuildFolderName());
55
+ const gamedataPath = await BuildCache.get("last-gamedata-path");
56
+ if (!gamedataPath?.gamepath)
57
+ return;
58
+ const targetPath = path.resolve(gamedataPath.gamepath, "development_resource_packs", await getBuildFolderName());
41
59
  try {
42
- await fs.unlink(targetPath);
60
+ await fs.unlink(targetPath).then(() => Log("INFO", "Unlinked build folder from gamedata!"));
43
61
  }
44
62
  catch (error) {
45
63
  console.error(error);
@@ -1,5 +1,6 @@
1
1
  import { config } from "../Configuration.js";
2
2
  import { getUUID } from "./linker.js";
3
+ export const version = config.packinfo?.version || [4, 0, 0];
3
4
  export async function genManifest() {
4
5
  const [uuid1, uuid2] = await getUUID();
5
6
  return JSON.stringify({
@@ -8,7 +9,7 @@ export async function genManifest() {
8
9
  name: config.packinfo?.name || "AsaJS",
9
10
  description: config.packinfo?.description || "Create your Minecraft JSON-UI resource packs using JavaScript.",
10
11
  uuid: uuid1,
11
- version: config.packinfo?.version || [4, 0, 0],
12
+ version,
12
13
  min_engine_version: [1, 21, 80],
13
14
  },
14
15
  modules: [
@@ -16,7 +17,7 @@ export async function genManifest() {
16
17
  description: "This resource pack generate by AsaJS.",
17
18
  type: "resources",
18
19
  uuid: uuid2,
19
- version: [4, 0, 0],
20
+ version: version,
20
21
  },
21
22
  ],
22
23
  subpacks: config.packinfo?.subpacks,
@@ -6,4 +6,6 @@ declare global {
6
6
  lastItem(): T;
7
7
  }
8
8
  }
9
+ type LogType = "INFO";
10
+ export declare function Log(type: LogType, message: string): void;
9
11
  export {};
@@ -1 +1,11 @@
1
- export declare function getGamedataPath(): string;
1
+ export interface PathInfo<Platform = NodeJS.Platform> {
2
+ os: Platform;
3
+ isGdk: Platform extends "win32" ? boolean : never;
4
+ gamepath: string | null;
5
+ }
6
+ export declare const pathinfo: PathInfo;
7
+ export declare function enable(uuid: string, version: [number, number, number], filepath: string): Promise<boolean | null>;
8
+ export declare function disable(uuid: string, filepath: string): Promise<boolean | null>;
9
+ export declare function enableRSP(): Promise<void>;
10
+ export declare function disableRSP(): Promise<void>;
11
+ export declare function getGamedataPath(): string | undefined;
@@ -1,6 +1,7 @@
1
1
  export declare function clearBuild(): Promise<void>;
2
2
  export declare function createBuildFolder(): Promise<void>;
3
3
  export declare function getBuildFolderName(): Promise<string>;
4
+ export declare let gamePath: string | null;
4
5
  export declare function linkToGame(): Promise<void>;
5
6
  export declare function unlink(): Promise<void>;
6
7
  export declare function getUUID(): Promise<[string, string]>;
@@ -1 +1,2 @@
1
+ export declare const version: [number, number, number];
1
2
  export declare function genManifest(): Promise<string>;