@unibridge/sdk 0.5.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/client.d.ts +6 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +59 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/commands/component/contract.d.ts +174 -0
  8. package/dist/commands/component/contract.d.ts.map +1 -0
  9. package/dist/commands/component/contract.js +142 -0
  10. package/dist/commands/component/contract.js.map +1 -0
  11. package/dist/commands/contracts.d.ts +9 -0
  12. package/dist/commands/contracts.d.ts.map +1 -0
  13. package/dist/commands/contracts.js +2 -0
  14. package/dist/commands/contracts.js.map +1 -0
  15. package/dist/commands/define.d.ts +19 -0
  16. package/dist/commands/define.d.ts.map +1 -0
  17. package/dist/commands/define.js +20 -0
  18. package/dist/commands/define.js.map +1 -0
  19. package/dist/commands/domain/contract.d.ts +10 -0
  20. package/dist/commands/domain/contract.d.ts.map +1 -0
  21. package/dist/commands/domain/contract.js +12 -0
  22. package/dist/commands/domain/contract.js.map +1 -0
  23. package/dist/commands/execute/contract.d.ts +4 -0
  24. package/dist/commands/execute/contract.d.ts.map +1 -0
  25. package/dist/commands/execute/contract.js +10 -0
  26. package/dist/commands/execute/contract.js.map +1 -0
  27. package/dist/commands/gameobject/contract.d.ts +320 -0
  28. package/dist/commands/gameobject/contract.d.ts.map +1 -0
  29. package/dist/commands/gameobject/contract.js +154 -0
  30. package/dist/commands/gameobject/contract.js.map +1 -0
  31. package/dist/commands/log/contract.d.ts +46 -0
  32. package/dist/commands/log/contract.d.ts.map +1 -0
  33. package/dist/commands/log/contract.js +31 -0
  34. package/dist/commands/log/contract.js.map +1 -0
  35. package/dist/commands/registry.d.ts +303 -0
  36. package/dist/commands/registry.d.ts.map +1 -0
  37. package/dist/commands/registry.js +10 -0
  38. package/dist/commands/registry.js.map +1 -0
  39. package/dist/commands/runtime.d.ts +7 -0
  40. package/dist/commands/runtime.d.ts.map +1 -0
  41. package/dist/commands/runtime.js +2 -0
  42. package/dist/commands/runtime.js.map +1 -0
  43. package/dist/commands/scene/contract.d.ts +127 -0
  44. package/dist/commands/scene/contract.d.ts.map +1 -0
  45. package/dist/commands/scene/contract.js +79 -0
  46. package/dist/commands/scene/contract.js.map +1 -0
  47. package/dist/commands/status/contract.d.ts +18 -0
  48. package/dist/commands/status/contract.d.ts.map +1 -0
  49. package/dist/commands/status/contract.js +16 -0
  50. package/dist/commands/status/contract.js.map +1 -0
  51. package/dist/commands/test/contract.d.ts +111 -0
  52. package/dist/commands/test/contract.d.ts.map +1 -0
  53. package/dist/commands/test/contract.js +71 -0
  54. package/dist/commands/test/contract.js.map +1 -0
  55. package/dist/connection.d.ts +37 -0
  56. package/dist/connection.d.ts.map +1 -0
  57. package/dist/connection.js +311 -0
  58. package/dist/connection.js.map +1 -0
  59. package/dist/hash.d.ts +4 -0
  60. package/dist/hash.d.ts.map +1 -0
  61. package/dist/hash.js +41 -0
  62. package/dist/hash.js.map +1 -0
  63. package/dist/index.d.ts +5 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +3 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/project.d.ts +6 -0
  68. package/dist/project.d.ts.map +1 -0
  69. package/dist/project.js +71 -0
  70. package/dist/project.js.map +1 -0
  71. package/dist/types.d.ts +55 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +2 -0
  74. package/dist/types.js.map +1 -0
  75. package/package.json +31 -5
  76. package/src/client.ts +0 -76
  77. package/src/commands/contracts.ts +0 -4
  78. package/src/commands/define.ts +0 -56
  79. package/src/commands/domain/contract.ts +0 -15
  80. package/src/commands/execute/contract.ts +0 -12
  81. package/src/commands/registry.ts +0 -6
  82. package/src/commands/runtime.ts +0 -7
  83. package/src/commands/scene/contract.ts +0 -46
  84. package/src/commands/status/contract.ts +0 -19
  85. package/src/connection.test.ts +0 -330
  86. package/src/connection.ts +0 -382
  87. package/src/hash.test.ts +0 -48
  88. package/src/hash.ts +0 -50
  89. package/src/index.ts +0 -10
  90. package/src/project.test.ts +0 -93
  91. package/src/project.ts +0 -99
  92. package/src/types.ts +0 -64
  93. package/tsconfig.json +0 -16
