@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.
Files changed (80) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/client.d.mts +3 -2
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +3 -2
  5. package/client.d.ts.map +1 -1
  6. package/client.js +2 -2
  7. package/client.js.map +1 -1
  8. package/client.mjs +1 -1
  9. package/client.mjs.map +1 -1
  10. package/exec-client.d.mts +3 -2
  11. package/exec-client.d.mts.map +1 -1
  12. package/exec-client.d.ts +3 -2
  13. package/exec-client.d.ts.map +1 -1
  14. package/exec-client.js +6 -1
  15. package/exec-client.js.map +1 -1
  16. package/exec-client.mjs +6 -1
  17. package/exec-client.mjs.map +1 -1
  18. package/index.d.mts +1 -1
  19. package/index.d.mts.map +1 -1
  20. package/index.d.ts +1 -1
  21. package/index.d.ts.map +1 -1
  22. package/index.js +1 -3
  23. package/index.js.map +1 -1
  24. package/index.mjs +0 -1
  25. package/index.mjs.map +1 -1
  26. package/instance-client.d.mts +13 -1
  27. package/instance-client.d.mts.map +1 -1
  28. package/instance-client.d.ts +13 -1
  29. package/instance-client.d.ts.map +1 -1
  30. package/instance-client.js +21 -2
  31. package/instance-client.js.map +1 -1
  32. package/instance-client.mjs +20 -2
  33. package/instance-client.mjs.map +1 -1
  34. package/internal/tslib.js +4 -4
  35. package/ios-client.d.mts +14 -2
  36. package/ios-client.d.mts.map +1 -1
  37. package/ios-client.d.ts +14 -2
  38. package/ios-client.d.ts.map +1 -1
  39. package/ios-client.js +24 -44
  40. package/ios-client.js.map +1 -1
  41. package/ios-client.mjs +23 -43
  42. package/ios-client.mjs.map +1 -1
  43. package/package.json +1 -11
  44. package/resources/index.d.mts +2 -1
  45. package/resources/index.d.mts.map +1 -1
  46. package/resources/index.d.ts +2 -1
  47. package/resources/index.d.ts.map +1 -1
  48. package/resources/index.js +3 -3
  49. package/resources/index.js.map +1 -1
  50. package/resources/index.mjs +1 -1
  51. package/resources/index.mjs.map +1 -1
  52. package/resources/xcode-instances-helpers.d.mts +76 -0
  53. package/resources/xcode-instances-helpers.d.mts.map +1 -0
  54. package/resources/xcode-instances-helpers.d.ts +76 -0
  55. package/resources/xcode-instances-helpers.d.ts.map +1 -0
  56. package/resources/xcode-instances-helpers.js +150 -0
  57. package/resources/xcode-instances-helpers.js.map +1 -0
  58. package/resources/xcode-instances-helpers.mjs +145 -0
  59. package/resources/xcode-instances-helpers.mjs.map +1 -0
  60. package/src/client.ts +11 -1
  61. package/src/exec-client.ts +8 -3
  62. package/src/index.ts +6 -9
  63. package/src/instance-client.ts +25 -4
  64. package/src/ios-client.ts +27 -44
  65. package/src/resources/index.ts +7 -1
  66. package/src/resources/xcode-instances-helpers.ts +228 -0
  67. package/src/version.ts +1 -1
  68. package/version.d.mts +1 -1
  69. package/version.d.ts +1 -1
  70. package/version.js +1 -1
  71. package/version.mjs +1 -1
  72. package/sandbox-client.d.mts +0 -129
  73. package/sandbox-client.d.mts.map +0 -1
  74. package/sandbox-client.d.ts +0 -129
  75. package/sandbox-client.d.ts.map +0 -1
  76. package/sandbox-client.js +0 -159
  77. package/sandbox-client.js.map +0 -1
  78. package/sandbox-client.mjs +0 -155
  79. package/sandbox-client.mjs.map +0 -1
  80. package/src/sandbox-client.ts +0 -278
