@notask/unity-cli-tools 1.1.2 → 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.
- package/.claude/settings.local.json +7 -0
- package/CHANGELOG.md +164 -146
- package/LICENSE +23 -23
- package/README.md +809 -347
- package/dist/cjs/errors/Result.js +76 -0
- package/dist/cjs/errors/UnityError.js +77 -0
- package/dist/cjs/errors/index.js +18 -0
- package/dist/cjs/events/hubEventEmitter.js +16 -16
- package/dist/cjs/events/hubEventParser.js +97 -27
- package/dist/cjs/events/patterns/implementations/bracketModulePattern.js +57 -0
- package/dist/cjs/events/patterns/implementations/errorPattern.js +99 -0
- package/dist/cjs/events/patterns/implementations/fallbackPattern.js +63 -0
- package/dist/cjs/events/patterns/implementations/index.js +9 -0
- package/dist/cjs/events/patterns/index.js +23 -0
- package/dist/cjs/events/patterns/patternRegistry.js +69 -0
- package/dist/cjs/events/patterns/statusNormalizer.js +280 -0
- package/dist/cjs/events/patterns/types.js +2 -0
- package/dist/cjs/index.js +7 -6
- package/dist/cjs/unityEditor.js +162 -194
- package/dist/cjs/unityHub.js +82 -78
- package/dist/cjs/utils/commandExecutor.js +8 -9
- package/dist/esm/errors/Result.d.ts +21 -0
- package/dist/esm/errors/Result.js +63 -0
- package/dist/esm/errors/UnityError.d.ts +36 -0
- package/dist/esm/errors/UnityError.js +64 -0
- package/dist/esm/errors/index.d.ts +2 -0
- package/dist/esm/errors/index.js +2 -0
- package/dist/esm/events/hubEventEmitter.d.ts +1 -1
- package/dist/esm/events/hubEventParser.d.ts +17 -3
- package/dist/esm/events/hubEventParser.js +97 -27
- package/dist/esm/events/patterns/implementations/bracketModulePattern.d.ts +11 -0
- package/dist/esm/events/patterns/implementations/bracketModulePattern.js +53 -0
- package/dist/esm/events/patterns/implementations/errorPattern.d.ts +22 -0
- package/dist/esm/events/patterns/implementations/errorPattern.js +95 -0
- package/dist/esm/events/patterns/implementations/fallbackPattern.d.ts +13 -0
- package/dist/esm/events/patterns/implementations/fallbackPattern.js +59 -0
- package/dist/esm/events/patterns/implementations/index.d.ts +3 -0
- package/dist/esm/events/patterns/implementations/index.js +3 -0
- package/dist/esm/events/patterns/index.d.ts +4 -0
- package/dist/esm/events/patterns/index.js +4 -0
- package/dist/esm/events/patterns/patternRegistry.d.ts +14 -0
- package/dist/esm/events/patterns/patternRegistry.js +65 -0
- package/dist/esm/events/patterns/statusNormalizer.d.ts +15 -0
- package/dist/esm/events/patterns/statusNormalizer.js +276 -0
- package/dist/esm/events/patterns/types.d.ts +30 -0
- package/dist/esm/events/patterns/types.js +1 -0
- package/dist/esm/index.d.ts +5 -4
- package/dist/esm/index.js +1 -0
- package/dist/esm/unityEditor.d.ts +11 -13
- package/dist/esm/unityEditor.js +175 -207
- package/dist/esm/unityHub.d.ts +12 -11
- package/dist/esm/unityHub.js +80 -76
- package/dist/esm/utils/commandExecutor.d.ts +4 -3
- package/dist/esm/utils/commandExecutor.js +8 -9
- package/package.json +70 -70
- package/sandbox/index.js +51 -0
- package/sandbox/node_modules/.package-lock.json +10495 -0
- package/sandbox/package.json +13 -0
package/dist/cjs/unityHub.js
CHANGED
|
@@ -9,7 +9,8 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const unity_js_1 = require("./types/unity.js");
|
|
10
10
|
const commandExecutor_js_1 = require("./utils/commandExecutor.js");
|
|
11
11
|
const unity_changeset_1 = require("unity-changeset");
|
|
12
|
-
const
|
|
12
|
+
const hubEventEmitter_js_1 = require("./events/hubEventEmitter.js");
|
|
13
|
+
const index_js_1 = require("./errors/index.js");
|
|
13
14
|
class UnityHub {
|
|
14
15
|
static CONFIG_PATHS = {
|
|
15
16
|
win32: {
|
|
@@ -56,122 +57,124 @@ class UnityHub {
|
|
|
56
57
|
const isAvailable = await UnityHub.isUnityHubAvailable();
|
|
57
58
|
if (!isAvailable) {
|
|
58
59
|
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 (0, commandExecutor_js_1.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
|
-
};
|
|
60
|
+
return (0, index_js_1.err)(new index_js_1.UnityHubNotFoundError("Unity Hub is not available", { hubPath: this.hubPath }));
|
|
79
61
|
}
|
|
62
|
+
const hubArgs = [this.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
|
|
63
|
+
console.debug(`Executing Unity Hub command: ${this.hubPath} ${hubArgs.join(" ")}`);
|
|
64
|
+
return await (0, commandExecutor_js_1.executeCommand)(this.hubPath, hubArgs, options);
|
|
80
65
|
}
|
|
81
66
|
static async getInstallPath() {
|
|
82
|
-
const
|
|
67
|
+
const result = await this.execUnityHubCommand(["install-path", "-g"], {
|
|
83
68
|
reject: false,
|
|
84
69
|
});
|
|
85
|
-
if (
|
|
86
|
-
|
|
70
|
+
if (!result.success) {
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
if (result.value.stderr) {
|
|
74
|
+
return (0, index_js_1.err)(new index_js_1.UnityCommandError(`Error getting install path: ${result.value.stderr}`, result.value.stdout, result.value.stderr, result.value.exitCode));
|
|
87
75
|
}
|
|
88
|
-
return stdout;
|
|
76
|
+
return (0, index_js_1.ok)(result.value.stdout.trim());
|
|
89
77
|
}
|
|
90
78
|
static async setInstallPath(path) {
|
|
91
|
-
const
|
|
79
|
+
const result = await this.execUnityHubCommand(["install-path", "-s", path], {
|
|
92
80
|
reject: false,
|
|
93
81
|
});
|
|
94
|
-
if (
|
|
95
|
-
|
|
82
|
+
if (!result.success) {
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
if (result.value.stderr) {
|
|
86
|
+
return (0, index_js_1.err)(new index_js_1.UnityCommandError(`Error setting install path: ${result.value.stderr}`, result.value.stdout, result.value.stderr, result.value.exitCode));
|
|
96
87
|
}
|
|
97
|
-
console.debug(`Install path set to: ${stdout}`);
|
|
88
|
+
console.debug(`Install path set to: ${result.value.stdout}`);
|
|
89
|
+
return (0, index_js_1.ok)(undefined);
|
|
98
90
|
}
|
|
99
91
|
static async getUnityInstallations(filter = "i") {
|
|
100
92
|
if (!["i", "a", "r"].includes(filter)) {
|
|
101
|
-
|
|
93
|
+
return (0, index_js_1.err)(new index_js_1.InvalidArgumentError(`Invalid filter "${filter}". Use "i" for installed, "a" for all, or "r" for available releases.`, { filter, validFilters: ["i", "a", "r"] }));
|
|
102
94
|
}
|
|
103
|
-
const
|
|
95
|
+
const result = await this.execUnityHubCommand(["editors", `-${filter}`], {
|
|
104
96
|
reject: false,
|
|
105
97
|
});
|
|
98
|
+
if (!result.success) {
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
const { stdout, stderr } = result.value;
|
|
106
102
|
const isSuccess = stdout.includes(", installed at");
|
|
107
|
-
if (stderr)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
if (stderr) {
|
|
104
|
+
return (0, index_js_1.err)(new index_js_1.UnityCommandError(`Get installations command warning/error: ${stderr}`, stdout, stderr, result.value.exitCode));
|
|
105
|
+
}
|
|
106
|
+
if (!isSuccess) {
|
|
107
|
+
return (0, index_js_1.err)(new index_js_1.UnityInstallationError("No Unity installations found. Consider installing a Unity version using Unity Hub.", {
|
|
108
|
+
filter,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
111
|
const lines = stdout.split(/\r\n|\n/);
|
|
112
112
|
const installations = {};
|
|
113
113
|
lines.forEach((line) => {
|
|
114
114
|
const [version, unityPath] = line.split(", installed at").map((entry) => entry.trim());
|
|
115
|
-
|
|
115
|
+
if (version && unityPath) {
|
|
116
|
+
installations[version] = unityPath;
|
|
117
|
+
}
|
|
116
118
|
});
|
|
117
|
-
if (Object.keys(installations).length <= 0)
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
if (Object.keys(installations).length <= 0) {
|
|
120
|
+
return (0, index_js_1.err)(new index_js_1.UnityInstallationError("No Unity installations found.", { filter }));
|
|
121
|
+
}
|
|
122
|
+
return (0, index_js_1.ok)(installations);
|
|
120
123
|
}
|
|
121
124
|
static async addModule(editorVersion, modules, childModules = true) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const args = ["install-modules", "-v", editorVersion];
|
|
125
|
-
if (modules.length > 0) {
|
|
126
|
-
args.push(...["--module", modules.join(" ")]);
|
|
127
|
-
if (childModules) {
|
|
128
|
-
args.push("--child-modules");
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
throw new Error("No module IDs provided.");
|
|
133
|
-
}
|
|
134
|
-
const installerEmitter = new hubEventEmitter_ts_1.UnityHubInstallerEvent();
|
|
135
|
-
this.execUnityHubCommand(args, {
|
|
136
|
-
reject: false,
|
|
137
|
-
onStdout: (data) => installerEmitter.Progress(data),
|
|
138
|
-
}).catch((error) => {
|
|
139
|
-
console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
|
|
140
|
-
});
|
|
141
|
-
return installerEmitter;
|
|
125
|
+
if (modules.length === 0) {
|
|
126
|
+
return (0, index_js_1.err)(new index_js_1.InvalidArgumentError("No module IDs provided.", { editorVersion, modules }));
|
|
142
127
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
128
|
+
console.debug(`Adding module ${modules} to Unity ${editorVersion}`);
|
|
129
|
+
const args = ["install-modules", "-v", editorVersion, "--module", modules.join(" ")];
|
|
130
|
+
if (childModules) {
|
|
131
|
+
args.push("--child-modules");
|
|
146
132
|
}
|
|
133
|
+
const installerEmitter = new hubEventEmitter_js_1.UnityHubInstallerEvent();
|
|
134
|
+
this.execUnityHubCommand(args, {
|
|
135
|
+
reject: false,
|
|
136
|
+
onStdout: (data) => installerEmitter.Progress(data),
|
|
137
|
+
})
|
|
138
|
+
.then((result) => {
|
|
139
|
+
if (!result.success) {
|
|
140
|
+
console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, result.error);
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
.catch((error) => {
|
|
144
|
+
console.error(`Error adding module ${modules} to Unity ${editorVersion}:`, error);
|
|
145
|
+
});
|
|
146
|
+
return (0, index_js_1.ok)(installerEmitter);
|
|
147
147
|
}
|
|
148
148
|
static async addEditor(version, modules = [], architecture) {
|
|
149
149
|
try {
|
|
150
150
|
const data = await (0, unity_changeset_1.getUnityChangeset)(version);
|
|
151
|
-
const args = ["install", "-v", version];
|
|
152
|
-
args.push("--changeset", data.changeset);
|
|
151
|
+
const args = ["install", "-v", version, "--changeset", data.changeset];
|
|
153
152
|
if (modules.length > 0) {
|
|
154
|
-
args.push("--module");
|
|
155
|
-
args.push(modules.join(" "));
|
|
153
|
+
args.push("--module", modules.join(" "));
|
|
156
154
|
}
|
|
157
155
|
if (!architecture) {
|
|
158
156
|
const arch = os_1.default.arch() || process.arch;
|
|
159
|
-
|
|
160
|
-
architecture = defaultArchitecture;
|
|
157
|
+
architecture = arch === "arm64" || arch === "arm" ? unity_js_1.EditorArchitecture.arm64 : unity_js_1.EditorArchitecture.x86_64;
|
|
161
158
|
}
|
|
162
159
|
args.push("--architecture", architecture);
|
|
163
|
-
const installerEmitter = new
|
|
160
|
+
const installerEmitter = new hubEventEmitter_js_1.UnityHubInstallerEvent();
|
|
164
161
|
this.execUnityHubCommand(args, {
|
|
165
162
|
reject: false,
|
|
166
163
|
onStdout: (data) => installerEmitter.Progress(data),
|
|
167
|
-
})
|
|
164
|
+
})
|
|
165
|
+
.then((result) => {
|
|
166
|
+
if (!result.success) {
|
|
167
|
+
console.error(`Error installing Unity ${version}:`, result.error);
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
.catch((error) => {
|
|
168
171
|
console.error(`Error installing Unity ${version}:`, error);
|
|
169
172
|
});
|
|
170
|
-
return installerEmitter;
|
|
173
|
+
return (0, index_js_1.ok)(installerEmitter);
|
|
171
174
|
}
|
|
172
175
|
catch (error) {
|
|
173
176
|
console.error(error);
|
|
174
|
-
|
|
177
|
+
return (0, index_js_1.err)(new index_js_1.UnityInstallationError(`Failed to install Unity ${version}: ${String(error)}`, { version, modules, architecture }));
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
static async getProjects() {
|
|
@@ -179,19 +182,20 @@ class UnityHub {
|
|
|
179
182
|
const projectsPath = this.getProjectsPath();
|
|
180
183
|
if (!projectsPath || !fs_extra_1.default.existsSync(projectsPath)) {
|
|
181
184
|
console.debug(`Projects file not found at: ${projectsPath}`);
|
|
182
|
-
return
|
|
185
|
+
return (0, index_js_1.err)(new index_js_1.UnityProjectError(`Projects file not found at: ${projectsPath}`, { projectsPath }));
|
|
183
186
|
}
|
|
184
187
|
const projectsData = await fs_extra_1.default.readJson(projectsPath);
|
|
185
188
|
const projects = Object.values(projectsData.data);
|
|
186
|
-
|
|
189
|
+
const mappedProjects = projects.map((project) => ({
|
|
187
190
|
name: project.title,
|
|
188
191
|
path: project.path,
|
|
189
192
|
version: project.version,
|
|
190
193
|
}));
|
|
194
|
+
return (0, index_js_1.ok)(mappedProjects);
|
|
191
195
|
}
|
|
192
196
|
catch (error) {
|
|
193
197
|
console.error("Error getting recent projects:", error);
|
|
194
|
-
return
|
|
198
|
+
return (0, index_js_1.err)(new index_js_1.UnityProjectError(`Failed to get projects: ${String(error)}`));
|
|
195
199
|
}
|
|
196
200
|
}
|
|
197
201
|
static async getDefaultProjectsDirectory() {
|
|
@@ -199,14 +203,14 @@ class UnityHub {
|
|
|
199
203
|
const projectDirPath = this.getProjectDirPath();
|
|
200
204
|
if (!projectDirPath || !fs_extra_1.default.existsSync(projectDirPath)) {
|
|
201
205
|
console.debug(`Project directory file not found at: ${projectDirPath}`);
|
|
202
|
-
return null;
|
|
206
|
+
return (0, index_js_1.ok)(null);
|
|
203
207
|
}
|
|
204
208
|
const projectDirData = await fs_extra_1.default.readJson(projectDirPath);
|
|
205
|
-
return projectDirData.directoryPath ?? null;
|
|
209
|
+
return (0, index_js_1.ok)(projectDirData.directoryPath ?? null);
|
|
206
210
|
}
|
|
207
211
|
catch (error) {
|
|
208
212
|
console.error("Error getting default project directory:", error);
|
|
209
|
-
return
|
|
213
|
+
return (0, index_js_1.err)(new index_js_1.UnityProjectError(`Failed to get default project directory: ${String(error)}`));
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
216
|
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.executeCommand = executeCommand;
|
|
4
4
|
const execa_1 = require("execa");
|
|
5
|
+
const index_js_1 = require("../errors/index.js");
|
|
6
|
+
const index_js_2 = require("../errors/index.js");
|
|
5
7
|
async function executeCommand(executable, args, options = {}) {
|
|
6
8
|
try {
|
|
7
9
|
const streamOutput = options.onStdout || options.onStderr;
|
|
@@ -40,19 +42,16 @@ async function executeCommand(executable, args, options = {}) {
|
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
const { stdout, stderr, exitCode } = await subprocess;
|
|
43
|
-
return {
|
|
44
|
-
success: true,
|
|
45
|
+
return (0, index_js_1.ok)({
|
|
45
46
|
stdout,
|
|
46
47
|
stderr,
|
|
47
48
|
exitCode,
|
|
48
|
-
};
|
|
49
|
+
});
|
|
49
50
|
}
|
|
50
51
|
catch (error) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
exitCode: error.exitCode,
|
|
56
|
-
};
|
|
52
|
+
const stdout = error.stdout ?? "";
|
|
53
|
+
const stderr = error.stderr ?? String(error);
|
|
54
|
+
const exitCode = error.exitCode;
|
|
55
|
+
return (0, index_js_1.err)(new index_js_2.UnityCommandError(`Command execution failed: ${executable} ${args.join(" ")}`, stdout, stderr, exitCode, { executable, args }));
|
|
57
56
|
}
|
|
58
57
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { UnityError } from "./UnityError.js";
|
|
2
|
+
export interface Success<T> {
|
|
3
|
+
readonly success: true;
|
|
4
|
+
readonly value: T;
|
|
5
|
+
}
|
|
6
|
+
export interface Failure<E extends UnityError> {
|
|
7
|
+
readonly success: false;
|
|
8
|
+
readonly error: E;
|
|
9
|
+
}
|
|
10
|
+
export type Result<T, E extends UnityError = UnityError> = Success<T> | Failure<E>;
|
|
11
|
+
export declare function ok<T>(value: T): Success<T>;
|
|
12
|
+
export declare function err<E extends UnityError>(error: E): Failure<E>;
|
|
13
|
+
export declare function isOk<T, E extends UnityError>(result: Result<T, E>): result is Success<T>;
|
|
14
|
+
export declare function isErr<T, E extends UnityError>(result: Result<T, E>): result is Failure<E>;
|
|
15
|
+
export declare function unwrap<T, E extends UnityError>(result: Result<T, E>): T;
|
|
16
|
+
export declare function unwrapOr<T, E extends UnityError>(result: Result<T, E>, defaultValue: T): T;
|
|
17
|
+
export declare function map<T, U, E extends UnityError>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
|
|
18
|
+
export declare function mapErr<T, E extends UnityError, F extends UnityError>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
|
|
19
|
+
export declare function andThen<T, U, E extends UnityError>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E>;
|
|
20
|
+
export declare function firstOk<T, E extends UnityError>(results: Result<T, E>[]): Result<T, E>;
|
|
21
|
+
export declare function combine<T, E extends UnityError>(results: Result<T, E>[]): Result<T[], E>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export function ok(value) {
|
|
2
|
+
return { success: true, value };
|
|
3
|
+
}
|
|
4
|
+
export function err(error) {
|
|
5
|
+
return { success: false, error };
|
|
6
|
+
}
|
|
7
|
+
export function isOk(result) {
|
|
8
|
+
return result.success === true;
|
|
9
|
+
}
|
|
10
|
+
export function isErr(result) {
|
|
11
|
+
return result.success === false;
|
|
12
|
+
}
|
|
13
|
+
export function unwrap(result) {
|
|
14
|
+
if (isOk(result)) {
|
|
15
|
+
return result.value;
|
|
16
|
+
}
|
|
17
|
+
throw result.error;
|
|
18
|
+
}
|
|
19
|
+
export function unwrapOr(result, defaultValue) {
|
|
20
|
+
if (isOk(result)) {
|
|
21
|
+
return result.value;
|
|
22
|
+
}
|
|
23
|
+
return defaultValue;
|
|
24
|
+
}
|
|
25
|
+
export function map(result, fn) {
|
|
26
|
+
if (isOk(result)) {
|
|
27
|
+
return ok(fn(result.value));
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
export function mapErr(result, fn) {
|
|
32
|
+
if (isErr(result)) {
|
|
33
|
+
return err(fn(result.error));
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
export function andThen(result, fn) {
|
|
38
|
+
if (isOk(result)) {
|
|
39
|
+
return fn(result.value);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
export function firstOk(results) {
|
|
44
|
+
if (results.length === 0) {
|
|
45
|
+
throw new Error("Cannot call firstOk on empty array");
|
|
46
|
+
}
|
|
47
|
+
for (const result of results) {
|
|
48
|
+
if (isOk(result)) {
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return results[results.length - 1];
|
|
53
|
+
}
|
|
54
|
+
export function combine(results) {
|
|
55
|
+
const values = [];
|
|
56
|
+
for (const result of results) {
|
|
57
|
+
if (isErr(result)) {
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
values.push(result.value);
|
|
61
|
+
}
|
|
62
|
+
return ok(values);
|
|
63
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare abstract class UnityError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly context?: Record<string, unknown>;
|
|
4
|
+
constructor(message: string, code: string, context?: Record<string, unknown>);
|
|
5
|
+
}
|
|
6
|
+
export declare class UnityHubNotFoundError extends UnityError {
|
|
7
|
+
constructor(message?: string, context?: Record<string, unknown>);
|
|
8
|
+
}
|
|
9
|
+
export declare class UnityEditorNotFoundError extends UnityError {
|
|
10
|
+
constructor(version: string, path?: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class UnityCommandError extends UnityError {
|
|
13
|
+
readonly stdout: string;
|
|
14
|
+
readonly stderr: string;
|
|
15
|
+
readonly exitCode?: number;
|
|
16
|
+
constructor(message: string, stdout?: string, stderr?: string, exitCode?: number, context?: Record<string, unknown>);
|
|
17
|
+
}
|
|
18
|
+
export declare class UnityInstallationError extends UnityError {
|
|
19
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
20
|
+
}
|
|
21
|
+
export declare class UnityProjectError extends UnityError {
|
|
22
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
23
|
+
}
|
|
24
|
+
export declare class UnityLicenseError extends UnityError {
|
|
25
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
26
|
+
}
|
|
27
|
+
export declare class UnityPackageError extends UnityError {
|
|
28
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
29
|
+
}
|
|
30
|
+
export declare class UnityTestError extends UnityError {
|
|
31
|
+
readonly testOutput: string;
|
|
32
|
+
constructor(message: string, testOutput?: string, context?: Record<string, unknown>);
|
|
33
|
+
}
|
|
34
|
+
export declare class InvalidArgumentError extends UnityError {
|
|
35
|
+
constructor(message: string, context?: Record<string, unknown>);
|
|
36
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export class UnityError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
context;
|
|
4
|
+
constructor(message, code, context) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = this.constructor.name;
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.context = context;
|
|
9
|
+
Error.captureStackTrace(this, this.constructor);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class UnityHubNotFoundError extends UnityError {
|
|
13
|
+
constructor(message = "Unity Hub is not available", context) {
|
|
14
|
+
super(message, "UNITY_HUB_NOT_FOUND", context);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class UnityEditorNotFoundError extends UnityError {
|
|
18
|
+
constructor(version, path) {
|
|
19
|
+
super(`Unity Editor version ${version} not found${path ? ` at path: ${path}` : ""}`, "UNITY_EDITOR_NOT_FOUND", { version, path });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class UnityCommandError extends UnityError {
|
|
23
|
+
stdout;
|
|
24
|
+
stderr;
|
|
25
|
+
exitCode;
|
|
26
|
+
constructor(message, stdout = "", stderr = "", exitCode, context) {
|
|
27
|
+
super(message, "UNITY_COMMAND_ERROR", context);
|
|
28
|
+
this.stdout = stdout;
|
|
29
|
+
this.stderr = stderr;
|
|
30
|
+
this.exitCode = exitCode;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class UnityInstallationError extends UnityError {
|
|
34
|
+
constructor(message, context) {
|
|
35
|
+
super(message, "UNITY_INSTALLATION_ERROR", context);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class UnityProjectError extends UnityError {
|
|
39
|
+
constructor(message, context) {
|
|
40
|
+
super(message, "UNITY_PROJECT_ERROR", context);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class UnityLicenseError extends UnityError {
|
|
44
|
+
constructor(message, context) {
|
|
45
|
+
super(message, "UNITY_LICENSE_ERROR", context);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class UnityPackageError extends UnityError {
|
|
49
|
+
constructor(message, context) {
|
|
50
|
+
super(message, "UNITY_PACKAGE_ERROR", context);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class UnityTestError extends UnityError {
|
|
54
|
+
testOutput;
|
|
55
|
+
constructor(message, testOutput = "", context) {
|
|
56
|
+
super(message, "UNITY_TEST_ERROR", context);
|
|
57
|
+
this.testOutput = testOutput;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export class InvalidArgumentError extends UnityError {
|
|
61
|
+
constructor(message, context) {
|
|
62
|
+
super(message, "INVALID_ARGUMENT", context);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
-
import { InstallerEventType, InstallerEvent } from "../types/unity.
|
|
2
|
+
import { InstallerEventType, InstallerEvent } from "../types/unity.js";
|
|
3
3
|
export interface InstallerEmitter extends EventEmitter {
|
|
4
4
|
on(event: InstallerEventType.Progress, listener: (info: InstallerEvent[]) => void): this;
|
|
5
5
|
on(event: InstallerEventType.Error, listener: (error: Error) => void): this;
|
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
import { InstallerEvent } from "../types/unity.
|
|
1
|
+
import { InstallerEvent } from "../types/unity.js";
|
|
2
|
+
import { ParserConfig, ParseResult, Pattern } from "./patterns/index.js";
|
|
2
3
|
export declare class UnityHubEventParser {
|
|
3
|
-
private static
|
|
4
|
+
private static patternRegistry;
|
|
5
|
+
private static statusNormalizer;
|
|
6
|
+
private static config;
|
|
7
|
+
private static initialize;
|
|
4
8
|
static parseUnityHubEvent(event: string): InstallerEvent[];
|
|
5
|
-
|
|
9
|
+
static parseWithDetails(event: string): ParseResult;
|
|
10
|
+
static setLocale(locale: string): void;
|
|
11
|
+
static getLocale(): string;
|
|
12
|
+
static registerCustomPattern(pattern: Pattern): void;
|
|
13
|
+
static addStatusNormalization(statusText: string, status: any, locale?: string): void;
|
|
14
|
+
static getUnknownStatuses(): string[];
|
|
15
|
+
static clearUnknownStatuses(): void;
|
|
16
|
+
static configure(config: Partial<ParserConfig>): void;
|
|
17
|
+
static getConfig(): Readonly<ParserConfig>;
|
|
18
|
+
static reset(): void;
|
|
19
|
+
static getPatternNames(): string[];
|
|
6
20
|
}
|
|
@@ -1,40 +1,110 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PatternRegistry, StatusNormalizer, BracketModulePattern, ErrorPattern, FallbackPattern, } from "./patterns/index.js";
|
|
2
2
|
export class UnityHubEventParser {
|
|
3
|
-
static
|
|
3
|
+
static patternRegistry;
|
|
4
|
+
static statusNormalizer;
|
|
5
|
+
static config = {
|
|
6
|
+
locale: "en",
|
|
7
|
+
logUnknownStatuses: true,
|
|
8
|
+
minConfidence: 30,
|
|
9
|
+
useFallbackPatterns: true,
|
|
10
|
+
};
|
|
11
|
+
static initialize() {
|
|
12
|
+
if (this.patternRegistry) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
this.statusNormalizer = new StatusNormalizer();
|
|
16
|
+
this.patternRegistry = new PatternRegistry();
|
|
17
|
+
this.patternRegistry.register(new ErrorPattern(this.config.locale));
|
|
18
|
+
this.patternRegistry.register(new BracketModulePattern(this.statusNormalizer, this.config.locale));
|
|
19
|
+
if (this.config.useFallbackPatterns) {
|
|
20
|
+
this.patternRegistry.register(new FallbackPattern(this.statusNormalizer, this.config.locale));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
4
23
|
static parseUnityHubEvent(event) {
|
|
24
|
+
this.initialize();
|
|
25
|
+
const result = this.parseWithDetails(event);
|
|
26
|
+
return result.events;
|
|
27
|
+
}
|
|
28
|
+
static parseWithDetails(event) {
|
|
29
|
+
this.initialize();
|
|
5
30
|
const events = [];
|
|
6
|
-
const
|
|
31
|
+
const unparsedLines = [];
|
|
32
|
+
const lines = event.split(/\r?\n/);
|
|
7
33
|
for (const line of lines) {
|
|
8
|
-
const
|
|
9
|
-
if (
|
|
10
|
-
events.push(errorLine);
|
|
34
|
+
const trimmedLine = line.trim();
|
|
35
|
+
if (!trimmedLine) {
|
|
11
36
|
continue;
|
|
12
37
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
for (const line of lines) {
|
|
16
|
-
const match = line.match(pattern);
|
|
17
|
-
if (match?.groups) {
|
|
18
|
-
const { module, status, progress } = match.groups;
|
|
38
|
+
const match = this.patternRegistry.match(trimmedLine, this.config.locale, this.config.minConfidence);
|
|
39
|
+
if (match) {
|
|
19
40
|
events.push({
|
|
20
|
-
module: module
|
|
21
|
-
status: status
|
|
22
|
-
progress: progress
|
|
41
|
+
module: match.module,
|
|
42
|
+
status: match.status,
|
|
43
|
+
progress: match.progress,
|
|
44
|
+
error: match.error,
|
|
23
45
|
});
|
|
24
46
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if (pattern.test(line)) {
|
|
31
|
-
return {
|
|
32
|
-
module: "UnityHub",
|
|
33
|
-
status: InstallerStatus.Error,
|
|
34
|
-
error: line.trim(),
|
|
35
|
-
};
|
|
47
|
+
else {
|
|
48
|
+
unparsedLines.push(trimmedLine);
|
|
49
|
+
if (this.config.logUnknownStatuses) {
|
|
50
|
+
console.debug(`UnityHubEventParser: Could not parse line: "${trimmedLine}"`);
|
|
51
|
+
}
|
|
36
52
|
}
|
|
37
53
|
}
|
|
38
|
-
return
|
|
54
|
+
return {
|
|
55
|
+
events,
|
|
56
|
+
unknownStatuses: this.statusNormalizer.getUnknownStatuses(),
|
|
57
|
+
unparsedLines,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
static setLocale(locale) {
|
|
61
|
+
this.config.locale = locale;
|
|
62
|
+
if (this.patternRegistry) {
|
|
63
|
+
this.patternRegistry.clear();
|
|
64
|
+
this.initialize();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
static getLocale() {
|
|
68
|
+
return this.config.locale;
|
|
69
|
+
}
|
|
70
|
+
static registerCustomPattern(pattern) {
|
|
71
|
+
this.initialize();
|
|
72
|
+
this.patternRegistry.register(pattern);
|
|
73
|
+
}
|
|
74
|
+
static addStatusNormalization(statusText, status, locale) {
|
|
75
|
+
this.initialize();
|
|
76
|
+
this.statusNormalizer.addNormalization({ text: statusText, status, locale });
|
|
77
|
+
}
|
|
78
|
+
static getUnknownStatuses() {
|
|
79
|
+
this.initialize();
|
|
80
|
+
return this.statusNormalizer.getUnknownStatuses();
|
|
81
|
+
}
|
|
82
|
+
static clearUnknownStatuses() {
|
|
83
|
+
this.initialize();
|
|
84
|
+
this.statusNormalizer.clearUnknownStatuses();
|
|
85
|
+
}
|
|
86
|
+
static configure(config) {
|
|
87
|
+
this.config = { ...this.config, ...config };
|
|
88
|
+
if (config.locale && this.patternRegistry) {
|
|
89
|
+
this.patternRegistry.clear();
|
|
90
|
+
this.initialize();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
static getConfig() {
|
|
94
|
+
return { ...this.config };
|
|
95
|
+
}
|
|
96
|
+
static reset() {
|
|
97
|
+
this.patternRegistry = undefined;
|
|
98
|
+
this.statusNormalizer = undefined;
|
|
99
|
+
this.config = {
|
|
100
|
+
locale: "en",
|
|
101
|
+
logUnknownStatuses: true,
|
|
102
|
+
minConfidence: 30,
|
|
103
|
+
useFallbackPatterns: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
static getPatternNames() {
|
|
107
|
+
this.initialize();
|
|
108
|
+
return this.patternRegistry.getPatternNames();
|
|
39
109
|
}
|
|
40
110
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Pattern, PatternMatch } from "../types.js";
|
|
2
|
+
import { StatusNormalizer } from "../statusNormalizer.js";
|
|
3
|
+
export declare class BracketModulePattern implements Pattern {
|
|
4
|
+
readonly name = "BracketModulePattern";
|
|
5
|
+
readonly priority = 80;
|
|
6
|
+
readonly locale?: string;
|
|
7
|
+
private statusNormalizer;
|
|
8
|
+
private pattern;
|
|
9
|
+
constructor(statusNormalizer: StatusNormalizer, locale?: string);
|
|
10
|
+
match(line: string, locale?: string): PatternMatch | null;
|
|
11
|
+
}
|