angular-odata 0.124.0 → 0.125.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.
@@ -196,6 +196,7 @@ const NEWLINE_REGEXP = /\r?\n/;
196
196
  const CACHE_KEY_SEPARATOR = ':';
197
197
  // Models
198
198
  const CID_FIELD_NAME = '_cid';
199
+ const EVENT_SPLITTER = /\s+/;
199
200
  // Standard vocabularies for annotating OData services
200
201
  // https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md
201
202
  const COMPUTED = /.*Computed$/;
@@ -1723,7 +1724,16 @@ function resolve(values, parser) {
1723
1724
  }
1724
1725
  function encode(values, parser) {
1725
1726
  if (parser !== undefined) {
1726
- return values.map((v) => Types.isObject(v) || v === null ? v : parser?.encode(v));
1727
+ return values.map((v) => {
1728
+ if (Types.isObject(v) || v == null)
1729
+ return v;
1730
+ try {
1731
+ return parser.encode(v);
1732
+ }
1733
+ catch {
1734
+ return v;
1735
+ }
1736
+ });
1727
1737
  }
1728
1738
  return values;
1729
1739
  }
@@ -3721,7 +3731,7 @@ const ODataHelper = {
3721
3731
  //odata.etag: the ETag of the entity
3722
3732
  ODATA_ETAG: '@odata.etag',
3723
3733
  ODATA_METADATA_ETAG: '@odata.metadataEtag',
3724
- //odata.type: the type of the containing {[key: string]: any} or targeted property if the type of the {[key: string]: any} or targeted property cannot be heuristically determined
3734
+ //odata.type: the type of the containing {[name: string]: any} or targeted property if the type of the {[name: string]: any} or targeted property cannot be heuristically determined
3725
3735
  ODATA_TYPE: '@odata.type',
3726
3736
  //odata.nextLink: the next link of a collection with partial results
3727
3737
  ODATA_NEXTLINK: '@odata.nextLink',
@@ -8366,40 +8376,42 @@ var ODataModelEventType;
8366
8376
  ODataModelEventType["Attach"] = "attach";
8367
8377
  })(ODataModelEventType || (ODataModelEventType = {}));
