@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
package/README.md CHANGED
@@ -1,347 +1,809 @@
1
- # Unity Command line Tools
2
-
3
- A TypeScript library for programmatically interacting with Unity Hub and Unity Editor command line interfaces.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @notask/unity-cli-tools
9
- ```
10
-
11
- ## Dual Module Support
12
-
13
- This package publishes separate builds for both ES Modules (ESM) and CommonJS (CJS). You can consume it either way:
14
-
15
- **ESM** (Node and bundlers):
16
- ```ts
17
- import { UnityHub } from "@notask/unity-cli-tools";
18
- ```
19
-
20
- **CJS**:
21
- ```js
22
- const { UnityHub } = require("@notask/unity-cli-tools");
23
- ```
24
-
25
- ## Requirements
26
-
27
- - Node.js 20+
28
- - Unity Hub installed
29
- - Unity Editor (for editor operations)
30
-
31
- ## Core Concepts
32
-
33
- Unity CLI Tools provides two main modules:
34
-
35
- - `UnityHub` - For interacting with Unity Hub
36
- - `UnityEditor` - For interacting with Unity Editor (documentation coming soon)
37
-
38
- ## UnityHub API Reference
39
-
40
- ### Checking Availability
41
-
42
- ```typescript
43
- import { UnityHub } from "unity-cli-tools";
44
-
45
- // Check if Unity Hub is available
46
- const isAvailable = await UnityHub.isUnityHubAvailable();
47
- ```
48
-
49
- ### Finding Unity Installations
50
-
51
- ```typescript
52
- // Get all installed Unity versions
53
- const installations = await UnityHub.getUnityInstallations();
54
- // Returns: { '2022.3.60f1': 'C:/Program Files/Unity/Hub/Editor/2022.3.60f1', ... }
55
- ```
56
-
57
- ### Managing Unity Versions
58
-
59
- ```typescript
60
- import { UnityHub, UnityModules } from "unity-cli-tools";
61
-
62
- // Install a new Unity version
63
- await UnityHub.addEditor("2022.3.60f1");
64
-
65
- // Install with specific modules
66
- await UnityHub.addEditor("2022.3.60f1", undefined, [UnityModules.AndroidBuildSupport, UnityModules.WebGLBuildSupport]);
67
-
68
- // Add modules to existing installation
69
- await UnityHub.addModule("2022.3.60f1", [UnityModules.IOSBuildSupport]);
70
- ```
71
-
72
- ### Installation Events
73
-
74
- ```typescript
75
- import { UnityHub, UnityModules, InstallerEventType } from "unity-cli-tools";
76
-
77
- // Install with event tracking (addEditor returns an event emitter)
78
- const installer = await UnityHub.addEditor("2022.3.60f1");
79
-
80
- // Get a promise that resolves when installation completes
81
- const installation = installer.completed;
82
-
83
- // Or listen to specific events
84
- installer.on(InstallerEventType.Progress, (events) => {
85
- console.log("Progress:", events.map(e => `${e.module}: ${e.status} ${e.progress || 0}%`));
86
- });
87
-
88
- installer.on(InstallerEventType.Error, (error) => {
89
- console.error("Installation error:", error);
90
- });
91
-
92
- installer.on(InstallerEventType.Completed, (events) => {
93
- console.log("Installation completed!");
94
- });
95
-
96
- // Cancel installation if needed
97
- installer.Cancel();
98
- ```
99
-
100
- ### Projects Management
101
-
102
- ```typescript
103
- // Get projects from Unity Hub
104
- const projects = await UnityHub.getProjects();
105
- // Returns: [{ name: 'ProjectName', path: '/path/to/project', version: '2022.3.60f1' }, ...]
106
-
107
- // Get default projects directory
108
- const defaultDir = await UnityHub.getDefaultProjectsDirectory();
109
- ```
110
-
111
- ### Custom Commands
112
-
113
- ```typescript
114
- // Execute any Hub command directly
115
- const result = await UnityHub.execUnityHubCommand(["editors", "-r"]);
116
- console.log(result.stdout);
117
- ```
118
-
119
- ## UnityEditor API Reference
120
-
121
- UnityEditor provides an interface for automating tasks directly in the Unity Editor:
122
-
123
- ### Installation and Availability
124
- ```typescript
125
- import UnityEditor from "@notask/unity-cli-tools";
126
-
127
- // Get the executable path and verify installation
128
- const unityPath = UnityEditor.getUnityExecutablePath("2022.3.15f1");
129
- const isInstalled = await UnityEditor.isUnityVersionInstalled("2022.3.15f1");
130
- console.log(`Installed: ${isInstalled}`, unityPath);
131
- ```
132
-
133
- ### Executing Raw Editor Commands
134
- ```typescript
135
- import { CommandResult } from "@notask/unity-cli-tools";
136
-
137
- const editorInfo = { version: "2022.3.15f1", path: unityPath };
138
- const result: CommandResult = await UnityEditor.execUnityEditorCommand(
139
- editorInfo,
140
- ["-batchmode", "-quit", "-projectPath", "/path/to/project"]
141
- );
142
- console.log(result.stdout);
143
- ```
144
-
145
- ### Creating and Opening Projects
146
- ```typescript
147
- import { ProjectInfo } from "@notask/unity-cli-tools";
148
-
149
- const projectInfo: ProjectInfo = {
150
- projectPath: "/path/to/new/project",
151
- editorVersion: "2022.3.15f1"
152
- };
153
-
154
- await UnityEditor.createProject(projectInfo);
155
- await UnityEditor.openProject(projectInfo, true, true);
156
- ```
157
-
158
- ### Running Tests
159
- ```typescript
160
- import { ProjectInfo, TestMode } from "@notask/unity-cli-tools";
161
-
162
- const projectInfo: ProjectInfo = {
163
- projectPath: "/path/to/project",
164
- editorVersion: "2022.3.15f1"
165
- };
166
-
167
- const { success, output } = await UnityEditor.runTests(projectInfo, TestMode.EditMode);
168
- console.log(success ? "Tests passed" : "Tests failed", output);
169
- ```
170
-
171
- ### License Management
172
- ```typescript
173
- import { ProjectInfo } from "@notask/unity-cli-tools";
174
-
175
- const projectInfo: ProjectInfo = {
176
- projectPath: "/path/to/project",
177
- editorVersion: "2022.3.15f1"
178
- };
179
-
180
- await UnityEditor.activateLicense(projectInfo, "XXXX-XXXX-XXXX-XXXX-XXXX", "user@example.com", "password");
181
- await UnityEditor.returnLicense(projectInfo);
182
- ```
183
-
184
- ### Importing and Exporting Packages
185
- ```typescript
186
- import { ProjectInfo } from "@notask/unity-cli-tools";
187
-
188
- const projectInfo: ProjectInfo = {
189
- projectPath: "/path/to/project",
190
- editorVersion: "2022.3.15f1"
191
- };
192
-
193
- await UnityEditor.exportPackage(
194
- projectInfo,
195
- ["Assets/UI", "Assets/Scripts"],
196
- "/path/to/output/MyPackage.unitypackage"
197
- );
198
- await UnityEditor.importPackage(
199
- projectInfo,
200
- "/path/to/downloads/OtherPackage.unitypackage"
201
- );
202
- ```
203
-
204
- ### Executing Custom Editor Methods
205
- ```typescript
206
- import { ProjectInfo } from "@notask/unity-cli-tools";
207
-
208
- const projectInfo: ProjectInfo = {
209
- projectPath: "/path/to/project",
210
- editorVersion: "2022.3.15f1"
211
- };
212
-
213
- const executionResult = await UnityEditor.executeMethod(
214
- projectInfo,
215
- "MyCompany.BuildTools.PerformBuild"
216
- );
217
- console.log(executionResult);
218
- ```
219
-
220
- ## Available Constants
221
-
222
- ### UnityModules
223
-
224
- | Constant | Description |
225
- | -------------------------- | ------------------------- |
226
- | `Documentation` | Unity documentation |
227
- | `AndroidBuildSupport` | Android platform support |
228
- | `AndroidSDKNDKTools` | Android SDK/NDK tools |
229
- | `OpenJDK` | Java Development Kit |
230
- | `IOSBuildSupport` | iOS platform support |
231
- | `TvOSBuildSupport` | tvOS platform support |
232
- | `LinuxBuildSupportMono` | Linux Mono support |
233
- | `LinuxBuildSupportIL2CPP` | Linux IL2CPP support |
234
- | `WebGLBuildSupport` | WebGL platform support |
235
- | `WindowsBuildSupport` | Windows platform support |
236
- | `VuforiaAR` | Vuforia AR support |
237
- | `WindowsBuildSupportMono` | Windows Mono support |
238
- | `LuminBuildSupport` | Magic Leap support |
239
- | `VisualStudioCommunity` | Visual Studio integration |
240
- | `MacBuildSupportMono` | macOS Mono support |
241
- | `MacBuildSupportIL2CPP` | macOS IL2CPP support |
242
- | `UniversalWindowsPlatform` | UWP support |
243
- | `UWPBuildSupportIL2CPP` | UWP IL2CPP support |
244
- | `UWPBuildSupportDotNet` | UWP .NET support |
245
-
246
- ### UnityLanguages
247
-
248
- | Constant | Description |
249
- | -------------------- | --------------------------------- |
250
- | `Japanese` | Japanese language pack |
251
- | `Korean` | Korean language pack |
252
- | `ChineseSimplified` | Simplified Chinese language pack |
253
- | `ChineseTraditional` | Traditional Chinese language pack |
254
- | `Chinese` | Chinese language pack (legacy) |
255
-
256
- ### InstallerStatus
257
-
258
- | Constant | Description |
259
- | ------------------ | ------------------------------- |
260
- | `Queued` | Queued for download |
261
- | `Validating` | Validating download |
262
- | `InProgress` | Installation in progress |
263
- | `Downloading` | Downloading installation files |
264
- | `QueuedInstall` | Queued for install |
265
- | `ValidatingInstall`| Validating installation |
266
- | `Installing` | Installing |
267
- | `Verifying` | Verifying installation |
268
- | `Installed` | Installed successfully |
269
- | `Error` | Installation error |
270
-
271
- ### InstallerEventType
272
-
273
- | Constant | Description |
274
- | ------------ | ------------------------------------------- |
275
- | `Progress` | Installation progress update event |
276
- | `Error` | Installation error event |
277
- | `Completed` | Installation completed successfully event |
278
- | `Cancelled` | Installation cancelled by user event |
279
-
280
-
281
- ## Configuration
282
-
283
- ### Environment Variables
284
-
285
- - `UNITY_HUB_PATH` - Custom path to Unity Hub executable
286
-
287
- ### Platform Detection
288
-
289
- The library automatically detects and uses the correct paths for:
290
-
291
- - Windows
292
- - macOS
293
- - Linux
294
-
295
- ## Examples
296
-
297
- ### Complete Unity Hub Workflow
298
-
299
- ```typescript
300
- import { UnityHub, UnityModules } from "unity-cli-tools";
301
-
302
- async function manageUnityInstallation() {
303
- try {
304
- // Check if hub is available
305
- const isAvailable = await UnityHub.isUnityHubAvailable();
306
- if (!isAvailable) {
307
- console.error("Unity Hub not found");
308
- return;
309
- }
310
-
311
- // List installations
312
- const installations = await UnityHub.getUnityInstallations();
313
- console.log("Installed versions:", Object.keys(installations));
314
-
315
- // Install WebGL support for specific version
316
- if (installations["2022.3.60f1"]) {
317
- await UnityHub.addModule("2022.3.60f1", [UnityModules.WebGLBuildSupport]);
318
- console.log("WebGL support added");
319
- }
320
-
321
- // Get recent projects
322
- const projects = await UnityHub.getProjects();
323
- console.log(
324
- "Recent projects:",
325
- projects.map((p) => p.name)
326
- );
327
- } catch (error) {
328
- console.error("Error in Unity workflow:", error);
329
- }
330
- }
331
- ```
332
-
333
- ## Advanced Usage
334
-
335
- ### Custom Command Execution
336
-
337
- ```typescript
338
- // List all editors with detailed output
339
- const result = await UnityHub.execUnityHubCommand(["editors", "-a"], {
340
- reject: true, // Throw error on failure
341
- timeout: 30000, // 30 second timeout
342
- env: { UNITY_HUB_VERBOSE: "1" }, // Custom environment variables
343
- });
344
-
345
- // Process output
346
- const editorList = result.stdout.split("\n").filter((line) => line.includes("Unity Version"));
347
- ```
1
+ # Unity Command line Tools
2
+
3
+ A TypeScript library for programmatically interacting with Unity Hub and Unity Editor command line interfaces.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @notask/unity-cli-tools
9
+ ```
10
+
11
+ ## Dual Module Support
12
+
13
+ This package publishes separate builds for both ES Modules (ESM) and CommonJS (CJS). You can consume it either way:
14
+
15
+ **ESM** (Node and bundlers):
16
+ ```ts
17
+ import { UnityHub } from "@notask/unity-cli-tools";
18
+ ```
19
+
20
+ **CJS**:
21
+ ```js
22
+ const { UnityHub } = require("@notask/unity-cli-tools");
23
+ ```
24
+
25
+ ## Requirements
26
+
27
+ - Node.js 20+
28
+ - Unity Hub installed
29
+ - Unity Editor (for editor operations)
30
+
31
+ ## Core Concepts
32
+
33
+ Unity CLI Tools provides two main modules:
34
+
35
+ - `UnityHub` - For interacting with Unity Hub
36
+ - `UnityEditor` - For interacting with Unity Editor
37
+
38
+ ### Error Handling with Result Pattern
39
+
40
+ All operations return a `Result<T, E>` type instead of throwing exceptions. This provides:
41
+
42
+ - **Type-safe error handling** - Errors are explicit in the return type
43
+ - **Rich error context** - Each error includes error codes, messages, and contextual data
44
+ - **Composable operations** - Chain operations with `map`, `andThen`, etc.
45
+ - **No unexpected exceptions** - All errors are handled explicitly
46
+
47
+ ```typescript
48
+ import { UnityHub, isOk, isErr } from "@notask/unity-cli-tools";
49
+
50
+ const result = await UnityHub.getUnityInstallations();
51
+
52
+ if (isOk(result)) {
53
+ // Type-safe access to the value
54
+ const installations = result.value;
55
+ console.log("Installed versions:", Object.keys(installations));
56
+ } else {
57
+ // Type-safe access to the error
58
+ console.error(`Error [${result.error.code}]:`, result.error.message);
59
+ console.error("Context:", result.error.context);
60
+ }
61
+ ```
62
+
63
+ ## UnityHub API Reference
64
+
65
+ ### Checking Availability
66
+
67
+ ```typescript
68
+ import { UnityHub } from "@notask/unity-cli-tools";
69
+
70
+ // Check if Unity Hub is available
71
+ const isAvailable = await UnityHub.isUnityHubAvailable();
72
+ ```
73
+
74
+ ### Finding Unity Installations
75
+
76
+ ```typescript
77
+ import { UnityHub, isOk } from "@notask/unity-cli-tools";
78
+
79
+ // Get all installed Unity versions
80
+ const result = await UnityHub.getUnityInstallations();
81
+
82
+ if (isOk(result)) {
83
+ const installations = result.value;
84
+ // Returns: { '2022.3.60f1': 'C:/Program Files/Unity/Hub/Editor/2022.3.60f1', ... }
85
+ console.log("Installed versions:", Object.keys(installations));
86
+ } else {
87
+ console.error("Failed to get installations:", result.error.message);
88
+ }
89
+ ```
90
+
91
+ ### Managing Unity Versions
92
+
93
+ ```typescript
94
+ import { UnityHub, UnityModules, isOk } from "@notask/unity-cli-tools";
95
+
96
+ // Install a new Unity version
97
+ const result = await UnityHub.addEditor("2022.3.60f1");
98
+
99
+ if (isOk(result)) {
100
+ const installer = result.value;
101
+
102
+ // Wait for installation to complete
103
+ await installer.completed;
104
+ console.log("Installation completed!");
105
+ } else {
106
+ console.error("Failed to start installation:", result.error.message);
107
+ }
108
+
109
+ // Install with specific modules
110
+ const resultWithModules = await UnityHub.addEditor(
111
+ "2022.3.60f1",
112
+ [UnityModules.AndroidBuildSupport, UnityModules.WebGLBuildSupport]
113
+ );
114
+
115
+ // Add modules to existing installation
116
+ const moduleResult = await UnityHub.addModule(
117
+ "2022.3.60f1",
118
+ [UnityModules.IOSBuildSupport]
119
+ );
120
+
121
+ if (isOk(moduleResult)) {
122
+ console.log("Module installation started");
123
+ }
124
+ ```
125
+
126
+ ### Installation Events
127
+
128
+ ```typescript
129
+ import { UnityHub, UnityModules, InstallerEventType, isOk } from "@notask/unity-cli-tools";
130
+
131
+ // Install with event tracking
132
+ const result = await UnityHub.addEditor("2022.3.60f1");
133
+
134
+ if (!isOk(result)) {
135
+ console.error("Failed to start installation:", result.error);
136
+ return;
137
+ }
138
+
139
+ const installer = result.value;
140
+
141
+ // Listen to progress events
142
+ installer.on(InstallerEventType.Progress, (events) => {
143
+ console.log("Progress:", events.map(e => `${e.module}: ${e.status} ${e.progress || 0}%`));
144
+ });
145
+
146
+ installer.on(InstallerEventType.Error, (errorEvents) => {
147
+ console.error("Installation error:", errorEvents);
148
+ });
149
+
150
+ installer.on(InstallerEventType.Completed, (events) => {
151
+ console.log("Installation completed!");
152
+ });
153
+
154
+ // Or use the promise
155
+ try {
156
+ const completedEvents = await installer.completed;
157
+ console.log("Installation finished:", completedEvents);
158
+ } catch (error) {
159
+ console.error("Installation failed:", error);
160
+ }
161
+
162
+ // Cancel installation if needed
163
+ installer.Cancel();
164
+ ```
165
+
166
+ ### Projects Management
167
+
168
+ ```typescript
169
+ import { UnityHub, isOk } from "@notask/unity-cli-tools";
170
+
171
+ // Get projects from Unity Hub
172
+ const result = await UnityHub.getProjects();
173
+
174
+ if (isOk(result)) {
175
+ const projects = result.value;
176
+ // Returns: [{ name: 'ProjectName', path: '/path/to/project', version: '2022.3.60f1' }, ...]
177
+ console.log("Projects:", projects);
178
+ }
179
+
180
+ // Get default projects directory
181
+ const dirResult = await UnityHub.getDefaultProjectsDirectory();
182
+
183
+ if (isOk(dirResult)) {
184
+ const defaultDir = dirResult.value; // string | null
185
+ console.log("Default directory:", defaultDir);
186
+ }
187
+ ```
188
+
189
+ ### Custom Commands
190
+
191
+ ```typescript
192
+ import { UnityHub, isOk } from "@notask/unity-cli-tools";
193
+
194
+ // Execute any Hub command directly
195
+ const result = await UnityHub.execUnityHubCommand(["editors", "-r"]);
196
+
197
+ if (isOk(result)) {
198
+ console.log(result.value.stdout);
199
+ console.log("Exit code:", result.value.exitCode);
200
+ } else {
201
+ console.error("Command failed:", result.error.stderr);
202
+ }
203
+ ```
204
+
205
+ ## UnityEditor API Reference
206
+
207
+ UnityEditor provides an interface for automating tasks directly in the Unity Editor:
208
+
209
+ ### Installation and Availability
210
+
211
+ ```typescript
212
+ import { UnityEditor } from "@notask/unity-cli-tools";
213
+
214
+ // Get the executable path and verify installation
215
+ const unityPath = UnityEditor.getUnityExecutablePath("2022.3.15f1");
216
+ const isInstalled = await UnityEditor.isUnityVersionInstalled("2022.3.15f1");
217
+ console.log(`Installed: ${isInstalled}`, unityPath);
218
+ ```
219
+
220
+ ### Executing Raw Editor Commands
221
+
222
+ ```typescript
223
+ import { UnityEditor, isOk } from "@notask/unity-cli-tools";
224
+
225
+ const editorInfo = { version: "2022.3.15f1", path: unityPath };
226
+ const result = await UnityEditor.execUnityEditorCommand(
227
+ editorInfo,
228
+ ["-batchmode", "-quit", "-projectPath", "/path/to/project"]
229
+ );
230
+
231
+ if (isOk(result)) {
232
+ console.log("Command output:", result.value.stdout);
233
+ console.log("Exit code:", result.value.exitCode);
234
+ } else {
235
+ console.error("Command failed:", result.error.message);
236
+ console.error("Error output:", result.error.stderr);
237
+ }
238
+ ```
239
+
240
+ ### Creating and Opening Projects
241
+
242
+ ```typescript
243
+ import { UnityEditor, ProjectInfo, isOk } from "@notask/unity-cli-tools";
244
+
245
+ const projectInfo: ProjectInfo = {
246
+ projectName: "MyAwesomeGame",
247
+ projectPath: "/path/to/new/project",
248
+ editorVersion: "2022.3.15f1"
249
+ };
250
+
251
+ // Create project
252
+ const createResult = await UnityEditor.createProject(projectInfo);
253
+
254
+ if (isOk(createResult)) {
255
+ console.log("Project created successfully!");
256
+
257
+ // Open project
258
+ const openResult = await UnityEditor.openProject(projectInfo, true, true);
259
+
260
+ if (isOk(openResult)) {
261
+ console.log("Project opened successfully!");
262
+ }
263
+ } else {
264
+ console.error("Failed to create project:", createResult.error.message);
265
+ }
266
+ ```
267
+
268
+ ### Running Tests
269
+
270
+ ```typescript
271
+ import { UnityEditor, ProjectInfo, TestMode, isOk } from "@notask/unity-cli-tools";
272
+
273
+ const projectInfo: ProjectInfo = {
274
+ projectName: "MyGame",
275
+ projectPath: "/path/to/project",
276
+ editorVersion: "2022.3.15f1"
277
+ };
278
+
279
+ const result = await UnityEditor.runTests(projectInfo, TestMode.EditMode);
280
+
281
+ if (isOk(result)) {
282
+ console.log("All tests passed!");
283
+ console.log("Test output:", result.value);
284
+ } else {
285
+ console.error("Tests failed:", result.error.message);
286
+
287
+ // UnityTestError includes the test output
288
+ if (result.error.code === "UNITY_TEST_ERROR") {
289
+ console.error("Test output:", result.error.testOutput);
290
+ }
291
+ }
292
+ ```
293
+
294
+ ### License Management
295
+
296
+ ```typescript
297
+ import { UnityEditor, ProjectInfo, isOk } from "@notask/unity-cli-tools";
298
+
299
+ const projectInfo: ProjectInfo = {
300
+ projectName: "MyGame",
301
+ projectPath: "/path/to/project",
302
+ editorVersion: "2022.3.15f1"
303
+ };
304
+
305
+ // Activate license
306
+ const activateResult = await UnityEditor.activateLicense(
307
+ projectInfo,
308
+ "XXXX-XXXX-XXXX-XXXX-XXXX",
309
+ "user@example.com",
310
+ "password"
311
+ );
312
+
313
+ if (isOk(activateResult)) {
314
+ console.log("License activated successfully!");
315
+
316
+ // Do work...
317
+
318
+ // Return license when done
319
+ const returnResult = await UnityEditor.returnLicense(projectInfo);
320
+
321
+ if (isOk(returnResult)) {
322
+ console.log("License returned successfully!");
323
+ }
324
+ } else {
325
+ console.error("License activation failed:", activateResult.error.message);
326
+ }
327
+ ```
328
+
329
+ ### Importing and Exporting Packages
330
+
331
+ ```typescript
332
+ import { UnityEditor, ProjectInfo, isOk } from "@notask/unity-cli-tools";
333
+
334
+ const projectInfo: ProjectInfo = {
335
+ projectName: "MyGame",
336
+ projectPath: "/path/to/project",
337
+ editorVersion: "2022.3.15f1"
338
+ };
339
+
340
+ // Export package
341
+ const exportResult = await UnityEditor.exportPackage(
342
+ projectInfo,
343
+ ["Assets/UI", "Assets/Scripts"],
344
+ "/path/to/output/MyPackage.unitypackage"
345
+ );
346
+
347
+ if (isOk(exportResult)) {
348
+ console.log("Package exported successfully!");
349
+ }
350
+
351
+ // Import package
352
+ const importResult = await UnityEditor.importPackage(
353
+ projectInfo,
354
+ "/path/to/downloads/OtherPackage.unitypackage"
355
+ );
356
+
357
+ if (isOk(importResult)) {
358
+ console.log("Package imported successfully!");
359
+ }
360
+ ```
361
+
362
+ ### Executing Custom Editor Methods
363
+
364
+ ```typescript
365
+ import { UnityEditor, ProjectInfo, isOk } from "@notask/unity-cli-tools";
366
+
367
+ const projectInfo: ProjectInfo = {
368
+ projectName: "MyGame",
369
+ projectPath: "/path/to/project",
370
+ editorVersion: "2022.3.15f1"
371
+ };
372
+
373
+ const result = await UnityEditor.executeMethod(
374
+ projectInfo,
375
+ "MyCompany.BuildTools.PerformBuild"
376
+ );
377
+
378
+ if (isOk(result)) {
379
+ console.log("Method executed successfully!");
380
+ console.log("Output:", result.value.stdout);
381
+ } else {
382
+ console.error("Method execution failed:", result.error.message);
383
+ }
384
+ ```
385
+
386
+ ## Error Handling
387
+
388
+ ### Error Types
389
+
390
+ The library provides specific error types for different failure scenarios:
391
+
392
+ ```typescript
393
+ import {
394
+ UnityHubNotFoundError,
395
+ UnityEditorNotFoundError,
396
+ UnityCommandError,
397
+ UnityInstallationError,
398
+ UnityProjectError,
399
+ UnityLicenseError,
400
+ UnityPackageError,
401
+ UnityTestError,
402
+ InvalidArgumentError,
403
+ } from "@notask/unity-cli-tools";
404
+ ```
405
+
406
+ Each error includes:
407
+ - `code` - Error code for programmatic handling
408
+ - `message` - Human-readable error message
409
+ - `context` - Additional contextual information
410
+ - `stack` - Stack trace
411
+
412
+ ### Error Handling Patterns
413
+
414
+ **Basic Pattern Matching:**
415
+ ```typescript
416
+ const result = await UnityHub.getUnityInstallations();
417
+
418
+ if (result.success) {
419
+ // Handle success
420
+ const installations = result.value;
421
+ } else {
422
+ // Handle error
423
+ const error = result.error;
424
+ console.error(`[${error.code}] ${error.message}`);
425
+ }
426
+ ```
427
+
428
+ **Type Guards:**
429
+ ```typescript
430
+ import { isOk, isErr } from "@notask/unity-cli-tools";
431
+
432
+ const result = await UnityHub.getUnityInstallations();
433
+
434
+ if (isOk(result)) {
435
+ // TypeScript knows result.value exists
436
+ const installations = result.value;
437
+ }
438
+
439
+ if (isErr(result)) {
440
+ // TypeScript knows result.error exists
441
+ const error = result.error;
442
+ }
443
+ ```
444
+
445
+ **Specific Error Handling:**
446
+ ```typescript
447
+ const result = await UnityHub.getUnityInstallations();
448
+
449
+ if (!result.success) {
450
+ switch (result.error.code) {
451
+ case "UNITY_HUB_NOT_FOUND":
452
+ console.error("Please install Unity Hub");
453
+ break;
454
+ case "UNITY_INSTALLATION_ERROR":
455
+ console.error("No Unity versions found");
456
+ break;
457
+ default:
458
+ console.error("Unexpected error:", result.error.message);
459
+ }
460
+ }
461
+ ```
462
+
463
+ **Chaining Operations:**
464
+ ```typescript
465
+ import { map, andThen } from "@notask/unity-cli-tools";
466
+
467
+ const result = await UnityHub.getUnityInstallations();
468
+
469
+ // Transform the result
470
+ const versions = map(result, (installations) => Object.keys(installations));
471
+
472
+ // Chain operations
473
+ const firstVersion = andThen(result, async (installations) => {
474
+ const versions = Object.keys(installations);
475
+ if (versions.length === 0) {
476
+ return err(new UnityInstallationError("No installations found"));
477
+ }
478
+ return ok(versions[0]);
479
+ });
480
+ ```
481
+
482
+ **Unwrapping (Use with Caution):**
483
+ ```typescript
484
+ import { unwrap, unwrapOr } from "@notask/unity-cli-tools";
485
+
486
+ // Throws if result is an error
487
+ const installations = unwrap(await UnityHub.getUnityInstallations());
488
+
489
+ // Returns default value if result is an error
490
+ const installations = unwrapOr(await UnityHub.getUnityInstallations(), {});
491
+ ```
492
+
493
+ ## Available Constants
494
+
495
+ ### UnityModules
496
+
497
+ | Constant | Description |
498
+ | -------------------------- | ------------------------- |
499
+ | `Documentation` | Unity documentation |
500
+ | `AndroidBuildSupport` | Android platform support |
501
+ | `AndroidSDKNDKTools` | Android SDK/NDK tools |
502
+ | `OpenJDK` | Java Development Kit |
503
+ | `IOSBuildSupport` | iOS platform support |
504
+ | `TvOSBuildSupport` | tvOS platform support |
505
+ | `LinuxBuildSupportMono` | Linux Mono support |
506
+ | `LinuxBuildSupportIL2CPP` | Linux IL2CPP support |
507
+ | `WebGLBuildSupport` | WebGL platform support |
508
+ | `WindowsBuildSupport` | Windows platform support |
509
+ | `VuforiaAR` | Vuforia AR support |
510
+ | `WindowsBuildSupportMono` | Windows Mono support |
511
+ | `LuminBuildSupport` | Magic Leap support |
512
+ | `VisualStudioCommunity` | Visual Studio integration |
513
+ | `MacBuildSupportMono` | macOS Mono support |
514
+ | `MacBuildSupportIL2CPP` | macOS IL2CPP support |
515
+ | `UniversalWindowsPlatform` | UWP support |
516
+ | `UWPBuildSupportIL2CPP` | UWP IL2CPP support |
517
+ | `UWPBuildSupportDotNet` | UWP .NET support |
518
+
519
+ ### UnityLanguages
520
+
521
+ | Constant | Description |
522
+ | -------------------- | --------------------------------- |
523
+ | `Japanese` | Japanese language pack |
524
+ | `Korean` | Korean language pack |
525
+ | `ChineseSimplified` | Simplified Chinese language pack |
526
+ | `ChineseTraditional` | Traditional Chinese language pack |
527
+ | `Chinese` | Chinese language pack (legacy) |
528
+
529
+ ### InstallerStatus
530
+
531
+ | Constant | Description |
532
+ | ------------------ | ------------------------------- |
533
+ | `Queued` | Queued for download |
534
+ | `Validating` | Validating download |
535
+ | `InProgress` | Installation in progress |
536
+ | `Downloading` | Downloading installation files |
537
+ | `QueuedInstall` | Queued for install |
538
+ | `ValidatingInstall`| Validating installation |
539
+ | `Installing` | Installing |
540
+ | `Verifying` | Verifying installation |
541
+ | `Installed` | Installed successfully |
542
+ | `Error` | Installation error |
543
+
544
+ ### InstallerEventType
545
+
546
+ | Constant | Description |
547
+ | ------------ | ------------------------------------------- |
548
+ | `Progress` | Installation progress update event |
549
+ | `Error` | Installation error event |
550
+ | `Completed` | Installation completed successfully event |
551
+ | `Cancelled` | Installation cancelled by user event |
552
+
553
+ ### Error Codes
554
+
555
+ | Code | Description |
556
+ | --------------------------- | ------------------------------------- |
557
+ | `UNITY_HUB_NOT_FOUND` | Unity Hub executable not found |
558
+ | `UNITY_EDITOR_NOT_FOUND` | Unity Editor version not found |
559
+ | `UNITY_COMMAND_ERROR` | Command execution failed |
560
+ | `UNITY_INSTALLATION_ERROR` | Installation operation failed |
561
+ | `UNITY_PROJECT_ERROR` | Project operation failed |
562
+ | `UNITY_LICENSE_ERROR` | License operation failed |
563
+ | `UNITY_PACKAGE_ERROR` | Package operation failed |
564
+ | `UNITY_TEST_ERROR` | Tests failed |
565
+ | `INVALID_ARGUMENT` | Invalid argument provided |
566
+
567
+ ## Configuration
568
+
569
+ ### Environment Variables
570
+
571
+ - `UNITY_HUB_PATH` - Custom path to Unity Hub executable
572
+
573
+ ### Platform Detection
574
+
575
+ The library automatically detects and uses the correct paths for:
576
+
577
+ - Windows
578
+ - macOS
579
+ - Linux
580
+
581
+ ## Examples
582
+
583
+ ### Complete Unity Hub Workflow
584
+
585
+ ```typescript
586
+ import { UnityHub, UnityModules, isOk } from "@notask/unity-cli-tools";
587
+
588
+ async function manageUnityInstallation() {
589
+ // Check if hub is available
590
+ const isAvailable = await UnityHub.isUnityHubAvailable();
591
+ if (!isAvailable) {
592
+ console.error("Unity Hub not found");
593
+ return;
594
+ }
595
+
596
+ // List installations
597
+ const installsResult = await UnityHub.getUnityInstallations();
598
+
599
+ if (!isOk(installsResult)) {
600
+ console.error("Failed to get installations:", installsResult.error.message);
601
+ return;
602
+ }
603
+
604
+ const installations = installsResult.value;
605
+ console.log("Installed versions:", Object.keys(installations));
606
+
607
+ // Install WebGL support for specific version
608
+ if (installations["2022.3.60f1"]) {
609
+ const moduleResult = await UnityHub.addModule(
610
+ "2022.3.60f1",
611
+ [UnityModules.WebGLBuildSupport]
612
+ );
613
+
614
+ if (isOk(moduleResult)) {
615
+ const installer = moduleResult.value;
616
+ await installer.completed;
617
+ console.log("WebGL support added");
618
+ }
619
+ }
620
+
621
+ // Get recent projects
622
+ const projectsResult = await UnityHub.getProjects();
623
+
624
+ if (isOk(projectsResult)) {
625
+ const projects = projectsResult.value;
626
+ console.log("Recent projects:", projects.map((p) => p.name));
627
+ }
628
+ }
629
+
630
+ manageUnityInstallation().catch(console.error);
631
+ ```
632
+
633
+ ### CI/CD Pipeline Example
634
+
635
+ ```typescript
636
+ import { UnityEditor, ProjectInfo, TestMode, isOk } from "@notask/unity-cli-tools";
637
+
638
+ async function ciPipeline() {
639
+ const projectInfo: ProjectInfo = {
640
+ projectName: "MyGame",
641
+ projectPath: process.cwd(),
642
+ editorVersion: "2022.3.15f1"
643
+ };
644
+
645
+ // Activate license
646
+ const licenseResult = await UnityEditor.activateLicense(
647
+ projectInfo,
648
+ process.env.UNITY_SERIAL!,
649
+ process.env.UNITY_EMAIL!,
650
+ process.env.UNITY_PASSWORD!
651
+ );
652
+
653
+ if (!isOk(licenseResult)) {
654
+ console.error("License activation failed:", licenseResult.error.message);
655
+ process.exit(1);
656
+ }
657
+
658
+ try {
659
+ // Run tests
660
+ const testResult = await UnityEditor.runTests(projectInfo, TestMode.EditMode);
661
+
662
+ if (!isOk(testResult)) {
663
+ console.error("Tests failed:", testResult.error.message);
664
+
665
+ if (testResult.error.code === "UNITY_TEST_ERROR") {
666
+ console.error("Test output:", testResult.error.testOutput);
667
+ }
668
+
669
+ process.exit(1);
670
+ }
671
+
672
+ console.log("All tests passed!");
673
+
674
+ // Build project
675
+ const buildResult = await UnityEditor.executeMethod(
676
+ projectInfo,
677
+ "BuildScript.PerformBuild"
678
+ );
679
+
680
+ if (!isOk(buildResult)) {
681
+ console.error("Build failed:", buildResult.error.message);
682
+ process.exit(1);
683
+ }
684
+
685
+ console.log("Build completed successfully!");
686
+
687
+ } finally {
688
+ // Always return license
689
+ await UnityEditor.returnLicense(projectInfo);
690
+ }
691
+ }
692
+
693
+ ciPipeline().catch(console.error);
694
+ ```
695
+
696
+ ## Advanced Usage
697
+
698
+ ### Custom Command Execution
699
+
700
+ ```typescript
701
+ import { UnityHub, isOk } from "@notask/unity-cli-tools";
702
+
703
+ // List all editors with detailed output
704
+ const result = await UnityHub.execUnityHubCommand(["editors", "-a"], {
705
+ timeout: 30000, // 30 second timeout
706
+ env: { UNITY_HUB_VERBOSE: "1" }, // Custom environment variables
707
+ });
708
+
709
+ if (isOk(result)) {
710
+ // Process output
711
+ const editorList = result.value.stdout
712
+ .split("\n")
713
+ .filter((line) => line.includes("Unity Version"));
714
+
715
+ console.log("Editors:", editorList);
716
+ } else {
717
+ console.error("Command failed:", result.error.message);
718
+ }
719
+ ```
720
+
721
+ ### Streaming Command Output
722
+
723
+ ```typescript
724
+ import { UnityHub, isOk } from "@notask/unity-cli-tools";
725
+
726
+ const result = await UnityHub.execUnityHubCommand(["editors", "-i"], {
727
+ onStdout: (line) => {
728
+ console.log("STDOUT:", line);
729
+ },
730
+ onStderr: (line) => {
731
+ console.error("STDERR:", line);
732
+ }
733
+ });
734
+
735
+ if (isOk(result)) {
736
+ console.log("Command completed");
737
+ }
738
+ ```
739
+
740
+ ## Migration Guide
741
+
742
+ ### Migrating from Previous Versions
743
+
744
+ **Version 2.x introduces breaking changes with the Result pattern:**
745
+
746
+ **Before (v1.x):**
747
+ ```typescript
748
+ try {
749
+ const installations = await UnityHub.getUnityInstallations();
750
+ console.log(installations);
751
+ } catch (error) {
752
+ console.error(error);
753
+ }
754
+ ```
755
+
756
+ **After (v2.x):**
757
+ ```typescript
758
+ import { isOk } from "@notask/unity-cli-tools";
759
+
760
+ const result = await UnityHub.getUnityInstallations();
761
+
762
+ if (isOk(result)) {
763
+ console.log(result.value);
764
+ } else {
765
+ console.error(result.error.message);
766
+ }
767
+ ```
768
+
769
+ **Method Return Type Changes:**
770
+
771
+ | Method | Old Return Type | New Return Type |
772
+ |--------|----------------|-----------------|
773
+ | `getUnityInstallations()` | `Promise<UnityInstallations>` (throws) | `Promise<Result<UnityInstallations, Error>>` |
774
+ | `runTests()` | `Promise<{success: boolean, output: string}>` | `Promise<Result<string, UnityTestError>>` |
775
+ | `activateLicense()` | `Promise<boolean>` | `Promise<Result<void, UnityLicenseError>>` |
776
+ | `createProject()` | `Promise<boolean>` | `Promise<Result<void, UnityProjectError>>` |
777
+
778
+ ## TypeScript Support
779
+
780
+ This library is written in TypeScript and provides full type definitions:
781
+
782
+ ```typescript
783
+ import {
784
+ UnityHub,
785
+ UnityEditor,
786
+ ProjectInfo,
787
+ UnityModules,
788
+ TestMode,
789
+ Result,
790
+ UnityError,
791
+ isOk,
792
+ isErr,
793
+ } from "@notask/unity-cli-tools";
794
+
795
+ // All types are exported and fully typed
796
+ const projectInfo: ProjectInfo = {
797
+ projectName: "MyGame",
798
+ projectPath: "/path/to/project",
799
+ editorVersion: "2022.3.15f1"
800
+ };
801
+ ```
802
+
803
+ ## Contributing
804
+
805
+ Contributions are welcome! Please feel free to submit a Pull Request.
806
+
807
+ ## License
808
+
809
+ MIT License - see LICENSE file for details