@notask/unity-cli-tools 1.2.0-rc.1 → 2.0.0

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 (64) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/CHANGELOG.md +164 -164
  3. package/LICENSE +23 -23
  4. package/README.md +809 -347
  5. package/dist/cjs/errors/Result.js +76 -0
  6. package/dist/cjs/errors/UnityError.js +77 -0
  7. package/dist/cjs/errors/index.js +18 -0
  8. package/dist/cjs/events/hubEventEmitter.js +16 -16
  9. package/dist/cjs/events/hubEventParser.js +97 -27
  10. package/dist/cjs/events/patterns/implementations/bracketModulePattern.js +57 -0
  11. package/dist/cjs/events/patterns/implementations/errorPattern.js +99 -0
  12. package/dist/cjs/events/patterns/implementations/fallbackPattern.js +63 -0
  13. package/dist/cjs/events/patterns/implementations/index.js +9 -0
  14. package/dist/cjs/events/patterns/index.js +23 -0
  15. package/dist/cjs/events/patterns/patternRegistry.js +69 -0
  16. package/dist/cjs/events/patterns/statusNormalizer.js +280 -0
  17. package/dist/cjs/events/patterns/types.js +2 -0
  18. package/dist/cjs/index.js +8 -11
  19. package/dist/cjs/unityEditor.js +182 -230
  20. package/dist/cjs/unityHub.js +110 -85
  21. package/dist/cjs/utils/commandExecutor.js +8 -9
  22. package/dist/esm/errors/Result.d.ts +21 -0
  23. package/dist/esm/errors/Result.js +63 -0
  24. package/dist/esm/errors/UnityError.d.ts +36 -0
  25. package/dist/esm/errors/UnityError.js +64 -0
  26. package/dist/esm/errors/index.d.ts +2 -0
  27. package/dist/esm/errors/index.js +2 -0
  28. package/dist/esm/events/hubEventEmitter.d.ts +1 -1
  29. package/dist/esm/events/hubEventParser.d.ts +17 -3
  30. package/dist/esm/events/hubEventParser.js +97 -27
  31. package/dist/esm/events/patterns/implementations/bracketModulePattern.d.ts +11 -0
  32. package/dist/esm/events/patterns/implementations/bracketModulePattern.js +53 -0
  33. package/dist/esm/events/patterns/implementations/errorPattern.d.ts +22 -0
  34. package/dist/esm/events/patterns/implementations/errorPattern.js +95 -0
  35. package/dist/esm/events/patterns/implementations/fallbackPattern.d.ts +13 -0
  36. package/dist/esm/events/patterns/implementations/fallbackPattern.js +59 -0
  37. package/dist/esm/events/patterns/implementations/index.d.ts +3 -0
  38. package/dist/esm/events/patterns/implementations/index.js +3 -0
  39. package/dist/esm/events/patterns/index.d.ts +4 -0
  40. package/dist/esm/events/patterns/index.js +4 -0
  41. package/dist/esm/events/patterns/patternRegistry.d.ts +14 -0
  42. package/dist/esm/events/patterns/patternRegistry.js +65 -0
  43. package/dist/esm/events/patterns/statusNormalizer.d.ts +15 -0
  44. package/dist/esm/events/patterns/statusNormalizer.js +276 -0
  45. package/dist/esm/events/patterns/types.d.ts +30 -0
  46. package/dist/esm/events/patterns/types.js +1 -0
  47. package/dist/esm/index.d.ts +5 -6
  48. package/dist/esm/index.js +1 -2
  49. package/dist/esm/unityEditor.d.ts +11 -15
  50. package/dist/esm/unityEditor.js +196 -244
  51. package/dist/esm/unityHub.d.ts +13 -11
  52. package/dist/esm/unityHub.js +108 -83
  53. package/dist/esm/utils/commandExecutor.d.ts +4 -3
  54. package/dist/esm/utils/commandExecutor.js +8 -9
  55. package/package.json +70 -70
  56. package/sandbox/index.js +51 -0
  57. package/sandbox/node_modules/.package-lock.json +10495 -0
  58. package/sandbox/package.json +13 -0
  59. package/dist/cjs/configs/unityConfig.js +0 -74
  60. package/dist/cjs/unityTemplates.js +0 -29
  61. package/dist/esm/configs/unityConfig.d.ts +0 -25
  62. package/dist/esm/configs/unityConfig.js +0 -68
  63. package/dist/esm/unityTemplates.d.ts +0 -10
  64. package/dist/esm/unityTemplates.js +0 -24