8368
8378
  class ODataModelEvent {
8369
- constructor(name, { model, collection, previous, value, attr, options, } = {}) {
8370
- this.bubbling = true;
8379
+ constructor(name, { model, collection, previous, value, attr, options, bubbly, chain, } = {}) {
8371
8380
  this.name = name;
8372
8381
  this.model = model;
8373
8382
  this.collection = collection;
8374
8383
  this.previous = previous;
8375
8384
  this.value = value;
8376
8385
  this.options = options;
8377
- this.chain = [
8386
+ this.chain = chain ?? [
8378
8387
  [
8379
- (this.collection || this.model),
8388
+ (this.model || this.collection),
8380
8389
  attr || null,
8381
8390
  ],
8382
8391
  ];
8383
- }
8384
- stopPropagation() {
8385
- this.bubbling = false;
8392
+ this.bubbly = bubbly ?? true;
8386
8393
  }
8387
8394
  push(model, attr) {
8388
- let event = new ODataModelEvent(this.name, {
8395
+ return new ODataModelEvent(this.name, {
8389
8396
  model: this.model,
8390
8397
  collection: this.collection,
8391
8398
  previous: this.previous,
8392
8399
  value: this.value,
8393
8400
  options: this.options,
8401
+ bubbly: this.bubbly,
8402
+ chain: [[model, attr], ...this.chain],
8394
8403
  });
8395
- event.chain = [...this.chain];
8396
- event.chain.splice(0, 0, [model, attr]);
8397
- return event;
8404
+ }
8405
+ stopPropagation() {
8406
+ this.bubbly = false;
8398
8407
  }
8399
8408
  visited(model) {
8400
8409
  return (this.chain.some((c) => c[0] === model) &&
8401
8410
  this.chain[this.chain.length - 1][0] !== model);
8402
8411
  }
8412
+ canContinueWith(self) {
8413
+ return this.bubbly && !this.visited(self);
8414
+ }
8403
8415
  get path() {
8404
8416
  return this.chain
8405
8417
  .map(([, attr], index) => typeof attr === 'number'
@@ -8424,14 +8436,39 @@ class ODataModelEvent {
8424
8436
  : undefined;
8425
8437
  }
8426
8438
  }
8427
- const BUBBLING = [
8428
- ODataModelEventType.Change,
8429
- ODataModelEventType.Reset,
8430
- ODataModelEventType.Update,
8431
- ODataModelEventType.Destroy,
8432
- ODataModelEventType.Add,
8433
- ODataModelEventType.Remove,
8434
- ];
8439
+ class ODataModelEventEmitter extends EventEmitter {
8440
+ constructor({ model, collection, } = {}) {
8441
+ super();
8442
+ this.model = model;
8443
+ this.collection = collection;
8444
+ }
8445
+ /*
8446
+ override emit(event: ODataModelEvent<T>): void {
8447
+ if (event.bubbly && ((this.collection || this.model) === undefined || !event.visited((this.collection || this.model)!))) {
8448
+ super.emit(event);
8449
+ }
8450
+ }
8451
+ */
8452
+ trigger(type, { collection, previous, value, attr, options, bubbly, } = {}) {
8453
+ const _trigger = (name) => this.emit(new ODataModelEvent(name, {
8454
+ model: this.model,
8455
+ collection: collection ?? this.collection,
8456
+ previous,
8457
+ value,
8458
+ attr,
8459
+ options,
8460
+ bubbly,
8461
+ }));
8462
+ if (type && EVENT_SPLITTER.test(type)) {
8463
+ for (let name of type.split(EVENT_SPLITTER)) {
8464
+ _trigger(name);
8465
+ }
8466
+ }
8467
+ else {
8468
+ _trigger(type);
8469
+ }
8470
+ }
8471
+ }
8435
8472
  const INCLUDE_SHALLOW = {
8436
8473
  include_concurrency: true,
8437
8474
  include_computed: true,
@@ -8657,7 +8694,7 @@ class ODataModelAttribute {
8657
8694
  constructor(_model, _field) {
8658
8695
  this._model = _model;
8659
8696
  this._field = _field;
8660
- this.events$ = new EventEmitter();
8697
+ this.events$ = new ODataModelEventEmitter();
8661
8698
  }
8662
8699
  get navigation() {
8663
8700
  return Boolean(this._field.navigation);
@@ -8747,6 +8784,7 @@ class ODataModelOptions {
8747
8784
  constructor({ options, schema, }) {
8748
8785
  this._fields = [];
8749
8786
  this.children = [];
8787
+ this.events$ = new ODataModelEventEmitter();
8750
8788
  this.tsToEdm = {
8751
8789
  string: EdmType.String,
8752
8790
  number: EdmType.Int32,
@@ -8890,11 +8928,10 @@ class ODataModelOptions {
8890
8928
  const current = self._resource;
8891
8929
  if (current === null || !current.isEqualTo(resource)) {
8892
8930
  self._resource = resource;
8893
- self.events$.emit(new ODataModelEvent(ODataModelEventType.Attach, {
8894
- model: self,
8931
+ self.events$.trigger(ODataModelEventType.Attach, {
8895
8932
  previous: current,
8896
8933
  value: resource,
8897
- }));
8934
+ });
8898
8935
  }
8899
8936
  }
8900
8937
  //# region Resource
@@ -8940,7 +8977,7 @@ class ODataModelOptions {
8940
8977
  resource = field.resourceFactory(resource);
8941
8978
  }
8942
8979
  if (resource === null)
8943
- throw new Error(`resource: Can't build resource for ${child}`);
8980
+ throw new Error(`Can't build resource for ${child}`);
8944
8981
  return resource;
8945
8982
  }
8946
8983
  collectionResourceFactory(query) {
@@ -8961,7 +8998,7 @@ class ODataModelOptions {
8961
8998
  entityResource(self) {
8962
8999
  let resource = this.modelResourceFactory(self._resource !== null ? self._resource.cloneQuery() : undefined);
8963
9000
  if (resource === undefined)
8964
- throw new Error(`entityResource: Can't build resource for ${self}`);
9001
+ throw new Error(`Can't build resource for ${self}`);
8965
9002
  const key = self.key({ field_mapping: true });
8966
9003
  if (key !== undefined)
8967
9004
  return resource.key(key);
@@ -8969,6 +9006,8 @@ class ODataModelOptions {
8969
9006
  }
8970
9007
  //#endregion
8971
9008
  bind(self, { parent, resource, annots, } = {}) {
9009
+ // Events
9010
+ self.events$.subscribe((e) => this.events$.emit(e));
8972
9011
  // Parent
8973
9012
  if (parent !== undefined) {
8974
9013
  self._parent = parent;
@@ -8982,17 +9021,17 @@ class ODataModelOptions {
8982
9021
  // Annotations
8983
9022
  self._annotations =
8984
9023
  annots || new ODataEntityAnnotations(ODataHelper[DEFAULT_VERSION]);
8985
- const fields = this.fields({
9024
+ // Fields
9025
+ this.fields({
8986
9026
  include_navigation: true,
8987
9027
  include_parents: true,
8988
- });
8989
- for (let field of fields) {
9028
+ }).forEach((field) => {
8990
9029
  Object.defineProperty(self, field.name, {
8991
9030
  configurable: true,
8992
9031
  get: () => this.get(self, field),
8993
9032
  set: (value) => this.set(self, field, value),
8994
9033
  });
8995
- }
9034
+ });
8996
9035
  }
8997
9036
  query(self, resource, func) {
8998
9037
  resource.query(func);
@@ -9254,10 +9293,7 @@ class ODataModelOptions {
9254
9293
  });
9255
9294
  }
9256
9295
  if (!silent && changes.length > 0) {
9257
- self.events$.emit(new ODataModelEvent(ODataModelEventType.Reset, {
9258
- model: self,
9259
- options: { changes },
9260
- }));
9296
+ self.events$.trigger(ODataModelEventType.Reset, { options: { changes } });
9261
9297
  }
9262
9298
  }
9263
9299
  assign(self, entity, { reset = false, reparent = false, silent = false, } = {}) {
@@ -9289,10 +9325,7 @@ class ODataModelOptions {
9289
9325
  }
9290
9326
  });
9291
9327
  if ((!self._silent && changes.length > 0) || self._reset) {
9292
- self.events$.emit(new ODataModelEvent(self._reset ? ODataModelEventType.Reset : ODataModelEventType.Update, {
9293
- model: self,
9294
- options: { changes },
9295
- }));
9328
+ self.events$.trigger(self._reset ? ODataModelEventType.Reset : ODataModelEventType.Update, { options: { changes } });
9296
9329
  }
9297
9330
  self._reset = false;
9298
9331
  self._reparent = false;
@@ -9430,23 +9463,20 @@ class ODataModelOptions {
9430
9463
  changed = attr.set(value, self._reset, self._reparent);
9431
9464
  }
9432
9465
  if (!self._silent && changed) {
9433
- self.events$.emit(new ODataModelEvent(ODataModelEventType.Change, {
9466
+ self.events$.trigger(ODataModelEventType.Change, {
9434
9467
  attr,
9435
- model: self,
9436
9468
  value,
9437
9469
  previous: current,
9438
9470
  options: { key: modelField.isKey() },
9439
- }));
9471
+ });
9440
9472
  }
9441
9473
  return changed;
9442
9474
  }
9443
9475
  _link(self, attr) {
9444
9476
  attr.events$.subscribe((event) => {
9445
- if (BUBBLING.indexOf(event.name) !== -1 &&
9446
- event.bubbling &&
9447
- !event.visited(self)) {
9477
+ if (event.canContinueWith(self)) {
9448
9478
  if (event.model === attr.get()) {
9449
- if (event.name === 'change' &&
9479
+ if (event.name === ODataModelEventType.Change &&
9450
9480
  attr.navigation &&
9451
9481
  event.options?.key) {
9452
9482
  let ref = attr.get().referential(attr);
@@ -9476,8 +9506,6 @@ class ODataCollection {
9476
9506
  this._resource = null;
9477
9507
  this._resources = [];
9478
9508
  this._entries = [];
9479
- //Events
9480
- this.events$ = new EventEmitter();
9481
9509
  this._sortBy = null;
9482
9510
  const Klass = this.constructor;
9483
9511
  if (model === undefined && Klass.model !== null)
@@ -9485,6 +9513,9 @@ class ODataCollection {
9485
9513
  if (model === undefined)
9486
9514
  throw new Error('Collection: Collection need model');
9487
9515
  this._model = model;
9516
+ // Events
9517
+ this.events$ = new ODataModelEventEmitter({ collection: this });
9518
+ this.events$.subscribe((e) => model.meta.events$.emit(e));
9488
9519
  // Parent
9489
9520
  if (parent !== undefined) {
9490
9521
  this._parent = parent;
@@ -9540,11 +9571,10 @@ class ODataCollection {
9540
9571
  const current = this._resource;
9541
9572
  if (current === null || !current.isEqualTo(resource)) {
9542
9573
  this._resource = resource;
9543
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Attach, {
9544
- collection: this,
9574
+ this.events$.trigger(ODataModelEventType.Attach, {
9545
9575
  previous: current,
9546
9576
  value: resource,
9547
- }));
9577
+ });
9548
9578
  }
9549
9579
  }
9550
9580
  withResource(resource, ctx) {
@@ -9620,20 +9650,14 @@ class ODataCollection {
9620
9650
  annots: this.annots(),
9621
9651
  });
9622
9652
  }
9623
- _request(obs$, { remove } = {}) {
9624
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Request, {
9625
- collection: this,
9653
+ _request(obs$, mapCallback) {
9654
+ this.events$.trigger(ODataModelEventType.Request, {
9626
9655
  options: { observable: obs$ },
9627
- }));
9628
- return obs$.pipe(map(({ entities, annots }) => {
9629
- this._annotations = annots;
9630
- const models = (entities || []).map((entity) => this.modelFactory(entity, { reset: true }));
9631
- this.assign(models, { reset: true, remove });
9632
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Sync, {
9633
- collection: this,
9634
- options: { models, entities, annots },
9635
- }));
9636
- return models;
9656
+ });
9657
+ return obs$.pipe(map((response) => {
9658
+ let parse = mapCallback(response);
9659
+ this.events$.trigger(ODataModelEventType.Sync, { options: response });
9660
+ return parse;
9637
9661
  }));
9638
9662
  }
9639
9663
  fetch({ withCount, remove, ...options } = {}) {
@@ -9645,18 +9669,33 @@ class ODataCollection {
9645
9669
  withCount,
9646
9670
  ...options,
9647
9671
  });
9648
- return this._request(obs$, { remove });
9672
+ return this._request(obs$, ({ entities, annots }) => {
9673
+ this._annotations = annots;
9674
+ const models = (entities || []).map((entity) => this.modelFactory(entity, { reset: true }));
9675
+ this.assign(models, { reset: true, remove: remove ?? true });
9676
+ return models;
9677
+ });
9649
9678
  }
9650
9679
  fetchAll({ withCount, remove, ...options } = {}) {
9651
9680
  const resource = this.resource();
9652
9681
  const obs$ = resource.fetchAll({ withCount, ...options });
9653
- return this._request(obs$, { remove });
9682
+ return this._request(obs$, ({ entities, annots }) => {
9683
+ this._annotations = annots;
9684
+ const models = (entities || []).map((entity) => this.modelFactory(entity, { reset: true }));
9685
+ this.assign(models, { reset: true, remove: remove ?? true });
9686
+ return models;
9687
+ });
9654
9688
  }
9655
9689
  fetchMany(top, { withCount, remove, ...options } = {}) {
9656
9690
  const resource = this.resource();
9657
9691
  resource.query((q) => remove || this.length == 0 ? q.skip().clear() : q.skip(this.length));
9658
9692
  const obs$ = resource.fetchMany(top, { withCount, ...options });
9659
- return this._request(obs$, { remove: remove ?? false });
9693
+ return this._request(obs$, ({ entities, annots }) => {
9694
+ this._annotations = annots;
9695
+ const models = (entities || []).map((entity) => this.modelFactory(entity, { reset: true }));
9696
+ this.assign(models, { reset: true, remove: remove ?? false });
9697
+ return models;
9698
+ });
9660
9699
  }
9661
9700
  fetchOne({ withCount, remove, ...options } = {}) {
9662
9701
  return this.fetchMany(1, { withCount, remove, ...options }).pipe(map((models) => models[0]));
@@ -9724,15 +9763,14 @@ class ODataCollection {
9724
9763
  ...toUpdateEntity.map((m) => m.asEntity((e) => e.save({ method, ...options }))),
9725
9764
  ...toUpdateContained.map((m) => m.save({ method, ...options })),
9726
9765
  ]);
9727
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Request, {
9728
- collection: this,
9766
+ this.events$.trigger(ODataModelEventType.Request, {
9729
9767
  options: { observable: obs$ },
9730
- }));
9768
+ });
9731
9769
  return obs$.pipe(map(() => {
9732
9770
  this._entries = this._entries
9733
9771
  .filter((entry) => entry.state !== ODataModelState.Removed)
9734
9772
  .map((entry) => ({ ...entry, state: ODataModelState.Unchanged }));
9735
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Sync, { collection: this }));
9773
+ this.events$.trigger(ODataModelEventType.Sync);
9736
9774
  return this;
9737
9775
  }));
9738
9776
  }
@@ -9782,10 +9820,7 @@ class ODataCollection {
9782
9820
  else
9783
9821
  this._entries.push(entry);
9784
9822
  if (!silent) {
9785
- model.events$.emit(new ODataModelEvent(ODataModelEventType.Add, {
9786
- model,
9787
- collection: this,
9788
- }));
9823
+ model.events$.trigger(ODataModelEventType.Add, { collection: this });
9789
9824
  }
9790
9825
  return entry.model;
9791
9826
  }
@@ -9800,10 +9835,9 @@ class ODataCollection {
9800
9835
  reparent,
9801
9836
  });
9802
9837
  if (!silent && added !== undefined) {
9803
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Update, {
9804
- collection: this,
9838
+ this.events$.trigger(ODataModelEventType.Update, {
9805
9839
  options: { added: [added], removed: [], merged: [] },
9806
- }));
9840
+ });
9807
9841
  }
9808
9842
  return added;
9809
9843
  }
@@ -9849,12 +9883,9 @@ class ODataCollection {
9849
9883
  if (entry === undefined || entry.state === ODataModelState.Removed) {
9850
9884
  return model;
9851
9885
  }
9852
- // Emit Event
9886
+ // Trigger Event
9853
9887
  if (!silent)
9854
- model.events$.emit(new ODataModelEvent(ODataModelEventType.Remove, {
9855
- model,
9856
- collection: this,
9857
- }));
9888
+ model.events$.trigger(ODataModelEventType.Remove, { collection: this });
9858
9889
  // Now remove
9859
9890
  const index = this._entries.indexOf(entry);
9860
9891
  this._entries.splice(index, 1);
@@ -9869,10 +9900,9 @@ class ODataCollection {
9869
9900
  removeModel(model, { silent = false, reset = false, } = {}) {
9870
9901
  const removed = this._removeModel(model, { silent, reset });
9871
9902
  if (!silent && removed !== undefined) {
9872
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Update, {
9873
- collection: this,
9903
+ this.events$.trigger(ODataModelEventType.Update, {
9874
9904
  options: { added: [], removed: [removed], merged: [] },
9875
- }));
9905
+ });
9876
9906
  }
9877
9907
  return removed;
9878
9908
  }
@@ -9931,10 +9961,9 @@ class ODataCollection {
9931
9961
  this._addModel(value, { reparent: true });
9932
9962
  toAdd.push(model);
9933
9963
  }
9934
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Update, {
9935
- collection: this,
9964
+ this.events$.trigger(ODataModelEventType.Update, {
9936
9965
  options: { added: toAdd, removed: toRemove, changed: toChange },
9937
- }));
9966
+ });
9938
9967
  return value;
9939
9968
  }
9940
9969
  }
@@ -9996,14 +10025,13 @@ class ODataCollection {
9996
10025
  });
9997
10026
  if (!silent &&
9998
10027
  (toAdd.length > 0 || toRemove.length > 0 || toChange.length > 0)) {
9999
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Reset, {
10000
- collection: this,
10028
+ this.events$.trigger(ODataModelEventType.Reset, {
10001
10029
  options: {
10002
10030
  added: toAdd.map((e) => e.model),
10003
10031
  removed: toRemove.map((e) => e.model),
10004
10032
  changed: toChange.map((e) => e.model),
10005
10033
  },
10006
- }));
10034
+ });
10007
10035
  }
10008
10036
  }
10009
10037
  clear({ silent = false } = {}) {
@@ -10013,10 +10041,9 @@ class ODataCollection {
10013
10041
  });
10014
10042
  this._entries = [];
10015
10043
  if (!silent) {
10016
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Update, {
10017
- collection: this,
10044
+ this.events$.trigger(ODataModelEventType.Update, {
10018
10045
  options: { removed: toRemove },
10019
- }));
10046
+ });
10020
10047
  }
