@unibridge/cli 0.5.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/dist/commands/domain.d.ts +11 -0
- package/dist/commands/domain.d.ts.map +1 -0
- package/dist/commands/domain.js +27 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/execute.d.ts +10 -0
- package/dist/commands/execute.d.ts.map +1 -0
- package/dist/commands/execute.js +27 -0
- package/dist/commands/execute.js.map +1 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +30 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/output.d.ts +6 -0
- package/dist/commands/output.d.ts.map +1 -0
- package/dist/commands/output.js +21 -0
- package/dist/commands/output.js.map +1 -0
- package/dist/commands/scene.d.ts +23 -0
- package/dist/commands/scene.d.ts.map +1 -0
- package/dist/commands/scene.js +71 -0
- package/dist/commands/scene.js.map +1 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +28 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/with-unity-client.d.ts +12 -0
- package/dist/commands/with-unity-client.d.ts.map +1 -0
- package/dist/commands/with-unity-client.js +27 -0
- package/dist/commands/with-unity-client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/options.d.ts +8 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +4 -0
- package/dist/options.js.map +1 -0
- package/dist/preflight.d.ts +8 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +18 -0
- package/dist/preflight.js.map +1 -0
- package/package.json +22 -0
- package/src/commands/domain.ts +49 -0
- package/src/commands/execute.ts +48 -0
- package/src/commands/init.ts +56 -0
- package/src/commands/output.ts +29 -0
- package/src/commands/scene.ts +135 -0
- package/src/commands/status.ts +49 -0
- package/src/commands/with-unity-client.ts +47 -0
- package/src/index.ts +29 -0
- package/src/options.ts +11 -0
- package/src/preflight.test.ts +39 -0
- package/src/preflight.ts +23 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { DomainReloadResult } from '@unibridge/sdk';
|
|
3
|
+
interface DomainReloadDeps {
|
|
4
|
+
reload: () => Promise<DomainReloadResult>;
|
|
5
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
6
|
+
exit?: (code: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function handleDomainReload(jsonOutput: boolean, deps: DomainReloadDeps): Promise<void>;
|
|
9
|
+
export declare function registerDomain(program: Command): void;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAIxD,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACzC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBrD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { runWithOutput } from "./output.js";
|
|
2
|
+
import { withUnityClient } from "./with-unity-client.js";
|
|
3
|
+
export async function handleDomainReload(jsonOutput, deps) {
|
|
4
|
+
await runWithOutput(jsonOutput, deps, () => deps.reload(), (_result, output) => {
|
|
5
|
+
output.log('Domain reload triggered.');
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export function registerDomain(program) {
|
|
9
|
+
const domain = program
|
|
10
|
+
.command('domain')
|
|
11
|
+
.description('Unity domain operations');
|
|
12
|
+
domain
|
|
13
|
+
.command('reload')
|
|
14
|
+
.description('Trigger an asset refresh and domain reload')
|
|
15
|
+
.action(async (_opts, command) => {
|
|
16
|
+
await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
|
|
17
|
+
await handleDomainReload(ctx.jsonOutput, {
|
|
18
|
+
reload: () => client.domainReload(),
|
|
19
|
+
console,
|
|
20
|
+
exit: (exitCode) => {
|
|
21
|
+
process.exitCode = exitCode;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/commands/domain.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAmB,EACnB,IAAsB;IAEtB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EACnB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAClB,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAA;IACxC,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yBAAyB,CAAC,CAAA;IAEzC,MAAM;SACH,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC/D,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,kBAAkB,CAAC,GAAG,CAAC,UAAU,EAAE;gBACvC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE;gBACnC,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
interface ExecuteDeps {
|
|
3
|
+
execute: (code: string) => Promise<unknown>;
|
|
4
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
5
|
+
exit?: (code: number) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function handleExecute(code: string, jsonOutput: boolean, deps: ExecuteDeps): Promise<void>;
|
|
8
|
+
export declare function registerExecute(program: Command): void;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIxC,UAAU,WAAW;IACnB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsBtD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { runWithOutput } from "./output.js";
|
|
2
|
+
import { withUnityClient } from "./with-unity-client.js";
|
|
3
|
+
export async function handleExecute(code, jsonOutput, deps) {
|
|
4
|
+
await runWithOutput(jsonOutput, deps, () => deps.execute(code), (result, output) => {
|
|
5
|
+
output.log(String(result));
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
export function registerExecute(program) {
|
|
9
|
+
program
|
|
10
|
+
.command('execute <code>')
|
|
11
|
+
.description('Execute C# code in the Unity Editor')
|
|
12
|
+
.action(async (code, _opts, command) => {
|
|
13
|
+
await withUnityClient(command, {
|
|
14
|
+
requirePlugin: true,
|
|
15
|
+
requiresExecute: true,
|
|
16
|
+
}, async (client, ctx) => {
|
|
17
|
+
await handleExecute(code, ctx.jsonOutput, {
|
|
18
|
+
execute: (requestCode) => client.execute(requestCode),
|
|
19
|
+
console,
|
|
20
|
+
exit: (exitCode) => {
|
|
21
|
+
process.exitCode = exitCode;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/commands/execute.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAY,EACZ,UAAmB,EACnB,IAAiB;IAEjB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EACxB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5B,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC7E,MAAM,eAAe,CACnB,OAAO,EACP;YACE,aAAa,EAAE,IAAI;YACnB,eAAe,EAAE,IAAI;SACtB,EACD,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE;gBACxC,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;gBACrD,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type InitOptions, type InitResult } from '@unibridge/sdk';
|
|
3
|
+
interface InitCommandOptions {
|
|
4
|
+
local?: string;
|
|
5
|
+
git?: string;
|
|
6
|
+
}
|
|
7
|
+
interface InitHandlerDeps {
|
|
8
|
+
init: (options?: InitOptions) => Promise<InitResult>;
|
|
9
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
10
|
+
}
|
|
11
|
+
export declare function handleInit(opts: InitCommandOptions, jsonOutput: boolean, deps?: InitHandlerDeps): Promise<void>;
|
|
12
|
+
export declare function registerInit(program: Command): void;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAInF,UAAU,kBAAkB;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IACpD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;CACxC;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,kBAAkB,EACxB,UAAU,EAAE,OAAO,EACnB,IAAI,GAAE,eAA4C,GACjD,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBnD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { init as sdkInit } from '@unibridge/sdk';
|
|
2
|
+
import { getGlobalOptions } from "../options.js";
|
|
3
|
+
import { runWithOutput } from "./output.js";
|
|
4
|
+
export async function handleInit(opts, jsonOutput, deps = { init: sdkInit, console }) {
|
|
5
|
+
const source = opts.local
|
|
6
|
+
? { type: 'local', path: opts.local }
|
|
7
|
+
: opts.git
|
|
8
|
+
? { type: 'git', url: opts.git }
|
|
9
|
+
: undefined;
|
|
10
|
+
await runWithOutput(jsonOutput, deps, () => deps.init({ source }), (result, output) => {
|
|
11
|
+
output.log(`Found Unity ${result.unityVersion} at ${result.projectPath}`);
|
|
12
|
+
output.log(`Installed com.msanatan.unibridge@${result.pluginVersion}`);
|
|
13
|
+
output.log('Open Unity to load the plugin.');
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export function registerInit(program) {
|
|
17
|
+
program
|
|
18
|
+
.command('init')
|
|
19
|
+
.description('Install the unibridge plugin into a Unity project')
|
|
20
|
+
.option('--local <path>', 'Install from a local path')
|
|
21
|
+
.option('--git <url>', 'Install from a custom git URL')
|
|
22
|
+
.action(async (opts, command) => {
|
|
23
|
+
const globalOpts = getGlobalOptions(command);
|
|
24
|
+
await handleInit(opts, globalOpts.json === true, {
|
|
25
|
+
init: (initOpts) => sdkInit({ ...initOpts, projectPath: globalOpts.project }),
|
|
26
|
+
console,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,IAAI,OAAO,EAAqC,MAAM,gBAAgB,CAAA;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAY3C,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAwB,EACxB,UAAmB,EACnB,OAAwB,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;IAElD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK;QACvB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAgB,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE;QAC9C,CAAC,CAAC,IAAI,CAAC,GAAG;YACR,CAAC,CAAC,EAAE,IAAI,EAAE,KAAc,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;YACzC,CAAC,CAAC,SAAS,CAAA;IAEf,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAC3B,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,YAAY,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QACzE,MAAM,CAAC,GAAG,CAAC,oCAAoC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAA;QACtE,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAA;IAC9C,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,gBAAgB,EAAE,2BAA2B,CAAC;SACrD,MAAM,CAAC,aAAa,EAAE,+BAA+B,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,OAAgB,EAAE,EAAE;QAC3D,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,UAAU,CACd,IAAI,EACJ,UAAU,CAAC,IAAI,KAAK,IAAI,EACxB;YACE,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC;YAC7E,OAAO;SACR,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface CommandOutputDeps {
|
|
2
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
3
|
+
exit?: (code: number) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare function runWithOutput<TResult>(jsonOutput: boolean, deps: CommandOutputDeps, execute: () => Promise<TResult>, renderText: (result: TResult, consoleLike: Pick<Console, 'log'>) => void): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/commands/output.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,aAAa,CAAC,OAAO,EACzC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC/B,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,IAAI,GACvE,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export async function runWithOutput(jsonOutput, deps, execute, renderText) {
|
|
2
|
+
try {
|
|
3
|
+
const result = await execute();
|
|
4
|
+
if (jsonOutput) {
|
|
5
|
+
deps.console.log(JSON.stringify({ success: true, result }));
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
renderText(result, deps.console);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12
|
+
if (jsonOutput) {
|
|
13
|
+
deps.console.log(JSON.stringify({ success: false, error: message }));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
deps.console.error(`Error: ${message}`);
|
|
17
|
+
}
|
|
18
|
+
deps.exit?.(1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/commands/output.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAmB,EACnB,IAAuB,EACvB,OAA+B,EAC/B,UAAwE;IAExE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;QAC9B,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;YAC3D,OAAM;QACR,CAAC;QAED,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtE,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACtE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAA;QACzC,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { SceneActiveResult, SceneCreateResult, SceneOpenResult } from '@unibridge/sdk';
|
|
3
|
+
interface SceneActiveDeps {
|
|
4
|
+
active: () => Promise<SceneActiveResult>;
|
|
5
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
6
|
+
exit?: (code: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function handleSceneActive(jsonOutput: boolean, deps: SceneActiveDeps): Promise<void>;
|
|
9
|
+
interface SceneOpenDeps {
|
|
10
|
+
open: (path: string) => Promise<SceneOpenResult>;
|
|
11
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
12
|
+
exit?: (code: number) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function handleSceneOpen(path: string, jsonOutput: boolean, deps: SceneOpenDeps): Promise<void>;
|
|
15
|
+
interface SceneCreateDeps {
|
|
16
|
+
create: (path: string) => Promise<SceneCreateResult>;
|
|
17
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
18
|
+
exit?: (code: number) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function handleSceneCreate(path: string, jsonOutput: boolean, deps: SceneCreateDeps): Promise<void>;
|
|
21
|
+
export declare function registerScene(program: Command): void;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../src/commands/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAI3F,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACxC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;IAChD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,UAAU,eAAe;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACpD,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6DpD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { runWithOutput } from "./output.js";
|
|
2
|
+
import { withUnityClient } from "./with-unity-client.js";
|
|
3
|
+
export async function handleSceneActive(jsonOutput, deps) {
|
|
4
|
+
await runWithOutput(jsonOutput, deps, () => deps.active(), (result, output) => {
|
|
5
|
+
output.log(`Name: ${result.scene.name}`);
|
|
6
|
+
output.log(`Path: ${result.scene.path}`);
|
|
7
|
+
output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`);
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function handleSceneOpen(path, jsonOutput, deps) {
|
|
11
|
+
await runWithOutput(jsonOutput, deps, () => deps.open(path), (result, output) => {
|
|
12
|
+
output.log(`Name: ${result.scene.name}`);
|
|
13
|
+
output.log(`Path: ${result.scene.path}`);
|
|
14
|
+
output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function handleSceneCreate(path, jsonOutput, deps) {
|
|
18
|
+
await runWithOutput(jsonOutput, deps, () => deps.create(path), (result, output) => {
|
|
19
|
+
output.log(`Name: ${result.scene.name}`);
|
|
20
|
+
output.log(`Path: ${result.scene.path}`);
|
|
21
|
+
output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function registerScene(program) {
|
|
25
|
+
const scene = program
|
|
26
|
+
.command('scene')
|
|
27
|
+
.description('Read and modify Unity scenes');
|
|
28
|
+
scene
|
|
29
|
+
.command('active')
|
|
30
|
+
.description('Show the active scene')
|
|
31
|
+
.action(async (_opts, command) => {
|
|
32
|
+
await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
|
|
33
|
+
await handleSceneActive(ctx.jsonOutput, {
|
|
34
|
+
active: () => client.sceneActive(),
|
|
35
|
+
console,
|
|
36
|
+
exit: (exitCode) => {
|
|
37
|
+
process.exitCode = exitCode;
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
scene
|
|
43
|
+
.command('create <path>')
|
|
44
|
+
.description('Create a new scene at a project-relative path')
|
|
45
|
+
.action(async (path, _opts, command) => {
|
|
46
|
+
await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
|
|
47
|
+
await handleSceneCreate(path, ctx.jsonOutput, {
|
|
48
|
+
create: (scenePath) => client.sceneCreate(scenePath),
|
|
49
|
+
console,
|
|
50
|
+
exit: (exitCode) => {
|
|
51
|
+
process.exitCode = exitCode;
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
scene
|
|
57
|
+
.command('open <path>')
|
|
58
|
+
.description('Open a scene by project-relative path')
|
|
59
|
+
.action(async (path, _opts, command) => {
|
|
60
|
+
await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
|
|
61
|
+
await handleSceneOpen(path, ctx.jsonOutput, {
|
|
62
|
+
open: (scenePath) => client.sceneOpen(scenePath),
|
|
63
|
+
console,
|
|
64
|
+
exit: (exitCode) => {
|
|
65
|
+
process.exitCode = exitCode;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=scene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.js","sourceRoot":"","sources":["../../src/commands/scene.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import type { StatusResult } from '@unibridge/sdk';
|
|
3
|
+
interface StatusDeps {
|
|
4
|
+
status: () => Promise<StatusResult>;
|
|
5
|
+
console: Pick<Console, 'log' | 'error'>;
|
|
6
|
+
exit?: (code: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function handleStatus(jsonOutput: boolean, deps: StatusDeps): Promise<void>;
|
|
9
|
+
export declare function registerStatus(program: Command): void;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAA;IACnC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,OAAO,CAAC,CAAA;IACvC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmBrD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { runWithOutput } from "./output.js";
|
|
2
|
+
import { withUnityClient } from "./with-unity-client.js";
|
|
3
|
+
export async function handleStatus(jsonOutput, deps) {
|
|
4
|
+
await runWithOutput(jsonOutput, deps, () => deps.status(), (result, output) => {
|
|
5
|
+
output.log(`Project: ${result.projectPath}`);
|
|
6
|
+
output.log(`Unity: ${result.unityVersion}`);
|
|
7
|
+
output.log(`Plugin: ${result.pluginVersion}`);
|
|
8
|
+
output.log(`Scene: ${result.activeScene}`);
|
|
9
|
+
output.log(`Mode: ${result.playMode}`);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export function registerStatus(program) {
|
|
13
|
+
program
|
|
14
|
+
.command('status')
|
|
15
|
+
.description('Show the current state of the Unity Editor')
|
|
16
|
+
.action(async (_opts, command) => {
|
|
17
|
+
await withUnityClient(command, { requirePlugin: true }, async (client, ctx) => {
|
|
18
|
+
await handleStatus(ctx.jsonOutput, {
|
|
19
|
+
status: () => client.status(),
|
|
20
|
+
console,
|
|
21
|
+
exit: (exitCode) => {
|
|
22
|
+
process.exitCode = exitCode;
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAQxD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAmB,EACnB,IAAgB;IAEhB,MAAM,aAAa,CACjB,UAAU,EACV,IAAI,EACJ,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EACnB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QAC5C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,YAAY,EAAE,CAAC,CAAA;QAC7C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,aAAa,EAAE,CAAC,CAAA;QAC9C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,WAAW,EAAE,CAAC,CAAA;QAC5C,MAAM,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC3C,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,KAA4B,EAAE,OAAgB,EAAE,EAAE;QAC/D,MAAM,eAAe,CACnB,OAAO,EACP,EAAE,aAAa,EAAE,IAAI,EAAE,EACvB,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE;gBACjC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE;gBAC7B,OAAO;gBACP,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACjB,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA;gBAC7B,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CACF,CAAA;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { createClient } from '@unibridge/sdk';
|
|
3
|
+
interface ClientCommandRequirements {
|
|
4
|
+
requirePlugin: boolean;
|
|
5
|
+
requiresExecute?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface GlobalCommandContext {
|
|
8
|
+
jsonOutput: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function withUnityClient(command: Command, requirements: ClientCommandRequirements, run: (client: ReturnType<typeof createClient>, ctx: GlobalCommandContext) => Promise<void>): Promise<void>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=with-unity-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-unity-client.d.ts","sourceRoot":"","sources":["../../src/commands/with-unity-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAI7C,UAAU,yBAAyB;IACjC,aAAa,EAAE,OAAO,CAAA;IACtB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,UAAU,oBAAoB;IAC5B,UAAU,EAAE,OAAO,CAAA;CACpB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,yBAAyB,EACvC,GAAG,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,EAAE,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,GACzF,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createClient } from '@unibridge/sdk';
|
|
2
|
+
import { getGlobalOptions } from "../options.js";
|
|
3
|
+
import { resolveCommandProject } from "../preflight.js";
|
|
4
|
+
export async function withUnityClient(command, requirements, run) {
|
|
5
|
+
let client;
|
|
6
|
+
try {
|
|
7
|
+
const globalOpts = getGlobalOptions(command);
|
|
8
|
+
const envExecute = process.env.UNIBRIDGE_ENABLE_EXECUTE !== '0';
|
|
9
|
+
const executeEnabled = globalOpts.execute !== false && envExecute;
|
|
10
|
+
const projectPath = resolveCommandProject({
|
|
11
|
+
project: globalOpts.project,
|
|
12
|
+
execute: executeEnabled,
|
|
13
|
+
}, requirements);
|
|
14
|
+
client = createClient({
|
|
15
|
+
projectPath,
|
|
16
|
+
enableExecute: executeEnabled,
|
|
17
|
+
connectTimeout: 10_000,
|
|
18
|
+
});
|
|
19
|
+
await run(client, {
|
|
20
|
+
jsonOutput: globalOpts.json === true,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
client?.close();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=with-unity-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-unity-client.js","sourceRoot":"","sources":["../../src/commands/with-unity-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAWvD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,YAAuC,EACvC,GAA0F;IAE1F,IAAI,MAAmD,CAAA;IAEvD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;QAC5C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG,CAAA;QAC/D,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,KAAK,KAAK,IAAI,UAAU,CAAA;QAEjE,MAAM,WAAW,GAAG,qBAAqB,CACvC;YACE,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,OAAO,EAAE,cAAc;SACxB,EACD,YAAY,CACb,CAAA;QAED,MAAM,GAAG,YAAY,CAAC;YACpB,WAAW;YACX,aAAa,EAAE,cAAc;YAC7B,cAAc,EAAE,MAAM;SACvB,CAAC,CAAA;QAEF,MAAM,GAAG,CAAC,MAAM,EAAE;YAChB,UAAU,EAAE,UAAU,CAAC,IAAI,KAAK,IAAI;SACrC,CAAC,CAAA;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,KAAK,EAAE,CAAA;IACjB,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { program } from 'commander';
|
|
5
|
+
import { registerDomain } from "./commands/domain.js";
|
|
6
|
+
import { registerInit } from "./commands/init.js";
|
|
7
|
+
import { registerExecute } from "./commands/execute.js";
|
|
8
|
+
import { registerStatus } from "./commands/status.js";
|
|
9
|
+
import { registerScene } from "./commands/scene.js";
|
|
10
|
+
const { version } = JSON.parse(readFileSync(path.join(import.meta.dirname, '..', 'package.json'), 'utf-8'));
|
|
11
|
+
program
|
|
12
|
+
.name('unibridge')
|
|
13
|
+
.description('Bridge between Unity and your code')
|
|
14
|
+
.version(version)
|
|
15
|
+
.option('-p, --project <path>', 'Path to Unity project')
|
|
16
|
+
.option('--json', 'Output result as JSON')
|
|
17
|
+
.option('--no-execute', 'Disable execute tool for this invocation');
|
|
18
|
+
registerDomain(program);
|
|
19
|
+
registerInit(program);
|
|
20
|
+
registerExecute(program);
|
|
21
|
+
registerStatus(program);
|
|
22
|
+
registerScene(program);
|
|
23
|
+
program.parse();
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CACrD,CAAA;AAExB,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,oCAAoC,CAAC;KACjD,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;KACvD,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;KACzC,MAAM,CAAC,cAAc,EAAE,0CAA0C,CAAC,CAAA;AAErE,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,aAAa,CAAC,OAAO,CAAC,CAAA;AAEtB,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
export interface GlobalCommandOptions {
|
|
3
|
+
project?: string;
|
|
4
|
+
json?: boolean;
|
|
5
|
+
execute?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function getGlobalOptions(command: Command): GlobalCommandOptions;
|
|
8
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,CAEvE"}
|
package/dist/options.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,gBAAgB,CAAC,OAAgB;IAC/C,OAAO,OAAO,CAAC,eAAe,EAA0B,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.d.ts","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EAC7C,MAAM,EAAE;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5D,MAAM,CAiBR"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { findUnityProject, isPluginInstalled } from '@unibridge/sdk';
|
|
2
|
+
export function resolveCommandProject(opts, config) {
|
|
3
|
+
let projectPath;
|
|
4
|
+
try {
|
|
5
|
+
projectPath = findUnityProject(opts.project);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
throw new Error('Unity project not found. Run inside a Unity project or pass --project <path>.');
|
|
9
|
+
}
|
|
10
|
+
if (config.requiresExecute && opts.execute === false) {
|
|
11
|
+
throw new Error('Execute is disabled for this invocation (--no-execute).');
|
|
12
|
+
}
|
|
13
|
+
if (config.requirePlugin && !isPluginInstalled(projectPath)) {
|
|
14
|
+
throw new Error('com.msanatan.unibridge is not installed. Run `unibridge init` first.');
|
|
15
|
+
}
|
|
16
|
+
return projectPath;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAEpE,MAAM,UAAU,qBAAqB,CACnC,IAA6C,EAC7C,MAA6D;IAE7D,IAAI,WAAmB,CAAA;IACvB,IAAI,CAAC;QACH,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;IAClG,CAAC;IAED,IAAI,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAA;IAC5E,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAA;IACzF,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@unibridge/cli",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node --test src/*.test.ts src/**/*.test.ts",
|
|
8
|
+
"build": "tsc -p tsconfig.json",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"bin": {
|
|
16
|
+
"unibridge": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@unibridge/sdk": "0.5.0",
|
|
20
|
+
"commander": "^14.0.3"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import type { DomainReloadResult } from '@unibridge/sdk'
|
|
3
|
+
import { runWithOutput } from './output.ts'
|
|
4
|
+
import { withUnityClient } from './with-unity-client.ts'
|
|
5
|
+
|
|
6
|
+
interface DomainReloadDeps {
|
|
7
|
+
reload: () => Promise<DomainReloadResult>
|
|
8
|
+
console: Pick<Console, 'log' | 'error'>
|
|
9
|
+
exit?: (code: number) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function handleDomainReload(
|
|
13
|
+
jsonOutput: boolean,
|
|
14
|
+
deps: DomainReloadDeps,
|
|
15
|
+
): Promise<void> {
|
|
16
|
+
await runWithOutput(
|
|
17
|
+
jsonOutput,
|
|
18
|
+
deps,
|
|
19
|
+
() => deps.reload(),
|
|
20
|
+
(_result, output) => {
|
|
21
|
+
output.log('Domain reload triggered.')
|
|
22
|
+
},
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function registerDomain(program: Command): void {
|
|
27
|
+
const domain = program
|
|
28
|
+
.command('domain')
|
|
29
|
+
.description('Unity domain operations')
|
|
30
|
+
|
|
31
|
+
domain
|
|
32
|
+
.command('reload')
|
|
33
|
+
.description('Trigger an asset refresh and domain reload')
|
|
34
|
+
.action(async (_opts: Record<string, never>, command: Command) => {
|
|
35
|
+
await withUnityClient(
|
|
36
|
+
command,
|
|
37
|
+
{ requirePlugin: true },
|
|
38
|
+
async (client, ctx) => {
|
|
39
|
+
await handleDomainReload(ctx.jsonOutput, {
|
|
40
|
+
reload: () => client.domainReload(),
|
|
41
|
+
console,
|
|
42
|
+
exit: (exitCode) => {
|
|
43
|
+
process.exitCode = exitCode
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
},
|
|
47
|
+
)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import { runWithOutput } from './output.ts'
|
|
3
|
+
import { withUnityClient } from './with-unity-client.ts'
|
|
4
|
+
|
|
5
|
+
interface ExecuteDeps {
|
|
6
|
+
execute: (code: string) => Promise<unknown>
|
|
7
|
+
console: Pick<Console, 'log' | 'error'>
|
|
8
|
+
exit?: (code: number) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function handleExecute(
|
|
12
|
+
code: string,
|
|
13
|
+
jsonOutput: boolean,
|
|
14
|
+
deps: ExecuteDeps,
|
|
15
|
+
): Promise<void> {
|
|
16
|
+
await runWithOutput(
|
|
17
|
+
jsonOutput,
|
|
18
|
+
deps,
|
|
19
|
+
() => deps.execute(code),
|
|
20
|
+
(result, output) => {
|
|
21
|
+
output.log(String(result))
|
|
22
|
+
},
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function registerExecute(program: Command): void {
|
|
27
|
+
program
|
|
28
|
+
.command('execute <code>')
|
|
29
|
+
.description('Execute C# code in the Unity Editor')
|
|
30
|
+
.action(async (code: string, _opts: Record<string, never>, command: Command) => {
|
|
31
|
+
await withUnityClient(
|
|
32
|
+
command,
|
|
33
|
+
{
|
|
34
|
+
requirePlugin: true,
|
|
35
|
+
requiresExecute: true,
|
|
36
|
+
},
|
|
37
|
+
async (client, ctx) => {
|
|
38
|
+
await handleExecute(code, ctx.jsonOutput, {
|
|
39
|
+
execute: (requestCode) => client.execute(requestCode),
|
|
40
|
+
console,
|
|
41
|
+
exit: (exitCode) => {
|
|
42
|
+
process.exitCode = exitCode
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import { init as sdkInit, type InitOptions, type InitResult } from '@unibridge/sdk'
|
|
3
|
+
import { getGlobalOptions } from '../options.ts'
|
|
4
|
+
import { runWithOutput } from './output.ts'
|
|
5
|
+
|
|
6
|
+
interface InitCommandOptions {
|
|
7
|
+
local?: string
|
|
8
|
+
git?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface InitHandlerDeps {
|
|
12
|
+
init: (options?: InitOptions) => Promise<InitResult>
|
|
13
|
+
console: Pick<Console, 'log' | 'error'>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function handleInit(
|
|
17
|
+
opts: InitCommandOptions,
|
|
18
|
+
jsonOutput: boolean,
|
|
19
|
+
deps: InitHandlerDeps = { init: sdkInit, console },
|
|
20
|
+
): Promise<void> {
|
|
21
|
+
const source = opts.local
|
|
22
|
+
? { type: 'local' as const, path: opts.local }
|
|
23
|
+
: opts.git
|
|
24
|
+
? { type: 'git' as const, url: opts.git }
|
|
25
|
+
: undefined
|
|
26
|
+
|
|
27
|
+
await runWithOutput(
|
|
28
|
+
jsonOutput,
|
|
29
|
+
deps,
|
|
30
|
+
() => deps.init({ source }),
|
|
31
|
+
(result, output) => {
|
|
32
|
+
output.log(`Found Unity ${result.unityVersion} at ${result.projectPath}`)
|
|
33
|
+
output.log(`Installed com.msanatan.unibridge@${result.pluginVersion}`)
|
|
34
|
+
output.log('Open Unity to load the plugin.')
|
|
35
|
+
},
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function registerInit(program: Command): void {
|
|
40
|
+
program
|
|
41
|
+
.command('init')
|
|
42
|
+
.description('Install the unibridge plugin into a Unity project')
|
|
43
|
+
.option('--local <path>', 'Install from a local path')
|
|
44
|
+
.option('--git <url>', 'Install from a custom git URL')
|
|
45
|
+
.action(async (opts: InitCommandOptions, command: Command) => {
|
|
46
|
+
const globalOpts = getGlobalOptions(command)
|
|
47
|
+
await handleInit(
|
|
48
|
+
opts,
|
|
49
|
+
globalOpts.json === true,
|
|
50
|
+
{
|
|
51
|
+
init: (initOpts) => sdkInit({ ...initOpts, projectPath: globalOpts.project }),
|
|
52
|
+
console,
|
|
53
|
+
},
|
|
54
|
+
)
|
|
55
|
+
})
|
|
56
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface CommandOutputDeps {
|
|
2
|
+
console: Pick<Console, 'log' | 'error'>
|
|
3
|
+
exit?: (code: number) => void
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export async function runWithOutput<TResult>(
|
|
7
|
+
jsonOutput: boolean,
|
|
8
|
+
deps: CommandOutputDeps,
|
|
9
|
+
execute: () => Promise<TResult>,
|
|
10
|
+
renderText: (result: TResult, consoleLike: Pick<Console, 'log'>) => void,
|
|
11
|
+
): Promise<void> {
|
|
12
|
+
try {
|
|
13
|
+
const result = await execute()
|
|
14
|
+
if (jsonOutput) {
|
|
15
|
+
deps.console.log(JSON.stringify({ success: true, result }))
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
renderText(result, deps.console)
|
|
20
|
+
} catch (error) {
|
|
21
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
22
|
+
if (jsonOutput) {
|
|
23
|
+
deps.console.log(JSON.stringify({ success: false, error: message }))
|
|
24
|
+
} else {
|
|
25
|
+
deps.console.error(`Error: ${message}`)
|
|
26
|
+
}
|
|
27
|
+
deps.exit?.(1)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import type { SceneActiveResult, SceneCreateResult, SceneOpenResult } from '@unibridge/sdk'
|
|
3
|
+
import { runWithOutput } from './output.ts'
|
|
4
|
+
import { withUnityClient } from './with-unity-client.ts'
|
|
5
|
+
|
|
6
|
+
interface SceneActiveDeps {
|
|
7
|
+
active: () => Promise<SceneActiveResult>
|
|
8
|
+
console: Pick<Console, 'log' | 'error'>
|
|
9
|
+
exit?: (code: number) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function handleSceneActive(
|
|
13
|
+
jsonOutput: boolean,
|
|
14
|
+
deps: SceneActiveDeps,
|
|
15
|
+
): Promise<void> {
|
|
16
|
+
await runWithOutput(
|
|
17
|
+
jsonOutput,
|
|
18
|
+
deps,
|
|
19
|
+
() => deps.active(),
|
|
20
|
+
(result, output) => {
|
|
21
|
+
output.log(`Name: ${result.scene.name}`)
|
|
22
|
+
output.log(`Path: ${result.scene.path}`)
|
|
23
|
+
output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`)
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface SceneOpenDeps {
|
|
29
|
+
open: (path: string) => Promise<SceneOpenResult>
|
|
30
|
+
console: Pick<Console, 'log' | 'error'>
|
|
31
|
+
exit?: (code: number) => void
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function handleSceneOpen(
|
|
35
|
+
path: string,
|
|
36
|
+
jsonOutput: boolean,
|
|
37
|
+
deps: SceneOpenDeps,
|
|
38
|
+
): Promise<void> {
|
|
39
|
+
await runWithOutput(
|
|
40
|
+
jsonOutput,
|
|
41
|
+
deps,
|
|
42
|
+
() => deps.open(path),
|
|
43
|
+
(result, output) => {
|
|
44
|
+
output.log(`Name: ${result.scene.name}`)
|
|
45
|
+
output.log(`Path: ${result.scene.path}`)
|
|
46
|
+
output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`)
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface SceneCreateDeps {
|
|
52
|
+
create: (path: string) => Promise<SceneCreateResult>
|
|
53
|
+
console: Pick<Console, 'log' | 'error'>
|
|
54
|
+
exit?: (code: number) => void
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function handleSceneCreate(
|
|
58
|
+
path: string,
|
|
59
|
+
jsonOutput: boolean,
|
|
60
|
+
deps: SceneCreateDeps,
|
|
61
|
+
): Promise<void> {
|
|
62
|
+
await runWithOutput(
|
|
63
|
+
jsonOutput,
|
|
64
|
+
deps,
|
|
65
|
+
() => deps.create(path),
|
|
66
|
+
(result, output) => {
|
|
67
|
+
output.log(`Name: ${result.scene.name}`)
|
|
68
|
+
output.log(`Path: ${result.scene.path}`)
|
|
69
|
+
output.log(`Dirty: ${result.scene.isDirty ? 'yes' : 'no'}`)
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function registerScene(program: Command): void {
|
|
75
|
+
const scene = program
|
|
76
|
+
.command('scene')
|
|
77
|
+
.description('Read and modify Unity scenes')
|
|
78
|
+
|
|
79
|
+
scene
|
|
80
|
+
.command('active')
|
|
81
|
+
.description('Show the active scene')
|
|
82
|
+
.action(async (_opts: Record<string, never>, command: Command) => {
|
|
83
|
+
await withUnityClient(
|
|
84
|
+
command,
|
|
85
|
+
{ requirePlugin: true },
|
|
86
|
+
async (client, ctx) => {
|
|
87
|
+
await handleSceneActive(ctx.jsonOutput, {
|
|
88
|
+
active: () => client.sceneActive(),
|
|
89
|
+
console,
|
|
90
|
+
exit: (exitCode) => {
|
|
91
|
+
process.exitCode = exitCode
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
},
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
scene
|
|
99
|
+
.command('create <path>')
|
|
100
|
+
.description('Create a new scene at a project-relative path')
|
|
101
|
+
.action(async (path: string, _opts: Record<string, never>, command: Command) => {
|
|
102
|
+
await withUnityClient(
|
|
103
|
+
command,
|
|
104
|
+
{ requirePlugin: true },
|
|
105
|
+
async (client, ctx) => {
|
|
106
|
+
await handleSceneCreate(path, ctx.jsonOutput, {
|
|
107
|
+
create: (scenePath) => client.sceneCreate(scenePath),
|
|
108
|
+
console,
|
|
109
|
+
exit: (exitCode) => {
|
|
110
|
+
process.exitCode = exitCode
|
|
111
|
+
},
|
|
112
|
+
})
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
scene
|
|
118
|
+
.command('open <path>')
|
|
119
|
+
.description('Open a scene by project-relative path')
|
|
120
|
+
.action(async (path: string, _opts: Record<string, never>, command: Command) => {
|
|
121
|
+
await withUnityClient(
|
|
122
|
+
command,
|
|
123
|
+
{ requirePlugin: true },
|
|
124
|
+
async (client, ctx) => {
|
|
125
|
+
await handleSceneOpen(path, ctx.jsonOutput, {
|
|
126
|
+
open: (scenePath) => client.sceneOpen(scenePath),
|
|
127
|
+
console,
|
|
128
|
+
exit: (exitCode) => {
|
|
129
|
+
process.exitCode = exitCode
|
|
130
|
+
},
|
|
131
|
+
})
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
})
|
|
135
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import type { StatusResult } from '@unibridge/sdk'
|
|
3
|
+
import { runWithOutput } from './output.ts'
|
|
4
|
+
import { withUnityClient } from './with-unity-client.ts'
|
|
5
|
+
|
|
6
|
+
interface StatusDeps {
|
|
7
|
+
status: () => Promise<StatusResult>
|
|
8
|
+
console: Pick<Console, 'log' | 'error'>
|
|
9
|
+
exit?: (code: number) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function handleStatus(
|
|
13
|
+
jsonOutput: boolean,
|
|
14
|
+
deps: StatusDeps,
|
|
15
|
+
): Promise<void> {
|
|
16
|
+
await runWithOutput(
|
|
17
|
+
jsonOutput,
|
|
18
|
+
deps,
|
|
19
|
+
() => deps.status(),
|
|
20
|
+
(result, output) => {
|
|
21
|
+
output.log(`Project: ${result.projectPath}`)
|
|
22
|
+
output.log(`Unity: ${result.unityVersion}`)
|
|
23
|
+
output.log(`Plugin: ${result.pluginVersion}`)
|
|
24
|
+
output.log(`Scene: ${result.activeScene}`)
|
|
25
|
+
output.log(`Mode: ${result.playMode}`)
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function registerStatus(program: Command): void {
|
|
31
|
+
program
|
|
32
|
+
.command('status')
|
|
33
|
+
.description('Show the current state of the Unity Editor')
|
|
34
|
+
.action(async (_opts: Record<string, never>, command: Command) => {
|
|
35
|
+
await withUnityClient(
|
|
36
|
+
command,
|
|
37
|
+
{ requirePlugin: true },
|
|
38
|
+
async (client, ctx) => {
|
|
39
|
+
await handleStatus(ctx.jsonOutput, {
|
|
40
|
+
status: () => client.status(),
|
|
41
|
+
console,
|
|
42
|
+
exit: (exitCode) => {
|
|
43
|
+
process.exitCode = exitCode
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
},
|
|
47
|
+
)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import { createClient } from '@unibridge/sdk'
|
|
3
|
+
import { getGlobalOptions } from '../options.ts'
|
|
4
|
+
import { resolveCommandProject } from '../preflight.ts'
|
|
5
|
+
|
|
6
|
+
interface ClientCommandRequirements {
|
|
7
|
+
requirePlugin: boolean
|
|
8
|
+
requiresExecute?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface GlobalCommandContext {
|
|
12
|
+
jsonOutput: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function withUnityClient(
|
|
16
|
+
command: Command,
|
|
17
|
+
requirements: ClientCommandRequirements,
|
|
18
|
+
run: (client: ReturnType<typeof createClient>, ctx: GlobalCommandContext) => Promise<void>,
|
|
19
|
+
): Promise<void> {
|
|
20
|
+
let client: ReturnType<typeof createClient> | undefined
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const globalOpts = getGlobalOptions(command)
|
|
24
|
+
const envExecute = process.env.UNIBRIDGE_ENABLE_EXECUTE !== '0'
|
|
25
|
+
const executeEnabled = globalOpts.execute !== false && envExecute
|
|
26
|
+
|
|
27
|
+
const projectPath = resolveCommandProject(
|
|
28
|
+
{
|
|
29
|
+
project: globalOpts.project,
|
|
30
|
+
execute: executeEnabled,
|
|
31
|
+
},
|
|
32
|
+
requirements,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
client = createClient({
|
|
36
|
+
projectPath,
|
|
37
|
+
enableExecute: executeEnabled,
|
|
38
|
+
connectTimeout: 10_000,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
await run(client, {
|
|
42
|
+
jsonOutput: globalOpts.json === true,
|
|
43
|
+
})
|
|
44
|
+
} finally {
|
|
45
|
+
client?.close()
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { program } from 'commander'
|
|
5
|
+
import { registerDomain } from './commands/domain.ts'
|
|
6
|
+
import { registerInit } from './commands/init.ts'
|
|
7
|
+
import { registerExecute } from './commands/execute.ts'
|
|
8
|
+
import { registerStatus } from './commands/status.ts'
|
|
9
|
+
import { registerScene } from './commands/scene.ts'
|
|
10
|
+
|
|
11
|
+
const { version } = JSON.parse(
|
|
12
|
+
readFileSync(path.join(import.meta.dirname, '..', 'package.json'), 'utf-8'),
|
|
13
|
+
) as { version: string }
|
|
14
|
+
|
|
15
|
+
program
|
|
16
|
+
.name('unibridge')
|
|
17
|
+
.description('Bridge between Unity and your code')
|
|
18
|
+
.version(version)
|
|
19
|
+
.option('-p, --project <path>', 'Path to Unity project')
|
|
20
|
+
.option('--json', 'Output result as JSON')
|
|
21
|
+
.option('--no-execute', 'Disable execute tool for this invocation')
|
|
22
|
+
|
|
23
|
+
registerDomain(program)
|
|
24
|
+
registerInit(program)
|
|
25
|
+
registerExecute(program)
|
|
26
|
+
registerStatus(program)
|
|
27
|
+
registerScene(program)
|
|
28
|
+
|
|
29
|
+
program.parse()
|
package/src/options.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
|
|
3
|
+
export interface GlobalCommandOptions {
|
|
4
|
+
project?: string
|
|
5
|
+
json?: boolean
|
|
6
|
+
execute?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getGlobalOptions(command: Command): GlobalCommandOptions {
|
|
10
|
+
return command.optsWithGlobals() as GlobalCommandOptions
|
|
11
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { mkdirSync, rmSync, writeFileSync } from 'node:fs'
|
|
4
|
+
import { resolveCommandProject } from './preflight.ts'
|
|
5
|
+
|
|
6
|
+
const projectPath = '/tmp/unibridge-cli-preflight/My Game'
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
mkdirSync(`${projectPath}/Assets`, { recursive: true })
|
|
10
|
+
mkdirSync(`${projectPath}/ProjectSettings`, { recursive: true })
|
|
11
|
+
mkdirSync(`${projectPath}/Packages`, { recursive: true })
|
|
12
|
+
writeFileSync(`${projectPath}/ProjectSettings/ProjectVersion.txt`, 'm_EditorVersion: 2022.3.10f1\n')
|
|
13
|
+
writeFileSync(`${projectPath}/Packages/manifest.json`, JSON.stringify({ dependencies: {} }, null, 2))
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
rmSync('/tmp/unibridge-cli-preflight', { recursive: true, force: true })
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
describe('resolveCommandProject', () => {
|
|
21
|
+
it('throws when plugin is missing for command execution', () => {
|
|
22
|
+
assert.throws(
|
|
23
|
+
() => resolveCommandProject({ project: projectPath, execute: true }, { requirePlugin: true, requiresExecute: true }),
|
|
24
|
+
/Run `unibridge init` first/,
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('throws when execute is disabled', () => {
|
|
29
|
+
writeFileSync(
|
|
30
|
+
`${projectPath}/Packages/manifest.json`,
|
|
31
|
+
JSON.stringify({ dependencies: { 'com.msanatan.unibridge': 'file:../unity' } }, null, 2),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
assert.throws(
|
|
35
|
+
() => resolveCommandProject({ project: projectPath, execute: false }, { requirePlugin: true, requiresExecute: true }),
|
|
36
|
+
/Execute is disabled/,
|
|
37
|
+
)
|
|
38
|
+
})
|
|
39
|
+
})
|
package/src/preflight.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { findUnityProject, isPluginInstalled } from '@unibridge/sdk'
|
|
2
|
+
|
|
3
|
+
export function resolveCommandProject(
|
|
4
|
+
opts: { project?: string; execute?: boolean },
|
|
5
|
+
config: { requirePlugin: boolean; requiresExecute?: boolean },
|
|
6
|
+
): string {
|
|
7
|
+
let projectPath: string
|
|
8
|
+
try {
|
|
9
|
+
projectPath = findUnityProject(opts.project)
|
|
10
|
+
} catch {
|
|
11
|
+
throw new Error('Unity project not found. Run inside a Unity project or pass --project <path>.')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (config.requiresExecute && opts.execute === false) {
|
|
15
|
+
throw new Error('Execute is disabled for this invocation (--no-execute).')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (config.requirePlugin && !isPluginInstalled(projectPath)) {
|
|
19
|
+
throw new Error('com.msanatan.unibridge is not installed. Run `unibridge init` first.')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return projectPath
|
|
23
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "src",
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"src/**/*.ts"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"src/**/*.test.ts"
|
|
15
|
+
]
|
|
16
|
+
}
|