@limrun/api 0.24.0 → 0.24.2
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 +8 -0
- package/client.d.mts +3 -2
- package/client.d.mts.map +1 -1
- package/client.d.ts +3 -2
- package/client.d.ts.map +1 -1
- package/client.js +2 -2
- package/client.js.map +1 -1
- package/client.mjs +1 -1
- package/client.mjs.map +1 -1
- package/exec-client.d.mts +3 -2
- package/exec-client.d.mts.map +1 -1
- package/exec-client.d.ts +3 -2
- package/exec-client.d.ts.map +1 -1
- package/exec-client.js +6 -1
- package/exec-client.js.map +1 -1
- package/exec-client.mjs +6 -1
- package/exec-client.mjs.map +1 -1
- package/index.d.mts +1 -1
- package/index.d.mts.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +1 -3
- package/index.js.map +1 -1
- package/index.mjs +0 -1
- package/index.mjs.map +1 -1
- package/instance-client.d.mts +13 -1
- package/instance-client.d.mts.map +1 -1
- package/instance-client.d.ts +13 -1
- package/instance-client.d.ts.map +1 -1
- package/instance-client.js +21 -2
- package/instance-client.js.map +1 -1
- package/instance-client.mjs +20 -2
- package/instance-client.mjs.map +1 -1
- package/internal/tslib.js +4 -4
- package/ios-client.d.mts +14 -2
- package/ios-client.d.mts.map +1 -1
- package/ios-client.d.ts +14 -2
- package/ios-client.d.ts.map +1 -1
- package/ios-client.js +24 -44
- package/ios-client.js.map +1 -1
- package/ios-client.mjs +23 -43
- package/ios-client.mjs.map +1 -1
- package/package.json +1 -11
- package/resources/index.d.mts +2 -1
- package/resources/index.d.mts.map +1 -1
- package/resources/index.d.ts +2 -1
- package/resources/index.d.ts.map +1 -1
- package/resources/index.js +3 -3
- package/resources/index.js.map +1 -1
- package/resources/index.mjs +1 -1
- package/resources/index.mjs.map +1 -1
- package/resources/xcode-instances-helpers.d.mts +76 -0
- package/resources/xcode-instances-helpers.d.mts.map +1 -0
- package/resources/xcode-instances-helpers.d.ts +76 -0
- package/resources/xcode-instances-helpers.d.ts.map +1 -0
- package/resources/xcode-instances-helpers.js +150 -0
- package/resources/xcode-instances-helpers.js.map +1 -0
- package/resources/xcode-instances-helpers.mjs +145 -0
- package/resources/xcode-instances-helpers.mjs.map +1 -0
- package/src/client.ts +11 -1
- package/src/exec-client.ts +8 -3
- package/src/index.ts +6 -9
- package/src/instance-client.ts +25 -4
- package/src/ios-client.ts +27 -44
- package/src/resources/index.ts +7 -1
- package/src/resources/xcode-instances-helpers.ts +228 -0
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
- package/sandbox-client.d.mts +0 -129
- package/sandbox-client.d.mts.map +0 -1
- package/sandbox-client.d.ts +0 -129
- package/sandbox-client.d.ts.map +0 -1
- package/sandbox-client.js +0 -159
- package/sandbox-client.js.map +0 -1
- package/sandbox-client.mjs +0 -155
- package/sandbox-client.mjs.map +0 -1
- package/src/sandbox-client.ts +0 -278
package/sandbox-client.js
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createXCodeSandboxClient = createXCodeSandboxClient;
|
|
4
|
-
const tslib_1 = require("./internal/tslib.js");
|
|
5
|
-
const os_1 = tslib_1.__importDefault(require("os"));
|
|
6
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
-
const folder_sync_1 = require("./folder-sync.js");
|
|
8
|
-
const exec_client_1 = require("./exec-client.js");
|
|
9
|
-
const folder_sync_ignore_1 = require("./folder-sync-ignore.js");
|
|
10
|
-
const crypto_1 = tslib_1.__importDefault(require("crypto"));
|
|
11
|
-
const proxy_transport_1 = require("./internal/proxy-transport.js");
|
|
12
|
-
/**
|
|
13
|
-
* Creates a client for interacting with a sandboxed Xcode build service.
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* // When using an iOS instance (simulator already configured):
|
|
17
|
-
* const client = await createXCodeSandboxClient({
|
|
18
|
-
* apiUrl: instance.status.sandbox.xcode.url,
|
|
19
|
-
* token: apiKey,
|
|
20
|
-
* });
|
|
21
|
-
*
|
|
22
|
-
* // When using a standalone sandbox (need to configure simulator):
|
|
23
|
-
* const client = await createXCodeSandboxClient({
|
|
24
|
-
* apiUrl: 'https://sandbox.example.com',
|
|
25
|
-
* token: 'xxx',
|
|
26
|
-
* simulator: {
|
|
27
|
-
* apiUrl: 'https://limulator.example.com',
|
|
28
|
-
* token: 'yyy', // optional, defaults to sandbox token
|
|
29
|
-
* },
|
|
30
|
-
* });
|
|
31
|
-
*
|
|
32
|
-
* // Sync code and build
|
|
33
|
-
* await client.sync('./my-ios-app', { watch: true });
|
|
34
|
-
* const build = client.xcodebuild();
|
|
35
|
-
* build.stdout.on('data', (line) => console.log('[build]', line));
|
|
36
|
-
* const { exitCode } = await build;
|
|
37
|
-
*/
|
|
38
|
-
async function createXCodeSandboxClient(options) {
|
|
39
|
-
const logLevel = options.logLevel ?? 'info';
|
|
40
|
-
const logger = {
|
|
41
|
-
debug: (...args) => {
|
|
42
|
-
if (logLevel === 'debug')
|
|
43
|
-
console.log('[XCodeSandbox]', ...args);
|
|
44
|
-
},
|
|
45
|
-
info: (...args) => {
|
|
46
|
-
if (logLevel === 'info' || logLevel === 'debug')
|
|
47
|
-
console.log('[XCodeSandbox]', ...args);
|
|
48
|
-
},
|
|
49
|
-
warn: (...args) => {
|
|
50
|
-
if (logLevel === 'warn' || logLevel === 'info' || logLevel === 'debug')
|
|
51
|
-
console.warn('[XCodeSandbox]', ...args);
|
|
52
|
-
},
|
|
53
|
-
error: (...args) => {
|
|
54
|
-
if (logLevel !== 'none')
|
|
55
|
-
console.error('[XCodeSandbox]', ...args);
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
const log = (level, msg) => {
|
|
59
|
-
switch (level) {
|
|
60
|
-
case 'debug':
|
|
61
|
-
logger.debug(msg);
|
|
62
|
-
break;
|
|
63
|
-
case 'info':
|
|
64
|
-
logger.info(msg);
|
|
65
|
-
break;
|
|
66
|
-
case 'warn':
|
|
67
|
-
logger.warn(msg);
|
|
68
|
-
break;
|
|
69
|
-
case 'error':
|
|
70
|
-
logger.error(msg);
|
|
71
|
-
break;
|
|
72
|
-
default:
|
|
73
|
-
logger.info(msg);
|
|
74
|
-
break;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
// Configure the simulator connection if provided
|
|
78
|
-
if (options.simulator) {
|
|
79
|
-
const cfg = {
|
|
80
|
-
simulatorApiUrl: options.simulator.apiUrl,
|
|
81
|
-
simulatorToken: options.simulator.token ?? options.token,
|
|
82
|
-
};
|
|
83
|
-
const res = await proxy_transport_1.nodeProxyTransport.fetch(`${options.apiUrl}/simulator`, {
|
|
84
|
-
method: 'POST',
|
|
85
|
-
headers: {
|
|
86
|
-
'Content-Type': 'application/json',
|
|
87
|
-
Authorization: `Bearer ${options.token}`,
|
|
88
|
-
},
|
|
89
|
-
body: JSON.stringify(cfg),
|
|
90
|
-
});
|
|
91
|
-
const text = await res.text();
|
|
92
|
-
if (!res.ok) {
|
|
93
|
-
throw new Error(`POST /simulator failed: ${res.status} ${text}`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
async sync(localCodePath, opts) {
|
|
98
|
-
// Use folder name and hash of absolute path to scope basisCacheDir uniquely for each sync root
|
|
99
|
-
const resolvedPath = path_1.default.resolve(localCodePath);
|
|
100
|
-
const folderName = path_1.default.basename(resolvedPath);
|
|
101
|
-
const hash = crypto_1.default.createHash('sha1').update(resolvedPath).digest('hex').slice(0, 8);
|
|
102
|
-
const cacheKey = `limsync-cache-${folderName}-${hash}`;
|
|
103
|
-
const basisCacheDir = opts?.basisCacheDir ?? path_1.default.join(os_1.default.tmpdir(), cacheKey);
|
|
104
|
-
const codeSyncOpts = {
|
|
105
|
-
apiUrl: options.apiUrl,
|
|
106
|
-
token: options.token,
|
|
107
|
-
udid: cacheKey,
|
|
108
|
-
install: opts?.install ?? true,
|
|
109
|
-
ignoreFn: await (0, folder_sync_ignore_1.createIgnoreFn)(localCodePath, {
|
|
110
|
-
basisCacheDir,
|
|
111
|
-
additional: (relativePath) => {
|
|
112
|
-
if (relativePath.startsWith('build/') ||
|
|
113
|
-
relativePath.startsWith('.build/') ||
|
|
114
|
-
relativePath.startsWith('DerivedData/') ||
|
|
115
|
-
relativePath.startsWith('Index.noindex/') ||
|
|
116
|
-
relativePath.startsWith('ModuleCache.noindex/') ||
|
|
117
|
-
relativePath.startsWith('.index-build/')) {
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
if (relativePath.startsWith('.swiftpm/') ||
|
|
121
|
-
relativePath.startsWith('Pods/') ||
|
|
122
|
-
relativePath.startsWith('Carthage/Build/')) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
if (relativePath.includes('/xcuserdata/')) {
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
if (relativePath.includes('.dSYM/')) {
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
// User-provided ignores
|
|
132
|
-
if (opts?.ignore?.(relativePath)) {
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
return false;
|
|
136
|
-
},
|
|
137
|
-
}),
|
|
138
|
-
basisCacheDir,
|
|
139
|
-
watch: opts?.watch ?? true,
|
|
140
|
-
maxPatchBytes: opts?.maxPatchBytes ?? 4 * 1024 * 1024,
|
|
141
|
-
launchMode: 'ForegroundIfRunning',
|
|
142
|
-
log,
|
|
143
|
-
};
|
|
144
|
-
const result = await (0, folder_sync_1.syncFolder)(localCodePath, codeSyncOpts);
|
|
145
|
-
if (result.stopWatching) {
|
|
146
|
-
return { stopWatching: result.stopWatching };
|
|
147
|
-
}
|
|
148
|
-
return {};
|
|
149
|
-
},
|
|
150
|
-
xcodebuild(opts) {
|
|
151
|
-
return (0, exec_client_1.exec)({ command: 'xcodebuild', ...(opts && { xcodebuild: opts }) }, {
|
|
152
|
-
apiUrl: options.apiUrl,
|
|
153
|
-
token: options.token,
|
|
154
|
-
log,
|
|
155
|
-
});
|
|
156
|
-
},
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
//# sourceMappingURL=sandbox-client.js.map
|
package/sandbox-client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox-client.js","sourceRoot":"","sources":["src/sandbox-client.ts"],"names":[],"mappings":"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"}
|
package/sandbox-client.mjs
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import os from 'os';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { syncFolder as syncFolderImpl } from "./folder-sync.mjs";
|
|
4
|
-
import { exec } from "./exec-client.mjs";
|
|
5
|
-
import { createIgnoreFn } from "./folder-sync-ignore.mjs";
|
|
6
|
-
import crypto from 'crypto';
|
|
7
|
-
import { nodeProxyTransport } from "./internal/proxy-transport.mjs";
|
|
8
|
-
/**
|
|
9
|
-
* Creates a client for interacting with a sandboxed Xcode build service.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* // When using an iOS instance (simulator already configured):
|
|
13
|
-
* const client = await createXCodeSandboxClient({
|
|
14
|
-
* apiUrl: instance.status.sandbox.xcode.url,
|
|
15
|
-
* token: apiKey,
|
|
16
|
-
* });
|
|
17
|
-
*
|
|
18
|
-
* // When using a standalone sandbox (need to configure simulator):
|
|
19
|
-
* const client = await createXCodeSandboxClient({
|
|
20
|
-
* apiUrl: 'https://sandbox.example.com',
|
|
21
|
-
* token: 'xxx',
|
|
22
|
-
* simulator: {
|
|
23
|
-
* apiUrl: 'https://limulator.example.com',
|
|
24
|
-
* token: 'yyy', // optional, defaults to sandbox token
|
|
25
|
-
* },
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* // Sync code and build
|
|
29
|
-
* await client.sync('./my-ios-app', { watch: true });
|
|
30
|
-
* const build = client.xcodebuild();
|
|
31
|
-
* build.stdout.on('data', (line) => console.log('[build]', line));
|
|
32
|
-
* const { exitCode } = await build;
|
|
33
|
-
*/
|
|
34
|
-
export async function createXCodeSandboxClient(options) {
|
|
35
|
-
const logLevel = options.logLevel ?? 'info';
|
|
36
|
-
const logger = {
|
|
37
|
-
debug: (...args) => {
|
|
38
|
-
if (logLevel === 'debug')
|
|
39
|
-
console.log('[XCodeSandbox]', ...args);
|
|
40
|
-
},
|
|
41
|
-
info: (...args) => {
|
|
42
|
-
if (logLevel === 'info' || logLevel === 'debug')
|
|
43
|
-
console.log('[XCodeSandbox]', ...args);
|
|
44
|
-
},
|
|
45
|
-
warn: (...args) => {
|
|
46
|
-
if (logLevel === 'warn' || logLevel === 'info' || logLevel === 'debug')
|
|
47
|
-
console.warn('[XCodeSandbox]', ...args);
|
|
48
|
-
},
|
|
49
|
-
error: (...args) => {
|
|
50
|
-
if (logLevel !== 'none')
|
|
51
|
-
console.error('[XCodeSandbox]', ...args);
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
const log = (level, msg) => {
|
|
55
|
-
switch (level) {
|
|
56
|
-
case 'debug':
|
|
57
|
-
logger.debug(msg);
|
|
58
|
-
break;
|
|
59
|
-
case 'info':
|
|
60
|
-
logger.info(msg);
|
|
61
|
-
break;
|
|
62
|
-
case 'warn':
|
|
63
|
-
logger.warn(msg);
|
|
64
|
-
break;
|
|
65
|
-
case 'error':
|
|
66
|
-
logger.error(msg);
|
|
67
|
-
break;
|
|
68
|
-
default:
|
|
69
|
-
logger.info(msg);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
// Configure the simulator connection if provided
|
|
74
|
-
if (options.simulator) {
|
|
75
|
-
const cfg = {
|
|
76
|
-
simulatorApiUrl: options.simulator.apiUrl,
|
|
77
|
-
simulatorToken: options.simulator.token ?? options.token,
|
|
78
|
-
};
|
|
79
|
-
const res = await nodeProxyTransport.fetch(`${options.apiUrl}/simulator`, {
|
|
80
|
-
method: 'POST',
|
|
81
|
-
headers: {
|
|
82
|
-
'Content-Type': 'application/json',
|
|
83
|
-
Authorization: `Bearer ${options.token}`,
|
|
84
|
-
},
|
|
85
|
-
body: JSON.stringify(cfg),
|
|
86
|
-
});
|
|
87
|
-
const text = await res.text();
|
|
88
|
-
if (!res.ok) {
|
|
89
|
-
throw new Error(`POST /simulator failed: ${res.status} ${text}`);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return {
|
|
93
|
-
async sync(localCodePath, opts) {
|
|
94
|
-
// Use folder name and hash of absolute path to scope basisCacheDir uniquely for each sync root
|
|
95
|
-
const resolvedPath = path.resolve(localCodePath);
|
|
96
|
-
const folderName = path.basename(resolvedPath);
|
|
97
|
-
const hash = crypto.createHash('sha1').update(resolvedPath).digest('hex').slice(0, 8);
|
|
98
|
-
const cacheKey = `limsync-cache-${folderName}-${hash}`;
|
|
99
|
-
const basisCacheDir = opts?.basisCacheDir ?? path.join(os.tmpdir(), cacheKey);
|
|
100
|
-
const codeSyncOpts = {
|
|
101
|
-
apiUrl: options.apiUrl,
|
|
102
|
-
token: options.token,
|
|
103
|
-
udid: cacheKey,
|
|
104
|
-
install: opts?.install ?? true,
|
|
105
|
-
ignoreFn: await createIgnoreFn(localCodePath, {
|
|
106
|
-
basisCacheDir,
|
|
107
|
-
additional: (relativePath) => {
|
|
108
|
-
if (relativePath.startsWith('build/') ||
|
|
109
|
-
relativePath.startsWith('.build/') ||
|
|
110
|
-
relativePath.startsWith('DerivedData/') ||
|
|
111
|
-
relativePath.startsWith('Index.noindex/') ||
|
|
112
|
-
relativePath.startsWith('ModuleCache.noindex/') ||
|
|
113
|
-
relativePath.startsWith('.index-build/')) {
|
|
114
|
-
return true;
|
|
115
|
-
}
|
|
116
|
-
if (relativePath.startsWith('.swiftpm/') ||
|
|
117
|
-
relativePath.startsWith('Pods/') ||
|
|
118
|
-
relativePath.startsWith('Carthage/Build/')) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
if (relativePath.includes('/xcuserdata/')) {
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
if (relativePath.includes('.dSYM/')) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
// User-provided ignores
|
|
128
|
-
if (opts?.ignore?.(relativePath)) {
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
return false;
|
|
132
|
-
},
|
|
133
|
-
}),
|
|
134
|
-
basisCacheDir,
|
|
135
|
-
watch: opts?.watch ?? true,
|
|
136
|
-
maxPatchBytes: opts?.maxPatchBytes ?? 4 * 1024 * 1024,
|
|
137
|
-
launchMode: 'ForegroundIfRunning',
|
|
138
|
-
log,
|
|
139
|
-
};
|
|
140
|
-
const result = await syncFolderImpl(localCodePath, codeSyncOpts);
|
|
141
|
-
if (result.stopWatching) {
|
|
142
|
-
return { stopWatching: result.stopWatching };
|
|
143
|
-
}
|
|
144
|
-
return {};
|
|
145
|
-
},
|
|
146
|
-
xcodebuild(opts) {
|
|
147
|
-
return exec({ command: 'xcodebuild', ...(opts && { xcodebuild: opts }) }, {
|
|
148
|
-
apiUrl: options.apiUrl,
|
|
149
|
-
token: options.token,
|
|
150
|
-
log,
|
|
151
|
-
});
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
//# sourceMappingURL=sandbox-client.mjs.map
|
package/sandbox-client.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox-client.mjs","sourceRoot":"","sources":["src/sandbox-client.ts"],"names":[],"mappings":"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"}
|
package/src/sandbox-client.ts
DELETED
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import os from 'os';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { syncFolder as syncFolderImpl, type FolderSyncOptions } from './folder-sync';
|
|
4
|
-
import { exec, ExecChildProcess } from './exec-client';
|
|
5
|
-
import { createIgnoreFn } from './folder-sync-ignore';
|
|
6
|
-
import crypto from 'crypto';
|
|
7
|
-
import { nodeProxyTransport } from './internal/proxy-transport';
|
|
8
|
-
|
|
9
|
-
export type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Build configuration for xcodebuild command.
|
|
13
|
-
*/
|
|
14
|
-
export type XcodeBuildConfig = {
|
|
15
|
-
workspace?: string;
|
|
16
|
-
project?: string;
|
|
17
|
-
scheme?: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Simulator connection details for configuring the sandbox.
|
|
22
|
-
*/
|
|
23
|
-
export type SimulatorConfig = {
|
|
24
|
-
/** The API URL of the simulator (limulator) */
|
|
25
|
-
apiUrl: string;
|
|
26
|
-
/** Auth token for the simulator. If not provided, uses the sandbox token. */
|
|
27
|
-
token?: string;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Options for syncing source code to the sandbox.
|
|
32
|
-
*/
|
|
33
|
-
export type SyncOptions = {
|
|
34
|
-
/**
|
|
35
|
-
* If true, watch the folder and re-sync on any changes. Defaults to true.
|
|
36
|
-
*/
|
|
37
|
-
watch?: boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Directory for the client-side folder-sync cache.
|
|
40
|
-
* Used to store the last-synced “basis” copies of files (and related sync metadata) so we can compute xdelta patches
|
|
41
|
-
* on subsequent syncs without re-downloading server state.
|
|
42
|
-
*
|
|
43
|
-
* Defaults to a temporary directory under the OS temp directory.
|
|
44
|
-
*/
|
|
45
|
-
basisCacheDir?: string;
|
|
46
|
-
/** Max patch size (bytes) to send as delta before falling back to full upload. */
|
|
47
|
-
maxPatchBytes?: number;
|
|
48
|
-
/** If true, install the app after syncing. Defaults to true. */
|
|
49
|
-
install?: boolean;
|
|
50
|
-
/**
|
|
51
|
-
* Optional predicate for ignoring files and directories during sync.
|
|
52
|
-
* Applied in addition to built-in sync and Xcode-specific ignore rules.
|
|
53
|
-
* Called with the relative path from the sync root (using forward slashes).
|
|
54
|
-
* For directories, the path ends with '/'.
|
|
55
|
-
* Return true to ignore, false to keep.
|
|
56
|
-
*
|
|
57
|
-
* @example
|
|
58
|
-
* // Ignore build folder
|
|
59
|
-
* ignore: (path) => path.startsWith('build/')
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* // Ignore anything outside src/ and JSON files
|
|
63
|
-
* ignore: (path) => !(path.startsWith('src/') || path.endsWith('.json'))
|
|
64
|
-
*/
|
|
65
|
-
ignore?: (relativePath: string) => boolean;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Result of a sync operation.
|
|
70
|
-
*/
|
|
71
|
-
export type SyncResult = {
|
|
72
|
-
/** Present only when watch=true; call to stop watching */
|
|
73
|
-
stopWatching?: () => void;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Client for interacting with a sandboxed Xcode build service.
|
|
78
|
-
*/
|
|
79
|
-
export type XCodeSandboxClient = {
|
|
80
|
-
/**
|
|
81
|
-
* Sync source code to the sandbox. In watch mode, keeps syncing on changes.
|
|
82
|
-
* Does NOT trigger builds - call xcodebuild() when ready.
|
|
83
|
-
*/
|
|
84
|
-
sync: (localCodePath: string, opts?: SyncOptions) => Promise<SyncResult>;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Trigger xcodebuild on the synced source code.
|
|
88
|
-
* Returns a ChildProcess-like object for streaming output.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* // Stream build output
|
|
92
|
-
* const build = client.xcodebuild();
|
|
93
|
-
* build.stdout.on('data', (line) => console.log(line));
|
|
94
|
-
* const { exitCode } = await build;
|
|
95
|
-
*/
|
|
96
|
-
xcodebuild: (opts?: XcodeBuildConfig) => ExecChildProcess;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export type CreateXCodeSandboxClientOptions = {
|
|
100
|
-
/** The API URL of the Xcode sandbox server */
|
|
101
|
-
apiUrl: string;
|
|
102
|
-
/** Auth token for the sandbox */
|
|
103
|
-
token: string;
|
|
104
|
-
/**
|
|
105
|
-
* Simulator (limulator) connection details. Only needed if the sandbox is not
|
|
106
|
-
* already configured (e.g., when created outside of an iOS instance).
|
|
107
|
-
* When provided, the client will call POST /simulator to set up the connection.
|
|
108
|
-
*/
|
|
109
|
-
simulator?: SimulatorConfig;
|
|
110
|
-
/**
|
|
111
|
-
* Controls logging verbosity
|
|
112
|
-
* @default 'info'
|
|
113
|
-
*/
|
|
114
|
-
logLevel?: LogLevel;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Creates a client for interacting with a sandboxed Xcode build service.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* // When using an iOS instance (simulator already configured):
|
|
122
|
-
* const client = await createXCodeSandboxClient({
|
|
123
|
-
* apiUrl: instance.status.sandbox.xcode.url,
|
|
124
|
-
* token: apiKey,
|
|
125
|
-
* });
|
|
126
|
-
*
|
|
127
|
-
* // When using a standalone sandbox (need to configure simulator):
|
|
128
|
-
* const client = await createXCodeSandboxClient({
|
|
129
|
-
* apiUrl: 'https://sandbox.example.com',
|
|
130
|
-
* token: 'xxx',
|
|
131
|
-
* simulator: {
|
|
132
|
-
* apiUrl: 'https://limulator.example.com',
|
|
133
|
-
* token: 'yyy', // optional, defaults to sandbox token
|
|
134
|
-
* },
|
|
135
|
-
* });
|
|
136
|
-
*
|
|
137
|
-
* // Sync code and build
|
|
138
|
-
* await client.sync('./my-ios-app', { watch: true });
|
|
139
|
-
* const build = client.xcodebuild();
|
|
140
|
-
* build.stdout.on('data', (line) => console.log('[build]', line));
|
|
141
|
-
* const { exitCode } = await build;
|
|
142
|
-
*/
|
|
143
|
-
export async function createXCodeSandboxClient(
|
|
144
|
-
options: CreateXCodeSandboxClientOptions,
|
|
145
|
-
): Promise<XCodeSandboxClient> {
|
|
146
|
-
const logLevel = options.logLevel ?? 'info';
|
|
147
|
-
const logger = {
|
|
148
|
-
debug: (...args: unknown[]) => {
|
|
149
|
-
if (logLevel === 'debug') console.log('[XCodeSandbox]', ...args);
|
|
150
|
-
},
|
|
151
|
-
info: (...args: unknown[]) => {
|
|
152
|
-
if (logLevel === 'info' || logLevel === 'debug') console.log('[XCodeSandbox]', ...args);
|
|
153
|
-
},
|
|
154
|
-
warn: (...args: unknown[]) => {
|
|
155
|
-
if (logLevel === 'warn' || logLevel === 'info' || logLevel === 'debug')
|
|
156
|
-
console.warn('[XCodeSandbox]', ...args);
|
|
157
|
-
},
|
|
158
|
-
error: (...args: unknown[]) => {
|
|
159
|
-
if (logLevel !== 'none') console.error('[XCodeSandbox]', ...args);
|
|
160
|
-
},
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const log = (level: 'debug' | 'info' | 'warn' | 'error', msg: string) => {
|
|
164
|
-
switch (level) {
|
|
165
|
-
case 'debug':
|
|
166
|
-
logger.debug(msg);
|
|
167
|
-
break;
|
|
168
|
-
case 'info':
|
|
169
|
-
logger.info(msg);
|
|
170
|
-
break;
|
|
171
|
-
case 'warn':
|
|
172
|
-
logger.warn(msg);
|
|
173
|
-
break;
|
|
174
|
-
case 'error':
|
|
175
|
-
logger.error(msg);
|
|
176
|
-
break;
|
|
177
|
-
default:
|
|
178
|
-
logger.info(msg);
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
// Configure the simulator connection if provided
|
|
184
|
-
if (options.simulator) {
|
|
185
|
-
const cfg: {
|
|
186
|
-
simulatorApiUrl?: string;
|
|
187
|
-
simulatorToken?: string;
|
|
188
|
-
} = {
|
|
189
|
-
simulatorApiUrl: options.simulator.apiUrl,
|
|
190
|
-
simulatorToken: options.simulator.token ?? options.token,
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const res = await nodeProxyTransport.fetch(`${options.apiUrl}/simulator`, {
|
|
194
|
-
method: 'POST',
|
|
195
|
-
headers: {
|
|
196
|
-
'Content-Type': 'application/json',
|
|
197
|
-
Authorization: `Bearer ${options.token}`,
|
|
198
|
-
},
|
|
199
|
-
body: JSON.stringify(cfg),
|
|
200
|
-
});
|
|
201
|
-
const text = await res.text();
|
|
202
|
-
if (!res.ok) {
|
|
203
|
-
throw new Error(`POST /simulator failed: ${res.status} ${text}`);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return {
|
|
208
|
-
async sync(localCodePath: string, opts?: SyncOptions): Promise<SyncResult> {
|
|
209
|
-
// Use folder name and hash of absolute path to scope basisCacheDir uniquely for each sync root
|
|
210
|
-
const resolvedPath = path.resolve(localCodePath);
|
|
211
|
-
const folderName = path.basename(resolvedPath);
|
|
212
|
-
const hash = crypto.createHash('sha1').update(resolvedPath).digest('hex').slice(0, 8);
|
|
213
|
-
const cacheKey = `limsync-cache-${folderName}-${hash}`;
|
|
214
|
-
const basisCacheDir = opts?.basisCacheDir ?? path.join(os.tmpdir(), cacheKey);
|
|
215
|
-
const codeSyncOpts: FolderSyncOptions = {
|
|
216
|
-
apiUrl: options.apiUrl,
|
|
217
|
-
token: options.token,
|
|
218
|
-
udid: cacheKey,
|
|
219
|
-
install: opts?.install ?? true,
|
|
220
|
-
ignoreFn: await createIgnoreFn(localCodePath, {
|
|
221
|
-
basisCacheDir,
|
|
222
|
-
additional: (relativePath: string) => {
|
|
223
|
-
if (
|
|
224
|
-
relativePath.startsWith('build/') ||
|
|
225
|
-
relativePath.startsWith('.build/') ||
|
|
226
|
-
relativePath.startsWith('DerivedData/') ||
|
|
227
|
-
relativePath.startsWith('Index.noindex/') ||
|
|
228
|
-
relativePath.startsWith('ModuleCache.noindex/') ||
|
|
229
|
-
relativePath.startsWith('.index-build/')
|
|
230
|
-
) {
|
|
231
|
-
return true;
|
|
232
|
-
}
|
|
233
|
-
if (
|
|
234
|
-
relativePath.startsWith('.swiftpm/') ||
|
|
235
|
-
relativePath.startsWith('Pods/') ||
|
|
236
|
-
relativePath.startsWith('Carthage/Build/')
|
|
237
|
-
) {
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
if (relativePath.includes('/xcuserdata/')) {
|
|
241
|
-
return true;
|
|
242
|
-
}
|
|
243
|
-
if (relativePath.includes('.dSYM/')) {
|
|
244
|
-
return true;
|
|
245
|
-
}
|
|
246
|
-
// User-provided ignores
|
|
247
|
-
if (opts?.ignore?.(relativePath)) {
|
|
248
|
-
return true;
|
|
249
|
-
}
|
|
250
|
-
return false;
|
|
251
|
-
},
|
|
252
|
-
}),
|
|
253
|
-
basisCacheDir,
|
|
254
|
-
watch: opts?.watch ?? true,
|
|
255
|
-
maxPatchBytes: opts?.maxPatchBytes ?? 4 * 1024 * 1024,
|
|
256
|
-
launchMode: 'ForegroundIfRunning',
|
|
257
|
-
log,
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
const result = await syncFolderImpl(localCodePath, codeSyncOpts);
|
|
261
|
-
if (result.stopWatching) {
|
|
262
|
-
return { stopWatching: result.stopWatching };
|
|
263
|
-
}
|
|
264
|
-
return {};
|
|
265
|
-
},
|
|
266
|
-
|
|
267
|
-
xcodebuild(opts?: XcodeBuildConfig): ExecChildProcess {
|
|
268
|
-
return exec(
|
|
269
|
-
{ command: 'xcodebuild', ...(opts && { xcodebuild: opts }) },
|
|
270
|
-
{
|
|
271
|
-
apiUrl: options.apiUrl,
|
|
272
|
-
token: options.token,
|
|
273
|
-
log,
|
|
274
|
-
},
|
|
275
|
-
);
|
|
276
|
-
},
|
|
277
|
-
};
|
|
278
|
-
}
|