@@ -0,0 +1,76 @@
1
+ import { XcodeInstances as GeneratedXcodeInstances, type XcodeInstance } from "./xcode-instances.mjs";
2
+ import { type IosInstance } from "./ios-instances.mjs";
3
+ import { type ExecChildProcess } from "../exec-client.mjs";
4
+ export type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
5
+ export type SyncOptions = {
6
+ /**
7
+ * If true, watch the folder and re-sync on any changes. Defaults to true.
8
+ */
9
+ watch?: boolean;
10
+ /**
11
+ * Directory for the client-side folder-sync cache.
12
+ * Defaults to a temporary directory under the OS temp directory.
13
+ */
14
+ basisCacheDir?: string;
15
+ /** Max patch size (bytes) to send as delta before falling back to full upload. */
16
+ maxPatchBytes?: number;
17
+ /** If true, install the app after syncing. Defaults to true. */
18
+ install?: boolean;
19
+ /**
20
+ * Optional predicate for ignoring files and directories during sync.
21
+ * Called with the relative path from the sync root (using forward slashes).
22
+ * For directories, the path ends with '/'.
23
+ * Return true to ignore, false to keep.
24
+ */
25
+ ignore?: (relativePath: string) => boolean;
26
+ };
27
+ export type SyncResult = {
28
+ /** Present only when watch=true; call to stop watching */
29
+ stopWatching?: () => void;
30
+ };
31
+ export type XcodeProjectConfig = {
32
+ workspace?: string;
33
+ project?: string;
34
+ scheme?: string;
35
+ };
36
+ export type XcodeBuildOptions = {
37
+ upload?: {
38
+ assetName: string;
39
+ };
40
+ };
41
+ export type XcodeClient = {
42
+ /**
43
+ * Sync source code to the xcode instance. In watch mode, keeps syncing on changes.
44
+ */
45
+ sync: (localCodePath: string, opts?: SyncOptions) => Promise<SyncResult>;
46
+ /**
47
+ * Trigger xcodebuild on the synced source code.
48
+ * Returns a ChildProcess-like object for streaming output.
49
+ *
50
+ * @example
51
+ * const build = xcode.xcodebuild({ scheme: 'MyApp' });
52
+ * build.stdout.on('data', (line) => console.log(line));
53
+ * const { exitCode } = await build;
54
+ */
55
+ xcodebuild: (settings?: XcodeProjectConfig, options?: XcodeBuildOptions) => ExecChildProcess;
56
+ /**
57
+ * Attach a simulator to this xcode instance.
58
+ * After attaching, builds will auto-install on the simulator.
59
+ */
60
+ attachSimulator: (simulator: IosInstance | {
61
+ apiUrl: string;
62
+ token: string;
63
+ }) => Promise<void>;
64
+ };
65
+ export type XcodeCreateClientParams = {
66
+ instance: XcodeInstance;
67
+ logLevel?: LogLevel;
68
+ } | {
69
+ apiUrl: string;
70
+ token: string;
71
+ logLevel?: LogLevel;
72
+ };
73
+ export declare class XcodeInstances extends GeneratedXcodeInstances {
74
+ createClient(params: XcodeCreateClientParams): Promise<XcodeClient>;
75
+ }
76
+ //# sourceMappingURL=xcode-instances-helpers.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcode-instances-helpers.d.mts","sourceRoot":"","sources":["../src/resources/xcode-instances-helpers.ts"],"names":[],"mappings":"OAIO,EAAE,cAAc,IAAI,uBAAuB,EAAE,KAAK,aAAa,EAAE;OACjE,EAAE,KAAK,WAAW,EAAE;OACpB,EAAQ,KAAK,gBAAgB,EAAoB;AAKxD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpE,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAEzE;;;;;;;;OAQG;IACH,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,iBAAiB,KAAK,gBAAgB,CAAC;IAE7F;;;OAGG;IACH,eAAe,EAAE,CAAC,SAAS,EAAE,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC;AAkB3D,qBAAa,cAAe,SAAQ,uBAAuB;IACnD,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC;CAmI1E"}
@@ -0,0 +1,76 @@
1
+ import { XcodeInstances as GeneratedXcodeInstances, type XcodeInstance } from "./xcode-instances.js";
2
+ import { type IosInstance } from "./ios-instances.js";
3
+ import { type ExecChildProcess } from "../exec-client.js";
4
+ export type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
5
+ export type SyncOptions = {
6
+ /**
7
+ * If true, watch the folder and re-sync on any changes. Defaults to true.
8
+ */
9
+ watch?: boolean;
10
+ /**
11
+ * Directory for the client-side folder-sync cache.
12
+ * Defaults to a temporary directory under the OS temp directory.
13
+ */
14
+ basisCacheDir?: string;
15
+ /** Max patch size (bytes) to send as delta before falling back to full upload. */
16
+ maxPatchBytes?: number;
17
+ /** If true, install the app after syncing. Defaults to true. */
18
+ install?: boolean;
19
+ /**
20
+ * Optional predicate for ignoring files and directories during sync.
21
+ * Called with the relative path from the sync root (using forward slashes).
22
+ * For directories, the path ends with '/'.
23
+ * Return true to ignore, false to keep.
24
+ */
25
+ ignore?: (relativePath: string) => boolean;
26
+ };
27
+ export type SyncResult = {
28
+ /** Present only when watch=true; call to stop watching */
29
+ stopWatching?: () => void;
30
+ };
31
+ export type XcodeProjectConfig = {
32
+ workspace?: string;
33
+ project?: string;
34
+ scheme?: string;
35
+ };
36
+ export type XcodeBuildOptions = {
37
+ upload?: {
38
+ assetName: string;
39
+ };
40
+ };
41
+ export type XcodeClient = {
42
+ /**
43
+ * Sync source code to the xcode instance. In watch mode, keeps syncing on changes.
44
+ */
45
+ sync: (localCodePath: string, opts?: SyncOptions) => Promise<SyncResult>;
46
+ /**
47
+ * Trigger xcodebuild on the synced source code.
48
+ * Returns a ChildProcess-like object for streaming output.
49
+ *
50
+ * @example
51
+ * const build = xcode.xcodebuild({ scheme: 'MyApp' });
52
+ * build.stdout.on('data', (line) => console.log(line));
53
+ * const { exitCode } = await build;
54
+ */
55
+ xcodebuild: (settings?: XcodeProjectConfig, options?: XcodeBuildOptions) => ExecChildProcess;
56
+ /**
57
+ * Attach a simulator to this xcode instance.
58
+ * After attaching, builds will auto-install on the simulator.
59
+ */
60
+ attachSimulator: (simulator: IosInstance | {
61
+ apiUrl: string;
62
+ token: string;
63
+ }) => Promise<void>;
64
+ };
65
+ export type XcodeCreateClientParams = {
66
+ instance: XcodeInstance;
67
+ logLevel?: LogLevel;
68
+ } | {
69
+ apiUrl: string;
70
+ token: string;
71
+ logLevel?: LogLevel;
72
+ };
73
+ export declare class XcodeInstances extends GeneratedXcodeInstances {
74
+ createClient(params: XcodeCreateClientParams): Promise<XcodeClient>;
75
+ }
76
+ //# sourceMappingURL=xcode-instances-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcode-instances-helpers.d.ts","sourceRoot":"","sources":["../src/resources/xcode-instances-helpers.ts"],"names":[],"mappings":"OAIO,EAAE,cAAc,IAAI,uBAAuB,EAAE,KAAK,aAAa,EAAE;OACjE,EAAE,KAAK,WAAW,EAAE;OACpB,EAAQ,KAAK,gBAAgB,EAAoB;AAKxD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpE,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB;;OAEG;IACH,IAAI,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAEzE;;;;;;;;OAQG;IACH,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,iBAAiB,KAAK,gBAAgB,CAAC;IAE7F;;;OAGG;IACH,eAAe,EAAE,CAAC,SAAS,EAAE,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChG,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,CAAC;AAkB3D,qBAAa,cAAe,SAAQ,uBAAuB;IACnD,YAAY,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC;CAmI1E"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XcodeInstances = void 0;
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 crypto_1 = tslib_1.__importDefault(require("crypto"));
8
+ const xcode_instances_1 = require("./xcode-instances.js");
9
+ const exec_client_1 = require("../exec-client.js");
10
+ const folder_sync_1 = require("../folder-sync.js");
11
+ const folder_sync_ignore_1 = require("../folder-sync-ignore.js");
12
+ const proxy_transport_1 = require("../internal/proxy-transport.js");
13
+ function createLogger(logLevel) {
14
+ const shouldLog = (level) => {
15
+ const levels = ['none', 'error', 'warn', 'info', 'debug'];
16
+ return levels.indexOf(logLevel) >= levels.indexOf(level);
17
+ };
18
+ return (level, msg) => {
19
+ if (!shouldLog(level))
20
+ return;
21
+ const prefix = '[XcodeInstance]';
22
+ if (level === 'error' || level === 'warn') {
23
+ console[level](prefix, msg);
24
+ }
25
+ else {
26
+ console.log(prefix, msg);
27
+ }
28
+ };
29
+ }
30
+ class XcodeInstances extends xcode_instances_1.XcodeInstances {
31
+ async createClient(params) {
32
+ let apiUrl;
33
+ let token;
34
+ if ('instance' in params) {
35
+ if (!params.instance.status.apiUrl) {
36
+ throw new Error('Instance not ready: apiUrl is not available');
37
+ }
38
+ apiUrl = params.instance.status.apiUrl;
39
+ token = params.instance.status.token;
40
+ }
41
+ else {
42
+ apiUrl = params.apiUrl;
43
+ token = params.token;
44
+ }
45
+ const log = createLogger(params.logLevel ?? 'info');
46
+ const client = this._client;
47
+ return {
48
+ async sync(localCodePath, opts) {
49
+ const resolvedPath = path_1.default.resolve(localCodePath);
50
+ const folderName = path_1.default.basename(resolvedPath);
51
+ const hash = crypto_1.default.createHash('sha1').update(resolvedPath).digest('hex').slice(0, 8);
52
+ const cacheKey = `limsync-cache-${folderName}-${hash}`;
53
+ const basisCacheDir = opts?.basisCacheDir ?? path_1.default.join(os_1.default.tmpdir(), cacheKey);
54
+ const codeSyncOpts = {
55
+ apiUrl,
56
+ token,
57
+ udid: cacheKey,
58
+ install: opts?.install ?? true,
59
+ ignoreFn: await (0, folder_sync_ignore_1.createIgnoreFn)(localCodePath, {
60
+ basisCacheDir,
61
+ additional: (relativePath) => {
62
+ if (relativePath.startsWith('build/') ||
63
+ relativePath.startsWith('.build/') ||
64
+ relativePath.startsWith('DerivedData/') ||
65
+ relativePath.startsWith('Index.noindex/') ||
66
+ relativePath.startsWith('ModuleCache.noindex/') ||
67
+ relativePath.startsWith('.index-build/')) {
68
+ return true;
69
+ }
70
+ if (relativePath.startsWith('.swiftpm/') ||
71
+ relativePath.startsWith('Pods/') ||
72
+ relativePath.startsWith('Carthage/Build/')) {
73
+ return true;
74
+ }
75
+ if (relativePath.includes('/xcuserdata/')) {
76
+ return true;
77
+ }
78
+ if (relativePath.includes('.dSYM/')) {
79
+ return true;
80
+ }
81
+ if (opts?.ignore?.(relativePath)) {
82
+ return true;
83
+ }
84
+ return false;
85
+ },
86
+ }),
87
+ basisCacheDir,
88
+ watch: opts?.watch ?? true,
89
+ maxPatchBytes: opts?.maxPatchBytes ?? 4 * 1024 * 1024,
90
+ launchMode: 'ForegroundIfRunning',
91
+ log,
92
+ };
93
+ const result = await (0, folder_sync_1.syncFolder)(localCodePath, codeSyncOpts);
94
+ if (result.stopWatching) {
95
+ return { stopWatching: result.stopWatching };
96
+ }
97
+ return {};
98
+ },
99
+ xcodebuild(settings, options) {
100
+ const request = {
101
+ command: 'xcodebuild',
102
+ ...(settings && { xcodebuild: settings }),
103
+ };
104
+ if (options?.upload) {
105
+ const uploadName = options.upload.assetName;
106
+ const requestPromise = client.assets
107
+ .getOrCreate({ name: uploadName })
108
+ .then((asset) => {
109
+ request.signedUploadUrl = asset.signedUploadUrl;
110
+ return request;
111
+ })
112
+ .catch((err) => {
113
+ throw new Error(`Failed to create upload URL for artifact '${uploadName}': ${err instanceof Error ? err.message : err}`);
114
+ });
115
+ return (0, exec_client_1.exec)(requestPromise, { apiUrl, token, log });
116
+ }
117
+ return (0, exec_client_1.exec)(request, { apiUrl, token, log });
118
+ },
119
+ async attachSimulator(simulator) {
120
+ let simApiUrl;
121
+ let simToken;
122
+ if ('status' in simulator) {
123
+ if (!simulator.status.apiUrl) {
124
+ throw new Error('Simulator instance not ready: apiUrl is not available');
125
+ }
126
+ simApiUrl = simulator.status.apiUrl;
127
+ simToken = simulator.status.token;
128
+ }
129
+ else {
130
+ simApiUrl = simulator.apiUrl;
131
+ simToken = simulator.token;
132
+ }
133
+ const res = await proxy_transport_1.nodeProxyTransport.fetch(`${apiUrl}/simulator`, {
134
+ method: 'POST',
135
+ headers: {
136
+ 'Content-Type': 'application/json',
137
+ Authorization: `Bearer ${token}`,
138
+ },
139
+ body: JSON.stringify({ apiUrl: simApiUrl, token: simToken }),
140
+ });
141
+ if (!res.ok) {
142
+ const text = await res.text();
143
+ throw new Error(`POST /simulator failed: ${res.status} ${text}`);
144
+ }
145
+ },
146
+ };
147
+ }
148
+ }
149
+ exports.XcodeInstances = XcodeInstances;
150
+ //# sourceMappingURL=xcode-instances-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcode-instances-helpers.js","sourceRoot":"","sources":["../src/resources/xcode-instances-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import os from 'os';
2
+ import path from 'path';
3
+ import crypto from 'crypto';
4
+ import { XcodeInstances as GeneratedXcodeInstances } from "./xcode-instances.mjs";
5
+ import { exec } from "../exec-client.mjs";
6
+ import { syncFolder as syncFolderImpl } from "../folder-sync.mjs";
7
+ import { createIgnoreFn } from "../folder-sync-ignore.mjs";
8
+ import { nodeProxyTransport } from "../internal/proxy-transport.mjs";
9
+ function createLogger(logLevel) {
10
+ const shouldLog = (level) => {
11
+ const levels = ['none', 'error', 'warn', 'info', 'debug'];
12
+ return levels.indexOf(logLevel) >= levels.indexOf(level);
13
+ };
14
+ return (level, msg) => {
15
+ if (!shouldLog(level))
16
+ return;
17
+ const prefix = '[XcodeInstance]';
18
+ if (level === 'error' || level === 'warn') {
19
+ console[level](prefix, msg);
20
+ }
21
+ else {
22
+ console.log(prefix, msg);
23
+ }
24
+ };
25
+ }
26
+ export class XcodeInstances extends GeneratedXcodeInstances {
27
+ async createClient(params) {
28
+ let apiUrl;
29
+ let token;
30
+ if ('instance' in params) {
31
+ if (!params.instance.status.apiUrl) {
32
+ throw new Error('Instance not ready: apiUrl is not available');
33
+ }
34
+ apiUrl = params.instance.status.apiUrl;
35
+ token = params.instance.status.token;
36
+ }
37
+ else {
38
+ apiUrl = params.apiUrl;
39
+ token = params.token;
40
+ }
41
+ const log = createLogger(params.logLevel ?? 'info');
42
+ const client = this._client;
43
+ return {
44
+ async sync(localCodePath, opts) {
45
+ const resolvedPath = path.resolve(localCodePath);
46
+ const folderName = path.basename(resolvedPath);
47
+ const hash = crypto.createHash('sha1').update(resolvedPath).digest('hex').slice(0, 8);
48
+ const cacheKey = `limsync-cache-${folderName}-${hash}`;
49
+ const basisCacheDir = opts?.basisCacheDir ?? path.join(os.tmpdir(), cacheKey);
50
+ const codeSyncOpts = {
51
+ apiUrl,
52
+ token,
53
+ udid: cacheKey,
54
+ install: opts?.install ?? true,
55
+ ignoreFn: await createIgnoreFn(localCodePath, {
56
+ basisCacheDir,
57
+ additional: (relativePath) => {
58
+ if (relativePath.startsWith('build/') ||
59
+ relativePath.startsWith('.build/') ||
60
+ relativePath.startsWith('DerivedData/') ||
61
+ relativePath.startsWith('Index.noindex/') ||
62
+ relativePath.startsWith('ModuleCache.noindex/') ||
63
+ relativePath.startsWith('.index-build/')) {
64
+ return true;
65
+ }
66
+ if (relativePath.startsWith('.swiftpm/') ||
67
+ relativePath.startsWith('Pods/') ||
68
+ relativePath.startsWith('Carthage/Build/')) {
69
+ return true;
70
+ }
71
+ if (relativePath.includes('/xcuserdata/')) {
72
+ return true;
73
+ }
74
+ if (relativePath.includes('.dSYM/')) {
75
+ return true;
76
+ }
77
+ if (opts?.ignore?.(relativePath)) {
78
+ return true;
79
+ }
80
+ return false;
81
+ },
82
+ }),
83
+ basisCacheDir,
84
+ watch: opts?.watch ?? true,
85
+ maxPatchBytes: opts?.maxPatchBytes ?? 4 * 1024 * 1024,
86
+ launchMode: 'ForegroundIfRunning',
87
+ log,
88
+ };
89
+ const result = await syncFolderImpl(localCodePath, codeSyncOpts);
90
+ if (result.stopWatching) {
91
+ return { stopWatching: result.stopWatching };
92
+ }
93
+ return {};
94
+ },
95
+ xcodebuild(settings, options) {
96
+ const request = {
97
+ command: 'xcodebuild',
98
+ ...(settings && { xcodebuild: settings }),
99
+ };
100
+ if (options?.upload) {
101
+ const uploadName = options.upload.assetName;
102
+ const requestPromise = client.assets
103
+ .getOrCreate({ name: uploadName })
104
+ .then((asset) => {
105
+ request.signedUploadUrl = asset.signedUploadUrl;
106
+ return request;
107
+ })
108
+ .catch((err) => {
109
+ throw new Error(`Failed to create upload URL for artifact '${uploadName}': ${err instanceof Error ? err.message : err}`);
110
+ });
111
+ return exec(requestPromise, { apiUrl, token, log });
112
+ }
113
+ return exec(request, { apiUrl, token, log });
114
+ },
115
+ async attachSimulator(simulator) {
116
+ let simApiUrl;
117
+ let simToken;
118
+ if ('status' in simulator) {
119
+ if (!simulator.status.apiUrl) {
120
+ throw new Error('Simulator instance not ready: apiUrl is not available');
121
+ }
122
+ simApiUrl = simulator.status.apiUrl;
123
+ simToken = simulator.status.token;
124
+ }
125
+ else {
126
+ simApiUrl = simulator.apiUrl;
127
+ simToken = simulator.token;
128
+ }
129
+ const res = await nodeProxyTransport.fetch(`${apiUrl}/simulator`, {
130
+ method: 'POST',
131
+ headers: {
132
+ 'Content-Type': 'application/json',
133
+ Authorization: `Bearer ${token}`,
134
+ },
135
+ body: JSON.stringify({ apiUrl: simApiUrl, token: simToken }),
136
+ });
137
+ if (!res.ok) {
138
+ const text = await res.text();
139
+ throw new Error(`POST /simulator failed: ${res.status} ${text}`);
140
+ }
141
+ },
142
+ };
143
+ }
144
+ }
145
+ //# sourceMappingURL=xcode-instances-helpers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xcode-instances-helpers.mjs","sourceRoot":"","sources":["../src/resources/xcode-instances-helpers.ts"],"names":[],"mappings":"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"}
package/src/client.ts CHANGED
@@ -45,9 +45,15 @@ import {
45
45
  XcodeInstance,
46
46
  XcodeInstanceCreateParams,
47
47
  XcodeInstanceListParams,
48
- XcodeInstances,
49
48
  XcodeInstancesItems,
50
49
  } from './resources/xcode-instances';
