angular-odata 0.105.0 → 0.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/esm2020/lib/api.mjs +44 -6
  2. package/esm2020/lib/client.mjs +6 -31
  3. package/esm2020/lib/helper.mjs +17 -7
  4. package/esm2020/lib/models/collection.mjs +25 -31
  5. package/esm2020/lib/models/model.mjs +6 -3
  6. package/esm2020/lib/models/options.mjs +5 -5
  7. package/esm2020/lib/resources/request.mjs +30 -2
  8. package/esm2020/lib/resources/resource.mjs +7 -50
  9. package/esm2020/lib/resources/responses/annotations.mjs +15 -3
  10. package/esm2020/lib/resources/responses/response.mjs +1 -1
  11. package/esm2020/lib/resources/responses/types.mjs +1 -1
  12. package/esm2020/lib/resources/types/batch.mjs +6 -9
  13. package/esm2020/lib/resources/types/count.mjs +1 -1
  14. package/esm2020/lib/resources/types/entity-set.mjs +32 -10
  15. package/esm2020/lib/resources/types/entity.mjs +1 -1
  16. package/esm2020/lib/resources/types/media.mjs +1 -1
  17. package/esm2020/lib/resources/types/metadata.mjs +3 -5
  18. package/esm2020/lib/resources/types/navigation-property.mjs +24 -6
  19. package/esm2020/lib/resources/types/options.mjs +1 -1
  20. package/esm2020/lib/resources/types/property.mjs +24 -4
  21. package/esm2020/lib/resources/types/reference.mjs +1 -1
  22. package/esm2020/lib/resources/types/singleton.mjs +1 -4
  23. package/esm2020/lib/resources/types/value.mjs +2 -2
  24. package/esm2020/lib/schema/parsers/callable.mjs +1 -1
  25. package/esm2020/lib/schema/parsers/edm.mjs +9 -9
  26. package/esm2020/lib/schema/parsers/enum-type.mjs +1 -1
  27. package/esm2020/lib/services/entity-set.mjs +7 -7
  28. package/esm2020/lib/utils/http.mjs +1 -1
  29. package/esm2020/lib/utils/objects.mjs +1 -1
  30. package/fesm2015/angular-odata.mjs +225 -157
  31. package/fesm2015/angular-odata.mjs.map +1 -1
  32. package/fesm2020/angular-odata.mjs +234 -162
  33. package/fesm2020/angular-odata.mjs.map +1 -1
  34. package/lib/api.d.ts +10 -3
  35. package/lib/client.d.ts +139 -1425
  36. package/lib/helper.d.ts +1 -1
  37. package/lib/models/collection.d.ts +11 -5
  38. package/lib/models/model.d.ts +7 -9
  39. package/lib/models/options.d.ts +3 -3
  40. package/lib/resources/query/handlers.d.ts +3 -1
  41. package/lib/resources/request.d.ts +13 -2
  42. package/lib/resources/resource.d.ts +2 -9
  43. package/lib/resources/responses/annotations.d.ts +17 -12
  44. package/lib/resources/responses/types.d.ts +3 -3
  45. package/lib/resources/types/count.d.ts +1 -1
  46. package/lib/resources/types/entity-set.d.ts +23 -6
  47. package/lib/resources/types/entity.d.ts +8 -24
  48. package/lib/resources/types/media.d.ts +7 -15
  49. package/lib/resources/types/metadata.d.ts +1 -1
  50. package/lib/resources/types/navigation-property.d.ts +26 -28
  51. package/lib/resources/types/options.d.ts +4 -2
  52. package/lib/resources/types/property.d.ts +28 -15
  53. package/lib/resources/types/reference.d.ts +3 -12
  54. package/lib/resources/types/singleton.d.ts +8 -27
  55. package/lib/services/entity-set.d.ts +15 -6
  56. package/lib/utils/http.d.ts +1 -1
  57. package/lib/utils/objects.d.ts +19 -5
  58. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common/http';
2
2
  import { HttpHeaders, HttpParams, HttpResponse, HttpErrorResponse, HttpEventType, HttpClientModule } from '@angular/common/http';
3
3
  import { of, throwError, Subject, map as map$1, firstValueFrom, EMPTY, Observable, forkJoin, NEVER } from 'rxjs';
4
- import { tap, startWith, map, expand, concatMap, toArray, finalize, switchMap, catchError } from 'rxjs/operators';
4
+ import { tap, startWith, map, expand, reduce, finalize, switchMap, catchError } from 'rxjs/operators';
5
5
  import * as i0 from '@angular/core';
6
6
  import { EventEmitter, Injectable, InjectionToken, NgModule } from '@angular/core';
7
7
 
