@limrun/api 0.41.0 → 0.42.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 (95) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/client.d.mts +4 -0
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +4 -0
  5. package/client.d.ts.map +1 -1
  6. package/client.js +3 -0
  7. package/client.js.map +1 -1
  8. package/client.mjs +3 -0
  9. package/client.mjs.map +1 -1
  10. package/exec-client.d.mts +34 -1
  11. package/exec-client.d.mts.map +1 -1
  12. package/exec-client.d.ts +34 -1
  13. package/exec-client.d.ts.map +1 -1
  14. package/exec-client.js +18 -4
  15. package/exec-client.js.map +1 -1
  16. package/exec-client.mjs +18 -4
  17. package/exec-client.mjs.map +1 -1
  18. package/folder-sync-ignore.d.mts +8 -0
  19. package/folder-sync-ignore.d.mts.map +1 -1
  20. package/folder-sync-ignore.d.ts +8 -0
  21. package/folder-sync-ignore.d.ts.map +1 -1
  22. package/folder-sync-ignore.js +12 -4
  23. package/folder-sync-ignore.js.map +1 -1
  24. package/folder-sync-ignore.mjs +12 -4
  25. package/folder-sync-ignore.mjs.map +1 -1
  26. package/index.d.mts +2 -1
  27. package/index.d.mts.map +1 -1
  28. package/index.d.ts +2 -1
  29. package/index.d.ts.map +1 -1
  30. package/index.js.map +1 -1
  31. package/index.mjs.map +1 -1
  32. package/ios-client.d.mts +49 -5
  33. package/ios-client.d.mts.map +1 -1
  34. package/ios-client.d.ts +49 -5
  35. package/ios-client.d.ts.map +1 -1
  36. package/ios-client.js +40 -3
  37. package/ios-client.js.map +1 -1
  38. package/ios-client.mjs +40 -3
  39. package/ios-client.mjs.map +1 -1
  40. package/package.json +1 -1
  41. package/resources/daemon-client-shared.d.mts +37 -0
  42. package/resources/daemon-client-shared.d.mts.map +1 -0
  43. package/resources/daemon-client-shared.d.ts +37 -0
  44. package/resources/daemon-client-shared.d.ts.map +1 -0
  45. package/resources/daemon-client-shared.js +51 -0
  46. package/resources/daemon-client-shared.js.map +1 -0
  47. package/resources/daemon-client-shared.mjs +45 -0
  48. package/resources/daemon-client-shared.mjs.map +1 -0
  49. package/resources/gradle-instances-helpers.d.mts +54 -0
  50. package/resources/gradle-instances-helpers.d.mts.map +1 -0
  51. package/resources/gradle-instances-helpers.d.ts +54 -0
  52. package/resources/gradle-instances-helpers.d.ts.map +1 -0
  53. package/resources/gradle-instances-helpers.js +98 -0
  54. package/resources/gradle-instances-helpers.js.map +1 -0
  55. package/resources/gradle-instances-helpers.mjs +94 -0
  56. package/resources/gradle-instances-helpers.mjs.map +1 -0
  57. package/resources/gradle-instances.d.mts +149 -0
  58. package/resources/gradle-instances.d.mts.map +1 -0
  59. package/resources/gradle-instances.d.ts +149 -0
  60. package/resources/gradle-instances.d.ts.map +1 -0
  61. package/resources/gradle-instances.js +41 -0
  62. package/resources/gradle-instances.js.map +1 -0
  63. package/resources/gradle-instances.mjs +37 -0
  64. package/resources/gradle-instances.mjs.map +1 -0
  65. package/resources/index.d.mts +2 -0
  66. package/resources/index.d.mts.map +1 -1
  67. package/resources/index.d.ts +2 -0
  68. package/resources/index.d.ts.map +1 -1
  69. package/resources/index.js +3 -1
  70. package/resources/index.js.map +1 -1
  71. package/resources/index.mjs +1 -0
  72. package/resources/index.mjs.map +1 -1
  73. package/resources/xcode-instances-helpers.d.mts +2 -11
  74. package/resources/xcode-instances-helpers.d.mts.map +1 -1
  75. package/resources/xcode-instances-helpers.d.ts +2 -11
  76. package/resources/xcode-instances-helpers.d.ts.map +1 -1
  77. package/resources/xcode-instances-helpers.js +5 -41
  78. package/resources/xcode-instances-helpers.js.map +1 -1
  79. package/resources/xcode-instances-helpers.mjs +3 -38
  80. package/resources/xcode-instances-helpers.mjs.map +1 -1
  81. package/src/client.ts +27 -0
  82. package/src/exec-client.ts +55 -5
  83. package/src/folder-sync-ignore.ts +22 -6
  84. package/src/index.ts +10 -0
  85. package/src/ios-client.ts +99 -8
  86. package/src/resources/daemon-client-shared.ts +71 -0
  87. package/src/resources/gradle-instances-helpers.ts +155 -0
  88. package/src/resources/gradle-instances.ts +206 -0
  89. package/src/resources/index.ts +13 -0
  90. package/src/resources/xcode-instances-helpers.ts +13 -59
  91. package/src/version.ts +1 -1
  92. package/version.d.mts +1 -1
  93. package/version.d.ts +1 -1
  94. package/version.js +1 -1
  95. package/version.mjs +1 -1