10021
10048
  }
10022
10049
  assign(objects, { remove = true, reset = false, reparent = false, silent = false, } = {}) {
@@ -10078,7 +10105,7 @@ class ODataCollection {
10078
10105
  }
10079
10106
  modelMap.push(model[Model.meta.cid]);
10080
10107
  });
10081
- if (remove || reset) {
10108
+ if (remove) {
10082
10109
  this._entries.forEach((entry, position) => {
10083
10110
  if (modelMap.indexOf(entry.model[Model.meta.cid]) === -1)
10084
10111
  toRemove.push([entry.model, position]);
@@ -10101,15 +10128,14 @@ class ODataCollection {
10101
10128
  toSort.length > 0)) ||
10102
10129
  reset) {
10103
10130
  this._sortBy = null;
10104
- this.events$.emit(new ODataModelEvent(reset ? ODataModelEventType.Reset : ODataModelEventType.Update, {
10105
- collection: this,
10131
+ this.events$.trigger(reset ? ODataModelEventType.Reset : ODataModelEventType.Update, {
10106
10132
  options: {
10107
10133
  added: toAdd,
10108
10134
  removed: toRemove,
10109
10135
  changed: toChange,
10110
10136
  sorted: toSort,
10111
10137
  },
10112
- }));
10138
+ });
10113
10139
  }
10114
10140
  }
10115
10141
  query(ctx) {
@@ -10118,40 +10144,37 @@ class ODataCollection {
10118
10144
  this.attach(resource);
10119
10145
  return this;
10120
10146
  }
10121
- callFunction(name, params, responseType, { ...options } = {}) {
10147
+ callFunction(name, params, responseType, options = {}) {
10122
10148
  const resource = this.resource();
10123
- if (resource instanceof ODataEntitySetResource) {
10124
- const func = resource.function(name);
10125
- func.query((q) => q.apply(options));
10126
- switch (responseType) {
10127
- case 'property':
10128
- return func.callProperty(params, options);
10129
- case 'model':
10130
- return func.callModel(params, options);
10131
- case 'collection':
10132
- return func.callCollection(params, options);
10133
- default:
10134
- return func.call(params, { responseType, ...options });
10135
- }
10149
+ if (!(resource instanceof ODataEntityResource))
10150
+ return throwError(() => new Error("callFunction: Can't call function without ODataEntitySetResource"));
10151
+ const func = resource.function(name).query((q) => q.apply(options));
10152
+ switch (responseType) {
10153
+ case 'property':
10154
+ return this._request(func.callProperty(params, options), (resp) => resp);
10155
+ case 'model':
10156
+ return this._request(func.callModel(params, options), (resp) => resp);
10157
+ case 'collection':
10158
+ return this._request(func.callCollection(params, options), (resp) => resp);
10159
+ default:
10160
+ return this._request(func.call(params, { responseType, ...options }), (resp) => resp);
10136
10161
  }
10137
- return throwError(() => new Error(`callFunction: Can't function without ODataEntitySetResource`));
10138
10162
  }
10139
- callAction(name, params, responseType, { ...options } = {}) {
10163
+ callAction(name, params, responseType, options = {}) {
10140
10164
  const resource = this.resource();
10141
10165
  if (!(resource instanceof ODataEntitySetResource)) {
10142
- return throwError(() => new Error(`callAction: Can't action without ODataEntitySetResource`));
10166
+ return throwError(() => new Error(`callAction: Can't call action without ODataEntitySetResource`));
10143
10167
  }
10144
- const action = resource.action(name);
10145
- action.query((q) => q.apply(options));
10168
+ const action = resource.action(name).query((q) => q.apply(options));
10146
10169
  switch (responseType) {
10147
10170
  case 'property':
10148
- return action.callProperty(params, options);
10171
+ return this._request(action.callProperty(params, options), (resp) => resp);
10149
10172
  case 'model':
10150
- return action.callModel(params, options);
10173
+ return this._request(action.callModel(params, options), (resp) => resp);
10151
10174
  case 'collection':
10152
- return action.callCollection(params, options);
10175
+ return this._request(action.callCollection(params, options), (resp) => resp);
10153
10176
  default:
10154
- return action.call(params, { responseType, ...options });
10177
+ return this._request(action.call(params, { responseType, ...options }), (resp) => resp);
10155
10178
  }
10156
10179
  }
10157
10180
  _unlink(entry) {
@@ -10165,14 +10188,13 @@ class ODataCollection {
10165
10188
  throw new Error('Collection: Subscription already exists');
10166
10189
  }
10167
10190
  entry.subscription = entry.model.events$.subscribe((event) => {
10168
- if (BUBBLING.indexOf(event.name) !== -1 &&
10169
- event.bubbling &&
10170
- !event.visited(this)) {
10191
+ if (event.canContinueWith(this)) {
10171
10192
  if (event.model === entry.model) {
10172
- if (event.name === 'destroy') {
10193
+ if (event.name === ODataModelEventType.Destroy) {
10173
10194
  this.removeModel(entry.model, { reset: true });
10174
10195
  }
10175
- else if (event.name === 'change' && event.options?.key) {
10196
+ else if (event.name === ODataModelEventType.Change &&
10197
+ event.options?.key) {
10176
10198
  entry.key = entry.model.key();
10177
10199
  }
10178
10200
  }
@@ -10259,9 +10281,7 @@ class ODataCollection {
10259
10281
  }
10260
10282
  isEmpty() {
10261
10283
  // Local length and if exists remote length
10262
- return (this.length === 0 &&
10263
- this.annots().count !== undefined &&
10264
- this.annots().count === 0);
10284
+ return this.length === 0;
10265
10285
  }
10266
10286
  //#region Sort
10267
10287
  _bisect(model) {
@@ -10311,9 +10331,7 @@ class ODataCollection {
10311
10331
  this._sortBy = by;
10312
10332
  this._entries = this._entries.sort((e1, e2) => this._compare(e1, e2, by, 0));
10313
10333
  if (!silent) {
10314
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Update, {
10315
- collection: this,
10316
- }));
10334
+ this.events$.trigger(ODataModelEventType.Update);
10317
10335
  }
10318
10336
  }
10319
10337
  }
@@ -10353,12 +10371,11 @@ class ODataModel {
10353
10371
  this._reset = false;
10354
10372
  this._reparent = false;
10355
10373
  this._silent = false;
10356
- // Events
10357
- this.events$ = new EventEmitter();
10358
10374
  const Klass = this.constructor;
10359
10375
  if (Klass.meta === undefined)
10360
- throw new Error(`ODataModel: Can't create model without metadata`);
10376
+ throw new Error(`Model: Can't create model without metadata`);
10361
10377
  this._meta = Klass.meta;
10378
+ this.events$ = new ODataModelEventEmitter({ model: this });
10362
10379
  this._meta.bind(this, { parent, resource, annots });
10363
10380
  // Client Id
10364
10381
  this[this._meta.cid] =
@@ -10448,11 +10465,10 @@ class ODataModel {
10448
10465
  isValid({ method, navigation = false, } = {}) {
10449
10466
  this._errors = this.validate({ method, navigation });
10450
10467
  if (this._errors !== undefined)
10451
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Invalid, {
10452
- model: this,
10468
+ this.events$.trigger(ODataModelEventType.Invalid, {
10453
10469
  value: this._errors,
10454
10470
  options: { method },
10455
- }));
10471
+ });
10456
10472
  return this._errors === undefined;
10457
10473
  }
10458
10474
  defaults() {
@@ -10526,12 +10542,8 @@ class ODataModel {
10526
10542
  }
10527
10543
  clear({ silent = false } = {}) {
10528
10544
  this._attributes.clear();
10529
- //this._changes.clear();
10530
- //this._relations.clear();
10531
10545
  if (!silent) {
10532
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Update, {
10533
- model: this,
10534
- }));
10546
+ this.events$.trigger(ODataModelEventType.Update);
10535
10547
  }
10536
10548
  }
10537
10549
  assign(entity, { reset = false, reparent = false, silent = false, } = {}) {
@@ -10544,21 +10556,16 @@ class ODataModel {
10544
10556
  annots: this.annots(),
10545
10557
  });
10546
10558
  }
10547
- _request(obs$) {
10548
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Request, {
10549
- model: this,
10559
+ _request(obs$, mapCallback) {
10560
+ this.events$.trigger(ODataModelEventType.Request, {
10550
10561
  options: { observable: obs$ },
10551
- }));
10552
- return obs$.pipe(map(({ entity, annots }) => {
10553
- this._annotations = annots;
10554
- this.assign(annots.attributes(entity || {}, 'full'), {
10555
- reset: true,
10562
+ });
10563
+ return obs$.pipe(map((response) => {
10564
+ let parse = mapCallback(response);
10565
+ this.events$.trigger(ODataModelEventType.Sync, {
10566
+ options: response,
10556
10567
  });
10557
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Sync, {
10558
- model: this,
10559
- options: { entity, annots },
10560
- }));
10561
- return this;
10568
+ return parse;
10562
10569
  }));
10563
10570
  }
10564
10571
  fetch({ ...options } = {}) {
@@ -10578,7 +10585,11 @@ class ODataModel {
10578
10585
  ...options,
10579
10586
  });
10580
10587
  }
10581
- return this._request(obs$);
10588
+ return this._request(obs$, ({ entity, annots }) => {
10589
+ this._annotations = annots;
10590
+ this.assign(annots.attributes(entity || {}, 'full'), { reset: true });
10591
+ return this;
10592
+ });
10582
10593
  }
10583
10594
  save({ method, navigation = false, validate = true, ...options } = {}) {
10584
10595
  let resource = this.resource();
@@ -10607,11 +10618,22 @@ class ODataModel {
10607
10618
  include_concurrency: true,
10608
10619
  include_navigation: navigation,
10609
10620
  });
10610
- return this._request((method === 'create'
10621
+ let obs$ = method === 'create'
10611
10622
  ? resource.create(_entity, options)
10612
10623
  : method === 'modify'
10613
- ? resource.modify(_entity, { etag: this.annots().etag, ...options })
10614
- : resource.update(_entity, { etag: this.annots().etag, ...options })).pipe(map(({ entity, annots }) => ({ entity: entity || _entity, annots }))));
10624
+ ? resource.modify(_entity, {
10625
+ etag: this.annots().etag,
10626
+ ...options,
10627
+ })
10628
+ : resource.update(_entity, {
10629
+ etag: this.annots().etag,
10630
+ ...options,
10631
+ });
10632
+ return this._request(obs$, ({ entity, annots }) => {
10633
+ this._annotations = annots;
10634
+ this.assign(annots.attributes(entity || _entity, 'full'), { reset: true });
10635
+ return this;
10636
+ });
10615
10637
  }
10616
10638
  destroy({ ...options } = {}) {
10617
10639
  let resource = this.resource();
@@ -10623,10 +10645,11 @@ class ODataModel {
10623
10645
  if (!resource.hasKey())
10624
10646
  return throwError(() => new Error("destroy: Can't destroy model without key"));
10625
10647
  const _entity = this.toEntity({ field_mapping: true });
10626
- const obs$ = resource
10627
- .destroy({ etag: this.annots().etag, ...options })
10628
- .pipe(map(({ entity, annots }) => ({ entity: entity || _entity, annots })));
10629
- return this._request(obs$).pipe(tap(() => this.events$.emit(new ODataModelEvent(ODataModelEventType.Destroy, { model: this }))));
10648
+ const obs$ = resource.destroy({ etag: this.annots().etag, ...options });
10649
+ return this._request(obs$, (resp) => {
10650
+ this.events$.trigger(ODataModelEventType.Destroy);
10651
+ return resp;
10652
+ });
10630
10653
  }
10631
10654
  /**
10632
10655
  * Create an execution context for change the internal query of a resource
@@ -10665,24 +10688,24 @@ class ODataModel {
10665
10688
  return this._meta.asEntity(this, ctx);
10666
10689
  }
10667
10690
  //#region Callables
10668
- callFunction(name, params, responseType, { ...options } = {}) {
10691
+ callFunction(name, params, responseType, options = {}) {
10669
10692
  const resource = this.resource();
10670
10693
  if (!(resource instanceof ODataEntityResource) || !resource.hasKey())
10671
10694
  return throwError(() => new Error("callFunction: Can't call function without ODataEntityResource with key"));
10672
10695
  const func = resource.function(name).query((q) => q.apply(options));
10673
10696
  switch (responseType) {
10674
10697
  case 'property':
10675
- return func.callProperty(params, options);
10698
+ return this._request(func.callProperty(params, options), (resp) => resp);
10676
10699
  case 'model':
10677
- return func.callModel(params, options);
10700
+ return this._request(func.callModel(params, options), (resp) => resp);
10678
10701
  case 'collection':
10679
- return func.callCollection(params, options);
10702
+ return this._request(func.callCollection(params, options), (resp) => resp);
10680
10703
  case 'blob':
10681
- return func.callBlob(params, options);
10704
+ return this._request(func.callBlob(params, options), (resp) => resp);
10682
10705
  case 'arraybuffer':
10683
- return func.callArraybuffer(params, options);
10706
+ return this._request(func.callArraybuffer(params, options), (resp) => resp);
10684
10707
  default:
10685
- return func.call(params, { responseType, ...options });
10708
+ return this._request(func.call(params, { responseType, ...options }), (resp) => resp);
10686
10709
  }
10687
10710
  }
10688
10711
  callAction(name, params, responseType, { ...options } = {}) {
@@ -10692,17 +10715,17 @@ class ODataModel {
10692
10715
  const action = resource.action(name).query((q) => q.apply(options));
10693
10716
  switch (responseType) {
10694
10717
  case 'property':
10695
- return action.callProperty(params, options);
10718
+ return this._request(action.callProperty(params, options), (resp) => resp);
10696
10719
  case 'model':
10697
- return action.callModel(params, options);
10720
+ return this._request(action.callModel(params, options), (resp) => resp);
10698
10721
  case 'collection':
10699
- return action.callCollection(params, options);
10722
+ return this._request(action.callCollection(params, options), (resp) => resp);
10700
10723
  case 'blob':
10701
- return action.callBlob(params, options);
10724
+ return this._request(action.callBlob(params, options), (resp) => resp);
10702
10725
  case 'arraybuffer':
10703
- return action.callArraybuffer(params, options);
10726
+ return this._request(action.callArraybuffer(params, options), (resp) => resp);
10704
10727
  default:
10705
- return action.call(params, { responseType, ...options });
10728
+ return this._request(action.call(params, { responseType, ...options }), (resp) => resp);
10706
10729
  }
10707
10730
  }
10708
10731
  //#endregion
@@ -10718,7 +10741,7 @@ class ODataModel {
10718
10741
  annots: this.annots(),
10719
10742
  });
10720
10743
  }
10721
- fetchNavigationProperty(name, responseType, { ...options } = {}) {
10744
+ fetchNavigationProperty(name, responseType, options = {}) {
10722
10745
  const nav = this.navigationProperty(name);
10723
10746
  nav.query((q) => q.apply(options));
10724
10747
  switch (responseType) {
@@ -10728,30 +10751,58 @@ class ODataModel {
10728
10751
  return nav.fetchCollection(options);
10729
10752
  }
10730
10753
  }
10731
- // Get Value
10732
- getValue(name, options) {
10754
+ fetchAttribute(name, options = {}) {
10733
10755
  const field = this._meta.field(name);
10734
- if (field === undefined || field.navigation)
10735
- throw Error(`getValue: Can't find property ${name}`);
10736
- let value = this[name];
10737
- if (value === undefined) {
10756
+ if (field === undefined)
10757
+ throw Error(`fetchAttribute: Can't find attribute ${name}`);
10758
+ if (field.isStructuredType() && field.collection) {
10759
+ let collection = field.collectionFactory({ parent: this });
10760
+ collection.query((q) => q.apply(options));
10761
+ return this._request(collection.fetch(options), () => {
10762
+ this.assign({ [name]: collection });
10763
+ return collection;
10764
+ });
10765
+ }
10766
+ else if (field.isStructuredType()) {
10767
+ let model = field.modelFactory({ parent: this });
10768
+ model.query((q) => q.apply(options));
10769
+ return this._request(model.fetch(options), () => {
10770
+ this.assign({ [name]: model });
10771
+ return model;
10772
+ });
10773
+ }
10774
+ else {
10738
10775
  const prop = field.resourceFactory(this.resource());
10739
- return field.collection
10740
- ? prop
10741
- .fetchCollection(options)
10742
- .pipe(tap((c) => this.assign({ [name]: c }, { silent: true })))
10743
- : field.isStructuredType()
10744
- ? prop
10745
- .fetchModel(options)
10746
- .pipe(tap((c) => this.assign({ [name]: c }, { silent: true })))
10747
- : prop
10748
- .fetchProperty(options)
10749
- .pipe(tap((c) => this.assign({ [name]: c }, { silent: true })));
10750
- }
10751
- return of(value);
10752
- }
10753
- //#region References
10754
- setReference(name, model, options) {
10776
+ prop.query((q) => q.apply(options));
10777
+ return this._request(prop.fetchProperty(options), (resp) => {
10778
+ this.assign({ [name]: resp });
10779
+ return resp;
10780
+ });
10781
+ }
10782
+ }
10783
+ getAttribute(name) {
10784
+ const field = this._meta.field(name);
10785
+ if (field === undefined)
10786
+ throw Error(`getAttribute: Can't find attribute ${name}`);
10787
+ let model = this[name];
10788
+ if (field.isStructuredType() && model === undefined) {
10789
+ if (field.collection) {
10790
+ model = field.collectionFactory({ parent: this });
10791
+ }
10792
+ else {
10793
+ const ref = field.navigation
10794
+ ? this.referenced(field)
10795
+ : undefined;
10796
+ model =
10797
+ ref === null
10798
+ ? null
10799
+ : field.modelFactory({ parent: this, value: ref });
10800
+ }
10801
+ this[name] = model;
10802
+ }
10803
+ return model;
10804
+ }
10805
+ setAttribute(name, model, options) {
10755
10806
  const reference = this.navigationProperty(name).reference();
10756
10807
  const etag = this.annots().etag;
10757
10808
  let obs$ = NEVER;
@@ -10766,37 +10817,31 @@ class ODataModel {
10766
10817
  else if (model === null) {
10767
10818
  obs$ = reference.unset({ etag, ...options });
10768
10819
  }
10769
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Request, {
10770
- model: this,
10771
- options: { observable: obs$ },
10772
- }));
10773
- return obs$.pipe(map((model) => {
10820
+ return this._request(obs$, (model) => {
10774
10821
  this.assign({ [name]: model });
10775
- this.events$.emit(new ODataModelEvent(ODataModelEventType.Sync, { model: this }));
10776
10822
  return this;
10777
- }));
10823
+ });
10778
10824
  }
10779
- getReference(name) {
10780
- const field = this._meta.field(name);
10781
- if (field === undefined || !field.navigation)
10782
- throw Error(`getReference: Can't find navigation property ${name}`);
10783
- let model = this[name];
10784
- if (model === null)
10785
- return null;
10786
- if (model === undefined) {
10787
- if (field.collection) {
10788
- model = field.collectionFactory({ parent: this });
10789
- }
10790
- else {
10791
- const value = this.referenced(field);
10792
- model =
10793
- value === null ? null : field.modelFactory({ parent: this, value });
10794
- }
10795
- this[name] = model;
10825
+ setReference(name, model, options) {
10826
+ const reference = this.navigationProperty(name).reference();
10827
+ const etag = this.annots().etag;
10828
+ let obs$ = NEVER;
10829
+ if (model instanceof ODataModel) {
10830
+ obs$ = reference.set(model._meta.entityResource(model), { etag, ...options });
10796
10831
  }
10797
- return model;
10832
+ else if (model instanceof ODataCollection) {
10833
+ obs$ = forkJoin(model
10834
+ .models()
10835
+ .map((m) => reference.add(m._meta.entityResource(m), options)));
10836
+ }
10837
+ else if (model === null) {
10838
+ obs$ = reference.unset({ etag, ...options });
10839
+ }
10840
+ return this._request(obs$, (model) => {
10841
+ this.assign({ [name]: model });
10842
+ return this;
10843
+ });
10798
10844
  }
10799
- //#endregion
10800
10845
  //#region Model Identity
10801
10846
  get [Symbol.toStringTag]() {
10802
10847
  return 'Model';
@@ -12019,5 +12064,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImpor
12019
12064
  * Generated bundle index. Do not edit.
12020
12065
  */
12021
12066
 
12022
- export { BUBBLING, Dates, Durations, EDM_PARSERS, EdmType, Enums, Http, INCLUDE_DEEP, INCLUDE_SHALLOW, ITEM_ROOT, Model, ModelField, NONE_PARSER, ODATA_CONFIG, OData, ODataActionResource, ODataAnnotations, ODataApi, ODataBaseService, ODataBatchRequest, ODataBatchResource, ODataCache, ODataCallable, ODataCallableParser, ODataClient, ODataCollection, ODataConfigAsyncLoader, ODataConfigLoader, ODataConfigSyncLoader, ODataCountResource, ODataEntitiesAnnotations, ODataEntityAnnotations, ODataEntityContainer, ODataEntityResource, ODataEntitySet, ODataEntitySetResource, ODataEntitySetService, ODataEntityTypeKey, ODataEnumType, ODataEnumTypeFieldParser, ODataEnumTypeParser, ODataFunctionResource, ODataInMemoryCache, ODataInStorageCache, ODataMediaResource, ODataMetadata, ODataMetadataResource, ODataModel, ODataModelAttribute, ODataModelEvent, ODataModelEventType, ODataModelField, ODataModelOptions, ODataModelState, ODataModule, ODataNavigationPropertyResource, ODataParameterParser, ODataPathSegments, ODataPathSegmentsHandler, ODataPropertyAnnotations, ODataPropertyResource, ODataQueryOptionHandler, ODataQueryOptions, ODataQueryOptionsHandler, ODataReferenceResource, ODataReferential, ODataRequest, ODataResource, ODataResponse, ODataSchema, ODataServiceFactory, ODataSettings, ODataSingletonResource, ODataSingletonService, ODataStructuredType, ODataStructuredTypeFieldParser, ODataStructuredTypeParser, ODataValueResource, Objects, PathSegment, QueryCustomTypes, QueryOption, RESERVED_FIELD_NAMES, SegmentHandler, StandardAggregateMethods, Strings, Types, Urls, alias, binary, buildPathAndQuery, createSyncLoader, duration, isQueryCustomType, isRawType, normalizeValue, raw };
12067
+ export { Dates, Durations, EDM_PARSERS, EdmType, Enums, Http, INCLUDE_DEEP, INCLUDE_SHALLOW, ITEM_ROOT, Model, ModelField, NONE_PARSER, ODATA_CONFIG, OData, ODataActionResource, ODataAnnotations, ODataApi, ODataBaseService, ODataBatchRequest, ODataBatchResource, ODataCache, ODataCallable, ODataCallableParser, ODataClient, ODataCollection, ODataConfigAsyncLoader, ODataConfigLoader, ODataConfigSyncLoader, ODataCountResource, ODataEntitiesAnnotations, ODataEntityAnnotations, ODataEntityContainer, ODataEntityResource, ODataEntitySet, ODataEntitySetResource, ODataEntitySetService, ODataEntityTypeKey, ODataEnumType, ODataEnumTypeFieldParser, ODataEnumTypeParser, ODataFunctionResource, ODataInMemoryCache, ODataInStorageCache, ODataMediaResource, ODataMetadata, ODataMetadataResource, ODataModel, ODataModelAttribute, ODataModelEvent, ODataModelEventEmitter, ODataModelEventType, ODataModelField, ODataModelOptions, ODataModelState, ODataModule, ODataNavigationPropertyResource, ODataParameterParser, ODataPathSegments, ODataPathSegmentsHandler, ODataPropertyAnnotations, ODataPropertyResource, ODataQueryOptionHandler, ODataQueryOptions, ODataQueryOptionsHandler, ODataReferenceResource, ODataReferential, ODataRequest, ODataResource, ODataResponse, ODataSchema, ODataServiceFactory, ODataSettings, ODataSingletonResource, ODataSingletonService, ODataStructuredType, ODataStructuredTypeFieldParser, ODataStructuredTypeParser, ODataValueResource, Objects, PathSegment, QueryCustomTypes, QueryOption, RESERVED_FIELD_NAMES, SegmentHandler, StandardAggregateMethods, Strings, Types, Urls, alias, binary, buildPathAndQuery, createSyncLoader, duration, isQueryCustomType, isRawType, normalizeValue, raw };
12023
12068
  //# sourceMappingURL=angular-odata.mjs.map