@@ -3120,6 +3120,7 @@ class ODataRequest {
3120
3120
  this.api = init.api;
3121
3121
  this.reportProgress = init.reportProgress;
3122
3122
  this.observe = init.observe;
3123
+ this.context = init.context;
3123
3124
  // Response Type
3124
3125
  this._responseType = init.responseType;
3125
3126
  // The Body
@@ -3212,6 +3213,33 @@ class ODataRequest {
3212
3213
  : params;
3213
3214
  //#endregion
3214
3215
  }
3216
+ static factory(api, method, resource, options) {
3217
+ const apiOptions = api.options;
3218
+ let params = options.params || {};
3219
+ if (options.withCount) {
3220
+ params = Http.mergeHttpParams(params, apiOptions.helper.countParam());
3221
+ }
3222
+ let etag = options.etag;
3223
+ if (etag === undefined && Types.isPlainObject(options.body)) {
3224
+ etag = apiOptions.helper.etag(options.body);
3225
+ }
3226
+ return new ODataRequest({
3227
+ method,
3228
+ etag,
3229
+ api,
3230
+ resource,
3231
+ params,
3232
+ context: options.context,
3233
+ body: options.body,
3234
+ observe: options.observe,
3235
+ headers: options.headers,
3236
+ reportProgress: options.reportProgress,
3237
+ responseType: options.responseType,
3238
+ fetchPolicy: options.fetchPolicy,
3239
+ withCredentials: options.withCredentials,
3240
+ bodyQueryOptions: options.bodyQueryOptions,
3241
+ });
3242
+ }
3215
3243
  get responseType() {
3216
3244
  return this._responseType &&
3217
3245
  ['property', 'entity', 'entities'].indexOf(this._responseType) !== -1
@@ -3400,7 +3428,8 @@ const ODataVersionBaseHelper = {
3400
3428
  };
3401
3429
  const ODataHelper = {
3402
3430
  //#region Version 4.0
3403
- [VERSION_4_0]: { ...ODataVersionBaseHelper,
3431
+ [VERSION_4_0]: {
3432
+ ...ODataVersionBaseHelper,
3404
3433
  VALUE: 'value',
3405
3434
  ODATA_ANNOTATION_PREFIX: '@odata',
3406
3435
  ODATA_FUNCTION_PREFIX: '#',
@@ -3484,10 +3513,12 @@ const ODataHelper = {
3484
3513
  },
3485
3514
  countParam() {
3486
3515
  return { [$COUNT]: 'true' };
3487
- }, },
3516
+ },
3517
+ },
3488
3518
  //#endregion
3489
3519
  //#region Version 3.0
3490
- [VERSION_3_0]: { ...ODataVersionBaseHelper,
3520
+ [VERSION_3_0]: {
3521
+ ...ODataVersionBaseHelper,
3491
3522
  ODATA_ANNOTATION_PREFIX: 'odata.',
3492
3523
  ODATA_FUNCTION_PREFIX: '',
3493
3524
  ODATA_ID: 'odata.id',
@@ -3514,10 +3545,12 @@ const ODataHelper = {
3514
3545
  },
3515
3546
  countParam() {
3516
3547
  return { [$INLINECOUNT]: 'allpages' };
3517
- }, },
3548
+ },
3549
+ },
3518
3550
  //#endregion
3519
3551
  //#region Version 2.0
3520
- [VERSION_2_0]: { ...ODataVersionBaseHelper,
3552
+ [VERSION_2_0]: {
3553
+ ...ODataVersionBaseHelper,
3521
3554
  ODATA_ID: 'id',
3522
3555
  ODATA_ETAG: 'etag',
3523
3556
  ODATA_ANNOTATION: '__metadata',
@@ -3533,12 +3566,17 @@ const ODataHelper = {
3533
3566
  }
3534
3567
  return annots;
3535
3568
  },
3569
+ context(annots) {
3570
+ let ctx = {};
3571
+ return ctx;
3572
+ },
3536
3573
  attributes(value, metadata) {
3537
3574
  return value;
3538
3575
  },
3539
3576
  countParam() {
3540
3577
  return { [$INLINECOUNT]: 'allpages' };
3541
- }, },
3578
+ },
3579
+ },
3542
3580
  //#endregion
3543
3581
  };
3544
3582
 
