@ember-data/model 5.3.0-alpha.1 → 5.3.0-alpha.11

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.
@@ -1,13 +1,13 @@
1
1
  import { macroCondition, getOwnConfig, importSync } from '@embroider/macros';
2
- import { assert, warn } from '@ember/debug';
3
- import EmberObject, { computed, get } from '@ember/object';
4
- import { recordIdentifierFor, storeFor as storeFor$1 } from '@ember-data/store';
5
- import { peekCache, RecordArray, MUTATE, SOURCE, recordIdentifierFor as recordIdentifierFor$1, IDENTIFIER_ARRAY_TAG, notifyArray, isStableIdentifier, storeFor, fastPush, coerceId } from '@ember-data/store/-private';
2
+ import { deprecate, assert, warn } from '@ember/debug';
6
3
  import { dasherize } from '@ember/string';
4
+ import EmberObject, { computed, get } from '@ember/object';
7
5
  import { dependentKeyCompat } from '@ember/object/compat';
8
6
  import { run } from '@ember/runloop';
9
7
  import { cached, tracked } from '@glimmer/tracking';
10
8
  import Ember from 'ember';
9
+ import { recordIdentifierFor as recordIdentifierFor$1, storeFor as storeFor$1 } from '@ember-data/store';
10
+ import { RecordArray, MUTATE, SOURCE, recordIdentifierFor, IDENTIFIER_ARRAY_TAG, notifyArray, isStableIdentifier, storeFor, peekCache, fastPush, coerceId } from '@ember-data/store/-private';
11
11
  import { A } from '@ember/array';
12
12
  import ArrayProxy from '@ember/array/proxy';
13
13
  import { mapBy, not } from '@ember/object/computed';
@@ -15,7 +15,6 @@ import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
15
15
  import ObjectProxy from '@ember/object/proxy';
16
16
  import { cacheFor } from '@ember/object/internals';
17
17
  import { addToTransaction, subscribe } from '@ember-data/tracking/-private';
18
- import { singularize } from 'ember-inflector';
19
18
  function isElementDescriptor(args) {
20
19
  let [maybeTarget, maybeKey, maybeDesc] = args;
21
20
  return (
@@ -34,152 +33,22 @@ function isElementDescriptor(args) {
34
33
  function computedMacroWithOptionalParams(fn) {
35
34
  return (...maybeDesc) => isElementDescriptor(maybeDesc) ? fn()(...maybeDesc) : fn(...maybeDesc);
36
35
  }
37
-
38
- /**
39
- @module @ember-data/model
40
- */
41
-
42
- /**
43
- `attr` defines an attribute on a [Model](/ember-data/release/classes/Model).
44
- By default, attributes are passed through as-is, however you can specify an
45
- optional type to have the value automatically transformed.
46
- Ember Data ships with four basic transform types: `string`, `number`,
47
- `boolean` and `date`. You can define your own transforms by subclassing
48
- [Transform](/ember-data/release/classes/Transform).
49
-
50
- Note that you cannot use `attr` to define an attribute of `id`.
51
-
52
- `attr` takes an optional hash as a second parameter, currently
53
- supported options are:
54
-
55
- - `defaultValue`: Pass a string or a function to be called to set the attribute
56
- to a default value if and only if the key is absent from the payload response.
57
-
58
- Example
59
-
60
- ```app/models/user.js
61
- import Model, { attr } from '@ember-data/model';
62
-
63
- export default class UserModel extends Model {
64
- @attr('string') username;
65
- @attr('string') email;
66
- @attr('boolean', { defaultValue: false }) verified;
67
- }
68
- ```
69
-
70
- Default value can also be a function. This is useful it you want to return
71
- a new object for each attribute.
72
-
73
- ```app/models/user.js
74
- import Model, { attr } from '@ember-data/model';
75
-
76
- export default class UserModel extends Model {
77
- @attr('string') username;
78
- @attr('string') email;
79
-
80
- @attr({
81
- defaultValue() {
82
- return {};
36
+ function normalizeModelName(type) {
37
+ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_STRICT_TYPES)) {
38
+ const result = dasherize(type);
39
+ deprecate(`The resource type '${type}' is not normalized. Update your application code to use '${result}' instead of '${type}'.`, result === type, {
40
+ id: 'ember-data:deprecate-non-strict-types',
41
+ until: '6.0',
42
+ for: 'ember-data',
43
+ since: {
44
+ available: '5.3',
45
+ enabled: '5.3'
83
46
  }
84
- })
85
- settings;
86
- }
87
- ```
88
-
89
- The `options` hash is passed as second argument to a transforms'
90
- `serialize` and `deserialize` method. This allows to configure a
91
- transformation and adapt the corresponding value, based on the config:
92
-
93
- ```app/models/post.js
94
- import Model, { attr } from '@ember-data/model';
95
-
96
- export default class PostModel extends Model {
97
- @attr('text', {
98
- uppercase: true
99
- })
100
- text;
101
- }
102
- ```
103
-
104
- ```app/transforms/text.js
105
- export default class TextTransform {
106
- serialize(value, options) {
107
- if (options.uppercase) {
108
- return value.toUpperCase();
109
- }
110
-
111
- return value;
112
- }
113
-
114
- deserialize(value) {
115
- return value;
116
- }
117
-
118
- static create() {
119
- return new this();
120
- }
121
- }
122
- ```
123
-
124
- @method attr
125
- @public
126
- @static
127
- @for @ember-data/model
128
- @param {String|Object} type the attribute type
129
- @param {Object} options a hash of options
130
- @return {Attribute}
131
- */
132
- function attr(type, options) {
133
- if (typeof type === 'object') {
134
- options = type;
135
- type = undefined;
136
- } else {
137
- options = options || {};
47
+ });
48
+ return result;
138
49
  }
139
- let meta = {
140
- type: type,
141
- isAttribute: true,
142
- options: options
143
- };
144
- return computed({
145
- get(key) {
146
- if (macroCondition(getOwnConfig().env.DEBUG)) {
147
- if (['currentState'].indexOf(key) !== -1) {
148
- throw new Error(`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your attr on ${this.constructor.toString()}`);
149
- }
150
- }
151
- if (this.isDestroyed || this.isDestroying) {
152
- return;
153
- }
154
- return peekCache(this).getAttr(recordIdentifierFor(this), key);
155
- },
156
- set(key, value) {
157
- if (macroCondition(getOwnConfig().env.DEBUG)) {
158
- if (['currentState'].indexOf(key) !== -1) {
159
- throw new Error(`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your attr on ${this.constructor.toString()}`);
160
- }
161
- }
162
- assert(`Attempted to set '${key}' on the deleted record ${recordIdentifierFor(this)}`, !this.currentState.isDeleted);
163
- const identifier = recordIdentifierFor(this);
164
- const cache = peekCache(this);
165
- let currentValue = cache.getAttr(identifier, key);
166
- if (currentValue !== value) {
167
- cache.setAttr(identifier, key, value);
168
- if (!this.isValid) {
169
- const {
170
- errors
171
- } = this;
172
- if (errors.get(key)) {
173
- errors.remove(key);
174
- this.currentState.cleanErrorRequests();
175
- }
176
- }
177
- }
178
- return value;
179
- }
180
- }).meta(meta);
50
+ return type;
181
51
  }
182
- var attr$1 = computedMacroWithOptionalParams(attr);
183
52
  function _initializerDefineProperty(target, property, descriptor, context) {
184
53
  if (!descriptor) return;
185
54
  Object.defineProperty(target, property, {
@@ -728,7 +597,7 @@ class RelatedCollection extends RecordArray {
728
597
  op: 'removeFromRelatedRecords',
729
598
  record: this.identifier,
730
599
  field: this.key,
731
- value: recordIdentifierFor$1(result)
600
+ value: recordIdentifierFor(result)
732
601
  });
733
602
  }
734
603
  break;
@@ -747,7 +616,7 @@ class RelatedCollection extends RecordArray {
747
616
  op: 'removeFromRelatedRecords',
748
617
  record: this.identifier,
749
618
  field: this.key,
750
- value: recordIdentifierFor$1(result),
619
+ value: recordIdentifierFor(result),
751
620
  index: 0
752
621
  });
753
622
  }
