@databricks/sdk-jobs 0.0.0-dev → 0.1.0-dev.1

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.
@@ -0,0 +1,1287 @@
1
+ // Code generated from API definition by Databricks SDK Generator. DO NOT EDIT.
2
+
3
+ import {VERSION as AUTH_VERSION} from '@databricks/sdk-auth';
4
+ import type {Call} from '@databricks/sdk-core/api';
5
+ import {retryOn} from '@databricks/sdk-core/api';
6
+ import {createDefault} from '@databricks/sdk-core/clientinfo';
7
+ import type {Logger} from '@databricks/sdk-core/logger';
8
+ import {NoOpLogger} from '@databricks/sdk-core/logger';
9
+ import type {CallOptions} from '@databricks/sdk-options/call';
10
+ import type {ClientOptions} from '@databricks/sdk-options/client';
11
+ import type {HttpClient} from '@databricks/sdk-core/http';
12
+ import {newHttpClient} from './transport';
13
+ import {
14
+ buildHttpRequest,
15
+ executeCall,
16
+ executeHttpCall,
17
+ marshalRequest,
18
+ parseResponse,
19
+ } from './utils';
20
+ import pkgJson from '../../package.json' with {type: 'json'};
21
+ import type {
22
+ BaseJob,
23
+ BaseRun,
24
+ CancelAllRunsRequest,
25
+ CancelAllRunsRequest_Response,
26
+ CancelRunRequest,
27
+ CancelRunRequest_Response,
28
+ CreateJobRequest,
29
+ CreateJobRequest_Response,
30
+ DeleteJobRequest,
31
+ DeleteJobRequest_Response,
32
+ DeleteRunRequest,
33
+ DeleteRunRequest_Response,
34
+ EnforcePolicyComplianceForJob,
35
+ EnforcePolicyComplianceForJob_Response,
36
+ ExportRunRequest,
37
+ ExportRunRequest_Response,
38
+ GetJobRequest,
39
+ GetJobRequest_Response,
40
+ GetPolicyComplianceForJob,
41
+ GetPolicyComplianceForJob_Response,
42
+ GetRunOutputRequest,
43
+ GetRunOutputRequest_Response,
44
+ GetRunRequest,
45
+ GetRunRequest_Response,
46
+ ListJobComplianceForPolicy,
47
+ ListJobComplianceForPolicy_JobCompliance,
48
+ ListJobComplianceForPolicy_Response,
49
+ ListJobsRequest,
50
+ ListJobsRequest_Response,
51
+ ListRunsRequest,
52
+ ListRunsRequest_Response,
53
+ RepairRunRequest,
54
+ RepairRunRequest_Response,
55
+ ResetJobRequest,
56
+ ResetJobRequest_Response,
57
+ RunNowRequest,
58
+ RunNowRequest_Response,
59
+ SubmitRunRequest,
60
+ SubmitRunRequest_Response,
61
+ UpdateJobRequest,
62
+ UpdateJobRequest_Response,
63
+ } from './model';
64
+ import {
65
+ RunLifeCycleState_RunLifeCycleState,
66
+ marshalCancelAllRunsRequestSchema,
67
+ marshalCancelRunRequestSchema,
68
+ marshalCreateJobRequestSchema,
69
+ marshalDeleteJobRequestSchema,
70
+ marshalDeleteRunRequestSchema,
71
+ marshalEnforcePolicyComplianceForJobSchema,
72
+ marshalRepairRunRequestSchema,
73
+ marshalResetJobRequestSchema,
74
+ marshalRunNowRequestSchema,
75
+ marshalSubmitRunRequestSchema,
76
+ marshalUpdateJobRequestSchema,
77
+ unmarshalCancelAllRunsRequest_ResponseSchema,
78
+ unmarshalCancelRunRequest_ResponseSchema,
79
+ unmarshalCreateJobRequest_ResponseSchema,
80
+ unmarshalDeleteJobRequest_ResponseSchema,
81
+ unmarshalDeleteRunRequest_ResponseSchema,
82
+ unmarshalEnforcePolicyComplianceForJob_ResponseSchema,
83
+ unmarshalExportRunRequest_ResponseSchema,
84
+ unmarshalGetJobRequest_ResponseSchema,
85
+ unmarshalGetPolicyComplianceForJob_ResponseSchema,
86
+ unmarshalGetRunOutputRequest_ResponseSchema,
87
+ unmarshalGetRunRequest_ResponseSchema,
88
+ unmarshalListJobComplianceForPolicy_ResponseSchema,
89
+ unmarshalListJobsRequest_ResponseSchema,
90
+ unmarshalListRunsRequest_ResponseSchema,
91
+ unmarshalRepairRunRequest_ResponseSchema,
92
+ unmarshalResetJobRequest_ResponseSchema,
93
+ unmarshalRunNowRequest_ResponseSchema,
94
+ unmarshalSubmitRunRequest_ResponseSchema,
95
+ unmarshalUpdateJobRequest_ResponseSchema,
96
+ } from './model';
97
+
98
+ // Package identity segment for this client to be used in the User-Agent header.
99
+ const PACKAGE_SEGMENT = {
100
+ key: 'sdk-js-' + pkgJson.name.replace(/^@[^/]+\/sdk-/, ''),
101
+ value: pkgJson.version,
102
+ };
103
+
104
+ class StillRunningError extends Error {}
105
+
106
+ export class JobsClient {
107
+ private readonly host: string;
108
+ // Workspace ID used to route workspace-level calls on unified hosts (SPOG).
109
+ // When set, workspace-level methods send X-Databricks-Org-Id on every
110
+ // request.
111
+ private readonly workspaceId: string | undefined;
112
+ private readonly httpClient: HttpClient;
113
+ private readonly logger: Logger;
114
+ // User-Agent header value. Composed once at construction from
115
+ // createDefault() merged with this package's identity and the active
116
+ // credential's name.
117
+ private readonly userAgent: string;
118
+
119
+ constructor(options: ClientOptions) {
120
+ if (options.host === undefined) {
121
+ throw new Error('Host is required.');
122
+ }
123
+ this.host = options.host.replace(/\/$/, '');
124
+ this.workspaceId = options.workspaceId;
125
+ this.logger = options.logger ?? new NoOpLogger();
126
+ const info = createDefault()
127
+ .with(PACKAGE_SEGMENT)
128
+ .with({key: 'sdk-js-auth', value: AUTH_VERSION})
129
+ .with({key: 'auth', value: options.credentials?.name() ?? 'default'});
130
+ this.userAgent = info.toString();
131
+ this.httpClient = newHttpClient(options);
132
+ }
133
+
134
+ /**
135
+ * Updates a job so the job clusters that are created when running
136
+ * the job (specified in `new_cluster`) are compliant with the
137
+ * current versions of their respective cluster policies.
138
+ * All-purpose clusters used in the job will not be updated.
139
+ */
140
+ async enforcePolicyComplianceForJob(
141
+ req: EnforcePolicyComplianceForJob,
142
+ options?: CallOptions
143
+ ): Promise<EnforcePolicyComplianceForJob_Response> {
144
+ const url = `${this.host}/api/2.0/policies/jobs/enforce-compliance`;
145
+ const body = marshalRequest(
146
+ req,
147
+ marshalEnforcePolicyComplianceForJobSchema
148
+ );
149
+ let resp: EnforcePolicyComplianceForJob_Response | undefined;
150
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
151
+ const headers = new Headers({'Content-Type': 'application/json'});
152
+ if (this.workspaceId !== undefined) {
153
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
154
+ }
155
+ headers.set('User-Agent', this.userAgent);
156
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
157
+ const respBody = await executeHttpCall({
158
+ request: httpReq,
159
+ httpClient: this.httpClient,
160
+ logger: this.logger,
161
+ });
162
+ resp = parseResponse(
163
+ respBody,
164
+ unmarshalEnforcePolicyComplianceForJob_ResponseSchema
165
+ );
166
+ };
167
+ await executeCall(call, options);
168
+ if (resp === undefined) {
169
+ throw new Error('API call completed without a result.');
170
+ }
171
+ return resp;
172
+ }
173
+
174
+ /**
175
+ * Returns the policy compliance status of a job. Jobs could be out of
176
+ * compliance if a cluster policy they use was updated after the job was
177
+ * last edited and some of its job clusters no longer comply with
178
+ * their updated policies.
179
+ */
180
+ async getPolicyComplianceForJob(
181
+ req: GetPolicyComplianceForJob,
182
+ options?: CallOptions
183
+ ): Promise<GetPolicyComplianceForJob_Response> {
184
+ const url = `${this.host}/api/2.0/policies/jobs/get-compliance`;
185
+ const params = new URLSearchParams();
186
+ if (req.jobId !== undefined) {
187
+ params.append('job_id', String(req.jobId));
188
+ }
189
+ const query = params.toString();
190
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
191
+ let resp: GetPolicyComplianceForJob_Response | undefined;
192
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
193
+ const headers = new Headers();
194
+ if (this.workspaceId !== undefined) {
195
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
196
+ }
197
+ headers.set('User-Agent', this.userAgent);
198
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
199
+ const respBody = await executeHttpCall({
200
+ request: httpReq,
201
+ httpClient: this.httpClient,
202
+ logger: this.logger,
203
+ });
204
+ resp = parseResponse(
205
+ respBody,
206
+ unmarshalGetPolicyComplianceForJob_ResponseSchema
207
+ );
208
+ };
209
+ await executeCall(call, options);
210
+ if (resp === undefined) {
211
+ throw new Error('API call completed without a result.');
212
+ }
213
+ return resp;
214
+ }
215
+
216
+ /**
217
+ * Returns the policy compliance status of all jobs that use a
218
+ * given policy. Jobs could be out of compliance if a cluster policy they
219
+ * use was updated after the job was last edited and its job
220
+ * clusters no longer comply with the updated policy.
221
+ */
222
+ async listJobComplianceForPolicy(
223
+ req: ListJobComplianceForPolicy,
224
+ options?: CallOptions
225
+ ): Promise<ListJobComplianceForPolicy_Response> {
226
+ const url = `${this.host}/api/2.0/policies/jobs/list-compliance`;
227
+ const params = new URLSearchParams();
228
+ if (req.policyId !== undefined) {
229
+ params.append('policy_id', req.policyId);
230
+ }
231
+ if (req.pageToken !== undefined) {
232
+ params.append('page_token', req.pageToken);
233
+ }
234
+ if (req.pageSize !== undefined) {
235
+ params.append('page_size', String(req.pageSize));
236
+ }
237
+ const query = params.toString();
238
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
239
+ let resp: ListJobComplianceForPolicy_Response | undefined;
240
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
241
+ const headers = new Headers();
242
+ if (this.workspaceId !== undefined) {
243
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
244
+ }
245
+ headers.set('User-Agent', this.userAgent);
246
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
247
+ const respBody = await executeHttpCall({
248
+ request: httpReq,
249
+ httpClient: this.httpClient,
250
+ logger: this.logger,
251
+ });
252
+ resp = parseResponse(
253
+ respBody,
254
+ unmarshalListJobComplianceForPolicy_ResponseSchema
255
+ );
256
+ };
257
+ await executeCall(call, options);
258
+ if (resp === undefined) {
259
+ throw new Error('API call completed without a result.');
260
+ }
261
+ return resp;
262
+ }
263
+
264
+ async *listJobComplianceForPolicyIter(
265
+ req: ListJobComplianceForPolicy,
266
+ options?: CallOptions
267
+ ): AsyncGenerator<ListJobComplianceForPolicy_JobCompliance> {
268
+ const pageReq: ListJobComplianceForPolicy = {...req};
269
+ for (;;) {
270
+ const resp = await this.listJobComplianceForPolicy(pageReq, options);
271
+ for (const item of resp.jobs ?? []) {
272
+ yield item;
273
+ }
274
+ if (resp.nextPageToken === undefined || resp.nextPageToken === '') {
275
+ return;
276
+ }
277
+ pageReq.pageToken = resp.nextPageToken;
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Cancels all active runs of a job. The runs are canceled asynchronously, so it doesn't
283
+ * prevent new runs from being started.
284
+ */
285
+ async cancelAllRuns(
286
+ req: CancelAllRunsRequest,
287
+ options?: CallOptions
288
+ ): Promise<CancelAllRunsRequest_Response> {
289
+ const url = `${this.host}/api/2.2/jobs/runs/cancel-all`;
290
+ const body = marshalRequest(req, marshalCancelAllRunsRequestSchema);
291
+ let resp: CancelAllRunsRequest_Response | undefined;
292
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
293
+ const headers = new Headers({'Content-Type': 'application/json'});
294
+ if (this.workspaceId !== undefined) {
295
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
296
+ }
297
+ headers.set('User-Agent', this.userAgent);
298
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
299
+ const respBody = await executeHttpCall({
300
+ request: httpReq,
301
+ httpClient: this.httpClient,
302
+ logger: this.logger,
303
+ });
304
+ resp = parseResponse(
305
+ respBody,
306
+ unmarshalCancelAllRunsRequest_ResponseSchema
307
+ );
308
+ };
309
+ await executeCall(call, options);
310
+ if (resp === undefined) {
311
+ throw new Error('API call completed without a result.');
312
+ }
313
+ return resp;
314
+ }
315
+
316
+ /**
317
+ * Cancels a job run or a task run. The run is canceled asynchronously, so it may still be running when
318
+ * this request completes.
319
+ */
320
+ async cancelRun(
321
+ req: CancelRunRequest,
322
+ options?: CallOptions
323
+ ): Promise<CancelRunRequest_Response> {
324
+ const url = `${this.host}/api/2.2/jobs/runs/cancel`;
325
+ const body = marshalRequest(req, marshalCancelRunRequestSchema);
326
+ let resp: CancelRunRequest_Response | undefined;
327
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
328
+ const headers = new Headers({'Content-Type': 'application/json'});
329
+ if (this.workspaceId !== undefined) {
330
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
331
+ }
332
+ headers.set('User-Agent', this.userAgent);
333
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
334
+ const respBody = await executeHttpCall({
335
+ request: httpReq,
336
+ httpClient: this.httpClient,
337
+ logger: this.logger,
338
+ });
339
+ resp = parseResponse(respBody, unmarshalCancelRunRequest_ResponseSchema);
340
+ };
341
+ await executeCall(call, options);
342
+ if (resp === undefined) {
343
+ throw new Error('API call completed without a result.');
344
+ }
345
+ return resp;
346
+ }
347
+
348
+ async cancelRunWaiter(
349
+ req: CancelRunRequest,
350
+ options?: CallOptions
351
+ ): Promise<CancelRunWaiter> {
352
+ await this.cancelRun(req, options);
353
+ if (req.runId === undefined) {
354
+ throw new Error('request field runId required for polling is missing');
355
+ }
356
+ return new CancelRunWaiter(this, req.runId);
357
+ }
358
+
359
+ /** Create a new job. */
360
+ async createJob(
361
+ req: CreateJobRequest,
362
+ options?: CallOptions
363
+ ): Promise<CreateJobRequest_Response> {
364
+ const url = `${this.host}/api/2.2/jobs/create`;
365
+ const body = marshalRequest(req, marshalCreateJobRequestSchema);
366
+ let resp: CreateJobRequest_Response | undefined;
367
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
368
+ const headers = new Headers({'Content-Type': 'application/json'});
369
+ if (this.workspaceId !== undefined) {
370
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
371
+ }
372
+ headers.set('User-Agent', this.userAgent);
373
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
374
+ const respBody = await executeHttpCall({
375
+ request: httpReq,
376
+ httpClient: this.httpClient,
377
+ logger: this.logger,
378
+ });
379
+ resp = parseResponse(respBody, unmarshalCreateJobRequest_ResponseSchema);
380
+ };
381
+ await executeCall(call, options);
382
+ if (resp === undefined) {
383
+ throw new Error('API call completed without a result.');
384
+ }
385
+ return resp;
386
+ }
387
+
388
+ /** Deletes a job. */
389
+ async deleteJob(
390
+ req: DeleteJobRequest,
391
+ options?: CallOptions
392
+ ): Promise<DeleteJobRequest_Response> {
393
+ const url = `${this.host}/api/2.2/jobs/delete`;
394
+ const body = marshalRequest(req, marshalDeleteJobRequestSchema);
395
+ let resp: DeleteJobRequest_Response | undefined;
396
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
397
+ const headers = new Headers({'Content-Type': 'application/json'});
398
+ if (this.workspaceId !== undefined) {
399
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
400
+ }
401
+ headers.set('User-Agent', this.userAgent);
402
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
403
+ const respBody = await executeHttpCall({
404
+ request: httpReq,
405
+ httpClient: this.httpClient,
406
+ logger: this.logger,
407
+ });
408
+ resp = parseResponse(respBody, unmarshalDeleteJobRequest_ResponseSchema);
409
+ };
410
+ await executeCall(call, options);
411
+ if (resp === undefined) {
412
+ throw new Error('API call completed without a result.');
413
+ }
414
+ return resp;
415
+ }
416
+
417
+ /** Deletes a non-active run. Returns an error if the run is active. */
418
+ async deleteRun(
419
+ req: DeleteRunRequest,
420
+ options?: CallOptions
421
+ ): Promise<DeleteRunRequest_Response> {
422
+ const url = `${this.host}/api/2.2/jobs/runs/delete`;
423
+ const body = marshalRequest(req, marshalDeleteRunRequestSchema);
424
+ let resp: DeleteRunRequest_Response | undefined;
425
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
426
+ const headers = new Headers({'Content-Type': 'application/json'});
427
+ if (this.workspaceId !== undefined) {
428
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
429
+ }
430
+ headers.set('User-Agent', this.userAgent);
431
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
432
+ const respBody = await executeHttpCall({
433
+ request: httpReq,
434
+ httpClient: this.httpClient,
435
+ logger: this.logger,
436
+ });
437
+ resp = parseResponse(respBody, unmarshalDeleteRunRequest_ResponseSchema);
438
+ };
439
+ await executeCall(call, options);
440
+ if (resp === undefined) {
441
+ throw new Error('API call completed without a result.');
442
+ }
443
+ return resp;
444
+ }
445
+
446
+ /** Export and retrieve the job run task. */
447
+ async exportRun(
448
+ req: ExportRunRequest,
449
+ options?: CallOptions
450
+ ): Promise<ExportRunRequest_Response> {
451
+ const url = `${this.host}/api/2.2/jobs/runs/export`;
452
+ const params = new URLSearchParams();
453
+ if (req.runId !== undefined) {
454
+ params.append('run_id', String(req.runId));
455
+ }
456
+ if (req.viewsToExport !== undefined) {
457
+ params.append('views_to_export', req.viewsToExport);
458
+ }
459
+ const query = params.toString();
460
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
461
+ let resp: ExportRunRequest_Response | undefined;
462
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
463
+ const headers = new Headers();
464
+ if (this.workspaceId !== undefined) {
465
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
466
+ }
467
+ headers.set('User-Agent', this.userAgent);
468
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
469
+ const respBody = await executeHttpCall({
470
+ request: httpReq,
471
+ httpClient: this.httpClient,
472
+ logger: this.logger,
473
+ });
474
+ resp = parseResponse(respBody, unmarshalExportRunRequest_ResponseSchema);
475
+ };
476
+ await executeCall(call, options);
477
+ if (resp === undefined) {
478
+ throw new Error('API call completed without a result.');
479
+ }
480
+ return resp;
481
+ }
482
+
483
+ /**
484
+ * Retrieves the details for a single job.
485
+ *
486
+ * Large arrays in the results will be paginated when they exceed 100 elements.
487
+ * A request for a single job will return all properties for that job, and the first 100 elements of array properties (`tasks`, `job_clusters`, `environments` and `parameters`).
488
+ * Use the `next_page_token` field to check for more results and pass its value as the `page_token` in subsequent requests.
489
+ * If any array properties have more than 100 elements, additional results will be returned on subsequent requests. Arrays without additional results will be empty on later pages.
490
+ */
491
+ async getJob(
492
+ req: GetJobRequest,
493
+ options?: CallOptions
494
+ ): Promise<GetJobRequest_Response> {
495
+ const url = `${this.host}/api/2.2/jobs/get`;
496
+ const params = new URLSearchParams();
497
+ if (req.jobId !== undefined) {
498
+ params.append('job_id', String(req.jobId));
499
+ }
500
+ if (req.includeTriggerState !== undefined) {
501
+ params.append('include_trigger_state', String(req.includeTriggerState));
502
+ }
503
+ if (req.pageToken !== undefined) {
504
+ params.append('page_token', req.pageToken);
505
+ }
506
+ const query = params.toString();
507
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
508
+ let resp: GetJobRequest_Response | undefined;
509
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
510
+ const headers = new Headers();
511
+ if (this.workspaceId !== undefined) {
512
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
513
+ }
514
+ headers.set('User-Agent', this.userAgent);
515
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
516
+ const respBody = await executeHttpCall({
517
+ request: httpReq,
518
+ httpClient: this.httpClient,
519
+ logger: this.logger,
520
+ });
521
+ resp = parseResponse(respBody, unmarshalGetJobRequest_ResponseSchema);
522
+ };
523
+ await executeCall(call, options);
524
+ if (resp === undefined) {
525
+ throw new Error('API call completed without a result.');
526
+ }
527
+ return resp;
528
+ }
529
+
530
+ /**
531
+ * Retrieves the metadata of a run.
532
+ *
533
+ * Large arrays in the results will be paginated when they exceed 100 elements.
534
+ * A request for a single run will return all properties for that run, and the first 100 elements of array properties (`tasks`, `job_clusters`, `job_parameters` and `repair_history`).
535
+ * Use the next_page_token field to check for more results and pass its value as the page_token in subsequent requests.
536
+ * If any array properties have more than 100 elements, additional results will be returned on subsequent requests. Arrays without additional results will be empty on later pages.
537
+ */
538
+ async getRun(
539
+ req: GetRunRequest,
540
+ options?: CallOptions
541
+ ): Promise<GetRunRequest_Response> {
542
+ const url = `${this.host}/api/2.2/jobs/runs/get`;
543
+ const params = new URLSearchParams();
544
+ if (req.runId !== undefined) {
545
+ params.append('run_id', String(req.runId));
546
+ }
547
+ if (req.includeHistory !== undefined) {
548
+ params.append('include_history', String(req.includeHistory));
549
+ }
550
+ if (req.includeResolvedValues !== undefined) {
551
+ params.append(
552
+ 'include_resolved_values',
553
+ String(req.includeResolvedValues)
554
+ );
555
+ }
556
+ if (req.pageToken !== undefined) {
557
+ params.append('page_token', req.pageToken);
558
+ }
559
+ const query = params.toString();
560
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
561
+ let resp: GetRunRequest_Response | undefined;
562
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
563
+ const headers = new Headers();
564
+ if (this.workspaceId !== undefined) {
565
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
566
+ }
567
+ headers.set('User-Agent', this.userAgent);
568
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
569
+ const respBody = await executeHttpCall({
570
+ request: httpReq,
571
+ httpClient: this.httpClient,
572
+ logger: this.logger,
573
+ });
574
+ resp = parseResponse(respBody, unmarshalGetRunRequest_ResponseSchema);
575
+ };
576
+ await executeCall(call, options);
577
+ if (resp === undefined) {
578
+ throw new Error('API call completed without a result.');
579
+ }
580
+ return resp;
581
+ }
582
+
583
+ /**
584
+ * Retrieve the output and metadata of a single task run. When a notebook task returns
585
+ * a value through the `dbutils.notebook.exit()` call, you can use this endpoint to retrieve
586
+ * that value. <Databricks> restricts this API to returning the first 5 MB of the output.
587
+ * To return a larger result, you can store job results in a cloud storage service.
588
+ *
589
+ * This endpoint validates that the __run_id__ parameter is valid and returns an HTTP status
590
+ * code 400 if the __run_id__ parameter is invalid. Runs are automatically removed after
591
+ * 60 days. If you to want to reference them beyond 60 days, you must save old run results
592
+ * before they expire.
593
+ */
594
+ async getRunOutput(
595
+ req: GetRunOutputRequest,
596
+ options?: CallOptions
597
+ ): Promise<GetRunOutputRequest_Response> {
598
+ const url = `${this.host}/api/2.2/jobs/runs/get-output`;
599
+ const params = new URLSearchParams();
600
+ if (req.runId !== undefined) {
601
+ params.append('run_id', String(req.runId));
602
+ }
603
+ const query = params.toString();
604
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
605
+ let resp: GetRunOutputRequest_Response | undefined;
606
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
607
+ const headers = new Headers();
608
+ if (this.workspaceId !== undefined) {
609
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
610
+ }
611
+ headers.set('User-Agent', this.userAgent);
612
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
613
+ const respBody = await executeHttpCall({
614
+ request: httpReq,
615
+ httpClient: this.httpClient,
616
+ logger: this.logger,
617
+ });
618
+ resp = parseResponse(
619
+ respBody,
620
+ unmarshalGetRunOutputRequest_ResponseSchema
621
+ );
622
+ };
623
+ await executeCall(call, options);
624
+ if (resp === undefined) {
625
+ throw new Error('API call completed without a result.');
626
+ }
627
+ return resp;
628
+ }
629
+
630
+ /** Retrieves a list of jobs. */
631
+ async listJobs(
632
+ req: ListJobsRequest,
633
+ options?: CallOptions
634
+ ): Promise<ListJobsRequest_Response> {
635
+ const url = `${this.host}/api/2.2/jobs/list`;
636
+ const params = new URLSearchParams();
637
+ if (req.offset !== undefined) {
638
+ params.append('offset', String(req.offset));
639
+ }
640
+ if (req.limit !== undefined) {
641
+ params.append('limit', String(req.limit));
642
+ }
643
+ if (req.expandTasks !== undefined) {
644
+ params.append('expand_tasks', String(req.expandTasks));
645
+ }
646
+ if (req.name !== undefined) {
647
+ params.append('name', req.name);
648
+ }
649
+ if (req.pageToken !== undefined) {
650
+ params.append('page_token', req.pageToken);
651
+ }
652
+ const query = params.toString();
653
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
654
+ let resp: ListJobsRequest_Response | undefined;
655
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
656
+ const headers = new Headers();
657
+ if (this.workspaceId !== undefined) {
658
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
659
+ }
660
+ headers.set('User-Agent', this.userAgent);
661
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
662
+ const respBody = await executeHttpCall({
663
+ request: httpReq,
664
+ httpClient: this.httpClient,
665
+ logger: this.logger,
666
+ });
667
+ resp = parseResponse(respBody, unmarshalListJobsRequest_ResponseSchema);
668
+ };
669
+ await executeCall(call, options);
670
+ if (resp === undefined) {
671
+ throw new Error('API call completed without a result.');
672
+ }
673
+ return resp;
674
+ }
675
+
676
+ async *listJobsIter(
677
+ req: ListJobsRequest,
678
+ options?: CallOptions
679
+ ): AsyncGenerator<BaseJob> {
680
+ const pageReq: ListJobsRequest = {...req};
681
+ for (;;) {
682
+ const resp = await this.listJobs(pageReq, options);
683
+ for (const item of resp.jobs ?? []) {
684
+ yield item;
685
+ }
686
+ if (resp.nextPageToken === undefined || resp.nextPageToken === '') {
687
+ return;
688
+ }
689
+ pageReq.pageToken = resp.nextPageToken;
690
+ }
691
+ }
692
+
693
+ /** List runs in descending order by start time. */
694
+ async listRuns(
695
+ req: ListRunsRequest,
696
+ options?: CallOptions
697
+ ): Promise<ListRunsRequest_Response> {
698
+ const url = `${this.host}/api/2.2/jobs/runs/list`;
699
+ const params = new URLSearchParams();
700
+ if (req.jobId !== undefined) {
701
+ params.append('job_id', String(req.jobId));
702
+ }
703
+ if (req.stateConstraint?.$case === 'activeOnly') {
704
+ params.append('active_only', String(req.stateConstraint.activeOnly));
705
+ }
706
+ if (req.stateConstraint?.$case === 'completedOnly') {
707
+ params.append(
708
+ 'completed_only',
709
+ String(req.stateConstraint.completedOnly)
710
+ );
711
+ }
712
+ if (req.offset !== undefined) {
713
+ params.append('offset', String(req.offset));
714
+ }
715
+ if (req.limit !== undefined) {
716
+ params.append('limit', String(req.limit));
717
+ }
718
+ if (req.runType !== undefined) {
719
+ params.append('run_type', req.runType);
720
+ }
721
+ if (req.expandTasks !== undefined) {
722
+ params.append('expand_tasks', String(req.expandTasks));
723
+ }
724
+ if (req.startTimeFrom !== undefined) {
725
+ params.append('start_time_from', String(req.startTimeFrom));
726
+ }
727
+ if (req.startTimeTo !== undefined) {
728
+ params.append('start_time_to', String(req.startTimeTo));
729
+ }
730
+ if (req.pageToken !== undefined) {
731
+ params.append('page_token', req.pageToken);
732
+ }
733
+ const query = params.toString();
734
+ const fullUrl = query !== '' ? `${url}?${query}` : url;
735
+ let resp: ListRunsRequest_Response | undefined;
736
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
737
+ const headers = new Headers();
738
+ if (this.workspaceId !== undefined) {
739
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
740
+ }
741
+ headers.set('User-Agent', this.userAgent);
742
+ const httpReq = buildHttpRequest('GET', fullUrl, headers, callSignal);
743
+ const respBody = await executeHttpCall({
744
+ request: httpReq,
745
+ httpClient: this.httpClient,
746
+ logger: this.logger,
747
+ });
748
+ resp = parseResponse(respBody, unmarshalListRunsRequest_ResponseSchema);
749
+ };
750
+ await executeCall(call, options);
751
+ if (resp === undefined) {
752
+ throw new Error('API call completed without a result.');
753
+ }
754
+ return resp;
755
+ }
756
+
757
+ async *listRunsIter(
758
+ req: ListRunsRequest,
759
+ options?: CallOptions
760
+ ): AsyncGenerator<BaseRun> {
761
+ const pageReq: ListRunsRequest = {...req};
762
+ for (;;) {
763
+ const resp = await this.listRuns(pageReq, options);
764
+ for (const item of resp.runs ?? []) {
765
+ yield item;
766
+ }
767
+ if (resp.nextPageToken === undefined || resp.nextPageToken === '') {
768
+ return;
769
+ }
770
+ pageReq.pageToken = resp.nextPageToken;
771
+ }
772
+ }
773
+
774
+ /**
775
+ * Re-run one or more tasks. Tasks are re-run as part of the original job run.
776
+ * They use the current job and task settings, and can be viewed in the history for the
777
+ * original job run.
778
+ */
779
+ async repair(
780
+ req: RepairRunRequest,
781
+ options?: CallOptions
782
+ ): Promise<RepairRunRequest_Response> {
783
+ const url = `${this.host}/api/2.2/jobs/runs/repair`;
784
+ const body = marshalRequest(req, marshalRepairRunRequestSchema);
785
+ let resp: RepairRunRequest_Response | undefined;
786
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
787
+ const headers = new Headers({'Content-Type': 'application/json'});
788
+ if (this.workspaceId !== undefined) {
789
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
790
+ }
791
+ headers.set('User-Agent', this.userAgent);
792
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
793
+ const respBody = await executeHttpCall({
794
+ request: httpReq,
795
+ httpClient: this.httpClient,
796
+ logger: this.logger,
797
+ });
798
+ resp = parseResponse(respBody, unmarshalRepairRunRequest_ResponseSchema);
799
+ };
800
+ await executeCall(call, options);
801
+ if (resp === undefined) {
802
+ throw new Error('API call completed without a result.');
803
+ }
804
+ return resp;
805
+ }
806
+
807
+ async repairWaiter(
808
+ req: RepairRunRequest,
809
+ options?: CallOptions
810
+ ): Promise<RepairWaiter> {
811
+ await this.repair(req, options);
812
+ if (req.runId === undefined) {
813
+ throw new Error('request field runId required for polling is missing');
814
+ }
815
+ return new RepairWaiter(this, req.runId);
816
+ }
817
+
818
+ /** Overwrite all settings for the given job. Use the [_Update_ endpoint](:method:jobs/update) to update job settings partially. */
819
+ async resetJob(
820
+ req: ResetJobRequest,
821
+ options?: CallOptions
822
+ ): Promise<ResetJobRequest_Response> {
823
+ const url = `${this.host}/api/2.2/jobs/reset`;
824
+ const body = marshalRequest(req, marshalResetJobRequestSchema);
825
+ let resp: ResetJobRequest_Response | undefined;
826
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
827
+ const headers = new Headers({'Content-Type': 'application/json'});
828
+ if (this.workspaceId !== undefined) {
829
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
830
+ }
831
+ headers.set('User-Agent', this.userAgent);
832
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
833
+ const respBody = await executeHttpCall({
834
+ request: httpReq,
835
+ httpClient: this.httpClient,
836
+ logger: this.logger,
837
+ });
838
+ resp = parseResponse(respBody, unmarshalResetJobRequest_ResponseSchema);
839
+ };
840
+ await executeCall(call, options);
841
+ if (resp === undefined) {
842
+ throw new Error('API call completed without a result.');
843
+ }
844
+ return resp;
845
+ }
846
+
847
+ /** Run a job and return the `run_id` of the triggered run. */
848
+ async runNow(
849
+ req: RunNowRequest,
850
+ options?: CallOptions
851
+ ): Promise<RunNowRequest_Response> {
852
+ const url = `${this.host}/api/2.2/jobs/run-now`;
853
+ const body = marshalRequest(req, marshalRunNowRequestSchema);
854
+ let resp: RunNowRequest_Response | undefined;
855
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
856
+ const headers = new Headers({'Content-Type': 'application/json'});
857
+ if (this.workspaceId !== undefined) {
858
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
859
+ }
860
+ headers.set('User-Agent', this.userAgent);
861
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
862
+ const respBody = await executeHttpCall({
863
+ request: httpReq,
864
+ httpClient: this.httpClient,
865
+ logger: this.logger,
866
+ });
867
+ resp = parseResponse(respBody, unmarshalRunNowRequest_ResponseSchema);
868
+ };
869
+ await executeCall(call, options);
870
+ if (resp === undefined) {
871
+ throw new Error('API call completed without a result.');
872
+ }
873
+ return resp;
874
+ }
875
+
876
+ async runNowWaiter(
877
+ req: RunNowRequest,
878
+ options?: CallOptions
879
+ ): Promise<RunNowWaiter> {
880
+ const resp = await this.runNow(req, options);
881
+ if (resp.runId === undefined) {
882
+ throw new Error('response field runId required for polling is missing');
883
+ }
884
+ return new RunNowWaiter(this, resp.runId);
885
+ }
886
+
887
+ /**
888
+ * Submit a one-time run. This endpoint allows you to submit a workload directly
889
+ * without creating a job. Runs submitted using this endpoint don’t display in
890
+ * the UI. Use the `jobs/runs/get` API to check the run state after the job is
891
+ * submitted.
892
+ *
893
+ * **Important:** Jobs submitted using this endpoint are not saved as a job.
894
+ * They do not show up in the Jobs UI, and do not retry when they fail. Because
895
+ * they are not saved, <Databricks> cannot auto-optimize serverless compute in case
896
+ * of failure. If your job fails, you may want to use classic compute to specify
897
+ * the compute needs for the job. Alternatively, use the `POST /jobs/create` and
898
+ * `POST /jobs/run-now` endpoints to create and run a saved job.
899
+ */
900
+ async submitRun(
901
+ req: SubmitRunRequest,
902
+ options?: CallOptions
903
+ ): Promise<SubmitRunRequest_Response> {
904
+ const url = `${this.host}/api/2.2/jobs/runs/submit`;
905
+ const body = marshalRequest(req, marshalSubmitRunRequestSchema);
906
+ let resp: SubmitRunRequest_Response | undefined;
907
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
908
+ const headers = new Headers({'Content-Type': 'application/json'});
909
+ if (this.workspaceId !== undefined) {
910
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
911
+ }
912
+ headers.set('User-Agent', this.userAgent);
913
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
914
+ const respBody = await executeHttpCall({
915
+ request: httpReq,
916
+ httpClient: this.httpClient,
917
+ logger: this.logger,
918
+ });
919
+ resp = parseResponse(respBody, unmarshalSubmitRunRequest_ResponseSchema);
920
+ };
921
+ await executeCall(call, options);
922
+ if (resp === undefined) {
923
+ throw new Error('API call completed without a result.');
924
+ }
925
+ return resp;
926
+ }
927
+
928
+ async submitRunWaiter(
929
+ req: SubmitRunRequest,
930
+ options?: CallOptions
931
+ ): Promise<SubmitRunWaiter> {
932
+ const resp = await this.submitRun(req, options);
933
+ if (resp.runId === undefined) {
934
+ throw new Error('response field runId required for polling is missing');
935
+ }
936
+ return new SubmitRunWaiter(this, resp.runId);
937
+ }
938
+
939
+ /** Add, update, or remove specific settings of an existing job. Use the [_Reset_ endpoint](:method:jobs/reset) to overwrite all job settings. */
940
+ async updateJob(
941
+ req: UpdateJobRequest,
942
+ options?: CallOptions
943
+ ): Promise<UpdateJobRequest_Response> {
944
+ const url = `${this.host}/api/2.2/jobs/update`;
945
+ const body = marshalRequest(req, marshalUpdateJobRequestSchema);
946
+ let resp: UpdateJobRequest_Response | undefined;
947
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
948
+ const headers = new Headers({'Content-Type': 'application/json'});
949
+ if (this.workspaceId !== undefined) {
950
+ headers.set('X-Databricks-Org-Id', this.workspaceId);
951
+ }
952
+ headers.set('User-Agent', this.userAgent);
953
+ const httpReq = buildHttpRequest('POST', url, headers, callSignal, body);
954
+ const respBody = await executeHttpCall({
955
+ request: httpReq,
956
+ httpClient: this.httpClient,
957
+ logger: this.logger,
958
+ });
959
+ resp = parseResponse(respBody, unmarshalUpdateJobRequest_ResponseSchema);
960
+ };
961
+ await executeCall(call, options);
962
+ if (resp === undefined) {
963
+ throw new Error('API call completed without a result.');
964
+ }
965
+ return resp;
966
+ }
967
+ }
968
+
969
+ export class CancelRunWaiter {
970
+ constructor(
971
+ private readonly client: JobsClient,
972
+ readonly runId: bigint
973
+ ) {}
974
+
975
+ /**
976
+ * Polls until the operation reaches a terminal state.
977
+ *
978
+ * Throws if a failure state is reached.
979
+ */
980
+ async wait(options?: CallOptions): Promise<GetRunRequest_Response> {
981
+ let result: GetRunRequest_Response | undefined;
982
+
983
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
984
+ const pollResp = await this.client.getRun(
985
+ {
986
+ runId: this.runId,
987
+ },
988
+ {...options, ...(callSignal !== undefined && {signal: callSignal})}
989
+ );
990
+
991
+ const status = pollResp.state?.lifeCycleState;
992
+ if (status === undefined) {
993
+ throw new Error('response missing required status field');
994
+ }
995
+
996
+ switch (status) {
997
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
998
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
999
+ result = pollResp;
1000
+ return;
1001
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR: {
1002
+ const msg = pollResp.state?.stateMessage ?? '(no message)';
1003
+ throw new Error(`terminal state ${status}: ${msg}`);
1004
+ }
1005
+ default:
1006
+ throw new StillRunningError();
1007
+ }
1008
+ };
1009
+
1010
+ const retryOptions: CallOptions = {
1011
+ ...(options?.signal !== undefined && {signal: options.signal}),
1012
+ retrier: () =>
1013
+ retryOn({}, (err: Error) => {
1014
+ return err instanceof StillRunningError;
1015
+ }),
1016
+ };
1017
+ await executeCall(call, retryOptions);
1018
+ if (result === undefined) {
1019
+ throw new Error('API call completed without a result.');
1020
+ }
1021
+ return result;
1022
+ }
1023
+
1024
+ /** Checks whether the operation has reached a terminal state. */
1025
+ async done(options?: CallOptions): Promise<boolean> {
1026
+ const pollResp = await this.client.getRun(
1027
+ {
1028
+ runId: this.runId,
1029
+ },
1030
+ options
1031
+ );
1032
+
1033
+ const status = pollResp.state?.lifeCycleState;
1034
+ if (status === undefined) {
1035
+ throw new Error('response missing required status field');
1036
+ }
1037
+
1038
+ switch (status) {
1039
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1040
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1041
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR:
1042
+ return true;
1043
+ default:
1044
+ return false;
1045
+ }
1046
+ }
1047
+ }
1048
+
1049
+ export class RepairWaiter {
1050
+ constructor(
1051
+ private readonly client: JobsClient,
1052
+ readonly runId: bigint
1053
+ ) {}
1054
+
1055
+ /**
1056
+ * Polls until the operation reaches a terminal state.
1057
+ *
1058
+ * Throws if a failure state is reached.
1059
+ */
1060
+ async wait(options?: CallOptions): Promise<GetRunRequest_Response> {
1061
+ let result: GetRunRequest_Response | undefined;
1062
+
1063
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
1064
+ const pollResp = await this.client.getRun(
1065
+ {
1066
+ runId: this.runId,
1067
+ },
1068
+ {...options, ...(callSignal !== undefined && {signal: callSignal})}
1069
+ );
1070
+
1071
+ const status = pollResp.state?.lifeCycleState;
1072
+ if (status === undefined) {
1073
+ throw new Error('response missing required status field');
1074
+ }
1075
+
1076
+ switch (status) {
1077
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1078
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1079
+ result = pollResp;
1080
+ return;
1081
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR: {
1082
+ const msg = pollResp.state?.stateMessage ?? '(no message)';
1083
+ throw new Error(`terminal state ${status}: ${msg}`);
1084
+ }
1085
+ default:
1086
+ throw new StillRunningError();
1087
+ }
1088
+ };
1089
+
1090
+ const retryOptions: CallOptions = {
1091
+ ...(options?.signal !== undefined && {signal: options.signal}),
1092
+ retrier: () =>
1093
+ retryOn({}, (err: Error) => {
1094
+ return err instanceof StillRunningError;
1095
+ }),
1096
+ };
1097
+ await executeCall(call, retryOptions);
1098
+ if (result === undefined) {
1099
+ throw new Error('API call completed without a result.');
1100
+ }
1101
+ return result;
1102
+ }
1103
+
1104
+ /** Checks whether the operation has reached a terminal state. */
1105
+ async done(options?: CallOptions): Promise<boolean> {
1106
+ const pollResp = await this.client.getRun(
1107
+ {
1108
+ runId: this.runId,
1109
+ },
1110
+ options
1111
+ );
1112
+
1113
+ const status = pollResp.state?.lifeCycleState;
1114
+ if (status === undefined) {
1115
+ throw new Error('response missing required status field');
1116
+ }
1117
+
1118
+ switch (status) {
1119
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1120
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1121
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR:
1122
+ return true;
1123
+ default:
1124
+ return false;
1125
+ }
1126
+ }
1127
+ }
1128
+
1129
+ export class RunNowWaiter {
1130
+ constructor(
1131
+ private readonly client: JobsClient,
1132
+ readonly runId: bigint
1133
+ ) {}
1134
+
1135
+ /**
1136
+ * Polls until the operation reaches a terminal state.
1137
+ *
1138
+ * Throws if a failure state is reached.
1139
+ */
1140
+ async wait(options?: CallOptions): Promise<GetRunRequest_Response> {
1141
+ let result: GetRunRequest_Response | undefined;
1142
+
1143
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
1144
+ const pollResp = await this.client.getRun(
1145
+ {
1146
+ runId: this.runId,
1147
+ },
1148
+ {...options, ...(callSignal !== undefined && {signal: callSignal})}
1149
+ );
1150
+
1151
+ const status = pollResp.state?.lifeCycleState;
1152
+ if (status === undefined) {
1153
+ throw new Error('response missing required status field');
1154
+ }
1155
+
1156
+ switch (status) {
1157
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1158
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1159
+ result = pollResp;
1160
+ return;
1161
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR: {
1162
+ const msg = pollResp.state?.stateMessage ?? '(no message)';
1163
+ throw new Error(`terminal state ${status}: ${msg}`);
1164
+ }
1165
+ default:
1166
+ throw new StillRunningError();
1167
+ }
1168
+ };
1169
+
1170
+ const retryOptions: CallOptions = {
1171
+ ...(options?.signal !== undefined && {signal: options.signal}),
1172
+ retrier: () =>
1173
+ retryOn({}, (err: Error) => {
1174
+ return err instanceof StillRunningError;
1175
+ }),
1176
+ };
1177
+ await executeCall(call, retryOptions);
1178
+ if (result === undefined) {
1179
+ throw new Error('API call completed without a result.');
1180
+ }
1181
+ return result;
1182
+ }
1183
+
1184
+ /** Checks whether the operation has reached a terminal state. */
1185
+ async done(options?: CallOptions): Promise<boolean> {
1186
+ const pollResp = await this.client.getRun(
1187
+ {
1188
+ runId: this.runId,
1189
+ },
1190
+ options
1191
+ );
1192
+
1193
+ const status = pollResp.state?.lifeCycleState;
1194
+ if (status === undefined) {
1195
+ throw new Error('response missing required status field');
1196
+ }
1197
+
1198
+ switch (status) {
1199
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1200
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1201
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR:
1202
+ return true;
1203
+ default:
1204
+ return false;
1205
+ }
1206
+ }
1207
+ }
1208
+
1209
+ export class SubmitRunWaiter {
1210
+ constructor(
1211
+ private readonly client: JobsClient,
1212
+ readonly runId: bigint
1213
+ ) {}
1214
+
1215
+ /**
1216
+ * Polls until the operation reaches a terminal state.
1217
+ *
1218
+ * Throws if a failure state is reached.
1219
+ */
1220
+ async wait(options?: CallOptions): Promise<GetRunRequest_Response> {
1221
+ let result: GetRunRequest_Response | undefined;
1222
+
1223
+ const call: Call = async (callSignal?: AbortSignal): Promise<void> => {
1224
+ const pollResp = await this.client.getRun(
1225
+ {
1226
+ runId: this.runId,
1227
+ },
1228
+ {...options, ...(callSignal !== undefined && {signal: callSignal})}
1229
+ );
1230
+
1231
+ const status = pollResp.state?.lifeCycleState;
1232
+ if (status === undefined) {
1233
+ throw new Error('response missing required status field');
1234
+ }
1235
+
1236
+ switch (status) {
1237
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1238
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1239
+ result = pollResp;
1240
+ return;
1241
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR: {
1242
+ const msg = pollResp.state?.stateMessage ?? '(no message)';
1243
+ throw new Error(`terminal state ${status}: ${msg}`);
1244
+ }
1245
+ default:
1246
+ throw new StillRunningError();
1247
+ }
1248
+ };
1249
+
1250
+ const retryOptions: CallOptions = {
1251
+ ...(options?.signal !== undefined && {signal: options.signal}),
1252
+ retrier: () =>
1253
+ retryOn({}, (err: Error) => {
1254
+ return err instanceof StillRunningError;
1255
+ }),
1256
+ };
1257
+ await executeCall(call, retryOptions);
1258
+ if (result === undefined) {
1259
+ throw new Error('API call completed without a result.');
1260
+ }
1261
+ return result;
1262
+ }
1263
+
1264
+ /** Checks whether the operation has reached a terminal state. */
1265
+ async done(options?: CallOptions): Promise<boolean> {
1266
+ const pollResp = await this.client.getRun(
1267
+ {
1268
+ runId: this.runId,
1269
+ },
1270
+ options
1271
+ );
1272
+
1273
+ const status = pollResp.state?.lifeCycleState;
1274
+ if (status === undefined) {
1275
+ throw new Error('response missing required status field');
1276
+ }
1277
+
1278
+ switch (status) {
1279
+ case RunLifeCycleState_RunLifeCycleState.TERMINATED:
1280
+ case RunLifeCycleState_RunLifeCycleState.SKIPPED:
1281
+ case RunLifeCycleState_RunLifeCycleState.INTERNAL_ERROR:
1282
+ return true;
1283
+ default:
1284
+ return false;
1285
+ }
1286
+ }
1287
+ }