@ember-data/model 4.12.0-beta.0 → 4.12.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +42 -18
- package/addon/-private.js +3 -61
- package/addon/-private.js.map +1 -1
- package/addon/{has-many-a275fe0d.js → has-many-2eb0dc13.js} +340 -1339
- package/addon/has-many-2eb0dc13.js.map +1 -0
- package/addon/index.js +1 -1
- package/addon-main.js +18 -15
- package/blueprints/model/HELP.md +26 -0
- package/blueprints/model/files/__root__/__path__/__name__.js +5 -0
- package/blueprints/model/index.js +150 -0
- package/blueprints/model/native-files/__root__/__path__/__name__.js +5 -0
- package/blueprints/model-test/index.js +33 -0
- package/blueprints/model-test/mocha-files/__root__/__path__/__test__.js +18 -0
- package/blueprints/model-test/mocha-rfc-232-files/__root__/__path__/__test__.js +15 -0
- package/blueprints/model-test/qunit-files/__root__/__path__/__test__.js +14 -0
- package/package.json +32 -26
- package/addon/has-many-a275fe0d.js.map +0 -1
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import { macroCondition,
|
|
2
|
-
import { assert,
|
|
1
|
+
import { macroCondition, getOwnConfig, importSync } from '@embroider/macros';
|
|
2
|
+
import { assert, warn } from '@ember/debug';
|
|
3
3
|
import EmberObject, { computed, get } from '@ember/object';
|
|
4
|
-
import { recordIdentifierFor, storeFor } from '@ember-data/store';
|
|
5
|
-
import {
|
|
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';
|
|
6
6
|
import { dasherize } from '@ember/string';
|
|
7
|
-
import
|
|
7
|
+
import { A } from '@ember/array';
|
|
8
8
|
import { singularize } from 'ember-inflector';
|
|
9
9
|
import { dependentKeyCompat } from '@ember/object/compat';
|
|
10
10
|
import { run } from '@ember/runloop';
|
|
11
11
|
import { cached, tracked } from '@glimmer/tracking';
|
|
12
12
|
import Ember from 'ember';
|
|
13
|
-
import { resolve, all } from 'rsvp';
|
|
14
|
-
import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
15
|
-
import ObjectProxy from '@ember/object/proxy';
|
|
16
13
|
import ArrayProxy from '@ember/array/proxy';
|
|
17
14
|
import { mapBy, not } from '@ember/object/computed';
|
|
15
|
+
import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
16
|
+
import ObjectProxy from '@ember/object/proxy';
|
|
18
17
|
import { cacheFor } from '@ember/object/internals';
|
|
19
18
|
import { addToTransaction, subscribe } from '@ember-data/tracking/-private';
|
|
20
19
|
function isElementDescriptor(args) {
|
|
@@ -103,9 +102,7 @@ function computedMacroWithOptionalParams(fn) {
|
|
|
103
102
|
```
|
|
104
103
|
|
|
105
104
|
```app/transforms/text.js
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
export default class TextTransform extends Transform {
|
|
105
|
+
export default class TextTransform {
|
|
109
106
|
serialize(value, options) {
|
|
110
107
|
if (options.uppercase) {
|
|
111
108
|
return value.toUpperCase();
|
|
@@ -117,6 +114,10 @@ function computedMacroWithOptionalParams(fn) {
|
|
|
117
114
|
deserialize(value) {
|
|
118
115
|
return value;
|
|
119
116
|
}
|
|
117
|
+
|
|
118
|
+
static create() {
|
|
119
|
+
return new this();
|
|
120
|
+
}
|
|
120
121
|
}
|
|
121
122
|
```
|
|
122
123
|
|
|
@@ -142,7 +143,7 @@ function attr(type, options) {
|
|
|
142
143
|
};
|
|
143
144
|
return computed({
|
|
144
145
|
get(key) {
|
|
145
|
-
if (macroCondition(
|
|
146
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
146
147
|
if (['currentState'].indexOf(key) !== -1) {
|
|
147
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()}`);
|
|
148
149
|
}
|
|
@@ -150,20 +151,20 @@ function attr(type, options) {
|
|
|
150
151
|
if (this.isDestroyed || this.isDestroying) {
|
|
151
152
|
return;
|
|
152
153
|
}
|
|
153
|
-
return
|
|
154
|
+
return peekCache(this).getAttr(recordIdentifierFor(this), key);
|
|
154
155
|
},
|
|
155
156
|
set(key, value) {
|
|
156
|
-
if (macroCondition(
|
|
157
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
157
158
|
if (['currentState'].indexOf(key) !== -1) {
|
|
158
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()}`);
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
assert(`Attempted to set '${key}' on the deleted record ${recordIdentifierFor(this)}`, !this.currentState.isDeleted);
|
|
162
163
|
const identifier = recordIdentifierFor(this);
|
|
163
|
-
const
|
|
164
|
-
let currentValue =
|
|
164
|
+
const cache = peekCache(this);
|
|
165
|
+
let currentValue = cache.getAttr(identifier, key);
|
|
165
166
|
if (currentValue !== value) {
|
|
166
|
-
|
|
167
|
+
cache.setAttr(identifier, key, value);
|
|
167
168
|
if (!this.isValid) {
|
|
168
169
|
const {
|
|
169
170
|
errors
|
|
@@ -211,63 +212,12 @@ function _applyDecoratedDescriptor(target, property, decorators, descriptor, con
|
|
|
211
212
|
}
|
|
212
213
|
return desc;
|
|
213
214
|
}
|
|
214
|
-
const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
|
|
215
|
-
function promiseObject(promise) {
|
|
216
|
-
return PromiseObject.create({
|
|
217
|
-
promise: resolve(promise)
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// constructor is accessed in some internals but not including it in the copyright for the deprecation
|
|
222
|
-
const ALLOWABLE_METHODS = ['constructor', 'then', 'catch', 'finally'];
|
|
223
|
-
const ALLOWABLE_PROPS = ['__ec_yieldable__', '__ec_cancel__'];
|
|
224
|
-
const PROXIED_OBJECT_PROPS = ['content', 'isPending', 'isSettled', 'isRejected', 'isFulfilled', 'promise', 'reason'];
|
|
225
|
-
const ProxySymbolString = String(Symbol.for('PROXY_CONTENT'));
|
|
226
|
-
function deprecatedPromiseObject(promise) {
|
|
227
|
-
const promiseObjectProxy = promiseObject(promise);
|
|
228
|
-
if (macroCondition(!isDevelopingApp())) {
|
|
229
|
-
return promiseObjectProxy;
|
|
230
|
-
}
|
|
231
|
-
const handler = {
|
|
232
|
-
get(target, prop, receiver) {
|
|
233
|
-
if (typeof prop === 'symbol') {
|
|
234
|
-
if (String(prop) === ProxySymbolString) {
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
return Reflect.get(target, prop, receiver);
|
|
238
|
-
}
|
|
239
|
-
if (prop === 'constructor') {
|
|
240
|
-
return target.constructor;
|
|
241
|
-
}
|
|
242
|
-
if (ALLOWABLE_PROPS.includes(prop)) {
|
|
243
|
-
return target[prop];
|
|
244
|
-
}
|
|
245
|
-
if (!ALLOWABLE_METHODS.includes(prop)) {
|
|
246
|
-
deprecate(`Accessing ${prop} is deprecated. The return type is being changed from PromiseObjectProxy to a Promise. The only available methods to access on this promise are .then, .catch and .finally`, false, {
|
|
247
|
-
id: 'ember-data:model-save-promise',
|
|
248
|
-
until: '5.0',
|
|
249
|
-
for: '@ember-data/store',
|
|
250
|
-
since: {
|
|
251
|
-
available: '4.4',
|
|
252
|
-
enabled: '4.4'
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
} else {
|
|
256
|
-
return target[prop].bind(target);
|
|
257
|
-
}
|
|
258
|
-
if (PROXIED_OBJECT_PROPS.includes(prop)) {
|
|
259
|
-
return target[prop];
|
|
260
|
-
}
|
|
261
|
-
const value = get(target, prop);
|
|
262
|
-
if (value && typeof value === 'function' && typeof value.bind === 'function') {
|
|
263
|
-
return value.bind(receiver);
|
|
264
|
-
}
|
|
265
|
-
return undefined;
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
return new Proxy(promiseObjectProxy, handler);
|
|
269
|
-
}
|
|
270
215
|
var _dec$1, _dec2, _dec3, _dec4, _class$6, _descriptor$5, _descriptor2$2;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
@module @ember-data/model
|
|
219
|
+
*/
|
|
220
|
+
|
|
271
221
|
// we force the type here to our own construct because mixin and extend patterns
|
|
272
222
|
// lose generic signatures. We also do this because we need to Omit `clear` from
|
|
273
223
|
// the type of ArrayProxy as we override it's signature.
|
|
@@ -632,385 +582,10 @@ let Errors = (_dec$1 = computed(), _dec2 = mapBy('content', 'message'), _dec3 =
|
|
|
632
582
|
writable: true,
|
|
633
583
|
initializer: null
|
|
634
584
|
})), _class$6));
|
|
635
|
-
function iterateData(data, fn) {
|
|
636
|
-
if (Array.isArray(data)) {
|
|
637
|
-
return data.map(fn);
|
|
638
|
-
} else {
|
|
639
|
-
return fn(data);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
function assertIdentifierHasId(identifier) {
|
|
643
|
-
assert(`Attempted to schedule a fetch for a record without an id.`, identifier.id !== null);
|
|
644
|
-
}
|
|
645
|
-
function normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
|
|
646
|
-
let normalizedResponse = serializer ? serializer.normalizeResponse(store, modelClass, payload, id, requestType) : payload;
|
|
647
|
-
validateDocumentStructure(normalizedResponse);
|
|
648
|
-
return normalizedResponse;
|
|
649
|
-
}
|
|
650
|
-
function validateDocumentStructure(doc) {
|
|
651
|
-
if (macroCondition(isDevelopingApp())) {
|
|
652
|
-
let errors = [];
|
|
653
|
-
if (!doc || typeof doc !== 'object') {
|
|
654
|
-
errors.push('Top level of a JSON API document must be an object');
|
|
655
|
-
} else {
|
|
656
|
-
if (!('data' in doc) && !('errors' in doc) && !('meta' in doc)) {
|
|
657
|
-
errors.push('One or more of the following keys must be present: "data", "errors", "meta".');
|
|
658
|
-
} else {
|
|
659
|
-
if ('data' in doc && 'errors' in doc) {
|
|
660
|
-
errors.push('Top level keys "errors" and "data" cannot both be present in a JSON API document');
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
if ('data' in doc) {
|
|
664
|
-
if (!(doc.data === null || Array.isArray(doc.data) || typeof doc.data === 'object')) {
|
|
665
|
-
errors.push('data must be null, an object, or an array');
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
if ('meta' in doc) {
|
|
669
|
-
if (typeof doc.meta !== 'object') {
|
|
670
|
-
errors.push('meta must be an object');
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
if ('errors' in doc) {
|
|
674
|
-
if (!Array.isArray(doc.errors)) {
|
|
675
|
-
errors.push('errors must be an array');
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
if ('links' in doc) {
|
|
679
|
-
if (typeof doc.links !== 'object') {
|
|
680
|
-
errors.push('links must be an object');
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
if ('jsonapi' in doc) {
|
|
684
|
-
if (typeof doc.jsonapi !== 'object') {
|
|
685
|
-
errors.push('jsonapi must be an object');
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
if ('included' in doc) {
|
|
689
|
-
if (typeof doc.included !== 'object') {
|
|
690
|
-
errors.push('included must be an array');
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
assert(`Response must be normalized to a valid JSON API document:\n\t* ${errors.join('\n\t* ')}`, errors.length === 0);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
function _findHasMany(adapter, store, identifier, link, relationship, options) {
|
|
698
|
-
const record = store._instanceCache.getRecord(identifier);
|
|
699
|
-
const snapshot = store._instanceCache.createSnapshot(identifier, options);
|
|
700
|
-
let modelClass = store.modelFor(relationship.type);
|
|
701
|
-
let useLink = !link || typeof link === 'string';
|
|
702
|
-
let relatedLink = useLink ? link : link.href;
|
|
703
|
-
let promise = adapter.findHasMany(store, snapshot, relatedLink, relationship);
|
|
704
|
-
let label = `DS: Handle Adapter#findHasMany of '${identifier.type}' : '${relationship.type}'`;
|
|
705
|
-
promise = guardDestroyedStore(promise, store, label);
|
|
706
|
-
promise = promise.then(adapterPayload => {
|
|
707
|
-
if (!_objectIsAlive(record)) {
|
|
708
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
709
|
-
deprecate(`A Promise for fetching ${relationship.type} did not resolve by the time your model was destroyed. This will error in a future release.`, false, {
|
|
710
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
711
|
-
until: '5.0',
|
|
712
|
-
for: '@ember-data/store',
|
|
713
|
-
since: {
|
|
714
|
-
available: '4.5',
|
|
715
|
-
enabled: '4.5'
|
|
716
|
-
}
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
assert(`You made a 'findHasMany' request for a ${identifier.type}'s '${relationship.key}' relationship, using link '${link}' , but the adapter's response did not have any data`, payloadIsNotBlank(adapterPayload));
|
|
721
|
-
let serializer = store.serializerFor(relationship.type);
|
|
722
|
-
let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findHasMany');
|
|
723
|
-
assert(`fetched the hasMany relationship '${relationship.name}' for ${identifier.type}:${identifier.id} with link '${link}', but no data member is present in the response. If no data exists, the response should set { data: [] }`, 'data' in payload && Array.isArray(payload.data));
|
|
724
|
-
payload = syncRelationshipDataFromLink(store, payload, identifier, relationship);
|
|
725
|
-
return store._push(payload);
|
|
726
|
-
}, null, `DS: Extract payload of '${identifier.type}' : hasMany '${relationship.type}'`);
|
|
727
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
728
|
-
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
729
|
-
}
|
|
730
|
-
return promise;
|
|
731
|
-
}
|
|
732
|
-
function _findBelongsTo(store, identifier, link, relationship, options) {
|
|
733
|
-
const record = store._instanceCache.getRecord(identifier);
|
|
734
|
-
let adapter = store.adapterFor(identifier.type);
|
|
735
|
-
assert(`You tried to load a belongsTo relationship but you have no adapter (for ${identifier.type})`, adapter);
|
|
736
|
-
assert(`You tried to load a belongsTo relationship from a specified 'link' in the original payload but your adapter does not implement 'findBelongsTo'`, typeof adapter.findBelongsTo === 'function');
|
|
737
|
-
let snapshot = store._instanceCache.createSnapshot(identifier, options);
|
|
738
|
-
let modelClass = store.modelFor(relationship.type);
|
|
739
|
-
let useLink = !link || typeof link === 'string';
|
|
740
|
-
let relatedLink = useLink ? link : link.href;
|
|
741
|
-
let promise = adapter.findBelongsTo(store, snapshot, relatedLink, relationship);
|
|
742
|
-
let label = `DS: Handle Adapter#findBelongsTo of ${identifier.type} : ${relationship.type}`;
|
|
743
|
-
promise = guardDestroyedStore(promise, store, label);
|
|
744
|
-
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
745
|
-
promise = promise.then(adapterPayload => {
|
|
746
|
-
if (!_objectIsAlive(record)) {
|
|
747
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
748
|
-
deprecate(`A Promise for fetching ${relationship.type} did not resolve by the time your model was destroyed. This will error in a future release.`, false, {
|
|
749
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
750
|
-
until: '5.0',
|
|
751
|
-
for: '@ember-data/store',
|
|
752
|
-
since: {
|
|
753
|
-
available: '4.5',
|
|
754
|
-
enabled: '4.5'
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
let serializer = store.serializerFor(relationship.type);
|
|
760
|
-
let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findBelongsTo');
|
|
761
|
-
assert(`fetched the belongsTo relationship '${relationship.name}' for ${identifier.type}:${identifier.id} with link '${link}', but no data member is present in the response. If no data exists, the response should set { data: null }`, 'data' in payload && (payload.data === null || typeof payload.data === 'object' && !Array.isArray(payload.data)));
|
|
762
|
-
if (!payload.data && !payload.links && !payload.meta) {
|
|
763
|
-
return null;
|
|
764
|
-
}
|
|
765
|
-
payload = syncRelationshipDataFromLink(store, payload, identifier, relationship);
|
|
766
|
-
return store._push(payload);
|
|
767
|
-
}, null, `DS: Extract payload of ${identifier.type} : ${relationship.type}`);
|
|
768
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
769
|
-
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
770
|
-
}
|
|
771
|
-
return promise;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// sync
|
|
775
|
-
// iterate over records in payload.data
|
|
776
|
-
// for each record
|
|
777
|
-
// assert that record.relationships[inverse] is either undefined (so we can fix it)
|
|
778
|
-
// or provide a data: {id, type} that matches the record that requested it
|
|
779
|
-
// return the relationship data for the parent
|
|
780
|
-
function syncRelationshipDataFromLink(store, payload, parentIdentifier, relationship) {
|
|
781
|
-
// ensure the right hand side (incoming payload) points to the parent record that
|
|
782
|
-
// requested this relationship
|
|
783
|
-
let relationshipData = payload.data ? iterateData(payload.data, (data, index) => {
|
|
784
|
-
const {
|
|
785
|
-
id,
|
|
786
|
-
type
|
|
787
|
-
} = data;
|
|
788
|
-
ensureRelationshipIsSetToParent(data, parentIdentifier, store, relationship, index);
|
|
789
|
-
return {
|
|
790
|
-
id,
|
|
791
|
-
type
|
|
792
|
-
};
|
|
793
|
-
}) : null;
|
|
794
|
-
const relatedDataHash = {};
|
|
795
|
-
if ('meta' in payload) {
|
|
796
|
-
relatedDataHash.meta = payload.meta;
|
|
797
|
-
}
|
|
798
|
-
if ('links' in payload) {
|
|
799
|
-
relatedDataHash.links = payload.links;
|
|
800
|
-
}
|
|
801
|
-
if ('data' in payload) {
|
|
802
|
-
relatedDataHash.data = relationshipData;
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
// now, push the left hand side (the parent record) to ensure things are in sync, since
|
|
806
|
-
// the payload will be pushed with store._push
|
|
807
|
-
const parentPayload = {
|
|
808
|
-
id: parentIdentifier.id,
|
|
809
|
-
type: parentIdentifier.type,
|
|
810
|
-
relationships: {
|
|
811
|
-
[relationship.key]: relatedDataHash
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
if (!Array.isArray(payload.included)) {
|
|
815
|
-
payload.included = [];
|
|
816
|
-
}
|
|
817
|
-
payload.included.push(parentPayload);
|
|
818
|
-
return payload;
|
|
819
|
-
}
|
|
820
|
-
function ensureRelationshipIsSetToParent(payload, parentIdentifier, store, parentRelationship, index) {
|
|
821
|
-
let {
|
|
822
|
-
id,
|
|
823
|
-
type
|
|
824
|
-
} = payload;
|
|
825
|
-
if (!payload.relationships) {
|
|
826
|
-
payload.relationships = {};
|
|
827
|
-
}
|
|
828
|
-
let {
|
|
829
|
-
relationships
|
|
830
|
-
} = payload;
|
|
831
|
-
let inverse = getInverse(store, parentIdentifier, parentRelationship, type);
|
|
832
|
-
if (inverse) {
|
|
833
|
-
let {
|
|
834
|
-
inverseKey,
|
|
835
|
-
kind
|
|
836
|
-
} = inverse;
|
|
837
|
-
let relationshipData = relationships[inverseKey] && relationships[inverseKey].data;
|
|
838
|
-
if (macroCondition(isDevelopingApp())) {
|
|
839
|
-
if (typeof relationshipData !== 'undefined' && !relationshipDataPointsToParent(relationshipData, parentIdentifier)) {
|
|
840
|
-
let inspect = function inspect(thing) {
|
|
841
|
-
return `'${JSON.stringify(thing)}'`;
|
|
842
|
-
};
|
|
843
|
-
let quotedType = inspect(type);
|
|
844
|
-
let quotedInverse = inspect(inverseKey);
|
|
845
|
-
let expected = inspect({
|
|
846
|
-
id: parentIdentifier.id,
|
|
847
|
-
type: parentIdentifier.type
|
|
848
|
-
});
|
|
849
|
-
let expectedModel = `${parentIdentifier.type}:${parentIdentifier.id}`;
|
|
850
|
-
let got = inspect(relationshipData);
|
|
851
|
-
let prefix = typeof index === 'number' ? `data[${index}]` : `data`;
|
|
852
|
-
let path = `${prefix}.relationships.${inverseKey}.data`;
|
|
853
|
-
let other = relationshipData ? `<${relationshipData.type}:${relationshipData.id}>` : null;
|
|
854
|
-
let relationshipFetched = `${expectedModel}.${parentRelationship.kind}("${parentRelationship.name}")`;
|
|
855
|
-
let includedRecord = `<${type}:${id}>`;
|
|
856
|
-
let message = [`Encountered mismatched relationship: Ember Data expected ${path} in the payload from ${relationshipFetched} to include ${expected} but got ${got} instead.\n`, `The ${includedRecord} record loaded at ${prefix} in the payload specified ${other} as its ${quotedInverse}, but should have specified ${expectedModel} (the record the relationship is being loaded from) as its ${quotedInverse} instead.`, `This could mean that the response for ${relationshipFetched} may have accidentally returned ${quotedType} records that aren't related to ${expectedModel} and could be related to a different ${parentIdentifier.type} record instead.`, `Ember Data has corrected the ${includedRecord} record's ${quotedInverse} relationship to ${expectedModel} so that ${relationshipFetched} will include ${includedRecord}.`, `Please update the response from the server or change your serializer to either ensure that the response for only includes ${quotedType} records that specify ${expectedModel} as their ${quotedInverse}, or omit the ${quotedInverse} relationship from the response.`].join('\n');
|
|
857
|
-
assert(message);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
if (kind !== 'hasMany' || typeof relationshipData !== 'undefined') {
|
|
861
|
-
relationships[inverseKey] = relationships[inverseKey] || {};
|
|
862
|
-
relationships[inverseKey].data = fixRelationshipData(relationshipData, kind, parentIdentifier);
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
function metaIsRelationshipDefinition(meta) {
|
|
867
|
-
return typeof meta._inverseKey === 'function';
|
|
868
|
-
}
|
|
869
|
-
function inverseForRelationship(store, identifier, key) {
|
|
870
|
-
const definition = store.getSchemaDefinitionService().relationshipsDefinitionFor(identifier)[key];
|
|
871
|
-
if (!definition) {
|
|
872
|
-
return null;
|
|
873
|
-
}
|
|
874
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE)) {
|
|
875
|
-
if (metaIsRelationshipDefinition(definition)) {
|
|
876
|
-
const modelClass = store.modelFor(identifier.type);
|
|
877
|
-
return definition._inverseKey(store, modelClass);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
assert(`Expected the relationship defintion to specify the inverse type or null.`, definition.options?.inverse === null || typeof definition.options?.inverse === 'string' && definition.options.inverse.length > 0);
|
|
881
|
-
return definition.options.inverse;
|
|
882
|
-
}
|
|
883
|
-
function getInverse(store, parentIdentifier, parentRelationship, type) {
|
|
884
|
-
let {
|
|
885
|
-
name: lhs_relationshipName
|
|
886
|
-
} = parentRelationship;
|
|
887
|
-
let {
|
|
888
|
-
type: parentType
|
|
889
|
-
} = parentIdentifier;
|
|
890
|
-
let inverseKey = inverseForRelationship(store, {
|
|
891
|
-
type: parentType
|
|
892
|
-
}, lhs_relationshipName);
|
|
893
|
-
if (inverseKey) {
|
|
894
|
-
const definition = store.getSchemaDefinitionService().relationshipsDefinitionFor({
|
|
895
|
-
type
|
|
896
|
-
});
|
|
897
|
-
let {
|
|
898
|
-
kind
|
|
899
|
-
} = definition[inverseKey];
|
|
900
|
-
return {
|
|
901
|
-
inverseKey,
|
|
902
|
-
kind
|
|
903
|
-
};
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
function relationshipDataPointsToParent(relationshipData, identifier) {
|
|
907
|
-
if (relationshipData === null) {
|
|
908
|
-
return false;
|
|
909
|
-
}
|
|
910
|
-
if (Array.isArray(relationshipData)) {
|
|
911
|
-
if (relationshipData.length === 0) {
|
|
912
|
-
return false;
|
|
913
|
-
}
|
|
914
|
-
for (let i = 0; i < relationshipData.length; i++) {
|
|
915
|
-
let entry = relationshipData[i];
|
|
916
|
-
if (validateRelationshipEntry(entry, identifier)) {
|
|
917
|
-
return true;
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
} else {
|
|
921
|
-
return validateRelationshipEntry(relationshipData, identifier);
|
|
922
|
-
}
|
|
923
|
-
return false;
|
|
924
|
-
}
|
|
925
|
-
function fixRelationshipData(relationshipData, relationshipKind, {
|
|
926
|
-
id,
|
|
927
|
-
type
|
|
928
|
-
}) {
|
|
929
|
-
let parentRelationshipData = {
|
|
930
|
-
id,
|
|
931
|
-
type
|
|
932
|
-
};
|
|
933
|
-
let payload;
|
|
934
|
-
if (relationshipKind === 'hasMany') {
|
|
935
|
-
payload = relationshipData || [];
|
|
936
|
-
if (relationshipData) {
|
|
937
|
-
// these arrays could be massive so this is better than filter
|
|
938
|
-
// Note: this is potentially problematic if type/id are not in the
|
|
939
|
-
// same state of normalization.
|
|
940
|
-
let found = relationshipData.find(v => {
|
|
941
|
-
return v.type === parentRelationshipData.type && v.id === parentRelationshipData.id;
|
|
942
|
-
});
|
|
943
|
-
if (!found) {
|
|
944
|
-
payload.push(parentRelationshipData);
|
|
945
|
-
}
|
|
946
|
-
} else {
|
|
947
|
-
payload.push(parentRelationshipData);
|
|
948
|
-
}
|
|
949
|
-
} else {
|
|
950
|
-
payload = relationshipData || {};
|
|
951
|
-
Object.assign(payload, parentRelationshipData);
|
|
952
|
-
}
|
|
953
|
-
return payload;
|
|
954
|
-
}
|
|
955
|
-
function validateRelationshipEntry({
|
|
956
|
-
id
|
|
957
|
-
}, {
|
|
958
|
-
id: parentModelID
|
|
959
|
-
}) {
|
|
960
|
-
return id && id.toString() === parentModelID;
|
|
961
|
-
}
|
|
962
|
-
function _bind(fn, ...args) {
|
|
963
|
-
return function () {
|
|
964
|
-
return fn.apply(undefined, args);
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
function _guard(promise, test) {
|
|
968
|
-
let guarded = promise.finally(() => {
|
|
969
|
-
if (!test()) {
|
|
970
|
-
guarded._subscribers.length = 0;
|
|
971
|
-
}
|
|
972
|
-
});
|
|
973
|
-
return guarded;
|
|
974
|
-
}
|
|
975
|
-
function _objectIsAlive(object) {
|
|
976
|
-
return !(object.isDestroyed || object.isDestroying);
|
|
977
|
-
}
|
|
978
|
-
function payloadIsNotBlank(adapterPayload) {
|
|
979
|
-
if (Array.isArray(adapterPayload)) {
|
|
980
|
-
return true;
|
|
981
|
-
} else {
|
|
982
|
-
return Object.keys(adapterPayload || {}).length;
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
function guardDestroyedStore(promise, store, label) {
|
|
986
|
-
let token;
|
|
987
|
-
if (macroCondition(isDevelopingApp())) {
|
|
988
|
-
token = store._trackAsyncRequestStart(label);
|
|
989
|
-
}
|
|
990
|
-
let wrapperPromise = resolve(promise, label).then(_v => {
|
|
991
|
-
if (!_objectIsAlive(store)) {
|
|
992
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
993
|
-
deprecate(`A Promise did not resolve by the time the store was destroyed. This will error in a future release.`, false, {
|
|
994
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
995
|
-
until: '5.0',
|
|
996
|
-
for: '@ember-data/store',
|
|
997
|
-
since: {
|
|
998
|
-
available: '4.5',
|
|
999
|
-
enabled: '4.5'
|
|
1000
|
-
}
|
|
1001
|
-
});
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
return promise;
|
|
1005
|
-
});
|
|
1006
|
-
return _guard(wrapperPromise, () => {
|
|
1007
|
-
if (macroCondition(isDevelopingApp())) {
|
|
1008
|
-
store._trackAsyncRequestEnd(token);
|
|
1009
|
-
}
|
|
1010
|
-
return _objectIsAlive(store);
|
|
1011
|
-
});
|
|
1012
|
-
}
|
|
1013
585
|
|
|
586
|
+
/**
|
|
587
|
+
@module @ember-data/store
|
|
588
|
+
*/
|
|
1014
589
|
/**
|
|
1015
590
|
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
1016
591
|
relationship.
|
|
@@ -1118,7 +693,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1118
693
|
switch (prop) {
|
|
1119
694
|
case 'length 0':
|
|
1120
695
|
{
|
|
1121
|
-
this._manager.
|
|
696
|
+
this._manager.mutate({
|
|
1122
697
|
op: 'replaceRelatedRecords',
|
|
1123
698
|
record: this.identifier,
|
|
1124
699
|
field: this.key,
|
|
@@ -1129,7 +704,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1129
704
|
case 'replace cell':
|
|
1130
705
|
{
|
|
1131
706
|
const [index, prior, value] = args;
|
|
1132
|
-
this._manager.
|
|
707
|
+
this._manager.mutate({
|
|
1133
708
|
op: 'replaceRelatedRecord',
|
|
1134
709
|
record: this.identifier,
|
|
1135
710
|
field: this.key,
|
|
@@ -1140,7 +715,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1140
715
|
break;
|
|
1141
716
|
}
|
|
1142
717
|
case 'push':
|
|
1143
|
-
this._manager.
|
|
718
|
+
this._manager.mutate({
|
|
1144
719
|
op: 'addToRelatedRecords',
|
|
1145
720
|
record: this.identifier,
|
|
1146
721
|
field: this.key,
|
|
@@ -1149,7 +724,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1149
724
|
break;
|
|
1150
725
|
case 'pop':
|
|
1151
726
|
if (result) {
|
|
1152
|
-
this._manager.
|
|
727
|
+
this._manager.mutate({
|
|
1153
728
|
op: 'removeFromRelatedRecords',
|
|
1154
729
|
record: this.identifier,
|
|
1155
730
|
field: this.key,
|
|
@@ -1158,7 +733,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1158
733
|
}
|
|
1159
734
|
break;
|
|
1160
735
|
case 'unshift':
|
|
1161
|
-
this._manager.
|
|
736
|
+
this._manager.mutate({
|
|
1162
737
|
op: 'addToRelatedRecords',
|
|
1163
738
|
record: this.identifier,
|
|
1164
739
|
field: this.key,
|
|
@@ -1168,7 +743,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1168
743
|
break;
|
|
1169
744
|
case 'shift':
|
|
1170
745
|
if (result) {
|
|
1171
|
-
this._manager.
|
|
746
|
+
this._manager.mutate({
|
|
1172
747
|
op: 'removeFromRelatedRecords',
|
|
1173
748
|
record: this.identifier,
|
|
1174
749
|
field: this.key,
|
|
@@ -1178,7 +753,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1178
753
|
}
|
|
1179
754
|
break;
|
|
1180
755
|
case 'sort':
|
|
1181
|
-
this._manager.
|
|
756
|
+
this._manager.mutate({
|
|
1182
757
|
op: 'sortRelatedRecords',
|
|
1183
758
|
record: this.identifier,
|
|
1184
759
|
field: this.key,
|
|
@@ -1190,7 +765,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1190
765
|
const [start, removeCount, ...adds] = args;
|
|
1191
766
|
// detect a full replace
|
|
1192
767
|
if (removeCount > 0 && adds.length === this[SOURCE].length) {
|
|
1193
|
-
this._manager.
|
|
768
|
+
this._manager.mutate({
|
|
1194
769
|
op: 'replaceRelatedRecords',
|
|
1195
770
|
record: this.identifier,
|
|
1196
771
|
field: this.key,
|
|
@@ -1199,7 +774,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1199
774
|
return;
|
|
1200
775
|
}
|
|
1201
776
|
if (removeCount > 0) {
|
|
1202
|
-
this._manager.
|
|
777
|
+
this._manager.mutate({
|
|
1203
778
|
op: 'removeFromRelatedRecords',
|
|
1204
779
|
record: this.identifier,
|
|
1205
780
|
field: this.key,
|
|
@@ -1208,7 +783,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1208
783
|
});
|
|
1209
784
|
}
|
|
1210
785
|
if (adds?.length) {
|
|
1211
|
-
this._manager.
|
|
786
|
+
this._manager.mutate({
|
|
1212
787
|
op: 'addToRelatedRecords',
|
|
1213
788
|
record: this.identifier,
|
|
1214
789
|
field: this.key,
|
|
@@ -1224,8 +799,9 @@ class RelatedCollection extends RecordArray {
|
|
|
1224
799
|
}
|
|
1225
800
|
notify() {
|
|
1226
801
|
const tag = this[IDENTIFIER_ARRAY_TAG];
|
|
1227
|
-
tag.ref = null;
|
|
1228
802
|
tag.shouldReset = true;
|
|
803
|
+
// @ts-expect-error
|
|
804
|
+
notifyArray(this);
|
|
1229
805
|
}
|
|
1230
806
|
|
|
1231
807
|
/**
|
|
@@ -1277,6 +853,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1277
853
|
const {
|
|
1278
854
|
store
|
|
1279
855
|
} = this;
|
|
856
|
+
assert(`Expected modelName to be set`, this.modelName);
|
|
1280
857
|
const record = store.createRecord(this.modelName, hash);
|
|
1281
858
|
this.push(record);
|
|
1282
859
|
return record;
|
|
@@ -1285,7 +862,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1285
862
|
RelatedCollection.prototype.isAsync = false;
|
|
1286
863
|
RelatedCollection.prototype.isPolymorphic = false;
|
|
1287
864
|
RelatedCollection.prototype.identifier = null;
|
|
1288
|
-
RelatedCollection.prototype.
|
|
865
|
+
RelatedCollection.prototype.cache = null;
|
|
1289
866
|
RelatedCollection.prototype._inverseIsAsync = false;
|
|
1290
867
|
RelatedCollection.prototype.key = '';
|
|
1291
868
|
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
@@ -1303,30 +880,14 @@ function extractIdentifiersFromRecords(records) {
|
|
|
1303
880
|
return records.map(extractIdentifierFromRecord$1);
|
|
1304
881
|
}
|
|
1305
882
|
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
1306
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
1307
|
-
if (isPromiseRecord$1(recordOrPromiseRecord)) {
|
|
1308
|
-
let content = recordOrPromiseRecord.content;
|
|
1309
|
-
assert('You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo relationship.', content !== undefined && content !== null);
|
|
1310
|
-
deprecate(`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`, false, {
|
|
1311
|
-
id: 'ember-data:deprecate-promise-proxies',
|
|
1312
|
-
until: '5.0',
|
|
1313
|
-
since: {
|
|
1314
|
-
enabled: '4.7',
|
|
1315
|
-
available: '4.7'
|
|
1316
|
-
},
|
|
1317
|
-
for: 'ember-data'
|
|
1318
|
-
});
|
|
1319
|
-
assertRecordPassedToHasMany(content);
|
|
1320
|
-
return recordIdentifierFor$1(content);
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1323
883
|
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
1324
884
|
return recordIdentifierFor$1(recordOrPromiseRecord);
|
|
1325
885
|
}
|
|
1326
|
-
|
|
1327
|
-
return !!record.then;
|
|
1328
|
-
}
|
|
886
|
+
const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
|
|
1329
887
|
var _dec, _class$5;
|
|
888
|
+
|
|
889
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
890
|
+
|
|
1330
891
|
const Extended = PromiseObject;
|
|
1331
892
|
|
|
1332
893
|
/**
|
|
@@ -1373,9 +934,26 @@ let PromiseBelongsTo = (_dec = computed(), (_class$5 = class PromiseBelongsTo ex
|
|
|
1373
934
|
}
|
|
1374
935
|
}, (_applyDecoratedDescriptor(_class$5.prototype, "id", [cached], Object.getOwnPropertyDescriptor(_class$5.prototype, "id"), _class$5.prototype), _applyDecoratedDescriptor(_class$5.prototype, "meta", [_dec], Object.getOwnPropertyDescriptor(_class$5.prototype, "meta"), _class$5.prototype)), _class$5));
|
|
1375
936
|
var _class$4, _descriptor$4, _descriptor2$1, _descriptor3, _descriptor4, _descriptor5;
|
|
1376
|
-
|
|
1377
|
-
|
|
937
|
+
/**
|
|
938
|
+
@module @ember-data/model
|
|
939
|
+
*/
|
|
940
|
+
/**
|
|
941
|
+
This class is returned as the result of accessing an async hasMany relationship
|
|
942
|
+
on an instance of a Model extending from `@ember-data/model`.
|
|
943
|
+
|
|
944
|
+
A PromiseManyArray is an iterable proxy that allows templates to consume related
|
|
945
|
+
ManyArrays and update once their contents are no longer pending.
|
|
1378
946
|
|
|
947
|
+
In your JS code you should resolve the promise first.
|
|
948
|
+
|
|
949
|
+
```js
|
|
950
|
+
const comments = await post.comments;
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
@class PromiseManyArray
|
|
954
|
+
@public
|
|
955
|
+
*/
|
|
956
|
+
let PromiseManyArray = (_class$4 = class PromiseManyArray {
|
|
1379
957
|
constructor(promise, content) {
|
|
1380
958
|
//---- Methods/Properties on ArrayProxy that we will keep as our API
|
|
1381
959
|
_initializerDefineProperty(this, "content", _descriptor$4, this);
|
|
@@ -1410,26 +988,7 @@ let PromiseManyArray = (_class$4 = class PromiseManyArray {
|
|
|
1410
988
|
_initializerDefineProperty(this, "isSettled", _descriptor5, this);
|
|
1411
989
|
this._update(promise, content);
|
|
1412
990
|
this.isDestroyed = false;
|
|
1413
|
-
|
|
1414
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_A_USAGE)) {
|
|
1415
|
-
const meta = Ember.meta(this);
|
|
1416
|
-
meta.hasMixin = mixin => {
|
|
1417
|
-
deprecate(`Do not use A() on an EmberData PromiseManyArray`, false, {
|
|
1418
|
-
id: 'ember-data:no-a-with-array-like',
|
|
1419
|
-
until: '5.0',
|
|
1420
|
-
since: {
|
|
1421
|
-
enabled: '4.7',
|
|
1422
|
-
available: '4.7'
|
|
1423
|
-
},
|
|
1424
|
-
for: 'ember-data'
|
|
1425
|
-
});
|
|
1426
|
-
// @ts-expect-error ArrayMixin is more than a type
|
|
1427
|
-
if (mixin === NativeArray || mixin === ArrayMixin) {
|
|
1428
|
-
return true;
|
|
1429
|
-
}
|
|
1430
|
-
return false;
|
|
1431
|
-
};
|
|
1432
|
-
} else if (macroCondition(isDevelopingApp())) {
|
|
991
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
1433
992
|
const meta = Ember.meta(this);
|
|
1434
993
|
meta.hasMixin = mixin => {
|
|
1435
994
|
assert(`Do not use A() on an EmberData PromiseManyArray`);
|
|
@@ -1527,7 +1086,6 @@ let PromiseManyArray = (_class$4 = class PromiseManyArray {
|
|
|
1527
1086
|
//---- Methods on EmberObject that we should keep
|
|
1528
1087
|
|
|
1529
1088
|
destroy() {
|
|
1530
|
-
this.isDestroying = true;
|
|
1531
1089
|
this.isDestroyed = true;
|
|
1532
1090
|
this.content = null;
|
|
1533
1091
|
this.promise = null;
|
|
@@ -1603,55 +1161,12 @@ let PromiseManyArray = (_class$4 = class PromiseManyArray {
|
|
|
1603
1161
|
return false;
|
|
1604
1162
|
}
|
|
1605
1163
|
}), _applyDecoratedDescriptor(_class$4.prototype, "links", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class$4.prototype, "links"), _class$4.prototype), _applyDecoratedDescriptor(_class$4.prototype, "meta", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class$4.prototype, "meta"), _class$4.prototype)), _class$4);
|
|
1606
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_MANY_ARRAY_BEHAVIORS)) {
|
|
1607
|
-
PromiseManyArray.prototype.createRecord = function createRecord(...args) {
|
|
1608
|
-
deprecate(`The createRecord method on ember-data's PromiseManyArray is deprecated. await the promise and work with the ManyArray directly.`, false, {
|
|
1609
|
-
id: 'ember-data:deprecate-promise-many-array-behaviors',
|
|
1610
|
-
until: '5.0',
|
|
1611
|
-
since: {
|
|
1612
|
-
enabled: '4.7',
|
|
1613
|
-
available: '4.7'
|
|
1614
|
-
},
|
|
1615
|
-
for: 'ember-data'
|
|
1616
|
-
});
|
|
1617
|
-
assert('You are trying to createRecord on an async manyArray before it has been created', this.content);
|
|
1618
|
-
return this.content.createRecord(...args);
|
|
1619
|
-
};
|
|
1620
|
-
Object.defineProperty(PromiseManyArray.prototype, 'firstObject', {
|
|
1621
|
-
get() {
|
|
1622
|
-
deprecate(`The firstObject property on ember-data's PromiseManyArray is deprecated. await the promise and work with the ManyArray directly.`, false, {
|
|
1623
|
-
id: 'ember-data:deprecate-promise-many-array-behaviors',
|
|
1624
|
-
until: '5.0',
|
|
1625
|
-
since: {
|
|
1626
|
-
enabled: '4.7',
|
|
1627
|
-
available: '4.7'
|
|
1628
|
-
},
|
|
1629
|
-
for: 'ember-data'
|
|
1630
|
-
});
|
|
1631
|
-
return this.content ? this.content.firstObject : undefined;
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1634
|
-
Object.defineProperty(PromiseManyArray.prototype, 'lastObject', {
|
|
1635
|
-
get() {
|
|
1636
|
-
deprecate(`The lastObject property on ember-data's PromiseManyArray is deprecated. await the promise and work with the ManyArray directly.`, false, {
|
|
1637
|
-
id: 'ember-data:deprecate-promise-many-array-behaviors',
|
|
1638
|
-
until: '5.0',
|
|
1639
|
-
since: {
|
|
1640
|
-
enabled: '4.7',
|
|
1641
|
-
available: '4.7'
|
|
1642
|
-
},
|
|
1643
|
-
for: 'ember-data'
|
|
1644
|
-
});
|
|
1645
|
-
return this.content ? this.content.lastObject : undefined;
|
|
1646
|
-
}
|
|
1647
|
-
});
|
|
1648
|
-
}
|
|
1649
1164
|
function tapPromise(proxy, promise) {
|
|
1650
1165
|
proxy.isPending = true;
|
|
1651
1166
|
proxy.isSettled = false;
|
|
1652
1167
|
proxy.isFulfilled = false;
|
|
1653
1168
|
proxy.isRejected = false;
|
|
1654
|
-
return resolve(promise).then(content => {
|
|
1169
|
+
return Promise.resolve(promise).then(content => {
|
|
1655
1170
|
proxy.isPending = false;
|
|
1656
1171
|
proxy.isFulfilled = true;
|
|
1657
1172
|
proxy.isSettled = true;
|
|
@@ -1665,41 +1180,6 @@ function tapPromise(proxy, promise) {
|
|
|
1665
1180
|
throw error;
|
|
1666
1181
|
});
|
|
1667
1182
|
}
|
|
1668
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_MANY_ARRAY_BEHAVIORS)) {
|
|
1669
|
-
const EmberObjectMethods = ['addObserver', 'cacheFor', 'decrementProperty', 'get', 'getProperties', 'incrementProperty', 'notifyPropertyChange', 'removeObserver', 'set', 'setProperties', 'toggleProperty'];
|
|
1670
|
-
EmberObjectMethods.forEach(method => {
|
|
1671
|
-
PromiseManyArray.prototype[method] = function delegatedMethod(...args) {
|
|
1672
|
-
deprecate(`The ${method} method on ember-data's PromiseManyArray is deprecated. await the promise and work with the ManyArray directly.`, false, {
|
|
1673
|
-
id: 'ember-data:deprecate-promise-many-array-behaviors',
|
|
1674
|
-
until: '5.0',
|
|
1675
|
-
since: {
|
|
1676
|
-
enabled: '4.7',
|
|
1677
|
-
available: '4.7'
|
|
1678
|
-
},
|
|
1679
|
-
for: 'ember-data'
|
|
1680
|
-
});
|
|
1681
|
-
return Ember[method](this, ...args);
|
|
1682
|
-
};
|
|
1683
|
-
});
|
|
1684
|
-
const InheritedProxyMethods = ['addArrayObserver', 'addObject', 'addObjects', 'any', 'arrayContentDidChange', 'arrayContentWillChange', 'clear', 'compact', 'every', 'filter', 'filterBy', 'find', 'findBy', 'getEach', 'includes', 'indexOf', 'insertAt', 'invoke', 'isAny', 'isEvery', 'lastIndexOf', 'map', 'mapBy',
|
|
1685
|
-
// TODO update RFC to note objectAt was deprecated (forEach was left for iteration)
|
|
1686
|
-
'objectAt', 'objectsAt', 'popObject', 'pushObject', 'pushObjects', 'reduce', 'reject', 'rejectBy', 'removeArrayObserver', 'removeAt', 'removeObject', 'removeObjects', 'replace', 'reverseObjects', 'setEach', 'setObjects', 'shiftObject', 'slice', 'sortBy', 'toArray', 'uniq', 'uniqBy', 'unshiftObject', 'unshiftObjects', 'without'];
|
|
1687
|
-
InheritedProxyMethods.forEach(method => {
|
|
1688
|
-
PromiseManyArray.prototype[method] = function proxiedMethod(...args) {
|
|
1689
|
-
deprecate(`The ${method} method on ember-data's PromiseManyArray is deprecated. await the promise and work with the ManyArray directly.`, false, {
|
|
1690
|
-
id: 'ember-data:deprecate-promise-many-array-behaviors',
|
|
1691
|
-
until: '5.0',
|
|
1692
|
-
since: {
|
|
1693
|
-
enabled: '4.7',
|
|
1694
|
-
available: '4.7'
|
|
1695
|
-
},
|
|
1696
|
-
for: 'ember-data'
|
|
1697
|
-
});
|
|
1698
|
-
assert(`Cannot call ${method} before content is assigned.`, this.content);
|
|
1699
|
-
return this.content[method](...args);
|
|
1700
|
-
};
|
|
1701
|
-
});
|
|
1702
|
-
}
|
|
1703
1183
|
|
|
1704
1184
|
/*
|
|
1705
1185
|
Assert that `addedRecord` has a valid type so it can be added to the
|
|
@@ -1714,40 +1194,14 @@ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_MANY_ARRAY_BEHA
|
|
|
1714
1194
|
`record.relationshipFor(key)`.
|
|
1715
1195
|
*/
|
|
1716
1196
|
let assertPolymorphicType;
|
|
1717
|
-
if (macroCondition(
|
|
1718
|
-
let checkPolymorphic = function checkPolymorphic(modelClass, addedModelClass) {
|
|
1719
|
-
if (modelClass.__isMixin) {
|
|
1720
|
-
return modelClass.__mixin.detect(addedModelClass.PrototypeMixin) ||
|
|
1721
|
-
// handle native class extension e.g. `class Post extends Model.extend(Commentable) {}`
|
|
1722
|
-
modelClass.__mixin.detect(Object.getPrototypeOf(addedModelClass).PrototypeMixin);
|
|
1723
|
-
}
|
|
1724
|
-
return addedModelClass.prototype instanceof modelClass || modelClass.detect(addedModelClass);
|
|
1725
|
-
};
|
|
1197
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
1726
1198
|
assertPolymorphicType = function assertPolymorphicType(parentIdentifier, parentDefinition, addedIdentifier, store) {
|
|
1727
|
-
let asserted = false;
|
|
1728
1199
|
if (parentDefinition.inverseIsImplicit) {
|
|
1729
1200
|
return;
|
|
1730
1201
|
}
|
|
1731
1202
|
if (parentDefinition.isPolymorphic) {
|
|
1732
1203
|
let meta = store.getSchemaDefinitionService().relationshipsDefinitionFor(addedIdentifier)[parentDefinition.inverseKey];
|
|
1733
|
-
|
|
1734
|
-
asserted = true;
|
|
1735
|
-
assert(`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. The definition should specify 'as: "${parentDefinition.type}"' in options.`, meta.options.as === parentDefinition.type);
|
|
1736
|
-
}
|
|
1737
|
-
}
|
|
1738
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_EXPLICIT_POLYMORPHISM)) {
|
|
1739
|
-
if (!asserted) {
|
|
1740
|
-
store = store._store ? store._store : store; // allow usage with storeWrapper
|
|
1741
|
-
let addedModelName = addedIdentifier.type;
|
|
1742
|
-
let parentModelName = parentIdentifier.type;
|
|
1743
|
-
let key = parentDefinition.key;
|
|
1744
|
-
let relationshipModelName = parentDefinition.type;
|
|
1745
|
-
let relationshipClass = store.modelFor(relationshipModelName);
|
|
1746
|
-
let addedClass = store.modelFor(addedModelName);
|
|
1747
|
-
let assertionMessage = `The '${addedModelName}' type does not implement '${relationshipModelName}' and thus cannot be assigned to the '${key}' relationship in '${parentModelName}'. Make it a descendant of '${relationshipModelName}' or use a mixin of the same name.`;
|
|
1748
|
-
let isPolymorphic = checkPolymorphic(relationshipClass, addedClass);
|
|
1749
|
-
assert(assertionMessage, isPolymorphic);
|
|
1750
|
-
}
|
|
1204
|
+
assert(`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. The definition should specify 'as: "${parentDefinition.type}"' in options.`, meta?.options.as === parentDefinition.type);
|
|
1751
1205
|
}
|
|
1752
1206
|
};
|
|
1753
1207
|
}
|
|
@@ -1966,7 +1420,8 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1966
1420
|
}
|
|
1967
1421
|
_resource() {
|
|
1968
1422
|
this._ref; // subscribe
|
|
1969
|
-
|
|
1423
|
+
const cache = this.store.cache;
|
|
1424
|
+
return cache.getRelationship(this.___identifier, this.key);
|
|
1970
1425
|
}
|
|
1971
1426
|
|
|
1972
1427
|
/**
|
|
@@ -2049,29 +1504,13 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
2049
1504
|
```
|
|
2050
1505
|
@method push
|
|
2051
1506
|
@public
|
|
2052
|
-
@param {Object
|
|
1507
|
+
@param {Object} object a JSONAPI document object describing the new value of this relationship.
|
|
2053
1508
|
@return {Promise<record>} A promise that resolves with the new value in this belongs-to relationship.
|
|
2054
1509
|
*/
|
|
2055
|
-
|
|
1510
|
+
push(data) {
|
|
2056
1511
|
let jsonApiDoc = data;
|
|
2057
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
2058
|
-
if (data.then) {
|
|
2059
|
-
jsonApiDoc = await resolve(data);
|
|
2060
|
-
if (jsonApiDoc !== data) {
|
|
2061
|
-
deprecate(`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`, false, {
|
|
2062
|
-
id: 'ember-data:deprecate-promise-proxies',
|
|
2063
|
-
until: '5.0',
|
|
2064
|
-
since: {
|
|
2065
|
-
enabled: '4.7',
|
|
2066
|
-
available: '4.7'
|
|
2067
|
-
},
|
|
2068
|
-
for: 'ember-data'
|
|
2069
|
-
});
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
1512
|
let record = this.store.push(jsonApiDoc);
|
|
2074
|
-
if (macroCondition(
|
|
1513
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
2075
1514
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
2076
1515
|
assertPolymorphicType(this.belongsToRelationship.identifier, this.belongsToRelationship.definition, recordIdentifierFor$1(record), this.store);
|
|
2077
1516
|
}
|
|
@@ -2086,7 +1525,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
2086
1525
|
value: recordIdentifierFor$1(record)
|
|
2087
1526
|
});
|
|
2088
1527
|
});
|
|
2089
|
-
return record;
|
|
1528
|
+
return Promise.resolve(record);
|
|
2090
1529
|
}
|
|
2091
1530
|
|
|
2092
1531
|
/**
|
|
@@ -2331,7 +1770,8 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2331
1770
|
return [];
|
|
2332
1771
|
}
|
|
2333
1772
|
_resource() {
|
|
2334
|
-
|
|
1773
|
+
const cache = this.store.cache;
|
|
1774
|
+
return cache.getRelationship(this.___identifier, this.key);
|
|
2335
1775
|
}
|
|
2336
1776
|
|
|
2337
1777
|
/**
|
|
@@ -2546,22 +1986,6 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2546
1986
|
*/
|
|
2547
1987
|
async push(objectOrPromise) {
|
|
2548
1988
|
let payload = objectOrPromise;
|
|
2549
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
2550
|
-
if (objectOrPromise.then) {
|
|
2551
|
-
payload = await resolve(objectOrPromise);
|
|
2552
|
-
if (payload !== objectOrPromise) {
|
|
2553
|
-
deprecate(`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`, false, {
|
|
2554
|
-
id: 'ember-data:deprecate-promise-proxies',
|
|
2555
|
-
until: '5.0',
|
|
2556
|
-
since: {
|
|
2557
|
-
enabled: '4.7',
|
|
2558
|
-
available: '4.7'
|
|
2559
|
-
},
|
|
2560
|
-
for: 'ember-data'
|
|
2561
|
-
});
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
}
|
|
2565
1989
|
let array;
|
|
2566
1990
|
if (!Array.isArray(payload) && typeof payload === 'object' && Array.isArray(payload.data)) {
|
|
2567
1991
|
array = payload.data;
|
|
@@ -2581,7 +2005,7 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2581
2005
|
data: obj
|
|
2582
2006
|
});
|
|
2583
2007
|
}
|
|
2584
|
-
if (macroCondition(
|
|
2008
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
2585
2009
|
let relationshipMeta = this.hasManyRelationship.definition;
|
|
2586
2010
|
let identifier = this.hasManyRelationship.identifier;
|
|
2587
2011
|
|
|
@@ -2774,9 +2198,9 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2774
2198
|
class LegacySupport {
|
|
2775
2199
|
constructor(record) {
|
|
2776
2200
|
this.record = record;
|
|
2777
|
-
this.store = storeFor
|
|
2201
|
+
this.store = storeFor(record);
|
|
2778
2202
|
this.identifier = recordIdentifierFor$1(record);
|
|
2779
|
-
this.
|
|
2203
|
+
this.cache = peekCache(record);
|
|
2780
2204
|
this._manyArrayCache = Object.create(null);
|
|
2781
2205
|
this._relationshipPromisesCache = Object.create(null);
|
|
2782
2206
|
this._relationshipProxyCache = Object.create(null);
|
|
@@ -2799,8 +2223,8 @@ class LegacySupport {
|
|
|
2799
2223
|
currentState.length = 0;
|
|
2800
2224
|
fastPush(currentState, identifiers);
|
|
2801
2225
|
}
|
|
2802
|
-
|
|
2803
|
-
this.
|
|
2226
|
+
mutate(mutation) {
|
|
2227
|
+
this.cache.mutate(mutation);
|
|
2804
2228
|
}
|
|
2805
2229
|
_findBelongsTo(key, resource, relationship, options) {
|
|
2806
2230
|
// TODO @runspired follow up if parent isNew then we should not be attempting load here
|
|
@@ -2815,7 +2239,7 @@ class LegacySupport {
|
|
|
2815
2239
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
2816
2240
|
const relationship = graphFor(this.store).get(this.identifier, key);
|
|
2817
2241
|
assert(`Expected ${key} to be a belongs-to relationship`, isBelongsTo(relationship));
|
|
2818
|
-
let resource = this.
|
|
2242
|
+
let resource = this.cache.getRelationship(this.identifier, key);
|
|
2819
2243
|
relationship.state.hasFailedLoadAttempt = false;
|
|
2820
2244
|
relationship.state.shouldForceReload = true;
|
|
2821
2245
|
let promise = this._findBelongsTo(key, resource, relationship, options);
|
|
@@ -2829,9 +2253,9 @@ class LegacySupport {
|
|
|
2829
2253
|
getBelongsTo(key, options) {
|
|
2830
2254
|
const {
|
|
2831
2255
|
identifier,
|
|
2832
|
-
|
|
2256
|
+
cache
|
|
2833
2257
|
} = this;
|
|
2834
|
-
let resource =
|
|
2258
|
+
let resource = cache.getRelationship(this.identifier, key);
|
|
2835
2259
|
let relatedIdentifier = resource && resource.data ? resource.data : null;
|
|
2836
2260
|
assert(`Expected a stable identifier`, !relatedIdentifier || isStableIdentifier(relatedIdentifier));
|
|
2837
2261
|
const store = this.store;
|
|
@@ -2867,7 +2291,7 @@ class LegacySupport {
|
|
|
2867
2291
|
}
|
|
2868
2292
|
}
|
|
2869
2293
|
setDirtyBelongsTo(key, value) {
|
|
2870
|
-
return this.
|
|
2294
|
+
return this.cache.mutate({
|
|
2871
2295
|
op: 'replaceRelatedRecord',
|
|
2872
2296
|
record: this.identifier,
|
|
2873
2297
|
field: key,
|
|
@@ -2877,7 +2301,7 @@ class LegacySupport {
|
|
|
2877
2301
|
true);
|
|
2878
2302
|
}
|
|
2879
2303
|
_getCurrentState(identifier, field) {
|
|
2880
|
-
let jsonApi = this.
|
|
2304
|
+
let jsonApi = this.cache.getRelationship(identifier, field);
|
|
2881
2305
|
const cache = this.store._instanceCache;
|
|
2882
2306
|
let identifiers = [];
|
|
2883
2307
|
if (jsonApi.data) {
|
|
@@ -2892,7 +2316,7 @@ class LegacySupport {
|
|
|
2892
2316
|
return [identifiers, jsonApi];
|
|
2893
2317
|
}
|
|
2894
2318
|
getManyArray(key, definition) {
|
|
2895
|
-
if (
|
|
2319
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2896
2320
|
let manyArray = this._manyArrayCache[key];
|
|
2897
2321
|
if (!definition) {
|
|
2898
2322
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
@@ -2904,7 +2328,7 @@ class LegacySupport {
|
|
|
2904
2328
|
store: this.store,
|
|
2905
2329
|
type: definition.type,
|
|
2906
2330
|
identifier: this.identifier,
|
|
2907
|
-
|
|
2331
|
+
cache: this.cache,
|
|
2908
2332
|
identifiers,
|
|
2909
2333
|
key,
|
|
2910
2334
|
meta: doc.meta || null,
|
|
@@ -2923,16 +2347,16 @@ class LegacySupport {
|
|
|
2923
2347
|
assert('hasMany only works with the @ember-data/json-api package');
|
|
2924
2348
|
}
|
|
2925
2349
|
fetchAsyncHasMany(key, relationship, manyArray, options) {
|
|
2926
|
-
if (
|
|
2350
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2927
2351
|
let loadingPromise = this._relationshipPromisesCache[key];
|
|
2928
2352
|
if (loadingPromise) {
|
|
2929
2353
|
return loadingPromise;
|
|
2930
2354
|
}
|
|
2931
|
-
const jsonApi = this.
|
|
2355
|
+
const jsonApi = this.cache.getRelationship(this.identifier, key);
|
|
2932
2356
|
const promise = this._findHasManyByJsonApiResource(jsonApi, this.identifier, relationship, options);
|
|
2933
2357
|
if (!promise) {
|
|
2934
2358
|
manyArray.isLoaded = true;
|
|
2935
|
-
return resolve(manyArray);
|
|
2359
|
+
return Promise.resolve(manyArray);
|
|
2936
2360
|
}
|
|
2937
2361
|
loadingPromise = promise.then(() => handleCompletedRelationshipRequest(this, key, relationship, manyArray), e => handleCompletedRelationshipRequest(this, key, relationship, manyArray, e));
|
|
2938
2362
|
this._relationshipPromisesCache[key] = loadingPromise;
|
|
@@ -2941,7 +2365,7 @@ class LegacySupport {
|
|
|
2941
2365
|
assert('hasMany only works with the @ember-data/json-api package');
|
|
2942
2366
|
}
|
|
2943
2367
|
reloadHasMany(key, options) {
|
|
2944
|
-
if (
|
|
2368
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2945
2369
|
let loadingPromise = this._relationshipPromisesCache[key];
|
|
2946
2370
|
if (loadingPromise) {
|
|
2947
2371
|
return loadingPromise;
|
|
@@ -2966,7 +2390,7 @@ class LegacySupport {
|
|
|
2966
2390
|
assert(`hasMany only works with the @ember-data/json-api package`);
|
|
2967
2391
|
}
|
|
2968
2392
|
getHasMany(key, options) {
|
|
2969
|
-
if (
|
|
2393
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2970
2394
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
2971
2395
|
const relationship = graphFor(this.store).get(this.identifier, key);
|
|
2972
2396
|
const {
|
|
@@ -3024,7 +2448,7 @@ class LegacySupport {
|
|
|
3024
2448
|
referenceFor(kind, name) {
|
|
3025
2449
|
let reference = this.references[name];
|
|
3026
2450
|
if (!reference) {
|
|
3027
|
-
if (!
|
|
2451
|
+
if (macroCondition(!getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
3028
2452
|
// TODO @runspired while this feels odd, it is not a regression in capability because we do
|
|
3029
2453
|
// not today support references pulling from RecordDatas other than our own
|
|
3030
2454
|
// because of the intimate API access involved. This is something we will need to redesign.
|
|
@@ -3033,7 +2457,7 @@ class LegacySupport {
|
|
|
3033
2457
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
3034
2458
|
const graph = graphFor(this.store);
|
|
3035
2459
|
const relationship = graph.get(this.identifier, name);
|
|
3036
|
-
if (macroCondition(
|
|
2460
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3037
2461
|
if (kind) {
|
|
3038
2462
|
let modelName = this.identifier.type;
|
|
3039
2463
|
let actualRelationshipKind = relationship.definition.kind;
|
|
@@ -3051,7 +2475,7 @@ class LegacySupport {
|
|
|
3051
2475
|
return reference;
|
|
3052
2476
|
}
|
|
3053
2477
|
_findHasManyByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
3054
|
-
if (
|
|
2478
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
3055
2479
|
if (!resource) {
|
|
3056
2480
|
return;
|
|
3057
2481
|
}
|
|
@@ -3068,66 +2492,52 @@ class LegacySupport {
|
|
|
3068
2492
|
shouldForceReload
|
|
3069
2493
|
} = state;
|
|
3070
2494
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
3071
|
-
const
|
|
2495
|
+
const identifiers = resource.data;
|
|
2496
|
+
const shouldFindViaLink = resource.links && resource.links.related && (typeof adapter.findHasMany === 'function' || typeof identifiers === 'undefined') && (shouldForceReload || hasDematerializedInverse || isStale || !allInverseRecordsAreLoaded && !isEmpty);
|
|
2497
|
+
const relationshipMeta = this.store.getSchemaDefinitionService().relationshipsDefinitionFor({
|
|
2498
|
+
type: definition.inverseType
|
|
2499
|
+
})[definition.key];
|
|
2500
|
+
const request = {
|
|
2501
|
+
useLink: shouldFindViaLink,
|
|
2502
|
+
field: relationshipMeta,
|
|
2503
|
+
links: resource.links,
|
|
2504
|
+
meta: resource.meta,
|
|
2505
|
+
options,
|
|
2506
|
+
record: parentIdentifier
|
|
2507
|
+
};
|
|
3072
2508
|
|
|
3073
2509
|
// fetch via link
|
|
3074
2510
|
if (shouldFindViaLink) {
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
relationship is fetched.
|
|
3086
|
-
The link (which is usually a URL) is passed through unchanged, so the
|
|
3087
|
-
adapter can make whatever request it wants.
|
|
3088
|
-
The usual use-case is for the server to register a URL as a link, and
|
|
3089
|
-
then use that URL in the future to make a request for the relationship.
|
|
3090
|
-
*/
|
|
3091
|
-
assert(`You tried to load a hasMany relationship but you have no adapter (for ${parentIdentifier.type})`, adapter);
|
|
3092
|
-
assert(`You tried to load a hasMany relationship from a specified 'link' in the original payload but your adapter does not implement 'findHasMany'`, typeof adapter.findHasMany === 'function');
|
|
3093
|
-
return _findHasMany(adapter, this.store, parentIdentifier, resource.links.related, relationshipMeta, options);
|
|
2511
|
+
assert(`Expected collection to be an array`, !identifiers || Array.isArray(identifiers));
|
|
2512
|
+
assert(`Expected stable identifiers`, !identifiers || identifiers.every(isStableIdentifier));
|
|
2513
|
+
return this.store.request({
|
|
2514
|
+
op: 'findHasMany',
|
|
2515
|
+
records: identifiers || [],
|
|
2516
|
+
data: request,
|
|
2517
|
+
cacheOptions: {
|
|
2518
|
+
[Symbol.for('ember-data:skip-cache')]: true
|
|
2519
|
+
}
|
|
2520
|
+
});
|
|
3094
2521
|
}
|
|
3095
2522
|
const preferLocalCache = hasReceivedData && !isEmpty;
|
|
3096
|
-
const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
if (allInverseRecordsAreLoaded) {
|
|
3101
|
-
return;
|
|
3102
|
-
}
|
|
3103
|
-
assert(`Expected collection to be an array`, Array.isArray(resource.data));
|
|
3104
|
-
if (allInverseRecordsAreLoaded) {
|
|
3105
|
-
return;
|
|
3106
|
-
}
|
|
3107
|
-
let finds = new Array(resource.data.length);
|
|
3108
|
-
let cache = this.store._instanceCache;
|
|
3109
|
-
for (let i = 0; i < resource.data.length; i++) {
|
|
3110
|
-
const identifier = resource.data[i];
|
|
3111
|
-
assert(`expected a stable identifier`, isStableIdentifier(identifier));
|
|
3112
|
-
finds[i] = cache._fetchDataIfNeededForIdentifier(identifier, options);
|
|
3113
|
-
}
|
|
3114
|
-
return all(finds);
|
|
2523
|
+
const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(identifiers) && identifiers.length > 0;
|
|
2524
|
+
const attemptLocalCache = !shouldForceReload && !isStale && (preferLocalCache || hasLocalPartialData);
|
|
2525
|
+
if (attemptLocalCache && allInverseRecordsAreLoaded) {
|
|
2526
|
+
return;
|
|
3115
2527
|
}
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
// fetch by data
|
|
3119
|
-
if (hasData || hasLocalPartialData) {
|
|
3120
|
-
const identifiers = resource.data;
|
|
2528
|
+
const hasData = hasReceivedData && !isEmpty;
|
|
2529
|
+
if (attemptLocalCache || hasData || hasLocalPartialData) {
|
|
3121
2530
|
assert(`Expected collection to be an array`, Array.isArray(identifiers));
|
|
3122
2531
|
assert(`Expected stable identifiers`, identifiers.every(isStableIdentifier));
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
2532
|
+
options.reload = options.reload || !attemptLocalCache || undefined;
|
|
2533
|
+
return this.store.request({
|
|
2534
|
+
op: 'findHasMany',
|
|
2535
|
+
records: identifiers,
|
|
2536
|
+
data: request,
|
|
2537
|
+
cacheOptions: {
|
|
2538
|
+
[Symbol.for('ember-data:skip-cache')]: true
|
|
2539
|
+
}
|
|
2540
|
+
});
|
|
3131
2541
|
}
|
|
3132
2542
|
|
|
3133
2543
|
// we were explicitly told we have no data and no links.
|
|
@@ -3138,7 +2548,14 @@ class LegacySupport {
|
|
|
3138
2548
|
}
|
|
3139
2549
|
_findBelongsToByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
3140
2550
|
if (!resource) {
|
|
3141
|
-
return resolve(null);
|
|
2551
|
+
return Promise.resolve(null);
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
// interleaved promises mean that we MUST cache this here
|
|
2555
|
+
// in order to prevent infinite re-render if the request
|
|
2556
|
+
// fails.
|
|
2557
|
+
if (this._pending) {
|
|
2558
|
+
return this._pending;
|
|
3142
2559
|
}
|
|
3143
2560
|
const identifier = resource.data ? resource.data : null;
|
|
3144
2561
|
assert(`Expected a stable identifier`, !identifier || isStableIdentifier(identifier));
|
|
@@ -3149,53 +2566,71 @@ class LegacySupport {
|
|
|
3149
2566
|
isEmpty,
|
|
3150
2567
|
shouldForceReload
|
|
3151
2568
|
} = relationship.state;
|
|
3152
|
-
|
|
3153
|
-
// short circuit if we are already loading
|
|
3154
|
-
let pendingRequest = identifier && this.store._fetchManager.getPendingFetch(identifier, options);
|
|
3155
|
-
if (pendingRequest) {
|
|
3156
|
-
return pendingRequest;
|
|
3157
|
-
}
|
|
3158
2569
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
3159
2570
|
const shouldFindViaLink = resource.links?.related && (shouldForceReload || hasDematerializedInverse || isStale || !allInverseRecordsAreLoaded && !isEmpty);
|
|
2571
|
+
const relationshipMeta = this.store.getSchemaDefinitionService().relationshipsDefinitionFor(this.identifier)[relationship.definition.key];
|
|
2572
|
+
assert(`Attempted to access a belongsTo relationship but no definition exists for it`, relationshipMeta);
|
|
2573
|
+
const request = {
|
|
2574
|
+
useLink: shouldFindViaLink,
|
|
2575
|
+
field: relationshipMeta,
|
|
2576
|
+
links: resource.links,
|
|
2577
|
+
meta: resource.meta,
|
|
2578
|
+
options,
|
|
2579
|
+
record: parentIdentifier
|
|
2580
|
+
};
|
|
3160
2581
|
|
|
3161
2582
|
// fetch via link
|
|
3162
2583
|
if (shouldFindViaLink) {
|
|
3163
|
-
const
|
|
3164
|
-
|
|
3165
|
-
|
|
2584
|
+
const future = this.store.request({
|
|
2585
|
+
op: 'findBelongsTo',
|
|
2586
|
+
records: identifier ? [identifier] : [],
|
|
2587
|
+
data: request,
|
|
2588
|
+
cacheOptions: {
|
|
2589
|
+
[Symbol.for('ember-data:skip-cache')]: true
|
|
2590
|
+
}
|
|
2591
|
+
});
|
|
2592
|
+
this._pending = future.then(doc => doc.content).finally(() => {
|
|
2593
|
+
this._pending = null;
|
|
2594
|
+
});
|
|
2595
|
+
return this._pending;
|
|
3166
2596
|
}
|
|
3167
|
-
|
|
3168
|
-
|
|
2597
|
+
const preferLocalCache = hasReceivedData && allInverseRecordsAreLoaded && !isEmpty;
|
|
2598
|
+
const hasLocalPartialData = hasDematerializedInverse || isEmpty && resource.data;
|
|
3169
2599
|
// null is explicit empty, undefined is "we don't know anything"
|
|
3170
|
-
const localDataIsEmpty =
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
2600
|
+
const localDataIsEmpty = !identifier;
|
|
2601
|
+
const attemptLocalCache = !shouldForceReload && !isStale && (preferLocalCache || hasLocalPartialData);
|
|
2602
|
+
|
|
2603
|
+
// we dont need to fetch and are empty
|
|
2604
|
+
if (attemptLocalCache && localDataIsEmpty) {
|
|
2605
|
+
return Promise.resolve(null);
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
// we dont need to fetch because we are local state
|
|
2609
|
+
const resourceIsLocal = identifier?.id === null;
|
|
2610
|
+
if (attemptLocalCache && allInverseRecordsAreLoaded || resourceIsLocal) {
|
|
2611
|
+
return Promise.resolve(identifier);
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
// we may need to fetch
|
|
2615
|
+
if (identifier) {
|
|
2616
|
+
assert(`Cannot fetch belongs-to relationship with no information`, identifier);
|
|
2617
|
+
options.reload = options.reload || !attemptLocalCache || undefined;
|
|
2618
|
+
this._pending = this.store.request({
|
|
2619
|
+
op: 'findBelongsTo',
|
|
2620
|
+
records: [identifier],
|
|
2621
|
+
data: request,
|
|
2622
|
+
cacheOptions: {
|
|
2623
|
+
[Symbol.for('ember-data:skip-cache')]: true
|
|
2624
|
+
}
|
|
2625
|
+
}).then(doc => doc.content).finally(() => {
|
|
2626
|
+
this._pending = null;
|
|
2627
|
+
});
|
|
2628
|
+
return this._pending;
|
|
3194
2629
|
}
|
|
3195
2630
|
|
|
3196
2631
|
// we were explicitly told we have no data and no links.
|
|
3197
2632
|
// TODO if the relationshipIsStale, should we hit the adapter anyway?
|
|
3198
|
-
return resolve(null);
|
|
2633
|
+
return Promise.resolve(null);
|
|
3199
2634
|
}
|
|
3200
2635
|
destroy() {
|
|
3201
2636
|
this.isDestroying = true;
|
|
@@ -3244,41 +2679,25 @@ function handleCompletedRelationshipRequest(recordExt, key, relationship, value,
|
|
|
3244
2679
|
if (proxy.content && proxy.content.isDestroying) {
|
|
3245
2680
|
proxy.set('content', null);
|
|
3246
2681
|
}
|
|
2682
|
+
recordExt.store.notifications._flush();
|
|
3247
2683
|
}
|
|
3248
2684
|
throw error;
|
|
3249
2685
|
}
|
|
3250
2686
|
if (isHasMany) {
|
|
3251
2687
|
value.isLoaded = true;
|
|
2688
|
+
} else {
|
|
2689
|
+
recordExt.store.notifications._flush();
|
|
3252
2690
|
}
|
|
3253
2691
|
relationship.state.hasFailedLoadAttempt = false;
|
|
3254
2692
|
// only set to not stale if no error is thrown
|
|
3255
2693
|
relationship.state.isStale = false;
|
|
3256
2694
|
return isHasMany || !value ? value : recordExt.store.peekRecord(value);
|
|
3257
2695
|
}
|
|
3258
|
-
function extractIdentifierFromRecord(
|
|
3259
|
-
if (!
|
|
2696
|
+
function extractIdentifierFromRecord(record) {
|
|
2697
|
+
if (!record) {
|
|
3260
2698
|
return null;
|
|
3261
2699
|
}
|
|
3262
|
-
|
|
3263
|
-
if (isPromiseRecord(recordOrPromiseRecord)) {
|
|
3264
|
-
let content = recordOrPromiseRecord.content;
|
|
3265
|
-
assert('You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo or hasMany relationship to the get call.', content !== undefined);
|
|
3266
|
-
deprecate(`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`, false, {
|
|
3267
|
-
id: 'ember-data:deprecate-promise-proxies',
|
|
3268
|
-
until: '5.0',
|
|
3269
|
-
since: {
|
|
3270
|
-
enabled: '4.7',
|
|
3271
|
-
available: '4.7'
|
|
3272
|
-
},
|
|
3273
|
-
for: 'ember-data'
|
|
3274
|
-
});
|
|
3275
|
-
return content ? recordIdentifierFor$1(content) : null;
|
|
3276
|
-
}
|
|
3277
|
-
}
|
|
3278
|
-
return recordIdentifierFor$1(recordOrPromiseRecord);
|
|
3279
|
-
}
|
|
3280
|
-
function isPromiseRecord(record) {
|
|
3281
|
-
return !!record.then;
|
|
2700
|
+
return recordIdentifierFor$1(record);
|
|
3282
2701
|
}
|
|
3283
2702
|
function anyUnloaded(store, relationship) {
|
|
3284
2703
|
let state = relationship.localState;
|
|
@@ -3355,7 +2774,8 @@ function notifyRelationship(identifier, key, record, meta) {
|
|
|
3355
2774
|
}
|
|
3356
2775
|
function notifyAttribute(store, identifier, key, record) {
|
|
3357
2776
|
let currentValue = cacheFor(record, key);
|
|
3358
|
-
|
|
2777
|
+
const cache = store.cache;
|
|
2778
|
+
if (currentValue !== cache.getAttr(identifier, key)) {
|
|
3359
2779
|
record.notifyPropertyChange(key);
|
|
3360
2780
|
}
|
|
3361
2781
|
}
|
|
@@ -3384,6 +2804,9 @@ let Tag = (_class$1 = class Tag {
|
|
|
3384
2804
|
this.rev = 1;
|
|
3385
2805
|
this.isDirty = true;
|
|
3386
2806
|
this.value = undefined;
|
|
2807
|
+
/*
|
|
2808
|
+
* whether this was part of a transaction when mutated
|
|
2809
|
+
*/
|
|
3387
2810
|
this.t = false;
|
|
3388
2811
|
}
|
|
3389
2812
|
notify() {
|
|
@@ -3487,11 +2910,11 @@ root
|
|
|
3487
2910
|
let RecordState = (_class3 = class RecordState {
|
|
3488
2911
|
constructor(record) {
|
|
3489
2912
|
_initializerDefineProperty(this, "isSaving", _descriptor2, this);
|
|
3490
|
-
const store = storeFor(record);
|
|
2913
|
+
const store = storeFor$1(record);
|
|
3491
2914
|
const identity = recordIdentifierFor$1(record);
|
|
3492
2915
|
this.identifier = identity;
|
|
3493
2916
|
this.record = record;
|
|
3494
|
-
this.cache = store.
|
|
2917
|
+
this.cache = store.cache;
|
|
3495
2918
|
this.pendingCount = 0;
|
|
3496
2919
|
this.fulfilledCount = 0;
|
|
3497
2920
|
this.rejectedCount = 0;
|
|
@@ -3551,7 +2974,7 @@ let RecordState = (_class3 = class RecordState {
|
|
|
3551
2974
|
|
|
3552
2975
|
// we instantiate lazily
|
|
3553
2976
|
// so we grab anything we don't have yet
|
|
3554
|
-
if (macroCondition(!
|
|
2977
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
3555
2978
|
const lastRequest = requests.getLastRequestForRecord(identity);
|
|
3556
2979
|
if (lastRequest) {
|
|
3557
2980
|
handleRequest(lastRequest);
|
|
@@ -3576,7 +2999,7 @@ let RecordState = (_class3 = class RecordState {
|
|
|
3576
2999
|
});
|
|
3577
3000
|
}
|
|
3578
3001
|
destroy() {
|
|
3579
|
-
storeFor(this.record).notifications.unsubscribe(this.handler);
|
|
3002
|
+
storeFor$1(this.record).notifications.unsubscribe(this.handler);
|
|
3580
3003
|
}
|
|
3581
3004
|
notify(key) {
|
|
3582
3005
|
getTag(this, key).notify();
|
|
@@ -3753,79 +3176,6 @@ function notifyErrorsStateChanged(state) {
|
|
|
3753
3176
|
state.notify('isError');
|
|
3754
3177
|
state.notify('adapterError');
|
|
3755
3178
|
}
|
|
3756
|
-
function typeForRelationshipMeta(meta) {
|
|
3757
|
-
let modelName = dasherize(meta.type || meta.key);
|
|
3758
|
-
if (meta.kind === 'hasMany') {
|
|
3759
|
-
modelName = singularize(modelName);
|
|
3760
|
-
}
|
|
3761
|
-
return modelName;
|
|
3762
|
-
}
|
|
3763
|
-
function shouldFindInverse(relationshipMeta) {
|
|
3764
|
-
let options = relationshipMeta.options;
|
|
3765
|
-
return !(options && options.inverse === null);
|
|
3766
|
-
}
|
|
3767
|
-
class RelationshipDefinition {
|
|
3768
|
-
constructor(meta) {
|
|
3769
|
-
this._type = '';
|
|
3770
|
-
this.__inverseKey = '';
|
|
3771
|
-
this.__hasCalculatedInverse = false;
|
|
3772
|
-
this.parentModelName = meta.parentModelName;
|
|
3773
|
-
this.meta = meta;
|
|
3774
|
-
}
|
|
3775
|
-
|
|
3776
|
-
/**
|
|
3777
|
-
* @internal
|
|
3778
|
-
* @deprecated
|
|
3779
|
-
*/
|
|
3780
|
-
get key() {
|
|
3781
|
-
return this.meta.key;
|
|
3782
|
-
}
|
|
3783
|
-
get kind() {
|
|
3784
|
-
return this.meta.kind;
|
|
3785
|
-
}
|
|
3786
|
-
get type() {
|
|
3787
|
-
if (this._type) {
|
|
3788
|
-
return this._type;
|
|
3789
|
-
}
|
|
3790
|
-
this._type = typeForRelationshipMeta(this.meta);
|
|
3791
|
-
return this._type;
|
|
3792
|
-
}
|
|
3793
|
-
get options() {
|
|
3794
|
-
return this.meta.options;
|
|
3795
|
-
}
|
|
3796
|
-
get name() {
|
|
3797
|
-
return this.meta.name;
|
|
3798
|
-
}
|
|
3799
|
-
_inverseKey(store, modelClass) {
|
|
3800
|
-
if (this.__hasCalculatedInverse === false) {
|
|
3801
|
-
this._calculateInverse(store, modelClass);
|
|
3802
|
-
}
|
|
3803
|
-
return this.__inverseKey;
|
|
3804
|
-
}
|
|
3805
|
-
_calculateInverse(store, modelClass) {
|
|
3806
|
-
this.__hasCalculatedInverse = true;
|
|
3807
|
-
let inverseKey;
|
|
3808
|
-
let inverse = null;
|
|
3809
|
-
if (shouldFindInverse(this.meta)) {
|
|
3810
|
-
inverse = modelClass.inverseFor(this.key, store);
|
|
3811
|
-
}
|
|
3812
|
-
// TODO make this error again for the non-polymorphic case
|
|
3813
|
-
if (macroCondition(isDevelopingApp())) {
|
|
3814
|
-
if (!this.options.polymorphic) {
|
|
3815
|
-
modelClass.typeForRelationship(this.key, store);
|
|
3816
|
-
}
|
|
3817
|
-
}
|
|
3818
|
-
if (inverse) {
|
|
3819
|
-
inverseKey = inverse.name;
|
|
3820
|
-
} else {
|
|
3821
|
-
inverseKey = null;
|
|
3822
|
-
}
|
|
3823
|
-
this.__inverseKey = inverseKey;
|
|
3824
|
-
}
|
|
3825
|
-
}
|
|
3826
|
-
function relationshipFromMeta(meta) {
|
|
3827
|
-
return new RelationshipDefinition(meta);
|
|
3828
|
-
}
|
|
3829
3179
|
var _class, _descriptor, _class2;
|
|
3830
3180
|
const {
|
|
3831
3181
|
changeProperties
|
|
@@ -3835,6 +3185,7 @@ function lookupLegacySupport(record) {
|
|
|
3835
3185
|
const identifier = recordIdentifierFor(record);
|
|
3836
3186
|
let support = LEGACY_SUPPORT.get(identifier);
|
|
3837
3187
|
if (!support) {
|
|
3188
|
+
assert(`Memory Leak Detected`, !record.isDestroyed && !record.isDestroying);
|
|
3838
3189
|
support = new LegacySupport(record);
|
|
3839
3190
|
LEGACY_SUPPORT.set(identifier, support);
|
|
3840
3191
|
LEGACY_SUPPORT.set(record, support);
|
|
@@ -3893,7 +3244,7 @@ function computeOnce(target, key, desc) {
|
|
|
3893
3244
|
}
|
|
3894
3245
|
|
|
3895
3246
|
/**
|
|
3896
|
-
Base class from which Models can be
|
|
3247
|
+
Base class from which Models can be defined.
|
|
3897
3248
|
|
|
3898
3249
|
```js
|
|
3899
3250
|
import Model, { attr } from '@ember-data/model';
|
|
@@ -3927,7 +3278,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3927
3278
|
_initializerDefineProperty(this, "isReloading", _descriptor, this);
|
|
3928
3279
|
}
|
|
3929
3280
|
init(options = {}) {
|
|
3930
|
-
if (macroCondition(
|
|
3281
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3931
3282
|
if (!options._secretInit && !options._createProps) {
|
|
3932
3283
|
throw new Error('You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.');
|
|
3933
3284
|
}
|
|
@@ -3939,8 +3290,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3939
3290
|
let store = this.store = _secretInit.store;
|
|
3940
3291
|
super.init(options);
|
|
3941
3292
|
let identity = _secretInit.identifier;
|
|
3942
|
-
_secretInit.cb(this, _secretInit.
|
|
3943
|
-
this.___recordState = macroCondition(
|
|
3293
|
+
_secretInit.cb(this, _secretInit.cache, identity, _secretInit.store);
|
|
3294
|
+
this.___recordState = macroCondition(getOwnConfig().env.DEBUG) ? new RecordState(this) : null;
|
|
3944
3295
|
this.setProperties(createProps);
|
|
3945
3296
|
let notifications = store.notifications;
|
|
3946
3297
|
this.___private_notifications = notifications.subscribe(identity, (identifier, type, key) => {
|
|
@@ -3950,7 +3301,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3950
3301
|
destroy() {
|
|
3951
3302
|
const identifier = recordIdentifierFor(this);
|
|
3952
3303
|
this.___recordState?.destroy();
|
|
3953
|
-
const store = storeFor(this);
|
|
3304
|
+
const store = storeFor$1(this);
|
|
3954
3305
|
store.notifications.unsubscribe(this.___private_notifications);
|
|
3955
3306
|
// Legacy behavior is to notify the relationships on destroy
|
|
3956
3307
|
// such that they "clear". It's uncertain this behavior would
|
|
@@ -4185,7 +3536,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4185
3536
|
return this.currentState.isError;
|
|
4186
3537
|
}
|
|
4187
3538
|
set isError(v) {
|
|
4188
|
-
if (macroCondition(
|
|
3539
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4189
3540
|
throw new Error(`isError is not directly settable`);
|
|
4190
3541
|
}
|
|
4191
3542
|
}
|
|
@@ -4210,7 +3561,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4210
3561
|
// this guard exists, because some dev-only deprecation code
|
|
4211
3562
|
// (addListener via validatePropertyInjections) invokes toString before the
|
|
4212
3563
|
// object is real.
|
|
4213
|
-
if (macroCondition(
|
|
3564
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4214
3565
|
try {
|
|
4215
3566
|
return recordIdentifierFor(this).id;
|
|
4216
3567
|
} catch {
|
|
@@ -4245,7 +3596,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4245
3596
|
// when using legacy/classic ember classes. Basically: lazy in prod and eager in dev.
|
|
4246
3597
|
// so we do this to try to steer folks to the nicer "dont user currentState"
|
|
4247
3598
|
// error.
|
|
4248
|
-
if (macroCondition(!
|
|
3599
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
4249
3600
|
if (!this.___recordState) {
|
|
4250
3601
|
this.___recordState = new RecordState(this);
|
|
4251
3602
|
}
|
|
@@ -4341,7 +3692,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4341
3692
|
@return {Object} an object whose values are primitive JSON values only
|
|
4342
3693
|
*/
|
|
4343
3694
|
serialize(options) {
|
|
4344
|
-
return storeFor(this).
|
|
3695
|
+
return storeFor$1(this).serializeRecord(this, options);
|
|
4345
3696
|
}
|
|
4346
3697
|
|
|
4347
3698
|
/*
|
|
@@ -4390,7 +3741,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4390
3741
|
deleteRecord() {
|
|
4391
3742
|
// ensure we've populated currentState prior to deleting a new record
|
|
4392
3743
|
if (this.currentState) {
|
|
4393
|
-
storeFor(this).deleteRecord(this);
|
|
3744
|
+
storeFor$1(this).deleteRecord(this);
|
|
4394
3745
|
}
|
|
4395
3746
|
}
|
|
4396
3747
|
|
|
@@ -4437,7 +3788,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4437
3788
|
} = this.currentState;
|
|
4438
3789
|
this.deleteRecord();
|
|
4439
3790
|
if (isNew) {
|
|
4440
|
-
return resolve(this);
|
|
3791
|
+
return Promise.resolve(this);
|
|
4441
3792
|
}
|
|
4442
3793
|
return this.save(options).then(_ => {
|
|
4443
3794
|
run(() => {
|
|
@@ -4457,7 +3808,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4457
3808
|
if (this.currentState.isNew && (this.isDestroyed || this.isDestroying)) {
|
|
4458
3809
|
return;
|
|
4459
3810
|
}
|
|
4460
|
-
storeFor(this).unloadRecord(this);
|
|
3811
|
+
storeFor$1(this).unloadRecord(this);
|
|
4461
3812
|
}
|
|
4462
3813
|
|
|
4463
3814
|
/**
|
|
@@ -4513,7 +3864,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4513
3864
|
and value is an [oldProp, newProp] array.
|
|
4514
3865
|
*/
|
|
4515
3866
|
changedAttributes() {
|
|
4516
|
-
return
|
|
3867
|
+
return peekCache(this).changedAttrs(recordIdentifierFor(this));
|
|
4517
3868
|
}
|
|
4518
3869
|
|
|
4519
3870
|
/**
|
|
@@ -4538,8 +3889,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4538
3889
|
const {
|
|
4539
3890
|
isNew
|
|
4540
3891
|
} = currentState;
|
|
4541
|
-
storeFor(this)._join(() => {
|
|
4542
|
-
|
|
3892
|
+
storeFor$1(this)._join(() => {
|
|
3893
|
+
peekCache(this).rollbackAttrs(recordIdentifierFor(this));
|
|
4543
3894
|
this.errors.clear();
|
|
4544
3895
|
currentState.cleanErrorRequests();
|
|
4545
3896
|
if (isNew) {
|
|
@@ -4554,7 +3905,12 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4554
3905
|
*/
|
|
4555
3906
|
// TODO @deprecate in favor of a public API or examples of how to test successfully
|
|
4556
3907
|
_createSnapshot() {
|
|
4557
|
-
|
|
3908
|
+
const store = storeFor$1(this);
|
|
3909
|
+
if (!store._fetchManager) {
|
|
3910
|
+
const FetchManager = importSync('@ember-data/legacy-compat/-private').FetchManager;
|
|
3911
|
+
store._fetchManager = new FetchManager(store);
|
|
3912
|
+
}
|
|
3913
|
+
return store._fetchManager.createSnapshot(recordIdentifierFor(this));
|
|
4558
3914
|
}
|
|
4559
3915
|
|
|
4560
3916
|
/**
|
|
@@ -4594,12 +3950,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4594
3950
|
save(options) {
|
|
4595
3951
|
let promise;
|
|
4596
3952
|
if (this.currentState.isNew && this.currentState.isDeleted) {
|
|
4597
|
-
promise = resolve(this);
|
|
3953
|
+
promise = Promise.resolve(this);
|
|
4598
3954
|
} else {
|
|
4599
|
-
promise = storeFor(this).saveRecord(this, options);
|
|
4600
|
-
}
|
|
4601
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SAVE_PROMISE_ACCESS)) {
|
|
4602
|
-
return deprecatedPromiseObject(promise);
|
|
3955
|
+
promise = storeFor$1(this).saveRecord(this, options);
|
|
4603
3956
|
}
|
|
4604
3957
|
return promise;
|
|
4605
3958
|
}
|
|
@@ -4627,21 +3980,24 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4627
3980
|
adapter returns successfully or rejected if the adapter returns
|
|
4628
3981
|
with an error.
|
|
4629
3982
|
*/
|
|
4630
|
-
reload(
|
|
4631
|
-
let options = {};
|
|
4632
|
-
if (typeof _options === 'object' && _options !== null && _options.adapterOptions) {
|
|
4633
|
-
options.adapterOptions = _options.adapterOptions;
|
|
4634
|
-
}
|
|
3983
|
+
reload(options = {}) {
|
|
4635
3984
|
options.isReloading = true;
|
|
4636
|
-
|
|
3985
|
+
options.reload = true;
|
|
3986
|
+
const identifier = recordIdentifierFor(this);
|
|
4637
3987
|
assert(`You cannot reload a record without an ID`, identifier.id);
|
|
4638
3988
|
this.isReloading = true;
|
|
4639
|
-
const promise = storeFor(this).
|
|
3989
|
+
const promise = storeFor$1(this).request({
|
|
3990
|
+
op: 'findRecord',
|
|
3991
|
+
data: {
|
|
3992
|
+
options,
|
|
3993
|
+
record: identifier
|
|
3994
|
+
},
|
|
3995
|
+
cacheOptions: {
|
|
3996
|
+
[Symbol.for('ember-data:skip-cache')]: true
|
|
3997
|
+
}
|
|
3998
|
+
}).then(() => this).finally(() => {
|
|
4640
3999
|
this.isReloading = false;
|
|
4641
4000
|
});
|
|
4642
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SAVE_PROMISE_ACCESS)) {
|
|
4643
|
-
return deprecatedPromiseObject(promise);
|
|
4644
|
-
}
|
|
4645
4001
|
return promise;
|
|
4646
4002
|
}
|
|
4647
4003
|
attr() {
|
|
@@ -4804,11 +4160,46 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4804
4160
|
return this.constructor.relationshipsByName.get(name);
|
|
4805
4161
|
}
|
|
4806
4162
|
inverseFor(key) {
|
|
4807
|
-
return this.constructor.inverseFor(key, storeFor(this));
|
|
4163
|
+
return this.constructor.inverseFor(key, storeFor$1(this));
|
|
4808
4164
|
}
|
|
4809
4165
|
eachAttribute(callback, binding) {
|
|
4810
4166
|
this.constructor.eachAttribute(callback, binding);
|
|
4811
4167
|
}
|
|
4168
|
+
|
|
4169
|
+
/**
|
|
4170
|
+
Create should only ever be called by the store. To create an instance of a
|
|
4171
|
+
`Model` in a dirty state use `store.createRecord`.
|
|
4172
|
+
To create instances of `Model` in a clean state, use `store.push`
|
|
4173
|
+
@method create
|
|
4174
|
+
@private
|
|
4175
|
+
@static
|
|
4176
|
+
*/
|
|
4177
|
+
/**
|
|
4178
|
+
Represents the model's class name as a string. This can be used to look up the model's class name through
|
|
4179
|
+
`Store`'s modelFor method.
|
|
4180
|
+
`modelName` is generated for you by Ember Data. It will be a lowercased, dasherized string.
|
|
4181
|
+
For example:
|
|
4182
|
+
```javascript
|
|
4183
|
+
store.modelFor('post').modelName; // 'post'
|
|
4184
|
+
store.modelFor('blog-post').modelName; // 'blog-post'
|
|
4185
|
+
```
|
|
4186
|
+
The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
|
|
4187
|
+
keys to underscore (instead of dasherized), you might use the following code:
|
|
4188
|
+
```javascript
|
|
4189
|
+
import RESTSerializer from '@ember-data/serializer/rest';
|
|
4190
|
+
import { underscore } from '<app-name>/utils/string-utils';
|
|
4191
|
+
export default const PostSerializer = RESTSerializer.extend({
|
|
4192
|
+
payloadKeyFromModelName(modelName) {
|
|
4193
|
+
return underscore(modelName);
|
|
4194
|
+
}
|
|
4195
|
+
});
|
|
4196
|
+
```
|
|
4197
|
+
@property modelName
|
|
4198
|
+
@public
|
|
4199
|
+
@type String
|
|
4200
|
+
@readonly
|
|
4201
|
+
@static
|
|
4202
|
+
*/
|
|
4812
4203
|
/*
|
|
4813
4204
|
These class methods below provide relationship
|
|
4814
4205
|
introspection abilities about relationships.
|
|
@@ -4822,7 +4213,6 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4822
4213
|
do it before using your model with the store, which uses these properties
|
|
4823
4214
|
extensively.
|
|
4824
4215
|
*/
|
|
4825
|
-
|
|
4826
4216
|
/**
|
|
4827
4217
|
For a given relationship name, returns the model type of the relationship.
|
|
4828
4218
|
For example, if you define a model like this:
|
|
@@ -4841,36 +4231,12 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4841
4231
|
@return {Model} the type of the relationship, or undefined
|
|
4842
4232
|
*/
|
|
4843
4233
|
static typeForRelationship(name, store) {
|
|
4844
|
-
|
|
4845
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
4846
|
-
id: 'ember-data:deprecate-early-static',
|
|
4847
|
-
for: 'ember-data',
|
|
4848
|
-
until: '5.0',
|
|
4849
|
-
since: {
|
|
4850
|
-
available: '4.7',
|
|
4851
|
-
enabled: '4.7'
|
|
4852
|
-
}
|
|
4853
|
-
});
|
|
4854
|
-
} else {
|
|
4855
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4856
|
-
}
|
|
4234
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4857
4235
|
let relationship = this.relationshipsByName.get(name);
|
|
4858
4236
|
return relationship && store.modelFor(relationship.type);
|
|
4859
4237
|
}
|
|
4860
4238
|
static get inverseMap() {
|
|
4861
|
-
|
|
4862
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
4863
|
-
id: 'ember-data:deprecate-early-static',
|
|
4864
|
-
for: 'ember-data',
|
|
4865
|
-
until: '5.0',
|
|
4866
|
-
since: {
|
|
4867
|
-
available: '4.7',
|
|
4868
|
-
enabled: '4.7'
|
|
4869
|
-
}
|
|
4870
|
-
});
|
|
4871
|
-
} else {
|
|
4872
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4873
|
-
}
|
|
4239
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4874
4240
|
return Object.create(null);
|
|
4875
4241
|
}
|
|
4876
4242
|
|
|
@@ -4901,19 +4267,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4901
4267
|
@return {Object} the inverse relationship, or null
|
|
4902
4268
|
*/
|
|
4903
4269
|
static inverseFor(name, store) {
|
|
4904
|
-
|
|
4905
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
4906
|
-
id: 'ember-data:deprecate-early-static',
|
|
4907
|
-
for: 'ember-data',
|
|
4908
|
-
until: '5.0',
|
|
4909
|
-
since: {
|
|
4910
|
-
available: '4.7',
|
|
4911
|
-
enabled: '4.7'
|
|
4912
|
-
}
|
|
4913
|
-
});
|
|
4914
|
-
} else {
|
|
4915
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4916
|
-
}
|
|
4270
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4917
4271
|
let inverseMap = this.inverseMap;
|
|
4918
4272
|
if (inverseMap[name]) {
|
|
4919
4273
|
return inverseMap[name];
|
|
@@ -4926,19 +4280,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4926
4280
|
|
|
4927
4281
|
//Calculate the inverse, ignoring the cache
|
|
4928
4282
|
static _findInverseFor(name, store) {
|
|
4929
|
-
|
|
4930
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
4931
|
-
id: 'ember-data:deprecate-early-static',
|
|
4932
|
-
for: 'ember-data',
|
|
4933
|
-
until: '5.0',
|
|
4934
|
-
since: {
|
|
4935
|
-
available: '4.7',
|
|
4936
|
-
enabled: '4.7'
|
|
4937
|
-
}
|
|
4938
|
-
});
|
|
4939
|
-
} else {
|
|
4940
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4941
|
-
}
|
|
4283
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
4942
4284
|
const relationship = this.relationshipsByName.get(name);
|
|
4943
4285
|
const {
|
|
4944
4286
|
options
|
|
@@ -4976,7 +4318,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4976
4318
|
if (possibleRelationships.length === 0) {
|
|
4977
4319
|
return null;
|
|
4978
4320
|
}
|
|
4979
|
-
if (macroCondition(
|
|
4321
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4980
4322
|
let filteredRelationships = possibleRelationships.filter(possibleRelationship => {
|
|
4981
4323
|
let optionsForRelationship = possibleRelationship.options;
|
|
4982
4324
|
return name === optionsForRelationship.inverse;
|
|
@@ -4994,46 +4336,18 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4994
4336
|
}
|
|
4995
4337
|
|
|
4996
4338
|
// ensure inverse is properly configured
|
|
4997
|
-
if (macroCondition(
|
|
4339
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4998
4340
|
if (isPolymorphic) {
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
deprecate(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${fieldOnInverse}' on type '${inverseSchema.modelName}' is misconfigured.`, false, {
|
|
5002
|
-
id: 'ember-data:non-explicit-relationships',
|
|
5003
|
-
since: {
|
|
5004
|
-
enabled: '4.7',
|
|
5005
|
-
available: '4.7'
|
|
5006
|
-
},
|
|
5007
|
-
until: '5.0',
|
|
5008
|
-
for: 'ember-data'
|
|
5009
|
-
});
|
|
5010
|
-
}
|
|
5011
|
-
} else {
|
|
5012
|
-
assert(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${fieldOnInverse}' on type '${inverseSchema.modelName}' is misconfigured.`, inverseOptions.as);
|
|
5013
|
-
assert(`options.as should match the expected type of the polymorphic relationship. Expected field '${fieldOnInverse}' on type '${inverseSchema.modelName}' to specify '${relationship.type}' but found '${inverseOptions.as}'`, !!inverseOptions.as && relationship.type === inverseOptions.as);
|
|
5014
|
-
}
|
|
4341
|
+
assert(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${fieldOnInverse}' on type '${inverseSchema.modelName}' is misconfigured.`, inverseOptions.as);
|
|
4342
|
+
assert(`options.as should match the expected type of the polymorphic relationship. Expected field '${fieldOnInverse}' on type '${inverseSchema.modelName}' to specify '${relationship.type}' but found '${inverseOptions.as}'`, !!inverseOptions.as && relationship.type === inverseOptions.as);
|
|
5015
4343
|
}
|
|
5016
4344
|
}
|
|
5017
4345
|
|
|
5018
4346
|
// ensure we are properly configured
|
|
5019
|
-
if (macroCondition(
|
|
4347
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5020
4348
|
if (inverseOptions.polymorphic) {
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
deprecate(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${name}' on type '${this.modelName}' is misconfigured.`, false, {
|
|
5024
|
-
id: 'ember-data:non-explicit-relationships',
|
|
5025
|
-
since: {
|
|
5026
|
-
enabled: '4.7',
|
|
5027
|
-
available: '4.7'
|
|
5028
|
-
},
|
|
5029
|
-
until: '5.0',
|
|
5030
|
-
for: 'ember-data'
|
|
5031
|
-
});
|
|
5032
|
-
}
|
|
5033
|
-
} else {
|
|
5034
|
-
assert(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${name}' on type '${this.modelName}' is misconfigured.`, options.as);
|
|
5035
|
-
assert(`options.as should match the expected type of the polymorphic relationship. Expected field '${name}' on type '${this.modelName}' to specify '${inverseRelationship.type}' but found '${options.as}'`, !!options.as && inverseRelationship.type === options.as);
|
|
5036
|
-
}
|
|
4349
|
+
assert(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${name}' on type '${this.modelName}' is misconfigured.`, options.as);
|
|
4350
|
+
assert(`options.as should match the expected type of the polymorphic relationship. Expected field '${name}' on type '${this.modelName}' to specify '${inverseRelationship.type}' but found '${options.as}'`, !!options.as && inverseRelationship.type === options.as);
|
|
5037
4351
|
}
|
|
5038
4352
|
}
|
|
5039
4353
|
assert(`The ${inverseSchema.modelName}:${fieldOnInverse} relationship declares 'inverse: null', but it was resolved as the inverse for ${this.modelName}:${name}.`, inverseOptions.inverse !== null);
|
|
@@ -5081,19 +4395,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5081
4395
|
*/
|
|
5082
4396
|
|
|
5083
4397
|
static get relationships() {
|
|
5084
|
-
|
|
5085
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5086
|
-
id: 'ember-data:deprecate-early-static',
|
|
5087
|
-
for: 'ember-data',
|
|
5088
|
-
until: '5.0',
|
|
5089
|
-
since: {
|
|
5090
|
-
available: '4.7',
|
|
5091
|
-
enabled: '4.7'
|
|
5092
|
-
}
|
|
5093
|
-
});
|
|
5094
|
-
} else {
|
|
5095
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5096
|
-
}
|
|
4398
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5097
4399
|
let map = new Map();
|
|
5098
4400
|
let relationshipsByName = this.relationshipsByName;
|
|
5099
4401
|
|
|
@@ -5139,19 +4441,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5139
4441
|
@readOnly
|
|
5140
4442
|
*/
|
|
5141
4443
|
static get relationshipNames() {
|
|
5142
|
-
|
|
5143
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5144
|
-
id: 'ember-data:deprecate-early-static',
|
|
5145
|
-
for: 'ember-data',
|
|
5146
|
-
until: '5.0',
|
|
5147
|
-
since: {
|
|
5148
|
-
available: '4.7',
|
|
5149
|
-
enabled: '4.7'
|
|
5150
|
-
}
|
|
5151
|
-
});
|
|
5152
|
-
} else {
|
|
5153
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5154
|
-
}
|
|
4444
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5155
4445
|
let names = {
|
|
5156
4446
|
hasMany: [],
|
|
5157
4447
|
belongsTo: []
|
|
@@ -5182,7 +4472,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5182
4472
|
import { get } from '@ember/object';
|
|
5183
4473
|
import Blog from 'app/models/blog';
|
|
5184
4474
|
let relatedTypes = Blog.relatedTypes');
|
|
5185
|
-
//=> [
|
|
4475
|
+
//=> ['user', 'post']
|
|
5186
4476
|
```
|
|
5187
4477
|
@property relatedTypes
|
|
5188
4478
|
@public
|
|
@@ -5191,19 +4481,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5191
4481
|
@readOnly
|
|
5192
4482
|
*/
|
|
5193
4483
|
static get relatedTypes() {
|
|
5194
|
-
|
|
5195
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5196
|
-
id: 'ember-data:deprecate-early-static',
|
|
5197
|
-
for: 'ember-data',
|
|
5198
|
-
until: '5.0',
|
|
5199
|
-
since: {
|
|
5200
|
-
available: '4.7',
|
|
5201
|
-
enabled: '4.7'
|
|
5202
|
-
}
|
|
5203
|
-
});
|
|
5204
|
-
} else {
|
|
5205
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5206
|
-
}
|
|
4484
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5207
4485
|
let types = [];
|
|
5208
4486
|
let rels = this.relationshipsObject;
|
|
5209
4487
|
let relationships = Object.keys(rels);
|
|
@@ -5251,43 +4529,19 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5251
4529
|
@readOnly
|
|
5252
4530
|
*/
|
|
5253
4531
|
static get relationshipsByName() {
|
|
5254
|
-
|
|
5255
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5256
|
-
id: 'ember-data:deprecate-early-static',
|
|
5257
|
-
for: 'ember-data',
|
|
5258
|
-
until: '5.0',
|
|
5259
|
-
since: {
|
|
5260
|
-
available: '4.7',
|
|
5261
|
-
enabled: '4.7'
|
|
5262
|
-
}
|
|
5263
|
-
});
|
|
5264
|
-
} else {
|
|
5265
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5266
|
-
}
|
|
4532
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5267
4533
|
let map = new Map();
|
|
5268
4534
|
let rels = this.relationshipsObject;
|
|
5269
4535
|
let relationships = Object.keys(rels);
|
|
5270
4536
|
for (let i = 0; i < relationships.length; i++) {
|
|
5271
4537
|
let key = relationships[i];
|
|
5272
4538
|
let value = rels[key];
|
|
5273
|
-
map.set(value.key, value);
|
|
4539
|
+
map.set(value.name || value.key, value);
|
|
5274
4540
|
}
|
|
5275
4541
|
return map;
|
|
5276
4542
|
}
|
|
5277
4543
|
static get relationshipsObject() {
|
|
5278
|
-
|
|
5279
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5280
|
-
id: 'ember-data:deprecate-early-static',
|
|
5281
|
-
for: 'ember-data',
|
|
5282
|
-
until: '5.0',
|
|
5283
|
-
since: {
|
|
5284
|
-
available: '4.7',
|
|
5285
|
-
enabled: '4.7'
|
|
5286
|
-
}
|
|
5287
|
-
});
|
|
5288
|
-
} else {
|
|
5289
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5290
|
-
}
|
|
4544
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5291
4545
|
let relationships = Object.create(null);
|
|
5292
4546
|
let modelName = this.modelName;
|
|
5293
4547
|
this.eachComputedProperty((name, meta) => {
|
|
@@ -5295,7 +4549,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5295
4549
|
meta.key = name;
|
|
5296
4550
|
meta.name = name;
|
|
5297
4551
|
meta.parentModelName = modelName;
|
|
5298
|
-
relationships[name] =
|
|
4552
|
+
relationships[name] = meta;
|
|
4553
|
+
assert(`You should not specify both options.as and options.inverse as null on ${modelName}.${meta.name}, as if there is no inverse field there is no abstract type to conform to. You may have intended for this relationship to be polymorphic, or you may have mistakenly set inverse to null.`, !(meta.options.inverse === null && meta.options.as?.length > 0));
|
|
5299
4554
|
}
|
|
5300
4555
|
});
|
|
5301
4556
|
return relationships;
|
|
@@ -5335,19 +4590,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5335
4590
|
@readOnly
|
|
5336
4591
|
*/
|
|
5337
4592
|
static get fields() {
|
|
5338
|
-
|
|
5339
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5340
|
-
id: 'ember-data:deprecate-early-static',
|
|
5341
|
-
for: 'ember-data',
|
|
5342
|
-
until: '5.0',
|
|
5343
|
-
since: {
|
|
5344
|
-
available: '4.7',
|
|
5345
|
-
enabled: '4.7'
|
|
5346
|
-
}
|
|
5347
|
-
});
|
|
5348
|
-
} else {
|
|
5349
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5350
|
-
}
|
|
4593
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5351
4594
|
let map = new Map();
|
|
5352
4595
|
this.eachComputedProperty((name, meta) => {
|
|
5353
4596
|
// TODO end reliance on these booleans and stop leaking them in the spec
|
|
@@ -5371,19 +4614,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5371
4614
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
5372
4615
|
*/
|
|
5373
4616
|
static eachRelationship(callback, binding) {
|
|
5374
|
-
|
|
5375
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5376
|
-
id: 'ember-data:deprecate-early-static',
|
|
5377
|
-
for: 'ember-data',
|
|
5378
|
-
until: '5.0',
|
|
5379
|
-
since: {
|
|
5380
|
-
available: '4.7',
|
|
5381
|
-
enabled: '4.7'
|
|
5382
|
-
}
|
|
5383
|
-
});
|
|
5384
|
-
} else {
|
|
5385
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5386
|
-
}
|
|
4617
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5387
4618
|
this.relationshipsByName.forEach((relationship, name) => {
|
|
5388
4619
|
callback.call(binding, name, relationship);
|
|
5389
4620
|
});
|
|
@@ -5401,19 +4632,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5401
4632
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
5402
4633
|
*/
|
|
5403
4634
|
static eachRelatedType(callback, binding) {
|
|
5404
|
-
|
|
5405
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5406
|
-
id: 'ember-data:deprecate-early-static',
|
|
5407
|
-
for: 'ember-data',
|
|
5408
|
-
until: '5.0',
|
|
5409
|
-
since: {
|
|
5410
|
-
available: '4.7',
|
|
5411
|
-
enabled: '4.7'
|
|
5412
|
-
}
|
|
5413
|
-
});
|
|
5414
|
-
} else {
|
|
5415
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5416
|
-
}
|
|
4635
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5417
4636
|
let relationshipTypes = this.relatedTypes;
|
|
5418
4637
|
for (let i = 0; i < relationshipTypes.length; i++) {
|
|
5419
4638
|
let type = relationshipTypes[i];
|
|
@@ -5421,19 +4640,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5421
4640
|
}
|
|
5422
4641
|
}
|
|
5423
4642
|
static determineRelationshipType(knownSide, store) {
|
|
5424
|
-
|
|
5425
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5426
|
-
id: 'ember-data:deprecate-early-static',
|
|
5427
|
-
for: 'ember-data',
|
|
5428
|
-
until: '5.0',
|
|
5429
|
-
since: {
|
|
5430
|
-
available: '4.7',
|
|
5431
|
-
enabled: '4.7'
|
|
5432
|
-
}
|
|
5433
|
-
});
|
|
5434
|
-
} else {
|
|
5435
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5436
|
-
}
|
|
4643
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5437
4644
|
let knownKey = knownSide.key;
|
|
5438
4645
|
let knownKind = knownSide.kind;
|
|
5439
4646
|
let inverse = this.inverseFor(knownKey, store);
|
|
@@ -5484,19 +4691,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5484
4691
|
@readOnly
|
|
5485
4692
|
*/
|
|
5486
4693
|
static get attributes() {
|
|
5487
|
-
|
|
5488
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5489
|
-
id: 'ember-data:deprecate-early-static',
|
|
5490
|
-
for: 'ember-data',
|
|
5491
|
-
until: '5.0',
|
|
5492
|
-
since: {
|
|
5493
|
-
available: '4.7',
|
|
5494
|
-
enabled: '4.7'
|
|
5495
|
-
}
|
|
5496
|
-
});
|
|
5497
|
-
} else {
|
|
5498
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5499
|
-
}
|
|
4694
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5500
4695
|
let map = new Map();
|
|
5501
4696
|
this.eachComputedProperty((name, meta) => {
|
|
5502
4697
|
if (meta.isAttribute) {
|
|
@@ -5540,19 +4735,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5540
4735
|
@readOnly
|
|
5541
4736
|
*/
|
|
5542
4737
|
static get transformedAttributes() {
|
|
5543
|
-
|
|
5544
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5545
|
-
id: 'ember-data:deprecate-early-static',
|
|
5546
|
-
for: 'ember-data',
|
|
5547
|
-
until: '5.0',
|
|
5548
|
-
since: {
|
|
5549
|
-
available: '4.7',
|
|
5550
|
-
enabled: '4.7'
|
|
5551
|
-
}
|
|
5552
|
-
});
|
|
5553
|
-
} else {
|
|
5554
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5555
|
-
}
|
|
4738
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5556
4739
|
let map = new Map();
|
|
5557
4740
|
this.eachAttribute((key, meta) => {
|
|
5558
4741
|
if (meta.type) {
|
|
@@ -5597,19 +4780,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5597
4780
|
@static
|
|
5598
4781
|
*/
|
|
5599
4782
|
static eachAttribute(callback, binding) {
|
|
5600
|
-
|
|
5601
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5602
|
-
id: 'ember-data:deprecate-early-static',
|
|
5603
|
-
for: 'ember-data',
|
|
5604
|
-
until: '5.0',
|
|
5605
|
-
since: {
|
|
5606
|
-
available: '4.7',
|
|
5607
|
-
enabled: '4.7'
|
|
5608
|
-
}
|
|
5609
|
-
});
|
|
5610
|
-
} else {
|
|
5611
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5612
|
-
}
|
|
4783
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5613
4784
|
this.attributes.forEach((meta, name) => {
|
|
5614
4785
|
callback.call(binding, name, meta);
|
|
5615
4786
|
});
|
|
@@ -5651,19 +4822,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5651
4822
|
@static
|
|
5652
4823
|
*/
|
|
5653
4824
|
static eachTransformedAttribute(callback, binding) {
|
|
5654
|
-
|
|
5655
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5656
|
-
id: 'ember-data:deprecate-early-static',
|
|
5657
|
-
for: 'ember-data',
|
|
5658
|
-
until: '5.0',
|
|
5659
|
-
since: {
|
|
5660
|
-
available: '4.7',
|
|
5661
|
-
enabled: '4.7'
|
|
5662
|
-
}
|
|
5663
|
-
});
|
|
5664
|
-
} else {
|
|
5665
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5666
|
-
}
|
|
4825
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5667
4826
|
this.transformedAttributes.forEach((type, name) => {
|
|
5668
4827
|
callback.call(binding, name, type);
|
|
5669
4828
|
});
|
|
@@ -5676,19 +4835,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5676
4835
|
@static
|
|
5677
4836
|
*/
|
|
5678
4837
|
static toString() {
|
|
5679
|
-
|
|
5680
|
-
deprecate(`Accessing schema information on Models without looking up the model via the store is deprecated. Use store.modelFor (or better Snapshots or the store.getSchemaDefinitionService() apis) instead.`, this.modelName, {
|
|
5681
|
-
id: 'ember-data:deprecate-early-static',
|
|
5682
|
-
for: 'ember-data',
|
|
5683
|
-
until: '5.0',
|
|
5684
|
-
since: {
|
|
5685
|
-
available: '4.7',
|
|
5686
|
-
enabled: '4.7'
|
|
5687
|
-
}
|
|
5688
|
-
});
|
|
5689
|
-
} else {
|
|
5690
|
-
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5691
|
-
}
|
|
4838
|
+
assert(`Accessing schema information on Models without looking up the model via the store is disallowed.`, this.modelName);
|
|
5692
4839
|
return `model:${this.modelName}`;
|
|
5693
4840
|
}
|
|
5694
4841
|
}, _class2.isModel = true, _class2.modelName = null, _class2), (_applyDecoratedDescriptor(_class.prototype, "isEmpty", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isEmpty"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isLoading", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isLoading"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isLoaded", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isLoaded"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "hasDirtyAttributes", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "hasDirtyAttributes"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isSaving", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isSaving"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isDeleted", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isDeleted"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isNew", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isNew"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isValid", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isValid"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "dirtyType", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "dirtyType"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "isError", [dependentKeyCompat], Object.getOwnPropertyDescriptor(_class.prototype, "isError"), _class.prototype), _descriptor = _applyDecoratedDescriptor(_class.prototype, "isReloading", [tracked], {
|
|
@@ -5702,7 +4849,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5702
4849
|
// the values initialized during create to `setUnknownProperty`
|
|
5703
4850
|
Model.prototype._createProps = null;
|
|
5704
4851
|
Model.prototype._secretInit = null;
|
|
5705
|
-
if (getOwnConfig().includeDataAdapter) {
|
|
4852
|
+
if (macroCondition(getOwnConfig().includeDataAdapter)) {
|
|
5706
4853
|
/**
|
|
5707
4854
|
Provides info about the model for debugging purposes
|
|
5708
4855
|
by grouping the properties into more semantic groups.
|
|
@@ -5717,16 +4864,21 @@ if (getOwnConfig().includeDataAdapter) {
|
|
|
5717
4864
|
@private
|
|
5718
4865
|
*/
|
|
5719
4866
|
Model.prototype._debugInfo = function () {
|
|
5720
|
-
let attributes = ['id'];
|
|
5721
4867
|
let relationships = {};
|
|
5722
4868
|
let expensiveProperties = [];
|
|
5723
|
-
|
|
4869
|
+
const identifier = recordIdentifierFor(this);
|
|
4870
|
+
const schema = this.store.getSchemaDefinitionService();
|
|
4871
|
+
const attrDefs = schema.attributesDefinitionFor(identifier);
|
|
4872
|
+
const relDefs = schema.relationshipsDefinitionFor(identifier);
|
|
4873
|
+
const attributes = Object.keys(attrDefs);
|
|
4874
|
+
attributes.unshift('id');
|
|
5724
4875
|
let groups = [{
|
|
5725
4876
|
name: 'Attributes',
|
|
5726
4877
|
properties: attributes,
|
|
5727
4878
|
expand: true
|
|
5728
4879
|
}];
|
|
5729
|
-
|
|
4880
|
+
Object.keys(relDefs).forEach(name => {
|
|
4881
|
+
const relationship = relDefs[name];
|
|
5730
4882
|
let properties = relationships[relationship.kind];
|
|
5731
4883
|
if (properties === undefined) {
|
|
5732
4884
|
properties = relationships[relationship.kind] = [];
|
|
@@ -5754,7 +4906,7 @@ if (getOwnConfig().includeDataAdapter) {
|
|
|
5754
4906
|
};
|
|
5755
4907
|
};
|
|
5756
4908
|
}
|
|
5757
|
-
if (macroCondition(
|
|
4909
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5758
4910
|
let lookupDescriptor = function lookupDescriptor(obj, keyName) {
|
|
5759
4911
|
let current = obj;
|
|
5760
4912
|
do {
|
|
@@ -5782,41 +4934,14 @@ if (macroCondition(isDevelopingApp())) {
|
|
|
5782
4934
|
}
|
|
5783
4935
|
}
|
|
5784
4936
|
});
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
for: 'ember-data',
|
|
5792
|
-
until: '5.0',
|
|
5793
|
-
since: {
|
|
5794
|
-
available: '4.7',
|
|
5795
|
-
enabled: '4.7'
|
|
5796
|
-
}
|
|
5797
|
-
});
|
|
5798
|
-
return originalReopen.call(this, ...arguments);
|
|
5799
|
-
};
|
|
5800
|
-
Model.reopenClass = function deprecatedReopenClass() {
|
|
5801
|
-
deprecate(`Model.reopenClass is deprecated. Use Foo extends Model to add static methods and properties to your class instead.`, false, {
|
|
5802
|
-
id: 'ember-data:deprecate-model-reopenclass',
|
|
5803
|
-
for: 'ember-data',
|
|
5804
|
-
until: '5.0',
|
|
5805
|
-
since: {
|
|
5806
|
-
available: '4.7',
|
|
5807
|
-
enabled: '4.7'
|
|
5808
|
-
}
|
|
5809
|
-
});
|
|
5810
|
-
return originalReopenClass.call(this, ...arguments);
|
|
5811
|
-
};
|
|
5812
|
-
}
|
|
4937
|
+
Model.reopen = function deprecatedReopen() {
|
|
4938
|
+
assert(`Model.reopen is deprecated. Use Foo extends Model to extend your class instead.`);
|
|
4939
|
+
};
|
|
4940
|
+
Model.reopenClass = function deprecatedReopenClass() {
|
|
4941
|
+
assert(`Model.reopenClass is deprecated. Use Foo extends Model to add static methods and properties to your class instead.`);
|
|
4942
|
+
};
|
|
5813
4943
|
}
|
|
5814
4944
|
function normalizeType$1(type) {
|
|
5815
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE)) {
|
|
5816
|
-
if (!type) {
|
|
5817
|
-
return;
|
|
5818
|
-
}
|
|
5819
|
-
}
|
|
5820
4945
|
return dasherize(type);
|
|
5821
4946
|
}
|
|
5822
4947
|
/**
|
|
@@ -5857,6 +4982,7 @@ function normalizeType$1(type) {
|
|
|
5857
4982
|
```
|
|
5858
4983
|
|
|
5859
4984
|
#### One-To-Many
|
|
4985
|
+
|
|
5860
4986
|
To declare a one-to-many relationship between two models, use
|
|
5861
4987
|
`belongsTo` in combination with `hasMany`, like this:
|
|
5862
4988
|
|
|
@@ -5864,7 +4990,7 @@ function normalizeType$1(type) {
|
|
|
5864
4990
|
import Model, { hasMany } from '@ember-data/model';
|
|
5865
4991
|
|
|
5866
4992
|
export default class PostModel extends Model {
|
|
5867
|
-
@hasMany('comment') comments;
|
|
4993
|
+
@hasMany('comment', { async: false, inverse: 'post' }) comments;
|
|
5868
4994
|
}
|
|
5869
4995
|
```
|
|
5870
4996
|
|
|
@@ -5872,23 +4998,10 @@ function normalizeType$1(type) {
|
|
|
5872
4998
|
import Model, { belongsTo } from '@ember-data/model';
|
|
5873
4999
|
|
|
5874
5000
|
export default class CommentModel extends Model {
|
|
5875
|
-
@belongsTo('post') post;
|
|
5876
|
-
}
|
|
5877
|
-
```
|
|
5878
|
-
|
|
5879
|
-
You can avoid passing a string as the first parameter. In that case Ember Data
|
|
5880
|
-
will infer the type from the key name.
|
|
5881
|
-
|
|
5882
|
-
```app/models/comment.js
|
|
5883
|
-
import Model, { belongsTo } from '@ember-data/model';
|
|
5884
|
-
|
|
5885
|
-
export default class CommentModel extends Model {
|
|
5886
|
-
@belongsTo post;
|
|
5001
|
+
@belongsTo('post', { async: false, inverse: 'comments' }) post;
|
|
5887
5002
|
}
|
|
5888
5003
|
```
|
|
5889
5004
|
|
|
5890
|
-
will lookup for a Post type.
|
|
5891
|
-
|
|
5892
5005
|
#### Sync relationships
|
|
5893
5006
|
|
|
5894
5007
|
Ember Data resolves sync relationships with the related resources
|
|
@@ -5900,7 +5013,8 @@ function normalizeType$1(type) {
|
|
|
5900
5013
|
|
|
5901
5014
|
export default class CommentModel extends Model {
|
|
5902
5015
|
@belongsTo('post', {
|
|
5903
|
-
async: false
|
|
5016
|
+
async: false,
|
|
5017
|
+
inverse: null
|
|
5904
5018
|
})
|
|
5905
5019
|
post;
|
|
5906
5020
|
}
|
|
@@ -5927,65 +5041,8 @@ function normalizeType$1(type) {
|
|
|
5927
5041
|
function belongsTo(modelName, options) {
|
|
5928
5042
|
let opts = options;
|
|
5929
5043
|
let userEnteredModelName = modelName;
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
deprecate('belongsTo() must specify the string type of the related resource as the first parameter', false, {
|
|
5933
|
-
id: 'ember-data:deprecate-non-strict-relationships',
|
|
5934
|
-
for: 'ember-data',
|
|
5935
|
-
until: '5.0',
|
|
5936
|
-
since: {
|
|
5937
|
-
enabled: '4.7',
|
|
5938
|
-
available: '4.7'
|
|
5939
|
-
}
|
|
5940
|
-
});
|
|
5941
|
-
if (typeof modelName === 'object') {
|
|
5942
|
-
opts = modelName;
|
|
5943
|
-
userEnteredModelName = undefined;
|
|
5944
|
-
} else {
|
|
5945
|
-
opts = options;
|
|
5946
|
-
userEnteredModelName = modelName;
|
|
5947
|
-
}
|
|
5948
|
-
assert('The first argument to belongsTo must be a string representing a model type key, not an instance of ' + typeof userEnteredModelName + ". E.g., to define a relation to the Person model, use belongsTo('person')", typeof userEnteredModelName === 'string' || typeof userEnteredModelName === 'undefined');
|
|
5949
|
-
}
|
|
5950
|
-
}
|
|
5951
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC)) {
|
|
5952
|
-
if (!opts || typeof opts.async !== 'boolean') {
|
|
5953
|
-
opts = opts || {};
|
|
5954
|
-
if (!('async' in opts)) {
|
|
5955
|
-
opts.async = true;
|
|
5956
|
-
}
|
|
5957
|
-
deprecate('belongsTo(<type>, <options>) must specify options.async as either `true` or `false`.', false, {
|
|
5958
|
-
id: 'ember-data:deprecate-non-strict-relationships',
|
|
5959
|
-
for: 'ember-data',
|
|
5960
|
-
until: '5.0',
|
|
5961
|
-
since: {
|
|
5962
|
-
enabled: '4.7',
|
|
5963
|
-
available: '4.7'
|
|
5964
|
-
}
|
|
5965
|
-
});
|
|
5966
|
-
} else {
|
|
5967
|
-
assert(`Expected belongsTo options.async to be a boolean`, opts && typeof opts.async === 'boolean');
|
|
5968
|
-
}
|
|
5969
|
-
} else {
|
|
5970
|
-
assert(`Expected belongsTo options.async to be a boolean`, opts && typeof opts.async === 'boolean');
|
|
5971
|
-
}
|
|
5972
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE)) {
|
|
5973
|
-
if (opts.inverse !== null && (typeof opts.inverse !== 'string' || opts.inverse.length === 0)) {
|
|
5974
|
-
deprecate('belongsTo(<type>, <options>) must specify options.inverse as either `null` or the name of the field on the related resource type.', false, {
|
|
5975
|
-
id: 'ember-data:deprecate-non-strict-relationships',
|
|
5976
|
-
for: 'ember-data',
|
|
5977
|
-
until: '5.0',
|
|
5978
|
-
since: {
|
|
5979
|
-
enabled: '4.7',
|
|
5980
|
-
available: '4.7'
|
|
5981
|
-
}
|
|
5982
|
-
});
|
|
5983
|
-
} else {
|
|
5984
|
-
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);
|
|
5985
|
-
}
|
|
5986
|
-
} else {
|
|
5987
|
-
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);
|
|
5988
|
-
}
|
|
5044
|
+
assert(`Expected belongsTo options.async to be a boolean`, opts && typeof opts.async === 'boolean');
|
|
5045
|
+
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);
|
|
5989
5046
|
let meta = {
|
|
5990
5047
|
type: normalizeType$1(userEnteredModelName),
|
|
5991
5048
|
isRelationship: true,
|
|
@@ -6003,7 +5060,7 @@ function belongsTo(modelName, options) {
|
|
|
6003
5060
|
return null;
|
|
6004
5061
|
}
|
|
6005
5062
|
const support = lookupLegacySupport(this);
|
|
6006
|
-
if (macroCondition(
|
|
5063
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6007
5064
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6008
5065
|
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()}`);
|
|
6009
5066
|
}
|
|
@@ -6022,7 +5079,7 @@ function belongsTo(modelName, options) {
|
|
|
6022
5079
|
},
|
|
6023
5080
|
set(key, value) {
|
|
6024
5081
|
const support = lookupLegacySupport(this);
|
|
6025
|
-
if (macroCondition(
|
|
5082
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6026
5083
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6027
5084
|
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()}`);
|
|
6028
5085
|
}
|
|
@@ -6036,11 +5093,6 @@ function belongsTo(modelName, options) {
|
|
|
6036
5093
|
}
|
|
6037
5094
|
var belongsTo$1 = computedMacroWithOptionalParams(belongsTo);
|
|
6038
5095
|
function normalizeType(type) {
|
|
6039
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_TYPE)) {
|
|
6040
|
-
if (!type) {
|
|
6041
|
-
return;
|
|
6042
|
-
}
|
|
6043
|
-
}
|
|
6044
5096
|
return singularize(dasherize(type));
|
|
6045
5097
|
}
|
|
6046
5098
|
|
|
@@ -6186,58 +5238,7 @@ function normalizeType(type) {
|
|
|
6186
5238
|
@return {Ember.computed} relationship
|
|
6187
5239
|
*/
|
|
6188
5240
|
function hasMany(type, options) {
|
|
6189
|
-
|
|
6190
|
-
if (typeof type !== 'string' || !type.length) {
|
|
6191
|
-
deprecate('hasMany(<type>, <options>) must specify the string type of the related resource as the first parameter', false, {
|
|
6192
|
-
id: 'ember-data:deprecate-non-strict-relationships',
|
|
6193
|
-
for: 'ember-data',
|
|
6194
|
-
until: '5.0',
|
|
6195
|
-
since: {
|
|
6196
|
-
enabled: '4.7',
|
|
6197
|
-
available: '4.7'
|
|
6198
|
-
}
|
|
6199
|
-
});
|
|
6200
|
-
if (typeof type === 'object') {
|
|
6201
|
-
options = type;
|
|
6202
|
-
type = undefined;
|
|
6203
|
-
}
|
|
6204
|
-
assert(`The first argument to hasMany must be a string representing a model type key, not an instance of ${inspect(type)}. E.g., to define a relation to the Comment model, use hasMany('comment')`, typeof type === 'string' || typeof type === 'undefined');
|
|
6205
|
-
}
|
|
6206
|
-
}
|
|
6207
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_ASYNC)) {
|
|
6208
|
-
if (!options || typeof options.async !== 'boolean') {
|
|
6209
|
-
options = options || {};
|
|
6210
|
-
if (!('async' in options)) {
|
|
6211
|
-
options.async = true;
|
|
6212
|
-
}
|
|
6213
|
-
deprecate('hasMany(<type>, <options>) must specify options.async as either `true` or `false`.', false, {
|
|
6214
|
-
id: 'ember-data:deprecate-non-strict-relationships',
|
|
6215
|
-
for: 'ember-data',
|
|
6216
|
-
until: '5.0',
|
|
6217
|
-
since: {
|
|
6218
|
-
enabled: '4.7',
|
|
6219
|
-
available: '4.7'
|
|
6220
|
-
}
|
|
6221
|
-
});
|
|
6222
|
-
} else {
|
|
6223
|
-
assert(`Expected hasMany options.async to be a boolean`, options && typeof options.async === 'boolean');
|
|
6224
|
-
}
|
|
6225
|
-
} else {
|
|
6226
|
-
assert(`Expected hasMany options.async to be a boolean`, options && typeof options.async === 'boolean');
|
|
6227
|
-
}
|
|
6228
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE)) {
|
|
6229
|
-
if (options.inverse !== null && (typeof options.inverse !== 'string' || options.inverse.length === 0)) {
|
|
6230
|
-
deprecate('hasMany(<type>, <options>) must specify options.inverse as either `null` or the name of the field on the related resource type.', false, {
|
|
6231
|
-
id: 'ember-data:deprecate-non-strict-relationships',
|
|
6232
|
-
for: 'ember-data',
|
|
6233
|
-
until: '5.0',
|
|
6234
|
-
since: {
|
|
6235
|
-
enabled: '4.7',
|
|
6236
|
-
available: '4.7'
|
|
6237
|
-
}
|
|
6238
|
-
});
|
|
6239
|
-
}
|
|
6240
|
-
}
|
|
5241
|
+
assert(`Expected hasMany options.async to be a boolean`, options && typeof options.async === 'boolean');
|
|
6241
5242
|
|
|
6242
5243
|
// Metadata about relationships is stored on the meta of
|
|
6243
5244
|
// the relationship. This is used for introspection and
|
|
@@ -6253,7 +5254,7 @@ function hasMany(type, options) {
|
|
|
6253
5254
|
};
|
|
6254
5255
|
return computed({
|
|
6255
5256
|
get(key) {
|
|
6256
|
-
if (macroCondition(
|
|
5257
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6257
5258
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6258
5259
|
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()}`);
|
|
6259
5260
|
}
|
|
@@ -6264,7 +5265,7 @@ function hasMany(type, options) {
|
|
|
6264
5265
|
return lookupLegacySupport(this).getHasMany(key);
|
|
6265
5266
|
},
|
|
6266
5267
|
set(key, records) {
|
|
6267
|
-
if (macroCondition(
|
|
5268
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6268
5269
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6269
5270
|
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()}`);
|
|
6270
5271
|
}
|