@openeo/js-client 2.6.0 → 2.7.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/README.md +3 -3
- package/openeo.d.ts +203 -24
- package/openeo.js +1851 -1187
- package/openeo.min.js +1 -1
- package/package.json +2 -2
- package/src/capabilities.js +9 -0
- package/src/connection.js +159 -179
- package/src/env.js +13 -3
- package/src/logs.js +36 -0
- package/src/openeo.js +1 -1
- package/src/pages.js +349 -0
- package/src/typedefs.js +30 -2
package/src/connection.js
CHANGED
|
@@ -17,6 +17,7 @@ const Service = require('./service');
|
|
|
17
17
|
|
|
18
18
|
const Builder = require('./builder/builder');
|
|
19
19
|
const BuilderNode = require('./builder/node');
|
|
20
|
+
const { CollectionPages, ItemPages, JobPages, ProcessPages, ServicePages, UserFilePages } = require('./pages');
|
|
20
21
|
|
|
21
22
|
const CONFORMANCE_RELS = [
|
|
22
23
|
'conformance',
|
|
@@ -106,14 +107,14 @@ class Connection {
|
|
|
106
107
|
* @throws {Error}
|
|
107
108
|
*/
|
|
108
109
|
async init() {
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
const response = await this._get('/');
|
|
111
|
+
const data = Object.assign({}, response.data);
|
|
111
112
|
data.links = this.makeLinksAbsolute(data.links, response);
|
|
112
113
|
|
|
113
114
|
if (!Array.isArray(data.conformsTo) && Array.isArray(data.links)) {
|
|
114
|
-
|
|
115
|
+
const conformanceLink = this._getLinkHref(data.links, CONFORMANCE_RELS);
|
|
115
116
|
if (conformanceLink) {
|
|
116
|
-
|
|
117
|
+
const response2 = await this._get(conformanceLink);
|
|
117
118
|
if (Utils.isObject(response2.data) && Array.isArray(response2.data.conformsTo)) {
|
|
118
119
|
data.conformsTo = response2.data.conformsTo;
|
|
119
120
|
}
|
|
@@ -135,10 +136,10 @@ class Connection {
|
|
|
135
136
|
if (this.processes.count() === 0) {
|
|
136
137
|
return;
|
|
137
138
|
}
|
|
138
|
-
|
|
139
|
+
const promises = this.processes.namespaces().map(namespace => {
|
|
139
140
|
let fn = () => Promise.resolve();
|
|
140
141
|
if (namespace === 'user') {
|
|
141
|
-
|
|
142
|
+
const userProcesses = this.processes.namespace('user');
|
|
142
143
|
if (!this.isAuthenticated()) {
|
|
143
144
|
fn = () => (this.processes.remove(null, 'user') ? Promise.resolve() : Promise.reject(new Error("Can't clear user processes")));
|
|
144
145
|
}
|
|
@@ -189,7 +190,7 @@ class Connection {
|
|
|
189
190
|
* @throws {Error}
|
|
190
191
|
*/
|
|
191
192
|
async listFileTypes() {
|
|
192
|
-
|
|
193
|
+
const response = await this._get('/file_formats');
|
|
193
194
|
return new FileTypes(response.data);
|
|
194
195
|
}
|
|
195
196
|
|
|
@@ -201,7 +202,7 @@ class Connection {
|
|
|
201
202
|
* @throws {Error}
|
|
202
203
|
*/
|
|
203
204
|
async listServiceTypes() {
|
|
204
|
-
|
|
205
|
+
const response = await this._get('/service_types');
|
|
205
206
|
return response.data;
|
|
206
207
|
}
|
|
207
208
|
|
|
@@ -213,7 +214,7 @@ class Connection {
|
|
|
213
214
|
* @throws {Error}
|
|
214
215
|
*/
|
|
215
216
|
async listUdfRuntimes() {
|
|
216
|
-
|
|
217
|
+
const response = await this._get('/udf_runtimes');
|
|
217
218
|
return response.data;
|
|
218
219
|
}
|
|
219
220
|
|
|
@@ -221,22 +222,27 @@ class Connection {
|
|
|
221
222
|
* List all collections available on the back-end.
|
|
222
223
|
*
|
|
223
224
|
* The collections returned always comply to the latest STAC version (currently 1.0.0).
|
|
225
|
+
* This function adds a self link to the response if not present.
|
|
224
226
|
*
|
|
225
227
|
* @async
|
|
226
228
|
* @returns {Promise<Collections>} A response compatible to the API specification.
|
|
227
229
|
* @throws {Error}
|
|
228
230
|
*/
|
|
229
231
|
async listCollections() {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
232
|
+
const pages = this.paginateCollections(null);
|
|
233
|
+
return await pages.nextPage([], false);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Paginate through the collections available on the back-end.
|
|
238
|
+
*
|
|
239
|
+
* The collections returned always comply to the latest STAC version (currently 1.0.0).
|
|
240
|
+
*
|
|
241
|
+
* @param {?number} [limit=50] - The number of collections per request/page as integer. If `null`, requests all collections.
|
|
242
|
+
* @returns {CollectionPages} A paged list of collections.
|
|
243
|
+
*/
|
|
244
|
+
paginateCollections(limit = 50) {
|
|
245
|
+
return new CollectionPages(this, limit);
|
|
240
246
|
}
|
|
241
247
|
|
|
242
248
|
/**
|
|
@@ -250,7 +256,7 @@ class Connection {
|
|
|
250
256
|
* @throws {Error}
|
|
251
257
|
*/
|
|
252
258
|
async describeCollection(collectionId) {
|
|
253
|
-
|
|
259
|
+
const response = await this._get('/collections/' + collectionId);
|
|
254
260
|
if (response.data.stac_version) {
|
|
255
261
|
return StacMigrate.collection(response.data);
|
|
256
262
|
}
|
|
@@ -260,13 +266,12 @@ class Connection {
|
|
|
260
266
|
}
|
|
261
267
|
|
|
262
268
|
/**
|
|
263
|
-
*
|
|
269
|
+
* Paginate through items for a specific collection.
|
|
270
|
+
*
|
|
264
271
|
* May not be available for all collections.
|
|
265
272
|
*
|
|
266
273
|
* The items returned always comply to the latest STAC version (currently 1.0.0).
|
|
267
274
|
*
|
|
268
|
-
* This is an experimental API and is subject to change.
|
|
269
|
-
*
|
|
270
275
|
* @async
|
|
271
276
|
* @param {string} collectionId - Collection ID to request items for.
|
|
272
277
|
* @param {?Array.<number>} [spatialExtent=null] - Limits the items to the given bounding box in WGS84:
|
|
@@ -279,51 +284,31 @@ class Connection {
|
|
|
279
284
|
* each must be either an RFC 3339 compatible string or a Date object.
|
|
280
285
|
* Also supports open intervals by setting one of the boundaries to `null`, but never both.
|
|
281
286
|
* @param {?number} [limit=null] - The amount of items per request/page as integer. If `null` (default), the back-end decides.
|
|
282
|
-
* @
|
|
287
|
+
* @returns {Promise<ItemPages>} A response compatible to the API specification.
|
|
283
288
|
* @throws {Error}
|
|
284
289
|
*/
|
|
285
|
-
|
|
286
|
-
let
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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);
|
|
290
|
+
listCollectionItems(collectionId, spatialExtent = null, temporalExtent = null, limit = null) {
|
|
291
|
+
let params = {};
|
|
292
|
+
if (Array.isArray(spatialExtent)) {
|
|
293
|
+
params.bbox = spatialExtent.join(',');
|
|
294
|
+
}
|
|
295
|
+
if (Array.isArray(temporalExtent)) {
|
|
296
|
+
params.datetime = temporalExtent
|
|
297
|
+
.map(e => {
|
|
298
|
+
if (e instanceof Date) {
|
|
299
|
+
return e.toISOString();
|
|
317
300
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
let links = this.makeLinksAbsolute(response.data.links);
|
|
325
|
-
nextUrl = this._getLinkHref(links, 'next');
|
|
301
|
+
else if (typeof e === 'string') {
|
|
302
|
+
return e;
|
|
303
|
+
}
|
|
304
|
+
return '..'; // Open date range
|
|
305
|
+
})
|
|
306
|
+
.join('/');
|
|
326
307
|
}
|
|
308
|
+
if (limit > 0) {
|
|
309
|
+
params.limit = limit;
|
|
310
|
+
}
|
|
311
|
+
return new ItemPages(this, collectionId, params, limit);
|
|
327
312
|
}
|
|
328
313
|
|
|
329
314
|
/**
|
|
@@ -346,7 +331,7 @@ class Connection {
|
|
|
346
331
|
}
|
|
347
332
|
|
|
348
333
|
/**
|
|
349
|
-
* List processes available on the back-end.
|
|
334
|
+
* List all processes available on the back-end.
|
|
350
335
|
*
|
|
351
336
|
* Requests pre-defined processes by default.
|
|
352
337
|
* Set the namespace parameter to request processes from a specific namespace.
|
|
@@ -354,27 +339,33 @@ class Connection {
|
|
|
354
339
|
* Note: The list of namespaces can be retrieved by calling `listProcesses` without a namespace given.
|
|
355
340
|
* The namespaces are then listed in the property `namespaces`.
|
|
356
341
|
*
|
|
342
|
+
* This function adds a self link to the response if not present.
|
|
343
|
+
*
|
|
357
344
|
* @async
|
|
358
345
|
* @param {?string} [namespace=null] - Namespace of the processes (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
|
|
359
346
|
* @returns {Promise<Processes>} - A response compatible to the API specification.
|
|
360
347
|
* @throws {Error}
|
|
361
348
|
*/
|
|
362
349
|
async listProcesses(namespace = null) {
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
}
|
|
350
|
+
const pages = this.paginateProcesses(namespace);
|
|
351
|
+
return await pages.nextPage([], false);
|
|
352
|
+
}
|
|
372
353
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
354
|
+
/**
|
|
355
|
+
* Paginate through the processes available on the back-end.
|
|
356
|
+
*
|
|
357
|
+
* Requests pre-defined processes by default.
|
|
358
|
+
* Set the namespace parameter to request processes from a specific namespace.
|
|
359
|
+
*
|
|
360
|
+
* Note: The list of namespaces can be retrieved by calling `listProcesses` without a namespace given.
|
|
361
|
+
* The namespaces are then listed in the property `namespaces`.
|
|
362
|
+
*
|
|
363
|
+
* @param {?string} [namespace=null] - Namespace of the processes (default to `null`, i.e. pre-defined processes). EXPERIMENTAL!
|
|
364
|
+
* @param {?number} [limit=50] - The number of processes per request/page as integer. If `null`, requests all processes.
|
|
365
|
+
* @returns {ProcessPages} A paged list of processes.
|
|
366
|
+
*/
|
|
367
|
+
paginateProcesses(namespace = null, limit = 50) {
|
|
368
|
+
return new ProcessPages(this, limit, namespace);
|
|
378
369
|
}
|
|
379
370
|
|
|
380
371
|
/**
|
|
@@ -395,7 +386,7 @@ class Connection {
|
|
|
395
386
|
await this.listProcesses();
|
|
396
387
|
}
|
|
397
388
|
else {
|
|
398
|
-
|
|
389
|
+
const response = await this._get(`/processes/${this.normalizeNamespace(namespace)}/${processId}`);
|
|
399
390
|
if (!Utils.isObject(response.data) || typeof response.data.id !== 'string') {
|
|
400
391
|
throw new Error('Invalid response received for process');
|
|
401
392
|
}
|
|
@@ -432,15 +423,15 @@ class Connection {
|
|
|
432
423
|
}
|
|
433
424
|
|
|
434
425
|
this.authProviderList = [];
|
|
435
|
-
|
|
426
|
+
const cap = this.capabilities();
|
|
436
427
|
|
|
437
428
|
// Add OIDC providers
|
|
438
429
|
if (cap.hasFeature('authenticateOIDC')) {
|
|
439
|
-
|
|
440
|
-
|
|
430
|
+
const res = await this._get('/credentials/oidc');
|
|
431
|
+
const oidcFactory = this.getOidcProviderFactory();
|
|
441
432
|
if (Utils.isObject(res.data) && Array.isArray(res.data.providers) && typeof oidcFactory === 'function') {
|
|
442
433
|
for(let i in res.data.providers) {
|
|
443
|
-
|
|
434
|
+
const obj = oidcFactory(res.data.providers[i]);
|
|
444
435
|
if (obj instanceof AuthProvider) {
|
|
445
436
|
this.authProviderList.push(obj);
|
|
446
437
|
}
|
|
@@ -521,7 +512,7 @@ class Connection {
|
|
|
521
512
|
* @see Connection#listAuthProviders
|
|
522
513
|
*/
|
|
523
514
|
async authenticateBasic(username, password) {
|
|
524
|
-
|
|
515
|
+
const basic = new BasicProvider(this);
|
|
525
516
|
await basic.login(username, password);
|
|
526
517
|
}
|
|
527
518
|
|
|
@@ -615,7 +606,7 @@ class Connection {
|
|
|
615
606
|
* @returns {AuthProvider}
|
|
616
607
|
*/
|
|
617
608
|
setAuthToken(type, providerId, token) {
|
|
618
|
-
|
|
609
|
+
const provider = new AuthProvider(type, this, {
|
|
619
610
|
id: providerId,
|
|
620
611
|
title: "Custom",
|
|
621
612
|
description: ""
|
|
@@ -635,23 +626,30 @@ class Connection {
|
|
|
635
626
|
* @throws {Error}
|
|
636
627
|
*/
|
|
637
628
|
async describeAccount() {
|
|
638
|
-
|
|
629
|
+
const response = await this._get('/me');
|
|
639
630
|
return response.data;
|
|
640
631
|
}
|
|
641
632
|
|
|
642
633
|
/**
|
|
643
|
-
*
|
|
634
|
+
* List all files from the user workspace.
|
|
644
635
|
*
|
|
645
636
|
* @async
|
|
646
637
|
* @returns {Promise<ResponseArray.<UserFile>>} A list of files.
|
|
647
638
|
* @throws {Error}
|
|
648
639
|
*/
|
|
649
640
|
async listFiles() {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
641
|
+
const pages = this.paginateFiles(null);
|
|
642
|
+
return await pages.nextPage();
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Paginate through the files from the user workspace.
|
|
647
|
+
*
|
|
648
|
+
* @param {?number} [limit=50] - The number of files per request/page as integer. If `null`, requests all files.
|
|
649
|
+
* @returns {ServicePages} A paged list of files.
|
|
650
|
+
*/
|
|
651
|
+
paginateFiles(limit = 50) {
|
|
652
|
+
return new UserFilePages(this, limit);
|
|
655
653
|
}
|
|
656
654
|
|
|
657
655
|
/**
|
|
@@ -682,7 +680,7 @@ class Connection {
|
|
|
682
680
|
if (targetPath === null) {
|
|
683
681
|
targetPath = Environment.fileNameForUpload(source);
|
|
684
682
|
}
|
|
685
|
-
|
|
683
|
+
const file = await this.getFile(targetPath);
|
|
686
684
|
return await file.uploadFile(source, statusCallback, abortController);
|
|
687
685
|
}
|
|
688
686
|
|
|
@@ -728,13 +726,15 @@ class Connection {
|
|
|
728
726
|
*
|
|
729
727
|
* @async
|
|
730
728
|
* @param {Process} process - User-defined process to validate.
|
|
731
|
-
* @returns {Promise<
|
|
729
|
+
* @returns {Promise<ValidationResult>} errors - A list of API compatible error objects. A valid process returns an empty list.
|
|
732
730
|
* @throws {Error}
|
|
733
731
|
*/
|
|
734
732
|
async validateProcess(process) {
|
|
735
|
-
|
|
733
|
+
const response = await this._post('/validation', this._normalizeUserProcess(process).process);
|
|
736
734
|
if (Array.isArray(response.data.errors)) {
|
|
737
|
-
|
|
735
|
+
const errors = response.data.errors;
|
|
736
|
+
errors['federation:backends'] = Array.isArray(response.data['federation:missing']) ? response.data['federation:missing'] : [];
|
|
737
|
+
return errors;
|
|
738
738
|
}
|
|
739
739
|
else {
|
|
740
740
|
throw new Error("Invalid validation response received.");
|
|
@@ -742,7 +742,7 @@ class Connection {
|
|
|
742
742
|
}
|
|
743
743
|
|
|
744
744
|
/**
|
|
745
|
-
*
|
|
745
|
+
* List all user-defined processes of the authenticated user.
|
|
746
746
|
*
|
|
747
747
|
* @async
|
|
748
748
|
* @param {Array.<UserProcess>} [oldProcesses=[]] - A list of existing user-defined processes to update.
|
|
@@ -750,29 +750,18 @@ class Connection {
|
|
|
750
750
|
* @throws {Error}
|
|
751
751
|
*/
|
|
752
752
|
async listUserProcesses(oldProcesses = []) {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
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');
|
|
753
|
+
const pages = this.paginateUserProcesses(null);
|
|
754
|
+
return await pages.nextPage(oldProcesses);
|
|
755
|
+
}
|
|
774
756
|
|
|
775
|
-
|
|
757
|
+
/**
|
|
758
|
+
* Paginates through the user-defined processes of the authenticated user.
|
|
759
|
+
*
|
|
760
|
+
* @param {?number} [limit=50] - The number of processes per request/page as integer. If `null`, requests all processes.
|
|
761
|
+
* @returns {ProcessPages} A paged list of user-defined processes.
|
|
762
|
+
*/
|
|
763
|
+
paginateUserProcesses(limit = 50) {
|
|
764
|
+
return this.paginateProcesses('user', limit);
|
|
776
765
|
}
|
|
777
766
|
|
|
778
767
|
/**
|
|
@@ -785,7 +774,7 @@ class Connection {
|
|
|
785
774
|
* @throws {Error}
|
|
786
775
|
*/
|
|
787
776
|
async setUserProcess(id, process) {
|
|
788
|
-
|
|
777
|
+
const pg = new UserProcess(this, id);
|
|
789
778
|
return await pg.replaceUserProcess(process);
|
|
790
779
|
}
|
|
791
780
|
|
|
@@ -798,7 +787,7 @@ class Connection {
|
|
|
798
787
|
* @throws {Error}
|
|
799
788
|
*/
|
|
800
789
|
async getUserProcess(id) {
|
|
801
|
-
|
|
790
|
+
const pg = new UserProcess(this, id);
|
|
802
791
|
return await pg.describeUserProcess();
|
|
803
792
|
}
|
|
804
793
|
|
|
@@ -816,15 +805,15 @@ class Connection {
|
|
|
816
805
|
* @returns {Promise<SyncResult>} - An object with the data and some metadata.
|
|
817
806
|
*/
|
|
818
807
|
async computeResult(process, plan = null, budget = null, abortController = null, additional = {}) {
|
|
819
|
-
|
|
808
|
+
const requestBody = this._normalizeUserProcess(
|
|
820
809
|
process,
|
|
821
810
|
Object.assign({}, additional, {
|
|
822
811
|
plan: plan,
|
|
823
812
|
budget: budget
|
|
824
813
|
})
|
|
825
814
|
);
|
|
826
|
-
|
|
827
|
-
|
|
815
|
+
const response = await this._post('/result', requestBody, Environment.getResponseType(), abortController);
|
|
816
|
+
const syncResult = {
|
|
828
817
|
data: response.data,
|
|
829
818
|
costs: null,
|
|
830
819
|
type: null,
|
|
@@ -839,15 +828,15 @@ class Connection {
|
|
|
839
828
|
syncResult.type = response.headers['content-type'];
|
|
840
829
|
}
|
|
841
830
|
|
|
842
|
-
|
|
831
|
+
const links = Array.isArray(response.headers.link) ? response.headers.link : [response.headers.link];
|
|
843
832
|
for(let link of links) {
|
|
844
833
|
if (typeof link !== 'string') {
|
|
845
834
|
continue;
|
|
846
835
|
}
|
|
847
|
-
|
|
836
|
+
const logs = link.match(/^<([^>]+)>;\s?rel="monitor"/i);
|
|
848
837
|
if (Array.isArray(logs) && logs.length > 1) {
|
|
849
838
|
try {
|
|
850
|
-
|
|
839
|
+
const logsResponse = await this._get(logs[1]);
|
|
851
840
|
if (Utils.isObject(logsResponse.data) && Array.isArray(logsResponse.data.logs)) {
|
|
852
841
|
syncResult.logs = logsResponse.data.logs;
|
|
853
842
|
}
|
|
@@ -878,13 +867,13 @@ class Connection {
|
|
|
878
867
|
* @throws {Error}
|
|
879
868
|
*/
|
|
880
869
|
async downloadResult(process, targetPath, plan = null, budget = null, abortController = null) {
|
|
881
|
-
|
|
870
|
+
const response = await this.computeResult(process, plan, budget, abortController);
|
|
882
871
|
// @ts-ignore
|
|
883
872
|
await Environment.saveToFile(response.data, targetPath);
|
|
884
873
|
}
|
|
885
874
|
|
|
886
875
|
/**
|
|
887
|
-
*
|
|
876
|
+
* List all batch jobs of the authenticated user.
|
|
888
877
|
*
|
|
889
878
|
* @async
|
|
890
879
|
* @param {Array.<Job>} [oldJobs=[]] - A list of existing jobs to update.
|
|
@@ -892,15 +881,19 @@ class Connection {
|
|
|
892
881
|
* @throws {Error}
|
|
893
882
|
*/
|
|
894
883
|
async listJobs(oldJobs = []) {
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
884
|
+
const pages = this.paginateJobs(null);
|
|
885
|
+
const firstPage = await pages.nextPage(oldJobs);
|
|
886
|
+
return firstPage;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Paginate through the batch jobs of the authenticated user.
|
|
891
|
+
*
|
|
892
|
+
* @param {?number} [limit=50] - The number of jobs per request/page as integer. If `null`, requests all jobs.
|
|
893
|
+
* @returns {JobPages} A paged list of jobs.
|
|
894
|
+
*/
|
|
895
|
+
paginateJobs(limit = 50) {
|
|
896
|
+
return new JobPages(this, limit);
|
|
904
897
|
}
|
|
905
898
|
|
|
906
899
|
/**
|
|
@@ -923,12 +916,12 @@ class Connection {
|
|
|
923
916
|
plan: plan,
|
|
924
917
|
budget: budget
|
|
925
918
|
});
|
|
926
|
-
|
|
927
|
-
|
|
919
|
+
const requestBody = this._normalizeUserProcess(process, additional);
|
|
920
|
+
const response = await this._post('/jobs', requestBody);
|
|
928
921
|
if (typeof response.headers['openeo-identifier'] !== 'string') {
|
|
929
922
|
throw new Error("Response did not contain a Job ID. Job has likely been created, but may not show up yet.");
|
|
930
923
|
}
|
|
931
|
-
|
|
924
|
+
const job = new Job(this, response.headers['openeo-identifier']).setAll(requestBody);
|
|
932
925
|
if (this.capabilities().hasFeature('describeJob')) {
|
|
933
926
|
return await job.describeJob();
|
|
934
927
|
}
|
|
@@ -946,12 +939,12 @@ class Connection {
|
|
|
946
939
|
* @throws {Error}
|
|
947
940
|
*/
|
|
948
941
|
async getJob(id) {
|
|
949
|
-
|
|
942
|
+
const job = new Job(this, id);
|
|
950
943
|
return await job.describeJob();
|
|
951
944
|
}
|
|
952
945
|
|
|
953
946
|
/**
|
|
954
|
-
*
|
|
947
|
+
* List all secondary web services of the authenticated user.
|
|
955
948
|
*
|
|
956
949
|
* @async
|
|
957
950
|
* @param {Array.<Service>} [oldServices=[]] - A list of existing services to update.
|
|
@@ -959,15 +952,18 @@ class Connection {
|
|
|
959
952
|
* @throws {Error}
|
|
960
953
|
*/
|
|
961
954
|
async listServices(oldServices = []) {
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
955
|
+
const pages = this.paginateServices(null);
|
|
956
|
+
return await pages.nextPage(oldServices);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Paginate through the secondary web services of the authenticated user.
|
|
961
|
+
*
|
|
962
|
+
* @param {?number} [limit=50] - The number of services per request/page as integer. If `null` (default), requests all services.
|
|
963
|
+
* @returns {ServicePages} A paged list of services.
|
|
964
|
+
*/
|
|
965
|
+
paginateServices(limit = 50) {
|
|
966
|
+
return new ServicePages(this, limit);
|
|
971
967
|
}
|
|
972
968
|
|
|
973
969
|
/**
|
|
@@ -987,7 +983,7 @@ class Connection {
|
|
|
987
983
|
* @throws {Error}
|
|
988
984
|
*/
|
|
989
985
|
async createService(process, type, title = null, description = null, enabled = true, configuration = {}, plan = null, budget = null, additional = {}) {
|
|
990
|
-
|
|
986
|
+
const requestBody = this._normalizeUserProcess(process, Object.assign({
|
|
991
987
|
title: title,
|
|
992
988
|
description: description,
|
|
993
989
|
type: type,
|
|
@@ -996,11 +992,11 @@ class Connection {
|
|
|
996
992
|
plan: plan,
|
|
997
993
|
budget: budget
|
|
998
994
|
}, additional));
|
|
999
|
-
|
|
995
|
+
const response = await this._post('/services', requestBody);
|
|
1000
996
|
if (typeof response.headers['openeo-identifier'] !== 'string') {
|
|
1001
997
|
throw new Error("Response did not contain a Service ID. Service has likely been created, but may not show up yet.");
|
|
1002
998
|
}
|
|
1003
|
-
|
|
999
|
+
const service = new Service(this, response.headers['openeo-identifier']).setAll(requestBody);
|
|
1004
1000
|
if (this.capabilities().hasFeature('describeService')) {
|
|
1005
1001
|
return service.describeService();
|
|
1006
1002
|
}
|
|
@@ -1018,26 +1014,10 @@ class Connection {
|
|
|
1018
1014
|
* @throws {Error}
|
|
1019
1015
|
*/
|
|
1020
1016
|
async getService(id) {
|
|
1021
|
-
|
|
1017
|
+
const service = new Service(this, id);
|
|
1022
1018
|
return await service.describeService();
|
|
1023
1019
|
}
|
|
1024
1020
|
|
|
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
1021
|
/**
|
|
1042
1022
|
* Get the a link with the given rel type.
|
|
1043
1023
|
*
|
|
@@ -1052,7 +1032,7 @@ class Connection {
|
|
|
1052
1032
|
rel = [rel];
|
|
1053
1033
|
}
|
|
1054
1034
|
if (Array.isArray(links)) {
|
|
1055
|
-
|
|
1035
|
+
const link = links.find(l => Utils.isObject(l) && rel.includes(l.rel) && typeof l.href === 'string');
|
|
1056
1036
|
if (link) {
|
|
1057
1037
|
return link.href;
|
|
1058
1038
|
}
|
|
@@ -1089,7 +1069,7 @@ class Connection {
|
|
|
1089
1069
|
return link;
|
|
1090
1070
|
}
|
|
1091
1071
|
try {
|
|
1092
|
-
|
|
1072
|
+
const url = new URL(link.href, baseUrl);
|
|
1093
1073
|
return Object.assign({}, link, {href: url.toString()});
|
|
1094
1074
|
} catch(error) {
|
|
1095
1075
|
return link;
|
|
@@ -1136,7 +1116,7 @@ class Connection {
|
|
|
1136
1116
|
* @see https://github.com/axios/axios#request-config
|
|
1137
1117
|
*/
|
|
1138
1118
|
async _post(path, body, responseType, abortController = null) {
|
|
1139
|
-
|
|
1119
|
+
const options = {
|
|
1140
1120
|
method: 'post',
|
|
1141
1121
|
responseType: responseType,
|
|
1142
1122
|
url: path,
|
|
@@ -1208,7 +1188,7 @@ class Connection {
|
|
|
1208
1188
|
* @throws {Error}
|
|
1209
1189
|
*/
|
|
1210
1190
|
async download(url, authorize) {
|
|
1211
|
-
|
|
1191
|
+
const result = await this._send({
|
|
1212
1192
|
method: 'get',
|
|
1213
1193
|
responseType: Environment.getResponseType(),
|
|
1214
1194
|
url: url,
|
|
@@ -1268,7 +1248,7 @@ class Connection {
|
|
|
1268
1248
|
|
|
1269
1249
|
try {
|
|
1270
1250
|
let response = await axios(options);
|
|
1271
|
-
|
|
1251
|
+
const capabilities = this.capabilities();
|
|
1272
1252
|
if (capabilities) {
|
|
1273
1253
|
response = capabilities.migrate(response);
|
|
1274
1254
|
}
|
|
@@ -1292,7 +1272,7 @@ class Connection {
|
|
|
1292
1272
|
// See: https://github.com/axios/axios/issues/815
|
|
1293
1273
|
if (options.responseType === Environment.getResponseType()) {
|
|
1294
1274
|
try {
|
|
1295
|
-
|
|
1275
|
+
const errorResponse = await Environment.handleErrorResponse(error);
|
|
1296
1276
|
throw enrichError(error, errorResponse);
|
|
1297
1277
|
} catch (error2) {
|
|
1298
1278
|
console.error(error2);
|