package/src/hash.test.ts DELETED
@@ -1,48 +0,0 @@
1
- import { describe, it } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { pipePath, projectHash, stateDir } from './hash.ts'
4
-
5
- describe('projectHash', () => {
6
- it('returns a 12-char hex string', () => {
7
- const hash = projectHash('/Users/me/MyGame')
8
- assert.equal(hash.length, 12)
9
- assert.match(hash, /^[a-f0-9]{12}$/)
10
- })
11
-
12
- it('is deterministic', () => {
13
- const a = projectHash('/Users/me/MyGame')
14
- const b = projectHash('/Users/me/MyGame')
15
- assert.equal(a, b)
16
- })
17
-
18
- it('differs for different paths', () => {
19
- const a = projectHash('/Users/me/GameA')
20
- const b = projectHash('/Users/me/GameB')
21
- assert.notEqual(a, b)
22
- })
23
-
24
- it('normalizes trailing slash differences', () => {
25
- const a = projectHash('/Users/me/MyGame')
26
- const b = projectHash('/Users/me/MyGame/')
27
- assert.equal(a, b)
28
- })
29
-
30
- it('handles paths with spaces', () => {
31
- const hash = projectHash('/Users/me/My Game')
32
- assert.match(hash, /^[a-f0-9]{12}$/)
33
- })
34
- })
35
-
36
- describe('pipePath', () => {
37
- it('returns a unix socket path on non-Windows', () => {
38
- const path = pipePath('/Users/me/MyGame')
39
- assert.match(path, /^\/tmp\/unibridge\/[a-f0-9]{12}\/bridge\.sock$/)
40
- })
41
- })
42
-
43
- describe('stateDir', () => {
44
- it('returns the temp directory for the project', () => {
45
- const dir = stateDir('/Users/me/MyGame')
46
- assert.match(dir, /^\/tmp\/unibridge\/[a-f0-9]{12}$/)
47
- })
48
- })
package/src/hash.ts DELETED
@@ -1,50 +0,0 @@
1
- import { createHash } from 'node:crypto'
2
- import { realpathSync } from 'node:fs'
3
- import os from 'node:os'
4
- import path from 'node:path'
5
-
6
- function canonicalizeProjectPath(projectPath: string): string {
7
- const resolved = path.resolve(projectPath)
8
- let canonical = resolved
9
-
10
- try {
11
- canonical = realpathSync.native(resolved)
12
- } catch {
13
- // Fall back to the resolved path when it does not exist yet.
14
- }
15
-
16
- canonical = canonical.replace(/\\/g, '/')
17
- canonical = canonical.replace(/\/+$/g, '')
18
-
19
- if (process.platform === 'win32') {
20
- canonical = canonical.toLowerCase()
21
- }
22
-
23
- return canonical
24
- }
25
-
26
- export function projectHash(projectPath: string): string {
27
- const canonical = canonicalizeProjectPath(projectPath)
28
- return createHash('sha256').update(canonical).digest('hex').slice(0, 12)
29
- }
30
-
31
- function stateBaseDir(): string {
32
- if (process.platform === 'win32') {
33
- return path.join(os.tmpdir(), 'unibridge')
34
- }
35
-
36
- return '/tmp/unibridge'
37
- }
38
-
39
- export function stateDir(projectPath: string): string {
40
- return path.join(stateBaseDir(), projectHash(projectPath))
41
- }
42
-
43
- export function pipePath(projectPath: string): string {
44
- const hash = projectHash(projectPath)
45
- if (process.platform === 'win32') {
46
- return `\\\\.\\pipe\\unibridge-${hash}`
47
- }
48
-
49
- return path.join(stateBaseDir(), hash, 'bridge.sock')
50
- }
package/src/index.ts DELETED
@@ -1,10 +0,0 @@
1
- export { init, findUnityProject, isPluginInstalled } from './project.ts'
2
- export { createClient } from './client.ts'
3
- export type * from './commands/contracts.ts'
4
- export type {
5
- InitOptions,
6
- InitResult,
7
- CommandResponse,
8
- ClientOptions,
9
- UniBridgeClient,
10
- } from './types.ts'
@@ -1,93 +0,0 @@
1
- import { afterEach, beforeEach, describe, it } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
4
- import { findUnityProject, init, isPluginInstalled, parseUnityVersion } from './project.ts'
5
-
6
- const baseDir = '/tmp/unibridge-sdk-project-tests'
7
- const testDir = `${baseDir}/test-unity-project`
8
- const testDirWithSpaces = `${baseDir}/test unity project`
9
-
10
- function createFakeProject(path: string, version = '2022.3.10f1') {
11
- mkdirSync(`${path}/Assets`, { recursive: true })
12
- mkdirSync(`${path}/ProjectSettings`, { recursive: true })
13
- mkdirSync(`${path}/Packages`, { recursive: true })
14
- writeFileSync(`${path}/ProjectSettings/ProjectVersion.txt`, `m_EditorVersion: ${version}\n`)
15
- writeFileSync(`${path}/Packages/manifest.json`, JSON.stringify({ dependencies: {} }, null, 2))
16
- }
17
-
18
- describe('findUnityProject', () => {
19
- beforeEach(() => createFakeProject(testDir))
20
- afterEach(() => rmSync(baseDir, { recursive: true, force: true }))
21
-
22
- it('finds project at the given path', () => {
23
- assert.equal(findUnityProject(testDir), testDir)
24
- })
25
-
26
- it('finds project from a subdirectory', () => {
27
- mkdirSync(`${testDir}/Assets/Scripts`, { recursive: true })
28
- assert.equal(findUnityProject(`${testDir}/Assets/Scripts`), testDir)
29
- })
30
-
31
- it('supports project paths with spaces', () => {
32
- createFakeProject(testDirWithSpaces)
33
- assert.equal(findUnityProject(testDirWithSpaces), testDirWithSpaces)
34
- })
35
-
36
- it('throws when no Unity project is found', () => {
37
- assert.throws(() => findUnityProject('/tmp'), /Unity project not found/)
38
- })
39
- })
40
-
41
- describe('parseUnityVersion', () => {
42
- beforeEach(() => createFakeProject(testDir, '6000.0.23f1'))
43
- afterEach(() => rmSync(baseDir, { recursive: true, force: true }))
44
-
45
- it('extracts version string', () => {
46
- assert.equal(parseUnityVersion(testDir), '6000.0.23f1')
47
- })
48
- })
49
-
50
- describe('init', () => {
51
- beforeEach(() => createFakeProject(testDir))
52
- afterEach(() => rmSync(baseDir, { recursive: true, force: true }))
53
-
54
- it('adds plugin to manifest.json with git source', async () => {
55
- const result = await init({ projectPath: testDir })
56
- assert.equal(result.unityVersion, '2022.3.10f1')
57
- assert.equal(result.pluginSource, 'git')
58
-
59
- const manifest = JSON.parse(readFileSync(`${testDir}/Packages/manifest.json`, 'utf-8'))
60
- assert.ok(manifest.dependencies['com.msanatan.unibridge'])
61
- })
62
-
63
- it('adds plugin with local source', async () => {
64
- const result = await init({
65
- projectPath: testDir,
66
- source: { type: 'local', path: '../unibridge/unity' },
67
- })
68
- assert.equal(result.pluginSource, 'local')
69
-
70
- const manifest = JSON.parse(readFileSync(`${testDir}/Packages/manifest.json`, 'utf-8'))
71
- assert.equal(manifest.dependencies['com.msanatan.unibridge'], 'file:../unibridge/unity')
72
- })
73
-
74
- it('no-ops when plugin is already at correct version', async () => {
75
- await init({ projectPath: testDir })
76
- const result = await init({ projectPath: testDir })
77
- assert.equal(result.pluginSource, 'git')
78
- })
79
- })
80
-
81
- describe('isPluginInstalled', () => {
82
- beforeEach(() => createFakeProject(testDir))
83
- afterEach(() => rmSync(baseDir, { recursive: true, force: true }))
84
-
85
- it('returns false when dependency is absent', () => {
86
- assert.equal(isPluginInstalled(testDir), false)
87
- })
88
-
89
- it('returns true after init installs the plugin', async () => {
90
- await init({ projectPath: testDir })
91
- assert.equal(isPluginInstalled(testDir), true)
92
- })
93
- })
package/src/project.ts DELETED
@@ -1,99 +0,0 @@
1
- import { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
2
- import path from 'node:path'
3
- import { cwd } from 'node:process'
4
- import type { InitOptions, InitResult } from './types.ts'
5
-
6
- const PLUGIN_NAME = 'com.msanatan.unibridge'
7
-
8
- const SDK_VERSION = (
9
- JSON.parse(
10
- readFileSync(path.join(import.meta.dirname, '..', 'package.json'), 'utf-8'),
11
- ) as { version: string }
12
- ).version
13
-
14
- const DEFAULT_GIT_SOURCE =
15
- `https://github.com/msanatan/unibridge.git?path=unity#v${SDK_VERSION}`
16
-
17
- interface Manifest {
18
- dependencies?: Record<string, string>
19
- }
20
-
21
- function readManifest(projectPath: string): Manifest {
22
- const manifestPath = path.join(projectPath, 'Packages', 'manifest.json')
23
- return JSON.parse(readFileSync(manifestPath, 'utf-8')) as Manifest
24
- }
25
-
26
- function writeManifestAtomic(projectPath: string, manifest: Manifest): void {
27
- const manifestPath = path.join(projectPath, 'Packages', 'manifest.json')
28
- const tempPath = `${manifestPath}.tmp`
29
- const content = `${JSON.stringify(manifest, null, 2)}\n`
30
- writeFileSync(tempPath, content, 'utf-8')
31
- renameSync(tempPath, manifestPath)
32
- }
33
-
34
- export function findUnityProject(startPath: string = cwd()): string {
35
- let current = path.resolve(startPath)
36
-
37
- while (true) {
38
- const assetsPath = path.join(current, 'Assets')
39
- const versionPath = path.join(current, 'ProjectSettings', 'ProjectVersion.txt')
40
-
41
- if (existsSync(assetsPath) && existsSync(versionPath)) {
42
- return current
43
- }
44
-
45
- const parent = path.dirname(current)
46
- if (parent === current) {
47
- throw new Error('Unity project not found. Run inside a Unity project or pass --project <path>.')
48
- }
49
-
50
- current = parent
51
- }
52
- }
53
-
54
- export function parseUnityVersion(projectPath: string): string {
55
- const versionPath = path.join(projectPath, 'ProjectSettings', 'ProjectVersion.txt')
56
- const content = readFileSync(versionPath, 'utf-8')
57
- const match = content.match(/m_EditorVersion:\s*(\S+)/)
58
- if (!match) {
59
- throw new Error(`Could not parse m_EditorVersion from ${versionPath}`)
60
- }
61
-
62
- return match[1]
63
- }
64
-
65
- export function isPluginInstalled(projectPath: string): boolean {
66
- const manifest = readManifest(projectPath)
67
- return Boolean(manifest.dependencies?.[PLUGIN_NAME])
68
- }
69
-
70
- export async function init(options: InitOptions = {}): Promise<InitResult> {
71
- const projectPath = findUnityProject(options.projectPath)
72
- const unityVersion = parseUnityVersion(projectPath)
73
-
74
- const manifest = readManifest(projectPath)
75
- const dependencies = { ...(manifest.dependencies ?? {}) }
76
-
77
- const pluginSource = options.source?.type ?? 'git'
78
- const pluginReference =
79
- options.source?.type === 'local'
80
- ? `file:${options.source.path}`
81
- : options.source?.type === 'git'
82
- ? options.source.url
83
- : DEFAULT_GIT_SOURCE
84
-
85
- if (dependencies[PLUGIN_NAME] !== pluginReference) {
86
- dependencies[PLUGIN_NAME] = pluginReference
87
- writeManifestAtomic(projectPath, {
88
- ...manifest,
89
- dependencies,
90
- })
91
- }
92
-
93
- return {
94
- projectPath,
95
- unityVersion,
96
- pluginVersion: SDK_VERSION,
97
- pluginSource,
98
- }
99
- }
package/src/types.ts DELETED
@@ -1,64 +0,0 @@
1
- import type { CommandMethods } from './commands/define.ts'
2
- import type { allCommands } from './commands/registry.ts'
3
-
4
- export interface InitOptions {
5
- projectPath?: string
6
- source?: GitSource | LocalSource
7
- }
8
-
9
- export interface GitSource {
10
- type: 'git'
11
- url: string
12
- }
13
-
14
- export interface LocalSource {
15
- type: 'local'
16
- path: string
17
- }
18
-
19
- export interface InitResult {
20
- projectPath: string
21
- unityVersion: string
22
- pluginVersion: string
23
- pluginSource: 'git' | 'local'
24
- }
25
-
26
- export interface CommandRequest {
27
- id: string
28
- command: string
29
- params: Record<string, unknown>
30
- }
31
-
32
- export interface CommandResponse {
33
- id: string
34
- success: boolean
35
- result?: unknown
36
- error?: string
37
- }
38
-
39
- export interface ServerMetadata {
40
- pid: number
41
- unityVersion: string
42
- pluginVersion: string
43
- protocolVersion: number
44
- capabilities?: {
45
- executeEnabled?: boolean
46
- }
47
- projectPath?: string
48
- }
49
-
50
- export interface TimeoutOptions {
51
- connectTimeout?: number
52
- commandTimeout?: number
53
- reconnectTimeout?: number
54
- }
55
-
56
- export interface ClientOptions extends TimeoutOptions {
57
- projectPath?: string
58
- enableExecute?: boolean
59
- }
60
-
61
- export type UniBridgeClient = CommandMethods<typeof allCommands> & {
62
- readonly projectPath: string
63
- close(): void
64
- }
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
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
- }