angular-odata 0.144.2 → 0.145.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.
@@ -183,7 +183,7 @@ const CHANGESET_PREFIX = 'changeset_';
183
183
  const DEFAULT_METADATA = 'minimal';
184
184
  const DEFAULT_STRIP_METADATA = 'full';
185
185
  const DEFAULT_FETCH_POLICY = 'network-only';
186
- const DEFAULT_TIMEOUT = 60; // Time in seconds
186
+ const DEFAULT_MAXAGE = 60; // The default max age for cache entries in seconds
187
187
  const CALLABLE_BINDING_PARAMETER = 'bindingParameter';
188
188
  const XSSI_PREFIX = /^\)\]\}',?\n/;
189
189
  // URL PARTS
@@ -1168,7 +1168,7 @@ const Durations = {
1168
1168
  v.months ? v.months + 'M' : '',
1169
1169
  v.weeks ? v.weeks + 'W' : '',
1170
1170
  v.days ? v.days + 'D' : '',
1171
- (v.hours || v.minutes || v.seconds) ? 'T' : '',
1171
+ v.hours || v.minutes || v.seconds ? 'T' : '',
1172
1172
  v.hours ? v.hours + 'H' : '',
1173
1173
  v.minutes ? v.minutes + 'M' : '',
1174
1174
  v.seconds ? v.seconds + 'S' : '',
@@ -2134,18 +2134,21 @@ class ODataEnumTypeParser extends ODataAnnotatable {
2134
2134
  toJsonSchema(options, parent) {
2135
2135
  let schema = (this.flags
2136
2136
  ? {
2137
- title: this.name,
2138
2137
  type: JsonSchemaType.array,
2138
+ title: this.name,
2139
+ uniqueItems: true,
2139
2140
  items: {
2140
- type: JsonSchemaType.integer,
2141
+ type: JsonSchemaType.string,
2142
+ enum: this._fields.map((f) => f.name),
2141
2143
  },
2142
2144
  }
2143
2145
  : {
2144
2146
  type: JsonSchemaType.integer,
2145
- enum: this._fields.map((f) => f.value),
2147
+ title: this.name,
2148
+ anyOf: this._fields.map((f) => ({ const: f.value, title: f.name })),
2146
2149
  });
2147
2150
  if (options?.map !== undefined) {
2148
- schema = options.map(schema, parent);
2151
+ schema = options.map(this, schema, parent);
2149
2152
  }
2150
2153
  return schema;
2151
2154
  }
@@ -2374,7 +2377,7 @@ class ODataStructuredTypeFieldParser extends ODataAnnotatable {
2374
2377
  additionalItems: false,
2375
2378
  };
2376
2379
  if (options?.map !== undefined) {
2377
- schema = options.map(schema, parent);
2380
+ schema = options.map(this, schema, parent);
2378
2381
  }
2379
2382
  return schema;
2380
2383
  }
@@ -2669,7 +2672,7 @@ class ODataStructuredTypeParser extends ODataAnnotatable {
2669
2672
  })
2670
2673
  .reduce((acc, v) => Object.assign(acc, v), {}));
2671
2674
  if (options?.map !== undefined) {
2672
- schema = options.map(schema, parent);
2675
+ schema = options.map(this, schema, parent);
2673
2676
  }
2674
2677
  return schema;
2675
2678
  }
@@ -3405,7 +3408,7 @@ class FilterExpression extends Expression {
3405
3408
  negated: this._negated,
3406
3409
  });
3407
3410
  if (exp.length() > 1) {
3408
- children.push(syntax.group(exp));
3411
+ children.push(operators.group(exp));
3409
3412
  }
3410
3413
  else {
3411
3414
  children.push(exp);
@@ -3417,7 +3420,7 @@ class FilterExpression extends Expression {
3417
3420
  children = [...children, ...node.children()];
3418
3421
  }
3419
3422
  else {
3420
- children.push(syntax.group(node));
3423
+ children.push(operators.group(node));
3421
3424
  }
3422
3425
  this._connector = connector;
3423
3426
  this._children = children;
@@ -3428,7 +3431,7 @@ class FilterExpression extends Expression {
3428
3431
  this._children = [...this._children, ...node.children()];
3429
3432
  }
3430
3433
  else {
3431
- this._children.push(node instanceof FilterExpression && !node.negated() ? syntax.group(node) : node);
3434
+ this._children.push(node instanceof FilterExpression && !node.negated() ? operators.group(node) : node);
3432
3435
  }
3433
3436
  return this;
3434
3437
  }
@@ -3489,7 +3492,7 @@ class FilterExpression extends Expression {
3489
3492
  e: (connector = 'and') => new FilterExpression({ connector }),
3490
3493
  });
3491
3494
  }
3492
- return this._add(syntax.any(left, exp, alias));
3495
+ return this._add(operators.any(left, exp, alias));
3493
3496
  }
3494
3497
  all(left, opts, alias) {
3495
3498
  let exp = undefined;
@@ -3501,13 +3504,13 @@ class FilterExpression extends Expression {
3501
3504
  e: (connector = 'and') => new FilterExpression({ connector }),
3502
3505
  });
3503
3506
  }
3504
- return this._add(syntax.all(left, exp, alias));
3507
+ return this._add(operators.all(left, exp, alias));
3505
3508
  }
3506
3509
  count(left, opts) {
3507
3510
  return this._add(new CountExpression().field(left, opts));
3508
3511
  }
3509
3512
  isof(left, type) {
3510
- return this._add(syntax.isof(left, type));
3513
+ return this._add(functions.isof(left, type));
3511
3514
  }
3512
3515
  combine(exp, connector = 'and') {
3513
3516
  return this._add(exp, connector);
@@ -3574,7 +3577,7 @@ class SearchExpression extends Expression {
3574
3577
  negated: this._negated,
3575
3578
  });
