@ember-data/model 4.12.0-beta.2 → 4.12.0-beta.4
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/addon/-private.js +2 -2
- package/addon/{has-many-26353d30.js → has-many-f4cb2303.js} +208 -565
- package/addon/has-many-f4cb2303.js.map +1 -0
- package/addon/index.js +1 -1
- package/addon-main.js +18 -15
- package/package.json +15 -14
- package/addon/has-many-26353d30.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { macroCondition,
|
|
1
|
+
import { macroCondition, getOwnConfig, importSync } from '@embroider/macros';
|
|
2
2
|
import { assert, deprecate, warn, inspect } 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
7
|
import ArrayMixin, { A, NativeArray } from '@ember/array';
|
|
8
8
|
import { singularize } from 'ember-inflector';
|
|
@@ -10,7 +10,6 @@ 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
13
|
import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
15
14
|
import ObjectProxy from '@ember/object/proxy';
|
|
16
15
|
import ArrayProxy from '@ember/array/proxy';
|
|
@@ -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
|
|
@@ -214,7 +215,7 @@ function _applyDecoratedDescriptor(target, property, decorators, descriptor, con
|
|
|
214
215
|
const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
|
|
215
216
|
function promiseObject(promise) {
|
|
216
217
|
return PromiseObject.create({
|
|
217
|
-
promise
|
|
218
|
+
promise
|
|
218
219
|
});
|
|
219
220
|
}
|
|
220
221
|
|
|
@@ -225,7 +226,7 @@ const PROXIED_OBJECT_PROPS = ['content', 'isPending', 'isSettled', 'isRejected',
|
|
|
225
226
|
const ProxySymbolString = String(Symbol.for('PROXY_CONTENT'));
|
|
226
227
|
function deprecatedPromiseObject(promise) {
|
|
227
228
|
const promiseObjectProxy = promiseObject(promise);
|
|
228
|
-
if (macroCondition(!
|
|
229
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
229
230
|
return promiseObjectProxy;
|
|
230
231
|
}
|
|
231
232
|
const handler = {
|
|
@@ -632,384 +633,6 @@ let Errors = (_dec$1 = computed(), _dec2 = mapBy('content', 'message'), _dec3 =
|
|
|
632
633
|
writable: true,
|
|
633
634
|
initializer: null
|
|
634
635
|
})), _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
636
|
|
|
1014
637
|
/**
|
|
1015
638
|
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
@@ -1118,7 +741,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1118
741
|
switch (prop) {
|
|
1119
742
|
case 'length 0':
|
|
1120
743
|
{
|
|
1121
|
-
this._manager.
|
|
744
|
+
this._manager.mutate({
|
|
1122
745
|
op: 'replaceRelatedRecords',
|
|
1123
746
|
record: this.identifier,
|
|
1124
747
|
field: this.key,
|
|
@@ -1129,7 +752,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1129
752
|
case 'replace cell':
|
|
1130
753
|
{
|
|
1131
754
|
const [index, prior, value] = args;
|
|
1132
|
-
this._manager.
|
|
755
|
+
this._manager.mutate({
|
|
1133
756
|
op: 'replaceRelatedRecord',
|
|
1134
757
|
record: this.identifier,
|
|
1135
758
|
field: this.key,
|
|
@@ -1140,7 +763,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1140
763
|
break;
|
|
1141
764
|
}
|
|
1142
765
|
case 'push':
|
|
1143
|
-
this._manager.
|
|
766
|
+
this._manager.mutate({
|
|
1144
767
|
op: 'addToRelatedRecords',
|
|
1145
768
|
record: this.identifier,
|
|
1146
769
|
field: this.key,
|
|
@@ -1149,7 +772,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1149
772
|
break;
|
|
1150
773
|
case 'pop':
|
|
1151
774
|
if (result) {
|
|
1152
|
-
this._manager.
|
|
775
|
+
this._manager.mutate({
|
|
1153
776
|
op: 'removeFromRelatedRecords',
|
|
1154
777
|
record: this.identifier,
|
|
1155
778
|
field: this.key,
|
|
@@ -1158,7 +781,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1158
781
|
}
|
|
1159
782
|
break;
|
|
1160
783
|
case 'unshift':
|
|
1161
|
-
this._manager.
|
|
784
|
+
this._manager.mutate({
|
|
1162
785
|
op: 'addToRelatedRecords',
|
|
1163
786
|
record: this.identifier,
|
|
1164
787
|
field: this.key,
|
|
@@ -1168,7 +791,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1168
791
|
break;
|
|
1169
792
|
case 'shift':
|
|
1170
793
|
if (result) {
|
|
1171
|
-
this._manager.
|
|
794
|
+
this._manager.mutate({
|
|
1172
795
|
op: 'removeFromRelatedRecords',
|
|
1173
796
|
record: this.identifier,
|
|
1174
797
|
field: this.key,
|
|
@@ -1178,7 +801,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1178
801
|
}
|
|
1179
802
|
break;
|
|
1180
803
|
case 'sort':
|
|
1181
|
-
this._manager.
|
|
804
|
+
this._manager.mutate({
|
|
1182
805
|
op: 'sortRelatedRecords',
|
|
1183
806
|
record: this.identifier,
|
|
1184
807
|
field: this.key,
|
|
@@ -1190,7 +813,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1190
813
|
const [start, removeCount, ...adds] = args;
|
|
1191
814
|
// detect a full replace
|
|
1192
815
|
if (removeCount > 0 && adds.length === this[SOURCE].length) {
|
|
1193
|
-
this._manager.
|
|
816
|
+
this._manager.mutate({
|
|
1194
817
|
op: 'replaceRelatedRecords',
|
|
1195
818
|
record: this.identifier,
|
|
1196
819
|
field: this.key,
|
|
@@ -1199,7 +822,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1199
822
|
return;
|
|
1200
823
|
}
|
|
1201
824
|
if (removeCount > 0) {
|
|
1202
|
-
this._manager.
|
|
825
|
+
this._manager.mutate({
|
|
1203
826
|
op: 'removeFromRelatedRecords',
|
|
1204
827
|
record: this.identifier,
|
|
1205
828
|
field: this.key,
|
|
@@ -1208,7 +831,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1208
831
|
});
|
|
1209
832
|
}
|
|
1210
833
|
if (adds?.length) {
|
|
1211
|
-
this._manager.
|
|
834
|
+
this._manager.mutate({
|
|
1212
835
|
op: 'addToRelatedRecords',
|
|
1213
836
|
record: this.identifier,
|
|
1214
837
|
field: this.key,
|
|
@@ -1278,6 +901,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1278
901
|
const {
|
|
1279
902
|
store
|
|
1280
903
|
} = this;
|
|
904
|
+
assert(`Expected modelName to be set`, this.modelName);
|
|
1281
905
|
const record = store.createRecord(this.modelName, hash);
|
|
1282
906
|
this.push(record);
|
|
1283
907
|
return record;
|
|
@@ -1286,7 +910,7 @@ class RelatedCollection extends RecordArray {
|
|
|
1286
910
|
RelatedCollection.prototype.isAsync = false;
|
|
1287
911
|
RelatedCollection.prototype.isPolymorphic = false;
|
|
1288
912
|
RelatedCollection.prototype.identifier = null;
|
|
1289
|
-
RelatedCollection.prototype.
|
|
913
|
+
RelatedCollection.prototype.cache = null;
|
|
1290
914
|
RelatedCollection.prototype._inverseIsAsync = false;
|
|
1291
915
|
RelatedCollection.prototype.key = '';
|
|
1292
916
|
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
@@ -1430,7 +1054,7 @@ let PromiseManyArray = (_class$4 = class PromiseManyArray {
|
|
|
1430
1054
|
}
|
|
1431
1055
|
return false;
|
|
1432
1056
|
};
|
|
1433
|
-
} else if (macroCondition(
|
|
1057
|
+
} else if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
1434
1058
|
const meta = Ember.meta(this);
|
|
1435
1059
|
meta.hasMixin = mixin => {
|
|
1436
1060
|
assert(`Do not use A() on an EmberData PromiseManyArray`);
|
|
@@ -1652,7 +1276,7 @@ function tapPromise(proxy, promise) {
|
|
|
1652
1276
|
proxy.isSettled = false;
|
|
1653
1277
|
proxy.isFulfilled = false;
|
|
1654
1278
|
proxy.isRejected = false;
|
|
1655
|
-
return resolve(promise).then(content => {
|
|
1279
|
+
return Promise.resolve(promise).then(content => {
|
|
1656
1280
|
proxy.isPending = false;
|
|
1657
1281
|
proxy.isFulfilled = true;
|
|
1658
1282
|
proxy.isSettled = true;
|
|
@@ -1715,7 +1339,7 @@ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_MANY_ARRAY_BEHA
|
|
|
1715
1339
|
`record.relationshipFor(key)`.
|
|
1716
1340
|
*/
|
|
1717
1341
|
let assertPolymorphicType;
|
|
1718
|
-
if (macroCondition(
|
|
1342
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
1719
1343
|
let checkPolymorphic = function checkPolymorphic(modelClass, addedModelClass) {
|
|
1720
1344
|
if (modelClass.__isMixin) {
|
|
1721
1345
|
return modelClass.__mixin.detect(addedModelClass.PrototypeMixin) ||
|
|
@@ -1967,7 +1591,8 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1967
1591
|
}
|
|
1968
1592
|
_resource() {
|
|
1969
1593
|
this._ref; // subscribe
|
|
1970
|
-
|
|
1594
|
+
const cache = macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA) ? this.store._instanceCache.getResourceCache(this.___identifier) : this.store.cache;
|
|
1595
|
+
return cache.getRelationship(this.___identifier, this.key);
|
|
1971
1596
|
}
|
|
1972
1597
|
|
|
1973
1598
|
/**
|
|
@@ -2057,7 +1682,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
2057
1682
|
let jsonApiDoc = data;
|
|
2058
1683
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
2059
1684
|
if (data.then) {
|
|
2060
|
-
jsonApiDoc = await
|
|
1685
|
+
jsonApiDoc = await data;
|
|
2061
1686
|
if (jsonApiDoc !== data) {
|
|
2062
1687
|
deprecate(`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`, false, {
|
|
2063
1688
|
id: 'ember-data:deprecate-promise-proxies',
|
|
@@ -2072,7 +1697,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
2072
1697
|
}
|
|
2073
1698
|
}
|
|
2074
1699
|
let record = this.store.push(jsonApiDoc);
|
|
2075
|
-
if (macroCondition(
|
|
1700
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
2076
1701
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
2077
1702
|
assertPolymorphicType(this.belongsToRelationship.identifier, this.belongsToRelationship.definition, recordIdentifierFor$1(record), this.store);
|
|
2078
1703
|
}
|
|
@@ -2332,7 +1957,8 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2332
1957
|
return [];
|
|
2333
1958
|
}
|
|
2334
1959
|
_resource() {
|
|
2335
|
-
|
|
1960
|
+
const cache = macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA) ? this.store._instanceCache.getResourceCache(this.___identifier) : this.store.cache;
|
|
1961
|
+
return cache.getRelationship(this.___identifier, this.key);
|
|
2336
1962
|
}
|
|
2337
1963
|
|
|
2338
1964
|
/**
|
|
@@ -2549,7 +2175,7 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2549
2175
|
let payload = objectOrPromise;
|
|
2550
2176
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
2551
2177
|
if (objectOrPromise.then) {
|
|
2552
|
-
payload = await
|
|
2178
|
+
payload = await objectOrPromise;
|
|
2553
2179
|
if (payload !== objectOrPromise) {
|
|
2554
2180
|
deprecate(`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`, false, {
|
|
2555
2181
|
id: 'ember-data:deprecate-promise-proxies',
|
|
@@ -2582,7 +2208,7 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2582
2208
|
data: obj
|
|
2583
2209
|
});
|
|
2584
2210
|
}
|
|
2585
|
-
if (macroCondition(
|
|
2211
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
2586
2212
|
let relationshipMeta = this.hasManyRelationship.definition;
|
|
2587
2213
|
let identifier = this.hasManyRelationship.identifier;
|
|
2588
2214
|
|
|
@@ -2775,9 +2401,9 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2775
2401
|
class LegacySupport {
|
|
2776
2402
|
constructor(record) {
|
|
2777
2403
|
this.record = record;
|
|
2778
|
-
this.store = storeFor
|
|
2404
|
+
this.store = storeFor(record);
|
|
2779
2405
|
this.identifier = recordIdentifierFor$1(record);
|
|
2780
|
-
this.
|
|
2406
|
+
this.cache = peekCache(record);
|
|
2781
2407
|
this._manyArrayCache = Object.create(null);
|
|
2782
2408
|
this._relationshipPromisesCache = Object.create(null);
|
|
2783
2409
|
this._relationshipProxyCache = Object.create(null);
|
|
@@ -2800,8 +2426,8 @@ class LegacySupport {
|
|
|
2800
2426
|
currentState.length = 0;
|
|
2801
2427
|
fastPush(currentState, identifiers);
|
|
2802
2428
|
}
|
|
2803
|
-
|
|
2804
|
-
this.
|
|
2429
|
+
mutate(mutation) {
|
|
2430
|
+
this.cache.mutate(mutation);
|
|
2805
2431
|
}
|
|
2806
2432
|
_findBelongsTo(key, resource, relationship, options) {
|
|
2807
2433
|
// TODO @runspired follow up if parent isNew then we should not be attempting load here
|
|
@@ -2816,7 +2442,7 @@ class LegacySupport {
|
|
|
2816
2442
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
2817
2443
|
const relationship = graphFor(this.store).get(this.identifier, key);
|
|
2818
2444
|
assert(`Expected ${key} to be a belongs-to relationship`, isBelongsTo(relationship));
|
|
2819
|
-
let resource = this.
|
|
2445
|
+
let resource = this.cache.getRelationship(this.identifier, key);
|
|
2820
2446
|
relationship.state.hasFailedLoadAttempt = false;
|
|
2821
2447
|
relationship.state.shouldForceReload = true;
|
|
2822
2448
|
let promise = this._findBelongsTo(key, resource, relationship, options);
|
|
@@ -2830,9 +2456,9 @@ class LegacySupport {
|
|
|
2830
2456
|
getBelongsTo(key, options) {
|
|
2831
2457
|
const {
|
|
2832
2458
|
identifier,
|
|
2833
|
-
|
|
2459
|
+
cache
|
|
2834
2460
|
} = this;
|
|
2835
|
-
let resource =
|
|
2461
|
+
let resource = cache.getRelationship(this.identifier, key);
|
|
2836
2462
|
let relatedIdentifier = resource && resource.data ? resource.data : null;
|
|
2837
2463
|
assert(`Expected a stable identifier`, !relatedIdentifier || isStableIdentifier(relatedIdentifier));
|
|
2838
2464
|
const store = this.store;
|
|
@@ -2868,7 +2494,7 @@ class LegacySupport {
|
|
|
2868
2494
|
}
|
|
2869
2495
|
}
|
|
2870
2496
|
setDirtyBelongsTo(key, value) {
|
|
2871
|
-
return this.
|
|
2497
|
+
return this.cache.mutate({
|
|
2872
2498
|
op: 'replaceRelatedRecord',
|
|
2873
2499
|
record: this.identifier,
|
|
2874
2500
|
field: key,
|
|
@@ -2878,7 +2504,7 @@ class LegacySupport {
|
|
|
2878
2504
|
true);
|
|
2879
2505
|
}
|
|
2880
2506
|
_getCurrentState(identifier, field) {
|
|
2881
|
-
let jsonApi = this.
|
|
2507
|
+
let jsonApi = this.cache.getRelationship(identifier, field, true);
|
|
2882
2508
|
const cache = this.store._instanceCache;
|
|
2883
2509
|
let identifiers = [];
|
|
2884
2510
|
if (jsonApi.data) {
|
|
@@ -2893,7 +2519,7 @@ class LegacySupport {
|
|
|
2893
2519
|
return [identifiers, jsonApi];
|
|
2894
2520
|
}
|
|
2895
2521
|
getManyArray(key, definition) {
|
|
2896
|
-
if (macroCondition(
|
|
2522
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2897
2523
|
let manyArray = this._manyArrayCache[key];
|
|
2898
2524
|
if (!definition) {
|
|
2899
2525
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
@@ -2905,7 +2531,7 @@ class LegacySupport {
|
|
|
2905
2531
|
store: this.store,
|
|
2906
2532
|
type: definition.type,
|
|
2907
2533
|
identifier: this.identifier,
|
|
2908
|
-
|
|
2534
|
+
cache: this.cache,
|
|
2909
2535
|
identifiers,
|
|
2910
2536
|
key,
|
|
2911
2537
|
meta: doc.meta || null,
|
|
@@ -2924,16 +2550,16 @@ class LegacySupport {
|
|
|
2924
2550
|
assert('hasMany only works with the @ember-data/json-api package');
|
|
2925
2551
|
}
|
|
2926
2552
|
fetchAsyncHasMany(key, relationship, manyArray, options) {
|
|
2927
|
-
if (macroCondition(
|
|
2553
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2928
2554
|
let loadingPromise = this._relationshipPromisesCache[key];
|
|
2929
2555
|
if (loadingPromise) {
|
|
2930
2556
|
return loadingPromise;
|
|
2931
2557
|
}
|
|
2932
|
-
const jsonApi = this.
|
|
2558
|
+
const jsonApi = this.cache.getRelationship(this.identifier, key);
|
|
2933
2559
|
const promise = this._findHasManyByJsonApiResource(jsonApi, this.identifier, relationship, options);
|
|
2934
2560
|
if (!promise) {
|
|
2935
2561
|
manyArray.isLoaded = true;
|
|
2936
|
-
return resolve(manyArray);
|
|
2562
|
+
return Promise.resolve(manyArray);
|
|
2937
2563
|
}
|
|
2938
2564
|
loadingPromise = promise.then(() => handleCompletedRelationshipRequest(this, key, relationship, manyArray), e => handleCompletedRelationshipRequest(this, key, relationship, manyArray, e));
|
|
2939
2565
|
this._relationshipPromisesCache[key] = loadingPromise;
|
|
@@ -2942,7 +2568,7 @@ class LegacySupport {
|
|
|
2942
2568
|
assert('hasMany only works with the @ember-data/json-api package');
|
|
2943
2569
|
}
|
|
2944
2570
|
reloadHasMany(key, options) {
|
|
2945
|
-
if (macroCondition(
|
|
2571
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2946
2572
|
let loadingPromise = this._relationshipPromisesCache[key];
|
|
2947
2573
|
if (loadingPromise) {
|
|
2948
2574
|
return loadingPromise;
|
|
@@ -2967,7 +2593,7 @@ class LegacySupport {
|
|
|
2967
2593
|
assert(`hasMany only works with the @ember-data/json-api package`);
|
|
2968
2594
|
}
|
|
2969
2595
|
getHasMany(key, options) {
|
|
2970
|
-
if (macroCondition(
|
|
2596
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
2971
2597
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
2972
2598
|
const relationship = graphFor(this.store).get(this.identifier, key);
|
|
2973
2599
|
const {
|
|
@@ -3025,7 +2651,7 @@ class LegacySupport {
|
|
|
3025
2651
|
referenceFor(kind, name) {
|
|
3026
2652
|
let reference = this.references[name];
|
|
3027
2653
|
if (!reference) {
|
|
3028
|
-
if (macroCondition(!
|
|
2654
|
+
if (macroCondition(!getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
3029
2655
|
// TODO @runspired while this feels odd, it is not a regression in capability because we do
|
|
3030
2656
|
// not today support references pulling from RecordDatas other than our own
|
|
3031
2657
|
// because of the intimate API access involved. This is something we will need to redesign.
|
|
@@ -3034,7 +2660,7 @@ class LegacySupport {
|
|
|
3034
2660
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
3035
2661
|
const graph = graphFor(this.store);
|
|
3036
2662
|
const relationship = graph.get(this.identifier, name);
|
|
3037
|
-
if (macroCondition(
|
|
2663
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3038
2664
|
if (kind) {
|
|
3039
2665
|
let modelName = this.identifier.type;
|
|
3040
2666
|
let actualRelationshipKind = relationship.definition.kind;
|
|
@@ -3052,7 +2678,7 @@ class LegacySupport {
|
|
|
3052
2678
|
return reference;
|
|
3053
2679
|
}
|
|
3054
2680
|
_findHasManyByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
3055
|
-
if (macroCondition(
|
|
2681
|
+
if (macroCondition(getOwnConfig().packages.HAS_JSON_API_PACKAGE)) {
|
|
3056
2682
|
if (!resource) {
|
|
3057
2683
|
return;
|
|
3058
2684
|
}
|
|
@@ -3069,66 +2695,46 @@ class LegacySupport {
|
|
|
3069
2695
|
shouldForceReload
|
|
3070
2696
|
} = state;
|
|
3071
2697
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
3072
|
-
const
|
|
2698
|
+
const identifiers = resource.data;
|
|
2699
|
+
const shouldFindViaLink = resource.links && resource.links.related && (typeof adapter.findHasMany === 'function' || typeof identifiers === 'undefined') && (shouldForceReload || hasDematerializedInverse || isStale || !allInverseRecordsAreLoaded && !isEmpty);
|
|
2700
|
+
const relationshipMeta = this.store.getSchemaDefinitionService().relationshipsDefinitionFor({
|
|
2701
|
+
type: definition.inverseType
|
|
2702
|
+
})[definition.key];
|
|
2703
|
+
const request = {
|
|
2704
|
+
useLink: shouldFindViaLink,
|
|
2705
|
+
field: relationshipMeta,
|
|
2706
|
+
links: resource.links,
|
|
2707
|
+
meta: resource.meta,
|
|
2708
|
+
options,
|
|
2709
|
+
record: parentIdentifier
|
|
2710
|
+
};
|
|
3073
2711
|
|
|
3074
2712
|
// fetch via link
|
|
3075
2713
|
if (shouldFindViaLink) {
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
/*
|
|
3084
|
-
If a relationship was originally populated by the adapter as a link
|
|
3085
|
-
(as opposed to a list of IDs), this method is called when the
|
|
3086
|
-
relationship is fetched.
|
|
3087
|
-
The link (which is usually a URL) is passed through unchanged, so the
|
|
3088
|
-
adapter can make whatever request it wants.
|
|
3089
|
-
The usual use-case is for the server to register a URL as a link, and
|
|
3090
|
-
then use that URL in the future to make a request for the relationship.
|
|
3091
|
-
*/
|
|
3092
|
-
assert(`You tried to load a hasMany relationship but you have no adapter (for ${parentIdentifier.type})`, adapter);
|
|
3093
|
-
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');
|
|
3094
|
-
return _findHasMany(adapter, this.store, parentIdentifier, resource.links.related, relationshipMeta, options);
|
|
2714
|
+
assert(`Expected collection to be an array`, !identifiers || Array.isArray(identifiers));
|
|
2715
|
+
assert(`Expected stable identifiers`, !identifiers || identifiers.every(isStableIdentifier));
|
|
2716
|
+
return this.store.request({
|
|
2717
|
+
op: 'findHasMany',
|
|
2718
|
+
records: identifiers || [],
|
|
2719
|
+
data: request
|
|
2720
|
+
});
|
|
3095
2721
|
}
|
|
3096
2722
|
const preferLocalCache = hasReceivedData && !isEmpty;
|
|
3097
|
-
const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
if (allInverseRecordsAreLoaded) {
|
|
3102
|
-
return;
|
|
3103
|
-
}
|
|
3104
|
-
assert(`Expected collection to be an array`, Array.isArray(resource.data));
|
|
3105
|
-
if (allInverseRecordsAreLoaded) {
|
|
3106
|
-
return;
|
|
3107
|
-
}
|
|
3108
|
-
let finds = new Array(resource.data.length);
|
|
3109
|
-
let cache = this.store._instanceCache;
|
|
3110
|
-
for (let i = 0; i < resource.data.length; i++) {
|
|
3111
|
-
const identifier = resource.data[i];
|
|
3112
|
-
assert(`expected a stable identifier`, isStableIdentifier(identifier));
|
|
3113
|
-
finds[i] = cache._fetchDataIfNeededForIdentifier(identifier, options);
|
|
3114
|
-
}
|
|
3115
|
-
return all(finds);
|
|
2723
|
+
const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(identifiers) && identifiers.length > 0;
|
|
2724
|
+
const attemptLocalCache = !shouldForceReload && !isStale && (preferLocalCache || hasLocalPartialData);
|
|
2725
|
+
if (attemptLocalCache && allInverseRecordsAreLoaded) {
|
|
2726
|
+
return;
|
|
3116
2727
|
}
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
// fetch by data
|
|
3120
|
-
if (hasData || hasLocalPartialData) {
|
|
3121
|
-
const identifiers = resource.data;
|
|
2728
|
+
const hasData = hasReceivedData && !isEmpty;
|
|
2729
|
+
if (attemptLocalCache || hasData || hasLocalPartialData) {
|
|
3122
2730
|
assert(`Expected collection to be an array`, Array.isArray(identifiers));
|
|
3123
2731
|
assert(`Expected stable identifiers`, identifiers.every(isStableIdentifier));
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
}
|
|
3131
|
-
return all(fetches);
|
|
2732
|
+
options.reload = options.reload || !attemptLocalCache || undefined;
|
|
2733
|
+
return this.store.request({
|
|
2734
|
+
op: 'findHasMany',
|
|
2735
|
+
records: identifiers,
|
|
2736
|
+
data: request
|
|
2737
|
+
});
|
|
3132
2738
|
}
|
|
3133
2739
|
|
|
3134
2740
|
// we were explicitly told we have no data and no links.
|
|
@@ -3139,7 +2745,14 @@ class LegacySupport {
|
|
|
3139
2745
|
}
|
|
3140
2746
|
_findBelongsToByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
3141
2747
|
if (!resource) {
|
|
3142
|
-
return resolve(null);
|
|
2748
|
+
return Promise.resolve(null);
|
|
2749
|
+
}
|
|
2750
|
+
|
|
2751
|
+
// interleaved promises mean that we MUST cache this here
|
|
2752
|
+
// in order to prevent infinite re-render if the request
|
|
2753
|
+
// fails.
|
|
2754
|
+
if (this._pending) {
|
|
2755
|
+
return this._pending;
|
|
3143
2756
|
}
|
|
3144
2757
|
const identifier = resource.data ? resource.data : null;
|
|
3145
2758
|
assert(`Expected a stable identifier`, !identifier || isStableIdentifier(identifier));
|
|
@@ -3150,53 +2763,65 @@ class LegacySupport {
|
|
|
3150
2763
|
isEmpty,
|
|
3151
2764
|
shouldForceReload
|
|
3152
2765
|
} = relationship.state;
|
|
3153
|
-
|
|
3154
|
-
// short circuit if we are already loading
|
|
3155
|
-
let pendingRequest = identifier && this.store._fetchManager.getPendingFetch(identifier, options);
|
|
3156
|
-
if (pendingRequest) {
|
|
3157
|
-
return pendingRequest;
|
|
3158
|
-
}
|
|
3159
2766
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
3160
2767
|
const shouldFindViaLink = resource.links?.related && (shouldForceReload || hasDematerializedInverse || isStale || !allInverseRecordsAreLoaded && !isEmpty);
|
|
2768
|
+
const relationshipMeta = this.store.getSchemaDefinitionService().relationshipsDefinitionFor(this.identifier)[relationship.definition.key];
|
|
2769
|
+
assert(`Attempted to access a belongsTo relationship but no definition exists for it`, relationshipMeta);
|
|
2770
|
+
const request = {
|
|
2771
|
+
useLink: shouldFindViaLink,
|
|
2772
|
+
field: relationshipMeta,
|
|
2773
|
+
links: resource.links,
|
|
2774
|
+
meta: resource.meta,
|
|
2775
|
+
options,
|
|
2776
|
+
record: parentIdentifier
|
|
2777
|
+
};
|
|
3161
2778
|
|
|
3162
2779
|
// fetch via link
|
|
3163
2780
|
if (shouldFindViaLink) {
|
|
3164
|
-
const
|
|
3165
|
-
|
|
3166
|
-
|
|
2781
|
+
const future = this.store.request({
|
|
2782
|
+
op: 'findBelongsTo',
|
|
2783
|
+
records: identifier ? [identifier] : [],
|
|
2784
|
+
data: request
|
|
2785
|
+
});
|
|
2786
|
+
this._pending = future.then(doc => doc.content).finally(() => {
|
|
2787
|
+
this._pending = null;
|
|
2788
|
+
});
|
|
2789
|
+
return this._pending;
|
|
3167
2790
|
}
|
|
3168
|
-
|
|
3169
|
-
|
|
2791
|
+
const preferLocalCache = hasReceivedData && allInverseRecordsAreLoaded && !isEmpty;
|
|
2792
|
+
const hasLocalPartialData = hasDematerializedInverse || isEmpty && resource.data;
|
|
3170
2793
|
// null is explicit empty, undefined is "we don't know anything"
|
|
3171
|
-
const localDataIsEmpty =
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
2794
|
+
const localDataIsEmpty = !identifier;
|
|
2795
|
+
const attemptLocalCache = !shouldForceReload && !isStale && (preferLocalCache || hasLocalPartialData);
|
|
2796
|
+
|
|
2797
|
+
// we dont need to fetch and are empty
|
|
2798
|
+
if (attemptLocalCache && localDataIsEmpty) {
|
|
2799
|
+
return Promise.resolve(null);
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
// we dont need to fetch because we are local state
|
|
2803
|
+
const resourceIsLocal = identifier?.id === null;
|
|
2804
|
+
if (attemptLocalCache && allInverseRecordsAreLoaded || resourceIsLocal) {
|
|
2805
|
+
return Promise.resolve(identifier);
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
// we may need to fetch
|
|
2809
|
+
if (identifier) {
|
|
2810
|
+
assert(`Cannot fetch belongs-to relationship with no information`, identifier);
|
|
2811
|
+
options.reload = options.reload || !attemptLocalCache || undefined;
|
|
2812
|
+
this._pending = this.store.request({
|
|
2813
|
+
op: 'findBelongsTo',
|
|
2814
|
+
records: [identifier],
|
|
2815
|
+
data: request
|
|
2816
|
+
}).then(doc => doc.content).finally(() => {
|
|
2817
|
+
this._pending = null;
|
|
2818
|
+
});
|
|
2819
|
+
return this._pending;
|
|
3195
2820
|
}
|
|
3196
2821
|
|
|
3197
2822
|
// we were explicitly told we have no data and no links.
|
|
3198
2823
|
// TODO if the relationshipIsStale, should we hit the adapter anyway?
|
|
3199
|
-
return resolve(null);
|
|
2824
|
+
return Promise.resolve(null);
|
|
3200
2825
|
}
|
|
3201
2826
|
destroy() {
|
|
3202
2827
|
this.isDestroying = true;
|
|
@@ -3245,11 +2870,14 @@ function handleCompletedRelationshipRequest(recordExt, key, relationship, value,
|
|
|
3245
2870
|
if (proxy.content && proxy.content.isDestroying) {
|
|
3246
2871
|
proxy.set('content', null);
|
|
3247
2872
|
}
|
|
2873
|
+
recordExt.store.notifications._flush();
|
|
3248
2874
|
}
|
|
3249
2875
|
throw error;
|
|
3250
2876
|
}
|
|
3251
2877
|
if (isHasMany) {
|
|
3252
2878
|
value.isLoaded = true;
|
|
2879
|
+
} else {
|
|
2880
|
+
recordExt.store.notifications._flush();
|
|
3253
2881
|
}
|
|
3254
2882
|
relationship.state.hasFailedLoadAttempt = false;
|
|
3255
2883
|
// only set to not stale if no error is thrown
|
|
@@ -3356,7 +2984,8 @@ function notifyRelationship(identifier, key, record, meta) {
|
|
|
3356
2984
|
}
|
|
3357
2985
|
function notifyAttribute(store, identifier, key, record) {
|
|
3358
2986
|
let currentValue = cacheFor(record, key);
|
|
3359
|
-
|
|
2987
|
+
const cache = macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA) ? peekCache(record) : store.cache;
|
|
2988
|
+
if (currentValue !== cache.getAttr(identifier, key)) {
|
|
3360
2989
|
record.notifyPropertyChange(key);
|
|
3361
2990
|
}
|
|
3362
2991
|
}
|
|
@@ -3491,11 +3120,11 @@ root
|
|
|
3491
3120
|
let RecordState = (_class3 = class RecordState {
|
|
3492
3121
|
constructor(record) {
|
|
3493
3122
|
_initializerDefineProperty(this, "isSaving", _descriptor2, this);
|
|
3494
|
-
const store = storeFor(record);
|
|
3123
|
+
const store = storeFor$1(record);
|
|
3495
3124
|
const identity = recordIdentifierFor$1(record);
|
|
3496
3125
|
this.identifier = identity;
|
|
3497
3126
|
this.record = record;
|
|
3498
|
-
this.cache =
|
|
3127
|
+
this.cache = macroCondition(getOwnConfig().deprecations.DEPRECATE_V1_RECORD_DATA) ? peekCache(record) : store.cache;
|
|
3499
3128
|
this.pendingCount = 0;
|
|
3500
3129
|
this.fulfilledCount = 0;
|
|
3501
3130
|
this.rejectedCount = 0;
|
|
@@ -3555,7 +3184,7 @@ let RecordState = (_class3 = class RecordState {
|
|
|
3555
3184
|
|
|
3556
3185
|
// we instantiate lazily
|
|
3557
3186
|
// so we grab anything we don't have yet
|
|
3558
|
-
if (macroCondition(!
|
|
3187
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
3559
3188
|
const lastRequest = requests.getLastRequestForRecord(identity);
|
|
3560
3189
|
if (lastRequest) {
|
|
3561
3190
|
handleRequest(lastRequest);
|
|
@@ -3580,7 +3209,7 @@ let RecordState = (_class3 = class RecordState {
|
|
|
3580
3209
|
});
|
|
3581
3210
|
}
|
|
3582
3211
|
destroy() {
|
|
3583
|
-
storeFor(this.record).notifications.unsubscribe(this.handler);
|
|
3212
|
+
storeFor$1(this.record).notifications.unsubscribe(this.handler);
|
|
3584
3213
|
}
|
|
3585
3214
|
notify(key) {
|
|
3586
3215
|
getTag(this, key).notify();
|
|
@@ -3814,7 +3443,7 @@ class RelationshipDefinition {
|
|
|
3814
3443
|
inverse = modelClass.inverseFor(this.key, store);
|
|
3815
3444
|
}
|
|
3816
3445
|
// TODO make this error again for the non-polymorphic case
|
|
3817
|
-
if (macroCondition(
|
|
3446
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3818
3447
|
if (!this.options.polymorphic) {
|
|
3819
3448
|
modelClass.typeForRelationship(this.key, store);
|
|
3820
3449
|
}
|
|
@@ -3839,6 +3468,7 @@ function lookupLegacySupport(record) {
|
|
|
3839
3468
|
const identifier = recordIdentifierFor(record);
|
|
3840
3469
|
let support = LEGACY_SUPPORT.get(identifier);
|
|
3841
3470
|
if (!support) {
|
|
3471
|
+
assert(`Memory Leak Detected`, !record.isDestroyed && !record.isDestroying);
|
|
3842
3472
|
support = new LegacySupport(record);
|
|
3843
3473
|
LEGACY_SUPPORT.set(identifier, support);
|
|
3844
3474
|
LEGACY_SUPPORT.set(record, support);
|
|
@@ -3931,7 +3561,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3931
3561
|
_initializerDefineProperty(this, "isReloading", _descriptor, this);
|
|
3932
3562
|
}
|
|
3933
3563
|
init(options = {}) {
|
|
3934
|
-
if (macroCondition(
|
|
3564
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3935
3565
|
if (!options._secretInit && !options._createProps) {
|
|
3936
3566
|
throw new Error('You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.');
|
|
3937
3567
|
}
|
|
@@ -3943,8 +3573,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3943
3573
|
let store = this.store = _secretInit.store;
|
|
3944
3574
|
super.init(options);
|
|
3945
3575
|
let identity = _secretInit.identifier;
|
|
3946
|
-
_secretInit.cb(this, _secretInit.
|
|
3947
|
-
this.___recordState = macroCondition(
|
|
3576
|
+
_secretInit.cb(this, _secretInit.cache, identity, _secretInit.store);
|
|
3577
|
+
this.___recordState = macroCondition(getOwnConfig().env.DEBUG) ? new RecordState(this) : null;
|
|
3948
3578
|
this.setProperties(createProps);
|
|
3949
3579
|
let notifications = store.notifications;
|
|
3950
3580
|
this.___private_notifications = notifications.subscribe(identity, (identifier, type, key) => {
|
|
@@ -3954,7 +3584,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3954
3584
|
destroy() {
|
|
3955
3585
|
const identifier = recordIdentifierFor(this);
|
|
3956
3586
|
this.___recordState?.destroy();
|
|
3957
|
-
const store = storeFor(this);
|
|
3587
|
+
const store = storeFor$1(this);
|
|
3958
3588
|
store.notifications.unsubscribe(this.___private_notifications);
|
|
3959
3589
|
// Legacy behavior is to notify the relationships on destroy
|
|
3960
3590
|
// such that they "clear". It's uncertain this behavior would
|
|
@@ -4189,7 +3819,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4189
3819
|
return this.currentState.isError;
|
|
4190
3820
|
}
|
|
4191
3821
|
set isError(v) {
|
|
4192
|
-
if (macroCondition(
|
|
3822
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4193
3823
|
throw new Error(`isError is not directly settable`);
|
|
4194
3824
|
}
|
|
4195
3825
|
}
|
|
@@ -4214,7 +3844,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4214
3844
|
// this guard exists, because some dev-only deprecation code
|
|
4215
3845
|
// (addListener via validatePropertyInjections) invokes toString before the
|
|
4216
3846
|
// object is real.
|
|
4217
|
-
if (macroCondition(
|
|
3847
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4218
3848
|
try {
|
|
4219
3849
|
return recordIdentifierFor(this).id;
|
|
4220
3850
|
} catch {
|
|
@@ -4249,7 +3879,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4249
3879
|
// when using legacy/classic ember classes. Basically: lazy in prod and eager in dev.
|
|
4250
3880
|
// so we do this to try to steer folks to the nicer "dont user currentState"
|
|
4251
3881
|
// error.
|
|
4252
|
-
if (macroCondition(!
|
|
3882
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
4253
3883
|
if (!this.___recordState) {
|
|
4254
3884
|
this.___recordState = new RecordState(this);
|
|
4255
3885
|
}
|
|
@@ -4345,7 +3975,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4345
3975
|
@return {Object} an object whose values are primitive JSON values only
|
|
4346
3976
|
*/
|
|
4347
3977
|
serialize(options) {
|
|
4348
|
-
return storeFor(this).
|
|
3978
|
+
return storeFor$1(this).serializeRecord(this, options);
|
|
4349
3979
|
}
|
|
4350
3980
|
|
|
4351
3981
|
/*
|
|
@@ -4394,7 +4024,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4394
4024
|
deleteRecord() {
|
|
4395
4025
|
// ensure we've populated currentState prior to deleting a new record
|
|
4396
4026
|
if (this.currentState) {
|
|
4397
|
-
storeFor(this).deleteRecord(this);
|
|
4027
|
+
storeFor$1(this).deleteRecord(this);
|
|
4398
4028
|
}
|
|
4399
4029
|
}
|
|
4400
4030
|
|
|
@@ -4441,7 +4071,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4441
4071
|
} = this.currentState;
|
|
4442
4072
|
this.deleteRecord();
|
|
4443
4073
|
if (isNew) {
|
|
4444
|
-
return resolve(this);
|
|
4074
|
+
return Promise.resolve(this);
|
|
4445
4075
|
}
|
|
4446
4076
|
return this.save(options).then(_ => {
|
|
4447
4077
|
run(() => {
|
|
@@ -4461,7 +4091,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4461
4091
|
if (this.currentState.isNew && (this.isDestroyed || this.isDestroying)) {
|
|
4462
4092
|
return;
|
|
4463
4093
|
}
|
|
4464
|
-
storeFor(this).unloadRecord(this);
|
|
4094
|
+
storeFor$1(this).unloadRecord(this);
|
|
4465
4095
|
}
|
|
4466
4096
|
|
|
4467
4097
|
/**
|
|
@@ -4517,7 +4147,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4517
4147
|
and value is an [oldProp, newProp] array.
|
|
4518
4148
|
*/
|
|
4519
4149
|
changedAttributes() {
|
|
4520
|
-
return
|
|
4150
|
+
return peekCache(this).changedAttrs(recordIdentifierFor(this));
|
|
4521
4151
|
}
|
|
4522
4152
|
|
|
4523
4153
|
/**
|
|
@@ -4542,8 +4172,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4542
4172
|
const {
|
|
4543
4173
|
isNew
|
|
4544
4174
|
} = currentState;
|
|
4545
|
-
storeFor(this)._join(() => {
|
|
4546
|
-
|
|
4175
|
+
storeFor$1(this)._join(() => {
|
|
4176
|
+
peekCache(this).rollbackAttrs(recordIdentifierFor(this));
|
|
4547
4177
|
this.errors.clear();
|
|
4548
4178
|
currentState.cleanErrorRequests();
|
|
4549
4179
|
if (isNew) {
|
|
@@ -4558,7 +4188,12 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4558
4188
|
*/
|
|
4559
4189
|
// TODO @deprecate in favor of a public API or examples of how to test successfully
|
|
4560
4190
|
_createSnapshot() {
|
|
4561
|
-
|
|
4191
|
+
const store = storeFor$1(this);
|
|
4192
|
+
if (!store._fetchManager) {
|
|
4193
|
+
const FetchManager = importSync('@ember-data/legacy-compat/-private').FetchManager;
|
|
4194
|
+
store._fetchManager = new FetchManager(store);
|
|
4195
|
+
}
|
|
4196
|
+
return store._fetchManager.createSnapshot(recordIdentifierFor(this));
|
|
4562
4197
|
}
|
|
4563
4198
|
|
|
4564
4199
|
/**
|
|
@@ -4598,9 +4233,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4598
4233
|
save(options) {
|
|
4599
4234
|
let promise;
|
|
4600
4235
|
if (this.currentState.isNew && this.currentState.isDeleted) {
|
|
4601
|
-
promise = resolve(this);
|
|
4236
|
+
promise = Promise.resolve(this);
|
|
4602
4237
|
} else {
|
|
4603
|
-
promise = storeFor(this).saveRecord(this, options);
|
|
4238
|
+
promise = storeFor$1(this).saveRecord(this, options);
|
|
4604
4239
|
}
|
|
4605
4240
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SAVE_PROMISE_ACCESS)) {
|
|
4606
4241
|
return deprecatedPromiseObject(promise);
|
|
@@ -4631,16 +4266,19 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4631
4266
|
adapter returns successfully or rejected if the adapter returns
|
|
4632
4267
|
with an error.
|
|
4633
4268
|
*/
|
|
4634
|
-
reload(
|
|
4635
|
-
let options = {};
|
|
4636
|
-
if (typeof _options === 'object' && _options !== null && _options.adapterOptions) {
|
|
4637
|
-
options.adapterOptions = _options.adapterOptions;
|
|
4638
|
-
}
|
|
4269
|
+
reload(options = {}) {
|
|
4639
4270
|
options.isReloading = true;
|
|
4640
|
-
|
|
4271
|
+
options.reload = true;
|
|
4272
|
+
const identifier = recordIdentifierFor(this);
|
|
4641
4273
|
assert(`You cannot reload a record without an ID`, identifier.id);
|
|
4642
4274
|
this.isReloading = true;
|
|
4643
|
-
const promise = storeFor(this).
|
|
4275
|
+
const promise = storeFor$1(this).request({
|
|
4276
|
+
op: 'findRecord',
|
|
4277
|
+
data: {
|
|
4278
|
+
options,
|
|
4279
|
+
record: identifier
|
|
4280
|
+
}
|
|
4281
|
+
}).then(() => this).finally(() => {
|
|
4644
4282
|
this.isReloading = false;
|
|
4645
4283
|
});
|
|
4646
4284
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SAVE_PROMISE_ACCESS)) {
|
|
@@ -4808,7 +4446,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4808
4446
|
return this.constructor.relationshipsByName.get(name);
|
|
4809
4447
|
}
|
|
4810
4448
|
inverseFor(key) {
|
|
4811
|
-
return this.constructor.inverseFor(key, storeFor(this));
|
|
4449
|
+
return this.constructor.inverseFor(key, storeFor$1(this));
|
|
4812
4450
|
}
|
|
4813
4451
|
eachAttribute(callback, binding) {
|
|
4814
4452
|
this.constructor.eachAttribute(callback, binding);
|
|
@@ -4980,7 +4618,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4980
4618
|
if (possibleRelationships.length === 0) {
|
|
4981
4619
|
return null;
|
|
4982
4620
|
}
|
|
4983
|
-
if (macroCondition(
|
|
4621
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4984
4622
|
let filteredRelationships = possibleRelationships.filter(possibleRelationship => {
|
|
4985
4623
|
let optionsForRelationship = possibleRelationship.options;
|
|
4986
4624
|
return name === optionsForRelationship.inverse;
|
|
@@ -4998,7 +4636,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4998
4636
|
}
|
|
4999
4637
|
|
|
5000
4638
|
// ensure inverse is properly configured
|
|
5001
|
-
if (macroCondition(
|
|
4639
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5002
4640
|
if (isPolymorphic) {
|
|
5003
4641
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_EXPLICIT_POLYMORPHISM)) {
|
|
5004
4642
|
if (!inverseOptions.as) {
|
|
@@ -5020,7 +4658,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5020
4658
|
}
|
|
5021
4659
|
|
|
5022
4660
|
// ensure we are properly configured
|
|
5023
|
-
if (macroCondition(
|
|
4661
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5024
4662
|
if (inverseOptions.polymorphic) {
|
|
5025
4663
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_EXPLICIT_POLYMORPHISM)) {
|
|
5026
4664
|
if (!options.as) {
|
|
@@ -5186,7 +4824,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5186
4824
|
import { get } from '@ember/object';
|
|
5187
4825
|
import Blog from 'app/models/blog';
|
|
5188
4826
|
let relatedTypes = Blog.relatedTypes');
|
|
5189
|
-
//=> [
|
|
4827
|
+
//=> ['user', 'post']
|
|
5190
4828
|
```
|
|
5191
4829
|
@property relatedTypes
|
|
5192
4830
|
@public
|
|
@@ -5274,7 +4912,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5274
4912
|
for (let i = 0; i < relationships.length; i++) {
|
|
5275
4913
|
let key = relationships[i];
|
|
5276
4914
|
let value = rels[key];
|
|
5277
|
-
map.set(value.key, value);
|
|
4915
|
+
map.set(value.name || value.key, value);
|
|
5278
4916
|
}
|
|
5279
4917
|
return map;
|
|
5280
4918
|
}
|
|
@@ -5721,16 +5359,21 @@ if (macroCondition(getOwnConfig().includeDataAdapter)) {
|
|
|
5721
5359
|
@private
|
|
5722
5360
|
*/
|
|
5723
5361
|
Model.prototype._debugInfo = function () {
|
|
5724
|
-
let attributes = ['id'];
|
|
5725
5362
|
let relationships = {};
|
|
5726
5363
|
let expensiveProperties = [];
|
|
5727
|
-
|
|
5364
|
+
const identifier = recordIdentifierFor(this);
|
|
5365
|
+
const schema = this.store.getSchemaDefinitionService();
|
|
5366
|
+
const attrDefs = schema.attributesDefinitionFor(identifier);
|
|
5367
|
+
const relDefs = schema.relationshipsDefinitionFor(identifier);
|
|
5368
|
+
const attributes = Object.keys(attrDefs);
|
|
5369
|
+
attributes.unshift('id');
|
|
5728
5370
|
let groups = [{
|
|
5729
5371
|
name: 'Attributes',
|
|
5730
5372
|
properties: attributes,
|
|
5731
5373
|
expand: true
|
|
5732
5374
|
}];
|
|
5733
|
-
|
|
5375
|
+
Object.keys(relDefs).forEach(name => {
|
|
5376
|
+
const relationship = relDefs[name];
|
|
5734
5377
|
let properties = relationships[relationship.kind];
|
|
5735
5378
|
if (properties === undefined) {
|
|
5736
5379
|
properties = relationships[relationship.kind] = [];
|
|
@@ -5758,7 +5401,7 @@ if (macroCondition(getOwnConfig().includeDataAdapter)) {
|
|
|
5758
5401
|
};
|
|
5759
5402
|
};
|
|
5760
5403
|
}
|
|
5761
|
-
if (macroCondition(
|
|
5404
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5762
5405
|
let lookupDescriptor = function lookupDescriptor(obj, keyName) {
|
|
5763
5406
|
let current = obj;
|
|
5764
5407
|
do {
|
|
@@ -6007,7 +5650,7 @@ function belongsTo(modelName, options) {
|
|
|
6007
5650
|
return null;
|
|
6008
5651
|
}
|
|
6009
5652
|
const support = lookupLegacySupport(this);
|
|
6010
|
-
if (macroCondition(
|
|
5653
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6011
5654
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6012
5655
|
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()}`);
|
|
6013
5656
|
}
|
|
@@ -6026,7 +5669,7 @@ function belongsTo(modelName, options) {
|
|
|
6026
5669
|
},
|
|
6027
5670
|
set(key, value) {
|
|
6028
5671
|
const support = lookupLegacySupport(this);
|
|
6029
|
-
if (macroCondition(
|
|
5672
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6030
5673
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6031
5674
|
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()}`);
|
|
6032
5675
|
}
|
|
@@ -6257,7 +5900,7 @@ function hasMany(type, options) {
|
|
|
6257
5900
|
};
|
|
6258
5901
|
return computed({
|
|
6259
5902
|
get(key) {
|
|
6260
|
-
if (macroCondition(
|
|
5903
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6261
5904
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6262
5905
|
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()}`);
|
|
6263
5906
|
}
|
|
@@ -6268,7 +5911,7 @@ function hasMany(type, options) {
|
|
|
6268
5911
|
return lookupLegacySupport(this).getHasMany(key);
|
|
6269
5912
|
},
|
|
6270
5913
|
set(key, records) {
|
|
6271
|
-
if (macroCondition(
|
|
5914
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6272
5915
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6273
5916
|
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()}`);
|
|
6274
5917
|
}
|