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

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/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ # [1.2.0-rc.1](https://github.com/NoTaskStudios/unity-cli-tools/compare/1.1.2...1.2.0-rc.1) (2025-05-08)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **Hub:** Remove hubPath field ([9b1b737](https://github.com/NoTaskStudios/unity-cli-tools/commit/9b1b737d90c91322872d715f86c9f7f53ae8c1ea))
7
+ * put return type on local functions ([1eef3de](https://github.com/NoTaskStudios/unity-cli-tools/commit/1eef3de26b03481cfc5476caa2d13a62b6fe0bdb))
8
+
9
+
10
+ ### Features
11
+
12
+ * **Config:** Create a entity to handle configurations ([ef8f34f](https://github.com/NoTaskStudios/unity-cli-tools/commit/ef8f34f143e2dcb1f1585588df23033ac68d3d80))
13
+ * **Config:** Added Template path and interfaces ([7ec4de0](https://github.com/NoTaskStudios/unity-cli-tools/commit/7ec4de0d9a22c50094d1ed027d3fa068245a9f73))
14
+ * **Config:** Create unity path types ([5b329bb](https://github.com/NoTaskStudios/unity-cli-tools/commit/5b329bb621b715bfaa63ead294d71c7bc8510fe2))
15
+ * **Editor:** Added cloneFromTemplate function ([149c389](https://github.com/NoTaskStudios/unity-cli-tools/commit/149c389c3421a8d88b06cdc32e690afa40b68f27))
16
+ * **Template:** Added UnityTemplates class for editor templates ([fca3256](https://github.com/NoTaskStudios/unity-cli-tools/commit/fca3256a14c4f8a8af701ced2f6449798f196020))
17
+ * **Template:** Template path configuration ([1067deb](https://github.com/NoTaskStudios/unity-cli-tools/commit/1067deb516d3ef7e4d5bb6f26298be44f3763774))
18
+
19
+ ## [1.1.2](https://github.com/NoTaskStudios/unity-cli-tools/compare/1.1.1...1.1.2) (2025-05-04)
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * **hot-fix:** completed promise as get ([22f152a](https://github.com/NoTaskStudios/unity-cli-tools/commit/22f152a5da016371719649593a96005a636fa9c5))
25
+
1
26
  ## [1.1.1](https://github.com/NoTaskStudios/unity-cli-tools/compare/1.1.0...1.1.1) (2025-05-04)
2
27
 
3
28
 
@@ -0,0 +1,74 @@
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
+ exports.UnityConfig = void 0;
7
+ const os_1 = __importDefault(require("os"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const UNITY_HUB_PATHS = {
10
+ win32: {
11
+ hubDir: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
12
+ projects: path_1.default.join(os_1.default.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
13
+ projectDir: path_1.default.join(os_1.default.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
14
+ },
15
+ darwin: {
16
+ hubDir: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
17
+ projects: path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
18
+ projectDir: path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
19
+ },
20
+ linux: {
21
+ hubDir: "/opt/UnityHub/UnityHub",
22
+ projects: path_1.default.join(os_1.default.homedir(), ".config", "UnityHub", "projects-v1.json"),
23
+ projectDir: path_1.default.join(os_1.default.homedir(), ".config", "UnityHub", "projectDir.json"),
24
+ },
25
+ };
26
+ const UNITY_EDITOR_PATHS = {
27
+ win32: {
28
+ base: "C:/Program Files/Unity/Hub/Editor",
29
+ executable: "Editor/Unity.exe",
30
+ projectTemplates: "Editor/Data/Resources/PackageManager/ProjectTemplates",
31
+ },
32
+ darwin: {
33
+ base: "/Applications/Unity/Hub/Editor",
34
+ executable: "Unity.app/Contents/MacOS/Unity",
35
+ projectTemplates: "Unity.app/Contents/Resources/PackageManager/ProjectTemplates",
36
+ },
37
+ linux: {
38
+ base: "/opt/unity/editor",
39
+ executable: "Editor/Unity",
40
+ projectTemplates: "Editor/Data/Resources/PackageManager/ProjectTemplates",
41
+ },
42
+ };
43
+ class UnityConfig {
44
+ static getPlatformConfig() {
45
+ const platform = process.platform;
46
+ const unityHubPaths = UNITY_HUB_PATHS[platform];
47
+ const unityEditorPaths = UNITY_EDITOR_PATHS[platform];
48
+ const settings = {
49
+ editor: {
50
+ base: environment.unityEditorPath ?? unityEditorPaths.base,
51
+ executable: unityEditorPaths.executable,
52
+ projectTemplates: unityEditorPaths.projectTemplates,
53
+ },
54
+ hub: {
55
+ hubDir: environment.unityHubPath ?? unityHubPaths.hubDir,
56
+ projects: unityHubPaths.projects,
57
+ projectDir: unityHubPaths.projectDir,
58
+ },
59
+ templates: {
60
+ projectTemplates: environment.unityProjectTemplatePath ?? unityEditorPaths.projectTemplates,
61
+ },
62
+ platform,
63
+ architecture: os_1.default.arch(),
64
+ };
65
+ return settings;
66
+ }
67
+ }
68
+ exports.UnityConfig = UnityConfig;
69
+ const environment = {
70
+ unityHubPath: process.env.UNITY_HUB_PATH,
71
+ unityEditorPath: process.env.UNITY_EDITOR_PATH,
72
+ unityProjectPath: process.env.UNITY_PROJECT_PATH,
73
+ unityProjectTemplatePath: process.env.UNITY_PROJECT_TEMPLATE_PATH,
74
+ };
@@ -9,11 +9,30 @@ class UnityHubInstallerEvent extends events_1.EventEmitter {
9
9
  constructor() {
10
10
  super();
11
11
  }
12
- completed = new Promise((resolve, reject) => {
13
- this.on(unity_ts_1.InstallerEventType.Completed, (events) => resolve(events));
14
- this.on(unity_ts_1.InstallerEventType.Error, (error) => reject(error));
15
- this.on(unity_ts_1.InstallerEventType.Cancelled, (events) => reject(new Error("Cancelled")));
16
- });
12
+ get completed() {
13
+ return new Promise((resolve, reject) => {
14
+ const onComplete = (events) => {
15
+ cleanup();
16
+ resolve(events);
17
+ };
18
+ const onError = (error) => {
19
+ cleanup();
20
+ reject(error);
21
+ };
22
+ const onCancel = () => {
23
+ cleanup();
24
+ reject(new Error("Cancelled"));
25
+ };
26
+ const cleanup = () => {
27
+ this.off(unity_ts_1.InstallerEventType.Completed, onComplete);
28
+ this.off(unity_ts_1.InstallerEventType.Error, onError);
29
+ this.off(unity_ts_1.InstallerEventType.Cancelled, onCancel);
30
+ };
31
+ this.on(unity_ts_1.InstallerEventType.Completed, onComplete);
32
+ this.on(unity_ts_1.InstallerEventType.Error, onError);
33
+ this.on(unity_ts_1.InstallerEventType.Cancelled, onCancel);
34
+ });
35
+ }
17
36
  Progress(raw) {
18
37
  const events = hubEventParser_ts_1.UnityHubEventParser.parseUnityHubEvent(raw);
19
38
  if (events.length === 0)
package/dist/cjs/index.js CHANGED
@@ -17,11 +17,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.UnityHubInstallerEvent = exports.UnityEditor = exports.UnityHub = void 0;
20
+ exports.UnityConfig = exports.UnityHubInstallerEvent = exports.UnityTemplates = exports.UnityEditor = exports.UnityHub = void 0;
21
21
  var unityHub_ts_1 = require("./unityHub.js");
22
22
  Object.defineProperty(exports, "UnityHub", { enumerable: true, get: function () { return __importDefault(unityHub_ts_1).default; } });
23
23
  var unityEditor_ts_1 = require("./unityEditor.js");
24
24
  Object.defineProperty(exports, "UnityEditor", { enumerable: true, get: function () { return __importDefault(unityEditor_ts_1).default; } });
25
+ var unityTemplates_ts_1 = require("./unityTemplates.js");
26
+ Object.defineProperty(exports, "UnityTemplates", { enumerable: true, get: function () { return __importDefault(unityTemplates_ts_1).default; } });
25
27
  var hubEventEmitter_ts_1 = require("./events/hubEventEmitter.js");
26
28
  Object.defineProperty(exports, "UnityHubInstallerEvent", { enumerable: true, get: function () { return hubEventEmitter_ts_1.UnityHubInstallerEvent; } });
29
+ var unityConfig_ts_1 = require("./configs/unityConfig.js");
30
+ Object.defineProperty(exports, "UnityConfig", { enumerable: true, get: function () { return unityConfig_ts_1.UnityConfig; } });
27
31
  __exportStar(require("./types/unity.js"), exports);
@@ -3,31 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const os_1 = __importDefault(require("os"));
7
6
  const fs_extra_1 = __importDefault(require("fs-extra"));
8
7
  const path_1 = __importDefault(require("path"));
9
8
  const unity_js_1 = require("./types/unity.js");
10
9
  const commandExecutor_js_1 = require("./utils/commandExecutor.js");
11
10
  const security_js_1 = require("./utils/security.js");
11
+ const unityConfig_ts_1 = require("./configs/unityConfig.js");
12
12
  class UnityEditor {
13
- static UNITY_PATHS = {
14
- win32: {
15
- base: "C:/Program Files/Unity/Hub/Editor",
16
- executable: "Editor/Unity.exe",
17
- },
18
- darwin: {
19
- base: "/Applications/Unity/Hub/Editor",
20
- executable: "Unity.app/Contents/MacOS/Unity",
21
- },
22
- linux: {
23
- base: "/opt/unity/editor",
24
- executable: "Editor/Unity",
25
- },
26
- };
13
+ static unityConfig = unityConfig_ts_1.UnityConfig.getPlatformConfig().editor;
27
14
  static getUnityExecutablePath(version) {
28
- const platform = os_1.default.platform();
29
- const unityConfig = UnityEditor.UNITY_PATHS[platform];
30
- const unityPath = path_1.default.join(unityConfig.base, version, unityConfig.executable);
15
+ const unityPath = path_1.default.join(this.unityConfig.base, version, this.unityConfig.executable);
16
+ return unityPath;
17
+ }
18
+ static getUnityTemplatesPath(version) {
19
+ const unityPath = path_1.default.join(this.unityConfig.base, version, this.unityConfig.projectTemplates);
31
20
  return unityPath;
32
21
  }
33
22
  static async isUnityVersionInstalled(version) {
@@ -227,15 +216,16 @@ class UnityEditor {
227
216
  return false;
228
217
  }
229
218
  }
230
- static async createProject(projectInfo, waitForExit = true) {
219
+ static async createProject(projectInfo, quit = false, useHub = true) {
231
220
  try {
232
221
  console.debug(`Creating new project at ${projectInfo.projectPath}`);
233
222
  const parentDir = path_1.default.dirname(projectInfo.projectPath);
234
223
  await fs_extra_1.default.ensureDir(parentDir);
235
224
  const args = ["-createProject", projectInfo.projectPath];
236
- if (waitForExit) {
225
+ if (useHub)
226
+ args.push("-useHub", "-hubIPC");
227
+ if (quit)
237
228
  args.push("-quit");
238
- }
239
229
  const editorInfo = { version: projectInfo.editorVersion };
240
230
  const { stdout, stderr } = await this.execUnityEditorCommand(editorInfo, args, {
241
231
  reject: false,
@@ -255,19 +245,45 @@ class UnityEditor {
255
245
  return false;
256
246
  }
257
247
  }
248
+ static async createProjectFromTemplate(projectInfo, templatePath, quit = false, useHub = true) {
249
+ try {
250
+ console.debug(`Creating new project from template at ${projectInfo.projectPath}`);
251
+ const parentDir = path_1.default.dirname(projectInfo.projectPath);
252
+ await fs_extra_1.default.ensureDir(parentDir);
253
+ const args = ["-createProject", projectInfo.projectPath, "-cloneFromTemplate", templatePath];
254
+ if (quit)
255
+ args.push("-quit");
256
+ if (useHub)
257
+ args.push("-useHub", "-hubIPC");
258
+ const editorInfo = { version: projectInfo.editorVersion };
259
+ const { stdout, stderr } = await this.execUnityEditorCommand(editorInfo, args, {
260
+ reject: false,
261
+ });
262
+ const creationSuccessful = !stdout.includes("Failed to create project") && !stderr.includes("Failed to create project");
263
+ if (creationSuccessful) {
264
+ console.debug(`Successfully created project from template at ${projectInfo.projectPath}`);
265
+ return true;
266
+ }
267
+ else {
268
+ console.error(`Failed to create project from template: ${stderr || stdout}`);
269
+ return false;
270
+ }
271
+ }
272
+ catch (error) {
273
+ console.error("Error creating project from template:", error);
274
+ return false;
275
+ }
276
+ }
258
277
  static async openProject(projectInfo, useHub = true, batchmode = false, waitForExit = true) {
259
278
  try {
260
279
  console.debug(`Opening project at ${projectInfo.projectPath}`);
261
280
  const args = ["-projectPath", projectInfo.projectPath];
262
- if (waitForExit) {
281
+ if (waitForExit)
263
282
  args.push("-quit");
264
- }
265
- if (batchmode) {
283
+ if (batchmode)
266
284
  args.push("-batchmode");
267
- }
268
- if (useHub) {
285
+ if (useHub)
269
286
  args.push(...["-useHub", "-hubIPC"]);
270
- }
271
287
  const editorInfo = { version: projectInfo.editorVersion };
272
288
  const options = { reject: false };
273
289
  const { stdout, stderr } = await this.execUnityEditorCommand(editorInfo, args, options);
@@ -5,47 +5,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const fs_extra_1 = __importDefault(require("fs-extra"));
7
7
  const os_1 = __importDefault(require("os"));
8
- const path_1 = __importDefault(require("path"));
9
8
  const unity_js_1 = require("./types/unity.js");
10
9
  const commandExecutor_js_1 = require("./utils/commandExecutor.js");
11
10
  const unity_changeset_1 = require("unity-changeset");
12
11
  const hubEventEmitter_ts_1 = require("./events/hubEventEmitter.js");
12
+ const unityConfig_ts_1 = require("./configs/unityConfig.js");
13
13
  class UnityHub {
14
- static CONFIG_PATHS = {
15
- win32: {
16
- hub: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
17
- projects: path_1.default.join(os_1.default.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
18
- projectDir: path_1.default.join(os_1.default.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
19
- },
20
- darwin: {
21
- hub: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
22
- projects: path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
23
- projectDir: path_1.default.join(os_1.default.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
24
- },
25
- linux: {
26
- hub: "/opt/UnityHub/UnityHub",
27
- projects: path_1.default.join(os_1.default.homedir(), ".config", "UnityHub", "projects-v1.json"),
28
- projectDir: path_1.default.join(os_1.default.homedir(), ".config", "UnityHub", "projectDir.json"),
29
- },
30
- };
31
- static platform = os_1.default.platform();
32
- static hubPath = this.getUnityHubPath();
14
+ static unityConfig = unityConfig_ts_1.UnityConfig.getPlatformConfig();
33
15
  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 || "";
16
+ return this.unityConfig.hub.hubDir;
39
17
  }
40
18
  static getProjectsPath() {
41
- return UnityHub.CONFIG_PATHS[this.platform].projects || "";
19
+ return this.unityConfig.hub.projects;
42
20
  }
43
21
  static getProjectDirPath() {
44
- return UnityHub.CONFIG_PATHS[this.platform].projectDir || "";
22
+ return this.unityConfig.hub.projectDir;
45
23
  }
46
24
  static async isUnityHubAvailable() {
47
25
  try {
48
- return !!this.hubPath && fs_extra_1.default.existsSync(this.hubPath);
26
+ const hubPath = this.getUnityHubPath();
27
+ return !!hubPath && fs_extra_1.default.existsSync(hubPath);
49
28
  }
50
29
  catch (error) {
51
30
  console.error("Error checking Unity Hub availability:", error);
@@ -64,9 +43,9 @@ class UnityHub {
64
43
  };
65
44
  }
66
45
  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);
46
+ const hubArgs = [this.unityConfig.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
47
+ console.debug(`Executing Unity Hub command: ${this.getUnityHubPath()} ${hubArgs.join(" ")}`);
48
+ return await (0, commandExecutor_js_1.executeCommand)(this.unityConfig.hub.hubDir, hubArgs, options);
70
49
  }
71
50
  catch (error) {
72
51
  console.error("Error executing Unity Hub command:", error);
@@ -0,0 +1,29 @@
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 path_1 = __importDefault(require("path"));
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const unityConfig_ts_1 = require("./configs/unityConfig.js");
9
+ class UnityTemplates {
10
+ static unityConfig = unityConfig_ts_1.UnityConfig.getPlatformConfig();
11
+ static getProjectTemplatesPath() {
12
+ return this.unityConfig.templates.projectTemplates;
13
+ }
14
+ static getProjectTemplatesPathForVersion(version) {
15
+ return path_1.default.join(this.unityConfig.editor.base, version, this.getProjectTemplatesPath());
16
+ }
17
+ static getProjectTemplates(version) {
18
+ const templatePath = this.getProjectTemplatesPathForVersion(version);
19
+ if (!fs_extra_1.default.existsSync(templatePath)) {
20
+ throw new Error(`Template path does not exist: ${templatePath}`);
21
+ }
22
+ const templates = fs_extra_1.default.readdirSync(templatePath).filter((file) => path_1.default.extname(file) === ".tgz");
23
+ return templates.map((template) => ({
24
+ templateName: path_1.default.basename(template, ".tgz"),
25
+ templatePath: path_1.default.join(templatePath, template),
26
+ }));
27
+ }
28
+ }
29
+ exports.default = UnityTemplates;
@@ -0,0 +1,25 @@
1
+ interface UnityHubPaths {
2
+ hubDir: string;
3
+ projects: string;
4
+ projectDir: string;
5
+ }
6
+ interface UnityEditorPaths {
7
+ base: string;
8
+ executable: string;
9
+ projectTemplates: string;
10
+ }
11
+ interface UnityTemplatePaths {
12
+ projectTemplates: string;
13
+ }
14
+ interface PlatformConfig {
15
+ editor: UnityEditorPaths;
16
+ hub: UnityHubPaths;
17
+ templates: UnityTemplatePaths;
18
+ platform: string;
19
+ architecture: string;
20
+ }
21
+ declare class UnityConfig {
22
+ static getPlatformConfig(): PlatformConfig;
23
+ }
24
+ export { UnityConfig };
25
+ export type { UnityHubPaths, UnityEditorPaths, UnityTemplatePaths, PlatformConfig };
@@ -0,0 +1,68 @@
1
+ import os from "os";
2
+ import path from "path";
3
+ const UNITY_HUB_PATHS = {
4
+ win32: {
5
+ hubDir: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
6
+ projects: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
7
+ projectDir: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
8
+ },
9
+ darwin: {
10
+ hubDir: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
11
+ projects: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
12
+ projectDir: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
13
+ },
14
+ linux: {
15
+ hubDir: "/opt/UnityHub/UnityHub",
16
+ projects: path.join(os.homedir(), ".config", "UnityHub", "projects-v1.json"),
17
+ projectDir: path.join(os.homedir(), ".config", "UnityHub", "projectDir.json"),
18
+ },
19
+ };
20
+ const UNITY_EDITOR_PATHS = {
21
+ win32: {
22
+ base: "C:/Program Files/Unity/Hub/Editor",
23
+ executable: "Editor/Unity.exe",
24
+ projectTemplates: "Editor/Data/Resources/PackageManager/ProjectTemplates",
25
+ },
26
+ darwin: {
27
+ base: "/Applications/Unity/Hub/Editor",
28
+ executable: "Unity.app/Contents/MacOS/Unity",
29
+ projectTemplates: "Unity.app/Contents/Resources/PackageManager/ProjectTemplates",
30
+ },
31
+ linux: {
32
+ base: "/opt/unity/editor",
33
+ executable: "Editor/Unity",
34
+ projectTemplates: "Editor/Data/Resources/PackageManager/ProjectTemplates",
35
+ },
36
+ };
37
+ class UnityConfig {
38
+ static getPlatformConfig() {
39
+ const platform = process.platform;
40
+ const unityHubPaths = UNITY_HUB_PATHS[platform];
41
+ const unityEditorPaths = UNITY_EDITOR_PATHS[platform];
42
+ const settings = {
43
+ editor: {
44
+ base: environment.unityEditorPath ?? unityEditorPaths.base,
45
+ executable: unityEditorPaths.executable,
46
+ projectTemplates: unityEditorPaths.projectTemplates,
47
+ },
48
+ hub: {
49
+ hubDir: environment.unityHubPath ?? unityHubPaths.hubDir,
50
+ projects: unityHubPaths.projects,
51
+ projectDir: unityHubPaths.projectDir,
52
+ },
53
+ templates: {
54
+ projectTemplates: environment.unityProjectTemplatePath ?? unityEditorPaths.projectTemplates,
55
+ },
56
+ platform,
57
+ architecture: os.arch(),
58
+ };
59
+ return settings;
60
+ }
61
+ }
62
+ const environment = {
63
+ unityHubPath: process.env.UNITY_HUB_PATH,
64
+ unityEditorPath: process.env.UNITY_EDITOR_PATH,
65
+ unityProjectPath: process.env.UNITY_PROJECT_PATH,
66
+ unityProjectTemplatePath: process.env.UNITY_PROJECT_TEMPLATE_PATH,
67
+ };
68
+ export { UnityConfig };
@@ -14,7 +14,7 @@ export interface InstallerEmitter extends EventEmitter {
14
14
  export declare class UnityHubInstallerEvent extends EventEmitter implements InstallerEmitter {
15
15
  #private;
16
16
  constructor();
17
- completed: Promise<InstallerEvent[]>;
17
+ get completed(): Promise<InstallerEvent[]>;
18
18
  Progress(raw: string): void;
19
19
  Cancel(): void;
20
20
  }
@@ -6,11 +6,30 @@ export class UnityHubInstallerEvent extends EventEmitter {
6
6
  constructor() {
7
7
  super();
8
8
  }
9
- completed = new Promise((resolve, reject) => {
10
- this.on(InstallerEventType.Completed, (events) => resolve(events));
11
- this.on(InstallerEventType.Error, (error) => reject(error));
12
- this.on(InstallerEventType.Cancelled, (events) => reject(new Error("Cancelled")));
13
- });
9
+ get completed() {
10
+ return new Promise((resolve, reject) => {
11
+ const onComplete = (events) => {
12
+ cleanup();
13
+ resolve(events);
14
+ };
15
+ const onError = (error) => {
16
+ cleanup();
17
+ reject(error);
18
+ };
19
+ const onCancel = () => {
20
+ cleanup();
21
+ reject(new Error("Cancelled"));
22
+ };
23
+ const cleanup = () => {
24
+ this.off(InstallerEventType.Completed, onComplete);
25
+ this.off(InstallerEventType.Error, onError);
26
+ this.off(InstallerEventType.Cancelled, onCancel);
27
+ };
28
+ this.on(InstallerEventType.Completed, onComplete);
29
+ this.on(InstallerEventType.Error, onError);
30
+ this.on(InstallerEventType.Cancelled, onCancel);
31
+ });
32
+ }
14
33
  Progress(raw) {
15
34
  const events = UnityHubEventParser.parseUnityHubEvent(raw);
16
35
  if (events.length === 0)
@@ -1,4 +1,6 @@
1
1
  export { default as UnityHub } from "./unityHub.ts";
2
2
  export { default as UnityEditor } from "./unityEditor.ts";
3
+ export { default as UnityTemplates } from "./unityTemplates.ts";
3
4
  export { UnityHubInstallerEvent } from "./events/hubEventEmitter.ts";
5
+ export { UnityConfig } from "./configs/unityConfig.ts";
4
6
  export * from "./types/unity.ts";
package/dist/esm/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  export { default as UnityHub } from "./unityHub.js";
2
2
  export { default as UnityEditor } from "./unityEditor.js";
3
+ export { default as UnityTemplates } from "./unityTemplates.js";
3
4
  export { UnityHubInstallerEvent } from "./events/hubEventEmitter.js";
5
+ export { UnityConfig } from "./configs/unityConfig.js";
4
6
  export * from "./types/unity.js";
@@ -2,6 +2,7 @@ import { ProjectInfo, TestMode, UnityBuildTarget, UnityEditorInfo } from "./type
2
2
  import { CommandOptions, CommandResult } from "./utils/commandExecutor.js";
3
3
  declare class UnityEditor {
4
4
  static getUnityExecutablePath(version: string): string;
5
+ static getUnityTemplatesPath(version: string): string;
5
6
  static isUnityVersionInstalled(version: string): Promise<boolean>;
6
7
  static execUnityEditorCommand(editorInfo: UnityEditorInfo, args: string[], options?: CommandOptions): Promise<CommandResult>;
7
8
  static executeMethod(projectInfo: ProjectInfo, method: string, args?: string[], options?: CommandOptions): Promise<CommandResult>;
@@ -13,7 +14,8 @@ declare class UnityEditor {
13
14
  static returnLicense(projectInfo: ProjectInfo): Promise<boolean>;
14
15
  static exportPackage(projectInfo: ProjectInfo, assetPaths: string[], outputPath: string): Promise<boolean>;
15
16
  static importPackage(projectInfo: ProjectInfo, packagePath: string): Promise<boolean>;
16
- static createProject(projectInfo: ProjectInfo, waitForExit?: boolean): Promise<boolean>;
17
+ static createProject(projectInfo: ProjectInfo, quit?: boolean, useHub?: boolean): Promise<boolean>;
18
+ static createProjectFromTemplate(projectInfo: ProjectInfo, templatePath: string, quit?: boolean, useHub?: boolean): Promise<boolean>;
17
19
  static openProject(projectInfo: ProjectInfo, useHub?: boolean, batchmode?: boolean, waitForExit?: boolean): Promise<boolean>;
18
20
  }
19
21
  export default UnityEditor;
@@ -1,28 +1,17 @@
1
- import os from "os";
2
1
  import fs from "fs-extra";
3
2
  import path from "path";
4
3
  import { TestMode } from "./types/unity.js";
5
4
  import { executeCommand } from "./utils/commandExecutor.js";
6
5
  import { redactSensitiveArgs } from "./utils/security.js";
6
+ import { UnityConfig } from "./configs/unityConfig.js";
7
7
  class UnityEditor {
8
- static UNITY_PATHS = {
9
- win32: {
10
- base: "C:/Program Files/Unity/Hub/Editor",
11
- executable: "Editor/Unity.exe",
12
- },
13
- darwin: {
14
- base: "/Applications/Unity/Hub/Editor",
15
- executable: "Unity.app/Contents/MacOS/Unity",
16
- },
17
- linux: {
18
- base: "/opt/unity/editor",
19
- executable: "Editor/Unity",
20
- },
21
- };
8
+ static unityConfig = UnityConfig.getPlatformConfig().editor;
22
9
  static getUnityExecutablePath(version) {
23
- const platform = os.platform();
24
- const unityConfig = UnityEditor.UNITY_PATHS[platform];
25
- const unityPath = path.join(unityConfig.base, version, unityConfig.executable);
10
+ const unityPath = path.join(this.unityConfig.base, version, this.unityConfig.executable);
11
+ return unityPath;
12
+ }
13
+ static getUnityTemplatesPath(version) {
14
+ const unityPath = path.join(this.unityConfig.base, version, this.unityConfig.projectTemplates);
26
15
  return unityPath;
27
16
  }
28
17
  static async isUnityVersionInstalled(version) {
@@ -222,15 +211,16 @@ class UnityEditor {
222
211
  return false;
223
212
  }
224
213
  }
225
- static async createProject(projectInfo, waitForExit = true) {
214
+ static async createProject(projectInfo, quit = false, useHub = true) {
226
215
  try {
227
216
  console.debug(`Creating new project at ${projectInfo.projectPath}`);
228
217
  const parentDir = path.dirname(projectInfo.projectPath);
229
218
  await fs.ensureDir(parentDir);
230
219
  const args = ["-createProject", projectInfo.projectPath];
231
- if (waitForExit) {
220
+ if (useHub)
221
+ args.push("-useHub", "-hubIPC");
222
+ if (quit)
232
223
  args.push("-quit");
233
- }
234
224
  const editorInfo = { version: projectInfo.editorVersion };
235
225
  const { stdout, stderr } = await this.execUnityEditorCommand(editorInfo, args, {
236
226
  reject: false,
@@ -250,19 +240,45 @@ class UnityEditor {
250
240
  return false;
251
241
  }
252
242
  }
243
+ static async createProjectFromTemplate(projectInfo, templatePath, quit = false, useHub = true) {
244
+ try {
245
+ console.debug(`Creating new project from template at ${projectInfo.projectPath}`);
246
+ const parentDir = path.dirname(projectInfo.projectPath);
247
+ await fs.ensureDir(parentDir);
248
+ const args = ["-createProject", projectInfo.projectPath, "-cloneFromTemplate", templatePath];
249
+ if (quit)
250
+ args.push("-quit");
251
+ if (useHub)
252
+ args.push("-useHub", "-hubIPC");
253
+ const editorInfo = { version: projectInfo.editorVersion };
254
+ const { stdout, stderr } = await this.execUnityEditorCommand(editorInfo, args, {
255
+ reject: false,
256
+ });
257
+ const creationSuccessful = !stdout.includes("Failed to create project") && !stderr.includes("Failed to create project");
258
+ if (creationSuccessful) {
259
+ console.debug(`Successfully created project from template at ${projectInfo.projectPath}`);
260
+ return true;
261
+ }
262
+ else {
263
+ console.error(`Failed to create project from template: ${stderr || stdout}`);
264
+ return false;
265
+ }
266
+ }
267
+ catch (error) {
268
+ console.error("Error creating project from template:", error);
269
+ return false;
270
+ }
271
+ }
253
272
  static async openProject(projectInfo, useHub = true, batchmode = false, waitForExit = true) {
254
273
  try {
255
274
  console.debug(`Opening project at ${projectInfo.projectPath}`);
256
275
  const args = ["-projectPath", projectInfo.projectPath];
257
- if (waitForExit) {
276
+ if (waitForExit)
258
277
  args.push("-quit");
259
- }
260
- if (batchmode) {
278
+ if (batchmode)
261
279
  args.push("-batchmode");
262
- }
263
- if (useHub) {
280
+ if (useHub)
264
281
  args.push(...["-useHub", "-hubIPC"]);
265
- }
266
282
  const editorInfo = { version: projectInfo.editorVersion };
267
283
  const options = { reject: false };
268
284
  const { stdout, stderr } = await this.execUnityEditorCommand(editorInfo, args, options);
@@ -2,7 +2,6 @@ import { EditorArchitecture, ModuleId, UnityInstallations } from "./types/unity.
2
2
  import { CommandOptions, CommandResult } from "./utils/commandExecutor.js";
3
3
  import { UnityHubInstallerEvent } from "./events/hubEventEmitter.ts";
4
4
  declare class UnityHub {
5
- private static CONFIG_PATHS;
6
5
  static getUnityHubPath(): string;
7
6
  static isUnityHubAvailable(): Promise<boolean>;
8
7
  static execUnityHubCommand(args: string[], options?: CommandOptions): Promise<CommandResult>;
@@ -1,46 +1,25 @@
1
1
  import fs from "fs-extra";
2
2
  import os from "os";
3
- import path from "path";
4
3
  import { EditorArchitecture, } from "./types/unity.js";
5
4
  import { executeCommand } from "./utils/commandExecutor.js";
6
5
  import { getUnityChangeset } from "unity-changeset";
7
6
  import { UnityHubInstallerEvent } from "./events/hubEventEmitter.js";
7
+ import { UnityConfig } from "./configs/unityConfig.js";
8
8
  class UnityHub {
9
- static CONFIG_PATHS = {
10
- win32: {
11
- hub: "C:\\Program Files\\Unity Hub\\Unity Hub.exe",
12
- projects: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projects-v1.json"),
13
- projectDir: path.join(os.homedir(), "AppData", "Roaming", "UnityHub", "projectDir.json"),
14
- },
15
- darwin: {
16
- hub: "/Applications/Unity Hub.app/Contents/MacOS/Unity Hub",
17
- projects: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projects-v1.json"),
18
- projectDir: path.join(os.homedir(), "Library", "Application Support", "UnityHub", "projectDir.json"),
19
- },
20
- linux: {
21
- hub: "/opt/UnityHub/UnityHub",
22
- projects: path.join(os.homedir(), ".config", "UnityHub", "projects-v1.json"),
23
- projectDir: path.join(os.homedir(), ".config", "UnityHub", "projectDir.json"),
24
- },
25
- };
26
- static platform = os.platform();
27
- static hubPath = this.getUnityHubPath();
9
+ static unityConfig = UnityConfig.getPlatformConfig();
28
10
  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 || "";
11
+ return this.unityConfig.hub.hubDir;
34
12
  }
35
13
  static getProjectsPath() {
36
- return UnityHub.CONFIG_PATHS[this.platform].projects || "";
14
+ return this.unityConfig.hub.projects;
37
15
  }
38
16
  static getProjectDirPath() {
39
- return UnityHub.CONFIG_PATHS[this.platform].projectDir || "";
17
+ return this.unityConfig.hub.projectDir;
40
18
  }
41
19
  static async isUnityHubAvailable() {
42
20
  try {
43
- return !!this.hubPath && fs.existsSync(this.hubPath);
21
+ const hubPath = this.getUnityHubPath();
22
+ return !!hubPath && fs.existsSync(hubPath);
44
23
  }
45
24
  catch (error) {
46
25
  console.error("Error checking Unity Hub availability:", error);
@@ -59,9 +38,9 @@ class UnityHub {
59
38
  };
60
39
  }
61
40
  try {
62
- const hubArgs = [this.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
63
- console.debug(`Executing Unity Hub command: ${this.hubPath} ${hubArgs.join(" ")}`);
64
- return await executeCommand(this.hubPath, hubArgs, options);
41
+ const hubArgs = [this.unityConfig.platform !== "linux" ? "--" : "", "--headless", ...args].filter(Boolean);
42
+ console.debug(`Executing Unity Hub command: ${this.getUnityHubPath()} ${hubArgs.join(" ")}`);
43
+ return await executeCommand(this.unityConfig.hub.hubDir, hubArgs, options);
65
44
  }
66
45
  catch (error) {
67
46
  console.error("Error executing Unity Hub command:", error);
@@ -0,0 +1,10 @@
1
+ interface ProjectTemplates {
2
+ templateName: string;
3
+ templatePath: string;
4
+ }
5
+ declare class UnityTemplates {
6
+ private static getProjectTemplatesPath;
7
+ private static getProjectTemplatesPathForVersion;
8
+ static getProjectTemplates(version: string): ProjectTemplates[];
9
+ }
10
+ export default UnityTemplates;
@@ -0,0 +1,24 @@
1
+ import path from "path";
2
+ import fs from "fs-extra";
3
+ import { UnityConfig } from "./configs/unityConfig.js";
4
+ class UnityTemplates {
5
+ static unityConfig = UnityConfig.getPlatformConfig();
6
+ static getProjectTemplatesPath() {
7
+ return this.unityConfig.templates.projectTemplates;
8
+ }
9
+ static getProjectTemplatesPathForVersion(version) {
10
+ return path.join(this.unityConfig.editor.base, version, this.getProjectTemplatesPath());
11
+ }
12
+ static getProjectTemplates(version) {
13
+ const templatePath = this.getProjectTemplatesPathForVersion(version);
14
+ if (!fs.existsSync(templatePath)) {
15
+ throw new Error(`Template path does not exist: ${templatePath}`);
16
+ }
17
+ const templates = fs.readdirSync(templatePath).filter((file) => path.extname(file) === ".tgz");
18
+ return templates.map((template) => ({
19
+ templateName: path.basename(template, ".tgz"),
20
+ templatePath: path.join(templatePath, template),
21
+ }));
22
+ }
23
+ }
24
+ export default UnityTemplates;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notask/unity-cli-tools",
3
- "version": "1.1.1",
3
+ "version": "1.2.0-rc.1",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/esm/index.d.ts",