3576
3579
  if (exp.length() > 1) {
3577
- children.push(syntax.group(exp));
3580
+ children.push(operators.group(exp));
3578
3581
  }
3579
3582
  else {
3580
3583
  children.push(exp);
@@ -3586,7 +3589,7 @@ class SearchExpression extends Expression {
3586
3589
  children = [...children, ...node.children()];
3587
3590
  }
3588
3591
  else {
3589
- children.push(syntax.group(node));
3592
+ children.push(operators.group(node));
3590
3593
  }
3591
3594
  this._connector = connector;
3592
3595
  this._children = children;
@@ -3597,7 +3600,7 @@ class SearchExpression extends Expression {
3597
3600
  this._children = [...this._children, ...node.children()];
3598
3601
  }
3599
3602
  else {
3600
- this._children.push(node instanceof SearchExpression && !node.negated() ? syntax.group(node) : node);
3603
+ this._children.push(node instanceof SearchExpression && !node.negated() ? operators.group(node) : node);
3601
3604
  }
3602
3605
  return this;
3603
3606
  }
@@ -3761,7 +3764,7 @@ class ApplyExpression extends Expression {
3761
3764
  return this;
3762
3765
  }
3763
3766
  aggregate(value, method, alias) {
3764
- return this._add(syntax.aggregate(value, method, alias));
3767
+ return this._add(transformations.aggregate(value, method, alias));
3765
3768
  }
3766
3769
  //topcount