package/src/index.ts CHANGED
@@ -13,6 +13,10 @@ export { buildSettingKeyPattern, parseBuildSettingEntries, validateBuildSettings
13
13
  export {
14
14
  exec,
15
15
  type ExecRequest,
16
+ type XcodeBuildExecRequest,
17
+ type GradleAndroidABI,
18
+ type GradleBuildExecRequest,
19
+ type GradleReactNativeConfig,
16
20
  type ExecOptions,
17
21
  type ExecResult,
18
22
  type ExecChildProcess,
@@ -46,6 +50,12 @@ export {
46
50
  type SimulatorDeviceInfo,
47
51
  type SimulatorInstallState,
48
52
  } from './resources/xcode-instances-helpers';
53
+ export {
54
+ type GradleCreateClientParams,
55
+ type GradleClient,
56
+ type GradleSyncOptions,
57
+ type GradleBuildOptions,
58
+ } from './resources/gradle-instances-helpers';
49
59
  export {
50
60
  LIMRUN_DIR,
51
61
  TRY_IMPORT_LINE,
package/src/ios-client.ts CHANGED
@@ -210,6 +210,20 @@ export type HttpProxyOptions = {
210
210
  localPort: number;
211
211
  };
212
212
 
213
+ /**
214
+ * Targets a file operation at an installed app's container instead of the
215
+ * sandbox staging folder. Mirrors `simctl get_app_container` semantics.
216
+ */
217
+ export type ContainerTargetOptions = {
218
+ /** Bundle ID of the installed app whose container should be targeted. */
219
+ bundleId: string;
220
+ /**
221
+ * Container to target: `app`, `data`, or a specific App Group identifier.
222
+ * Defaults to `app` server-side, matching `simctl get_app_container`.
223
+ */
224
+ containerType?: string;
225
+ };
226
+
213
227
  /**
214
228
  * Result of auto-discovering a StoreKit configuration from the
215
229
  * simulator's cached sandbox response.
@@ -794,12 +808,45 @@ export type InstanceClient = {
794
808
  simctl: (args: string[], opts?: { disconnectOnExit?: boolean }) => SimctlExecution;
795
809
 
796
810
  /**
797
- * Copy a file to the sandbox of the simulator. Returns the path of the file that can be used in simctl commands.
798
- * @param name The name of the file in the sandbox of the simulator.
799
- * @param path The path of the file to copy to the sandbox of the simulator.
800
- * @returns A promise that resolves to the path of the file that can be used in simctl commands.
811
+ * Push a local file to the simulator. Returns the path of the file on the simulator host
812
+ * that can be used in simctl commands.
813
+ *
814
+ * When `opts.bundleId` is provided, `destination` is treated as a relative path inside
815
+ * that app's container on the simulator (intermediate directories are created
816
+ * as needed) instead of a filename in the sandbox staging folder.
817
+ *
818
+ * @param path The path of the local file to copy to the simulator.
819
+ * @param destination The name of the file in the sandbox of the simulator, or a relative path inside the app container when `opts.bundleId` is set.
820
+ * @param opts Optional app container targeting.
821
+ * @param opts.bundleId Bundle ID of the installed app whose container should receive the file.
822
+ * @param opts.containerType Container to target: `app`, `data`, or a specific App Group identifier. Defaults to `app` server-side, matching `simctl get_app_container`.
823
+ * @returns A promise that resolves to the path of the file on the simulator host.
801
824
  */
802
- cp: (name: string, path: string) => Promise<string>;
825
+ pushFile: (path: string, destination: string, opts?: ContainerTargetOptions) => Promise<string>;
826
+
827
+ /**
828
+ * Read a file from the simulator and return its content.
829
+ *
830
+ * When `opts.bundleId` is provided, `name` is treated as a relative path inside
831
+ * that app's container; otherwise it addresses the sandbox staging folder
832
+ * (the same namespace `pushFile` uploads to without a bundle ID).
833
+ *
834
+ * @param name The name of the file, or a relative path inside the app container when `opts.bundleId` is set.
835
+ * @param opts Optional app container targeting (see `pushFile`).
836
+ * @returns A promise that resolves to the file content.
837
+ */
838
+ pullFile: (name: string, opts?: ContainerTargetOptions) => Promise<Buffer>;
839
+
840
+ /**
841
+ * Delete a file or folder (recursively) on the simulator.
842
+ *
843
+ * When `opts.bundleId` is provided, `name` is treated as a relative path inside
844
+ * that app's container; otherwise it addresses the sandbox staging folder.
845
+ *
846
+ * @param name The name of the file, or a relative path inside the app container when `opts.bundleId` is set.
847
+ * @param opts Optional app container targeting (see `pushFile`).
848
+ */
849
+ deleteFile: (name: string, opts?: ContainerTargetOptions) => Promise<void>;
803
850
 
804
851
  /**
805
852
  * Run `xcrun` command with the given arguments.
@@ -1821,7 +1868,9 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
1821
1868
  xcrun,
1822
1869
  startXcrunShim,
1823
1870
  xcodebuild,
1824
- cp,
1871
+ pushFile,
1872
+ pullFile,
1873
+ deleteFile,
1825
1874
  lsof,
1826
1875
  deviceInfo: cachedDeviceInfo,
1827
1876
  });
@@ -2245,9 +2294,24 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
2245
2294
  return execution;
2246
2295
  };
2247
2296
 
2248
- const cp = async (name: string, filePath: string): Promise<string> => {
2297
+ const buildFilesUrl = (name: string, opts?: ContainerTargetOptions): string => {
2298
+ const params = new URLSearchParams({ name });
2299
+ if (opts?.bundleId) {
2300
+ params.set('bundleId', opts.bundleId);
2301
+ if (opts.containerType) {
2302
+ params.set('containerType', opts.containerType);
2303
+ }
2304
+ }
2305
+ return `${options.apiUrl}/files?${params.toString()}`;
2306
+ };
2307
+
2308
+ const pushFile = async (
2309
+ filePath: string,
2310
+ destination: string,
2311
+ opts?: ContainerTargetOptions,
2312
+ ): Promise<string> => {
2249
2313
  const fileStream = fs.createReadStream(filePath);
2250
- const uploadUrl = `${options.apiUrl}/files?name=${encodeURIComponent(name)}`;
2314
+ const uploadUrl = buildFilesUrl(destination, opts);
2251
2315
  try {
2252
2316
  // Node's fetch (undici) supports streaming request bodies but TS DOM types may not include
2253
2317
  // `duplex` and may not accept Node ReadStreams as BodyInit in some configs.
@@ -2274,6 +2338,33 @@ export async function createInstanceClient(options: InstanceClientOptions): Prom
2274
2338
  }
2275
2339
  };
2276
2340
 
2341
+ const pullFile = async (name: string, opts?: ContainerTargetOptions): Promise<Buffer> => {
2342
+ const response = await nodeProxyTransport.fetch(buildFilesUrl(name, opts), {
2343
+ method: 'GET',
2344
+ headers: {
2345
+ Authorization: `Bearer ${options.token}`,
2346
+ },
2347
+ });
2348
+ if (!response.ok) {
2349
+ const errorBody = await response.text();
2350
+ throw new Error(`Download of '${name}' failed: ${response.status} ${errorBody}`);
2351
+ }
2352
+ return Buffer.from(await response.arrayBuffer());
2353
+ };
2354
+
2355
+ const deleteFile = async (name: string, opts?: ContainerTargetOptions): Promise<void> => {
2356
+ const response = await nodeProxyTransport.fetch(buildFilesUrl(name, opts), {
2357
+ method: 'DELETE',
2358
+ headers: {
2359
+ Authorization: `Bearer ${options.token}`,
2360
+ },
2361
+ });
2362
+ if (!response.ok) {
2363
+ const errorBody = await response.text();
2364
+ throw new Error(`Deletion of '${name}' failed: ${response.status} ${errorBody}`);
2365
+ }
2366
+ };
2367
+
2277
2368
  const setStoreKitConfig = async (bundleId: string, storekit: Buffer | Uint8Array): Promise<void> => {
2278
2369
  const body = Buffer.isBuffer(storekit) ? storekit : Buffer.from(storekit);
2279
2370
  const url = `${options.apiUrl}/payments/storeKitConfigs/${encodeURIComponent(bundleId)}`;
@@ -0,0 +1,71 @@
1
+ // Helpers and platform-neutral types shared by the per-instance build-daemon
2
+ // clients (xcode, gradle).
3
+
4
+ import os from 'os';
5
+ import path from 'path';
6
+ import crypto from 'crypto';
7
+
8
+ export type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
9
+
10
+ /**
11
+ * Derives the client-side folder-sync cache location for a local project.
12
+ * The key format is a compatibility contract: changing it orphans every
13
+ * user's existing basis cache, so both daemon clients must share this one
14
+ * derivation.
15
+ */
16
+ export function deriveBasisCache(
17
+ localCodePath: string,
18
+ override?: string,
19
+ ): { cacheKey: string; basisCacheDir: string } {
20
+ const resolvedPath = path.resolve(localCodePath);
21
+ const folderName = path.basename(resolvedPath);
22
+ const hash = crypto.createHash('sha1').update(resolvedPath).digest('hex').slice(0, 8);
23
+ const cacheKey = `limsync-cache-${folderName}-${hash}`;
24
+ return { cacheKey, basisCacheDir: override ?? path.join(os.tmpdir(), cacheKey) };
25
+ }
26
+
27
+ export type SyncResult = {
28
+ /**
29
+ * Number of bytes transmitted to the server for this sync (full uploads plus
30
+ * delta patches, before transport compression). In watch mode, this reflects
31
+ * the initial sync only.
32
+ */
33
+ bytesSent?: number;
34
+ /** Present only when watch=true; call to stop watching */
35
+ stopWatching?: () => Promise<void>;
36
+ };
37
+
38
+ export type AssetUploadUrls = { signedUploadUrl: string; signedDownloadUrl: string };
39
+
40
+ /**
41
+ * Mints presigned upload/download URLs for a named asset via assets.getOrCreate,
42
+ * wrapping failures with the asset name (and the original error as cause).
43
+ */
44
+ export function mintAssetUploadUrls(
45
+ assets: { getOrCreate: (body: { name: string; ttl?: string }) => Promise<AssetUploadUrls> },
46
+ name: string,
47
+ ttl?: string,
48
+ ): Promise<AssetUploadUrls> {
49
+ return assets.getOrCreate({ name, ...(ttl && { ttl }) }).catch((err) => {
50
+ const message = `Failed to create upload URL for asset '${name}': ${
51
+ err instanceof Error ? err.message : err
52
+ }`;
53
+ // @ts-ignore - not all envs have native support for cause yet
54
+ throw new Error(message, { cause: err });
55
+ });
56
+ }
57
+
58
+ const logLevels: LogLevel[] = ['none', 'error', 'warn', 'info', 'debug'];
59
+
60
+ export function createDaemonLogger(prefix: string, logLevel: LogLevel) {
61
+ const threshold = logLevels.indexOf(logLevel);
62
+ const shouldLog = (level: LogLevel) => threshold >= logLevels.indexOf(level);
63
+ return (level: 'debug' | 'info' | 'warn' | 'error', msg: string) => {
64
+ if (!shouldLog(level)) return;
65
+ if (level === 'error' || level === 'warn') {
66
+ console[level](prefix, msg);
67
+ } else {
68
+ console.log(prefix, msg);
69
+ }
70
+ };
71
+ }
@@ -0,0 +1,155 @@
1
+ import { GradleInstances as GeneratedGradleInstances, type GradleInstance } from './gradle-instances';
2
+ import {
3
+ exec,
4
+ type ExecChildProcess,
5
+ type GradleBuildExecRequest,
6
+ type GradleReactNativeConfig,
7
+ } from '../exec-client';
8
+ import { syncFolder as syncFolderImpl, type FolderSyncOptions } from '../folder-sync';
9
+ import { createIgnoreFn } from '../folder-sync-ignore';
10
+ import {
11
+ createDaemonLogger,
12
+ deriveBasisCache,
13
+ mintAssetUploadUrls,
14
+ type LogLevel,
15
+ type SyncResult,
16
+ } from './daemon-client-shared';
17
+
18
+ export type GradleCreateClientParams = { logLevel?: LogLevel } & (
19
+ | { instance: GradleInstance }
20
+ | { apiUrl: string; token: string }
21
+ );
22
+
23
+ export type GradleSyncOptions = {
24
+ /**
25
+ * Directory for the client-side folder-sync cache.
26
+ * Defaults to a temporary directory under the OS temp directory.
27
+ */
28
+ basisCacheDir?: string;
29
+ /**
30
+ * Optional predicate for ignoring files and directories during sync.
31
+ * Called with the relative path from the sync root (using forward slashes).
32
+ * For directories, the path ends with '/'.
33
+ * Return true to ignore, false to keep.
34
+ */
35
+ ignore?: (relativePath: string) => boolean;
36
+ /**
37
+ * Optional predicate for force-including paths that would otherwise be
38
+ * dropped. Same calling convention as `ignore`; return true to force-sync.
39
+ */
40
+ include?: (relativePath: string) => boolean;
41
+ };
42
+
43
+ export type GradleBuildOptions = {
44
+ /** Gradle tasks to run. Omit for the server default (assembleDebug). */
45
+ tasks?: string[];
46
+ /** Relative path to the Gradle root when auto-discovery is ambiguous. */
47
+ projectPath?: string;
48
+ /** Upload the built APK as a named org asset, or to a presigned URL. */
49
+ upload?: { assetName: string; signedUploadUrl?: never } | { signedUploadUrl: string; assetName?: never };
50
+ /** React Native / Expo tuning. */
51
+ reactNative?: GradleReactNativeConfig;
52
+ };
53
+
54
+ export type GradleClient = {
55
+ sync(localCodePath: string, opts?: GradleSyncOptions): Promise<SyncResult>;
56
+ gradlebuild(options?: GradleBuildOptions): ExecChildProcess;
57
+ };
58
+
59
+ // Machine-local or regenerable files that must never reach the build
60
+ // sandbox: local.properties points at the developer's own SDK and would
61
+ // shadow the image's. Only ROOT-level cache/output dirs are defaulted;
62
+ // nested module build/ dirs are the project .gitignore's job (dropping any
63
+ // 'build' segment would silently exclude legitimate packages named build).
64
+ function gradleDefaultIgnore(relativePath: string): boolean {
65
+ const trimmed = relativePath.endsWith('/') ? relativePath.slice(0, -1) : relativePath;
66
+ const segments = trimmed.split('/');
67
+ if (segments[segments.length - 1] === 'local.properties') {
68
+ return true;
69
+ }
70
+ return segments.length === 1 && (trimmed === '.gradle' || trimmed === '.kotlin' || trimmed === 'build');
71
+ }
72
+
73
+ export class GradleInstances extends GeneratedGradleInstances {
74
+ async createClient(params: GradleCreateClientParams): Promise<GradleClient> {
75
+ let apiUrl: string;
76
+ let token: string;
77
+ if ('instance' in params) {
78
+ if (!params.instance.status.apiUrl) {
79
+ throw new Error('Instance not ready: apiUrl is not available');
80
+ }
81
+ apiUrl = params.instance.status.apiUrl;
82
+ token = params.instance.status.token;
83
+ } else {
84
+ apiUrl = params.apiUrl;
85
+ token = params.token;
86
+ }
87
+
88
+ const log = createDaemonLogger('[GradleInstance]', params.logLevel ?? 'info');
89
+ const client = this._client;
90
+
91
+ return {
92
+ async sync(localCodePath: string, opts?: GradleSyncOptions): Promise<SyncResult> {
93
+ const { cacheKey, basisCacheDir } = deriveBasisCache(localCodePath, opts?.basisCacheDir);
94
+ const userIgnore = opts?.ignore;
95
+ const codeSyncOpts: FolderSyncOptions = {
96
+ apiUrl,
97
+ token,
98
+ udid: cacheKey,
99
+ install: false,
100
+ ignoreFn: await createIgnoreFn(localCodePath, {
101
+ basisCacheDir,
102
+ log,
103
+ xcodeDefaults: false,
104
+ // Honor nested module .gitignore files (app/.gitignore's /build,
105
+ // etc.); gradleDefaultIgnore only covers root-level build/.gradle/
106
+ // .kotlin, so without this a locally-built project would sync its
107
+ // nested build/ artifact trees.
108
+ nestedGitignore: true,
109
+ additional: userIgnore ? (p) => gradleDefaultIgnore(p) || userIgnore(p) : gradleDefaultIgnore,
110
+ ...(opts?.include ? { include: opts.include } : {}),
111
+ }),
112
+ basisCacheDir,
113
+ // Gradle builds are one-shot; no dev-loop watch like xcode.
114
+ watch: false,
115
+ launchMode: 'ForegroundIfRunning',
116
+ log,
117
+ syncSymlinks: true,
118
+ };
119
+
120
+ const result = await syncFolderImpl(localCodePath, codeSyncOpts);
121
+ const out: SyncResult = {};
122
+ if (result.bytesSent !== undefined) {
123
+ out.bytesSent = result.bytesSent;
124
+ }
125
+ return out;
126
+ },
127
+
128
+ gradlebuild(options?: GradleBuildOptions): ExecChildProcess {
129
+ const request: GradleBuildExecRequest = {
130
+ command: 'gradlebuild',
131
+ ...(options?.tasks?.length && { tasks: options.tasks }),
132
+ ...(options?.projectPath && { projectPath: options.projectPath }),
133
+ ...(options?.reactNative && { reactNative: options.reactNative }),
134
+ };
135
+
136
+ if (options?.upload && 'assetName' in options.upload) {
137
+ const requestPromise = mintAssetUploadUrls(client.assets, options.upload.assetName).then(
138
+ (asset) => {
139
+ request.signedUploadUrl = asset.signedUploadUrl;
140
+ request.additionalMetadata = { signedDownloadUrl: asset.signedDownloadUrl };
141
+ return request;
142
+ },
143
+ );
144
+ return exec(requestPromise, { apiUrl, token, log });
145
+ }
146
+
147
+ if (options?.upload && 'signedUploadUrl' in options.upload) {
148
+ request.signedUploadUrl = options.upload.signedUploadUrl;
149
+ }
150
+
151
+ return exec(request, { apiUrl, token, log });
152
+ },
153
+ };
154
+ }
155
+ }
@@ -0,0 +1,206 @@
1
+ // Hand-written following the Stainless resource pattern; a future generation
2
+ // from the OpenAPI spec reconciles with this file.
3
+
4
+ import { APIResource } from '../core/resource';
5
+ import { APIPromise } from '../core/api-promise';
6
+ import { Items, type ItemsParams, PagePromise } from '../core/pagination';
7
+ import { buildHeaders } from '../internal/headers';
8
+ import { RequestOptions } from '../internal/request-options';
9
+ import { path } from '../internal/utils/path';
10
+
11
+ export class GradleInstances extends APIResource {
12
+ /**
13
+ * Create a gradle instance
14
+ */
15
+ create(params: GradleInstanceCreateParams, options?: RequestOptions): APIPromise<GradleInstance> {
16
+ const { reuseIfExists, wait, ...body } = params;
17
+ return this._client.post('/v1/gradle_instances', { query: { reuseIfExists, wait }, body, ...options });
18
+ }
19
+
20
+ /**
21
+ * List gradle instances
22
+ */
23
+ list(
24
+ query: GradleInstanceListParams | null | undefined = {},
25
+ options?: RequestOptions,
26
+ ): PagePromise<GradleInstancesItems, GradleInstance> {
27
+ return this._client.getAPIList('/v1/gradle_instances', Items<GradleInstance>, { query, ...options });
28
+ }
29
+
30
+ /**
31
+ * Delete gradle instance with given name
32
+ */
33
+ delete(id: string, options?: RequestOptions): APIPromise<void> {
34
+ return this._client.delete(path`/v1/gradle_instances/${id}`, {
35
+ ...options,
36
+ headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
37
+ });
38
+ }
39
+
40
+ /**
41
+ * Get gradle instance with given ID
42
+ */
43
+ get(id: string, options?: RequestOptions): APIPromise<GradleInstance> {
44
+ return this._client.get(path`/v1/gradle_instances/${id}`, options);
45
+ }
46
+ }
47
+
48
+ export type GradleInstancesItems = Items<GradleInstance>;
49
+
50
+ export interface GradleInstance {
51
+ metadata: GradleInstance.Metadata;
52
+
53
+ spec: GradleInstance.Spec;
54
+
55
+ status: GradleInstance.Status;
56
+ }
57
+
58
+ export namespace GradleInstance {
59
+ export interface Metadata {
60
+ id: string;
61
+
62
+ createdAt: string;
63
+
64
+ organizationId: string;
65
+
66
+ displayName?: string;
67
+
68
+ labels?: { [key: string]: string };
69
+
70
+ terminatedAt?: string;
71
+ }
72
+
73
+ export interface Spec {
74
+ inactivityTimeout: string;
75
+
76
+ region: string;
77
+
78
+ hardTimeout?: string;
79
+ }
80
+
81
+ export interface Status {
82
+ token: string;
83
+
84
+ state: 'unknown' | 'creating' | 'assigned' | 'ready' | 'terminated';
85
+
86
+ apiUrl?: string;
87
+
88
+ errorMessage?: string;
89
+
90
+ /**
91
+ * Machine-readable reason the instance was terminated. Always present once state
92
+ * is "terminated", never present before that. New values may be added over time,
93
+ * so treat any unrecognized value as "Unknown". Known values:
94
+ *
95
+ * - "UserRequested": terminated by a delete request to the API.
96
+ * - "InactivityTimeout": the timeout given in spec.inactivityTimeout elapsed.
97
+ * - "HardTimeout": the timeout given in spec.hardTimeout elapsed.
98
+ * - "Unknown": terminated for a cause the platform did not attribute, including
99
+ * instances that failed to get ready during creation. See errorMessage for
100
+ * details when available.
101
+ */
102
+ terminationReason?: string;
103
+ }
104
+ }
105
+
106
+ export interface GradleInstanceCreateParams {
107
+ /**
108
+ * Query param: If there is another instance with given labels and region, return
109
+ * that one instead of creating a new instance.
110
+ */
111
+ reuseIfExists?: boolean;
112
+
113
+ /**
114
+ * Query param: Return after the instance is ready to connect.
115
+ */
116
+ wait?: boolean;
117
+
118
+ /**
119
+ * Body param
120
+ */
121
+ metadata?: GradleInstanceCreateParams.Metadata;
122
+
123
+ /**
124
+ * Body param
125
+ */
126
+ spec?: GradleInstanceCreateParams.Spec;
127
+ }
128
+
129
+ export namespace GradleInstanceCreateParams {
130
+ export interface Metadata {
131
+ displayName?: string;
132
+
133
+ labels?: { [key: string]: string };
134
+ }
135
+
136
+ export interface Spec {
137
+ clues?: Array<Spec.Clue>;
138
+
139
+ /**
140
+ * After how many minutes should the instance be terminated. Example values 1m,
141
+ * 10m, 3h. Default is "0" which means no hard timeout.
142
+ */
143
+ hardTimeout?: string;
144
+
145
+ /**
146
+ * After how many minutes of inactivity should the instance be terminated. Example
147
+ * values 1m, 10m, 3h. Default is 5m.
148
+ */
149
+ inactivityTimeout?: string;
150
+
151
+ /**
152
+ * Where the instance will be created. If not given, the region is decided based on
153
+ * scheduling clues (client IP) and availability.
154
+ *
155
+ * A region is a preference, not a hard pin: the request always overflows to every
156
+ * other available region, ordered by proximity, when the preferred ones are full.
157
+ *
158
+ * Accepted values:
159
+ *
160
+ * - A specific region name (e.g. "us-west1"). It is tried first, then the
161
+ * remaining regions in order of proximity to it. Scheduling clues (client IP)
162
+ * are ignored when a region is given.
163
+ * - A region group name (e.g. "us", "eu"). Its member regions are tried first in
164
+ * their listed order, then the remaining regions by proximity to the first
165
+ * member.
166
+ * - A pipe-separated, ordered list of regions (e.g. "us-east1|us-west1"). Those
167
+ * are tried first in the given order, then the remaining regions by proximity to
168
+ * the first.
169
+ */
170
+ region?: string;
171
+ }
172
+
173
+ export namespace Spec {
174
+ export interface Clue {
175
+ kind: 'ClientIP';
176
+
177
+ clientIp?: string;
178
+ }
179
+ }
180
+ }
181
+
182
+ export interface GradleInstanceListParams extends ItemsParams {
183
+ /**
184
+ * Labels filter to apply to instances to return. Expects a comma-separated list of
185
+ * key=value pairs (e.g., env=prod,region=us-west).
186
+ */
187
+ labelSelector?: string;
188
+
189
+ /**
190
+ * State filter to apply to gradle instances to return. Each comma-separated state
191
+ * will be used as part of an OR clause, e.g. "assigned,ready" will return all
192
+ * instances that are either assigned or ready.
193
+ *
194
+ * Valid states: creating, assigned, ready, terminated, unknown
195
+ */
196
+ state?: string;
197
+ }
198
+
199
+ export declare namespace GradleInstances {
200
+ export {
201
+ type GradleInstance as GradleInstance,
202
+ type GradleInstancesItems as GradleInstancesItems,
203
+ type GradleInstanceCreateParams as GradleInstanceCreateParams,
204
+ type GradleInstanceListParams as GradleInstanceListParams,
205
+ };
206
+ }
@@ -37,6 +37,12 @@ export {
37
37
  type XcodeInstanceListParams,
38
38
  type XcodeInstancesItems,
39
39
  } from './xcode-instances';
40
+ export {
41
+ type GradleInstance,
42
+ type GradleInstanceCreateParams,
43
+ type GradleInstanceListParams,
44
+ type GradleInstancesItems,
45
+ } from './gradle-instances';
40
46
 
41
47
  export { Assets, AssetGetOrUploadParams, AssetGetOrUploadResponse } from './assets-helpers';
42
48
  export {
@@ -57,3 +63,10 @@ export {
57
63
  type SimulatorInstallState,
58
64
  type RbeInstallResult,
59
65
  } from './xcode-instances-helpers';
66
+ export {
67
+ GradleInstances,
68
+ type GradleCreateClientParams,
69
+ type GradleClient,
70
+ type GradleSyncOptions,
71
+ type GradleBuildOptions,
72
+ } from './gradle-instances-helpers';