@@ -3725,13 +3763,13 @@ const EDM_PARSERS = {
3725
3763
  //Edm.Int64 Signed 16-bit integer
3726
3764
  'Edm.Int64': EdmParser(toNumber, toNumber, toNumber),
3727
3765
  //Edm.Date Date without a time-zone offset
3728
- 'Edm.Date': EdmParser((v) => new Date(`${v}T00:00:00.000Z`), (v) => toDate(v).toISOString().substring(0, 10), (v) => toDate(v).toISOString().substring(0, 10)),
3766
+ 'Edm.Date': EdmParser((v) => new Date(`${v}T00:00:00.000Z`), (v) => toDate(v).toISOString().substring(0, 10), (v) => raw(toDate(v).toISOString().substring(0, 10))),
3729
3767
  //Edm.TimeOfDay Clock time 00:00-23:59:59.999999999999
3730
- 'Edm.TimeOfDay': EdmParser((v) => new Date(`1970-01-01T${v}Z`), (v) => toDate(v).toISOString().substring(11, 23), (v) => toDate(v).toISOString().substring(11, 23)),
3768
+ 'Edm.TimeOfDay': EdmParser((v) => new Date(`1970-01-01T${v}Z`), (v) => toDate(v).toISOString().substring(11, 23), (v) => raw(toDate(v).toISOString().substring(11, 23))),
3731
3769
  //Edm.DateTimeOffset Date and time with a time-zone offset, no leap seconds
3732
- 'Edm.DateTimeOffset': EdmParser(toDate, (v) => toDate(v).toISOString(), (v) => toDate(v).toISOString()),
3770
+ 'Edm.DateTimeOffset': EdmParser(toDate, (v) => toDate(v).toISOString(), (v) => raw(toDate(v).toISOString())),
3733
3771
  //Edm.Duration Signed duration in days, hours, minutes, and (sub)seconds
3734
- 'Edm.Duration': EdmParser((v) => Durations.toDuration(v), (v) => Durations.toString(v), (v) => Durations.toString(v)),
3772
+ 'Edm.Duration': EdmParser((v) => Durations.toDuration(v), (v) => Durations.toString(v), (v) => raw(Durations.toString(v))),
3735
3773
  //Edm.Decimal Numeric values with fixed precision and scale
3736
3774
  'Edm.Decimal': EdmParser((v, o) => {
3737
3775
  if (typeof v === 'string' && o.ieee754Compatible) {
@@ -3753,16 +3791,16 @@ const EDM_PARSERS = {
3753
3791
  if (typeof o.field.scale === 'number') {
3754
3792
  vstr = parseFloat(vstr).toFixed(o.field.scale);
3755
3793
  }
3756
- return vstr;
3794
+ return raw(vstr);
3757
3795
  }
3758
3796
  return v;
3759
3797
  }),
3760
3798
  //Edm.Double IEEE 754 binary64 floating-point number (15-17 decimal digits)
3761
- 'Edm.Double': EdmParser((v) => (v === 'INF' ? Infinity : v), (v) => (v === Infinity ? 'INF' : v), (v) => (v === Infinity ? 'INF' : v)),
3799
+ 'Edm.Double': EdmParser((v) => (v === 'INF' ? Infinity : v), (v) => (v === Infinity ? 'INF' : v), (v) => raw((v === Infinity ? 'INF' : v.toString()))),
3762
3800
  //Edm.Single IEEE 754 binary32 floating-point number (6-9 decimal digits)
3763
- 'Edm.Single': EdmParser((v) => (v === 'INF' ? Infinity : v), (v) => (v === Infinity ? 'INF' : v), (v) => (v === Infinity ? 'INF' : v)),
3801
+ 'Edm.Single': EdmParser((v) => (v === 'INF' ? Infinity : v), (v) => (v === Infinity ? 'INF' : v), (v) => raw((v === Infinity ? 'INF' : v.toString()))),
3764
3802
  //Edm.Binary Binary data
3765
- 'Edm.Binary': EdmParser((v) => ArrayBuffers.toArrayBuffer(v), (v) => ArrayBuffers.toString(v), (v) => ArrayBuffers.toString(v)),
3803
+ 'Edm.Binary': EdmParser((v) => ArrayBuffers.toArrayBuffer(v), (v) => ArrayBuffers.toString(v), (v) => raw(ArrayBuffers.toString(v))),
3766
3804
  };
3767
3805
  /*
3768
3806
  Edm.Stream Binary data stream
@@ -5098,61 +5136,20 @@ class ODataResource {
5098
5136
  return ODataResource.resolveKey(value, this.schema);
5099
5137
  }
5100
5138
  //#endregion
5101
- // Base Requests
5102
- request(method, options) {
5103
- const apiOptions = this.api.options;
5104
- let params = options.params || {};
5105
- if (options.withCount) {
5106
- params = Http.mergeHttpParams(params, apiOptions.helper.countParam());
5107
- }
5108
- let etag = options.etag;
5109
- if (etag === undefined && Types.isPlainObject(options.body)) {
5110
- etag = apiOptions.helper.etag(options.body);
5111
- }
5112
- const request = new ODataRequest({
5113
- method,
5114
- etag,
5115
- body: options.body,
5116
- api: this.api,
5117
- resource: this,
5118
- observe: 'response',
5119
- headers: options.headers,
5120
- reportProgress: options.reportProgress,
5121
- params: params,
5122
- responseType: options.responseType,
5123
- fetchPolicy: options.fetchPolicy,
5124
- withCredentials: options.withCredentials,
5125
- bodyQueryOptions: options.bodyQueryOptions,
5126
- });
5127
- const res$ = this.api.request(request);
5128
- switch (options.responseType) {
5129
- case 'entities':
5130
- return res$.pipe(map((res) => res.entities()));
5131
- case 'entity':
5132
- return res$.pipe(map((res) => res.entity()));
5133
- case 'property':
5134
- return res$.pipe(map((res) => res.property()));
5135
- case 'value':
5136
- return res$.pipe(map((res) => res.value()));
5137
- default:
5138
- // Other responseTypes (arraybuffer, blob, json, text) return body
5139
- return res$.pipe(map((res) => res.body));
5140
- }
5141
- }
5142
5139
  get(options = {}) {
5143
- return this.request('GET', options);
5140
+ return this.api.request('GET', this, options);
5144
5141
  }
5145
5142
  post(body, options = {}) {
5146
- return this.request('POST', { body, ...options });
5143
+ return this.api.request('POST', this, { body, ...options });
5147
5144
  }
5148
5145
  put(body, options = {}) {
5149
- return this.request('PUT', { body, ...options });
5146
+ return this.api.request('PUT', this, { body, ...options });
5150
5147
  }
5151
5148
  patch(body, options = {}) {
5152
- return this.request('PATCH', { body, ...options });
5149
+ return this.api.request('PATCH', this, { body, ...options });
5153
5150
  }
5154
5151
  delete(options = {}) {
5155
- return this.request('DELETE', options);
5152
+ return this.api.request('DELETE', this, options);
5156
5153
  }
5157
5154
  }
5158
5155
 
@@ -5374,18 +5371,16 @@ class ODataBatchResource extends ODataResource {
5374
5371
  [CONTENT_TYPE]: MULTIPART_MIXED_BOUNDARY + bound,
5375
5372
  [ACCEPT]: MULTIPART_MIXED,
5376
5373
  });
5377
- const request = new ODataRequest({
5378
- method: 'POST',
5374
+ return this.api
5375
+ .request('POST', this, {
5379
5376
  body: ODataBatchResource.buildBody(bound, this._requests),
5380
- api: this.api,
5381
- resource: this,
5382
- observe: 'response',
5383
5377
  responseType: 'text',
5378
+ observe: 'response',
5384
5379
  headers: headers,
5385
5380
  params: options ? options.params : undefined,
5386
5381
  withCredentials: options ? options.withCredentials : undefined,
5387
- });
5388
- return this.api.request(request).pipe(map$1((response) => {
5382
+ })
5383
+ .pipe(map$1((response) => {
5389
5384
  if (this._responses == null) {
5390
5385
  this._responses = [];
5391
5386
  }
@@ -5816,7 +5811,7 @@ class ODataValueResource extends ODataResource {
5816
5811
  }
5817
5812
  //#endregion
5818
5813
  //#region Requests
5819
- get(options) {
5814
+ get(options = {}) {
5820
5815
  return super.get({ responseType: 'value', ...options });
5821
5816
  }
5822
5817
  //#endregion
@@ -5991,6 +5986,24 @@ class ODataPropertyResource extends ODataResource {
5991
5986
  ? this.asCollection(entities, { annots, reset: true })
5992
5987
  : null));
5993
5988
  }
5989
+ fetchOne(options) {
5990
+ let res = this.clone();
5991
+ res.query((q) => q.top(1));
5992
+ return res.fetch({ responseType: 'entities', ...options }).pipe(map(({ entities, annots }) => ({ entity: entities !== null ? entities[0] || null : null, annots })));
5993
+ }
5994
+ fetchMany(top, options) {
5995
+ let res = this.clone();
5996
+ let fetch = (opts) => {
5997
+ if (opts) {
5998
+ res.query((q) => q.paging(opts));
5999
+ }
6000
+ return res.fetch({ responseType: 'entities', ...options });
6001
+ };
6002
+ return fetch({ top }).pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
6003
+ entities: [...(acc.entities || []), ...(entities || [])],
6004
+ annots: acc.annots.union(annots)
6005
+ })));
6006
+ }
5994
6007
  /**
5995
6008
  * Fetch all entities
5996
6009
  * @param options Options for the request
@@ -6006,7 +6019,10 @@ class ODataPropertyResource extends ODataResource {
6006
6019
  }
6007
6020
  return res.fetch({ responseType: 'entities', ...options });
6008
6021
  };
6009
- return fetch().pipe(expand(({ annots: meta }) => meta.skip || meta.skiptoken ? fetch(meta) : EMPTY), concatMap(({ entities }) => entities || []), toArray());
6022
+ return fetch().pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
6023
+ entities: [...(acc.entities || []), ...(entities || [])],
6024
+ annots: acc.annots.union(annots)
6025
+ })));
6010
6026
  }
6011
6027
  }
6012
6028
 
@@ -6234,7 +6250,6 @@ class ODataNavigationPropertyResource extends ODataResource {
6234
6250
  * Update an existing entity
6235
6251
  * @param attrs The entity attributes
6236
6252
  * @param options Options for the request
6237
- * @param etag The etag of the entity
6238
6253
  * @returns The updated entity with the annotations
6239
6254
  */
6240
6255
  update(attrs, options) {
@@ -6244,7 +6259,6 @@ class ODataNavigationPropertyResource extends ODataResource {
6244
6259
  * Modify an existing entity
6245
6260
  * @param attrs The entity attributes
6246
6261
  * @param options Options for the request
6247
- * @param etag The etag of the entity
6248
6262
  * @returns The modified entity with the annotations
6249
6263
  */
6250
6264
  modify(attrs, options) {
@@ -6253,7 +6267,6 @@ class ODataNavigationPropertyResource extends ODataResource {
6253
6267
  /**
6254
6268
  * Delete an existing entity
6255
6269
  * @param options Options for the request
6256
- * @param etag The etag of the entity
6257
6270
  * @returns An observable of the destroy
6258
6271
  */
6259
6272
  destroy(options) {
@@ -6298,6 +6311,24 @@ class ODataNavigationPropertyResource extends ODataResource {
6298
6311
  ? this.asCollection(entities, { annots, reset: true })
6299
6312
  : null));
6300
6313
  }
6314
+ fetchOne(options) {
6315
+ let res = this.clone();
6316
+ res.query((q) => q.top(1));
6317
+ return res.fetch({ responseType: 'entities', ...options }).pipe(map(({ entities, annots }) => ({ entity: entities !== null ? entities[0] || null : null, annots })));
6318
+ }
6319
+ fetchMany(top, options) {
6320
+ let res = this.clone();
6321
+ let fetch = (opts) => {
6322
+ if (opts) {
6323
+ res.query((q) => q.paging(opts));
6324
+ }
6325
+ return res.fetch({ responseType: 'entities', ...options });
6326
+ };
6327
+ return fetch({ top }).pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
6328
+ entities: [...(acc.entities || []), ...(entities || [])],
6329
+ annots: acc.annots.union(annots)
6330
+ })));
6331
+ }
6301
6332
  /**
6302
6333
  * Fetch all entities
6303
6334
  * @param options Options for the request
@@ -6313,7 +6344,10 @@ class ODataNavigationPropertyResource extends ODataResource {
6313
6344
  }
6314
6345
  return res.fetch({ responseType: 'entities', ...options });
6315
6346
  };
6316
- return fetch().pipe(expand(({ annots: meta }) => meta.skip || meta.skiptoken ? fetch(meta) : EMPTY), concatMap(({ entities }) => entities || []), toArray());
6347
+ return fetch().pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
6348
+ entities: [...(acc.entities || []), ...(entities || [])],
6349
+ annots: acc.annots.union(annots)
6350
+ })));
6317
6351
  }
6318
6352
  }
6319
6353
 
@@ -6469,7 +6503,7 @@ class ODataEntitySetResource extends ODataResource {
6469
6503
  });
6470
6504
  }
6471
6505
  //#region Requests
6472
- post(attrs, options = {}) {
6506
+ post(attrs, options) {
6473
6507
  return super.post(attrs, { responseType: 'entity', ...options });
6474
6508
  }
6475
6509
  get(options = {}) {
@@ -6483,13 +6517,23 @@ class ODataEntitySetResource extends ODataResource {
6483
6517
  fetch(options) {
6484
6518
  return this.get(options);
6485
6519
  }
6486
- fetchEntities(options) {
6487
- return this.fetch(options).pipe(map(({ entities }) => entities));
6520
+ fetchOne(options) {
6521
+ let res = this.clone();
6522
+ res.query((q) => q.top(1));
6523
+ return res.fetch(options).pipe(map(({ entities, annots }) => ({ entity: entities !== null ? entities[0] || null : null, annots })));
6488
6524
  }
6489
- fetchCollection(options) {
6490
- return this.fetch(options).pipe(map(({ entities, annots }) => entities
6491
- ? this.asCollection(entities, { annots, reset: true })
6492
- : null));
6525
+ fetchMany(top, options) {
6526
+ let res = this.clone();
6527
+ let fetch = (opts) => {
6528
+ if (opts) {
6529
+ res.query((q) => q.paging(opts));
6530
+ }
6531
+ return res.fetch(options);
6532
+ };
6533
+ return fetch({ top }).pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
6534
+ entities: [...(acc.entities || []), ...(entities || [])],
6535
+ annots: acc.annots.union(annots)
6536
+ })));
6493
6537
  }
6494
6538
  fetchAll(options) {
6495
6539
  let res = this.clone();
@@ -6501,7 +6545,19 @@ class ODataEntitySetResource extends ODataResource {
6501
6545
  }
6502
6546
  return res.fetch(options);
6503
6547
  };
6504
- return fetch().pipe(expand(({ annots: meta }) => meta.skip || meta.skiptoken ? fetch(meta) : EMPTY), concatMap(({ entities }) => entities || []), toArray());
6548
+ return fetch().pipe(expand(({ annots }) => annots.skip || annots.skiptoken ? fetch(annots) : EMPTY), map(({ entities, annots }) => ({ entities: entities || [], annots })), reduce((acc, { entities, annots }) => ({
6549
+ entities: [...(acc.entities || []), ...(entities || [])],
6550
+ annots: acc.annots.union(annots)
6551
+ })));
6552
+ }
6553
+ //#endregion
6554
+ fetchEntities(options) {
6555
+ return this.fetch(options).pipe(map(({ entities }) => entities));
6556
+ }
6557
+ fetchCollection(options) {
6558
+ return this.fetch(options).pipe(map(({ entities, annots }) => entities
6559
+ ? this.asCollection(entities, { annots, reset: true })
6560
+ : null));
6505
6561
  }
6506
6562
  }
6507
6563
 
@@ -6528,6 +6584,9 @@ class ODataAnnotations {
6528
6584
  }
6529
6585
  }
6530
6586
  class ODataPropertyAnnotations extends ODataAnnotations {
6587
+ union(other) {
6588
+ return new ODataPropertyAnnotations(this.helper, new Map([...this.annotations, ...other.annotations]), Object.assign({}, this.context, other.context));
6589
+ }
6531
6590
  clone() {
6532
6591
  return new ODataPropertyAnnotations(this.helper, new Map(this.annotations), this.context);
6533
6592
  }
@@ -6536,6 +6595,9 @@ class ODataPropertyAnnotations extends ODataAnnotations {
6536
6595
  }
6537
6596
  }
6538
6597
  class ODataEntityAnnotations extends ODataAnnotations {
6598
+ union(other) {
6599
+ return new ODataEntityAnnotations(this.helper, new Map([...this.annotations, ...other.annotations]), Object.assign({}, this.context, other.context));
6600
+ }
6539
6601
  clone() {
6540
6602
  return new ODataEntityAnnotations(this.helper, new Map(this.annotations), this.context);
6541
6603
  }
@@ -6575,8 +6637,11 @@ class ODataEntityAnnotations extends ODataAnnotations {
6575
6637
  }
6576
6638
  return this._properties;
6577
6639
  }
6578
- property(name) {
6579
- return this.properties.get(name);
6640
+ property(name, type) {
6641
+ const props = this.properties.get(name);
6642
+ return type === 'collection'
6643
+ ? new ODataEntitiesAnnotations(this.helper, props)
6644
+ : new ODataEntityAnnotations(this.helper, props);
6580
6645
  }
6581
6646
  get functions() {
6582
6647
  if (this._functions === undefined) {
@@ -6589,6 +6654,9 @@ class ODataEntityAnnotations extends ODataAnnotations {
6589
6654
  }
6590
6655
  }
6591
6656
  class ODataEntitiesAnnotations extends ODataAnnotations {
6657
+ union(other) {
6658
+ return new ODataEntitiesAnnotations(this.helper, new Map([...this.annotations, ...other.annotations]), Object.assign({}, this.context, other.context));
6659
+ }
6592
6660
  clone() {
6593
6661
  return new ODataEntitiesAnnotations(this.helper, new Map(this.annotations), this.context);
6594
6662
  }
@@ -7657,14 +7725,12 @@ class ODataMetadataResource extends ODataResource {
7657
7725
  //#endregion
7658
7726
  //#region Requests
7659
7727
  get(options) {
7660
- return super
7661
- .get({ responseType: 'text', ...options })
7662
- .pipe(map((body) => new ODataMetadata(body)));
7728
+ return super.get({ responseType: 'text', ...options });
7663
7729
  }
7664
7730
  //#endregion
7665
7731
  //#region Shortcuts
7666
7732
  fetch(options) {
7667
- return this.get(options);
7733
+ return this.get(options).pipe(map((body) => new ODataMetadata(body)));
7668
7734
  }
7669
7735
  }
7670
7736
 
@@ -7763,7 +7829,6 @@ class ODataSingletonResource extends ODataResource {
7763
7829
  /**
7764
7830
  * Fetch an existing entity.
7765
7831
  * @param options The options for the request.
7766
- * @param etag The etag to use for the request.
7767
7832
  * @returns Observable of the entity with the annotations.
7768
7833
  */
