@openeo/js-client 2.3.1 → 2.5.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/openeo.js CHANGED
@@ -7,7 +7,7 @@
7
7
  var a = typeof exports === 'object' ? factory(require("Oidc"), require("axios"), (function webpackLoadOptionalExternalModule() { try { return require("multihashes"); } catch(e) {} }())) : factory(root["Oidc"], root["axios"], root["multihashes"]);
8
8
  for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
9
9
  }
10
- })(self, function(__WEBPACK_EXTERNAL_MODULE__6__, __WEBPACK_EXTERNAL_MODULE__300__, __WEBPACK_EXTERNAL_MODULE__263__) {
10
+ })(self, (__WEBPACK_EXTERNAL_MODULE__6__, __WEBPACK_EXTERNAL_MODULE__300__, __WEBPACK_EXTERNAL_MODULE__263__) => {
11
11
  return /******/ (() => { // webpackBootstrap
12
12
  /******/ var __webpack_modules__ = ({
13
13
 
@@ -1263,7 +1263,15 @@ var Catalog = {
1263
1263
 
1264
1264
  _.ensure(catalog, 'stac_extensions', []) && DONE;
1265
1265
  V.before('0.8.0') && _.populateExtensions(catalog, 'catalog') && DONE;
1266
- }
1266
+ },
1267
+
1268
+ openeo(obj) {
1269
+ _.rename(obj, 'api_version', 'openeo:api_version') && DONE;
1270
+ _.rename(obj, 'backend_version', 'openeo:backend_version') && DONE;
1271
+ _.rename(obj, 'production', 'openeo:production') && DONE;
1272
+ _.rename(obj, 'endpoints', 'openeo:endpoints') && DONE;
1273
+ _.rename(obj, 'billing', 'openeo:billing') && DONE;
1274
+ },
1267
1275
 
1268
1276
  };
1269
1277
 
@@ -1297,6 +1305,8 @@ var Collection = {
1297
1305
  },
1298
1306
 
1299
1307
  extent(collection) {
1308
+ _.ensure(collection, "extent", {});
1309
+
1300
1310
  if (V.before('0.8.0')) {
1301
1311
  // Restructure spatial extent
1302
1312
  if (Array.isArray(collection.extent.spatial)) {
@@ -1316,9 +1326,14 @@ var Collection = {
1316
1326
  }
1317
1327
  }
1318
1328
 
1329
+ _.ensure(collection.extent, "spatial", {});
1330
+ _.ensure(collection.extent.spatial, "bbox", []);
1331
+ _.ensure(collection.extent, "temporal", {});
1332
+ _.ensure(collection.extent.temporal, "interval", []);
1333
+
1319
1334
  if (V.before('1.0.0-rc.3')) {
1320
1335
  // The first extent in a Collection is always the overall extent, followed by more specific extents.
1321
- if (Array.isArray(collection.extent.temporal.interval) && collection.extent.temporal.interval.length > 1) {
1336
+ if (collection.extent.temporal.interval.length > 1) {
1322
1337
  let min, max;
1323
1338
  for(let interval of collection.extent.temporal.interval) {
1324
1339
  if (interval[0] === null) {
@@ -1350,7 +1365,7 @@ var Collection = {
1350
1365
  max ? _.toISOString(max) : null
1351
1366
  ]);
1352
1367
  }
1353
- if (Array.isArray(collection.extent.spatial.bbox) && collection.extent.spatial.bbox.length > 1) {
1368
+ if (collection.extent.spatial.bbox.length > 1) {
1354
1369
  let count = collection.extent.spatial.bbox.reduce((val, bbox) => Array.isArray(bbox) ? Math.max(bbox.length, val) : val, 4);
1355
1370
  if (count >= 4) {
1356
1371
  let union = new Array(count).fill(null);
@@ -1840,6 +1855,7 @@ class AuthProvider {
1840
1855
  /**
1841
1856
  * Abstract method that extending classes implement the login process with.
1842
1857
  *
1858
+ * @async
1843
1859
  * @param {...*} args
1844
1860
  * @throws {Error}
1845
1861
  */
@@ -1885,7 +1901,7 @@ class BaseEntity {
1885
1901
  * Creates an instance of this object.
1886
1902
  *
1887
1903
  * @param {Connection} connection - A Connection object representing an established connection to an openEO back-end.
1888
- * @param {Array} properties - A mapping from the API property names to the JS client property names (usually to convert between snake_case and camelCase), e.g. `["id", "title", ["process_graph", "processGraph"]]`
1904
+ * @param {Array.<string|Array.<string>>} properties - A mapping from the API property names to the JS client property names (usually to convert between snake_case and camelCase), e.g. `["id", "title", ["process_graph", "processGraph"]]`
1889
1905
  */
1890
1906
  constructor(connection) {
1891
1907
  let properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
@@ -2460,19 +2476,19 @@ class Builder {
2460
2476
  this.id = id;
2461
2477
  /**
2462
2478
  * The parent builder.
2463
- * @type {?Builder}
2479
+ * @type {Builder | null}
2464
2480
  */
2465
2481
 
2466
2482
  this.parent = parent;
2467
2483
  /**
2468
2484
  * The parent node.
2469
- * @type {?BuilderNode}
2485
+ * @type {BuilderNode | null}
2470
2486
  */
2471
2487
 
2472
2488
  this.parentNode = null;
2473
2489
  /**
2474
2490
  * The parent parameter name.
2475
- * @type {?string}
2491
+ * @type {string | null}
2476
2492
  */
2477
2493
 
2478
2494
  this.parentParameter = null;
@@ -2589,7 +2605,7 @@ class Builder {
2589
2605
  /**
2590
2606
  * Gets the callback parameter specifics from the parent process.
2591
2607
  *
2592
- * @returns {Array}
2608
+ * @returns {Array.<object.<string,*>>}
2593
2609
  * @todo Should this also pass callback parameters from parents until root is reached?
2594
2610
  */
2595
2611
 
@@ -2808,7 +2824,7 @@ class Formula {
2808
2824
 
2809
2825
  this.tree = parser.parse(formula);
2810
2826
  /**
2811
- * @type {?Builder}
2827
+ * @type {Builder | null}
2812
2828
  */
2813
2829
 
2814
2830
  this.builder = null;
@@ -3083,7 +3099,7 @@ class BuilderNode {
3083
3099
  /**
3084
3100
  * Converts a sorted array of arguments to an object with the respective parameter names.
3085
3101
  *
3086
- * @param {Array} processArgs
3102
+ * @param {Array.<object.<string, *>>} processArgs
3087
3103
  * @returns {object.<string, *>}
3088
3104
  * @throws {Error}
3089
3105
  */
@@ -4328,7 +4344,7 @@ class Connection {
4328
4344
  * Auth Provider cache
4329
4345
  *
4330
4346
  * @protected
4331
- * @type {?Array.<AuthProvider>}
4347
+ * @type {Array.<AuthProvider> | null}
4332
4348
  */
4333
4349
 
4334
4350
  this.authProviderList = null;
@@ -4336,7 +4352,7 @@ class Connection {
4336
4352
  * Current auth provider
4337
4353
  *
4338
4354
  * @protected
4339
- * @type {?AuthProvider}
4355
+ * @type {AuthProvider | null}
4340
4356
  */
4341
4357
 
4342
4358
  this.authProvider = null;
@@ -4344,7 +4360,7 @@ class Connection {
4344
4360
  * Capability cache
4345
4361
  *
4346
4362
  * @protected
4347
- * @type {?Capabilities}
4363
+ * @type {Capabilities | null}
4348
4364
  */
4349
4365
 
4350
4366
  this.capabilitiesObject = null;
@@ -4412,10 +4428,12 @@ class Connection {
4412
4428
  let fn = () => Promise.resolve();
4413
4429
 
4414
4430
  if (namespace === 'user') {
4431
+ let userProcesses = this.processes.namespace('user');
4432
+
4415
4433
  if (!this.isAuthenticated()) {
4416
4434
  fn = () => this.processes.remove(null, 'user') ? Promise.resolve() : Promise.reject(new Error("Can't clear user processes"));
4417
4435
  } else if (this.capabilities().hasFeature('listUserProcesses')) {
4418
- fn = () => this.listUserProcesses();
4436
+ fn = () => this.listUserProcesses(userProcesses);
4419
4437
  }
4420
4438
  } else if (this.capabilities().hasFeature('listProcesses')) {
4421
4439
  fn = () => this.listProcesses(namespace);
@@ -4545,7 +4563,7 @@ class Connection {
4545
4563
  * 2. Lower left corner, coordinate axis 2
4546
4564
  * 3. Upper right corner, coordinate axis 1
4547
4565
  * 4. Upper right corner, coordinate axis 2
4548
- * @param {?Array.<*>} [temporalExtent=null] - Limits the items to the specified temporal interval.
4566
+ * @param {?Array} [temporalExtent=null] - Limits the items to the specified temporal interval.
4549
4567
  * The interval has to be specified as an array with exactly two elements (start, end) and
4550
4568
  * each must be either an RFC 3339 compatible string or a Date object.
4551
4569
  * Also supports open intervals by setting one of the boundaries to `null`, but never both.
@@ -4598,6 +4616,26 @@ class Connection {
4598
4616
  nextUrl = this._getLinkHref(response.data.links);
4599
4617
  }
4600
4618
  }
4619
+ /**
4620
+ * Normalisation of the namespace to a value that is compatible with the OpenEO specs - EXPERIMENTAL.
4621
+ *
4622
+ * This is required to support UDP that are shared as public. These can only be executed with providing the full URL
4623
+ * (e.g. https://<backend>/processes/<namespace>/<process_id>) as the namespace value in the processing graph. For other
4624
+ * parts of the API (such as the listing of the processes, only the name of the namespace is required.
4625
+ *
4626
+ * This function will extract the short name of the namespace from a shareable URL.
4627
+ *
4628
+ * @protected
4629
+ * @param {?string} namespace - Namespace of the process
4630
+ * @returns {?string}
4631
+ */
4632
+
4633
+
4634
+ normalizeNamespace(namespace) {
4635
+ // 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
4636
+ const matches = namespace.match(/^https?:\/\/.*\/processes\/(@?[\w\-.~:]+)\/?/i);
4637
+ return matches && matches.length > 1 ? matches[1] : namespace;
4638
+ }
4601
4639
  /**
4602
4640
  * List processes available on the back-end.
4603
4641
  *
@@ -4621,7 +4659,7 @@ class Connection {
4621
4659
  namespace = 'backend';
4622
4660
  }
4623
4661
 
4624
- let path = namespace === 'backend' ? '/processes' : `/processes/${namespace}`;
4662
+ let path = namespace === 'backend' ? '/processes' : `/processes/${this.normalizeNamespace(namespace)}`;
4625
4663
  let response = await this._get(path);
4626
4664
 
4627
4665
  if (!Utils.isObject(response.data) || !Array.isArray(response.data.processes)) {
@@ -4657,7 +4695,7 @@ class Connection {
4657
4695
  if (namespace === 'backend') {
4658
4696
  await this.listProcesses();
4659
4697
  } else {
4660
- let response = await this._get(`/processes/${namespace}/${processId}`);
4698
+ let response = await this._get(`/processes/${this.normalizeNamespace(namespace)}/${processId}`);
4661
4699
 
4662
4700
  if (!Utils.isObject(response.data) || typeof response.data.id !== 'string') {
4663
4701
  throw new Error('Invalid response received for process');
@@ -4924,14 +4962,15 @@ class Connection {
4924
4962
  * Lists all files from the user workspace.
4925
4963
  *
4926
4964
  * @async
4927
- * @returns {Promise<Array.<UserFile>>} A list of files.
4965
+ * @returns {Promise<ResponseArray.<UserFile>>} A list of files.
4928
4966
  * @throws {Error}
4929
4967
  */
4930
4968
 
4931
4969
 
4932
4970
  async listFiles() {
4933
4971
  let response = await this._get('/files');
4934
- return response.data.files.map(f => new UserFile(this, f.path).setAll(f));
4972
+ let files = response.data.files.map(f => new UserFile(this, f.path).setAll(f));
4973
+ return this._toResponseArray(files, response.data);
4935
4974
  }
4936
4975
  /**
4937
4976
  * A callback that is executed on upload progress updates.
@@ -5036,22 +5075,36 @@ class Connection {
5036
5075
  * Lists all user-defined processes of the authenticated user.
5037
5076
  *
5038
5077
  * @async
5039
- * @returns {Promise<Array.<UserProcess>>} A list of user-defined processes.
5078
+ * @param {Array.<UserProcess>} [oldProcesses=[]] - A list of existing user-defined processes to update.
5079
+ * @returns {Promise<ResponseArray.<UserProcess>>} A list of user-defined processes.
5040
5080
  * @throws {Error}
5041
5081
  */
5042
5082
 
5043
5083
 
5044
5084
  async listUserProcesses() {
5085
+ let oldProcesses = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5045
5086
  let response = await this._get('/process_graphs');
5046
5087
 
5047
5088
  if (!Utils.isObject(response.data) || !Array.isArray(response.data.processes)) {
5048
5089
  throw new Error('Invalid response received for processes');
5049
- } // Store processes in cache
5090
+ } // Remove existing processes from cache
5050
5091
 
5051
5092
 
5052
- this.processes.remove(null, 'user');
5053
- this.processes.addAll(response.data.processes, 'user');
5054
- return response.data.processes.map(pg => new UserProcess(this, pg.id).setAll(pg));
5093
+ this.processes.remove(null, 'user'); // Update existing processes if needed
5094
+
5095
+ let newProcesses = response.data.processes.map(newProcess => {
5096
+ let process = oldProcesses.find(oldProcess => oldProcess.id === newProcess.id);
5097
+
5098
+ if (!process) {
5099
+ process = new UserProcess(this, newProcess.id);
5100
+ }
5101
+
5102
+ return process.setAll(newProcess);
5103
+ }); // Store plain JS variant (i.e. no Job objects involved) of processes in cache
5104
+
5105
+ let jsonProcesses = oldProcesses.length > 0 ? newProcesses.map(p => p.toJSON()) : response.data.processes;
5106
+ this.processes.addAll(jsonProcesses, 'user');
5107
+ return this._toResponseArray(newProcesses, response.data);
5055
5108
  }
5056
5109
  /**
5057
5110
  * Creates a new stored user-defined process at the back-end.
@@ -5177,14 +5230,26 @@ class Connection {
5177
5230
  * Lists all batch jobs of the authenticated user.
5178
5231
  *
5179
5232
  * @async
5180
- * @returns {Promise<Array.<Job>>} A list of jobs.
5233
+ * @param {Array.<Job>} [oldJobs=[]] - A list of existing jobs to update.
5234
+ * @returns {Promise<ResponseArray.<Job>>} A list of jobs.
5181
5235
  * @throws {Error}
5182
5236
  */
5183
5237
 
5184
5238
 
5185
5239
  async listJobs() {
5240
+ let oldJobs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5186
5241
  let response = await this._get('/jobs');
5187
- return response.data.jobs.map(j => new Job(this, j.id).setAll(j));
5242
+ let newJobs = response.data.jobs.map(newJob => {
5243
+ delete newJob.status;
5244
+ let job = oldJobs.find(oldJob => oldJob.id === newJob.id);
5245
+
5246
+ if (!job) {
5247
+ job = new Job(this, newJob.id);
5248
+ }
5249
+
5250
+ return job.setAll(newJob);
5251
+ });
5252
+ return this._toResponseArray(newJobs, response.data);
5188
5253
  }
5189
5254
  /**
5190
5255
  * Creates a new batch job at the back-end.
@@ -5248,14 +5313,25 @@ class Connection {
5248
5313
  * Lists all secondary web services of the authenticated user.
5249
5314
  *
5250
5315
  * @async
5251
- * @returns {Promise<Array.<Job>>} A list of services.
5316
+ * @param {Array.<Service>} [oldServices=[]] - A list of existing services to update.
5317
+ * @returns {Promise<ResponseArray.<Job>>} A list of services.
5252
5318
  * @throws {Error}
5253
5319
  */
5254
5320
 
5255
5321
 
5256
5322
  async listServices() {
5323
+ let oldServices = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
5257
5324
  let response = await this._get('/services');
5258
- return response.data.services.map(s => new Service(this, s.id).setAll(s));
5325
+ let newServices = response.data.services.map(newService => {
5326
+ let service = oldServices.find(oldService => oldService.id === newService.id);
5327
+
5328
+ if (!service) {
5329
+ service = new Service(this, newService.id);
5330
+ }
5331
+
5332
+ return service.setAll(newService);
5333
+ });
5334
+ return this._toResponseArray(newServices, response.data);
5259
5335
  }
5260
5336
  /**
5261
5337
  * Creates a new secondary web service at the back-end.
@@ -5322,9 +5398,27 @@ class Connection {
5322
5398
  let service = new Service(this, id);
5323
5399
  return await service.describeService();
5324
5400
  }
5401
+ /**
5402
+ * Adds additional response details to the array.
5403
+ *
5404
+ * Adds links and federation:missing.
5405
+ *
5406
+ * @protected
5407
+ * @param {Array.<*>} arr
5408
+ * @param {object.<string, *>} response
5409
+ * @returns {ResponseArray}
5410
+ */
5411
+
5412
+
5413
+ _toResponseArray(arr, response) {
5414
+ arr.links = Array.isArray(response.links) ? response.links : [];
5415
+ arr['federation:missing'] = Array.isArray(response['federation:missing']) ? response['federation:missing'] : [];
5416
+ return arr;
5417
+ }
5325
5418
  /**
5326
5419
  * Get the a link with the given rel type.
5327
5420
  *
5421
+ * @protected
5328
5422
  * @param {Array.<Link>} links - An array of links.
5329
5423
  * @param {string} rel - Relation type to find, defaults to `next`.
5330
5424
  * @returns {string | null}
@@ -5348,6 +5442,7 @@ class Connection {
5348
5442
  /**
5349
5443
  * Sends a GET request.
5350
5444
  *
5445
+ * @protected
5351
5446
  * @async
5352
5447
  * @param {string} path
5353
5448
  * @param {object.<string, *>} query
@@ -5372,6 +5467,7 @@ class Connection {
5372
5467
  /**
5373
5468
  * Sends a POST request.
5374
5469
  *
5470
+ * @protected
5375
5471
  * @async
5376
5472
  * @param {string} path
5377
5473
  * @param {*} body
@@ -5396,6 +5492,7 @@ class Connection {
5396
5492
  /**
5397
5493
  * Sends a PUT request.
5398
5494
  *
5495
+ * @protected
5399
5496
  * @async
5400
5497
  * @param {string} path
5401
5498
  * @param {*} body
@@ -5414,6 +5511,7 @@ class Connection {
5414
5511
  /**
5415
5512
  * Sends a PATCH request.
5416
5513
  *
5514
+ * @protected
5417
5515
  * @async
5418
5516
  * @param {string} path
5419
5517
  * @param {*} body
@@ -5432,6 +5530,7 @@ class Connection {
5432
5530
  /**
5433
5531
  * Sends a DELETE request.
5434
5532
  *
5533
+ * @protected
5435
5534
  * @async
5436
5535
  * @param {string} path
5437
5536
  * @returns {Promise<AxiosResponse>}
@@ -5478,6 +5577,7 @@ class Connection {
5478
5577
  * Tries to smoothly handle error responses by providing an object for all response types,
5479
5578
  * instead of Streams or Blobs for non-JSON response types.
5480
5579
  *
5580
+ * @protected
5481
5581
  * @async
5482
5582
  * @param {object.<string, *>} options
5483
5583
  * @param {?AbortController} [abortController=null] - An AbortController object that can be used to cancel the request.
@@ -5565,6 +5665,7 @@ class FileTypes {
5565
5665
  */
5566
5666
  constructor(data) {
5567
5667
  /**
5668
+ * @protected
5568
5669
  * @type {FileTypesAPI}
5569
5670
  */
5570
5671
  this.data = {
@@ -5585,6 +5686,15 @@ class FileTypes {
5585
5686
  this.data[io][type.toUpperCase()] = data[io][type];
5586
5687
  }
5587
5688
  }
5689
+ /**
5690
+ * A list of backends from the federation that are missing in the response data.
5691
+ *
5692
+ * @public
5693
+ * @type {Array.<string>}
5694
+ */
5695
+
5696
+
5697
+ this['federation:missing'] = data['federation:missing'];
5588
5698
  }
5589
5699
  /**
5590
5700
  * Returns the file types response as a JSON serializable representation of the data that is API compliant.
@@ -5723,7 +5833,7 @@ class Job extends BaseEntity {
5723
5833
  * The process chain to be executed.
5724
5834
  * @public
5725
5835
  * @readonly
5726
- * @type {Process}
5836
+ * @type {?Process}
5727
5837
  */
5728
5838
 
5729
5839
  this.process = undefined;
@@ -5732,7 +5842,7 @@ class Job extends BaseEntity {
5732
5842
  * One of "created", "queued", "running", "canceled", "finished" or "error".
5733
5843
  * @public
5734
5844
  * @readonly
5735
- * @type {string}
5845
+ * @type {?string}
5736
5846
  */
5737
5847
 
5738
5848
  this.status = undefined;
@@ -5740,7 +5850,7 @@ class Job extends BaseEntity {
5740
5850
  * Indicates the process of a running batch job in percent.
5741
5851
  * @public
5742
5852
  * @readonly
5743
- * @type {number}
5853
+ * @type {?number}
5744
5854
  */
5745
5855
 
5746
5856
  this.progress = undefined;
@@ -5748,7 +5858,7 @@ class Job extends BaseEntity {
5748
5858
  * Date and time of creation, formatted as a RFC 3339 date-time.
5749
5859
  * @public
5750
5860
  * @readonly
5751
- * @type {string}
5861
+ * @type {?string}
5752
5862
  */
5753
5863
 
5754
5864
  this.created = undefined;
@@ -5756,7 +5866,7 @@ class Job extends BaseEntity {
5756
5866
  * Date and time of the last status change, formatted as a RFC 3339 date-time.
5757
5867
  * @public
5758
5868
  * @readonly
5759
- * @type {string}
5869
+ * @type {?string}
5760
5870
  */
5761
5871
 
5762
5872
  this.updated = undefined;
@@ -5764,7 +5874,7 @@ class Job extends BaseEntity {
5764
5874
  * The billing plan to process and charge the batch job with.
5765
5875
  * @public
5766
5876
  * @readonly
5767
- * @type {string}
5877
+ * @type {?string}
5768
5878
  */
5769
5879
 
5770
5880
  this.plan = undefined;
@@ -6216,7 +6326,7 @@ class OidcProvider extends AuthProvider {
6216
6326
  /**
6217
6327
  * The client ID to use for authentication.
6218
6328
  *
6219
- * @type {?string}
6329
+ * @type {string | null}
6220
6330
  */
6221
6331
 
6222
6332
  this.clientId = null;
@@ -6244,6 +6354,13 @@ class OidcProvider extends AuthProvider {
6244
6354
  */
6245
6355
 
6246
6356
  this.scopes = Array.isArray(options.scopes) && options.scopes.length > 0 ? options.scopes : ['openid'];
6357
+ /**
6358
+ * The scope that is used to request a refresh token.
6359
+ *
6360
+ * @type {string}
6361
+ */
6362
+
6363
+ this.refreshTokenScope = "offline_access";
6247
6364
  /**
6248
6365
  * Any additional links.
6249
6366
  *
@@ -6304,21 +6421,25 @@ class OidcProvider extends AuthProvider {
6304
6421
  *
6305
6422
  * Supported only in Browser environments.
6306
6423
  *
6424
+ * @async
6307
6425
  * @param {object.<string, *>} [options={}] - Object with authentication options.
6426
+ * @param {boolean} [requestRefreshToken=false] - If set to `true`, adds a scope to request a refresh token.
6308
6427
  * @returns {Promise<void>}
6309
6428
  * @throws {Error}
6310
6429
  * @see https://github.com/IdentityModel/oidc-client-js/wiki#other-optional-settings
6430
+ * @see {OidcProvider#refreshTokenScope}
6311
6431
  */
6312
6432
 
6313
6433
 
6314
6434
  async login() {
6315
6435
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6436
+ let requestRefreshToken = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
6316
6437
 
6317
6438
  if (!this.issuer || typeof this.issuer !== 'string') {
6318
6439
  throw new Error("No Issuer URL available for OpenID Connect");
6319
6440
  }
6320
6441
 
6321
- this.manager = new Oidc.UserManager(this.getOptions(options));
6442
+ this.manager = new Oidc.UserManager(this.getOptions(options, requestRefreshToken));
6322
6443
  this.addListener('UserLoaded', async () => this.setUser(await this.manager.getUser()), 'js-client');
6323
6444
  this.addListener('AccessTokenExpired', () => this.setUser(null), 'js-client');
6324
6445
 
@@ -6363,18 +6484,27 @@ class OidcProvider extends AuthProvider {
6363
6484
  *
6364
6485
  * @protected
6365
6486
  * @param {object.<string, *>} options
6487
+ * @param {boolean} [requestRefreshToken=false] - If set to `true`, adds a scope to request a refresh token.
6366
6488
  * @returns {object.<string, *>}
6489
+ * @see {OidcProvider#refreshTokenScope}
6367
6490
  */
6368
6491
 
6369
6492
 
6370
6493
  getOptions() {
6371
6494
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
6495
+ let requestRefreshToken = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
6372
6496
  let response_type = this.getResponseType();
6497
+ let scope = this.scopes.slice(0);
6498
+
6499
+ if (requestRefreshToken && !scope.includes(this.refreshTokenScope)) {
6500
+ scope.push(this.refreshTokenScope);
6501
+ }
6502
+
6373
6503
  return Object.assign({
6374
6504
  client_id: this.clientId,
6375
6505
  redirect_uri: OidcProvider.redirectUrl,
6376
6506
  authority: this.issuer.replace('/.well-known/openid-configuration', ''),
6377
- scope: this.scopes.join(' '),
6507
+ scope: scope.join(' '),
6378
6508
  validateSubOnSilentRenew: true,
6379
6509
  response_type,
6380
6510
  response_mode: response_type.includes('code') ? 'query' : 'fragment'
@@ -6652,7 +6782,7 @@ class OpenEO {
6652
6782
 
6653
6783
 
6654
6784
  static clientVersion() {
6655
- return "2.3.1";
6785
+ return "2.5.0";
6656
6786
  }
6657
6787
 
6658
6788
  }
@@ -6728,7 +6858,7 @@ class Service extends BaseEntity {
6728
6858
  * The process chain to be executed.
6729
6859
  * @public
6730
6860
  * @readonly
6731
- * @type {Process}
6861
+ * @type {?Process}
6732
6862
  */
6733
6863
 
6734
6864
  this.process = undefined;
@@ -6736,7 +6866,7 @@ class Service extends BaseEntity {
6736
6866
  * URL at which the secondary web service is accessible
6737
6867
  * @public
6738
6868
  * @readonly
6739
- * @type {string}
6869
+ * @type {?string}
6740
6870
  */
6741
6871
 
6742
6872
  this.url = undefined;
@@ -6744,14 +6874,14 @@ class Service extends BaseEntity {
6744
6874
  * Web service type (protocol / standard) that is exposed.
6745
6875
  * @public
6746
6876
  * @readonly
6747
- * @type {string}
6877
+ * @type {?string}
6748
6878
  */
6749
6879
 
6750
6880
  this.type = undefined;
6751
6881
  /**
6752
6882
  * @public
6753
6883
  * @readonly
6754
- * @type {boolean}
6884
+ * @type {?boolean}
6755
6885
  */
6756
6886
 
6757
6887
  this.enabled = undefined;
@@ -6759,7 +6889,7 @@ class Service extends BaseEntity {
6759
6889
  * Map of configuration settings, i.e. the setting names supported by the secondary web service combined with actual values.
6760
6890
  * @public
6761
6891
  * @readonly
6762
- * @type {object.<string, *>}
6892
+ * @type {?object.<string, *>}
6763
6893
  */
6764
6894
 
6765
6895
  this.configuration = undefined;
@@ -6767,7 +6897,7 @@ class Service extends BaseEntity {
6767
6897
  * Additional attributes of the secondary web service, e.g. available layers for a WMS based on the bands in the underlying GeoTiff.
6768
6898
  * @public
6769
6899
  * @readonly
6770
- * @type {object.<string, *>}
6900
+ * @type {?object.<string, *>}
6771
6901
  */
6772
6902
 
6773
6903
  this.attributes = undefined;
@@ -6775,7 +6905,7 @@ class Service extends BaseEntity {
6775
6905
  * Date and time of creation, formatted as a RFC 3339 date-time.
6776
6906
  * @public
6777
6907
  * @readonly
6778
- * @type {string}
6908
+ * @type {?string}
6779
6909
  */
6780
6910
 
6781
6911
  this.created = undefined;
@@ -6783,7 +6913,7 @@ class Service extends BaseEntity {
6783
6913
  * The billing plan to process and charge the service with.
6784
6914
  * @public
6785
6915
  * @readonly
6786
- * @type {string}
6916
+ * @type {?string}
6787
6917
  */
6788
6918
 
6789
6919
  this.plan = undefined;
@@ -7134,7 +7264,7 @@ class UserProcess extends BaseEntity {
7134
7264
  * A list of categories.
7135
7265
  * @public
7136
7266
  * @readonly
7137
- * @type {Array.<string>}
7267
+ * @type {?Array.<string>}
7138
7268
  */
7139
7269
 
7140
7270
  this.categories = undefined;
@@ -7159,7 +7289,7 @@ class UserProcess extends BaseEntity {
7159
7289
  * Specifies that the process or parameter is deprecated with the potential to be removed in any of the next versions.
7160
7290
  * @public
7161
7291
  * @readonly
7162
- * @type {boolean}
7292
+ * @type {?boolean}
7163
7293
  */
7164
7294
 
7165
7295
  this.deprecated = undefined;
@@ -7167,7 +7297,7 @@ class UserProcess extends BaseEntity {
7167
7297
  * Declares the process or parameter to be experimental, which means that it is likely to change or may produce unpredictable behaviour.
7168
7298
  * @public
7169
7299
  * @readonly
7170
- * @type {boolean}
7300
+ * @type {?boolean}
7171
7301
  */
7172
7302
 
7173
7303
  this.experimental = undefined;
@@ -7175,14 +7305,14 @@ class UserProcess extends BaseEntity {
7175
7305
  * Declares any exceptions (errors) that might occur during execution of this process.
7176
7306
  * @public
7177
7307
  * @readonly
7178
- * @type {object.<string, *>}
7308
+ * @type {?object.<string, *>}
7179
7309
  */
7180
7310
 
7181
7311
  this.exceptions = undefined;
7182
7312
  /**
7183
7313
  * @public
7184
7314
  * @readonly
7185
- * @type {Array.<object.<string, *>>}
7315
+ * @type {?Array.<object.<string, *>>}
7186
7316
  */
7187
7317
 
7188
7318
  this.examples = undefined;
@@ -7190,14 +7320,14 @@ class UserProcess extends BaseEntity {
7190
7320
  * Links related to this process.
7191
7321
  * @public
7192
7322
  * @readonly
7193
- * @type {Array.<Link>}
7323
+ * @type {?Array.<Link>}
7194
7324
  */
7195
7325
 
7196
7326
  this.links = undefined;
7197
7327
  /**
7198
7328
  * @public
7199
7329
  * @readonly
7200
- * @type {object.<string, *>}
7330
+ * @type {?object.<string, *>}
7201
7331
  */
7202
7332
 
7203
7333
  this.processGraph = undefined;