@@ -1,25 +1,47 @@
1
1
  import fs from "fs-extra";
2
2
  import os from "os";
3
+ import path from "path";
3
4
  import { EditorArchitecture, } from "./types/unity.js";
4
5
  import { executeCommand } from "./utils/commandExecutor.js";
5
6
  import { getUnityChangeset } from "unity-changeset";
6
7
  import { UnityHubInstallerEvent } from "./events/hubEventEmitter.js";
7
- import { UnityConfig } from "./configs/unityConfig.js";
8
+ import { ok, err, UnityHubNotFoundError, UnityCommandError, UnityInstallationError, UnityProjectError, InvalidArgumentError, } from "./errors/index.js";
8
9
  class UnityHub {
9
- static unityConfig = UnityConfig.getPlatformConfig();
10
+ static CONFIG_PATHS = {
11
+ win32: {
12
+ hub: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
13
+ projects: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
14
+ projectDir: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
15
+ },
16
+ darwin: {
17
+ hub: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
18
+ projects: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
19
+ projectDir: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
20
+ },
21
+ linux: {
22
+ hub: "/opt/UnityHub/UnityHub",
23
+ projects: path.join(os.homedir(), ".config", "UnityHub", "projects-v1.json"),
24
+ projectDir: path.join(os.homedir(), ".config", "UnityHub", "projectDir.json"),
25
+ },
26
+ };
27
+ static platform = os.platform();
28
+ static hubPath = this.getUnityHubPath();
10
29
  static getUnityHubPath() {
11
- return this.unityConfig.hub.hubDir;
30
+ const envPath = process.env.UNITY_HUB_PATH ?? "";
31
+ if (envPath && fs.existsSync(envPath)) {
32
+ return envPath;
33
+ }
34
+ return UnityHub.CONFIG_PATHS[this.platform].hub || "";
12
35
  }
13
36
  static getProjectsPath() {
14
- return this.unityConfig.hub.projects;
37
+ return UnityHub.CONFIG_PATHS[this.platform].projects || "";
15
38
  }
16
39
  static getProjectDirPath() {
17
- return this.unityConfig.hub.projectDir;
40
+ return UnityHub.CONFIG_PATHS[this.platform].projectDir || "";
18
41
  }
19
42
  static async isUnityHubAvailable() {
20
43
  try {
21
- const hubPath = this.getUnityHubPath();
22
- return !!hubPath && fs.existsSync(hubPath);
44
+ return !!this.hubPath && fs.existsSync(this.hubPath);
23
45
  }
24
46
  catch (error) {
25
47
  console.error("Error checking Unity Hub availability:", error);
@@ -30,122 +52,124 @@ class UnityHub {
30
52
  const isAvailable = await UnityHub.isUnityHubAvailable();
31
53
  if (!isAvailable) {
32
54
  console.error("Unity Hub is not available.");
33
- return {
34
- success: false,
35
- stdout: "",
36
- stderr: "Unity Hub is not available.",
37
- exitCode: -1,
38
- };
39
- }
40
- try {
41
- const hubArgs = [this.unityConfig.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
42
- console.debug(`Executing Unity Hub command: ${this.getUnityHubPath()} ${hubArgs.join(" ")}`);
43
- return await executeCommand(this.unityConfig.hub.hubDir, hubArgs, options);
44
- }
45
- catch (error) {
46
- console.error("Error executing Unity Hub command:", error);
47
- return {
48
- success: false,
49
- stdout: "",
50
- stderr: String(error),
51
- exitCode: -1,
52
- };
55
+ return err(new UnityHubNotFoundError("Unity Hub is not available", { hubPath: this.hubPath }));
53
56
  }
57
+ const hubArgs = [this.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
58
+ console.debug(`Executing Unity Hub command: ${this.hubPath} ${hubArgs.join(" ")}`);
59
+ return await executeCommand(this.hubPath, hubArgs, options);
54
60
  }
55
61
  static async getInstallPath() {
56
- const { stdout, stderr } = await this.execUnityHubCommand(["install-path", "-g"], {
62
+ const result = await this.execUnityHubCommand(["install-path", "-g"], {
57
63
  reject: false,
58
64
  });
59
- if (stderr) {
60
- throw new Error(`Error getting install path: ${stderr}`);
65
+ if (!result.success) {
66
+ return result;
67
+ }
68
+ if (result.value.stderr) {
69
+ return err(new UnityCommandError(`Error getting install path: ${result.value.stderr}`, result.value.stdout, result.value.stderr, result.value.exitCode));
61
70
  }
62
- return stdout;
71
+ return ok(result.value.stdout.trim());
63
72
  }
64
73
  static async setInstallPath(path) {
65
- const { stdout, stderr } = await this.execUnityHubCommand(["install-path", "-s", path], {
74
+ const result = await this.execUnityHubCommand(["install-path", "-s", path], {
66
75
  reject: false,
67
76
  });
68
- if (stderr) {
69
- throw new Error(`Error setting install path: ${stderr}`);
77
+ if (!result.success) {
78
+ return result;
79
+ }
80
+ if (result.value.stderr) {
81
+ return err(new UnityCommandError(`Error setting install path: ${result.value.stderr}`, result.value.stdout, result.value.stderr, result.value.exitCode));
70
82
  }
71
- console.debug(`Install path set to: ${stdout}`);
83
+ console.debug(`Install path set to: ${result.value.stdout}`);
84
+ return ok(undefined);
72
85
  }
73
86
  static async getUnityInstallations(filter = "i") {
74
87
  if (!["i", "a", "r"].includes(filter)) {
75
- throw new Error(`Invalid filter "${filter}". Use "i" for installed, "a" for all, or "r" for available releases.`);
88
+ return err(new InvalidArgumentError(`Invalid filter "${filter}". Use "i" for installed, "a" for all, or "r" for available releases.`, { filter, validFilters: ["i", "a", "r"] }));
76
89
  }
77
- const { stdout, stderr } = await this.execUnityHubCommand(["editors", `-${filter}`], {
90
+ const result = await this.execUnityHubCommand(["editors", `-${filter}`], {
78
91
  reject: false,
79
92
  });
93
+ if (!result.success) {
94
+ return result;
95
+ }
96
+ const { stdout, stderr } = result.value;
80
97
  const isSuccess = stdout.includes(", installed at");
81
- if (stderr)
82
- throw new Error(`Get installations command warning/error: ${stderr}`);
83
- if (!isSuccess)
84
- throw new Error(`Consider install a Unity version using Unity Hub.`);
98
+ if (stderr) {
99
+ return err(new UnityCommandError(`Get installations command warning/error: ${stderr}`, stdout, stderr, result.value.exitCode));
100
+ }
101
+ if (!isSuccess) {
102
+ return err(new UnityInstallationError("No Unity installations found. Consider installing a Unity version using Unity Hub.", {
103
+ filter,
104
+ }));
105
+ }
85
106
  const lines = stdout.split(/\r\n|\n/);
86
107
  const installations = {};
87
108
  lines.forEach((line) => {
88
109
  const [version, unityPath] = line.split(", installed at").map((entry) => entry.trim());
89
- installations[version] = unityPath;
110
+ if (version && unityPath) {
111
+ installations[version] = unityPath;
112
+ }
90
113
  });
91
- if (Object.keys(installations).length <= 0)
92
- throw new Error("No unity installations found.");
93
- return installations;
114
+ if (Object.keys(installations).length <= 0) {
115
+ return err(new UnityInstallationError("No Unity installations found.", { filter }));
116
+ }
117
+ return ok(installations);
94
118
  }
95
119
  static async addModule(editorVersion, modules, childModules = true) {
96
- try {
97
- console.debug(`Adding module ${modules} to Unity ${editorVersion}`);
98
- const args = ["install-modules", "-v", editorVersion];
99
- if (modules.length > 0) {
100
- args.push(...["--module", modules.join(" ")]);
101
- if (childModules) {
102
- args.push("--child-modules");
103
- }
104
- }
105
- else {
106
- throw new Error("No module IDs provided.");
107
- }
108
- const installerEmitter = new UnityHubInstallerEvent();
109
- this.execUnityHubCommand(args, {
110
- reject: false,
111
- onStdout: (data) => installerEmitter.Progress(data),
112
- }).catch((error) => {
113
- console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
114
- });
115
- return installerEmitter;
120
+ if (modules.length === 0) {
121
+ return err(new InvalidArgumentError("No module IDs provided.", { editorVersion, modules }));
116
122
  }
117
- catch (error) {
118
- console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
119
- throw error;
123
+ console.debug(`Adding module ${modules} to Unity ${editorVersion}`);
124
+ const args = ["install-modules", "-v", editorVersion, "--module", modules.join(" ")];
125
+ if (childModules) {
126
+ args.push("--child-modules");
120
127
  }
128
+ const installerEmitter = new UnityHubInstallerEvent();
129
+ this.execUnityHubCommand(args, {
130
+ reject: false,
131
+ onStdout: (data) => installerEmitter.Progress(data),
132
+ })
133
+ .then((result) => {
134
+ if (!result.success) {
135
+ console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, result.error);
136
+ }
137
+ })
138
+ .catch((error) => {
139
+ console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
140
+ });
141
+ return ok(installerEmitter);
121
142
  }
122
143
  static async addEditor(version, modules = [], architecture) {
123
144
  try {
124
145
  const data = await getUnityChangeset(version);
125
- const args = ["install", "-v", version];
126
- args.push("--changeset", data.changeset);
146
+ const args = ["install", "-v", version, "--changeset", data.changeset];
127
147
  if (modules.length > 0) {
128
- args.push("--module");
129
- args.push(modules.join(" "));
148
+ args.push("--module", modules.join(" "));
130
149
  }
131
150
  if (!architecture) {
132
151
  const arch = os.arch() || process.arch;
133
- const defaultArchitecture = arch === "arm64" || arch === "arm" ? EditorArchitecture.arm64 : EditorArchitecture.x86_64;
134
- architecture = defaultArchitecture;
152
+ architecture = arch === "arm64" || arch === "arm" ? EditorArchitecture.arm64 : EditorArchitecture.x86_64;
135
153
  }
136
154
  args.push("--architecture", architecture);
137
155
  const installerEmitter = new UnityHubInstallerEvent();
138
156
  this.execUnityHubCommand(args, {
139
157
  reject: false,
140
158
  onStdout: (data) => installerEmitter.Progress(data),
141
- }).catch((error) => {
159
+ })
160
+ .then((result) => {
161
+ if (!result.success) {
162
+ console.error(`Error installing Unity ${version}:`, result.error);
163
+ }
164
+ })
165
+ .catch((error) => {
142
166
  console.error(`Error installing Unity ${version}:`, error);
143
167
  });
144
- return installerEmitter;
168
+ return ok(installerEmitter);
145
169
  }
146
170
  catch (error) {
147
171
  console.error(error);
148
- throw error;
172
+ return err(new UnityInstallationError(`Failed to install Unity ${version}: ${String(error)}`, { version, modules, architecture }));
149
173
  }
150
174
  }
151
175
  static async getProjects() {
@@ -153,19 +177,20 @@ class UnityHub {
153
177
  const projectsPath = this.getProjectsPath();
154
178
  if (!projectsPath || !fs.existsSync(projectsPath)) {
155
179
  console.debug(`Projects file not found at: ${projectsPath}`);
156
- return [];
180
+ return err(new UnityProjectError(`Projects file not found at: ${projectsPath}`, { projectsPath }));
157
181
  }
158
182
  const projectsData = await fs.readJson(projectsPath);
159
183
  const projects = Object.values(projectsData.data);
160
- return projects.map((project) => ({
184
+ const mappedProjects = projects.map((project) => ({
161
185
  name: project.title,
162
186
  path: project.path,
163
187
  version: project.version,
164
188
  }));
189
+ return ok(mappedProjects);
165
190
  }
166
191
  catch (error) {
167
192
  console.error("Error getting recent projects:", error);
168
- return [];
193
+ return err(new UnityProjectError(`Failed to get projects: ${String(error)}`));
169
194
  }
170
195
  }
171
196
  static async getDefaultProjectsDirectory() {
@@ -173,14 +198,14 @@ class UnityHub {
173
198
  const projectDirPath = this.getProjectDirPath();
174
199
  if (!projectDirPath || !fs.existsSync(projectDirPath)) {
175
200
  console.debug(`Project directory file not found at: ${projectDirPath}`);
176
- return null;
201
+ return ok(null);
177
202
  }
178
203
  const projectDirData = await fs.readJson(projectDirPath);
179
- return projectDirData.directoryPath ?? null;
204
+ return ok(projectDirData.directoryPath ?? null);
180
205
  }
181
206
  catch (error) {
182
207
  console.error("Error getting default project directory:", error);
183
- return null;
208
+ return err(new UnityProjectError(`Failed to get default project directory: ${String(error)}`));
184
209
  }
185
210
  }
186
211
  }
@@ -1,4 +1,6 @@
1
1
  import { Options } from "execa";
2
+ import { Result } from "../errors/index.js";
3
+ import { UnityCommandError } from "../errors/index.js";
2
4
  export interface CommandOptions extends Options {
3
5
  reject?: boolean;
4
6
  timeout?: number;
@@ -7,10 +9,9 @@ export interface CommandOptions extends Options {
7
9
  env?: Record<string, string>;
8
10
  cwd?: string;
9
11
  }
10
- export interface CommandResult {
11
- success: boolean;
12
+ export interface CommandOutput {
12
13
  stdout: string;
13
14
  stderr: string;
14
15
  exitCode?: number;
15
16
  }
16
- export declare function executeCommand(executable: string, args: string[], options?: CommandOptions): Promise<CommandResult>;
17
+ export declare function executeCommand(executable: string, args: string[], options?: CommandOptions): Promise<Result<CommandOutput, UnityCommandError>>;
@@ -1,4 +1,6 @@
1
1
  import { execa } from "execa";
2
+ import { ok, err } from "../errors/index.js";
3
+ import { UnityCommandError } from "../errors/index.js";
2
4
  export async function executeCommand(executable, args, options = {}) {
3
5
  try {
4
6
  const streamOutput = options.onStdout || options.onStderr;
@@ -37,19 +39,16 @@ export async function executeCommand(executable, args, options = {}) {
37
39
  }
38
40
  }
39
41
  const { stdout, stderr, exitCode } = await subprocess;
40
- return {
41
- success: true,
42
+ return ok({
42
43
  stdout,
43
44
  stderr,
44
45
  exitCode,
45
- };
46
+ });
46
47
  }
47
48
  catch (error) {
48
- return {
49
- success: false,
50
- stdout: error.stdout ?? "",
51
- stderr: error.stderr ?? String(error),
52
- exitCode: error.exitCode,
53
- };
49
+ const stdout = error.stdout ?? "";
50
+ const stderr = error.stderr ?? String(error);
51
+ const exitCode = error.exitCode;
52
+ return err(new UnityCommandError(`Command execution failed: ${executable} ${args.join(" ")}`, stdout, stderr, exitCode, { executable, args }));
54
53
  }
55
54
  }
package/package.json CHANGED
@@ -1,70 +1,70 @@
1
- {
2
- "name": "@notask/unity-cli-tools",
3
- "version": "1.2.0-rc.1",
4
- "main": "dist/cjs/index.js",
5
- "module": "dist/esm/index.js",
6
- "types": "dist/esm/index.d.ts",
7
- "type": "module",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/esm/index.js",
11
- "require": "./dist/cjs/index.js",
12
- "types": "./dist/esm/index.d.ts"
13
- }
14
- },
15
- "private": false,
16
- "publishConfig": {
17
- "access": "public"
18
- },
19
- "repository": {
20
- "type": "git",
21
- "url": "https://github.com/NoTaskStudios/unity-cli-tools.git"
22
- },
23
- "scripts": {
24
- "clean": "rimraf dist",
25
- "build": "npm run clean && npm run build:esm && npm run build:cjs",
26
- "build:esm": "tsc --project tsconfig.json",
27
- "build:cjs": "tsc --project tsconfig.cjs.json && node scripts/write-cjs-package.cjs",
28
- "test": "jest --passWithNoTests",
29
- "test:coverage": "jest --coverage",
30
- "lint": "eslint . --ext .ts",
31
- "lint:fix": "eslint . --ext .ts --fix",
32
- "format": "prettier --write \"src/**/*.ts\"",
33
- "format:check": "prettier --check \"src/**/*.ts\"",
34
- "semantic-release": "semantic-release"
35
- },
36
- "keywords": [
37
- "unity",
38
- "cli",
39
- "tools",
40
- "command line"
41
- ],
42
- "author": "NoTask Team",
43
- "license": "MIT",
44
- "description": "A tools for Unity command line development.",
45
- "dependencies": {
46
- "execa": "^9.5.2",
47
- "fs-extra": "^11.3.0",
48
- "unity-changeset": "2.5.0"
49
- },
50
- "devDependencies": {
51
- "@eslint/js": "9.24.0",
52
- "@semantic-release/changelog": "^6.0.3",
53
- "@semantic-release/git": "^10.0.1",
54
- "@semantic-release/npm": "^12.0.1",
55
- "@types/fs-extra": "^11.0.4",
56
- "@types/jest": "^29.5.14",
57
- "@types/node": "^22.13.14",
58
- "@typescript-eslint/eslint-plugin": "^8.30.1",
59
- "@typescript-eslint/parser": "^8.30.1",
60
- "eslint": "9.24.0",
61
- "jest": "^29.7.0",
62
- "prettier": "^3.5.3",
63
- "rimraf": "6.0.1",
64
- "semantic-release": "^24.2.3",
65
- "ts-jest": "^29.3.1",
66
- "tsx": "4.19.3",
67
- "typescript": "^5.8.3",
68
- "typescript-eslint": "8.30.1"
69
- }
70
- }
1
+ {
2
+ "name": "@notask/unity-cli-tools",
3
+ "version": "2.0.0",
4
+ "main": "dist/cjs/index.js",
5
+ "module": "dist/esm/index.js",
6
+ "types": "dist/esm/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/esm/index.js",
11
+ "require": "./dist/cjs/index.js",
12
+ "types": "./dist/esm/index.d.ts"
13
+ }
14
+ },
15
+ "private": false,
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/NoTaskStudios/unity-cli-tools.git"
22
+ },
23
+ "scripts": {
24
+ "clean": "rimraf dist",
25
+ "build": "npm run clean && npm run build:esm && npm run build:cjs",
26
+ "build:esm": "tsc --project tsconfig.json",
27
+ "build:cjs": "tsc --project tsconfig.cjs.json && node scripts/write-cjs-package.cjs",
28
+ "test": "jest --passWithNoTests",
29
+ "test:coverage": "jest --coverage",
30
+ "lint": "eslint . --ext .ts",
31
+ "lint:fix": "eslint . --ext .ts --fix",
32
+ "format": "prettier --write \"src/**/*.ts\"",
33
+ "format:check": "prettier --check \"src/**/*.ts\"",
34
+ "semantic-release": "semantic-release"
35
+ },
36
+ "keywords": [
37
+ "unity",
38
+ "cli",
39
+ "tools",
40
+ "command line"
41
+ ],
42
+ "author": "NoTask Team",
43
+ "license": "MIT",
44
+ "description": "A tools for Unity command line development.",
45
+ "dependencies": {
46
+ "execa": "^9.5.2",
47
+ "fs-extra": "^11.3.0",
48
+ "unity-changeset": "3.1.0"
49
+ },
50
+ "devDependencies": {
51
+ "@eslint/js": "9.24.0",
52
+ "@semantic-release/changelog": "^6.0.3",
53
+ "@semantic-release/git": "^10.0.1",
54
+ "@semantic-release/npm": "^12.0.1",
55
+ "@types/fs-extra": "^11.0.4",
56
+ "@types/jest": "^29.5.14",
57
+ "@types/node": "^22.13.14",
58
+ "@typescript-eslint/eslint-plugin": "^8.30.1",
59
+ "@typescript-eslint/parser": "^8.30.1",
60
+ "eslint": "9.24.0",
61
+ "jest": "^29.7.0",
62
+ "prettier": "^3.5.3",
63
+ "rimraf": "6.0.1",
64
+ "semantic-release": "^24.2.3",
65
+ "ts-jest": "^29.3.1",
66
+ "tsx": "4.19.3",
67
+ "typescript": "^5.8.3",
68
+ "typescript-eslint": "8.30.1"
69
+ }
70
+ }
@@ -0,0 +1,51 @@
1
+ import { UnityEditor, UnityHub, InstallerEventType, UnityModules, isOk, isErr } from "@notask/unity-cli-tools";
2
+
3
+ // Check if Unity Hub is available
4
+ const isAvailable = await UnityHub.isUnityHubAvailable();
5
+
6
+ if (!isAvailable) {
7
+ console.error("Unity Hub is not available on this system.");
8
+ process.exit(1);
9
+ } else {
10
+ console.log("Unity Hub is available.");
11
+ }
12
+
13
+ // Get projects from Unity Hub
14
+ const result = await UnityHub.getProjects();
15
+
16
+ if (isOk(result)) {
17
+ const projects = result.value;
18
+ // Returns: [{ name: 'ProjectName', path: '/path/to/project', version: '2022.3.60f1' }, ...]
19
+ console.log("Projects:", projects);
20
+ }
21
+
22
+ // Get default projects directory
23
+ const dirResult = await UnityHub.getDefaultProjectsDirectory();
24
+
25
+ if (isOk(dirResult)) {
26
+ const defaultDir = dirResult.value; // string | null
27
+ console.log("Default directory:", defaultDir);
28
+ }
29
+
30
+ const addModuleEvent = await UnityHub.addModule("6000.3.2f1", UnityModules.WebGLBuildSupport);
31
+
32
+ if (!isOk(addModuleEvent)) {
33
+ console.error("Failed to start installation:", addModuleEvent.error);
34
+ }
35
+
36
+ const installer = addModuleEvent.value;
37
+ // Listen to progress events
38
+ installer.on(InstallerEventType.Progress, (events) => {
39
+ console.log(
40
+ "Progress:",
41
+ events.map((e) => `${e.module}: ${e.status} ${e.progress || 0}%`)
42
+ );
43
+ });
44
+
45
+ installer.on(InstallerEventType.Error, (errorEvents) => {
46
+ console.error("Installation error:", errorEvents);
47
+ });
48
+
49
+ installer.on(InstallerEventType.Completed, (events) => {
50
+ console.log("Installation completed!");
51
+ });