@openeo/js-client 2.5.0 → 2.6.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.
- package/LICENSE +201 -201
- package/README.md +93 -83
- package/openeo.d.ts +112 -53
- package/openeo.js +3670 -4114
- package/openeo.min.js +1 -1
- package/package.json +72 -70
- package/src/authprovider.js +147 -138
- package/src/baseentity.js +162 -162
- package/src/basicprovider.js +69 -48
- package/src/browser.js +168 -168
- package/src/builder/builder.js +400 -400
- package/src/builder/formula.js +211 -211
- package/src/builder/node.js +268 -268
- package/src/builder/parameter.js +144 -144
- package/src/builder/tapdigit.js +489 -489
- package/src/capabilities.js +265 -220
- package/src/connection.js +1310 -1212
- package/src/env.js +5 -5
- package/src/filetypes.js +111 -111
- package/src/job.js +323 -322
- package/src/logs.js +73 -68
- package/src/node.js +168 -168
- package/src/oidcprovider.js +387 -375
- package/src/openeo.js +137 -138
- package/src/service.js +222 -221
- package/src/typedefs.js +242 -242
- package/src/userfile.js +128 -128
- package/src/userprocess.js +166 -166
package/src/connection.js
CHANGED
|
@@ -1,1212 +1,1310 @@
|
|
|
1
|
-
const Environment = require('./env');
|
|
2
|
-
const Utils = require('@openeo/js-commons/src/utils');
|
|
3
|
-
const ProcessRegistry = require('@openeo/js-commons/src/processRegistry');
|
|
4
|
-
const axios = require('axios')
|
|
5
|
-
const StacMigrate = require('@radiantearth/stac-migrate');
|
|
6
|
-
|
|
7
|
-
const AuthProvider = require('./authprovider');
|
|
8
|
-
const BasicProvider = require('./basicprovider');
|
|
9
|
-
const OidcProvider = require('./oidcprovider');
|
|
10
|
-
|
|
11
|
-
const Capabilities = require('./capabilities');
|
|
12
|
-
const FileTypes = require('./filetypes');
|
|
13
|
-
const UserFile = require('./userfile');
|
|
14
|
-
const Job = require('./job');
|
|
15
|
-
const UserProcess = require('./userprocess');
|
|
16
|
-
const Service = require('./service');
|
|
17
|
-
|
|
18
|
-
const Builder = require('./builder/builder');
|
|
19
|
-
const BuilderNode = require('./builder/node');
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* @returns {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
*
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
* @
|
|
226
|
-
* @
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
* @param {
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
*
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
* @
|
|
482
|
-
* @
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
*
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
* @
|
|
543
|
-
*/
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
*
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
* @
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
this.
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
* @
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
*
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
let
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
* @
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
* @
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
* @
|
|
695
|
-
* @
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
* @
|
|
748
|
-
* @param {
|
|
749
|
-
* @returns {Promise<UserProcess
|
|
750
|
-
* @throws {Error}
|
|
751
|
-
*/
|
|
752
|
-
async
|
|
753
|
-
let
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
*
|
|
780
|
-
*
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
);
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
* @
|
|
875
|
-
* @param {
|
|
876
|
-
* @param {?
|
|
877
|
-
* @param {?
|
|
878
|
-
* @
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
let
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
return job;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
*
|
|
908
|
-
*
|
|
909
|
-
* @
|
|
910
|
-
* @
|
|
911
|
-
* @
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
let response = await this.
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
return
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
* @
|
|
944
|
-
* @param {
|
|
945
|
-
* @
|
|
946
|
-
* @
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
*
|
|
979
|
-
*
|
|
980
|
-
* @
|
|
981
|
-
* @param {
|
|
982
|
-
* @
|
|
983
|
-
* @
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
*
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
return
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
/**
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
* @
|
|
1031
|
-
* @param {
|
|
1032
|
-
* @param {string
|
|
1033
|
-
* @returns {
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
return
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
*
|
|
1110
|
-
*
|
|
1111
|
-
* @
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
*
|
|
1127
|
-
*
|
|
1128
|
-
*
|
|
1129
|
-
* @
|
|
1130
|
-
* @param {
|
|
1131
|
-
* @
|
|
1132
|
-
* @
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
*
|
|
1150
|
-
*
|
|
1151
|
-
*
|
|
1152
|
-
*
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
* @
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
}
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1
|
+
const Environment = require('./env');
|
|
2
|
+
const Utils = require('@openeo/js-commons/src/utils');
|
|
3
|
+
const ProcessRegistry = require('@openeo/js-commons/src/processRegistry');
|
|
4
|
+
const axios = require('axios');
|
|
5
|
+
const StacMigrate = require('@radiantearth/stac-migrate');
|
|
6
|
+
|
|
7
|
+
const AuthProvider = require('./authprovider');
|
|
8
|
+
const BasicProvider = require('./basicprovider');
|
|
9
|
+
const OidcProvider = require('./oidcprovider');
|
|
10
|
+
|
|
11
|
+
const Capabilities = require('./capabilities');
|
|
12
|
+
const FileTypes = require('./filetypes');
|
|
13
|
+
const UserFile = require('./userfile');
|
|
14
|
+
const Job = require('./job');
|
|
15
|
+
const UserProcess = require('./userprocess');
|
|
16
|
+
const Service = require('./service');
|
|
17
|
+
|
|
18
|
+
const Builder = require('./builder/builder');
|
|
19
|
+
const BuilderNode = require('./builder/node');
|
|
20
|
+
|
|
21
|
+
const CONFORMANCE_RELS = [
|
|
22
|
+
'conformance',
|
|
23
|
+
'http://www.opengis.net/def/rel/ogc/1.0/conformance'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A connection to a back-end.
|
|
28
|
+
*/
|
|
29
|
+
class Connection {
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new Connection.
|
|
33
|
+
*
|
|
34
|
+
* @param {string} baseUrl - The versioned URL or the back-end instance.
|
|
35
|
+
* @param {Options} [options={}] - Additional options for the connection.
|
|
36
|
+
* @param {?string} [url=null] - User-provided URL of the backend connected to.
|
|
37
|
+
*/
|
|
38
|
+
constructor(baseUrl, options = {}, url = null) {
|
|
39
|
+
/**
|
|
40
|
+
* User-provided URL of the backend connected to.
|
|
41
|
+
*
|
|
42
|
+
* `null` if not given and the connection was directly made to a versioned instance of the back-end.
|
|
43
|
+
*
|
|
44
|
+
* @protected
|
|
45
|
+
* @type {string | null}
|
|
46
|
+
*/
|
|
47
|
+
this.url = url;
|
|
48
|
+
/**
|
|
49
|
+
* The versioned URL or the back-end instance.
|
|
50
|
+
*
|
|
51
|
+
* @protected
|
|
52
|
+
* @type {string}
|
|
53
|
+
*/
|
|
54
|
+
this.baseUrl = Utils.normalizeUrl(baseUrl);
|
|
55
|
+
/**
|
|
56
|
+
* Auth Provider cache
|
|
57
|
+
*
|
|
58
|
+
* @protected
|
|
59
|
+
* @type {Array.<AuthProvider> | null}
|
|
60
|
+
*/
|
|
61
|
+
this.authProviderList = null;
|
|
62
|
+
/**
|
|
63
|
+
* Current auth provider
|
|
64
|
+
*
|
|
65
|
+
* @protected
|
|
66
|
+
* @type {AuthProvider | null}
|
|
67
|
+
*/
|
|
68
|
+
this.authProvider = null;
|
|
69
|
+
/**
|
|
70
|
+
* Capability cache
|
|
71
|
+
*
|
|
72
|
+
* @protected
|
|
73
|
+
* @type {Capabilities | null}
|
|
74
|
+
*/
|
|
75
|
+
this.capabilitiesObject = null;
|
|
76
|
+
/**
|
|
77
|
+
* Listeners for events.
|
|
78
|
+
*
|
|
79
|
+
* @protected
|
|
80
|
+
* @type {object.<string|Function>}
|
|
81
|
+
*/
|
|
82
|
+
this.listeners = {};
|
|
83
|
+
/**
|
|
84
|
+
* Additional options for the connection.
|
|
85
|
+
*
|
|
86
|
+
* @protected
|
|
87
|
+
* @type {Options}
|
|
88
|
+
*/
|
|
89
|
+
this.options = options;
|
|
90
|
+
/**
|
|
91
|
+
* Process cache
|
|
92
|
+
*
|
|
93
|
+
* @protected
|
|
94
|
+
* @type {ProcessRegistry}
|
|
95
|
+
*/
|
|
96
|
+
this.processes = new ProcessRegistry([], Boolean(options.addNamespaceToProcess));
|
|
97
|
+
this.processes.listeners.push((...args) => this.emit('processesChanged', ...args));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Initializes the connection by requesting the capabilities.
|
|
102
|
+
*
|
|
103
|
+
* @async
|
|
104
|
+
* @protected
|
|
105
|
+
* @returns {Promise<Capabilities>} Capabilities
|
|
106
|
+
* @throws {Error}
|
|
107
|
+
*/
|
|
108
|
+
async init() {
|
|
109
|
+
let response = await this._get('/');
|
|
110
|
+
let data = Object.assign({}, response.data);
|
|
111
|
+
data.links = this.makeLinksAbsolute(data.links, response);
|
|
112
|
+
|
|
113
|
+
if (!Array.isArray(data.conformsTo) && Array.isArray(data.links)) {
|
|
114
|
+
let conformanceLink = this._getLinkHref(data.links, CONFORMANCE_RELS);
|
|
115
|
+
if (conformanceLink) {
|
|
116
|
+
let response2 = await this._get(conformanceLink);
|
|
117
|
+
if (Utils.isObject(response2.data) && Array.isArray(response2.data.conformsTo)) {
|
|
118
|
+
data.conformsTo = response2.data.conformsTo;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.capabilitiesObject = new Capabilities(data);
|
|
124
|
+
return this.capabilitiesObject;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Refresh the cache for processes.
|
|
129
|
+
*
|
|
130
|
+
* @async
|
|
131
|
+
* @protected
|
|
132
|
+
* @returns {Promise}
|
|
133
|
+
*/
|
|
134
|
+
async refreshProcessCache() {
|
|
135
|
+
if (this.processes.count() === 0) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
let promises = this.processes.namespaces().map(namespace => {
|
|
139
|
+
let fn = () => Promise.resolve();
|
|
140
|
+
if (namespace === 'user') {
|
|
141
|
+
let userProcesses = this.processes.namespace('user');
|
|
142
|
+
if (!this.isAuthenticated()) {
|
|
143
|
+
fn = () => (this.processes.remove(null, 'user') ? Promise.resolve() : Promise.reject(new Error("Can't clear user processes")));
|
|
144
|
+
}
|
|
145
|
+
else if (this.capabilities().hasFeature('listUserProcesses')) {
|
|
146
|
+
fn = () => this.listUserProcesses(userProcesses);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (this.capabilities().hasFeature('listProcesses')) {
|
|
150
|
+
fn = () => this.listProcesses(namespace);
|
|
151
|
+
}
|
|
152
|
+
return fn().catch(error => console.warn(`Could not update processes for namespace '${namespace}' due to an error: ${error.message}`));
|
|
153
|
+
});
|
|
154
|
+
return await Promise.all(promises);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Returns the URL of the versioned back-end instance currently connected to.
|
|
159
|
+
*
|
|
160
|
+
* @returns {string} The versioned URL or the back-end instance.
|
|
161
|
+
*/
|
|
162
|
+
getBaseUrl() {
|
|
163
|
+
return this.baseUrl;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Returns the user-provided URL of the back-end currently connected to.
|
|
168
|
+
*
|
|
169
|
+
* @returns {string} The URL or the back-end.
|
|
170
|
+
*/
|
|
171
|
+
getUrl() {
|
|
172
|
+
return this.url || this.baseUrl;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Returns the capabilities of the back-end.
|
|
177
|
+
*
|
|
178
|
+
* @returns {Capabilities} Capabilities
|
|
179
|
+
*/
|
|
180
|
+
capabilities() {
|
|
181
|
+
return this.capabilitiesObject;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* List the supported output file formats.
|
|
186
|
+
*
|
|
187
|
+
* @async
|
|
188
|
+
* @returns {Promise<FileTypes>} A response compatible to the API specification.
|
|
189
|
+
* @throws {Error}
|
|
190
|
+
*/
|
|
191
|
+
async listFileTypes() {
|
|
192
|
+
let response = await this._get('/file_formats');
|
|
193
|
+
return new FileTypes(response.data);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* List the supported secondary service types.
|
|
198
|
+
*
|
|
199
|
+
* @async
|
|
200
|
+
* @returns {Promise<object.<string, ServiceType>>} A response compatible to the API specification.
|
|
201
|
+
* @throws {Error}
|
|
202
|
+
*/
|
|
203
|
+
async listServiceTypes() {
|
|
204
|
+
let response = await this._get('/service_types');
|
|
205
|
+
return response.data;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* List the supported UDF runtimes.
|
|
210
|
+
*
|
|
211
|
+
* @async
|
|
212
|
+
* @returns {Promise<object.<string, UdfRuntime>>} A response compatible to the API specification.
|
|
213
|
+
* @throws {Error}
|
|
214
|
+
*/
|
|
215
|
+
async listUdfRuntimes() {
|
|
216
|
+
let response = await this._get('/udf_runtimes');
|
|
217
|
+
return response.data;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* List all collections available on the back-end.
|
|
222
|
+
*
|
|
223
|
+
* The collections returned always comply to the latest STAC version (currently 1.0.0).
|
|
224
|
+
*
|
|
225
|
+
* @async
|
|
226
|
+
* @returns {Promise<Collections>} A response compatible to the API specification.
|
|
227
|
+
* @throws {Error}
|
|
228
|
+
*/
|
|
229
|
+
async listCollections() {
|
|
230
|
+
let response = await this._get('/collections');
|
|
231
|
+
if (Utils.isObject(response.data) && Array.isArray(response.data.collections)) {
|
|
232
|
+
response.data.collections = response.data.collections.map(collection => {
|
|
233
|
+
if (collection.stac_version) {
|
|
234
|
+
return StacMigrate.collection(collection);
|
|
235
|
+
}
|
|
236
|
+
return collection;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return response.data;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Get further information about a single collection.
|
|
244
|
+
*
|
|
245
|
+
* The collection returned always complies to the latest STAC version (currently 1.0.0).
|
|
246
|
+
*
|
|
247
|
+
* @async
|
|
248
|
+
* @param {string} collectionId - Collection ID to request further metadata for.
|
|
249
|
+
* @returns {Promise<Collection>} - A response compatible to the API specification.
|
|
250
|
+
* @throws {Error}
|
|
251
|
+
*/
|
|
252
|
+
async describeCollection(collectionId) {
|
|
253
|
+
let response = await this._get('/collections/' + collectionId);
|
|
254
|
+
if (response.data.stac_version) {
|
|
255
|
+
return StacMigrate.collection(response.data);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
return response.data;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Loads items for a specific image collection.
|
|
264
|
+
* May not be available for all collections.
|
|
265
|
+
*
|
|
266
|
+
* The items returned always comply to the latest STAC version (currently 1.0.0).
|
|
267
|
+
*
|
|
268
|
+
* This is an experimental API and is subject to change.
|
|
269
|
+
*
|
|
270
|
+
* @async
|
|
271
|
+
* @param {string} collectionId - Collection ID to request items for.
|
|
272
|
+
* @param {?Array.<number>} [spatialExtent=null] - Limits the items to the given bounding box in WGS84:
|
|
273
|
+
* 1. Lower left corner, coordinate axis 1
|
|
274
|
+
* 2. Lower left corner, coordinate axis 2
|
|
275
|
+
* 3. Upper right corner, coordinate axis 1
|
|
276
|
+
* 4. Upper right corner, coordinate axis 2
|
|
277
|
+
* @param {?Array} [temporalExtent=null] - Limits the items to the specified temporal interval.
|
|
278
|
+
* The interval has to be specified as an array with exactly two elements (start, end) and
|
|
279
|
+
* each must be either an RFC 3339 compatible string or a Date object.
|
|
280
|
+
* Also supports open intervals by setting one of the boundaries to `null`, but never both.
|
|
281
|
+
* @param {?number} [limit=null] - The amount of items per request/page as integer. If `null` (default), the back-end decides.
|
|
282
|
+
* @yields {Promise<ItemCollection>} A response compatible to the API specification.
|
|
283
|
+
* @throws {Error}
|
|
284
|
+
*/
|
|
285
|
+
async * listCollectionItems(collectionId, spatialExtent = null, temporalExtent = null, limit = null) {
|
|
286
|
+
let page = 1;
|
|
287
|
+
let nextUrl = '/collections/' + collectionId + '/items';
|
|
288
|
+
while(nextUrl) {
|
|
289
|
+
let params = {};
|
|
290
|
+
if (page === 1) {
|
|
291
|
+
if (Array.isArray(spatialExtent)) {
|
|
292
|
+
params.bbox = spatialExtent.join(',');
|
|
293
|
+
}
|
|
294
|
+
if (Array.isArray(temporalExtent)) {
|
|
295
|
+
params.datetime = temporalExtent
|
|
296
|
+
.map(e => {
|
|
297
|
+
if (e instanceof Date) {
|
|
298
|
+
return e.toISOString();
|
|
299
|
+
}
|
|
300
|
+
else if (typeof e === 'string') {
|
|
301
|
+
return e;
|
|
302
|
+
}
|
|
303
|
+
return '..'; // Open date range
|
|
304
|
+
})
|
|
305
|
+
.join('/');
|
|
306
|
+
}
|
|
307
|
+
if (limit > 0) {
|
|
308
|
+
params.limit = limit;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
let response = await this._get(nextUrl, params);
|
|
313
|
+
if (Utils.isObject(response.data) && Array.isArray(response.data.features)) {
|
|
314
|
+
response.data.features = response.data.features.map(item => {
|
|
315
|
+
if (item.stac_version) {
|
|
316
|
+
return StacMigrate.item(item);
|
|
317
|
+
}
|
|
318
|
+
return item;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
yield response.data;
|
|
322
|
+
|
|
323
|
+
page++;
|
|
324
|
+
let links = this.makeLinksAbsolute(response.data.links);
|
|
325
|
+
nextUrl = this._getLinkHref(links, 'next');
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Normalisation of the namespace to a value that is compatible with the OpenEO specs - EXPERIMENTAL.
|
|
331
|
+
*
|
|
332
|
+
* This is required to support UDP that are shared as public. These can only be executed with providing the full URL
|
|
333
|
+
* (e.g. https://<backend>/processes/<namespace>/<process_id>) as the namespace value in the processing graph. For other
|
|
334
|
+
* parts of the API (such as the listing of the processes, only the name of the namespace is required.
|
|
335
|
+
*
|
|
336
|
+
* This function will extract the short name of the namespace from a shareable URL.
|
|
337
|
+
*
|
|
338
|
+
* @protected
|
|
339
|
+
* @param {?string} namespace - Namespace of the process
|
|
340
|
+
* @returns {?string}
|
|
341
|
+
*/
|
|
342
|
+
normalizeNamespace(namespace) {
|
|
343
|
+
// The pattern in https://github.com/Open-EO/openeo-api/pull/348 doesn't include the double colon yet - the regexp may change in the future
|
|
344
|
+
const matches = namespace.match( /^https?:\/\/.*\/processes\/(@?[\w\-.~:]+)\/?/i);
|
|
345
|
+
return matches && matches.length > 1 ? matches[1] : namespace;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* List processes available on the back-end.
|
|
350
|
+
*
|
|
351
|
+
* Requests pre-defined processes by default.
|
|
352
|
+
* Set the namespace parameter to request processes from a specific namespace.
|
|
353
|
+
*
|
|
354
|
+
* Note: The list of namespaces can be retrieved by calling `listProcesses` without a namespace given.
|
|
355
|
+
* The namespaces are then listed in the property `namespaces`.
|
|
356
|
+
*
|
|
357
|
+
* @async
|
|
358
|
+
* @param {?string} [namespace=null] - Namespace of the processes (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
|
|
359
|
+
* @returns {Promise<Processes>} - A response compatible to the API specification.
|
|
360
|
+
* @throws {Error}
|
|
361
|
+
*/
|
|
362
|
+
async listProcesses(namespace = null) {
|
|
363
|
+
if (!namespace) {
|
|
364
|
+
namespace = 'backend';
|
|
365
|
+
}
|
|
366
|
+
let path = (namespace === 'backend') ? '/processes' : `/processes/${this.normalizeNamespace(namespace)}`;
|
|
367
|
+
let response = await this._get(path);
|
|
368
|
+
|
|
369
|
+
if (!Utils.isObject(response.data) || !Array.isArray(response.data.processes)) {
|
|
370
|
+
throw new Error('Invalid response received for processes');
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Store processes in cache
|
|
374
|
+
this.processes.remove(null, namespace);
|
|
375
|
+
this.processes.addAll(response.data.processes, namespace);
|
|
376
|
+
|
|
377
|
+
return Object.assign(response.data, {processes: this.processes.namespace(namespace)});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Get information about a single process.
|
|
382
|
+
*
|
|
383
|
+
* @async
|
|
384
|
+
* @param {string} processId - Collection ID to request further metadata for.
|
|
385
|
+
* @param {?string} [namespace=null] - Namespace of the process (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
|
|
386
|
+
* @returns {Promise<?Process>} - A single process as object, or `null` if none is found.
|
|
387
|
+
* @throws {Error}
|
|
388
|
+
* @see Connection#listProcesses
|
|
389
|
+
*/
|
|
390
|
+
async describeProcess(processId, namespace = null) {
|
|
391
|
+
if (!namespace) {
|
|
392
|
+
namespace = 'backend';
|
|
393
|
+
}
|
|
394
|
+
if (namespace === 'backend') {
|
|
395
|
+
await this.listProcesses();
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
let response = await this._get(`/processes/${this.normalizeNamespace(namespace)}/${processId}`);
|
|
399
|
+
if (!Utils.isObject(response.data) || typeof response.data.id !== 'string') {
|
|
400
|
+
throw new Error('Invalid response received for process');
|
|
401
|
+
}
|
|
402
|
+
this.processes.add(response.data, namespace);
|
|
403
|
+
}
|
|
404
|
+
return this.processes.get(processId, namespace);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Returns an object to simply build user-defined processes based upon pre-defined processes.
|
|
409
|
+
*
|
|
410
|
+
* @async
|
|
411
|
+
* @param {string} id - A name for the process.
|
|
412
|
+
* @returns {Promise<Builder>}
|
|
413
|
+
* @throws {Error}
|
|
414
|
+
* @see Connection#listProcesses
|
|
415
|
+
*/
|
|
416
|
+
async buildProcess(id) {
|
|
417
|
+
await this.listProcesses();
|
|
418
|
+
return new Builder(this.processes, null, id);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* List all authentication methods supported by the back-end.
|
|
423
|
+
*
|
|
424
|
+
* @async
|
|
425
|
+
* @returns {Promise<Array.<AuthProvider>>} An array containing all supported AuthProviders (including all OIDC providers and HTTP Basic).
|
|
426
|
+
* @throws {Error}
|
|
427
|
+
* @see AuthProvider
|
|
428
|
+
*/
|
|
429
|
+
async listAuthProviders() {
|
|
430
|
+
if (this.authProviderList !== null) {
|
|
431
|
+
return this.authProviderList;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
this.authProviderList = [];
|
|
435
|
+
let cap = this.capabilities();
|
|
436
|
+
|
|
437
|
+
// Add OIDC providers
|
|
438
|
+
if (cap.hasFeature('authenticateOIDC')) {
|
|
439
|
+
let res = await this._get('/credentials/oidc');
|
|
440
|
+
let oidcFactory = this.getOidcProviderFactory();
|
|
441
|
+
if (Utils.isObject(res.data) && Array.isArray(res.data.providers) && typeof oidcFactory === 'function') {
|
|
442
|
+
for(let i in res.data.providers) {
|
|
443
|
+
let obj = oidcFactory(res.data.providers[i]);
|
|
444
|
+
if (obj instanceof AuthProvider) {
|
|
445
|
+
this.authProviderList.push(obj);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Add Basic provider
|
|
452
|
+
if (cap.hasFeature('authenticateBasic')) {
|
|
453
|
+
this.authProviderList.push(new BasicProvider(this));
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return this.authProviderList;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* This function is meant to create the OIDC providers used for authentication.
|
|
461
|
+
*
|
|
462
|
+
* The function gets passed a single argument that contains the
|
|
463
|
+
* provider information as provided by the API, e.g. having the properties
|
|
464
|
+
* `id`, `issuer`, `title` etc.
|
|
465
|
+
*
|
|
466
|
+
* The function must return an instance of AuthProvider or any derived class.
|
|
467
|
+
* May return `null` if the instance can't be created.
|
|
468
|
+
*
|
|
469
|
+
* @callback oidcProviderFactoryFunction
|
|
470
|
+
* @param {object.<string, *>} providerInfo - The provider information as provided by the API, having the properties `id`, `issuer`, `title` etc.
|
|
471
|
+
* @returns {AuthProvider | null}
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Sets a factory function that creates custom OpenID Connect provider instances.
|
|
476
|
+
*
|
|
477
|
+
* You only need to call this if you have implemented a new AuthProvider based
|
|
478
|
+
* on the AuthProvider interface (or OIDCProvider class), e.g. to use a
|
|
479
|
+
* OIDC library other than oidc-client-js.
|
|
480
|
+
*
|
|
481
|
+
* @param {?oidcProviderFactoryFunction} [providerFactoryFunc=null]
|
|
482
|
+
* @see AuthProvider
|
|
483
|
+
*/
|
|
484
|
+
setOidcProviderFactory(providerFactoryFunc) {
|
|
485
|
+
this.oidcProviderFactory = providerFactoryFunc;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Get the OpenID Connect provider factory.
|
|
490
|
+
*
|
|
491
|
+
* Returns `null` if OIDC is not supported by the client or an instance
|
|
492
|
+
* can't be created for whatever reason.
|
|
493
|
+
*
|
|
494
|
+
* @returns {oidcProviderFactoryFunction | null}
|
|
495
|
+
* @see AuthProvider
|
|
496
|
+
*/
|
|
497
|
+
getOidcProviderFactory() {
|
|
498
|
+
if (typeof this.oidcProviderFactory === 'function') {
|
|
499
|
+
return this.oidcProviderFactory;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
if (OidcProvider.isSupported()) {
|
|
503
|
+
return providerInfo => new OidcProvider(this, providerInfo);
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Authenticates with username and password against a back-end supporting HTTP Basic Authentication.
|
|
513
|
+
*
|
|
514
|
+
* DEPRECATED in favor of using `listAuthProviders` and `BasicProvider`.
|
|
515
|
+
*
|
|
516
|
+
* @async
|
|
517
|
+
* @deprecated
|
|
518
|
+
* @param {string} username
|
|
519
|
+
* @param {string} password
|
|
520
|
+
* @see BasicProvider
|
|
521
|
+
* @see Connection#listAuthProviders
|
|
522
|
+
*/
|
|
523
|
+
async authenticateBasic(username, password) {
|
|
524
|
+
let basic = new BasicProvider(this);
|
|
525
|
+
await basic.login(username, password);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Returns whether the user is authenticated (logged in) at the back-end or not.
|
|
530
|
+
*
|
|
531
|
+
* @returns {boolean} `true` if authenticated, `false` if not.
|
|
532
|
+
*/
|
|
533
|
+
isAuthenticated() {
|
|
534
|
+
return (this.authProvider !== null);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Emits the given event.
|
|
539
|
+
*
|
|
540
|
+
* @protected
|
|
541
|
+
* @param {string} event
|
|
542
|
+
* @param {...*} args
|
|
543
|
+
*/
|
|
544
|
+
emit(event, ...args) {
|
|
545
|
+
if (typeof this.listeners[event] === 'function') {
|
|
546
|
+
this.listeners[event](...args);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Registers a listener with the given event.
|
|
552
|
+
*
|
|
553
|
+
* Currently supported:
|
|
554
|
+
* - authProviderChanged(provider): Raised when the auth provider has changed.
|
|
555
|
+
* - tokenChanged(token): Raised when the access token has changed.
|
|
556
|
+
* - processesChanged(type, data, namespace): Raised when the process registry has changed (i.e. a process was added, updated or deleted).
|
|
557
|
+
*
|
|
558
|
+
* @param {string} event
|
|
559
|
+
* @param {Function} callback
|
|
560
|
+
*/
|
|
561
|
+
on(event, callback) {
|
|
562
|
+
this.listeners[event] = callback;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Removes a listener from the given event.
|
|
567
|
+
*
|
|
568
|
+
* @param {string} event
|
|
569
|
+
*/
|
|
570
|
+
off(event) {
|
|
571
|
+
delete this.listeners[event];
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Returns the AuthProvider.
|
|
576
|
+
*
|
|
577
|
+
* @returns {AuthProvider | null}
|
|
578
|
+
*/
|
|
579
|
+
getAuthProvider() {
|
|
580
|
+
return this.authProvider;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Sets the AuthProvider.
|
|
585
|
+
*
|
|
586
|
+
* @param {AuthProvider} provider
|
|
587
|
+
*/
|
|
588
|
+
setAuthProvider(provider) {
|
|
589
|
+
if (provider === this.authProvider) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
if (provider instanceof AuthProvider) {
|
|
593
|
+
this.authProvider = provider;
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
this.authProvider = null;
|
|
597
|
+
}
|
|
598
|
+
this.emit('authProviderChanged', this.authProvider);
|
|
599
|
+
// Update process cache on auth changes: https://github.com/Open-EO/openeo-js-client/issues/55
|
|
600
|
+
this.refreshProcessCache();
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Sets the authentication token for the connection.
|
|
605
|
+
*
|
|
606
|
+
* This creates a new custom `AuthProvider` with the given details and returns it.
|
|
607
|
+
* After calling this function you can make requests against the API.
|
|
608
|
+
*
|
|
609
|
+
* This is NOT recommended to use. Only use if you know what you are doing.
|
|
610
|
+
* It is recommended to authenticate through `listAuthProviders` or related functions.
|
|
611
|
+
*
|
|
612
|
+
* @param {string} type - The authentication type, e.g. `basic` or `oidc`.
|
|
613
|
+
* @param {string} providerId - The provider identifier. For OIDC the `id` of the provider.
|
|
614
|
+
* @param {string} token - The actual access token as given by the authentication method during the login process.
|
|
615
|
+
* @returns {AuthProvider}
|
|
616
|
+
*/
|
|
617
|
+
setAuthToken(type, providerId, token) {
|
|
618
|
+
let provider = new AuthProvider(type, this, {
|
|
619
|
+
id: providerId,
|
|
620
|
+
title: "Custom",
|
|
621
|
+
description: ""
|
|
622
|
+
});
|
|
623
|
+
provider.setToken(token);
|
|
624
|
+
this.setAuthProvider(provider);
|
|
625
|
+
return provider;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Get information about the authenticated user.
|
|
630
|
+
*
|
|
631
|
+
* Updates the User ID if available.
|
|
632
|
+
*
|
|
633
|
+
* @async
|
|
634
|
+
* @returns {Promise<UserAccount>} A response compatible to the API specification.
|
|
635
|
+
* @throws {Error}
|
|
636
|
+
*/
|
|
637
|
+
async describeAccount() {
|
|
638
|
+
let response = await this._get('/me');
|
|
639
|
+
return response.data;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Lists all files from the user workspace.
|
|
644
|
+
*
|
|
645
|
+
* @async
|
|
646
|
+
* @returns {Promise<ResponseArray.<UserFile>>} A list of files.
|
|
647
|
+
* @throws {Error}
|
|
648
|
+
*/
|
|
649
|
+
async listFiles() {
|
|
650
|
+
let response = await this._get('/files');
|
|
651
|
+
let files = response.data.files.map(
|
|
652
|
+
f => new UserFile(this, f.path).setAll(f)
|
|
653
|
+
);
|
|
654
|
+
return this._toResponseArray(files, response.data);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* A callback that is executed on upload progress updates.
|
|
659
|
+
*
|
|
660
|
+
* @callback uploadStatusCallback
|
|
661
|
+
* @param {number} percentCompleted - The percent (0-100) completed.
|
|
662
|
+
* @param {UserFile} file - The file object corresponding to the callback.
|
|
663
|
+
*/
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Uploads a file to the user workspace.
|
|
667
|
+
* If a file with the name exists, overwrites it.
|
|
668
|
+
*
|
|
669
|
+
* This method has different behaviour depending on the environment.
|
|
670
|
+
* In a nodeJS environment the source must be a path to a file as string.
|
|
671
|
+
* In a browser environment the source must be an object from a file upload form.
|
|
672
|
+
*
|
|
673
|
+
* @async
|
|
674
|
+
* @param {*} source - The source, see method description for details.
|
|
675
|
+
* @param {?string} [targetPath=null] - The target path on the server, relative to the user workspace. Defaults to the file name of the source file.
|
|
676
|
+
* @param {?uploadStatusCallback} [statusCallback=null] - Optionally, a callback that is executed on upload progress updates.
|
|
677
|
+
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the upload process.
|
|
678
|
+
* @returns {Promise<UserFile>}
|
|
679
|
+
* @throws {Error}
|
|
680
|
+
*/
|
|
681
|
+
async uploadFile(source, targetPath = null, statusCallback = null, abortController = null) {
|
|
682
|
+
if (targetPath === null) {
|
|
683
|
+
targetPath = Environment.fileNameForUpload(source);
|
|
684
|
+
}
|
|
685
|
+
let file = await this.getFile(targetPath);
|
|
686
|
+
return await file.uploadFile(source, statusCallback, abortController);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Opens a (existing or non-existing) file without reading any information or creating a new file at the back-end.
|
|
691
|
+
*
|
|
692
|
+
* @async
|
|
693
|
+
* @param {string} path - Path to the file, relative to the user workspace.
|
|
694
|
+
* @returns {Promise<UserFile>} A file.
|
|
695
|
+
* @throws {Error}
|
|
696
|
+
*/
|
|
697
|
+
async getFile(path) {
|
|
698
|
+
return new UserFile(this, path);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Takes a UserProcess, BuilderNode or a plain object containing process nodes
|
|
703
|
+
* and converts it to an API compliant object.
|
|
704
|
+
*
|
|
705
|
+
* @param {UserProcess|BuilderNode|object.<string, *>} process - Process to be normalized.
|
|
706
|
+
* @param {object.<string, *>} additional - Additional properties to be merged with the resulting object.
|
|
707
|
+
* @returns {object.<string, *>}
|
|
708
|
+
* @protected
|
|
709
|
+
*/
|
|
710
|
+
_normalizeUserProcess(process, additional = {}) {
|
|
711
|
+
if (process instanceof UserProcess) {
|
|
712
|
+
process = process.toJSON();
|
|
713
|
+
}
|
|
714
|
+
else if (process instanceof BuilderNode) {
|
|
715
|
+
process.result = true;
|
|
716
|
+
process = process.parent.toJSON();
|
|
717
|
+
}
|
|
718
|
+
else if (Utils.isObject(process) && !Utils.isObject(process.process_graph)) {
|
|
719
|
+
process = {
|
|
720
|
+
process_graph: process
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
return Object.assign({}, additional, {process: process});
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
/**
|
|
727
|
+
* Validates a user-defined process at the back-end.
|
|
728
|
+
*
|
|
729
|
+
* @async
|
|
730
|
+
* @param {Process} process - User-defined process to validate.
|
|
731
|
+
* @returns {Promise<Array.<ApiError>>} errors - A list of API compatible error objects. A valid process returns an empty list.
|
|
732
|
+
* @throws {Error}
|
|
733
|
+
*/
|
|
734
|
+
async validateProcess(process) {
|
|
735
|
+
let response = await this._post('/validation', this._normalizeUserProcess(process).process);
|
|
736
|
+
if (Array.isArray(response.data.errors)) {
|
|
737
|
+
return response.data.errors;
|
|
738
|
+
}
|
|
739
|
+
else {
|
|
740
|
+
throw new Error("Invalid validation response received.");
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Lists all user-defined processes of the authenticated user.
|
|
746
|
+
*
|
|
747
|
+
* @async
|
|
748
|
+
* @param {Array.<UserProcess>} [oldProcesses=[]] - A list of existing user-defined processes to update.
|
|
749
|
+
* @returns {Promise<ResponseArray.<UserProcess>>} A list of user-defined processes.
|
|
750
|
+
* @throws {Error}
|
|
751
|
+
*/
|
|
752
|
+
async listUserProcesses(oldProcesses = []) {
|
|
753
|
+
let response = await this._get('/process_graphs');
|
|
754
|
+
|
|
755
|
+
if (!Utils.isObject(response.data) || !Array.isArray(response.data.processes)) {
|
|
756
|
+
throw new Error('Invalid response received for processes');
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Remove existing processes from cache
|
|
760
|
+
this.processes.remove(null, 'user');
|
|
761
|
+
|
|
762
|
+
// Update existing processes if needed
|
|
763
|
+
let newProcesses = response.data.processes.map(newProcess => {
|
|
764
|
+
let process = oldProcesses.find(oldProcess => oldProcess.id === newProcess.id);
|
|
765
|
+
if (!process) {
|
|
766
|
+
process = new UserProcess(this, newProcess.id);
|
|
767
|
+
}
|
|
768
|
+
return process.setAll(newProcess);
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
// Store plain JS variant (i.e. no Job objects involved) of processes in cache
|
|
772
|
+
let jsonProcesses = oldProcesses.length > 0 ? newProcesses.map(p => p.toJSON()) : response.data.processes;
|
|
773
|
+
this.processes.addAll(jsonProcesses, 'user');
|
|
774
|
+
|
|
775
|
+
return this._toResponseArray(newProcesses, response.data);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Creates a new stored user-defined process at the back-end.
|
|
780
|
+
*
|
|
781
|
+
* @async
|
|
782
|
+
* @param {string} id - Unique identifier for the process.
|
|
783
|
+
* @param {Process} process - A user-defined process.
|
|
784
|
+
* @returns {Promise<UserProcess>} The new user-defined process.
|
|
785
|
+
* @throws {Error}
|
|
786
|
+
*/
|
|
787
|
+
async setUserProcess(id, process) {
|
|
788
|
+
let pg = new UserProcess(this, id);
|
|
789
|
+
return await pg.replaceUserProcess(process);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Get all information about a user-defined process.
|
|
794
|
+
*
|
|
795
|
+
* @async
|
|
796
|
+
* @param {string} id - Identifier of the user-defined process.
|
|
797
|
+
* @returns {Promise<UserProcess>} The user-defined process.
|
|
798
|
+
* @throws {Error}
|
|
799
|
+
*/
|
|
800
|
+
async getUserProcess(id) {
|
|
801
|
+
let pg = new UserProcess(this, id);
|
|
802
|
+
return await pg.describeUserProcess();
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* Executes a process synchronously and returns the result as the response.
|
|
807
|
+
*
|
|
808
|
+
* Please note that requests can take a very long time of several minutes or even hours.
|
|
809
|
+
*
|
|
810
|
+
* @async
|
|
811
|
+
* @param {Process} process - A user-defined process.
|
|
812
|
+
* @param {?string} [plan=null] - The billing plan to use for this computation.
|
|
813
|
+
* @param {?number} [budget=null] - The maximum budget allowed to spend for this computation.
|
|
814
|
+
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the processing request.
|
|
815
|
+
* @param {object.<string, *>} [additional={}] - Other parameters to pass for the batch job, e.g. `log_level`.
|
|
816
|
+
* @returns {Promise<SyncResult>} - An object with the data and some metadata.
|
|
817
|
+
*/
|
|
818
|
+
async computeResult(process, plan = null, budget = null, abortController = null, additional = {}) {
|
|
819
|
+
let requestBody = this._normalizeUserProcess(
|
|
820
|
+
process,
|
|
821
|
+
Object.assign({}, additional, {
|
|
822
|
+
plan: plan,
|
|
823
|
+
budget: budget
|
|
824
|
+
})
|
|
825
|
+
);
|
|
826
|
+
let response = await this._post('/result', requestBody, Environment.getResponseType(), abortController);
|
|
827
|
+
let syncResult = {
|
|
828
|
+
data: response.data,
|
|
829
|
+
costs: null,
|
|
830
|
+
type: null,
|
|
831
|
+
logs: []
|
|
832
|
+
};
|
|
833
|
+
|
|
834
|
+
if (typeof response.headers['openeo-costs'] === 'number') {
|
|
835
|
+
syncResult.costs = response.headers['openeo-costs'];
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
if (typeof response.headers['content-type'] === 'string') {
|
|
839
|
+
syncResult.type = response.headers['content-type'];
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
let links = Array.isArray(response.headers.link) ? response.headers.link : [response.headers.link];
|
|
843
|
+
for(let link of links) {
|
|
844
|
+
if (typeof link !== 'string') {
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
let logs = link.match(/^<([^>]+)>;\s?rel="monitor"/i);
|
|
848
|
+
if (Array.isArray(logs) && logs.length > 1) {
|
|
849
|
+
try {
|
|
850
|
+
let logsResponse = await this._get(logs[1]);
|
|
851
|
+
if (Utils.isObject(logsResponse.data) && Array.isArray(logsResponse.data.logs)) {
|
|
852
|
+
syncResult.logs = logsResponse.data.logs;
|
|
853
|
+
}
|
|
854
|
+
} catch(error) {
|
|
855
|
+
console.warn(error);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
return syncResult;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Executes a process synchronously and downloads to result the given path.
|
|
865
|
+
*
|
|
866
|
+
* Please note that requests can take a very long time of several minutes or even hours.
|
|
867
|
+
*
|
|
868
|
+
* This method has different behaviour depending on the environment.
|
|
869
|
+
* If a NodeJs environment, writes the downloaded file to the target location on the file system.
|
|
870
|
+
* In a browser environment, offers the file for downloading using the specified name (folders are not supported).
|
|
871
|
+
*
|
|
872
|
+
* @async
|
|
873
|
+
* @param {Process} process - A user-defined process.
|
|
874
|
+
* @param {string} targetPath - The target, see method description for details.
|
|
875
|
+
* @param {?string} [plan=null] - The billing plan to use for this computation.
|
|
876
|
+
* @param {?number} [budget=null] - The maximum budget allowed to spend for this computation.
|
|
877
|
+
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the processing request.
|
|
878
|
+
* @throws {Error}
|
|
879
|
+
*/
|
|
880
|
+
async downloadResult(process, targetPath, plan = null, budget = null, abortController = null) {
|
|
881
|
+
let response = await this.computeResult(process, plan, budget, abortController);
|
|
882
|
+
// @ts-ignore
|
|
883
|
+
await Environment.saveToFile(response.data, targetPath);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* Lists all batch jobs of the authenticated user.
|
|
888
|
+
*
|
|
889
|
+
* @async
|
|
890
|
+
* @param {Array.<Job>} [oldJobs=[]] - A list of existing jobs to update.
|
|
891
|
+
* @returns {Promise<ResponseArray.<Job>>} A list of jobs.
|
|
892
|
+
* @throws {Error}
|
|
893
|
+
*/
|
|
894
|
+
async listJobs(oldJobs = []) {
|
|
895
|
+
let response = await this._get('/jobs');
|
|
896
|
+
let newJobs = response.data.jobs.map(newJob => {
|
|
897
|
+
let job = oldJobs.find(oldJob => oldJob.id === newJob.id);
|
|
898
|
+
if (!job) {
|
|
899
|
+
job = new Job(this, newJob.id);
|
|
900
|
+
}
|
|
901
|
+
return job.setAll(newJob);
|
|
902
|
+
});
|
|
903
|
+
return this._toResponseArray(newJobs, response.data);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Creates a new batch job at the back-end.
|
|
908
|
+
*
|
|
909
|
+
* @async
|
|
910
|
+
* @param {Process} process - A user-define process to execute.
|
|
911
|
+
* @param {?string} [title=null] - A title for the batch job.
|
|
912
|
+
* @param {?string} [description=null] - A description for the batch job.
|
|
913
|
+
* @param {?string} [plan=null] - The billing plan to use for this batch job.
|
|
914
|
+
* @param {?number} [budget=null] - The maximum budget allowed to spend for this batch job.
|
|
915
|
+
* @param {object.<string, *>} [additional={}] - Other parameters to pass for the batch job, e.g. `log_level`.
|
|
916
|
+
* @returns {Promise<Job>} The stored batch job.
|
|
917
|
+
* @throws {Error}
|
|
918
|
+
*/
|
|
919
|
+
async createJob(process, title = null, description = null, plan = null, budget = null, additional = {}) {
|
|
920
|
+
additional = Object.assign({}, additional, {
|
|
921
|
+
title: title,
|
|
922
|
+
description: description,
|
|
923
|
+
plan: plan,
|
|
924
|
+
budget: budget
|
|
925
|
+
});
|
|
926
|
+
let requestBody = this._normalizeUserProcess(process, additional);
|
|
927
|
+
let response = await this._post('/jobs', requestBody);
|
|
928
|
+
if (typeof response.headers['openeo-identifier'] !== 'string') {
|
|
929
|
+
throw new Error("Response did not contain a Job ID. Job has likely been created, but may not show up yet.");
|
|
930
|
+
}
|
|
931
|
+
let job = new Job(this, response.headers['openeo-identifier']).setAll(requestBody);
|
|
932
|
+
if (this.capabilities().hasFeature('describeJob')) {
|
|
933
|
+
return await job.describeJob();
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
return job;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Get all information about a batch job.
|
|
942
|
+
*
|
|
943
|
+
* @async
|
|
944
|
+
* @param {string} id - Batch Job ID.
|
|
945
|
+
* @returns {Promise<Job>} The batch job.
|
|
946
|
+
* @throws {Error}
|
|
947
|
+
*/
|
|
948
|
+
async getJob(id) {
|
|
949
|
+
let job = new Job(this, id);
|
|
950
|
+
return await job.describeJob();
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
/**
|
|
954
|
+
* Lists all secondary web services of the authenticated user.
|
|
955
|
+
*
|
|
956
|
+
* @async
|
|
957
|
+
* @param {Array.<Service>} [oldServices=[]] - A list of existing services to update.
|
|
958
|
+
* @returns {Promise<ResponseArray.<Job>>} A list of services.
|
|
959
|
+
* @throws {Error}
|
|
960
|
+
*/
|
|
961
|
+
async listServices(oldServices = []) {
|
|
962
|
+
let response = await this._get('/services');
|
|
963
|
+
let newServices = response.data.services.map(newService => {
|
|
964
|
+
let service = oldServices.find(oldService => oldService.id === newService.id);
|
|
965
|
+
if (!service) {
|
|
966
|
+
service = new Service(this, newService.id);
|
|
967
|
+
}
|
|
968
|
+
return service.setAll(newService);
|
|
969
|
+
});
|
|
970
|
+
return this._toResponseArray(newServices, response.data);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Creates a new secondary web service at the back-end.
|
|
975
|
+
*
|
|
976
|
+
* @async
|
|
977
|
+
* @param {Process} process - A user-defined process.
|
|
978
|
+
* @param {string} type - The type of service to be created (see `Connection.listServiceTypes()`).
|
|
979
|
+
* @param {?string} [title=null] - A title for the service.
|
|
980
|
+
* @param {?string} [description=null] - A description for the service.
|
|
981
|
+
* @param {boolean} [enabled=true] - Enable the service (`true`, default) or not (`false`).
|
|
982
|
+
* @param {object.<string, *>} [configuration={}] - Configuration parameters to pass to the service.
|
|
983
|
+
* @param {?string} [plan=null] - The billing plan to use for this service.
|
|
984
|
+
* @param {?number} [budget=null] - The maximum budget allowed to spend for this service.
|
|
985
|
+
* @param {object.<string, *>} [additional={}] - Other parameters to pass for the service, e.g. `log_level`.
|
|
986
|
+
* @returns {Promise<Service>} The stored service.
|
|
987
|
+
* @throws {Error}
|
|
988
|
+
*/
|
|
989
|
+
async createService(process, type, title = null, description = null, enabled = true, configuration = {}, plan = null, budget = null, additional = {}) {
|
|
990
|
+
let requestBody = this._normalizeUserProcess(process, Object.assign({
|
|
991
|
+
title: title,
|
|
992
|
+
description: description,
|
|
993
|
+
type: type,
|
|
994
|
+
enabled: enabled,
|
|
995
|
+
configuration: configuration,
|
|
996
|
+
plan: plan,
|
|
997
|
+
budget: budget
|
|
998
|
+
}, additional));
|
|
999
|
+
let response = await this._post('/services', requestBody);
|
|
1000
|
+
if (typeof response.headers['openeo-identifier'] !== 'string') {
|
|
1001
|
+
throw new Error("Response did not contain a Service ID. Service has likely been created, but may not show up yet.");
|
|
1002
|
+
}
|
|
1003
|
+
let service = new Service(this, response.headers['openeo-identifier']).setAll(requestBody);
|
|
1004
|
+
if (this.capabilities().hasFeature('describeService')) {
|
|
1005
|
+
return service.describeService();
|
|
1006
|
+
}
|
|
1007
|
+
else {
|
|
1008
|
+
return service;
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* Get all information about a secondary web service.
|
|
1014
|
+
*
|
|
1015
|
+
* @async
|
|
1016
|
+
* @param {string} id - Service ID.
|
|
1017
|
+
* @returns {Promise<Service>} The service.
|
|
1018
|
+
* @throws {Error}
|
|
1019
|
+
*/
|
|
1020
|
+
async getService(id) {
|
|
1021
|
+
let service = new Service(this, id);
|
|
1022
|
+
return await service.describeService();
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* Adds additional response details to the array.
|
|
1027
|
+
*
|
|
1028
|
+
* Adds links and federation:missing.
|
|
1029
|
+
*
|
|
1030
|
+
* @protected
|
|
1031
|
+
* @param {Array.<*>} arr
|
|
1032
|
+
* @param {object.<string, *>} response
|
|
1033
|
+
* @returns {ResponseArray}
|
|
1034
|
+
*/
|
|
1035
|
+
_toResponseArray(arr, response) {
|
|
1036
|
+
arr.links = Array.isArray(response.links) ? response.links : [];
|
|
1037
|
+
arr['federation:missing'] = Array.isArray(response['federation:missing']) ? response['federation:missing'] : [];
|
|
1038
|
+
return arr;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
/**
|
|
1042
|
+
* Get the a link with the given rel type.
|
|
1043
|
+
*
|
|
1044
|
+
* @protected
|
|
1045
|
+
* @param {Array.<Link>} links - An array of links.
|
|
1046
|
+
* @param {string|Array.<string>} rel - Relation type(s) to find.
|
|
1047
|
+
* @returns {string | null}
|
|
1048
|
+
* @throws {Error}
|
|
1049
|
+
*/
|
|
1050
|
+
_getLinkHref(links, rel) {
|
|
1051
|
+
if (!Array.isArray(rel)) {
|
|
1052
|
+
rel = [rel];
|
|
1053
|
+
}
|
|
1054
|
+
if (Array.isArray(links)) {
|
|
1055
|
+
let link = links.find(l => Utils.isObject(l) && rel.includes(l.rel) && typeof l.href === 'string');
|
|
1056
|
+
if (link) {
|
|
1057
|
+
return link.href;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Makes all links in the list absolute.
|
|
1065
|
+
*
|
|
1066
|
+
* @param {Array.<Link>} links - An array of links.
|
|
1067
|
+
* @param {?string|AxiosResponse} [base=null] - The base url to use for relative links, or an response to derive the url from.
|
|
1068
|
+
* @returns {Array.<Link>}
|
|
1069
|
+
*/
|
|
1070
|
+
makeLinksAbsolute(links, base = null) {
|
|
1071
|
+
if (!Array.isArray(links)) {
|
|
1072
|
+
return links;
|
|
1073
|
+
}
|
|
1074
|
+
let baseUrl = null;
|
|
1075
|
+
if (Utils.isObject(base) && base.headers && base.config && base.request) { // AxiosResponse
|
|
1076
|
+
baseUrl = base.config.baseURL + base.config.url;
|
|
1077
|
+
}
|
|
1078
|
+
else if (typeof base !== 'string') {
|
|
1079
|
+
baseUrl = this._getLinkHref(links, 'self');
|
|
1080
|
+
}
|
|
1081
|
+
else {
|
|
1082
|
+
baseUrl = base;
|
|
1083
|
+
}
|
|
1084
|
+
if (!baseUrl) {
|
|
1085
|
+
return links;
|
|
1086
|
+
}
|
|
1087
|
+
return links.map((link) => {
|
|
1088
|
+
if (!Utils.isObject(link) || typeof link.href !== 'string') {
|
|
1089
|
+
return link;
|
|
1090
|
+
}
|
|
1091
|
+
try {
|
|
1092
|
+
let url = new URL(link.href, baseUrl);
|
|
1093
|
+
return Object.assign({}, link, {href: url.toString()});
|
|
1094
|
+
} catch(error) {
|
|
1095
|
+
return link;
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Sends a GET request.
|
|
1102
|
+
*
|
|
1103
|
+
* @protected
|
|
1104
|
+
* @async
|
|
1105
|
+
* @param {string} path
|
|
1106
|
+
* @param {object.<string, *>} query
|
|
1107
|
+
* @param {string} responseType - Response type according to axios, defaults to `json`.
|
|
1108
|
+
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the request.
|
|
1109
|
+
* @returns {Promise<AxiosResponse>}
|
|
1110
|
+
* @throws {Error}
|
|
1111
|
+
* @see https://github.com/axios/axios#request-config
|
|
1112
|
+
*/
|
|
1113
|
+
async _get(path, query, responseType, abortController = null) {
|
|
1114
|
+
return await this._send({
|
|
1115
|
+
method: 'get',
|
|
1116
|
+
responseType: responseType,
|
|
1117
|
+
url: path,
|
|
1118
|
+
// Timeout for capabilities requests as they are used for a quick first discovery to check whether the server is a openEO back-end.
|
|
1119
|
+
// Without timeout connecting with a wrong server url may take forever.
|
|
1120
|
+
timeout: path === '/' ? 5000 : 0,
|
|
1121
|
+
params: query
|
|
1122
|
+
}, abortController);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Sends a POST request.
|
|
1127
|
+
*
|
|
1128
|
+
* @protected
|
|
1129
|
+
* @async
|
|
1130
|
+
* @param {string} path
|
|
1131
|
+
* @param {*} body
|
|
1132
|
+
* @param {string} responseType - Response type according to axios, defaults to `json`.
|
|
1133
|
+
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the request.
|
|
1134
|
+
* @returns {Promise<AxiosResponse>}
|
|
1135
|
+
* @throws {Error}
|
|
1136
|
+
* @see https://github.com/axios/axios#request-config
|
|
1137
|
+
*/
|
|
1138
|
+
async _post(path, body, responseType, abortController = null) {
|
|
1139
|
+
let options = {
|
|
1140
|
+
method: 'post',
|
|
1141
|
+
responseType: responseType,
|
|
1142
|
+
url: path,
|
|
1143
|
+
data: body
|
|
1144
|
+
};
|
|
1145
|
+
return await this._send(options, abortController);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
/**
|
|
1149
|
+
* Sends a PUT request.
|
|
1150
|
+
*
|
|
1151
|
+
* @protected
|
|
1152
|
+
* @async
|
|
1153
|
+
* @param {string} path
|
|
1154
|
+
* @param {*} body
|
|
1155
|
+
* @returns {Promise<AxiosResponse>}
|
|
1156
|
+
* @throws {Error}
|
|
1157
|
+
*/
|
|
1158
|
+
async _put(path, body) {
|
|
1159
|
+
return await this._send({
|
|
1160
|
+
method: 'put',
|
|
1161
|
+
url: path,
|
|
1162
|
+
data: body
|
|
1163
|
+
});
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/**
|
|
1167
|
+
* Sends a PATCH request.
|
|
1168
|
+
*
|
|
1169
|
+
* @protected
|
|
1170
|
+
* @async
|
|
1171
|
+
* @param {string} path
|
|
1172
|
+
* @param {*} body
|
|
1173
|
+
* @returns {Promise<AxiosResponse>}
|
|
1174
|
+
* @throws {Error}
|
|
1175
|
+
*/
|
|
1176
|
+
async _patch(path, body) {
|
|
1177
|
+
return await this._send({
|
|
1178
|
+
method: 'patch',
|
|
1179
|
+
url: path,
|
|
1180
|
+
data: body
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/**
|
|
1185
|
+
* Sends a DELETE request.
|
|
1186
|
+
*
|
|
1187
|
+
* @protected
|
|
1188
|
+
* @async
|
|
1189
|
+
* @param {string} path
|
|
1190
|
+
* @returns {Promise<AxiosResponse>}
|
|
1191
|
+
* @throws {Error}
|
|
1192
|
+
*/
|
|
1193
|
+
async _delete(path) {
|
|
1194
|
+
return await this._send({
|
|
1195
|
+
method: 'delete',
|
|
1196
|
+
url: path
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
/**
|
|
1201
|
+
* Downloads data from a URL.
|
|
1202
|
+
*
|
|
1203
|
+
* May include authorization details where required.
|
|
1204
|
+
*
|
|
1205
|
+
* @param {string} url - An absolute or relative URL to download data from.
|
|
1206
|
+
* @param {boolean} authorize - Send authorization details (`true`) or not (`false`).
|
|
1207
|
+
* @returns {Promise<Stream.Readable|Blob>} - Returns the data as `Stream` in NodeJS environments or as `Blob` in browsers
|
|
1208
|
+
* @throws {Error}
|
|
1209
|
+
*/
|
|
1210
|
+
async download(url, authorize) {
|
|
1211
|
+
let result = await this._send({
|
|
1212
|
+
method: 'get',
|
|
1213
|
+
responseType: Environment.getResponseType(),
|
|
1214
|
+
url: url,
|
|
1215
|
+
authorization: authorize
|
|
1216
|
+
});
|
|
1217
|
+
return result.data;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
/**
|
|
1221
|
+
* Get the authorization header for requests.
|
|
1222
|
+
*
|
|
1223
|
+
* @protected
|
|
1224
|
+
* @returns {object.<string, string>}
|
|
1225
|
+
*/
|
|
1226
|
+
_getAuthHeaders() {
|
|
1227
|
+
const headers = {};
|
|
1228
|
+
if (this.isAuthenticated()) {
|
|
1229
|
+
headers.Authorization = 'Bearer ' + this.authProvider.getToken();
|
|
1230
|
+
}
|
|
1231
|
+
return headers;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
/**
|
|
1235
|
+
* Sends a HTTP request.
|
|
1236
|
+
*
|
|
1237
|
+
* Options mostly conform to axios,
|
|
1238
|
+
* see {@link https://github.com/axios/axios#request-config}.
|
|
1239
|
+
*
|
|
1240
|
+
* Automatically sets a baseUrl and the authorization information.
|
|
1241
|
+
* Default responseType is `json`.
|
|
1242
|
+
*
|
|
1243
|
+
* Tries to smoothly handle error responses by providing an object for all response types,
|
|
1244
|
+
* instead of Streams or Blobs for non-JSON response types.
|
|
1245
|
+
*
|
|
1246
|
+
* @protected
|
|
1247
|
+
* @async
|
|
1248
|
+
* @param {object.<string, *>} options
|
|
1249
|
+
* @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the request.
|
|
1250
|
+
* @returns {Promise<AxiosResponse>}
|
|
1251
|
+
* @throws {Error}
|
|
1252
|
+
* @see https://github.com/axios/axios
|
|
1253
|
+
*/
|
|
1254
|
+
async _send(options, abortController = null) {
|
|
1255
|
+
options.baseURL = this.baseUrl;
|
|
1256
|
+
if (typeof options.authorization === 'undefined' || options.authorization === true) {
|
|
1257
|
+
if (!options.headers) {
|
|
1258
|
+
options.headers = {};
|
|
1259
|
+
}
|
|
1260
|
+
Object.assign(options.headers, this._getAuthHeaders());
|
|
1261
|
+
}
|
|
1262
|
+
if (!options.responseType) {
|
|
1263
|
+
options.responseType = 'json';
|
|
1264
|
+
}
|
|
1265
|
+
if (abortController) {
|
|
1266
|
+
options.signal = abortController.signal;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
try {
|
|
1270
|
+
let response = await axios(options);
|
|
1271
|
+
let capabilities = this.capabilities();
|
|
1272
|
+
if (capabilities) {
|
|
1273
|
+
response = capabilities.migrate(response);
|
|
1274
|
+
}
|
|
1275
|
+
return response;
|
|
1276
|
+
} catch(error) {
|
|
1277
|
+
if (axios.isCancel(error)) {
|
|
1278
|
+
throw error;
|
|
1279
|
+
}
|
|
1280
|
+
const checkContentType = type => (typeof type === 'string' && type.indexOf('/json') !== -1);
|
|
1281
|
+
const enrichError = (origin, response) => {
|
|
1282
|
+
if (typeof response.message === 'string') {
|
|
1283
|
+
origin.message = response.message;
|
|
1284
|
+
}
|
|
1285
|
+
origin.code = typeof response.code === 'string' ? response.code : "";
|
|
1286
|
+
origin.id = response.id;
|
|
1287
|
+
origin.links = Array.isArray(response.links) ? response.links : [];
|
|
1288
|
+
return origin;
|
|
1289
|
+
};
|
|
1290
|
+
if (Utils.isObject(error.response) && Utils.isObject(error.response.data) && (checkContentType(error.response.data.type) || (Utils.isObject(error.response.headers) && checkContentType(error.response.headers['content-type'])))) {
|
|
1291
|
+
// JSON error responses are Blobs and streams if responseType is set as such, so convert to JSON if required.
|
|
1292
|
+
// See: https://github.com/axios/axios/issues/815
|
|
1293
|
+
if (options.responseType === Environment.getResponseType()) {
|
|
1294
|
+
try {
|
|
1295
|
+
let errorResponse = await Environment.handleErrorResponse(error);
|
|
1296
|
+
throw enrichError(error, errorResponse);
|
|
1297
|
+
} catch (error2) {
|
|
1298
|
+
console.error(error2);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
else {
|
|
1302
|
+
throw enrichError(error, error.response.data);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
throw error;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
module.exports = Connection;
|