50
+ import {
51
+ XcodeInstances,
52
+ XcodeCreateClientParams,
53
+ XcodeClient,
54
+ XcodeProjectConfig,
55
+ XcodeBuildOptions,
56
+ } from './resources/xcode-instances-helpers';
51
57
  import { type Fetch } from './internal/builtin-types';
52
58
  import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
53
59
  import { FinalRequestOptions, RequestOptions } from './internal/request-options';
@@ -828,5 +834,9 @@ export declare namespace Limrun {
828
834
  type XcodeInstancesItems as XcodeInstancesItems,
829
835
  type XcodeInstanceCreateParams as XcodeInstanceCreateParams,
830
836
  type XcodeInstanceListParams as XcodeInstanceListParams,
837
+ type XcodeCreateClientParams as XcodeCreateClientParams,
838
+ type XcodeClient as XcodeClient,
839
+ type XcodeProjectConfig as XcodeProjectConfig,
840
+ type XcodeBuildOptions as XcodeBuildOptions,
831
841
  };
832
842
  }
@@ -19,6 +19,7 @@ export type ExecRequest = {
19
19
  project?: string;
20
20
  scheme?: string;
21
21
  };
22
+ signedUploadUrl?: string;
22
23
  };
23
24
 
24
25
  export type ExecOptions = {
@@ -107,10 +108,14 @@ export class ExecChildProcess implements PromiseLike<ExecResult> {
107
108
  private readonly options: ExecOptions;
108
109
  private readonly log: (level: 'debug' | 'info' | 'warn' | 'error', msg: string) => void;
109
110
 
110
- constructor(request: ExecRequest, options: ExecOptions) {
111
+ constructor(request: ExecRequest | Promise<ExecRequest>, options: ExecOptions) {
111
112
  this.options = options;
112
113
  this.log = options.log ?? (() => {});
113
- this.resultPromise = this.run(request);
114
+ if (request instanceof Promise) {
115
+ this.resultPromise = request.then((r) => this.run(r));
116
+ } else {
117
+ this.resultPromise = this.run(request);
118
+ }
114
119
  }
115
120
 
116
121
  /** Implement PromiseLike so this object can be awaited */
@@ -331,6 +336,6 @@ export class ExecChildProcess implements PromiseLike<ExecResult> {
331
336
  * // Wait for completion
332
337
  * const { exitCode, status } = await proc;
333
338
  */
334
- export function exec(request: ExecRequest, options: ExecOptions): ExecChildProcess {
339
+ export function exec(request: ExecRequest | Promise<ExecRequest>, options: ExecOptions): ExecChildProcess {
335
340
  return new ExecChildProcess(request, options);
336
341
  }
package/src/index.ts CHANGED
@@ -8,15 +8,6 @@ export { Limrun, type ClientOptions } from './client';
8
8
  export { PagePromise } from './core/pagination';
9
9
  export * from './instance-client';
10
10
  export * as Ios from './ios-client';
11
- export {
12
- createXCodeSandboxClient,
13
- type XCodeSandboxClient,
14
- type CreateXCodeSandboxClientOptions,
15
- type SimulatorConfig,
16
- type SyncOptions,
17
- type SyncResult,
18
- type XcodeBuildConfig,
19
- } from './sandbox-client';
20
11
  export {
21
12
  exec,
22
13
  type ExecRequest,
@@ -24,6 +15,12 @@ export {
24
15
  type ExecResult,
25
16
  type ExecChildProcess,
26
17
  } from './exec-client';
18
+ export {
19
+ type XcodeCreateClientParams,
20
+ type XcodeClient,
21
+ type XcodeProjectConfig,
22
+ type XcodeBuildOptions,
23
+ } from './resources/xcode-instances-helpers';
27
24
  export {
28
25
  LimrunError,
29
26
  APIError,
@@ -84,8 +84,10 @@ export type InstanceClient = {
84
84
  openUrl: (url: string) => Promise<OpenUrlResult>;
85
85
  /**
86
86
  * Start recording device video. Use stopRecording() to finish the recording.
87
+ * When provided, `quality` must be one of `5`, `6`, `7`, `8`, `9`, or `10`.
88
+ * The server default is `5`.
87
89
  */
88
- startRecording: () => Promise<void>;
90
+ startRecording: (options?: { quality?: RecordingQuality }) => Promise<void>;
89
91
  /**
90
92
  * Stop the active server-side recording.
91
93
  * If `saveTo.presignedUrl` is provided, the server uploads the completed file there before resolving.
@@ -128,6 +130,14 @@ export type InstanceClient = {
128
130
  export type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
129
131
 
130
132
  export type ScrollDirection = 'up' | 'down' | 'left' | 'right';
133
+ export enum RecordingQuality {
134
+ Q5 = 5,
135
+ Q6 = 6,
136
+ Q7 = 7,
137
+ Q8 = 8,
138
+ Q9 = 9,
139
+ Q10 = 10,
140
+ }
131
141
 
132
142
  export type AndroidSelector = {
133
143
  resourceId?: string;
@@ -397,7 +407,7 @@ type CommandRequestMap = {
397
407
  scrollScreen: { direction: ScrollDirection; amount?: number };
398
408
  scrollElement: AndroidElementTarget & { direction: ScrollDirection; amount?: number };
399
409
  openUrl: { url: string };
400
- startRecording: Record<string, never>;
410
+ startRecording: { quality?: RecordingQuality };
401
411
  stopRecording: { upload?: { presignedUrl: string } };
402
412
  };
403
413
 
@@ -904,8 +914,19 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
904
914
  };
905
915
  };
906
916
 
907
- const startRecording = async (): Promise<void> => {
908
- await sendRequest('startRecording', {});
917
+ const startRecording = async (recordingOptions?: { quality?: RecordingQuality }): Promise<void> => {
918
+ const request: CommandRequestMap['startRecording'] = {};
919
+ if (recordingOptions?.quality !== undefined) {
920
+ if (
921
+ !Number.isInteger(recordingOptions.quality) ||
922
+ recordingOptions.quality < 5 ||
923
+ recordingOptions.quality > 10
924
+ ) {
925
+ throw new Error('quality must be one of: 5, 6, 7, 8, 9, 10');
926
+ }
927
+ request.quality = recordingOptions.quality;
928
+ }
929
+ await sendRequest('startRecording', request);
909
930
  };
910
931
 
911
932
  const stopRecording = async (saveTo: { presignedUrl?: string; localPath?: string }): Promise<string> => {