@@ -757,7 +626,7 @@ class RelatedCollection extends RecordArray {
757
626
  op: 'sortRelatedRecords',
758
627
  record: this.identifier,
759
628
  field: this.key,
760
- value: result.map(recordIdentifierFor$1)
629
+ value: result.map(recordIdentifierFor)
761
630
  });
762
631
  break;
763
632
  case 'splice':
@@ -778,7 +647,7 @@ class RelatedCollection extends RecordArray {
778
647
  op: 'removeFromRelatedRecords',
779
648
  record: this.identifier,
780
649
  field: this.key,
781
- value: result.map(recordIdentifierFor$1),
650
+ value: result.map(recordIdentifierFor),
782
651
  index: start
783
652
  });
784
653
  }
@@ -858,6 +727,9 @@ class RelatedCollection extends RecordArray {
858
727
  this.push(record);
859
728
  return record;
860
729
  }
730
+ destroy() {
731
+ super.destroy(false);
732
+ }
861
733
  }
862
734
  RelatedCollection.prototype.isAsync = false;
863
735
  RelatedCollection.prototype.isPolymorphic = false;
@@ -869,7 +741,7 @@ RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
869
741
  function assertRecordPassedToHasMany(record) {
870
742
  assert(`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`, function () {
871
743
  try {
872
- recordIdentifierFor$1(record);
744
+ recordIdentifierFor(record);
873
745
  return true;
874
746
  } catch {
875
747
  return false;
@@ -881,7 +753,7 @@ function extractIdentifiersFromRecords(records) {
881
753
  }
882
754
  function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
883
755
  assertRecordPassedToHasMany(recordOrPromiseRecord);
884
- return recordIdentifierFor$1(recordOrPromiseRecord);
756
+ return recordIdentifierFor(recordOrPromiseRecord);
885
757
  }
886
758
  const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
887
759
  var _dec, _class$5;
@@ -919,7 +791,7 @@ let PromiseBelongsTo = (_dec = computed(), (_class$5 = class PromiseBelongsTo ex
919
791
  get meta() {
920
792
  // eslint-disable-next-line no-constant-condition
921
793
  {
922
- assert('You attempted to access meta on the promise for the async belongsTo relationship ' + `${this.get('_belongsToState').modelName}:${this.get('_belongsToState').key}'.` + '\nUse `record.belongsTo(relationshipName).meta()` instead.', false);
794
+ assert('You attempted to access meta on the promise for the async belongsTo relationship ' + `${this._belongsToState.modelName}:${this._belongsToState.key}'.` + '\nUse `record.belongsTo(relationshipName).meta()` instead.', false);
923
795
  }
924
796
  return;
925
797
  }
@@ -1224,12 +1096,8 @@ function isResourceIdentiferWithRelatedLinks$1(value) {
1224
1096
  @public
1225
1097
  */
1226
1098
  let BelongsToReference = (_class$3 = class BelongsToReference {
1227
- // unsubscribe tokens given to us by the notification manager
1228
-
1229
1099
  constructor(store, graph, parentIdentifier, belongsToRelationship, key) {
1230
- this.___identifier = void 0;
1231
- this.___token = void 0;
1232
- this.___relatedToken = null;
1100
+ // unsubscribe tokens given to us by the notification manager
1233
1101
  _initializerDefineProperty(this, "_ref", _descriptor$3, this);
1234
1102
  this.graph = graph;
1235
1103
  this.key = key;
@@ -1237,6 +1105,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
1237
1105
  this.type = belongsToRelationship.definition.type;
1238
1106
  this.store = store;
1239
1107
  this.___identifier = parentIdentifier;
1108
+ this.___relatedToken = null;
1240
1109
  this.___token = store.notifications.subscribe(parentIdentifier, (_, bucket, notifiedKey) => {
1241
1110
  if (bucket === 'relationships' && notifiedKey === key) {
1242
1111
  this._ref++;
@@ -1512,7 +1381,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
1512
1381
  let record = this.store.push(jsonApiDoc);
1513
1382
  if (macroCondition(getOwnConfig().env.DEBUG)) {
1514
1383
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
1515
- assertPolymorphicType(this.belongsToRelationship.identifier, this.belongsToRelationship.definition, recordIdentifierFor$1(record), this.store);
1384
+ assertPolymorphicType(this.belongsToRelationship.identifier, this.belongsToRelationship.definition, recordIdentifierFor(record), this.store);
1516
1385
  }
1517
1386
  const {
1518
1387
  identifier
@@ -1522,7 +1391,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
1522
1391
  op: 'replaceRelatedRecord',
1523
1392
  record: identifier,
1524
1393
  field: this.key,
1525
- value: recordIdentifierFor$1(record)
1394
+ value: recordIdentifierFor(record)
1526
1395
  });
1527
1396
  });
1528
1397
  return Promise.resolve(record);
@@ -1704,9 +1573,8 @@ function isResourceIdentiferWithRelatedLinks(value) {
1704
1573
  @extends Reference
1705
1574
  */
1706
1575
  let HasManyReference = (_class$2 = class HasManyReference {
1707
- // unsubscribe tokens given to us by the notification manager
1708
-
1709
1576
  constructor(store, graph, parentIdentifier, hasManyRelationship, key) {
1577
+ // unsubscribe tokens given to us by the notification manager
1710
1578
  this.___token = void 0;
1711
1579
  this.___identifier = void 0;
1712
1580
  this.___relatedTokenMap = void 0;
@@ -2010,9 +1878,9 @@ let HasManyReference = (_class$2 = class HasManyReference {
2010
1878
  let identifier = this.hasManyRelationship.identifier;
2011
1879
 
2012
1880
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
2013
- assertPolymorphicType(identifier, relationshipMeta, recordIdentifierFor(record), store);
1881
+ assertPolymorphicType(identifier, relationshipMeta, recordIdentifierFor$1(record), store);
2014
1882
  }
2015
- return recordIdentifierFor(record);
1883
+ return recordIdentifierFor$1(record);
2016
1884
  });
2017
1885
  const {
2018
1886
  identifier
@@ -2199,8 +2067,12 @@ class LegacySupport {
2199
2067
  constructor(record) {
2200
2068
  this.record = record;
2201
2069
  this.store = storeFor(record);
2202
- this.identifier = recordIdentifierFor$1(record);
2070
+ this.identifier = recordIdentifierFor(record);
2203
2071
  this.cache = peekCache(record);
2072
+ if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
2073
+ const graphFor = importSync('@ember-data/graph/-private').graphFor;
2074
+ this.graph = graphFor(this.store);
2075
+ }
2204
2076
  this._manyArrayCache = Object.create(null);
2205
2077
  this._relationshipPromisesCache = Object.create(null);
2206
2078
  this._relationshipProxyCache = Object.create(null);
@@ -2237,14 +2109,14 @@ class LegacySupport {
2237
2109
  if (loadingPromise) {
2238
2110
  return loadingPromise;
2239
2111
  }
2240
- const graphFor = importSync('@ember-data/graph/-private').graphFor;
2241
- const relationship = graphFor(this.store).get(this.identifier, key);
2112
+ const relationship = this.graph.get(this.identifier, key);
2242
2113
  assert(`Expected ${key} to be a belongs-to relationship`, isBelongsTo(relationship));
2243
2114
  let resource = this.cache.getRelationship(this.identifier, key);
2244
2115
  relationship.state.hasFailedLoadAttempt = false;
2245
2116
  relationship.state.shouldForceReload = true;
2246
2117
  let promise = this._findBelongsTo(key, resource, relationship, options);
2247
2118
  if (this._relationshipProxyCache[key]) {
2119
+ // @ts-expect-error
2248
2120
  return this._updatePromiseProxyFor('belongsTo', key, {
2249
2121
  promise
2250
2122
  });
@@ -2260,8 +2132,7 @@ class LegacySupport {
2260
2132
  let relatedIdentifier = resource && resource.data ? resource.data : null;
2261
2133
  assert(`Expected a stable identifier`, !relatedIdentifier || isStableIdentifier(relatedIdentifier));
2262
2134
  const store = this.store;
2263
- const graphFor = importSync('@ember-data/graph/-private').graphFor;
2264
- const relationship = graphFor(store).get(this.identifier, key);
2135
+ const relationship = this.graph.get(this.identifier, key);
2265
2136
  assert(`Expected ${key} to be a belongs-to relationship`, isBelongsTo(relationship));
2266
2137
  let isAsync = relationship.definition.isAsync;
2267
2138
  let _belongsToState = {
@@ -2307,10 +2178,10 @@ class LegacySupport {
2307
2178
  let identifiers = [];
2308
2179
  if (jsonApi.data) {
2309
2180
  for (let i = 0; i < jsonApi.data.length; i++) {
2310
- const identifier = jsonApi.data[i];
2311
- assert(`Expected a stable identifier`, isStableIdentifier(identifier));
2312
- if (cache.recordIsLoaded(identifier, true)) {
2313
- identifiers.push(identifier);
2181
+ const relatedIdentifier = jsonApi.data[i];
2182
+ assert(`Expected a stable identifier`, isStableIdentifier(relatedIdentifier));
2183
+ if (cache.recordIsLoaded(relatedIdentifier, true)) {
2184
+ identifiers.push(relatedIdentifier);
2314
2185
  }
2315
2186
  }
2316
2187
  }
@@ -2320,8 +2191,7 @@ class LegacySupport {
2320
2191
  if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
2321
2192
  let manyArray = this._manyArrayCache[key];
2322
2193
  if (!definition) {
2323
- const graphFor = importSync('@ember-data/graph/-private').graphFor;
2324
- definition = graphFor(this.store).get(this.identifier, key).definition;
2194
+ definition = this.graph.get(this.identifier, key).definition;
2325
2195
  }
2326
2196
  if (!manyArray) {
2327
2197
  const [identifiers, doc] = this._getCurrentState(this.identifier, key);
@@ -2371,8 +2241,7 @@ class LegacySupport {
2371
2241
  if (loadingPromise) {
2372
2242
  return loadingPromise;
2373
2243
  }
2374
- const graphFor = importSync('@ember-data/graph/-private').graphFor;
2375
- const relationship = graphFor(this.store).get(this.identifier, key);
2244
+ const relationship = this.graph.get(this.identifier, key);
2376
2245
  const {
2377
2246
  definition,
2378
2247
  state
@@ -2392,8 +2261,7 @@ class LegacySupport {
2392
2261
  }
2393
2262
  getHasMany(key, options) {
2394
2263
  if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
2395
- const graphFor = importSync('@ember-data/graph/-private').graphFor;
2396
- const relationship = graphFor(this.store).get(this.identifier, key);
2264
+ const relationship = this.graph.get(this.identifier, key);
2397
2265
  const {
2398
2266
  definition,
2399
2267
  state
@@ -2455,21 +2323,23 @@ class LegacySupport {
2455
2323
  // because of the intimate API access involved. This is something we will need to redesign.
2456
2324
  assert(`snapshot.belongsTo only supported for @ember-data/json-api`);
2457
2325
  }
2458
- const graphFor = importSync('@ember-data/graph/-private').graphFor;
2459
- const graph = graphFor(this.store);
2460
- const relationship = graph.get(this.identifier, name);
2326
+ const {
2327
+ graph,
2328
+ identifier
2329
+ } = this;
2330
+ const relationship = graph.get(identifier, name);
2461
2331
  if (macroCondition(getOwnConfig().env.DEBUG)) {
2462
2332
  if (kind) {
2463
- let modelName = this.identifier.type;
2333
+ let modelName = identifier.type;
2464
2334
  let actualRelationshipKind = relationship.definition.kind;
2465
2335
  assert(`You tried to get the '${name}' relationship on a '${modelName}' via record.${kind}('${name}'), but the relationship is of kind '${actualRelationshipKind}'. Use record.${actualRelationshipKind}('${name}') instead.`, actualRelationshipKind === kind);
2466
2336
  }
2467
2337
  }
2468
2338
  let relationshipKind = relationship.definition.kind;
2469
2339
  if (relationshipKind === 'belongsTo') {
2470
- reference = new BelongsToReference(this.store, graph, this.identifier, relationship, name);
2340
+ reference = new BelongsToReference(this.store, graph, identifier, relationship, name);
2471
2341
  } else if (relationshipKind === 'hasMany') {
2472
- reference = new HasManyReference(this.store, graph, this.identifier, relationship, name);
2342
+ reference = new HasManyReference(this.store, graph, identifier, relationship, name);
2473
2343
  }
2474
2344
  this.references[name] = reference;
2475
2345
  }
@@ -2699,7 +2569,7 @@ function extractIdentifierFromRecord(record) {
2699
2569
  if (!record) {
2700
2570
  return null;
2701
2571
  }
2702
- return recordIdentifierFor$1(record);
2572
+ return recordIdentifierFor(record);
2703
2573
  }
2704
2574
  function anyUnloaded(store, relationship) {
2705
2575
  let state = relationship.localState;
@@ -2733,8 +2603,8 @@ function notifyChanges(identifier, value, key, record, store) {
2733
2603
  if (key) {
2734
2604
  notifyAttribute(store, identifier, key, record);
2735
2605
  } else {
2736
- record.eachAttribute(key => {
2737
- notifyAttribute(store, identifier, key, record);
2606
+ record.eachAttribute(name => {
2607
+ notifyAttribute(store, identifier, name, record);
2738
2608
  });
2739
2609
  }
2740
2610
  } else if (value === 'relationships') {
@@ -2742,8 +2612,8 @@ function notifyChanges(identifier, value, key, record, store) {
2742
2612
  let meta = record.constructor.relationshipsByName.get(key);
2743
2613
  notifyRelationship(identifier, key, record, meta);
2744
2614
  } else {
2745
- record.eachRelationship((key, meta) => {
2746
- notifyRelationship(identifier, key, record, meta);
2615
+ record.eachRelationship((name, meta) => {
2616
+ notifyRelationship(identifier, name, record, meta);
2747
2617
  });
2748
2618
  }
2749
2619
  } else if (value === 'identity') {
@@ -2803,6 +2673,11 @@ function isInvalidError(error) {
2803
2673
  let Tag = (_class$1 = class Tag {
2804
2674
  constructor() {
2805
2675
  _initializerDefineProperty(this, "ref", _descriptor$1, this);
2676
+ if (macroCondition(getOwnConfig().env.DEBUG)) {
2677
+ const [base, prop] = arguments;
2678
+ this._debug_base = base;
2679
+ this._debug_prop = prop;
2680
+ }
2806
2681
  this.rev = 1;
2807
2682
  this.isDirty = true;
2808
2683
  this.value = undefined;
@@ -2835,7 +2710,8 @@ function getTag(record, key) {
2835
2710
  tags = Object.create(null);
2836
2711
  Tags.set(record, tags);
2837
2712
  }
2838
- return tags[key] = tags[key] || new Tag();
2713
+ // @ts-expect-error
2714
+ return tags[key] = tags[key] || (macroCondition(getOwnConfig().env.DEBUG) ? new Tag(record.constructor.modelName, key) : new Tag());
2839
2715
  }
2840
2716
  function peekTag(record, key) {
2841
2717
  let tags = Tags.get(record);
@@ -2913,7 +2789,7 @@ let RecordState = (_class3 = class RecordState {
2913
2789
  constructor(record) {
2914
2790
  _initializerDefineProperty(this, "isSaving", _descriptor2, this);
2915
2791
  const store = storeFor$1(record);
2916
- const identity = recordIdentifierFor$1(record);
2792
+ const identity = recordIdentifierFor(record);
2917
2793
  this.identifier = identity;
2918
2794
  this.record = record;
2919
2795
  this.cache = store.cache;
@@ -3184,7 +3060,7 @@ const {
3184
3060
  } = Ember;
3185
3061
  const LEGACY_SUPPORT = new Map();
3186
3062
  function lookupLegacySupport(record) {
3187
- const identifier = recordIdentifierFor(record);
3063
+ const identifier = recordIdentifierFor$1(record);
3188
3064
  let support = LEGACY_SUPPORT.get(identifier);
3189
3065
  if (!support) {
3190
3066
  assert(`Memory Leak Detected`, !record.isDestroyed && !record.isDestroying);
@@ -3301,7 +3177,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3301
3177
  });
3302
3178
  }
3303
3179
  destroy() {
3304
- const identifier = recordIdentifierFor(this);
3180
+ const identifier = recordIdentifierFor$1(this);
3305
3181
  this.___recordState?.destroy();
3306
3182
  const store = storeFor$1(this);
3307
3183
  store.notifications.unsubscribe(this.___private_notifications);
@@ -3565,16 +3441,16 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3565
3441
  // object is real.
3566
3442
  if (macroCondition(getOwnConfig().env.DEBUG)) {
3567
3443
  try {
3568
- return recordIdentifierFor(this).id;
3444
+ return recordIdentifierFor$1(this).id;
3569
3445
  } catch {
3570
3446
  return void 0;
3571
3447
  }
3572
3448
  }
3573
- return recordIdentifierFor(this).id;
3449
+ return recordIdentifierFor$1(this).id;
3574
3450
  }
3575
3451
  set id(id) {
3576
3452
  const normalizedId = coerceId(id);
3577
- const identifier = recordIdentifierFor(this);
3453
+ const identifier = recordIdentifierFor$1(this);
3578
3454
  let didChange = normalizedId !== identifier.id;
3579
3455
  assert(`Cannot set ${identifier.type} record's id to ${id}, because id is already ${identifier.id}`, !didChange || identifier.id === null);
3580
3456
  if (normalizedId !== null && didChange) {
@@ -3866,7 +3742,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3866
3742
  and value is an [oldProp, newProp] array.
3867
3743
  */
3868
3744
  changedAttributes() {
3869
- return peekCache(this).changedAttrs(recordIdentifierFor(this));
3745
+ return peekCache(this).changedAttrs(recordIdentifierFor$1(this));
3870
3746
  }
3871
3747
 
3872
3748
  /**
@@ -3892,7 +3768,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3892
3768
  isNew
3893
3769
  } = currentState;
3894
3770
  storeFor$1(this)._join(() => {
3895
- peekCache(this).rollbackAttrs(recordIdentifierFor(this));
3771
+ peekCache(this).rollbackAttrs(recordIdentifierFor$1(this));
3896
3772
  this.errors.clear();
3897
3773
  currentState.cleanErrorRequests();
3898
3774
  if (isNew) {
@@ -3912,7 +3788,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3912
3788
  const FetchManager = importSync('@ember-data/legacy-compat/-private').FetchManager;
3913
3789
  store._fetchManager = new FetchManager(store);
3914
3790
  }
3915
- return store._fetchManager.createSnapshot(recordIdentifierFor(this));
3791
+ return store._fetchManager.createSnapshot(recordIdentifierFor$1(this));
3916
3792
  }
3917
3793
 
3918
3794
  /**
@@ -3954,6 +3830,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3954
3830
  if (this.currentState.isNew && this.currentState.isDeleted) {
3955
3831
  promise = Promise.resolve(this);
3956
3832
  } else {
3833
+ this.errors.clear();
3957
3834
  promise = storeFor$1(this).saveRecord(this, options);
3958
3835
  }
3959
3836
  return promise;
@@ -3985,7 +3862,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
3985
3862
  reload(options = {}) {
3986
3863
  options.isReloading = true;
3987
3864
  options.reload = true;
3988
- const identifier = recordIdentifierFor(this);
3865
+ const identifier = recordIdentifierFor$1(this);
3989
3866
  assert(`You cannot reload a record without an ID`, identifier.id);
3990
3867
  this.isReloading = true;
3991
3868
  const promise = storeFor$1(this).request({
@@ -4167,41 +4044,6 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
4167
4044
  eachAttribute(callback, binding) {
4168
4045
  this.constructor.eachAttribute(callback, binding);
4169
4046
  }
4170
-
4171
- /**
4172
- Create should only ever be called by the store. To create an instance of a
4173
- `Model` in a dirty state use `store.createRecord`.
4174
- To create instances of `Model` in a clean state, use `store.push`
4175
- @method create
4176
- @private
4177
- @static
4178
- */
4179
- /**
4180
- Represents the model's class name as a string. This can be used to look up the model's class name through
4181
- `Store`'s modelFor method.
4182
- `modelName` is generated for you by Ember Data. It will be a lowercased, dasherized string.
4183
- For example:
4184
- ```javascript
4185
- store.modelFor('post').modelName; // 'post'
4186
- store.modelFor('blog-post').modelName; // 'blog-post'
4187
- ```
4188
- The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
4189
- keys to underscore (instead of dasherized), you might use the following code:
4190
- ```javascript
4191
- import RESTSerializer from '@ember-data/serializer/rest';
4192
- import { underscore } from '<app-name>/utils/string-utils';
4193
- export default const PostSerializer = RESTSerializer.extend({
4194
- payloadKeyFromModelName(modelName) {
4195
- return underscore(modelName);
4196
- }
4197
- });
4198
- ```
4199
- @property modelName
4200
- @public
4201
- @type String
4202
- @readonly
4203
- @static
4204
- */
4205
4047
  /*
4206
4048
  These class methods below provide relationship
4207
4049
  introspection abilities about relationships.
@@ -4868,7 +4710,7 @@ if (macroCondition(getOwnConfig().includeDataAdapter)) {
4868
4710
  Model.prototype._debugInfo = function () {
4869
4711
  let relationships = {};
4870
4712
  let expensiveProperties = [];
4871
- const identifier = recordIdentifierFor(this);
4713
+ const identifier = recordIdentifierFor$1(this);
4872
4714
  const schema = this.store.getSchemaDefinitionService();
4873
4715
  const attrDefs = schema.attributesDefinitionFor(identifier);
4874
4716
  const relDefs = schema.relationshipsDefinitionFor(identifier);
@@ -4943,344 +4785,4 @@ if (macroCondition(getOwnConfig().env.DEBUG)) {
4943
4785
  assert(`Model.reopenClass is deprecated. Use Foo extends Model to add static methods and properties to your class instead.`);
4944
4786
  };
4945
4787
  }
4946
- function normalizeType$1(type) {
4947
- return dasherize(type);
4948
- }
4949
- /**
4950
- @module @ember-data/model
4951
- */
4952
-
4953
- /**
4954
- `belongsTo` is used to define One-To-One and One-To-Many
4955
- relationships on a [Model](/ember-data/release/classes/Model).
4956
-
4957
-
4958
- `belongsTo` takes an optional hash as a second parameter, currently
4959
- supported options are:
4960
-
4961
- - `async`: A boolean value used to explicitly declare this to be an async relationship. The default is true.
4962
- - `inverse`: A string used to identify the inverse property on a
4963
- related model in a One-To-Many relationship. See [Explicit Inverses](#explicit-inverses)
4964
- - `polymorphic` A boolean value to mark the relationship as polymorphic
4965
-
4966
- #### One-To-One
4967
- To declare a one-to-one relationship between two models, use
4968
- `belongsTo`:
4969
-
4970
- ```app/models/user.js
4971
- import Model, { belongsTo } from '@ember-data/model';
4972
-
4973
- export default class UserModel extends Model {
4974
- @belongsTo('profile') profile;
4975
- }
4976
- ```
4977
-
4978
- ```app/models/profile.js
4979
- import Model, { belongsTo } from '@ember-data/model';
4980
-
4981
- export default class ProfileModel extends Model {
4982
- @belongsTo('user') user;
4983
- }
4984
- ```
4985
-
4986
- #### One-To-Many
4987
-
4988
- To declare a one-to-many relationship between two models, use
4989
- `belongsTo` in combination with `hasMany`, like this:
4990
-
4991
- ```app/models/post.js
4992
- import Model, { hasMany } from '@ember-data/model';
4993
-
4994
- export default class PostModel extends Model {
4995
- @hasMany('comment', { async: false, inverse: 'post' }) comments;
4996
- }
4997
- ```
4998
-
4999
- ```app/models/comment.js
5000
- import Model, { belongsTo } from '@ember-data/model';
5001
-
5002
- export default class CommentModel extends Model {
5003
- @belongsTo('post', { async: false, inverse: 'comments' }) post;
5004
- }
5005
- ```
5006
-
5007
- #### Sync relationships
5008
-
5009
- Ember Data resolves sync relationships with the related resources
5010
- available in its local store, hence it is expected these resources
5011
- to be loaded before or along-side the primary resource.
5012
-
5013
- ```app/models/comment.js
5014
- import Model, { belongsTo } from '@ember-data/model';
5015
-
5016
- export default class CommentModel extends Model {
5017
- @belongsTo('post', {
5018
- async: false,
5019
- inverse: null
5020
- })
5021
- post;
5022
- }
5023
- ```
5024
-
5025
- In contrast to async relationship, accessing a sync relationship
5026
- will always return the record (Model instance) for the existing
5027
- local resource, or null. But it will error on access when
5028
- a related resource is known to exist and it has not been loaded.
5029
-
5030
- ```
5031
- let post = comment.post;
5032
-
5033
- ```
5034
-
5035
- @method belongsTo
5036
- @public
5037
- @static
5038
- @for @ember-data/model
5039
- @param {String} modelName (optional) type of the relationship
5040
- @param {Object} options (optional) a hash of options
5041
- @return {Ember.computed} relationship
5042
- */
5043
- function belongsTo(modelName, options) {
5044
- let opts = options;
5045
- let userEnteredModelName = modelName;
5046
- assert(`Expected belongsTo options.async to be a boolean`, opts && typeof opts.async === 'boolean');
5047
- assert(`Expected belongsTo options.inverse to be either null or the string type of the related resource.`, opts.inverse === null || typeof opts.inverse === 'string' && opts.inverse.length > 0);
5048
- let meta = {
5049
- type: normalizeType$1(userEnteredModelName),
5050
- isRelationship: true,
5051
- options: opts,
5052
- kind: 'belongsTo',
5053
- name: 'Belongs To',
5054
- key: null
5055
- };
5056
- return computed({
5057
- get(key) {
5058
- // this is a legacy behavior we may not carry into a new model setup
5059
- // it's better to error on disconnected records so users find errors
5060
- // in their logic.
5061
- if (this.isDestroying || this.isDestroyed) {
5062
- return null;
5063
- }
5064
- const support = lookupLegacySupport(this);
5065
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5066
- if (['currentState'].indexOf(key) !== -1) {
5067
- throw new Error(`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your belongsTo on ${this.constructor.toString()}`);
5068
- }
5069
- if (Object.prototype.hasOwnProperty.call(opts, 'serialize')) {
5070
- warn(`You provided a serialize option on the "${key}" property in the "${support.identifier.type}" class, this belongs in the serializer. See Serializer and it's implementations https://api.emberjs.com/ember-data/release/classes/Serializer`, false, {
5071
- id: 'ds.model.serialize-option-in-belongs-to'
5072
- });
5073
- }
5074
- if (Object.prototype.hasOwnProperty.call(opts, 'embedded')) {
5075
- warn(`You provided an embedded option on the "${key}" property in the "${support.identifier.type}" class, this belongs in the serializer. See EmbeddedRecordsMixin https://api.emberjs.com/ember-data/release/classes/EmbeddedRecordsMixin`, false, {
5076
- id: 'ds.model.embedded-option-in-belongs-to'
5077
- });
5078
- }
5079
- }
5080
- return support.getBelongsTo(key);
5081
- },
5082
- set(key, value) {
5083
- const support = lookupLegacySupport(this);
5084
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5085
- if (['currentState'].indexOf(key) !== -1) {
5086
- throw new Error(`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your belongsTo on ${this.constructor.toString()}`);
5087
- }
5088
- }
5089
- this.store._join(() => {
5090
- support.setDirtyBelongsTo(key, value);
5091
- });
5092
- return support.getBelongsTo(key);
5093
- }
5094
- }).meta(meta);
5095
- }
5096
- var belongsTo$1 = computedMacroWithOptionalParams(belongsTo);
5097
- function normalizeType(type) {
5098
- return singularize(dasherize(type));
5099
- }
5100
-
5101
- /**
5102
- `hasMany` is used to define One-To-Many and Many-To-Many
5103
- relationships on a [Model](/ember-data/release/classes/Model).
5104
-
5105
- `hasMany` takes an optional hash as a second parameter, currently
5106
- supported options are:
5107
-
5108
- - `async`: A boolean value used to explicitly declare this to be an async relationship. The default is true.
5109
- - `inverse`: A string used to identify the inverse property on a related model.
5110
- - `polymorphic` A boolean value to mark the relationship as polymorphic
5111
-
5112
- #### One-To-Many
5113
- To declare a one-to-many relationship between two models, use
5114
- `belongsTo` in combination with `hasMany`, like this:
5115
-
5116
- ```app/models/post.js
5117
- import Model, { hasMany } from '@ember-data/model';
5118
-
5119
- export default class PostModel extends Model {
5120
- @hasMany('comment') comments;
5121
- }
5122
- ```
5123
-
5124
- ```app/models/comment.js
5125
- import Model, { belongsTo } from '@ember-data/model';
5126
-
5127
- export default class CommentModel extends Model {
5128
- @belongsTo('post') post;
5129
- }
5130
- ```
5131
-
5132
- #### Many-To-Many
5133
- To declare a many-to-many relationship between two models, use
5134
- `hasMany`:
5135
-
5136
- ```app/models/post.js
5137
- import Model, { hasMany } from '@ember-data/model';
5138
-
5139
- export default class PostModel extends Model {
5140
- @hasMany('tag') tags;
5141
- }
5142
- ```
5143
-
5144
- ```app/models/tag.js
5145
- import Model, { hasMany } from '@ember-data/model';
5146
-
5147
- export default class TagModel extends Model {
5148
- @hasMany('post') posts;
5149
- }
5150
- ```
5151
-
5152
- You can avoid passing a string as the first parameter. In that case Ember Data
5153
- will infer the type from the singularized key name.
5154
-
5155
- ```app/models/post.js
5156
- import Model, { hasMany } from '@ember-data/model';
5157
-
5158
- export default class PostModel extends Model {
5159
- @hasMany tags;
5160
- }
5161
- ```
5162
-
5163
- will lookup for a Tag type.
5164
-
5165
- #### Explicit Inverses
5166
-
5167
- Ember Data will do its best to discover which relationships map to
5168
- one another. In the one-to-many code above, for example, Ember Data
5169
- can figure out that changing the `comments` relationship should update
5170
- the `post` relationship on the inverse because post is the only
5171
- relationship to that model.
5172
-
5173
- However, sometimes you may have multiple `belongsTo`/`hasMany` for the
5174
- same type. You can specify which property on the related model is
5175
- the inverse using `hasMany`'s `inverse` option:
5176
-
5177
- ```app/models/comment.js
5178
- import Model, { belongsTo } from '@ember-data/model';
5179
-
5180
- export default class CommentModel extends Model {
5181
- @belongsTo('post') onePost;
5182
- @belongsTo('post') twoPost
5183
- @belongsTo('post') redPost;
5184
- @belongsTo('post') bluePost;
5185
- }
5186
- ```
5187
-
5188
- ```app/models/post.js
5189
- import Model, { hasMany } from '@ember-data/model';
5190
-
5191
- export default class PostModel extends Model {
5192
- @hasMany('comment', {
5193
- inverse: 'redPost'
5194
- })
5195
- comments;
5196
- }
5197
- ```
5198
-
5199
- You can also specify an inverse on a `belongsTo`, which works how
5200
- you'd expect.
5201
-
5202
- #### Sync relationships
5203
-
5204
- Ember Data resolves sync relationships with the related resources
5205
- available in its local store, hence it is expected these resources
5206
- to be loaded before or along-side the primary resource.
5207
-
5208
- ```app/models/post.js
5209
- import Model, { hasMany } from '@ember-data/model';
5210
-
5211
- export default class PostModel extends Model {
5212
- @hasMany('comment', {
5213
- async: false
5214
- })
5215
- comments;
5216
- }
5217
- ```
5218
-
5219
- In contrast to async relationship, accessing a sync relationship
5220
- will always return a [ManyArray](/ember-data/release/classes/ManyArray) instance
5221
- containing the existing local resources. But it will error on access
5222
- when any of the known related resources have not been loaded.
5223
-
5224
- ```
5225
- post.comments.forEach((comment) => {
5226
-
5227
- });
5228
-
5229
- ```
5230
-
5231
- If you are using `links` with sync relationships, you have to use
5232
- `ref.reload` to fetch the resources.
5233
-
5234
- @method hasMany
5235
- @public
5236
- @static
5237
- @for @ember-data/model
5238
- @param {String} type (optional) type of the relationship
5239
- @param {Object} options (optional) a hash of options
5240
- @return {Ember.computed} relationship
5241
- */
5242
- function hasMany(type, options) {
5243
- assert(`Expected hasMany options.async to be a boolean`, options && typeof options.async === 'boolean');
5244
-
5245
- // Metadata about relationships is stored on the meta of
5246
- // the relationship. This is used for introspection and
5247
- // serialization. Note that `key` is populated lazily
5248
- // the first time the CP is called.
5249
- let meta = {
5250
- type: normalizeType(type),
5251
- options,
5252
- isRelationship: true,
5253
- kind: 'hasMany',
5254
- name: 'Has Many',
5255
- key: null
5256
- };
5257
- return computed({
5258
- get(key) {
5259
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5260
- if (['currentState'].indexOf(key) !== -1) {
5261
- throw new Error(`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your hasMany on ${this.constructor.toString()}`);
5262
- }
5263
- }
5264
- if (this.isDestroying || this.isDestroyed) {
5265
- return A();
5266
- }
5267
- return lookupLegacySupport(this).getHasMany(key);
5268
- },
5269
- set(key, records) {
5270
- if (macroCondition(getOwnConfig().env.DEBUG)) {
5271
- if (['currentState'].indexOf(key) !== -1) {
5272
- throw new Error(`'${key}' is a reserved property name on instances of classes extending Model. Please choose a different property name for your hasMany on ${this.constructor.toString()}`);
5273
- }
5274
- }
5275
- const support = lookupLegacySupport(this);
5276
- const manyArray = support.getManyArray(key);
5277
- assert(`You must pass an array of records to set a hasMany relationship`, Array.isArray(records));
5278
- this.store._join(() => {
5279
- manyArray.splice(0, manyArray.length, ...records);
5280
- });
5281
- return support.getHasMany(key);
5282
- }
5283
- }).meta(meta);
5284
- }
5285
- var hasMany$1 = computedMacroWithOptionalParams(hasMany);
5286
- export { Errors as E, LEGACY_SUPPORT as L, Model as M, PromiseBelongsTo as P, RelatedCollection as R, attr$1 as a, belongsTo$1 as b, PromiseManyArray as c, hasMany$1 as h };
4788
+ export { Errors as E, LEGACY_SUPPORT as L, Model as M, PromiseBelongsTo as P, RelatedCollection as R, PromiseManyArray as a, computedMacroWithOptionalParams as c, lookupLegacySupport as l, normalizeModelName as n };