3767
3770
  topCount(opts) {
@@ -3827,10 +3830,10 @@ class ApplyExpression extends Expression {
3827
3830
  }
3828
3831
  //groupby
3829
3832
  groupBy(props, opts) {
3830
- let properties = props({ rollup: (e) => syntax.rollup(e) });
3833
+ let properties = props({ rollup: (e) => operators.rollup(e) });
3831
3834
  properties = Array.isArray(properties) ? properties : [properties];
3832
- const transformations = opts !== undefined ? opts(new GroupByTransformations()) : undefined;
3833
- return this._add(syntax.groupby(properties, transformations));
3835
+ const transformation = opts !== undefined ? opts(new GroupByTransformations()) : undefined;
3836
+ return this._add(transformations.groupby(properties, transformation));
3834
3837
  }
3835
3838
  //filter
3836
3839
  filter(opts) {
@@ -3932,6 +3935,7 @@ class OrderByExpression extends Expression {
3932
3935
  return opts({
3933
3936
  t: FieldFactory(),
3934
3937
  e: () => new OrderByExpression(),
3938
+ o: operators,
3935
3939
  }, current ?? new OrderByExpression());
3936
3940
  }
3937
3941
  _add(node) {
@@ -3980,6 +3984,7 @@ class SelectExpression extends Expression {
3980
3984
  return opts({
3981
3985
  t: FieldFactory(),
3982
3986
  e: () => new SelectExpression(),
3987
+ o: operators,
3983
3988
  }, current ?? new SelectExpression());
3984
3989
  }
3985
3990
  toJson() {
@@ -4129,6 +4134,7 @@ class ExpandExpression extends Expression {
4129
4134
  return opts({
4130
4135
  t: FieldFactory(),
4131
4136
  e: () => new ExpandExpression(),
4137
+ o: operators,
4132
4138
  }, current ?? new ExpandExpression());
4133
4139
  }
4134
4140
  toJson() {
@@ -4245,6 +4251,8 @@ const RenderableFactory = (value) => {
4245
4251
  return Lambda.fromJson(value);
4246
4252
  case 'Type':
4247
4253
  return Type.fromJson(value);
4254
+ case 'Casting':
4255
+ return Casting.fromJson(value);
4248
4256
  case 'Field':
4249
4257
  return FieldFactory(value['names']);
4250
4258
  default:
@@ -4262,7 +4270,7 @@ function applyMixins(derivedCtor, constructors) {
4262
4270
  }
4263
4271
  function render(value, { aliases, normalize, escape, prefix, parser, options, } = {}) {
4264
4272
  if (Types.isFunction(value)) {
4265
- return render(value(syntax), {
4273
+ return render(value({ o: operators, f: functions }), {
4266
4274
  aliases,
4267
4275
  normalize,
4268
4276
  prefix,
@@ -4659,6 +4667,13 @@ class GroupingOperators {
4659
4667
  return new Function('rollup', values, 'none');
4660
4668
  }
4661
4669
  }
4670
+ class CastingOperators {
4671
+ cast(left, type) {
4672
+ return FieldFactory([
4673
+ type !== undefined ? new Casting(type, left) : new Casting(left),
4674
+ ]);
4675
+ }
4676
+ }
4662
4677
  class Aggregate {
4663
4678
  value;
4664
4679
  method;
@@ -4834,6 +4849,46 @@ class Type {
4834
4849
  return parser?.findChildParser((p) => p.isTypeOf(this.type));
4835
4850
  }
4836
4851
  }
4852
+ class Casting {
4853
+ type;
4854
+ value;
4855
+ constructor(type, value) {
4856
+ this.type = type;
4857
+ this.value = value;
4858
+ }
4859
+ get [Symbol.toStringTag]() {
4860
+ return 'Casting';
4861
+ }
4862
+ toJson() {
4863
+ return {
4864
+ $type: Types.rawType(this),
4865
+ type: this.type,
4866
+ value: this.value,
4867
+ };
4868
+ }
4869
+ static fromJson(json) {
4870
+ return new Casting(json['type'], RenderableFactory(json['value']));
4871
+ }
4872
+ render({ aliases, escape, prefix, parser, options, }) {
4873
+ let value;
4874
+ if (this.value) {
4875
+ parser = resolve([this.value], parser);
4876
+ let [left, right] = encode([this.value], parser, options);
4877
+ value = render(left, { aliases, escape, prefix, parser, options });
4878
+ }
4879
+ return value ? `${this.value}/${this.type}` : `${this.type}`;
4880
+ }
4881
+ clone() {
4882
+ return new Type(this.type, Objects.clone(this.value));
4883
+ }
4884
+ resolve(parser) {
4885
+ parser =
4886
+ parser instanceof ODataStructuredTypeFieldParser && parser.isStructuredType()
4887
+ ? parser.structuredType()
4888
+ : parser;
4889
+ return parser?.findChildParser((p) => p.isTypeOf(this.type));
4890
+ }
4891
+ }
4837
4892
  class Lambda {
4838
4893
  op;
4839
4894
  values;
@@ -4896,6 +4951,7 @@ applyMixins(ODataOperators, [
4896
4951
  LogicalOperators,
4897
4952
  ArithmeticOperators,
4898
4953
  GroupingOperators,
4954
+ CastingOperators,
4899
4955
  LambdaOperators,
4900
4956
  ]);
4901
4957
  const operators = new ODataOperators();
@@ -4916,10 +4972,6 @@ class ODataTransformations {
4916
4972
  }
4917
4973
  applyMixins(ODataTransformations, [Transformations]);
4918
4974
  const transformations = new ODataTransformations();
4919
- class ODataSyntax {
4920
- }
4921
- applyMixins(ODataSyntax, [ODataOperators, ODataFunctions, ODataTransformations]);
4922
- const syntax = new ODataSyntax();
4923
4975
 
4924
4976
  class ComputeExpression extends Expression {
4925
4977
  names;
@@ -5865,6 +5917,7 @@ class ODataRequest {
5865
5917
  withCredentials;
5866
5918
  bodyQueryOptions;
5867
5919
  fetchPolicy;
5920
+ maxAge;
5868
5921
  resource;
5869
5922
  _responseType;
5870
5923
  _method;
@@ -5887,7 +5940,8 @@ class ODataRequest {
5887
5940
  this._body = this.resource.serialize(this._body, init.parserOptions);
5888
5941
  this.withCredentials =
5889
5942
  init.withCredentials === undefined ? this.api.options.withCredentials : init.withCredentials;
5890
- this.fetchPolicy = init.fetchPolicy || this.api.options.fetchPolicy;
5943
+ this.fetchPolicy = init.fetchPolicy ?? this.api.options.fetchPolicy;
5944
+ this.maxAge = init.maxAge;
5891
5945
  this.bodyQueryOptions = [
5892
5946
  ...(this.api.options.bodyQueryOptions || []),
5893
5947
  ...(init.bodyQueryOptions || []),
@@ -5985,6 +6039,7 @@ class ODataRequest {
5985
6039
  reportProgress: options.reportProgress,
5986
6040
  responseType: options.responseType,
5987
6041
  fetchPolicy: options.fetchPolicy,
6042
+ maxAge: options.maxAge,
5988
6043
  parserOptions: options.parserOptions,
5989
6044
  withCredentials: options.withCredentials,
5990
6045
  bodyQueryOptions: options.bodyQueryOptions,
@@ -6118,7 +6173,11 @@ class ODataResource {
6118
6173
  resource = this.api.entitySet(entitySet).entity(entity);
6119
6174
  resource.query((q) => q.restore(this.queryOptions.toQueryArguments()));
6120
6175
  }
6121
- return new ModelType(entity, { resource, annots, reset });
6176
+ return ModelType.factory(entity, {
6177
+ resource: resource,
6178
+ annots,
6179
+ reset,
6180
+ });
6122
6181
  }
6123
6182
  asCollection(entities, { reset, annots, CollectionType, } = {}) {
6124
6183
  reset ??= annots !== undefined;
@@ -6133,7 +6192,11 @@ class ODataResource {
6133
6192
  resource = this.api.entitySet(entitySet);
6134
6193
  resource.query((q) => q.restore(this.queryOptions.toQueryArguments()));
6135
6194
  }
6136
- return new CollectionType(entities, { resource, annots, reset });
6195
+ return CollectionType.factory(entities, {
6196
+ resource: resource,
6197
+ annots,
6198
+ reset,
6199
+ });
6137
6200
  }
6138
6201
  //#endregion
6139
6202
  isTypeOf(other) {
@@ -10215,6 +10278,15 @@ class ODataCollection {
10215
10278
  entities = entities || [];
10216
10279
  this.assign(entities, { reset });
10217
10280
  }
10281
+ static factory(entities = [], { parent, resource, annots, model, reset = false, } = {}) {
10282
+ return this.model.meta.collectionFactory(this, entities, {
10283
+ parent,
10284
+ resource,
10285
+ annots,
10286
+ reset,
10287
+ model,
10288
+ });
10289
+ }
10218
10290
  isParentOf(child) {
10219
10291
  return child !== this && ODataModelOptions.chain(child).some((p) => p[0] === this);
10220
10292
  }
@@ -10290,11 +10362,7 @@ class ODataCollection {
10290
10362
  // Change to child model
10291
10363
  Model = schema.model;
10292
10364
  }
10293
- return new Model(data, {
10294
- annots,
10295
- reset,
10296
- parent: [this, null],
10297
- });
10365
+ return Model.factory(data, { annots, reset, parent: [this, null] });
10298
10366
  }
10299
10367
  toEntities({ client_id = false, include_navigation = false, include_concurrency = false, include_computed = false, include_key = true, include_id = false, include_non_field = false, changes_only = false, field_mapping = false, chain = [], } = {}) {
10300
10368
  return this._entries
@@ -10730,7 +10798,8 @@ class ODataCollection {
10730
10798
  const toMerge = [];
10731
10799
  const toRemove = [];
10732
10800
  objects.forEach((obj, index) => {
10733
- const model = ODataModelOptions.isModel(obj)
10801
+ const isModel = ODataModelOptions.isModel(obj);
10802
+ const model = isModel
10734
10803
  ? obj
10735
10804
  : this.modelFactory(obj, {
10736
10805
  reset,
@@ -10739,11 +10808,11 @@ class ODataCollection {
10739
10808
  // Try find entry
10740
10809
  const entry = this._findEntry(model);
10741
10810
  if (merge && entry !== undefined) {
10742
- if (entry.model !== model) {
10743
- entry.model.assign(model.toEntity({
10744
- client_id: true,
10745
- ...INCLUDE_DEEP,
10746
- }), { add, merge, remove, reset, silent });
10811
+ if (entry.model !== model || !isModel) {
10812
+ const entity = entry.model !== model
10813
+ ? model.toEntity({ client_id: true, ...INCLUDE_DEEP })
10814
+ : obj;
10815
+ entry.model.assign(entity, { add, merge, remove, reset, silent });
10747
10816
  // Model Change?
10748
10817
  if (entry.model.hasChanged())
10749
10818
  toMerge.push(entry.model);
@@ -10984,30 +11053,6 @@ class ODataModel {
10984
11053
  _meta;
10985
11054
  // Events
10986
11055
  events$;
10987
- static buildMetaOptions({ config, structuredType, }) {
10988
- if (config === undefined) {
10989
- const fields = structuredType
10990
- .fields({ include_navigation: true, include_parents: true })
10991
- .reduce((acc, field) => {
10992
- let name = field.name;
10993
- // Prevent collision with reserved keywords
10994
- while (RESERVED_FIELD_NAMES.includes(name)) {
10995
- name = name + '_';
10996
- }
10997
- return Object.assign(acc, {
10998
- [name]: {
10999
- field: field.name,
11000
- default: field.default,
11001
- required: !field.nullable,
11002
- },
11003
- });
11004
- }, {});
11005
- config = {
11006
- fields: new Map(Object.entries(fields)),
11007
- };
11008
- }
11009
- return new ODataModelOptions({ config, structuredType });
11010
- }
11011
11056
  constructor(data = {}, { parent, resource, annots, reset = false, } = {}) {
11012
11057
  const Klass = this.constructor;
11013
11058
  if (Klass.meta === undefined)
@@ -11025,6 +11070,9 @@ class ODataModel {
11025
11070
  data = Objects.merge(this.defaults(), data);
11026
11071
  this.assign(data, { reset });
11027
11072
  }
11073
+ static factory(data = {}, { parent, resource, annots, reset = false, } = {}) {
11074
+ return this.meta.modelFactory(this, data, { parent, resource, annots, reset });
11075
+ }
11028
11076
  //#region Resources
11029
11077
  resource() {
11030
11078
  return ODataModelOptions.resource(this);
@@ -11525,7 +11573,6 @@ class ODataModel {
11525
11573
  return this.collection()?.prev(this);
11526
11574
  }
11527
11575
  }
11528
- const RESERVED_FIELD_NAMES = Object.getOwnPropertyNames(ODataModel.prototype);
11529
11576
 
11530
11577
  var ODataModelEventType;
11531
11578
  (function (ODataModelEventType) {
@@ -11770,6 +11817,9 @@ class ODataModelField {
11770
11817
  isEnumType() {
11771
11818
  return this.parser.isEnumType();
11772
11819
  }
11820
+ isEdmType() {
11821
+ return this.parser.isEdmType();
11822
+ }
11773
11823
  enumType() {
11774
11824
  const enumType = this.enumForType ? this.enumForType(this.type) : undefined;
11775
11825
  //Throw error if not found
@@ -11818,8 +11868,8 @@ class ODataModelField {
11818
11868
  }
11819
11869
  }
11820
11870
  defaults() {
11821
- const meta = this.optionsForType ? this.optionsForType(this.type) : undefined;
11822
- return this.isStructuredType() && meta !== undefined ? meta.defaults() : this.default;
11871
+ const meta = this.optionsForType && this.isStructuredType() ? this.optionsForType(this.type) : undefined;
11872
+ return meta !== undefined ? meta.defaults() : this.default;
11823
11873
  }
11824
11874
  deserialize(value, options) {
11825
11875
  const parserOptions = options ?? this.parserOptions;
@@ -11862,7 +11912,7 @@ class ODataModelField {
11862
11912
  // Change to child model
11863
11913
  Model = meta.model;
11864
11914
  }
11865
- return new Model((value || {}), {
11915
+ return Model.factory((value || {}), {
11866
11916
  annots,
11867
11917
  reset,
11868
11918
  parent: [parent, this],
@@ -11874,7 +11924,7 @@ class ODataModelField {
11874
11924
  const Collection = this.collectionForType ? this.collectionForType(this.type) : undefined;
11875
11925
  if (Collection === undefined)
11876
11926
  throw Error(`No Collection type for ${this.name}`);
11877
- return new Collection((value || []), {
11927
+ return Collection.factory((value || []), {
11878
11928
  annots: annots,
11879
11929
  reset,
11880
11930
  parent: [parent, this],
@@ -11917,6 +11967,9 @@ class ODataModelAttribute {
11917
11967
  get fieldName() {
11918
11968
  return this._field.field;
11919
11969
  }
11970
+ isStructuredType() {
11971
+ return this._field.isStructuredType();
11972
+ }
11920
11973
  get() {
11921
11974
  return this.state === ODataModelState.Changed ? this.change : this.value;
11922
11975
  }
@@ -11975,6 +12028,7 @@ class ODataModelAttribute {
11975
12028
  }
11976
12029
  }
11977
12030
  class ODataModelOptions {
12031
+ pool = new Map();
11978
12032
  name;
11979
12033
  cid;
11980
12034
  base;
@@ -11992,6 +12046,30 @@ class ODataModelOptions {
11992
12046
  this.cid = config?.cid ?? CID_FIELD_NAME;
11993
12047
  config.fields.forEach((value, key) => this.addField(key, value));
11994
12048
  }
12049
+ modelFactory(Model, data = {}, { parent, resource, annots, reset = false, } = {}) {
12050
+ if (!(this.structuredType.isEntityType() && this.structuredType.isSimpleKey()))
12051
+ return new Model(data, { parent, resource, annots, reset });
12052
+ let key = this.resolveKey(data);
12053
+ if (key !== undefined) {
12054
+ const model = this.pool.get(key.toString());
12055
+ if (model !== undefined) {
12056
+ if (parent !== undefined)
12057
+ model._parent = parent;
12058
+ if (resource !== undefined)
12059
+ model.attach(resource);
12060
+ if (annots !== undefined)
12061
+ model._annotations = annots;
12062
+ return model;
12063
+ }
12064
+ }
12065
+ const model = new Model(data, { parent, resource, annots, reset });
12066
+ if (key !== undefined)
12067
+ this.pool.set(key.toString(), model);
12068
+ return model;
12069
+ }
12070
+ collectionFactory(Collection, entities = [], { parent, resource, annots, model, reset = false, } = {}) {
12071
+ return new Collection(entities, { parent, resource, annots, reset, model });
12072
+ }
11995
12073
  get api() {
11996
12074
  return this.structuredType.api;
11997
12075
  }
@@ -12261,7 +12339,7 @@ class ODataModelOptions {
12261
12339
  .find((field) => field.field === name);
12262
12340
  if (field !== undefined) {
12263
12341
  v = Types.isPlainObject(v) || ODataModelOptions.isModel(v) ? v[field.name] : v;
12264
- options = this.api.optionsForType(field.type);
12342
+ options = field.isStructuredType() ? this.api.optionsForType(field.type) : undefined;
12265
12343
  }
12266
12344
  }
12267
12345
  if (field === undefined)
@@ -12303,7 +12381,7 @@ class ODataModelOptions {
12303
12381
  include_navigation: false,
12304
12382
  include_parents: true,
12305
12383
  }).find((field) => field.field === ref.property);
12306
- const meta = this.api.optionsForType(attr.type);
12384
+ const meta = attr.isStructuredType() ? this.api.optionsForType(attr.type) : undefined;
12307
12385
  const to = meta
12308
12386
  ?.fields({ include_navigation: false, include_parents: true })
12309
12387
  .find((field) => field.field === ref.referencedProperty);
@@ -12655,7 +12733,9 @@ class ODataModelOptions {
12655
12733
  }
12656
12734
  // Resolve referentials
12657
12735
  if (!ODataModelOptions.isCollection(attr.get())) {
12658
- const meta = this.api.optionsForType(modelField.type);
12736
+ const meta = modelField.isStructuredType()
12737
+ ? this.api.optionsForType(modelField.type)
12738
+ : undefined;
12659
12739
  const ref = meta?.resolveReferential(attr.get(), attr, {
12660
12740
  resolve: false,
12661
12741
  });
@@ -12783,6 +12863,7 @@ class ODataApiOptions {
12783
12863
  }
12784
12864
  }
12785
12865
 
12866
+ const RESERVED_FIELD_NAMES = Object.getOwnPropertyNames(ODataModel.prototype);
12786
12867
  /**
12787
12868
  * Api abstraction for consuming OData services.
12788
12869
  */
@@ -12968,6 +13049,7 @@ class ODataApi {
12968
13049
  bodyQueryOptions: options.bodyQueryOptions,
12969
13050
  reportProgress: options.reportProgress,
12970
13051
  fetchPolicy: options.fetchPolicy,
13052
+ maxAge: options.maxAge,
12971
13053
  parserOptions: options.parserOptions,
12972
13054
  withCredentials: options.withCredentials,
12973
13055
  });
@@ -12979,7 +13061,7 @@ class ODataApi {
12979
13061
  return res$;
12980
13062
  }
12981
13063
  if (this.cache !== undefined) {
12982
- res$ = this.cache.handleRequest(req, res$);
13064
+ res$ = this.handleRequest(req, res$);
12983
13065
  }
12984
13066
  switch (options.observe || 'body') {
12985
13067
  case 'body':
@@ -13004,6 +13086,55 @@ class ODataApi {
13004
13086
  throw new Error(`Unreachable: unhandled observe type ${options.observe}}`);
13005
13087
  }
13006
13088
  }
13089
+ /**
13090
+ * Using the request, handle the fetching of the response
13091
+ * @param req The request to fetch
13092
+ * @param res$ Observable of the response
13093
+ * @returns
13094
+ */
13095
+ handleRequest(req, res$) {
13096
+ return req.isFetch()
13097
+ ? this.handleFetch(req, res$)
13098
+ : req.isMutate()
13099
+ ? this.handleMutate(req, res$)
13100
+ : res$;
13101
+ }
13102
+ handleFetch(req, res$) {
13103
+ const policy = req.fetchPolicy;
13104
+ const cached = this.cache.getResponse(req);
13105
+ if (policy === 'no-cache') {
13106
+ return res$;
13107
+ }
13108
+ if (policy === 'cache-only') {
13109
+ if (cached) {
13110
+ return of(cached);
13111
+ }
13112
+ else {
13113
+ return throwError(() => new Error('No Cached'));
13114
+ }
13115
+ }
13116
+ if (policy === 'cache-first' || policy === 'cache-and-network' || policy === 'network-only') {
13117
+ res$ = res$.pipe(tap((res) => {
13118
+ if (res.options.cacheability !== 'no-store')
13119
+ this.cache.putResponse(req, res);
13120
+ }));
13121
+ }
13122
+ return cached !== undefined && policy !== 'network-only'
13123
+ ? policy === 'cache-and-network'
13124
+ ? res$.pipe(startWith(cached))
13125
+ : of(cached)
13126
+ : res$;
13127
+ }
13128
+ handleMutate(req, res$) {
13129
+ const requests = req.isBatch()
13130
+ ? req.resource.requests().filter((r) => r.isMutate())
13131
+ : [req];
13132
+ for (var r of requests) {
13133
+ const scope = this.cache.scope(r);
13134
+ this.cache.forget({ scope });
13135
+ }
13136
+ return res$;
13137
+ }
13007
13138
  //# region Find by Type
13008
13139
  // Memoize
13009
13140
  memo = {
@@ -13214,11 +13345,30 @@ class ODataApi {
13214
13345
  return this.memo.options.get(type);
13215
13346
  }
13216
13347
  let meta = undefined;
13217
- if (!type.startsWith('Edm.')) {
13218
- structuredType = this.findStructuredType(type) ?? structuredType;
13219
- if (structuredType !== undefined) {
13220
- meta = ODataModel.buildMetaOptions({ config, structuredType });
13348
+ structuredType = this.findStructuredType(type) ?? structuredType;
13349
+ if (structuredType !== undefined) {
13350
+ if (config === undefined) {
13351
+ const fields = structuredType
13352
+ .fields({ include_navigation: true, include_parents: true })
13353
+ .reduce((acc, field) => {
13354
+ let name = field.name;
13355
+ // Prevent collision with reserved keywords
13356
+ while (RESERVED_FIELD_NAMES.includes(name)) {
13357
+ name = name + '_';
13358
+ }
13359
+ return Object.assign(acc, {
13360
+ [name]: {
13361
+ field: field.name,
13362
+ default: field.default,
13363
+ required: !field.nullable,
13364
+ },
13365
+ });
13366
+ }, {});
13367
+ config = {
13368
+ fields: new Map(Object.entries(fields)),
13369
+ };
13221
13370
  }
13371
+ meta = new ODataModelOptions({ config, structuredType });
13222
13372
  }
13223
13373
  // Set Options for next time
13224
13374
  this.memo.options.set(type, meta);
@@ -13903,10 +14053,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.5", ngImpor
13903
14053
  }] });
13904
14054
 
13905
14055
  class ODataBaseCache {
13906
- timeout;
14056
+ maxAge;
13907
14057
  entries;
13908
- constructor({ timeout = DEFAULT_TIMEOUT }) {
13909
- this.timeout = timeout;
14058
+ constructor({ maxAge = DEFAULT_MAXAGE }) {
14059
+ this.maxAge = maxAge;
13910
14060
  this.entries = new Map();
13911
14061
  }
13912
14062
  /**
@@ -13940,15 +14090,15 @@ class ODataBaseCache {
13940
14090
  /**
13941
14091
  * Build an entry from a payload and some options
13942
14092
  * @param payload The payload to store in the cache
13943
- * @param timeout The timeout for the entry
14093
+ * @param maxAge The maximum age for the entry
13944
14094
  * @param tags The tags for the entry
13945
14095
  * @returns The entry to store in the cache
13946
14096
  */
13947
- buildEntry(payload, { timeout, tags }) {
14097
+ buildEntry(payload, { maxAge, tags }) {
13948
14098
  return {
13949
14099
  payload,
13950
- lastread: Date.now(),
13951
- timeout: (timeout ?? this.timeout) * 1000,
14100
+ date: Date.now(),
14101
+ maxAge: (maxAge ?? this.maxAge) * 1000,
13952
14102
  tags: tags ?? [],
13953
14103
  };
13954
14104
  }
@@ -13964,12 +14114,12 @@ class ODataBaseCache {
13964
14114
  * Put some payload in the cache
13965
14115
  * @param name The name for the entry
13966
14116
  * @param payload The payload to store in the cache
13967
- * @param timeout The timeout for the entry
14117
+ * @param maxAge The maximum age for the entry
13968
14118
  * @param scope The scope for the entry
13969
14119
  * @param tags The tags for the entry
13970
14120
  */
13971
- put(name, payload, { timeout, scope, tags } = {}) {
13972
- const entry = this.buildEntry(payload, { timeout, tags });
14121
+ put(name, payload, { maxAge, scope, tags } = {}) {
14122
+ const entry = this.buildEntry(payload, { maxAge, tags });
13973
14123
  const key = this.buildKey([...(scope ?? []), name]);
13974
14124
  this.entries.set(key, entry);
13975
14125
  }
@@ -13982,10 +14132,7 @@ class ODataBaseCache {
13982
14132
  get(name, { scope } = {}) {
13983
14133
  const key = this.buildKey([...(scope || []), name]);
13984
14134
  const entry = this.entries.get(key);
13985
- if (entry === undefined || this.isExpired(entry))
13986
- return undefined;
13987
- entry.lastread = Date.now();
13988
- return entry.payload;
14135
+ return entry !== undefined && !this.isExpired(entry) ? entry.payload : undefined;
13989
14136
  }
13990
14137
  /**
13991
14138
  * Remove all cache entries that are matching with the given options
@@ -14016,62 +14163,13 @@ class ODataBaseCache {
14016
14163
  * @returns Boolean indicating if the entry is expired
14017
14164
  */
14018
14165
  isExpired(entry) {
14019
- return entry.lastread < (Date.now() - entry.timeout);
14020
- }
14021
- /**
14022
- * Using the request, handle the fetching of the response
14023
- * @param req The request to fetch
14024
- * @param res$ Observable of the response
14025
- * @returns
14026
- */
14027
- handleRequest(req, res$) {
14028
- return req.isFetch()
14029
- ? this.handleFetch(req, res$)
14030
- : req.isMutate()
14031
- ? this.handleMutate(req, res$)
14032
- : res$;
14033
- }
14034
- handleFetch(req, res$) {
14035
- const policy = req.fetchPolicy;
14036
- const cached = this.getResponse(req);
14037
- if (policy === 'no-cache') {
14038
- return res$;
14039
- }
14040
- if (policy === 'cache-only') {
14041
- if (cached) {
14042
- return of(cached);
14043
- }
14044
- else {
14045
- return throwError(() => new Error('No Cached'));
14046
- }
14047
- }
14048
- if (policy === 'cache-first' || policy === 'cache-and-network' || policy === 'network-only') {
14049
- res$ = res$.pipe(tap((res) => {
14050
- if (res.options.cacheability !== 'no-store')
14051
- this.putResponse(req, res);
14052
- }));
14053
- }
14054
- return cached !== undefined && policy !== 'network-only'
14055
- ? policy === 'cache-and-network'
14056
- ? res$.pipe(startWith(cached))
14057
- : of(cached)
14058
- : res$;
14059
- }
14060
- handleMutate(req, res$) {
14061
- const requests = req.isBatch()
14062
- ? req.resource.requests().filter((r) => r.isMutate())
14063
- : [req];
14064
- for (var r of requests) {
14065
- const scope = this.scope(r);
14066
- this.forget({ scope });
14067
- }
14068
- return res$;
14166
+ return entry.date < Date.now() - entry.maxAge;
14069
14167
  }
14070
14168
  }
14071
14169
 
14072
14170
  class ODataInMemoryCache extends ODataBaseCache {
14073
- constructor({ timeout } = {}) {
14074
- super({ timeout });
14171
+ constructor({ maxAge } = {}) {
14172
+ super({ maxAge });
14075
14173
  }
14076
14174
  /**
14077
14175
  * Store the response in the cache
@@ -14082,7 +14180,7 @@ class ODataInMemoryCache extends ODataBaseCache {
14082
14180
  let scope = this.scope(req);
14083
14181
  let tags = this.tags(res);
14084
14182
  this.put(req.cacheKey, res, {
14085
- timeout: res.options.maxAge,
14183
+ maxAge: req.maxAge ?? res.options.maxAge,
14086
14184
  scope,
14087
14185
  tags,
14088
14186
  });
@@ -14101,8 +14199,8 @@ class ODataInMemoryCache extends ODataBaseCache {
14101
14199
  class ODataInStorageCache extends ODataBaseCache {
14102
14200
  name;
14103
14201
  storage;
14104
- constructor({ name, storage = sessionStorage, timeout, }) {
14105
- super({ timeout });
14202
+ constructor({ name, storage = sessionStorage, maxAge, }) {
14203
+ super({ maxAge });
14106
14204
  this.name = name;
14107
14205
  this.storage = storage;
14108
14206
  this.restore();
@@ -14112,7 +14210,13 @@ class ODataInStorageCache extends ODataBaseCache {
14112
14210
  * Store the cache in the storage
14113
14211
  */
14114
14212
  store() {
14115
- this.storage.setItem(this.name, JSON.stringify(Array.from(this.entries.entries())));
14213
+ this.storage.setItem(this.name, JSON.stringify(Array.from(this.entries.entries()).map(([key, entry]) => [
14214
+ key,
14215
+ {
14216
+ ...entry,
14217
+ payload: entry.payload instanceof ODataResponse ? entry.payload.toJson() : entry.payload,
14218
+ },
14219
+ ])));
14116
14220
  }
14117
14221
  /**
14118
14222
  * Restore the cache from the storage
@@ -14135,8 +14239,8 @@ class ODataInStorageCache extends ODataBaseCache {
14135
14239
  putResponse(req, res) {
14136
14240
  const scope = this.scope(req);
14137
14241
  const tags = this.tags(res);
14138
- this.put(req.cacheKey, res.toJson(), {
14139
- timeout: res.options.maxAge,
14242
+ this.put(req.cacheKey, res, {
14243
+ maxAge: req.maxAge ?? res.options.maxAge,
14140
14244
  scope,
14141
14245
  tags,
14142
14246
  });
@@ -14149,7 +14253,11 @@ class ODataInStorageCache extends ODataBaseCache {
14149
14253
  getResponse(req) {
14150
14254
  const scope = this.scope(req);
14151
14255
  const data = this.get(req.cacheKey, { scope });
14152
- return data !== undefined ? ODataResponse.fromJson(req, data) : undefined;
14256
+ return data instanceof ODataResponse
14257
+ ? data
14258
+ : data !== undefined
14259
+ ? ODataResponse.fromJson(req, data)
14260
+ : undefined;
14153
14261
  }
14154
14262
  }
14155
14263
 
@@ -14161,5 +14269,5 @@ class ODataInStorageCache extends ODataBaseCache {
14161
14269
  * Generated bundle index. Do not edit.
14162
14270
  */
14163
14271
 
14164
- export { Aggregate, ApplyExpression, ArithmeticFunctions, ArithmeticOperators, BUBBLES, CollectionFunctions, ComputeExpression, ConditionalFunctions, DateAndTimeFunctions, Dates, Durations, EDM_PARSERS, EdmType, Enums, ExpandExpression, ExpandField, Expression, FieldFactory, FilterExpression, Function, GeoFunctions, GroupBy, GroupByTransformations, Grouping, GroupingOperators, Http, INCLUDE_DEEP, INCLUDE_SHALLOW, ITEM_ROOT, JsonSchemaType, Lambda, LambdaOperators, LogicalOperators, Model, ModelField, NONE_PARSER, ODATA_CONFIG, OData, ODataActionResource, ODataAnnotations, ODataApi, ODataBaseCache, ODataBaseService, ODataBatchRequest, ODataBatchResource, ODataCallable, ODataCallableParser, ODataClient, ODataCollection, ODataConfigAsyncLoader, ODataConfigLoader, ODataConfigSyncLoader, ODataCountResource, ODataEntitiesAnnotations, ODataEntityAnnotations, ODataEntityContainer, ODataEntityResource, ODataEntitySet, ODataEntitySetResource, ODataEntitySetService, ODataEntityTypeKey, ODataEnumType, ODataEnumTypeFieldParser, ODataEnumTypeParser, ODataFunctionResource, ODataFunctions, ODataInMemoryCache, ODataInStorageCache, ODataMediaResource, ODataMetadata, ODataMetadataLoader, ODataMetadataParser, ODataMetadataResource, ODataModel, ODataModelAttribute, ODataModelEvent, ODataModelEventEmitter, ODataModelEventType, ODataModelField, ODataModelOptions, ODataModelState, ODataModule, ODataNavigationPropertyResource, ODataOperators, ODataParameterParser, ODataPathSegments, ODataPathSegmentsHandler, ODataPropertyAnnotations, ODataPropertyResource, ODataQueryOptionHandler, ODataQueryOptions, ODataQueryOptionsHandler, ODataReferenceResource, ODataReferential, ODataRequest, ODataResource, ODataResponse, ODataSchema, ODataServiceFactory, ODataSettings, ODataSingleton, ODataSingletonResource, ODataSingletonService, ODataStructuredType, ODataStructuredTypeFieldParser, ODataStructuredTypeParser, ODataSyntax, ODataTransformations, ODataValueResource, Objects, Operator, OrderByExpression, OrderByField, PathSegment, QueryCustomTypes, QueryOption, RenderableFactory, SearchExpression, SearchTerm, SegmentHandler, SelectExpression, StandardAggregateMethods, StringAndCollectionFunctions, StringFunctions, Strings, Transformations, Type, TypeFunctions, Types, Urls, alias, binary, buildPathAndQuery, createSyncLoader, duration, encode, functions, isQueryCustomType, isRawType, normalizeValue, operators, pathAndParamsFromQueryOptions, pathAndParamsFromSegments, provideODataClient, raw, render, resolve, syntax, transformations };
14272
+ export { Aggregate, ApplyExpression, ArithmeticFunctions, ArithmeticOperators, BUBBLES, Casting, CastingOperators, CollectionFunctions, ComputeExpression, ConditionalFunctions, DateAndTimeFunctions, Dates, Durations, EDM_PARSERS, EdmType, Enums, ExpandExpression, ExpandField, Expression, FieldFactory, FilterExpression, Function, GeoFunctions, GroupBy, GroupByTransformations, Grouping, GroupingOperators, Http, INCLUDE_DEEP, INCLUDE_SHALLOW, ITEM_ROOT, JsonSchemaType, Lambda, LambdaOperators, LogicalOperators, Model, ModelField, NONE_PARSER, ODATA_CONFIG, OData, ODataActionResource, ODataAnnotations, ODataApi, ODataBaseCache, ODataBaseService, ODataBatchRequest, ODataBatchResource, ODataCallable, ODataCallableParser, ODataClient, ODataCollection, ODataConfigAsyncLoader, ODataConfigLoader, ODataConfigSyncLoader, ODataCountResource, ODataEntitiesAnnotations, ODataEntityAnnotations, ODataEntityContainer, ODataEntityResource, ODataEntitySet, ODataEntitySetResource, ODataEntitySetService, ODataEntityTypeKey, ODataEnumType, ODataEnumTypeFieldParser, ODataEnumTypeParser, ODataFunctionResource, ODataFunctions, ODataInMemoryCache, ODataInStorageCache, ODataMediaResource, ODataMetadata, ODataMetadataLoader, ODataMetadataParser, ODataMetadataResource, ODataModel, ODataModelAttribute, ODataModelEvent, ODataModelEventEmitter, ODataModelEventType, ODataModelField, ODataModelOptions, ODataModelState, ODataModule, ODataNavigationPropertyResource, ODataOperators, ODataParameterParser, ODataPathSegments, ODataPathSegmentsHandler, ODataPropertyAnnotations, ODataPropertyResource, ODataQueryOptionHandler, ODataQueryOptions, ODataQueryOptionsHandler, ODataReferenceResource, ODataReferential, ODataRequest, ODataResource, ODataResponse, ODataSchema, ODataServiceFactory, ODataSettings, ODataSingleton, ODataSingletonResource, ODataSingletonService, ODataStructuredType, ODataStructuredTypeFieldParser, ODataStructuredTypeParser, ODataTransformations, ODataValueResource, Objects, Operator, OrderByExpression, OrderByField, PathSegment, QueryCustomTypes, QueryOption, RenderableFactory, SearchExpression, SearchTerm, SegmentHandler, SelectExpression, StandardAggregateMethods, StringAndCollectionFunctions, StringFunctions, Strings, Transformations, Type, TypeFunctions, Types, Urls, alias, binary, buildPathAndQuery, createSyncLoader, duration, encode, functions, isQueryCustomType, isRawType, normalizeValue, operators, pathAndParamsFromQueryOptions, pathAndParamsFromSegments, provideODataClient, raw, render, resolve, transformations };
14165
14273
  //# sourceMappingURL=angular-odata.mjs.map