7769
7834
  fetch(options) {
@@ -7772,7 +7837,6 @@ class ODataSingletonResource extends ODataResource {
7772
7837
  /**
7773
7838
  * Fetch an existing entity.
7774
7839
  * @param options The options for the request.
7775
- * @param etag The etag to use for the request.
7776
7840
  * @returns Observable of the entity.
7777
7841
  */
7778
7842
  fetchEntity(options) {
@@ -7781,7 +7845,6 @@ class ODataSingletonResource extends ODataResource {
7781
7845
  /**
7782
7846
  * Fetch an existing entity and return a model.
7783
7847
  * @param options The options for the request.
7784
- * @param etag The etag to use for the request.
7785
7848
  * @returns Observable of the entity.
7786
7849
  */
7787
7850
  fetchModel(options) {
@@ -8091,9 +8154,9 @@ class ODataModelField {
8091
8154
  : base.property(this.parser.name);
8092
8155
  }
8093
8156
  annotationsFactory(base) {
8094
- return this.parser.collection
8095
- ? new ODataEntitiesAnnotations(base.helper, base.property(this.parser.name))
8096
- : new ODataEntityAnnotations(base.helper, base.property(this.parser.name));
8157
+ return this.parser.collection ?
8158
+ base.property(this.parser.name, 'collection') :
8159
+ base.property(this.parser.name, 'single');
8097
8160
  }
8098
8161
  schemaFactory(base) {
8099
8162
  return this.api.findStructuredTypeForType(this.parser.type);
@@ -8947,12 +9010,6 @@ class ODataCollection {
8947
9010
  get length() {
8948
9011
  return this.models().length;
8949
9012
  }
8950
- isEmpty() {
8951
- // Local length and if exists remote length
8952
- return (this.length === 0 &&
8953
- this.annots().count !== undefined &&
8954
- this.annots().count === 0);
8955
- }
8956
9013
  isParentOf(child) {
8957
9014
  return (child !== this &&
8958
9015
  ODataModelOptions.chain(child).some((p) => p[0] === this));
@@ -9057,6 +9114,15 @@ class ODataCollection {
9057
9114
  annots: this.annots(),
9058
9115
  });
9059
9116
  }
9117
+ _request(obs$) {
9118
+ this.events$.emit(new ODataModelEvent('request', { collection: this, options: { observable: obs$ } }));
9119
+ return obs$.pipe(map(({ entities, annots }) => {
9120
+ this._annotations = annots;
9121
+ this.assign(entities || [], { reset: true });
9122
+ this.events$.emit(new ODataModelEvent('sync', { collection: this, options: { entities, annots } }));
9123
+ return this;
9124
+ }));
9125
+ }
9060
9126
  fetch({ withCount, ...options } = {}) {
9061
9127
  const resource = this.resource();
9062
9128
  const obs$ = resource instanceof ODataEntitySetResource
@@ -9066,32 +9132,17 @@ class ODataCollection {
9066
9132
  withCount,
9067
9133
  ...options,
9068
9134
  });
9069
- this.events$.emit(new ODataModelEvent('request', { collection: this, value: obs$ }));
9070
- return obs$.pipe(map(({ entities, annots }) => {
9071
- this._annotations = annots;
9072
- this.assign(entities || [], { reset: true });
9073
- this.events$.emit(new ODataModelEvent('sync', { collection: this }));
9074
- return this;
9075
- }));
9135
+ return this._request(obs$);
9076
9136
  }
9077
- fetchAll(options) {
9137
+ fetchMany(top, { withCount, ...options } = {}) {
9078
9138
  const resource = this.resource();
9079
- if (resource instanceof ODataPropertyResource)
9080
- return throwError(() => new Error('fetchAll: Resource is ODataPropertyResource'));
9081
- const obs$ = resource.fetchAll(options);
9082
- this.events$.emit(new ODataModelEvent('request', {
9083
- collection: this,
9084
- options: { observable: obs$ },
9085
- }));
9086
- return obs$.pipe(map((entities) => {
9087
- this._annotations = new ODataEntitiesAnnotations(ODataHelper[resource?.api?.options.version || DEFAULT_VERSION]);
9088
- this.assign(entities || [], { reset: true });
9089
- this.events$.emit(new ODataModelEvent('sync', {
9090
- collection: this,
9091
- options: { entities },
9092
- }));
9093
- return this;
9094
- }));
9139
+ const obs$ = resource.fetchMany(top, { withCount, ...options });
9140
+ return this._request(obs$);
9141
+ }
9142
+ fetchAll({ withCount, ...options } = {}) {
9143
+ const resource = this.resource();
9144
+ const obs$ = resource.fetchAll({ withCount, ...options });
9145
+ return this._request(obs$);
9095
9146
  }
9096
9147
  /**
9097
9148
  * Save all models in the collection
@@ -9656,6 +9707,12 @@ class ODataCollection {
9656
9707
  const m = models.find((m) => m.equals(model));
9657
9708
  return m === undefined ? -1 : models.indexOf(m);
9658
9709
  }
9710
+ isEmpty() {
9711
+ // Local length and if exists remote length
9712
+ return (this.length === 0 &&
9713
+ this.annots().count !== undefined &&
9714
+ this.annots().count === 0);
9715
+ }
9659
9716
  //#region Sort
9660
9717
  _bisect(model) {
9661
9718
  let index = -1;
@@ -9721,6 +9778,7 @@ class ODataModel {
9721
9778
  this._changes = new Map();
9722
9779
  this._relations = new Map();
9723
9780
  this._resource = null;
9781
+ this._annotations = null;
9724
9782
  this._reset = false;
9725
9783
  this._reparent = false;
9726
9784
  this._silent = false;
@@ -9791,7 +9849,7 @@ class ODataModel {
9791
9849
  return this._meta.schema;
9792
9850
  }
9793
9851
  annots() {
9794
- return this._annotations;
9852
+ return this._annotations ?? new ODataEntityAnnotations(ODataHelper[DEFAULT_VERSION]);
9795
9853
  }
9796
9854
  key({ field_mapping = false, resolve = true, } = {}) {
9797
9855
  return this._meta.resolveKey(this, { field_mapping, resolve });
@@ -10329,16 +10387,54 @@ class ODataApi {
10329
10387
  const schema = this.findCallableForType(path);
10330
10388
  return ODataFunctionResource.factory(this, { path, schema });
10331
10389
  }
10332
- request(req) {
10390
+ //request(req: ODataRequest<any>): Observable<any> {
10391
+ request(method, resource, options) {
10392
+ let req = ODataRequest.factory(this, method, resource, {
10393
+ body: options.body,
10394
+ etag: options.etag,
10395
+ context: options.context,
10396
+ headers: options.headers,
10397
+ params: options.params,
10398
+ responseType: options.responseType,
10399
+ observe: (options.observe === 'events' ? 'events' : 'response'),
10400
+ withCount: options.withCount,
10401
+ bodyQueryOptions: options.bodyQueryOptions,
10402
+ reportProgress: options.reportProgress,
10403
+ fetchPolicy: options.fetchPolicy,
10404
+ withCredentials: options.withCredentials,
10405
+ });
10333
10406
  let res$ = this.requester !== undefined ? this.requester(req) : NEVER;
10334
10407
  res$ = res$.pipe(map((res) => res.type === HttpEventType.Response
10335
10408
  ? ODataResponse.fromHttpResponse(req, res)
10336
10409
  : res));
10337
10410
  if (this.errorHandler !== undefined)
10338
10411
  res$ = res$.pipe(catchError(this.errorHandler));
10339
- return req.observe === 'response'
10340
- ? this.cache.handleRequest(req, res$)
10341
- : res$;
10412
+ if (options.observe === 'events') {
10413
+ return res$;
10414
+ }
10415
+ res$ = this.cache.handleRequest(req, res$);
10416
+ switch (options.observe || 'body') {
10417
+ case 'body':
10418
+ switch (options.responseType) {
10419
+ case 'entities':
10420
+ return res$.pipe(map((res) => res.entities()));
10421
+ case 'entity':
10422
+ return res$.pipe(map((res) => res.entity()));
10423
+ case 'property':
10424
+ return res$.pipe(map((res) => res.property()));
10425
+ case 'value':
10426
+ return res$.pipe(map((res) => res.value()));
10427
+ default:
10428
+ // Other responseTypes (arraybuffer, blob, json, text) return body
10429
+ return res$.pipe(map((res) => res.body));
10430
+ }
10431
+ case 'response':
10432
+ // The response stream was requested directly, so return it.
10433
+ return res$;
10434
+ default:
10435
+ // Guard against new future observe types being added.
10436
+ throw new Error(`Unreachable: unhandled observe type ${options.observe}}`);
10437
+ }
10342
10438
  }
10343
10439
  findSchemaForType(type) {
10344
10440
  const schemas = this.schemas.filter((s) => s.isNamespaceOf(type));
@@ -10734,7 +10830,6 @@ function addBody(options, body) {
10734
10830
  return {
10735
10831
  body,
10736
10832
  etag: options.etag,
10737
- apiName: options.apiName,
10738
10833
  fetchPolicy: options.fetchPolicy,
10739
10834
  headers: options.headers,
10740
10835
  observe: options.observe,
@@ -10752,6 +10847,7 @@ class ODataClient {
10752
10847
  this.settings.configure({
10753
10848
  requester: (req) => this.http.request(req.method, `${req.url}`, {
10754
10849
  body: req.body,
10850
+ context: req.context,
10755
10851
  headers: req.headers,
10756
10852
  observe: req.observe,
10757
10853
  params: req.params,
@@ -10928,32 +11024,8 @@ class ODataClient {
10928
11024
  return this.apiFor(apiNameOrType).function(path);
10929
11025
  }
10930
11026
  request(method, resource, options) {
10931
- let api = options.apiName
10932
- ? this.settings.apiByName(options.apiName)
10933
- : resource.api;
10934
- if (!api)
10935
- throw new Error(`The types: '[${resource
10936
- .types()
10937
- .join(', ')}]' does not belongs to any known configuration`);
10938
- const request = new ODataRequest({
10939
- method,
10940
- api,
10941
- resource,
10942
- body: options.body,
10943
- observe: options.observe === 'events' ? 'events' : 'response',
10944
- etag: options.etag,
10945
- headers: options.headers,
10946
- reportProgress: options.reportProgress,
10947
- params: options.params,
10948
- responseType: options.responseType,
10949
- fetchPolicy: options.fetchPolicy,
10950
- withCredentials: options.withCredentials,
10951
- });
10952
- return api
10953
- .request(request)
10954
- .pipe(map((res) => options.observe === undefined || options.observe === 'body'
10955
- ? res.body
10956
- : res));
11027
+ let api = this.apiFor(resource);
11028
+ return api.request(method, resource, options);
10957
11029
  }
10958
11030
  delete(resource, options = {}) {
10959
11031
  return this.request('DELETE', resource, addBody(options, null));
@@ -11076,8 +11148,8 @@ class ODataEntitySetService extends ODataEntityService {
11076
11148
  * @param withCount Get the count of the entities.
11077
11149
  * @param options The options for the request.
11078
11150
  */
11079
- fetchMany(options) {
11080
- return this.entities().fetch(options);
11151
+ fetchMany(top, options) {
11152
+ return this.entities().fetchMany(top, options);
11081
11153
  }
11082
11154
  /**
11083
11155
  * Get an entity from the entity set.
@@ -11085,8 +11157,8 @@ class ODataEntitySetService extends ODataEntityService {
11085
11157
  * @param etag The etag for the entity.
11086
11158
  * @param options The options for the request.
11087
11159
  */
11088
- fetchOne(key, options) {
11089
- return this.entity(key).fetch(options);
11160
+ fetchOne(options) {
11161
+ return this.entities().fetchOne(options);
11090
11162
  }
11091
11163
  /**
11092
11164
  * Create an entity in the entity set.
@@ -11143,11 +11215,11 @@ class ODataEntitySetService extends ODataEntityService {
11143
11215
  * @param options The options for the request.
11144
11216
  */
11145
11217
  fetchOrCreate(key, attrs, { etag, ...options } = {}) {
11146
- return this.fetchOne(key, { etag, ...options }).pipe(catchError((error) => {
11218
+ return this.entity(key).fetch({ etag, ...options }).pipe(catchError((error) => {
11147
11219
  if (error.status === 404)
11148
11220
  return this.create(attrs, options);
11149
11221
  else
11150
- return throwError(error);
11222
+ return throwError(() => error);
11151
11223
  }));
11152
11224
  }
11153
11225
  /**