@ember-data/model 4.12.0-alpha.11 → 4.12.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
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
4
|
import { recordIdentifierFor, storeFor as storeFor$1 } from '@ember-data/store';
|
|
@@ -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';
|
|
@@ -144,7 +143,7 @@ function attr(type, options) {
|
|
|
144
143
|
};
|
|
145
144
|
return computed({
|
|
146
145
|
get(key) {
|
|
147
|
-
if (
|
|
146
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
148
147
|
if (['currentState'].indexOf(key) !== -1) {
|
|
149
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()}`);
|
|
150
149
|
}
|
|
@@ -155,7 +154,7 @@ function attr(type, options) {
|
|
|
155
154
|
return peekCache(this).getAttr(recordIdentifierFor(this), key);
|
|
156
155
|
},
|
|
157
156
|
set(key, value) {
|
|
158
|
-
if (
|
|
157
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
159
158
|
if (['currentState'].indexOf(key) !== -1) {
|
|
160
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()}`);
|
|
161
160
|
}
|
|
@@ -216,7 +215,7 @@ function _applyDecoratedDescriptor(target, property, decorators, descriptor, con
|
|
|
216
215
|
const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
|
|
217
216
|
function promiseObject(promise) {
|
|
218
217
|
return PromiseObject.create({
|
|
219
|
-
promise
|
|
218
|
+
promise
|
|
220
219
|
});
|
|
221
220
|
}
|
|
222
221
|
|
|
@@ -227,7 +226,7 @@ const PROXIED_OBJECT_PROPS = ['content', 'isPending', 'isSettled', 'isRejected',
|
|
|
227
226
|
const ProxySymbolString = String(Symbol.for('PROXY_CONTENT'));
|
|
228
227
|
function deprecatedPromiseObject(promise) {
|
|
229
228
|
const promiseObjectProxy = promiseObject(promise);
|
|
230
|
-
if (!
|
|
229
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
231
230
|
return promiseObjectProxy;
|
|
232
231
|
}
|
|
233
232
|
const handler = {
|
|
@@ -634,384 +633,6 @@ let Errors = (_dec$1 = computed(), _dec2 = mapBy('content', 'message'), _dec3 =
|
|
|
634
633
|
writable: true,
|
|
635
634
|
initializer: null
|
|
636
635
|
})), _class$6));
|
|
637
|
-
function iterateData(data, fn) {
|
|
638
|
-
if (Array.isArray(data)) {
|
|
639
|
-
return data.map(fn);
|
|
640
|
-
} else {
|
|
641
|
-
return fn(data);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
function assertIdentifierHasId(identifier) {
|
|
645
|
-
assert(`Attempted to schedule a fetch for a record without an id.`, identifier.id !== null);
|
|
646
|
-
}
|
|
647
|
-
function normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
|
|
648
|
-
let normalizedResponse = serializer ? serializer.normalizeResponse(store, modelClass, payload, id, requestType) : payload;
|
|
649
|
-
validateDocumentStructure(normalizedResponse);
|
|
650
|
-
return normalizedResponse;
|
|
651
|
-
}
|
|
652
|
-
function validateDocumentStructure(doc) {
|
|
653
|
-
if (isDevelopingApp()) {
|
|
654
|
-
let errors = [];
|
|
655
|
-
if (!doc || typeof doc !== 'object') {
|
|
656
|
-
errors.push('Top level of a JSON API document must be an object');
|
|
657
|
-
} else {
|
|
658
|
-
if (!('data' in doc) && !('errors' in doc) && !('meta' in doc)) {
|
|
659
|
-
errors.push('One or more of the following keys must be present: "data", "errors", "meta".');
|
|
660
|
-
} else {
|
|
661
|
-
if ('data' in doc && 'errors' in doc) {
|
|
662
|
-
errors.push('Top level keys "errors" and "data" cannot both be present in a JSON API document');
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
if ('data' in doc) {
|
|
666
|
-
if (!(doc.data === null || Array.isArray(doc.data) || typeof doc.data === 'object')) {
|
|
667
|
-
errors.push('data must be null, an object, or an array');
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
if ('meta' in doc) {
|
|
671
|
-
if (typeof doc.meta !== 'object') {
|
|
672
|
-
errors.push('meta must be an object');
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
if ('errors' in doc) {
|
|
676
|
-
if (!Array.isArray(doc.errors)) {
|
|
677
|
-
errors.push('errors must be an array');
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
if ('links' in doc) {
|
|
681
|
-
if (typeof doc.links !== 'object') {
|
|
682
|
-
errors.push('links must be an object');
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
if ('jsonapi' in doc) {
|
|
686
|
-
if (typeof doc.jsonapi !== 'object') {
|
|
687
|
-
errors.push('jsonapi must be an object');
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
if ('included' in doc) {
|
|
691
|
-
if (typeof doc.included !== 'object') {
|
|
692
|
-
errors.push('included must be an array');
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
assert(`Response must be normalized to a valid JSON API document:\n\t* ${errors.join('\n\t* ')}`, errors.length === 0);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
function _findHasMany(adapter, store, identifier, link, relationship, options) {
|
|
700
|
-
const record = store._instanceCache.getRecord(identifier);
|
|
701
|
-
const snapshot = store._instanceCache.createSnapshot(identifier, options);
|
|
702
|
-
let modelClass = store.modelFor(relationship.type);
|
|
703
|
-
let useLink = !link || typeof link === 'string';
|
|
704
|
-
let relatedLink = useLink ? link : link.href;
|
|
705
|
-
let promise = adapter.findHasMany(store, snapshot, relatedLink, relationship);
|
|
706
|
-
let label = `DS: Handle Adapter#findHasMany of '${identifier.type}' : '${relationship.type}'`;
|
|
707
|
-
promise = guardDestroyedStore(promise, store, label);
|
|
708
|
-
promise = promise.then(adapterPayload => {
|
|
709
|
-
if (!_objectIsAlive(record)) {
|
|
710
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
711
|
-
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, {
|
|
712
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
713
|
-
until: '5.0',
|
|
714
|
-
for: '@ember-data/store',
|
|
715
|
-
since: {
|
|
716
|
-
available: '4.5',
|
|
717
|
-
enabled: '4.5'
|
|
718
|
-
}
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
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));
|
|
723
|
-
let serializer = store.serializerFor(relationship.type);
|
|
724
|
-
let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findHasMany');
|
|
725
|
-
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));
|
|
726
|
-
payload = syncRelationshipDataFromLink(store, payload, identifier, relationship);
|
|
727
|
-
return store._push(payload);
|
|
728
|
-
}, null, `DS: Extract payload of '${identifier.type}' : hasMany '${relationship.type}'`);
|
|
729
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
730
|
-
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
731
|
-
}
|
|
732
|
-
return promise;
|
|
733
|
-
}
|
|
734
|
-
function _findBelongsTo(store, identifier, link, relationship, options) {
|
|
735
|
-
const record = store._instanceCache.getRecord(identifier);
|
|
736
|
-
let adapter = store.adapterFor(identifier.type);
|
|
737
|
-
assert(`You tried to load a belongsTo relationship but you have no adapter (for ${identifier.type})`, adapter);
|
|
738
|
-
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');
|
|
739
|
-
let snapshot = store._instanceCache.createSnapshot(identifier, options);
|
|
740
|
-
let modelClass = store.modelFor(relationship.type);
|
|
741
|
-
let useLink = !link || typeof link === 'string';
|
|
742
|
-
let relatedLink = useLink ? link : link.href;
|
|
743
|
-
let promise = adapter.findBelongsTo(store, snapshot, relatedLink, relationship);
|
|
744
|
-
let label = `DS: Handle Adapter#findBelongsTo of ${identifier.type} : ${relationship.type}`;
|
|
745
|
-
promise = guardDestroyedStore(promise, store, label);
|
|
746
|
-
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
747
|
-
promise = promise.then(adapterPayload => {
|
|
748
|
-
if (!_objectIsAlive(record)) {
|
|
749
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
750
|
-
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, {
|
|
751
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
752
|
-
until: '5.0',
|
|
753
|
-
for: '@ember-data/store',
|
|
754
|
-
since: {
|
|
755
|
-
available: '4.5',
|
|
756
|
-
enabled: '4.5'
|
|
757
|
-
}
|
|
758
|
-
});
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
let serializer = store.serializerFor(relationship.type);
|
|
762
|
-
let payload = normalizeResponseHelper(serializer, store, modelClass, adapterPayload, null, 'findBelongsTo');
|
|
763
|
-
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)));
|
|
764
|
-
if (!payload.data && !payload.links && !payload.meta) {
|
|
765
|
-
return null;
|
|
766
|
-
}
|
|
767
|
-
payload = syncRelationshipDataFromLink(store, payload, identifier, relationship);
|
|
768
|
-
return store._push(payload);
|
|
769
|
-
}, null, `DS: Extract payload of ${identifier.type} : ${relationship.type}`);
|
|
770
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
771
|
-
promise = _guard(promise, _bind(_objectIsAlive, record));
|
|
772
|
-
}
|
|
773
|
-
return promise;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
// sync
|
|
777
|
-
// iterate over records in payload.data
|
|
778
|
-
// for each record
|
|
779
|
-
// assert that record.relationships[inverse] is either undefined (so we can fix it)
|
|
780
|
-
// or provide a data: {id, type} that matches the record that requested it
|
|
781
|
-
// return the relationship data for the parent
|
|
782
|
-
function syncRelationshipDataFromLink(store, payload, parentIdentifier, relationship) {
|
|
783
|
-
// ensure the right hand side (incoming payload) points to the parent record that
|
|
784
|
-
// requested this relationship
|
|
785
|
-
let relationshipData = payload.data ? iterateData(payload.data, (data, index) => {
|
|
786
|
-
const {
|
|
787
|
-
id,
|
|
788
|
-
type
|
|
789
|
-
} = data;
|
|
790
|
-
ensureRelationshipIsSetToParent(data, parentIdentifier, store, relationship, index);
|
|
791
|
-
return {
|
|
792
|
-
id,
|
|
793
|
-
type
|
|
794
|
-
};
|
|
795
|
-
}) : null;
|
|
796
|
-
const relatedDataHash = {};
|
|
797
|
-
if ('meta' in payload) {
|
|
798
|
-
relatedDataHash.meta = payload.meta;
|
|
799
|
-
}
|
|
800
|
-
if ('links' in payload) {
|
|
801
|
-
relatedDataHash.links = payload.links;
|
|
802
|
-
}
|
|
803
|
-
if ('data' in payload) {
|
|
804
|
-
relatedDataHash.data = relationshipData;
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
// now, push the left hand side (the parent record) to ensure things are in sync, since
|
|
808
|
-
// the payload will be pushed with store._push
|
|
809
|
-
const parentPayload = {
|
|
810
|
-
id: parentIdentifier.id,
|
|
811
|
-
type: parentIdentifier.type,
|
|
812
|
-
relationships: {
|
|
813
|
-
[relationship.key]: relatedDataHash
|
|
814
|
-
}
|
|
815
|
-
};
|
|
816
|
-
if (!Array.isArray(payload.included)) {
|
|
817
|
-
payload.included = [];
|
|
818
|
-
}
|
|
819
|
-
payload.included.push(parentPayload);
|
|
820
|
-
return payload;
|
|
821
|
-
}
|
|
822
|
-
function ensureRelationshipIsSetToParent(payload, parentIdentifier, store, parentRelationship, index) {
|
|
823
|
-
let {
|
|
824
|
-
id,
|
|
825
|
-
type
|
|
826
|
-
} = payload;
|
|
827
|
-
if (!payload.relationships) {
|
|
828
|
-
payload.relationships = {};
|
|
829
|
-
}
|
|
830
|
-
let {
|
|
831
|
-
relationships
|
|
832
|
-
} = payload;
|
|
833
|
-
let inverse = getInverse(store, parentIdentifier, parentRelationship, type);
|
|
834
|
-
if (inverse) {
|
|
835
|
-
let {
|
|
836
|
-
inverseKey,
|
|
837
|
-
kind
|
|
838
|
-
} = inverse;
|
|
839
|
-
let relationshipData = relationships[inverseKey] && relationships[inverseKey].data;
|
|
840
|
-
if (isDevelopingApp()) {
|
|
841
|
-
if (typeof relationshipData !== 'undefined' && !relationshipDataPointsToParent(relationshipData, parentIdentifier)) {
|
|
842
|
-
let inspect = function inspect(thing) {
|
|
843
|
-
return `'${JSON.stringify(thing)}'`;
|
|
844
|
-
};
|
|
845
|
-
let quotedType = inspect(type);
|
|
846
|
-
let quotedInverse = inspect(inverseKey);
|
|
847
|
-
let expected = inspect({
|
|
848
|
-
id: parentIdentifier.id,
|
|
849
|
-
type: parentIdentifier.type
|
|
850
|
-
});
|
|
851
|
-
let expectedModel = `${parentIdentifier.type}:${parentIdentifier.id}`;
|
|
852
|
-
let got = inspect(relationshipData);
|
|
853
|
-
let prefix = typeof index === 'number' ? `data[${index}]` : `data`;
|
|
854
|
-
let path = `${prefix}.relationships.${inverseKey}.data`;
|
|
855
|
-
let other = relationshipData ? `<${relationshipData.type}:${relationshipData.id}>` : null;
|
|
856
|
-
let relationshipFetched = `${expectedModel}.${parentRelationship.kind}("${parentRelationship.name}")`;
|
|
857
|
-
let includedRecord = `<${type}:${id}>`;
|
|
858
|
-
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');
|
|
859
|
-
assert(message);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
if (kind !== 'hasMany' || typeof relationshipData !== 'undefined') {
|
|
863
|
-
relationships[inverseKey] = relationships[inverseKey] || {};
|
|
864
|
-
relationships[inverseKey].data = fixRelationshipData(relationshipData, kind, parentIdentifier);
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
function metaIsRelationshipDefinition(meta) {
|
|
869
|
-
return typeof meta._inverseKey === 'function';
|
|
870
|
-
}
|
|
871
|
-
function inverseForRelationship(store, identifier, key) {
|
|
872
|
-
const definition = store.getSchemaDefinitionService().relationshipsDefinitionFor(identifier)[key];
|
|
873
|
-
if (!definition) {
|
|
874
|
-
return null;
|
|
875
|
-
}
|
|
876
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE)) {
|
|
877
|
-
if (metaIsRelationshipDefinition(definition)) {
|
|
878
|
-
const modelClass = store.modelFor(identifier.type);
|
|
879
|
-
return definition._inverseKey(store, modelClass);
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
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);
|
|
883
|
-
return definition.options.inverse;
|
|
884
|
-
}
|
|
885
|
-
function getInverse(store, parentIdentifier, parentRelationship, type) {
|
|
886
|
-
let {
|
|
887
|
-
name: lhs_relationshipName
|
|
888
|
-
} = parentRelationship;
|
|
889
|
-
let {
|
|
890
|
-
type: parentType
|
|
891
|
-
} = parentIdentifier;
|
|
892
|
-
let inverseKey = inverseForRelationship(store, {
|
|
893
|
-
type: parentType
|
|
894
|
-
}, lhs_relationshipName);
|
|
895
|
-
if (inverseKey) {
|
|
896
|
-
const definition = store.getSchemaDefinitionService().relationshipsDefinitionFor({
|
|
897
|
-
type
|
|
898
|
-
});
|
|
899
|
-
let {
|
|
900
|
-
kind
|
|
901
|
-
} = definition[inverseKey];
|
|
902
|
-
return {
|
|
903
|
-
inverseKey,
|
|
904
|
-
kind
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
function relationshipDataPointsToParent(relationshipData, identifier) {
|
|
909
|
-
if (relationshipData === null) {
|
|
910
|
-
return false;
|
|
911
|
-
}
|
|
912
|
-
if (Array.isArray(relationshipData)) {
|
|
913
|
-
if (relationshipData.length === 0) {
|
|
914
|
-
return false;
|
|
915
|
-
}
|
|
916
|
-
for (let i = 0; i < relationshipData.length; i++) {
|
|
917
|
-
let entry = relationshipData[i];
|
|
918
|
-
if (validateRelationshipEntry(entry, identifier)) {
|
|
919
|
-
return true;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
} else {
|
|
923
|
-
return validateRelationshipEntry(relationshipData, identifier);
|
|
924
|
-
}
|
|
925
|
-
return false;
|
|
926
|
-
}
|
|
927
|
-
function fixRelationshipData(relationshipData, relationshipKind, {
|
|
928
|
-
id,
|
|
929
|
-
type
|
|
930
|
-
}) {
|
|
931
|
-
let parentRelationshipData = {
|
|
932
|
-
id,
|
|
933
|
-
type
|
|
934
|
-
};
|
|
935
|
-
let payload;
|
|
936
|
-
if (relationshipKind === 'hasMany') {
|
|
937
|
-
payload = relationshipData || [];
|
|
938
|
-
if (relationshipData) {
|
|
939
|
-
// these arrays could be massive so this is better than filter
|
|
940
|
-
// Note: this is potentially problematic if type/id are not in the
|
|
941
|
-
// same state of normalization.
|
|
942
|
-
let found = relationshipData.find(v => {
|
|
943
|
-
return v.type === parentRelationshipData.type && v.id === parentRelationshipData.id;
|
|
944
|
-
});
|
|
945
|
-
if (!found) {
|
|
946
|
-
payload.push(parentRelationshipData);
|
|
947
|
-
}
|
|
948
|
-
} else {
|
|
949
|
-
payload.push(parentRelationshipData);
|
|
950
|
-
}
|
|
951
|
-
} else {
|
|
952
|
-
payload = relationshipData || {};
|
|
953
|
-
Object.assign(payload, parentRelationshipData);
|
|
954
|
-
}
|
|
955
|
-
return payload;
|
|
956
|
-
}
|
|
957
|
-
function validateRelationshipEntry({
|
|
958
|
-
id
|
|
959
|
-
}, {
|
|
960
|
-
id: parentModelID
|
|
961
|
-
}) {
|
|
962
|
-
return id && id.toString() === parentModelID;
|
|
963
|
-
}
|
|
964
|
-
function _bind(fn, ...args) {
|
|
965
|
-
return function () {
|
|
966
|
-
return fn.apply(undefined, args);
|
|
967
|
-
};
|
|
968
|
-
}
|
|
969
|
-
function _guard(promise, test) {
|
|
970
|
-
let guarded = promise.finally(() => {
|
|
971
|
-
if (!test()) {
|
|
972
|
-
guarded._subscribers.length = 0;
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
return guarded;
|
|
976
|
-
}
|
|
977
|
-
function _objectIsAlive(object) {
|
|
978
|
-
return !(object.isDestroyed || object.isDestroying);
|
|
979
|
-
}
|
|
980
|
-
function payloadIsNotBlank(adapterPayload) {
|
|
981
|
-
if (Array.isArray(adapterPayload)) {
|
|
982
|
-
return true;
|
|
983
|
-
} else {
|
|
984
|
-
return Object.keys(adapterPayload || {}).length;
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
function guardDestroyedStore(promise, store, label) {
|
|
988
|
-
let token;
|
|
989
|
-
if (isDevelopingApp()) {
|
|
990
|
-
token = store._trackAsyncRequestStart(label);
|
|
991
|
-
}
|
|
992
|
-
let wrapperPromise = resolve(promise, label).then(_v => {
|
|
993
|
-
if (!_objectIsAlive(store)) {
|
|
994
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
995
|
-
deprecate(`A Promise did not resolve by the time the store was destroyed. This will error in a future release.`, false, {
|
|
996
|
-
id: 'ember-data:rsvp-unresolved-async',
|
|
997
|
-
until: '5.0',
|
|
998
|
-
for: '@ember-data/store',
|
|
999
|
-
since: {
|
|
1000
|
-
available: '4.5',
|
|
1001
|
-
enabled: '4.5'
|
|
1002
|
-
}
|
|
1003
|
-
});
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
return promise;
|
|
1007
|
-
});
|
|
1008
|
-
return _guard(wrapperPromise, () => {
|
|
1009
|
-
if (isDevelopingApp()) {
|
|
1010
|
-
store._trackAsyncRequestEnd(token);
|
|
1011
|
-
}
|
|
1012
|
-
return _objectIsAlive(store);
|
|
1013
|
-
});
|
|
1014
|
-
}
|
|
1015
636
|
|
|
1016
637
|
/**
|
|
1017
638
|
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
@@ -1433,7 +1054,7 @@ let PromiseManyArray = (_class$4 = class PromiseManyArray {
|
|
|
1433
1054
|
}
|
|
1434
1055
|
return false;
|
|
1435
1056
|
};
|
|
1436
|
-
} else if (
|
|
1057
|
+
} else if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
1437
1058
|
const meta = Ember.meta(this);
|
|
1438
1059
|
meta.hasMixin = mixin => {
|
|
1439
1060
|
assert(`Do not use A() on an EmberData PromiseManyArray`);
|
|
@@ -1655,7 +1276,7 @@ function tapPromise(proxy, promise) {
|
|
|
1655
1276
|
proxy.isSettled = false;
|
|
1656
1277
|
proxy.isFulfilled = false;
|
|
1657
1278
|
proxy.isRejected = false;
|
|
1658
|
-
return resolve(promise).then(content => {
|
|
1279
|
+
return Promise.resolve(promise).then(content => {
|
|
1659
1280
|
proxy.isPending = false;
|
|
1660
1281
|
proxy.isFulfilled = true;
|
|
1661
1282
|
proxy.isSettled = true;
|
|
@@ -1718,7 +1339,7 @@ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_MANY_ARRAY_BEHA
|
|
|
1718
1339
|
`record.relationshipFor(key)`.
|
|
1719
1340
|
*/
|
|
1720
1341
|
let assertPolymorphicType;
|
|
1721
|
-
if (
|
|
1342
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
1722
1343
|
let checkPolymorphic = function checkPolymorphic(modelClass, addedModelClass) {
|
|
1723
1344
|
if (modelClass.__isMixin) {
|
|
1724
1345
|
return modelClass.__mixin.detect(addedModelClass.PrototypeMixin) ||
|
|
@@ -2061,7 +1682,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
2061
1682
|
let jsonApiDoc = data;
|
|
2062
1683
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
2063
1684
|
if (data.then) {
|
|
2064
|
-
jsonApiDoc = await
|
|
1685
|
+
jsonApiDoc = await data;
|
|
2065
1686
|
if (jsonApiDoc !== data) {
|
|
2066
1687
|
deprecate(`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`, false, {
|
|
2067
1688
|
id: 'ember-data:deprecate-promise-proxies',
|
|
@@ -2076,7 +1697,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
2076
1697
|
}
|
|
2077
1698
|
}
|
|
2078
1699
|
let record = this.store.push(jsonApiDoc);
|
|
2079
|
-
if (
|
|
1700
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
2080
1701
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
2081
1702
|
assertPolymorphicType(this.belongsToRelationship.identifier, this.belongsToRelationship.definition, recordIdentifierFor$1(record), this.store);
|
|
2082
1703
|
}
|
|
@@ -2554,7 +2175,7 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2554
2175
|
let payload = objectOrPromise;
|
|
2555
2176
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_PROMISE_PROXIES)) {
|
|
2556
2177
|
if (objectOrPromise.then) {
|
|
2557
|
-
payload = await
|
|
2178
|
+
payload = await objectOrPromise;
|
|
2558
2179
|
if (payload !== objectOrPromise) {
|
|
2559
2180
|
deprecate(`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`, false, {
|
|
2560
2181
|
id: 'ember-data:deprecate-promise-proxies',
|
|
@@ -2587,7 +2208,7 @@ let HasManyReference = (_class$2 = class HasManyReference {
|
|
|
2587
2208
|
data: obj
|
|
2588
2209
|
});
|
|
2589
2210
|
}
|
|
2590
|
-
if (
|
|
2211
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
2591
2212
|
let relationshipMeta = this.hasManyRelationship.definition;
|
|
2592
2213
|
let identifier = this.hasManyRelationship.identifier;
|
|
2593
2214
|
|
|
@@ -2938,7 +2559,7 @@ class LegacySupport {
|
|
|
2938
2559
|
const promise = this._findHasManyByJsonApiResource(jsonApi, this.identifier, relationship, options);
|
|
2939
2560
|
if (!promise) {
|
|
2940
2561
|
manyArray.isLoaded = true;
|
|
2941
|
-
return resolve(manyArray);
|
|
2562
|
+
return Promise.resolve(manyArray);
|
|
2942
2563
|
}
|
|
2943
2564
|
loadingPromise = promise.then(() => handleCompletedRelationshipRequest(this, key, relationship, manyArray), e => handleCompletedRelationshipRequest(this, key, relationship, manyArray, e));
|
|
2944
2565
|
this._relationshipPromisesCache[key] = loadingPromise;
|
|
@@ -3039,7 +2660,7 @@ class LegacySupport {
|
|
|
3039
2660
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
3040
2661
|
const graph = graphFor(this.store);
|
|
3041
2662
|
const relationship = graph.get(this.identifier, name);
|
|
3042
|
-
if (
|
|
2663
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3043
2664
|
if (kind) {
|
|
3044
2665
|
let modelName = this.identifier.type;
|
|
3045
2666
|
let actualRelationshipKind = relationship.definition.kind;
|
|
@@ -3074,66 +2695,46 @@ class LegacySupport {
|
|
|
3074
2695
|
shouldForceReload
|
|
3075
2696
|
} = state;
|
|
3076
2697
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
3077
|
-
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
|
+
};
|
|
3078
2711
|
|
|
3079
2712
|
// fetch via link
|
|
3080
2713
|
if (shouldFindViaLink) {
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
/*
|
|
3089
|
-
If a relationship was originally populated by the adapter as a link
|
|
3090
|
-
(as opposed to a list of IDs), this method is called when the
|
|
3091
|
-
relationship is fetched.
|
|
3092
|
-
The link (which is usually a URL) is passed through unchanged, so the
|
|
3093
|
-
adapter can make whatever request it wants.
|
|
3094
|
-
The usual use-case is for the server to register a URL as a link, and
|
|
3095
|
-
then use that URL in the future to make a request for the relationship.
|
|
3096
|
-
*/
|
|
3097
|
-
assert(`You tried to load a hasMany relationship but you have no adapter (for ${parentIdentifier.type})`, adapter);
|
|
3098
|
-
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');
|
|
3099
|
-
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
|
+
});
|
|
3100
2721
|
}
|
|
3101
2722
|
const preferLocalCache = hasReceivedData && !isEmpty;
|
|
3102
|
-
const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
if (allInverseRecordsAreLoaded) {
|
|
3107
|
-
return;
|
|
3108
|
-
}
|
|
3109
|
-
assert(`Expected collection to be an array`, Array.isArray(resource.data));
|
|
3110
|
-
if (allInverseRecordsAreLoaded) {
|
|
3111
|
-
return;
|
|
3112
|
-
}
|
|
3113
|
-
let finds = new Array(resource.data.length);
|
|
3114
|
-
let cache = this.store._fetchManager;
|
|
3115
|
-
for (let i = 0; i < resource.data.length; i++) {
|
|
3116
|
-
const identifier = resource.data[i];
|
|
3117
|
-
assert(`expected a stable identifier`, isStableIdentifier(identifier));
|
|
3118
|
-
finds[i] = cache.fetchDataIfNeededForIdentifier(identifier, options);
|
|
3119
|
-
}
|
|
3120
|
-
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;
|
|
3121
2727
|
}
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
// fetch by data
|
|
3125
|
-
if (hasData || hasLocalPartialData) {
|
|
3126
|
-
const identifiers = resource.data;
|
|
2728
|
+
const hasData = hasReceivedData && !isEmpty;
|
|
2729
|
+
if (attemptLocalCache || hasData || hasLocalPartialData) {
|
|
3127
2730
|
assert(`Expected collection to be an array`, Array.isArray(identifiers));
|
|
3128
2731
|
assert(`Expected stable identifiers`, identifiers.every(isStableIdentifier));
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
}
|
|
3136
|
-
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
|
+
});
|
|
3137
2738
|
}
|
|
3138
2739
|
|
|
3139
2740
|
// we were explicitly told we have no data and no links.
|
|
@@ -3144,7 +2745,14 @@ class LegacySupport {
|
|
|
3144
2745
|
}
|
|
3145
2746
|
_findBelongsToByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
3146
2747
|
if (!resource) {
|
|
3147
|
-
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;
|
|
3148
2756
|
}
|
|
3149
2757
|
const identifier = resource.data ? resource.data : null;
|
|
3150
2758
|
assert(`Expected a stable identifier`, !identifier || isStableIdentifier(identifier));
|
|
@@ -3155,53 +2763,65 @@ class LegacySupport {
|
|
|
3155
2763
|
isEmpty,
|
|
3156
2764
|
shouldForceReload
|
|
3157
2765
|
} = relationship.state;
|
|
3158
|
-
|
|
3159
|
-
// short circuit if we are already loading
|
|
3160
|
-
let pendingRequest = identifier && this.store._fetchManager.getPendingFetch(identifier, options);
|
|
3161
|
-
if (pendingRequest) {
|
|
3162
|
-
return pendingRequest;
|
|
3163
|
-
}
|
|
3164
2766
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
3165
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
|
+
};
|
|
3166
2778
|
|
|
3167
2779
|
// fetch via link
|
|
3168
2780
|
if (shouldFindViaLink) {
|
|
3169
|
-
const
|
|
3170
|
-
|
|
3171
|
-
|
|
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;
|
|
3172
2790
|
}
|
|
3173
|
-
|
|
3174
|
-
|
|
2791
|
+
const preferLocalCache = hasReceivedData && allInverseRecordsAreLoaded && !isEmpty;
|
|
2792
|
+
const hasLocalPartialData = hasDematerializedInverse || isEmpty && resource.data;
|
|
3175
2793
|
// null is explicit empty, undefined is "we don't know anything"
|
|
3176
|
-
const localDataIsEmpty =
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
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;
|
|
3200
2820
|
}
|
|
3201
2821
|
|
|
3202
2822
|
// we were explicitly told we have no data and no links.
|
|
3203
2823
|
// TODO if the relationshipIsStale, should we hit the adapter anyway?
|
|
3204
|
-
return resolve(null);
|
|
2824
|
+
return Promise.resolve(null);
|
|
3205
2825
|
}
|
|
3206
2826
|
destroy() {
|
|
3207
2827
|
this.isDestroying = true;
|
|
@@ -3250,11 +2870,14 @@ function handleCompletedRelationshipRequest(recordExt, key, relationship, value,
|
|
|
3250
2870
|
if (proxy.content && proxy.content.isDestroying) {
|
|
3251
2871
|
proxy.set('content', null);
|
|
3252
2872
|
}
|
|
2873
|
+
recordExt.store.notifications._flush();
|
|
3253
2874
|
}
|
|
3254
2875
|
throw error;
|
|
3255
2876
|
}
|
|
3256
2877
|
if (isHasMany) {
|
|
3257
2878
|
value.isLoaded = true;
|
|
2879
|
+
} else {
|
|
2880
|
+
recordExt.store.notifications._flush();
|
|
3258
2881
|
}
|
|
3259
2882
|
relationship.state.hasFailedLoadAttempt = false;
|
|
3260
2883
|
// only set to not stale if no error is thrown
|
|
@@ -3561,7 +3184,7 @@ let RecordState = (_class3 = class RecordState {
|
|
|
3561
3184
|
|
|
3562
3185
|
// we instantiate lazily
|
|
3563
3186
|
// so we grab anything we don't have yet
|
|
3564
|
-
if (!
|
|
3187
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
3565
3188
|
const lastRequest = requests.getLastRequestForRecord(identity);
|
|
3566
3189
|
if (lastRequest) {
|
|
3567
3190
|
handleRequest(lastRequest);
|
|
@@ -3820,7 +3443,7 @@ class RelationshipDefinition {
|
|
|
3820
3443
|
inverse = modelClass.inverseFor(this.key, store);
|
|
3821
3444
|
}
|
|
3822
3445
|
// TODO make this error again for the non-polymorphic case
|
|
3823
|
-
if (
|
|
3446
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3824
3447
|
if (!this.options.polymorphic) {
|
|
3825
3448
|
modelClass.typeForRelationship(this.key, store);
|
|
3826
3449
|
}
|
|
@@ -3938,7 +3561,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3938
3561
|
_initializerDefineProperty(this, "isReloading", _descriptor, this);
|
|
3939
3562
|
}
|
|
3940
3563
|
init(options = {}) {
|
|
3941
|
-
if (
|
|
3564
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
3942
3565
|
if (!options._secretInit && !options._createProps) {
|
|
3943
3566
|
throw new Error('You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.');
|
|
3944
3567
|
}
|
|
@@ -3951,7 +3574,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3951
3574
|
super.init(options);
|
|
3952
3575
|
let identity = _secretInit.identifier;
|
|
3953
3576
|
_secretInit.cb(this, _secretInit.cache, identity, _secretInit.store);
|
|
3954
|
-
this.___recordState =
|
|
3577
|
+
this.___recordState = macroCondition(getOwnConfig().env.DEBUG) ? new RecordState(this) : null;
|
|
3955
3578
|
this.setProperties(createProps);
|
|
3956
3579
|
let notifications = store.notifications;
|
|
3957
3580
|
this.___private_notifications = notifications.subscribe(identity, (identifier, type, key) => {
|
|
@@ -4196,7 +3819,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4196
3819
|
return this.currentState.isError;
|
|
4197
3820
|
}
|
|
4198
3821
|
set isError(v) {
|
|
4199
|
-
if (
|
|
3822
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4200
3823
|
throw new Error(`isError is not directly settable`);
|
|
4201
3824
|
}
|
|
4202
3825
|
}
|
|
@@ -4221,7 +3844,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4221
3844
|
// this guard exists, because some dev-only deprecation code
|
|
4222
3845
|
// (addListener via validatePropertyInjections) invokes toString before the
|
|
4223
3846
|
// object is real.
|
|
4224
|
-
if (
|
|
3847
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4225
3848
|
try {
|
|
4226
3849
|
return recordIdentifierFor(this).id;
|
|
4227
3850
|
} catch {
|
|
@@ -4256,7 +3879,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4256
3879
|
// when using legacy/classic ember classes. Basically: lazy in prod and eager in dev.
|
|
4257
3880
|
// so we do this to try to steer folks to the nicer "dont user currentState"
|
|
4258
3881
|
// error.
|
|
4259
|
-
if (!
|
|
3882
|
+
if (macroCondition(!getOwnConfig().env.DEBUG)) {
|
|
4260
3883
|
if (!this.___recordState) {
|
|
4261
3884
|
this.___recordState = new RecordState(this);
|
|
4262
3885
|
}
|
|
@@ -4352,7 +3975,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4352
3975
|
@return {Object} an object whose values are primitive JSON values only
|
|
4353
3976
|
*/
|
|
4354
3977
|
serialize(options) {
|
|
4355
|
-
return storeFor$1(this).
|
|
3978
|
+
return storeFor$1(this).serializeRecord(this, options);
|
|
4356
3979
|
}
|
|
4357
3980
|
|
|
4358
3981
|
/*
|
|
@@ -4448,7 +4071,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4448
4071
|
} = this.currentState;
|
|
4449
4072
|
this.deleteRecord();
|
|
4450
4073
|
if (isNew) {
|
|
4451
|
-
return resolve(this);
|
|
4074
|
+
return Promise.resolve(this);
|
|
4452
4075
|
}
|
|
4453
4076
|
return this.save(options).then(_ => {
|
|
4454
4077
|
run(() => {
|
|
@@ -4565,7 +4188,12 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4565
4188
|
*/
|
|
4566
4189
|
// TODO @deprecate in favor of a public API or examples of how to test successfully
|
|
4567
4190
|
_createSnapshot() {
|
|
4568
|
-
|
|
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));
|
|
4569
4197
|
}
|
|
4570
4198
|
|
|
4571
4199
|
/**
|
|
@@ -4605,7 +4233,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4605
4233
|
save(options) {
|
|
4606
4234
|
let promise;
|
|
4607
4235
|
if (this.currentState.isNew && this.currentState.isDeleted) {
|
|
4608
|
-
promise = resolve(this);
|
|
4236
|
+
promise = Promise.resolve(this);
|
|
4609
4237
|
} else {
|
|
4610
4238
|
promise = storeFor$1(this).saveRecord(this, options);
|
|
4611
4239
|
}
|
|
@@ -4638,16 +4266,19 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4638
4266
|
adapter returns successfully or rejected if the adapter returns
|
|
4639
4267
|
with an error.
|
|
4640
4268
|
*/
|
|
4641
|
-
reload(
|
|
4642
|
-
let options = {};
|
|
4643
|
-
if (typeof _options === 'object' && _options !== null && _options.adapterOptions) {
|
|
4644
|
-
options.adapterOptions = _options.adapterOptions;
|
|
4645
|
-
}
|
|
4269
|
+
reload(options = {}) {
|
|
4646
4270
|
options.isReloading = true;
|
|
4647
|
-
|
|
4271
|
+
options.reload = true;
|
|
4272
|
+
const identifier = recordIdentifierFor(this);
|
|
4648
4273
|
assert(`You cannot reload a record without an ID`, identifier.id);
|
|
4649
4274
|
this.isReloading = true;
|
|
4650
|
-
const promise = storeFor$1(this).
|
|
4275
|
+
const promise = storeFor$1(this).request({
|
|
4276
|
+
op: 'findRecord',
|
|
4277
|
+
data: {
|
|
4278
|
+
options,
|
|
4279
|
+
record: identifier
|
|
4280
|
+
}
|
|
4281
|
+
}).then(() => this).finally(() => {
|
|
4651
4282
|
this.isReloading = false;
|
|
4652
4283
|
});
|
|
4653
4284
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_SAVE_PROMISE_ACCESS)) {
|
|
@@ -4987,7 +4618,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4987
4618
|
if (possibleRelationships.length === 0) {
|
|
4988
4619
|
return null;
|
|
4989
4620
|
}
|
|
4990
|
-
if (
|
|
4621
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4991
4622
|
let filteredRelationships = possibleRelationships.filter(possibleRelationship => {
|
|
4992
4623
|
let optionsForRelationship = possibleRelationship.options;
|
|
4993
4624
|
return name === optionsForRelationship.inverse;
|
|
@@ -5005,7 +4636,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5005
4636
|
}
|
|
5006
4637
|
|
|
5007
4638
|
// ensure inverse is properly configured
|
|
5008
|
-
if (
|
|
4639
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5009
4640
|
if (isPolymorphic) {
|
|
5010
4641
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_EXPLICIT_POLYMORPHISM)) {
|
|
5011
4642
|
if (!inverseOptions.as) {
|
|
@@ -5027,7 +4658,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5027
4658
|
}
|
|
5028
4659
|
|
|
5029
4660
|
// ensure we are properly configured
|
|
5030
|
-
if (
|
|
4661
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5031
4662
|
if (inverseOptions.polymorphic) {
|
|
5032
4663
|
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_NON_EXPLICIT_POLYMORPHISM)) {
|
|
5033
4664
|
if (!options.as) {
|
|
@@ -5281,7 +4912,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
5281
4912
|
for (let i = 0; i < relationships.length; i++) {
|
|
5282
4913
|
let key = relationships[i];
|
|
5283
4914
|
let value = rels[key];
|
|
5284
|
-
map.set(value.key, value);
|
|
4915
|
+
map.set(value.name || value.key, value);
|
|
5285
4916
|
}
|
|
5286
4917
|
return map;
|
|
5287
4918
|
}
|
|
@@ -5728,16 +5359,21 @@ if (macroCondition(getOwnConfig().includeDataAdapter)) {
|
|
|
5728
5359
|
@private
|
|
5729
5360
|
*/
|
|
5730
5361
|
Model.prototype._debugInfo = function () {
|
|
5731
|
-
let attributes = ['id'];
|
|
5732
5362
|
let relationships = {};
|
|
5733
5363
|
let expensiveProperties = [];
|
|
5734
|
-
|
|
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');
|
|
5735
5370
|
let groups = [{
|
|
5736
5371
|
name: 'Attributes',
|
|
5737
5372
|
properties: attributes,
|
|
5738
5373
|
expand: true
|
|
5739
5374
|
}];
|
|
5740
|
-
|
|
5375
|
+
Object.keys(relDefs).forEach(name => {
|
|
5376
|
+
const relationship = relDefs[name];
|
|
5741
5377
|
let properties = relationships[relationship.kind];
|
|
5742
5378
|
if (properties === undefined) {
|
|
5743
5379
|
properties = relationships[relationship.kind] = [];
|
|
@@ -5765,7 +5401,7 @@ if (macroCondition(getOwnConfig().includeDataAdapter)) {
|
|
|
5765
5401
|
};
|
|
5766
5402
|
};
|
|
5767
5403
|
}
|
|
5768
|
-
if (
|
|
5404
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
5769
5405
|
let lookupDescriptor = function lookupDescriptor(obj, keyName) {
|
|
5770
5406
|
let current = obj;
|
|
5771
5407
|
do {
|
|
@@ -6014,7 +5650,7 @@ function belongsTo(modelName, options) {
|
|
|
6014
5650
|
return null;
|
|
6015
5651
|
}
|
|
6016
5652
|
const support = lookupLegacySupport(this);
|
|
6017
|
-
if (
|
|
5653
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6018
5654
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6019
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()}`);
|
|
6020
5656
|
}
|
|
@@ -6033,7 +5669,7 @@ function belongsTo(modelName, options) {
|
|
|
6033
5669
|
},
|
|
6034
5670
|
set(key, value) {
|
|
6035
5671
|
const support = lookupLegacySupport(this);
|
|
6036
|
-
if (
|
|
5672
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6037
5673
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6038
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()}`);
|
|
6039
5675
|
}
|
|
@@ -6264,7 +5900,7 @@ function hasMany(type, options) {
|
|
|
6264
5900
|
};
|
|
6265
5901
|
return computed({
|
|
6266
5902
|
get(key) {
|
|
6267
|
-
if (
|
|
5903
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6268
5904
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6269
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()}`);
|
|
6270
5906
|
}
|
|
@@ -6275,7 +5911,7 @@ function hasMany(type, options) {
|
|
|
6275
5911
|
return lookupLegacySupport(this).getHasMany(key);
|
|
6276
5912
|
},
|
|
6277
5913
|
set(key, records) {
|
|
6278
|
-
if (
|
|
5914
|
+
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
6279
5915
|
if (['currentState'].indexOf(key) !== -1) {
|
|
6280
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()}`);
|
|
6281
5917
|
}
|