@notask/unity-cli-tools 1.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.
- package/.nvmrc +0 -0
- package/.prettierrc +8 -0
- package/CHANGELOG.md +31 -0
- package/LICENSE +23 -0
- package/README.md +194 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/types/unity.d.ts +91 -0
- package/dist/types/unity.js +58 -0
- package/dist/unityHub.d.ts +26 -0
- package/dist/unityHub.js +208 -0
- package/dist/utils/commandExecutor.d.ts +14 -0
- package/dist/utils/commandExecutor.js +27 -0
- package/dist-cjs/index.js +23 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/types/unity.js +61 -0
- package/dist-cjs/unityHub.js +213 -0
- package/dist-cjs/utils/commandExecutor.js +30 -0
- package/dist-cjs.zip +0 -0
- package/dist-esm.zip +0 -0
- package/dist-tar/notask-unity-cli-tools-1.0.0.tgz +0 -0
- package/eslint.config.js +60 -0
- package/package.json +69 -0
- package/scripts/write-cjs-package.cjs +9 -0
package/.nvmrc
ADDED
|
Binary file
|
package/.prettierrc
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 1.0.0 (2025-04-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **Hub:** Renaming the 'moduleId' parameter to 'modules' ([50384f4](https://github.com/NoTaskStudios/unity-cli-tools/commit/50384f41a2c58a18e2da135ffa5ae357a6e20ca7))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **Command:** Add a command executor on top execa ([8c25801](https://github.com/NoTaskStudios/unity-cli-tools/commit/8c25801f9a866a92bc95ebed9aa556c8a5574ede))
|
|
12
|
+
* **Hub:** Add unity hub command line by code ([bffbdba](https://github.com/NoTaskStudios/unity-cli-tools/commit/bffbdbaf24bb505482ab51d47214f1e9c5e7942c))
|
|
13
|
+
* **Types:** Add unity types for hub and editor ([23a7b41](https://github.com/NoTaskStudios/unity-cli-tools/commit/23a7b4172f5d3b80876aaf043b961759cbe4274c))
|
|
14
|
+
|
|
15
|
+
# 1.0.0-rc.1 (2025-04-22)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **Hub:** Renaming the 'moduleId' parameter to 'modules' ([50384f4](https://github.com/NoTaskStudios/unity-cli-tools/commit/50384f41a2c58a18e2da135ffa5ae357a6e20ca7))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* **Command:** Add a command executor on top execa ([8c25801](https://github.com/NoTaskStudios/unity-cli-tools/commit/8c25801f9a866a92bc95ebed9aa556c8a5574ede))
|
|
26
|
+
* **Hub:** Add unity hub command line by code ([bffbdba](https://github.com/NoTaskStudios/unity-cli-tools/commit/bffbdbaf24bb505482ab51d47214f1e9c5e7942c))
|
|
27
|
+
* **Types:** Add unity types for hub and editor ([23a7b41](https://github.com/NoTaskStudios/unity-cli-tools/commit/23a7b4172f5d3b80876aaf043b961759cbe4274c))
|
|
28
|
+
|
|
29
|
+
# Changelog
|
|
30
|
+
|
|
31
|
+
All notable changes to this project will be documented in this file.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022-2025 NoTask Studios, LTD.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the
|
|
7
|
+
Software), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED AS
|
|
17
|
+
IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
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 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
|
+
### Projects Management
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// Get projects from Unity Hub
|
|
76
|
+
const projects = await UnityHub.getProjects();
|
|
77
|
+
// Returns: [{ name: 'ProjectName', path: '/path/to/project', version: '2022.3.60f1' }, ...]
|
|
78
|
+
|
|
79
|
+
// Get default projects directory
|
|
80
|
+
const defaultDir = await UnityHub.getDefaultProjectsDirectory();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Custom Commands
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// Execute any Hub command directly
|
|
87
|
+
const result = await UnityHub.execUnityHubCommand(["editors", "-r"]);
|
|
88
|
+
console.log(result.stdout);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Available Constants
|
|
92
|
+
|
|
93
|
+
### UnityModules
|
|
94
|
+
|
|
95
|
+
| Constant | Description |
|
|
96
|
+
| -------------------------- | ------------------------- |
|
|
97
|
+
| `Documentation` | Unity documentation |
|
|
98
|
+
| `AndroidBuildSupport` | Android platform support |
|
|
99
|
+
| `AndroidSDKNDKTools` | Android SDK/NDK tools |
|
|
100
|
+
| `OpenJDK` | Java Development Kit |
|
|
101
|
+
| `IOSBuildSupport` | iOS platform support |
|
|
102
|
+
| `TvOSBuildSupport` | tvOS platform support |
|
|
103
|
+
| `LinuxBuildSupportMono` | Linux Mono support |
|
|
104
|
+
| `LinuxBuildSupportIL2CPP` | Linux IL2CPP support |
|
|
105
|
+
| `WebGLBuildSupport` | WebGL platform support |
|
|
106
|
+
| `WindowsBuildSupport` | Windows platform support |
|
|
107
|
+
| `VuforiaAR` | Vuforia AR support |
|
|
108
|
+
| `WindowsBuildSupportMono` | Windows Mono support |
|
|
109
|
+
| `LuminBuildSupport` | Magic Leap support |
|
|
110
|
+
| `VisualStudioCommunity` | Visual Studio integration |
|
|
111
|
+
| `MacBuildSupportMono` | macOS Mono support |
|
|
112
|
+
| `MacBuildSupportIL2CPP` | macOS IL2CPP support |
|
|
113
|
+
| `UniversalWindowsPlatform` | UWP support |
|
|
114
|
+
| `UWPBuildSupportIL2CPP` | UWP IL2CPP support |
|
|
115
|
+
| `UWPBuildSupportDotNet` | UWP .NET support |
|
|
116
|
+
|
|
117
|
+
### UnityLanguages
|
|
118
|
+
|
|
119
|
+
| Constant | Description |
|
|
120
|
+
| -------------------- | --------------------------------- |
|
|
121
|
+
| `Japanese` | Japanese language pack |
|
|
122
|
+
| `Korean` | Korean language pack |
|
|
123
|
+
| `ChineseSimplified` | Simplified Chinese language pack |
|
|
124
|
+
| `ChineseTraditional` | Traditional Chinese language pack |
|
|
125
|
+
| `Chinese` | Chinese language pack (legacy) |
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
### Environment Variables
|
|
131
|
+
|
|
132
|
+
- `UNITY_HUB_PATH` - Custom path to Unity Hub executable
|
|
133
|
+
|
|
134
|
+
### Platform Detection
|
|
135
|
+
|
|
136
|
+
The library automatically detects and uses the correct paths for:
|
|
137
|
+
|
|
138
|
+
- Windows
|
|
139
|
+
- macOS
|
|
140
|
+
- Linux
|
|
141
|
+
|
|
142
|
+
## Examples
|
|
143
|
+
|
|
144
|
+
### Complete Unity Hub Workflow
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import { UnityHub, UnityModules } from "unity-cli-tools";
|
|
148
|
+
|
|
149
|
+
async function manageUnityInstallation() {
|
|
150
|
+
try {
|
|
151
|
+
// Check if hub is available
|
|
152
|
+
const isAvailable = await UnityHub.isUnityHubAvailable();
|
|
153
|
+
if (!isAvailable) {
|
|
154
|
+
console.error("Unity Hub not found");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// List installations
|
|
159
|
+
const installations = await UnityHub.getUnityInstallations();
|
|
160
|
+
console.log("Installed versions:", Object.keys(installations));
|
|
161
|
+
|
|
162
|
+
// Install WebGL support for specific version
|
|
163
|
+
if (installations["2022.3.60f1"]) {
|
|
164
|
+
await UnityHub.addModule("2022.3.60f1", [UnityModules.WebGLBuildSupport]);
|
|
165
|
+
console.log("WebGL support added");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Get recent projects
|
|
169
|
+
const projects = await UnityHub.getProjects();
|
|
170
|
+
console.log(
|
|
171
|
+
"Recent projects:",
|
|
172
|
+
projects.map((p) => p.name)
|
|
173
|
+
);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error("Error in Unity workflow:", error);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Advanced Usage
|
|
181
|
+
|
|
182
|
+
### Custom Command Execution
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// List all editors with detailed output
|
|
186
|
+
const result = await UnityHub.execUnityHubCommand(["editors", "-a"], {
|
|
187
|
+
reject: true, // Throw error on failure
|
|
188
|
+
timeout: 30000, // 30 second timeout
|
|
189
|
+
env: { UNITY_HUB_VERBOSE: "1" }, // Custom environment variables
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Process output
|
|
193
|
+
const editorList = result.stdout.split("\n").filter((line) => line.includes("Unity Version"));
|
|
194
|
+
```
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export type UnityEditorInfo = Record<string, string>;
|
|
2
|
+
export interface UnityHubProject {
|
|
3
|
+
title: string;
|
|
4
|
+
lastModified: number;
|
|
5
|
+
isCustomEditor: boolean;
|
|
6
|
+
path: string;
|
|
7
|
+
containingFolderPath: string;
|
|
8
|
+
version: string;
|
|
9
|
+
architecture: string;
|
|
10
|
+
changeset: string;
|
|
11
|
+
isFavorite: boolean;
|
|
12
|
+
localProjectId: string;
|
|
13
|
+
cloudEnabled: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface UnityHubProjectsList {
|
|
16
|
+
data: UnityHubProject[];
|
|
17
|
+
}
|
|
18
|
+
export declare enum UnityModules {
|
|
19
|
+
Documentation = "documentation",
|
|
20
|
+
AndroidBuildSupport = "android",
|
|
21
|
+
AndroidSDKNDKTools = "android-sdk-ndk-tools",
|
|
22
|
+
OpenJDK = "android-open-jdk",
|
|
23
|
+
IOSBuildSupport = "ios",
|
|
24
|
+
TvOSBuildSupport = "appletv",
|
|
25
|
+
LinuxBuildSupportMono = "linux-mono",
|
|
26
|
+
LinuxBuildSupportIL2CPP = "linux-il2cpp",
|
|
27
|
+
WebGLBuildSupport = "webgl",
|
|
28
|
+
WindowsBuildSupport = "windows",
|
|
29
|
+
VuforiaAR = "vuforia-ar",
|
|
30
|
+
WindowsBuildSupportMono = "windows-mono",
|
|
31
|
+
LuminBuildSupport = "lumin",
|
|
32
|
+
VisualStudioCommunity = "visualstudio",
|
|
33
|
+
MacBuildSupportMono = "mac-mono",
|
|
34
|
+
MacBuildSupportIL2CPP = "mac-il2cpp",
|
|
35
|
+
UniversalWindowsPlatform = "universal-windows-platform",
|
|
36
|
+
UWPBuildSupportIL2CPP = "uwp-il2cpp",
|
|
37
|
+
UWPBuildSupportDotNet = "uwp-.net"
|
|
38
|
+
}
|
|
39
|
+
export declare enum UnityLanguages {
|
|
40
|
+
Japanese = "language-ja",
|
|
41
|
+
Korean = "language-ko",
|
|
42
|
+
ChineseSimplified = "language-zh-hans",
|
|
43
|
+
ChineseTraditional = "language-zh-hant",
|
|
44
|
+
Chinese = "language-zh-cn"
|
|
45
|
+
}
|
|
46
|
+
export declare enum EditorArchitecture {
|
|
47
|
+
x86_64 = "x86_64",
|
|
48
|
+
arm64 = "arm64"
|
|
49
|
+
}
|
|
50
|
+
export type ModuleId = UnityModules | UnityLanguages;
|
|
51
|
+
export type UnityInstallations = Record<string, string>;
|
|
52
|
+
export interface ProjectInfo {
|
|
53
|
+
path: string;
|
|
54
|
+
editorVersion: string;
|
|
55
|
+
projectName: string;
|
|
56
|
+
scenes?: string[];
|
|
57
|
+
}
|
|
58
|
+
export interface ProjectSettings {
|
|
59
|
+
companyName?: string;
|
|
60
|
+
productName?: string;
|
|
61
|
+
bundleVersion?: string;
|
|
62
|
+
}
|
|
63
|
+
export declare enum TestMode {
|
|
64
|
+
EditMode = "editmode",
|
|
65
|
+
PlayMode = "playmode"
|
|
66
|
+
}
|
|
67
|
+
export declare enum UnityBuildTarget {
|
|
68
|
+
StandaloneOSX = "StandaloneOSX",
|
|
69
|
+
StandaloneWindows = "StandaloneWindows",
|
|
70
|
+
iOS = "iOS",
|
|
71
|
+
Android = "Android",
|
|
72
|
+
StandaloneWindows64 = "StandaloneWindows64",
|
|
73
|
+
WebGL = "WebGL",
|
|
74
|
+
WSAPlayer = "WSAPlayer",
|
|
75
|
+
StandaloneLinux64 = "StandaloneLinux64",
|
|
76
|
+
PS4 = "PS4",
|
|
77
|
+
XboxOne = "XboxOne",
|
|
78
|
+
tvOS = "tvOS",
|
|
79
|
+
Switch = "Switch",
|
|
80
|
+
LinuxHeadlessSimulation = "LinuxHeadlessSimulation",
|
|
81
|
+
PS5 = "PS5",
|
|
82
|
+
VisionOS = "VisionOS"
|
|
83
|
+
}
|
|
84
|
+
export interface ParsedVersion {
|
|
85
|
+
major: number;
|
|
86
|
+
minor: number;
|
|
87
|
+
patch: number;
|
|
88
|
+
type: string;
|
|
89
|
+
revision: number;
|
|
90
|
+
original: string;
|
|
91
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export var UnityModules;
|
|
2
|
+
(function (UnityModules) {
|
|
3
|
+
UnityModules["Documentation"] = "documentation";
|
|
4
|
+
UnityModules["AndroidBuildSupport"] = "android";
|
|
5
|
+
UnityModules["AndroidSDKNDKTools"] = "android-sdk-ndk-tools";
|
|
6
|
+
UnityModules["OpenJDK"] = "android-open-jdk";
|
|
7
|
+
UnityModules["IOSBuildSupport"] = "ios";
|
|
8
|
+
UnityModules["TvOSBuildSupport"] = "appletv";
|
|
9
|
+
UnityModules["LinuxBuildSupportMono"] = "linux-mono";
|
|
10
|
+
UnityModules["LinuxBuildSupportIL2CPP"] = "linux-il2cpp";
|
|
11
|
+
UnityModules["WebGLBuildSupport"] = "webgl";
|
|
12
|
+
UnityModules["WindowsBuildSupport"] = "windows";
|
|
13
|
+
UnityModules["VuforiaAR"] = "vuforia-ar";
|
|
14
|
+
UnityModules["WindowsBuildSupportMono"] = "windows-mono";
|
|
15
|
+
UnityModules["LuminBuildSupport"] = "lumin";
|
|
16
|
+
UnityModules["VisualStudioCommunity"] = "visualstudio";
|
|
17
|
+
UnityModules["MacBuildSupportMono"] = "mac-mono";
|
|
18
|
+
UnityModules["MacBuildSupportIL2CPP"] = "mac-il2cpp";
|
|
19
|
+
UnityModules["UniversalWindowsPlatform"] = "universal-windows-platform";
|
|
20
|
+
UnityModules["UWPBuildSupportIL2CPP"] = "uwp-il2cpp";
|
|
21
|
+
UnityModules["UWPBuildSupportDotNet"] = "uwp-.net";
|
|
22
|
+
})(UnityModules || (UnityModules = {}));
|
|
23
|
+
export var UnityLanguages;
|
|
24
|
+
(function (UnityLanguages) {
|
|
25
|
+
UnityLanguages["Japanese"] = "language-ja";
|
|
26
|
+
UnityLanguages["Korean"] = "language-ko";
|
|
27
|
+
UnityLanguages["ChineseSimplified"] = "language-zh-hans";
|
|
28
|
+
UnityLanguages["ChineseTraditional"] = "language-zh-hant";
|
|
29
|
+
UnityLanguages["Chinese"] = "language-zh-cn";
|
|
30
|
+
})(UnityLanguages || (UnityLanguages = {}));
|
|
31
|
+
export var EditorArchitecture;
|
|
32
|
+
(function (EditorArchitecture) {
|
|
33
|
+
EditorArchitecture["x86_64"] = "x86_64";
|
|
34
|
+
EditorArchitecture["arm64"] = "arm64";
|
|
35
|
+
})(EditorArchitecture || (EditorArchitecture = {}));
|
|
36
|
+
export var TestMode;
|
|
37
|
+
(function (TestMode) {
|
|
38
|
+
TestMode["EditMode"] = "editmode";
|
|
39
|
+
TestMode["PlayMode"] = "playmode";
|
|
40
|
+
})(TestMode || (TestMode = {}));
|
|
41
|
+
export var UnityBuildTarget;
|
|
42
|
+
(function (UnityBuildTarget) {
|
|
43
|
+
UnityBuildTarget["StandaloneOSX"] = "StandaloneOSX";
|
|
44
|
+
UnityBuildTarget["StandaloneWindows"] = "StandaloneWindows";
|
|
45
|
+
UnityBuildTarget["iOS"] = "iOS";
|
|
46
|
+
UnityBuildTarget["Android"] = "Android";
|
|
47
|
+
UnityBuildTarget["StandaloneWindows64"] = "StandaloneWindows64";
|
|
48
|
+
UnityBuildTarget["WebGL"] = "WebGL";
|
|
49
|
+
UnityBuildTarget["WSAPlayer"] = "WSAPlayer";
|
|
50
|
+
UnityBuildTarget["StandaloneLinux64"] = "StandaloneLinux64";
|
|
51
|
+
UnityBuildTarget["PS4"] = "PS4";
|
|
52
|
+
UnityBuildTarget["XboxOne"] = "XboxOne";
|
|
53
|
+
UnityBuildTarget["tvOS"] = "tvOS";
|
|
54
|
+
UnityBuildTarget["Switch"] = "Switch";
|
|
55
|
+
UnityBuildTarget["LinuxHeadlessSimulation"] = "LinuxHeadlessSimulation";
|
|
56
|
+
UnityBuildTarget["PS5"] = "PS5";
|
|
57
|
+
UnityBuildTarget["VisionOS"] = "VisionOS";
|
|
58
|
+
})(UnityBuildTarget || (UnityBuildTarget = {}));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EditorArchitecture, ModuleId, UnityInstallations, UnityLanguages, UnityModules } from "./types/unity.js";
|
|
2
|
+
import { CommandOptions, CommandResult } from "./utils/commandExecutor.js";
|
|
3
|
+
declare class UnityHub {
|
|
4
|
+
private static CONFIG_PATHS;
|
|
5
|
+
static readonly Modules: typeof UnityModules;
|
|
6
|
+
static readonly Languages: typeof UnityLanguages;
|
|
7
|
+
private static platform;
|
|
8
|
+
private static hubPath;
|
|
9
|
+
private static getUnityHubPath;
|
|
10
|
+
private static getProjectsPath;
|
|
11
|
+
private static getProjectDirPath;
|
|
12
|
+
static isUnityHubAvailable(): Promise<boolean>;
|
|
13
|
+
static execUnityHubCommand(args: string[], options?: CommandOptions): Promise<CommandResult>;
|
|
14
|
+
static getInstallPath(): Promise<string>;
|
|
15
|
+
static setInstallPath(path: string): Promise<void>;
|
|
16
|
+
static getUnityInstallations(): Promise<UnityInstallations>;
|
|
17
|
+
static addModule(editorVersion: string, modules: ModuleId[], childModules?: boolean): Promise<void>;
|
|
18
|
+
static addEditor(version: string, changeset?: string, modules?: ModuleId[], architecture?: EditorArchitecture): Promise<void>;
|
|
19
|
+
static getProjects(): Promise<{
|
|
20
|
+
name: string;
|
|
21
|
+
path: string;
|
|
22
|
+
version: string;
|
|
23
|
+
}[]>;
|
|
24
|
+
static getDefaultProjectsDirectory(): Promise<string | null>;
|
|
25
|
+
}
|
|
26
|
+
export default UnityHub;
|
package/dist/unityHub.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import fs from "fs-extra";
|
|
2
|
+
import os from "os";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { EditorArchitecture, UnityLanguages, UnityModules, } from "./types/unity.js";
|
|
5
|
+
import { executeCommand } from "./utils/commandExecutor.js";
|
|
6
|
+
class UnityHub {
|
|
7
|
+
static CONFIG_PATHS = {
|
|
8
|
+
win32: {
|
|
9
|
+
hub: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
|
|
10
|
+
projects: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
|
|
11
|
+
projectDir: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
|
|
12
|
+
},
|
|
13
|
+
darwin: {
|
|
14
|
+
hub: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
|
|
15
|
+
projects: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
|
|
16
|
+
projectDir: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
|
|
17
|
+
},
|
|
18
|
+
linux: {
|
|
19
|
+
hub: "/opt/UnityHub/UnityHub",
|
|
20
|
+
projects: path.join(os.homedir(), ".config", "UnityHub", "projects-v1.json"),
|
|
21
|
+
projectDir: path.join(os.homedir(), ".config", "UnityHub", "projectDir.json"),
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
static Modules = UnityModules;
|
|
25
|
+
static Languages = UnityLanguages;
|
|
26
|
+
static platform = os.platform();
|
|
27
|
+
static hubPath = this.getUnityHubPath();
|
|
28
|
+
static getUnityHubPath() {
|
|
29
|
+
const envPath = process.env.UNITY_HUB_PATH ?? "";
|
|
30
|
+
if (envPath && fs.existsSync(envPath)) {
|
|
31
|
+
return envPath;
|
|
32
|
+
}
|
|
33
|
+
return UnityHub.CONFIG_PATHS[this.platform].hub || "";
|
|
34
|
+
}
|
|
35
|
+
static getProjectsPath() {
|
|
36
|
+
return UnityHub.CONFIG_PATHS[this.platform].projects || "";
|
|
37
|
+
}
|
|
38
|
+
static getProjectDirPath() {
|
|
39
|
+
return UnityHub.CONFIG_PATHS[this.platform].projectDir || "";
|
|
40
|
+
}
|
|
41
|
+
static async isUnityHubAvailable() {
|
|
42
|
+
try {
|
|
43
|
+
if (!this.hubPath || !fs.existsSync(this.hubPath)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error("Error checking Unity Hub availability:", error);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
static async execUnityHubCommand(args, options = {}) {
|
|
56
|
+
const isAvailable = await UnityHub.isUnityHubAvailable();
|
|
57
|
+
if (!isAvailable) {
|
|
58
|
+
console.error("Unity Hub is not available.");
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
stdout: "",
|
|
62
|
+
stderr: "Unity Hub is not available.",
|
|
63
|
+
exitCode: -1,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const hubArgs = [this.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
|
|
68
|
+
console.debug(`Executing Unity Hub command: ${this.hubPath} ${hubArgs.join(" ")}`);
|
|
69
|
+
return await executeCommand(this.hubPath, hubArgs, options);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error("Error executing Unity Hub command:", error);
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
stdout: "",
|
|
76
|
+
stderr: String(error),
|
|
77
|
+
exitCode: -1,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
static async getInstallPath() {
|
|
82
|
+
const { stdout, stderr } = await this.execUnityHubCommand(["install-path", "-g"], {
|
|
83
|
+
reject: false,
|
|
84
|
+
});
|
|
85
|
+
if (stderr) {
|
|
86
|
+
throw new Error(`Error getting install path: ${stderr}`);
|
|
87
|
+
}
|
|
88
|
+
return stdout;
|
|
89
|
+
}
|
|
90
|
+
static async setInstallPath(path) {
|
|
91
|
+
const { stdout, stderr } = await this.execUnityHubCommand(["install-path", "-s", path], {
|
|
92
|
+
reject: false,
|
|
93
|
+
});
|
|
94
|
+
if (stderr) {
|
|
95
|
+
throw new Error(`Error setting install path: ${stderr}`);
|
|
96
|
+
}
|
|
97
|
+
console.debug(`Install path set to: ${stdout}`);
|
|
98
|
+
}
|
|
99
|
+
static async getUnityInstallations() {
|
|
100
|
+
const { stdout, stderr } = await this.execUnityHubCommand(["editors", "-i"], {
|
|
101
|
+
reject: false,
|
|
102
|
+
});
|
|
103
|
+
const isSuccess = stdout.includes(", installed at");
|
|
104
|
+
if (stderr)
|
|
105
|
+
throw new Error(`Get installations command warning/error: ${stderr}`);
|
|
106
|
+
if (!isSuccess)
|
|
107
|
+
throw new Error(`Consider install a Unity version using Unity Hub.`);
|
|
108
|
+
const lines = stdout.split(/\r\n|\n/);
|
|
109
|
+
const installations = {};
|
|
110
|
+
lines.forEach((line) => {
|
|
111
|
+
const [version, unityPath] = line.split(", installed at").map((entry) => entry.trim());
|
|
112
|
+
installations[version] = unityPath;
|
|
113
|
+
});
|
|
114
|
+
if (Object.keys(installations).length <= 0)
|
|
115
|
+
throw new Error("No unity installations found.");
|
|
116
|
+
return installations;
|
|
117
|
+
}
|
|
118
|
+
static async addModule(editorVersion, modules, childModules = false) {
|
|
119
|
+
try {
|
|
120
|
+
console.debug(`Adding module ${modules} to Unity ${editorVersion}`);
|
|
121
|
+
const args = ["install-modules", "-v", editorVersion];
|
|
122
|
+
if (modules.length > 0) {
|
|
123
|
+
args.push("--module");
|
|
124
|
+
args.push(modules.join(" "));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
throw new Error("No module IDs provided.");
|
|
128
|
+
}
|
|
129
|
+
if (childModules) {
|
|
130
|
+
args.push("--child-modules");
|
|
131
|
+
}
|
|
132
|
+
const { stdout, stderr } = await this.execUnityHubCommand(args, {
|
|
133
|
+
reject: false,
|
|
134
|
+
});
|
|
135
|
+
console.debug(`Add module command output: ${stdout}`);
|
|
136
|
+
if (stderr) {
|
|
137
|
+
console.warn(`Add module command warning/error: ${stderr}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
static async addEditor(version, changeset, modules = [], architecture = EditorArchitecture.x86_64) {
|
|
146
|
+
try {
|
|
147
|
+
console.debug(`Installing Unity ${version} ${(changeset ?? "") ? `(changeset: ${changeset})` : ""}`);
|
|
148
|
+
const args = ["install", "-v", version];
|
|
149
|
+
if (changeset) {
|
|
150
|
+
args.push("--changeset", changeset);
|
|
151
|
+
}
|
|
152
|
+
if (modules.length > 0) {
|
|
153
|
+
args.push("--module");
|
|
154
|
+
args.push(modules.join(" "));
|
|
155
|
+
}
|
|
156
|
+
if (this.platform === "darwin") {
|
|
157
|
+
args.push("--architecture", architecture);
|
|
158
|
+
}
|
|
159
|
+
const { stdout, stderr } = await this.execUnityHubCommand(args, {
|
|
160
|
+
reject: false,
|
|
161
|
+
});
|
|
162
|
+
if (stderr) {
|
|
163
|
+
throw new Error(`Error installing Unity ${version}: ${stderr}`);
|
|
164
|
+
}
|
|
165
|
+
console.log(`Unity ${version}. ${stdout}`);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
console.error(error);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
static async getProjects() {
|
|
173
|
+
try {
|
|
174
|
+
const projectsPath = this.getProjectsPath();
|
|
175
|
+
if (!projectsPath || !fs.existsSync(projectsPath)) {
|
|
176
|
+
console.debug(`Projects file not found at: ${projectsPath}`);
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
const projectsData = await fs.readJson(projectsPath);
|
|
180
|
+
const projects = Object.values(projectsData.data);
|
|
181
|
+
return projects.map((project) => ({
|
|
182
|
+
name: project.title,
|
|
183
|
+
path: project.path,
|
|
184
|
+
version: project.version,
|
|
185
|
+
}));
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
console.error("Error getting recent projects:", error);
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
static async getDefaultProjectsDirectory() {
|
|
193
|
+
try {
|
|
194
|
+
const projectDirPath = this.getProjectDirPath();
|
|
195
|
+
if (!projectDirPath || !fs.existsSync(projectDirPath)) {
|
|
196
|
+
console.debug(`Project directory file not found at: ${projectDirPath}`);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
const projectDirData = await fs.readJson(projectDirPath);
|
|
200
|
+
return projectDirData.directoryPath ?? null;
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
console.error("Error getting default project directory:", error);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
export default UnityHub;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Options } from "execa";
|
|
2
|
+
export interface CommandOptions extends Options {
|
|
3
|
+
reject?: boolean;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
env?: Record<string, string>;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CommandResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
exitCode?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function executeCommand(executable: string, args: string[], options?: CommandOptions): Promise<CommandResult>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
export async function executeCommand(executable, args, options = {}) {
|
|
3
|
+
try {
|
|
4
|
+
const subprocess = execa(executable, args, {
|
|
5
|
+
reject: options.reject ?? false,
|
|
6
|
+
timeout: options.timeout,
|
|
7
|
+
env: options.env,
|
|
8
|
+
cwd: options.cwd,
|
|
9
|
+
encoding: "utf8",
|
|
10
|
+
});
|
|
11
|
+
const { stdout, stderr, exitCode } = await subprocess;
|
|
12
|
+
return {
|
|
13
|
+
success: true,
|
|
14
|
+
stdout,
|
|
15
|
+
stderr,
|
|
16
|
+
exitCode,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return {
|
|
21
|
+
success: false,
|
|
22
|
+
stdout: error.stdout ?? "",
|
|
23
|
+
stderr: error.stderr ?? String(error),
|
|
24
|
+
exitCode: error.exitCode,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.UnityHub = void 0;
|
|
21
|
+
var unityHub_ts_1 = require("./unityHub.js");
|
|
22
|
+
Object.defineProperty(exports, "UnityHub", { enumerable: true, get: function () { return __importDefault(unityHub_ts_1).default; } });
|
|
23
|
+
__exportStar(require("./types/unity.js"), exports);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnityBuildTarget = exports.TestMode = exports.EditorArchitecture = exports.UnityLanguages = exports.UnityModules = void 0;
|
|
4
|
+
var UnityModules;
|
|
5
|
+
(function (UnityModules) {
|
|
6
|
+
UnityModules["Documentation"] = "documentation";
|
|
7
|
+
UnityModules["AndroidBuildSupport"] = "android";
|
|
8
|
+
UnityModules["AndroidSDKNDKTools"] = "android-sdk-ndk-tools";
|
|
9
|
+
UnityModules["OpenJDK"] = "android-open-jdk";
|
|
10
|
+
UnityModules["IOSBuildSupport"] = "ios";
|
|
11
|
+
UnityModules["TvOSBuildSupport"] = "appletv";
|
|
12
|
+
UnityModules["LinuxBuildSupportMono"] = "linux-mono";
|
|
13
|
+
UnityModules["LinuxBuildSupportIL2CPP"] = "linux-il2cpp";
|
|
14
|
+
UnityModules["WebGLBuildSupport"] = "webgl";
|
|
15
|
+
UnityModules["WindowsBuildSupport"] = "windows";
|
|
16
|
+
UnityModules["VuforiaAR"] = "vuforia-ar";
|
|
17
|
+
UnityModules["WindowsBuildSupportMono"] = "windows-mono";
|
|
18
|
+
UnityModules["LuminBuildSupport"] = "lumin";
|
|
19
|
+
UnityModules["VisualStudioCommunity"] = "visualstudio";
|
|
20
|
+
UnityModules["MacBuildSupportMono"] = "mac-mono";
|
|
21
|
+
UnityModules["MacBuildSupportIL2CPP"] = "mac-il2cpp";
|
|
22
|
+
UnityModules["UniversalWindowsPlatform"] = "universal-windows-platform";
|
|
23
|
+
UnityModules["UWPBuildSupportIL2CPP"] = "uwp-il2cpp";
|
|
24
|
+
UnityModules["UWPBuildSupportDotNet"] = "uwp-.net";
|
|
25
|
+
})(UnityModules || (exports.UnityModules = UnityModules = {}));
|
|
26
|
+
var UnityLanguages;
|
|
27
|
+
(function (UnityLanguages) {
|
|
28
|
+
UnityLanguages["Japanese"] = "language-ja";
|
|
29
|
+
UnityLanguages["Korean"] = "language-ko";
|
|
30
|
+
UnityLanguages["ChineseSimplified"] = "language-zh-hans";
|
|
31
|
+
UnityLanguages["ChineseTraditional"] = "language-zh-hant";
|
|
32
|
+
UnityLanguages["Chinese"] = "language-zh-cn";
|
|
33
|
+
})(UnityLanguages || (exports.UnityLanguages = UnityLanguages = {}));
|
|
34
|
+
var EditorArchitecture;
|
|
35
|
+
(function (EditorArchitecture) {
|
|
36
|
+
EditorArchitecture["x86_64"] = "x86_64";
|
|
37
|
+
EditorArchitecture["arm64"] = "arm64";
|
|
38
|
+
})(EditorArchitecture || (exports.EditorArchitecture = EditorArchitecture = {}));
|
|
39
|
+
var TestMode;
|
|
40
|
+
(function (TestMode) {
|
|
41
|
+
TestMode["EditMode"] = "editmode";
|
|
42
|
+
TestMode["PlayMode"] = "playmode";
|
|
43
|
+
})(TestMode || (exports.TestMode = TestMode = {}));
|
|
44
|
+
var UnityBuildTarget;
|
|
45
|
+
(function (UnityBuildTarget) {
|
|
46
|
+
UnityBuildTarget["StandaloneOSX"] = "StandaloneOSX";
|
|
47
|
+
UnityBuildTarget["StandaloneWindows"] = "StandaloneWindows";
|
|
48
|
+
UnityBuildTarget["iOS"] = "iOS";
|
|
49
|
+
UnityBuildTarget["Android"] = "Android";
|
|
50
|
+
UnityBuildTarget["StandaloneWindows64"] = "StandaloneWindows64";
|
|
51
|
+
UnityBuildTarget["WebGL"] = "WebGL";
|
|
52
|
+
UnityBuildTarget["WSAPlayer"] = "WSAPlayer";
|
|
53
|
+
UnityBuildTarget["StandaloneLinux64"] = "StandaloneLinux64";
|
|
54
|
+
UnityBuildTarget["PS4"] = "PS4";
|
|
55
|
+
UnityBuildTarget["XboxOne"] = "XboxOne";
|
|
56
|
+
UnityBuildTarget["tvOS"] = "tvOS";
|
|
57
|
+
UnityBuildTarget["Switch"] = "Switch";
|
|
58
|
+
UnityBuildTarget["LinuxHeadlessSimulation"] = "LinuxHeadlessSimulation";
|
|
59
|
+
UnityBuildTarget["PS5"] = "PS5";
|
|
60
|
+
UnityBuildTarget["VisionOS"] = "VisionOS";
|
|
61
|
+
})(UnityBuildTarget || (exports.UnityBuildTarget = UnityBuildTarget = {}));
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
7
|
+
const os_1 = __importDefault(require("os"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const unity_js_1 = require("./types/unity.js");
|
|
10
|
+
const commandExecutor_js_1 = require("./utils/commandExecutor.js");
|
|
11
|
+
class UnityHub {
|
|
12
|
+
static CONFIG_PATHS = {
|
|
13
|
+
win32: {
|
|
14
|
+
hub: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
|
|
15
|
+
projects: path_1.default.join(os_1.default.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
|
|
16
|
+
projectDir: path_1.default.join(os_1.default.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
|
|
17
|
+
},
|
|
18
|
+
darwin: {
|
|
19
|
+
hub: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
|
|
20
|
+
projects: path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
|
|
21
|
+
projectDir: path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
|
|
22
|
+
},
|
|
23
|
+
linux: {
|
|
24
|
+
hub: "/opt/UnityHub/UnityHub",
|
|
25
|
+
projects: path_1.default.join(os_1.default.homedir(), ".config", "UnityHub", "projects-v1.json"),
|
|
26
|
+
projectDir: path_1.default.join(os_1.default.homedir(), ".config", "UnityHub", "projectDir.json"),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
static Modules = unity_js_1.UnityModules;
|
|
30
|
+
static Languages = unity_js_1.UnityLanguages;
|
|
31
|
+
static platform = os_1.default.platform();
|
|
32
|
+
static hubPath = this.getUnityHubPath();
|
|
33
|
+
static getUnityHubPath() {
|
|
34
|
+
const envPath = process.env.UNITY_HUB_PATH ?? "";
|
|
35
|
+
if (envPath && fs_extra_1.default.existsSync(envPath)) {
|
|
36
|
+
return envPath;
|
|
37
|
+
}
|
|
38
|
+
return UnityHub.CONFIG_PATHS[this.platform].hub || "";
|
|
39
|
+
}
|
|
40
|
+
static getProjectsPath() {
|
|
41
|
+
return UnityHub.CONFIG_PATHS[this.platform].projects || "";
|
|
42
|
+
}
|
|
43
|
+
static getProjectDirPath() {
|
|
44
|
+
return UnityHub.CONFIG_PATHS[this.platform].projectDir || "";
|
|
45
|
+
}
|
|
46
|
+
static async isUnityHubAvailable() {
|
|
47
|
+
try {
|
|
48
|
+
if (!this.hubPath || !fs_extra_1.default.existsSync(this.hubPath)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error("Error checking Unity Hub availability:", error);
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
static async execUnityHubCommand(args, options = {}) {
|
|
61
|
+
const isAvailable = await UnityHub.isUnityHubAvailable();
|
|
62
|
+
if (!isAvailable) {
|
|
63
|
+
console.error("Unity Hub is not available.");
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
stdout: "",
|
|
67
|
+
stderr: "Unity Hub is not available.",
|
|
68
|
+
exitCode: -1,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const hubArgs = [this.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
|
|
73
|
+
console.debug(`Executing Unity Hub command: ${this.hubPath} ${hubArgs.join(" ")}`);
|
|
74
|
+
return await (0, commandExecutor_js_1.executeCommand)(this.hubPath, hubArgs, options);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error("Error executing Unity Hub command:", error);
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
stdout: "",
|
|
81
|
+
stderr: String(error),
|
|
82
|
+
exitCode: -1,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
static async getInstallPath() {
|
|
87
|
+
const { stdout, stderr } = await this.execUnityHubCommand(["install-path", "-g"], {
|
|
88
|
+
reject: false,
|
|
89
|
+
});
|
|
90
|
+
if (stderr) {
|
|
91
|
+
throw new Error(`Error getting install path: ${stderr}`);
|
|
92
|
+
}
|
|
93
|
+
return stdout;
|
|
94
|
+
}
|
|
95
|
+
static async setInstallPath(path) {
|
|
96
|
+
const { stdout, stderr } = await this.execUnityHubCommand(["install-path", "-s", path], {
|
|
97
|
+
reject: false,
|
|
98
|
+
});
|
|
99
|
+
if (stderr) {
|
|
100
|
+
throw new Error(`Error setting install path: ${stderr}`);
|
|
101
|
+
}
|
|
102
|
+
console.debug(`Install path set to: ${stdout}`);
|
|
103
|
+
}
|
|
104
|
+
static async getUnityInstallations() {
|
|
105
|
+
const { stdout, stderr } = await this.execUnityHubCommand(["editors", "-i"], {
|
|
106
|
+
reject: false,
|
|
107
|
+
});
|
|
108
|
+
const isSuccess = stdout.includes(", installed at");
|
|
109
|
+
if (stderr)
|
|
110
|
+
throw new Error(`Get installations command warning/error: ${stderr}`);
|
|
111
|
+
if (!isSuccess)
|
|
112
|
+
throw new Error(`Consider install a Unity version using Unity Hub.`);
|
|
113
|
+
const lines = stdout.split(/\r\n|\n/);
|
|
114
|
+
const installations = {};
|
|
115
|
+
lines.forEach((line) => {
|
|
116
|
+
const [version, unityPath] = line.split(", installed at").map((entry) => entry.trim());
|
|
117
|
+
installations[version] = unityPath;
|
|
118
|
+
});
|
|
119
|
+
if (Object.keys(installations).length <= 0)
|
|
120
|
+
throw new Error("No unity installations found.");
|
|
121
|
+
return installations;
|
|
122
|
+
}
|
|
123
|
+
static async addModule(editorVersion, modules, childModules = false) {
|
|
124
|
+
try {
|
|
125
|
+
console.debug(`Adding module ${modules} to Unity ${editorVersion}`);
|
|
126
|
+
const args = ["install-modules", "-v", editorVersion];
|
|
127
|
+
if (modules.length > 0) {
|
|
128
|
+
args.push("--module");
|
|
129
|
+
args.push(modules.join(" "));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
throw new Error("No module IDs provided.");
|
|
133
|
+
}
|
|
134
|
+
if (childModules) {
|
|
135
|
+
args.push("--child-modules");
|
|
136
|
+
}
|
|
137
|
+
const { stdout, stderr } = await this.execUnityHubCommand(args, {
|
|
138
|
+
reject: false,
|
|
139
|
+
});
|
|
140
|
+
console.debug(`Add module command output: ${stdout}`);
|
|
141
|
+
if (stderr) {
|
|
142
|
+
console.warn(`Add module command warning/error: ${stderr}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
static async addEditor(version, changeset, modules = [], architecture = unity_js_1.EditorArchitecture.x86_64) {
|
|
151
|
+
try {
|
|
152
|
+
console.debug(`Installing Unity ${version} ${(changeset ?? "") ? `(changeset: ${changeset})` : ""}`);
|
|
153
|
+
const args = ["install", "-v", version];
|
|
154
|
+
if (changeset) {
|
|
155
|
+
args.push("--changeset", changeset);
|
|
156
|
+
}
|
|
157
|
+
if (modules.length > 0) {
|
|
158
|
+
args.push("--module");
|
|
159
|
+
args.push(modules.join(" "));
|
|
160
|
+
}
|
|
161
|
+
if (this.platform === "darwin") {
|
|
162
|
+
args.push("--architecture", architecture);
|
|
163
|
+
}
|
|
164
|
+
const { stdout, stderr } = await this.execUnityHubCommand(args, {
|
|
165
|
+
reject: false,
|
|
166
|
+
});
|
|
167
|
+
if (stderr) {
|
|
168
|
+
throw new Error(`Error installing Unity ${version}: ${stderr}`);
|
|
169
|
+
}
|
|
170
|
+
console.log(`Unity ${version}. ${stdout}`);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error(error);
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
static async getProjects() {
|
|
178
|
+
try {
|
|
179
|
+
const projectsPath = this.getProjectsPath();
|
|
180
|
+
if (!projectsPath || !fs_extra_1.default.existsSync(projectsPath)) {
|
|
181
|
+
console.debug(`Projects file not found at: ${projectsPath}`);
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
const projectsData = await fs_extra_1.default.readJson(projectsPath);
|
|
185
|
+
const projects = Object.values(projectsData.data);
|
|
186
|
+
return projects.map((project) => ({
|
|
187
|
+
name: project.title,
|
|
188
|
+
path: project.path,
|
|
189
|
+
version: project.version,
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.error("Error getting recent projects:", error);
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
static async getDefaultProjectsDirectory() {
|
|
198
|
+
try {
|
|
199
|
+
const projectDirPath = this.getProjectDirPath();
|
|
200
|
+
if (!projectDirPath || !fs_extra_1.default.existsSync(projectDirPath)) {
|
|
201
|
+
console.debug(`Project directory file not found at: ${projectDirPath}`);
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
const projectDirData = await fs_extra_1.default.readJson(projectDirPath);
|
|
205
|
+
return projectDirData.directoryPath ?? null;
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error("Error getting default project directory:", error);
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
exports.default = UnityHub;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.executeCommand = executeCommand;
|
|
4
|
+
const execa_1 = require("execa");
|
|
5
|
+
async function executeCommand(executable, args, options = {}) {
|
|
6
|
+
try {
|
|
7
|
+
const subprocess = (0, execa_1.execa)(executable, args, {
|
|
8
|
+
reject: options.reject ?? false,
|
|
9
|
+
timeout: options.timeout,
|
|
10
|
+
env: options.env,
|
|
11
|
+
cwd: options.cwd,
|
|
12
|
+
encoding: "utf8",
|
|
13
|
+
});
|
|
14
|
+
const { stdout, stderr, exitCode } = await subprocess;
|
|
15
|
+
return {
|
|
16
|
+
success: true,
|
|
17
|
+
stdout,
|
|
18
|
+
stderr,
|
|
19
|
+
exitCode,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
return {
|
|
24
|
+
success: false,
|
|
25
|
+
stdout: error.stdout ?? "",
|
|
26
|
+
stderr: error.stderr ?? String(error),
|
|
27
|
+
exitCode: error.exitCode,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
package/dist-cjs.zip
ADDED
|
Binary file
|
package/dist-esm.zip
ADDED
|
Binary file
|
|
Binary file
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import tseslint from "typescript-eslint";
|
|
3
|
+
import { defineConfig } from "eslint/config";
|
|
4
|
+
|
|
5
|
+
export default defineConfig([
|
|
6
|
+
{
|
|
7
|
+
files: ["**/*.{js,mjs,cjs,ts}"],
|
|
8
|
+
plugins: { js },
|
|
9
|
+
extends: ["js/recommended"],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
files: ["**/*.{js,mjs,cjs,ts}"],
|
|
13
|
+
},
|
|
14
|
+
...tseslint.configs.recommended,
|
|
15
|
+
{
|
|
16
|
+
files: ["**/*.ts"],
|
|
17
|
+
languageOptions: {
|
|
18
|
+
parser: tseslint.parser,
|
|
19
|
+
parserOptions: {
|
|
20
|
+
project: "./tsconfig.json",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
plugins: {
|
|
24
|
+
"@typescript-eslint": tseslint.plugin,
|
|
25
|
+
},
|
|
26
|
+
rules: {
|
|
27
|
+
// Disable JS rule and enable TS equivalent
|
|
28
|
+
"no-unused-vars": "off",
|
|
29
|
+
"@typescript-eslint/no-unused-vars": "warn",
|
|
30
|
+
|
|
31
|
+
// Typed linting rules
|
|
32
|
+
"@typescript-eslint/explicit-function-return-type": "error",
|
|
33
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
34
|
+
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
35
|
+
"@typescript-eslint/no-floating-promises": "error",
|
|
36
|
+
"@typescript-eslint/prefer-nullish-coalescing": "error",
|
|
37
|
+
"@typescript-eslint/prefer-optional-chain": "error",
|
|
38
|
+
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
39
|
+
"@typescript-eslint/no-unnecessary-condition": "warn",
|
|
40
|
+
"@typescript-eslint/prefer-ts-expect-error": "error",
|
|
41
|
+
"@typescript-eslint/ban-ts-comment": ["error", { "ts-expect-error": "allow-with-description" }],
|
|
42
|
+
|
|
43
|
+
// Code style
|
|
44
|
+
"@typescript-eslint/consistent-type-definitions": ["error", "interface"],
|
|
45
|
+
"@typescript-eslint/consistent-type-assertions": "error",
|
|
46
|
+
"@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "explicit" }],
|
|
47
|
+
"@typescript-eslint/no-non-null-assertion": "error",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
files: ["eslint.config.js"],
|
|
52
|
+
rules: {
|
|
53
|
+
"@typescript-eslint/explicit-function-return-type": "off",
|
|
54
|
+
"@typescript-eslint/strict-boolean-expressions": "off",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
ignores: ["node_modules", "dist", "dist-cjs", "**/*.cjs"],
|
|
59
|
+
},
|
|
60
|
+
]);
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@notask/unity-cli-tools",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist-cjs/index.js",
|
|
5
|
+
"module": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist-cjs/index.js",
|
|
12
|
+
"types": "./dist/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 dist-cjs",
|
|
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
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@eslint/js": "9.24.0",
|
|
51
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
52
|
+
"@semantic-release/git": "^10.0.1",
|
|
53
|
+
"@semantic-release/npm": "^12.0.1",
|
|
54
|
+
"@types/fs-extra": "^11.0.4",
|
|
55
|
+
"@types/jest": "^29.5.14",
|
|
56
|
+
"@types/node": "^22.13.14",
|
|
57
|
+
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
|
58
|
+
"@typescript-eslint/parser": "^8.30.1",
|
|
59
|
+
"eslint": "9.24.0",
|
|
60
|
+
"jest": "^29.7.0",
|
|
61
|
+
"prettier": "^3.5.3",
|
|
62
|
+
"rimraf": "6.0.1",
|
|
63
|
+
"semantic-release": "^24.2.3",
|
|
64
|
+
"ts-jest": "^29.3.1",
|
|
65
|
+
"tsx": "4.19.3",
|
|
66
|
+
"typescript": "^5.8.3",
|
|
67
|
+
"typescript-eslint": "8.30.1"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const outDir = path.resolve(__dirname, "..", "dist-cjs");
|
|
6
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
7
|
+
|
|
8
|
+
const pkg = { type: "commonjs" };
|
|
9
|
+
fs.writeFileSync(path.join(outDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|