@ember-data/model 4.8.0-alpha.4 → 4.8.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/-private/belongs-to.js +4 -4
- package/addon/-private/deprecated-promise-proxy.ts +54 -0
- package/addon/-private/has-many.js +7 -5
- package/addon/-private/legacy-relationships-support.ts +182 -118
- package/addon/-private/many-array.ts +211 -249
- package/addon/-private/model.js +147 -73
- package/addon/-private/promise-belongs-to.ts +1 -1
- package/addon/-private/promise-many-array.ts +35 -13
- package/addon/-private/promise-proxy-base.js +4 -0
- package/addon/-private/record-state.ts +1 -1
- package/addon/-private/references/belongs-to.ts +35 -13
- package/addon/-private/references/has-many.ts +40 -17
- package/addon/-private/relationship-meta.ts +3 -1
- package/index.js +2 -0
- package/package.json +6 -6
|
@@ -1,45 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@module @ember-data/store
|
|
3
3
|
*/
|
|
4
|
-
import
|
|
5
|
-
import MutableArray from '@ember/array/mutable';
|
|
6
|
-
import { assert } from '@ember/debug';
|
|
7
|
-
import EmberObject, { get } from '@ember/object';
|
|
8
|
-
|
|
9
|
-
import { all } from 'rsvp';
|
|
4
|
+
import { assert, deprecate } from '@ember/debug';
|
|
10
5
|
|
|
6
|
+
import { DEPRECATE_PROMISE_PROXIES } from '@ember-data/private-build-infra/deprecations';
|
|
11
7
|
import type Store from '@ember-data/store';
|
|
12
|
-
import {
|
|
8
|
+
import { IDENTIFIER_ARRAY_TAG, MUTATE, RecordArray, recordIdentifierFor, SOURCE } from '@ember-data/store/-private';
|
|
13
9
|
import type ShimModelClass from '@ember-data/store/-private/legacy-model-support/shim-model-class';
|
|
14
|
-
import
|
|
10
|
+
import { IdentifierArrayCreateOptions } from '@ember-data/store/-private/record-arrays/identifier-array';
|
|
15
11
|
import type { CreateRecordProperties } from '@ember-data/store/-private/store-service';
|
|
16
|
-
import type {
|
|
17
|
-
import type { CollectionResourceRelationship, Links, PaginationLinks } from '@ember-data/types/q/ember-data-json-api';
|
|
12
|
+
import type { Links, PaginationLinks } from '@ember-data/types/q/ember-data-json-api';
|
|
18
13
|
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
19
14
|
import type { RecordData } from '@ember-data/types/q/record-data';
|
|
20
15
|
import type { RecordInstance } from '@ember-data/types/q/record-instance';
|
|
21
16
|
import type { FindOptions } from '@ember-data/types/q/store';
|
|
22
17
|
import type { Dict } from '@ember-data/types/q/utils';
|
|
23
18
|
|
|
24
|
-
import diffArray from './diff-array';
|
|
25
19
|
import { LegacySupport } from './legacy-relationships-support';
|
|
26
20
|
|
|
27
|
-
interface MutableArrayWithObject<T, M = T> extends EmberObject, MutableArray<M> {}
|
|
28
|
-
const MutableArrayWithObject = EmberObject.extend(MutableArray) as unknown as new <
|
|
29
|
-
T,
|
|
30
|
-
M = T
|
|
31
|
-
>() => MutableArrayWithObject<T, M>;
|
|
32
|
-
|
|
33
21
|
export interface ManyArrayCreateArgs {
|
|
22
|
+
identifiers: StableRecordIdentifier[];
|
|
23
|
+
type: string;
|
|
34
24
|
store: Store;
|
|
35
|
-
|
|
25
|
+
allowMutation: boolean;
|
|
26
|
+
manager: LegacySupport;
|
|
27
|
+
|
|
36
28
|
identifier: StableRecordIdentifier;
|
|
37
29
|
recordData: RecordData;
|
|
30
|
+
meta: Dict<unknown> | null;
|
|
31
|
+
links: Links | PaginationLinks | null;
|
|
38
32
|
key: string;
|
|
39
33
|
isPolymorphic: boolean;
|
|
40
34
|
isAsync: boolean;
|
|
41
35
|
_inverseIsAsync: boolean;
|
|
42
|
-
legacySupport: LegacySupport;
|
|
43
36
|
isLoaded: boolean;
|
|
44
37
|
}
|
|
45
38
|
/**
|
|
@@ -84,44 +77,26 @@ export interface ManyArrayCreateArgs {
|
|
|
84
77
|
|
|
85
78
|
@class ManyArray
|
|
86
79
|
@public
|
|
87
|
-
@extends Ember.EmberObject
|
|
88
|
-
@uses Ember.MutableArray
|
|
89
80
|
*/
|
|
90
|
-
export default class
|
|
81
|
+
export default class RelatedCollection extends RecordArray {
|
|
91
82
|
declare isAsync: boolean;
|
|
92
|
-
|
|
93
|
-
declare isPolymorphic: boolean;
|
|
94
|
-
declare _isDirty: boolean;
|
|
95
|
-
declare _isUpdating: boolean;
|
|
96
|
-
declare _hasNotified: boolean;
|
|
97
|
-
declare __hasArrayObservers: boolean;
|
|
98
|
-
declare hasArrayObservers: boolean; // override the base declaration
|
|
99
|
-
declare _length: number;
|
|
100
|
-
declare _meta: Dict<unknown> | null;
|
|
101
|
-
declare _links: Links | PaginationLinks | null;
|
|
102
|
-
declare currentState: StableRecordIdentifier[];
|
|
103
|
-
declare identifier: StableRecordIdentifier;
|
|
104
|
-
declare recordData: RecordData;
|
|
105
|
-
declare legacySupport: LegacySupport;
|
|
106
|
-
declare store: Store;
|
|
107
|
-
declare key: string;
|
|
108
|
-
declare type: DSModelSchema;
|
|
109
|
-
|
|
110
|
-
init() {
|
|
111
|
-
super.init();
|
|
112
|
-
|
|
113
|
-
/**
|
|
83
|
+
/**
|
|
114
84
|
The loading state of this array
|
|
115
85
|
|
|
116
86
|
@property {Boolean} isLoaded
|
|
117
87
|
@public
|
|
118
88
|
*/
|
|
119
|
-
this.isLoaded = this.isLoaded || false;
|
|
120
|
-
this.isAsync = this.isAsync || false;
|
|
121
89
|
|
|
122
|
-
|
|
90
|
+
declare isLoaded: boolean;
|
|
91
|
+
/**
|
|
92
|
+
`true` if the relationship is polymorphic, `false` otherwise.
|
|
123
93
|
|
|
124
|
-
|
|
94
|
+
@property {Boolean} isPolymorphic
|
|
95
|
+
@private
|
|
96
|
+
*/
|
|
97
|
+
declare isPolymorphic: boolean;
|
|
98
|
+
declare _inverseIsAsync: boolean;
|
|
99
|
+
/**
|
|
125
100
|
Metadata associated with the request for async hasMany relationships.
|
|
126
101
|
|
|
127
102
|
Example
|
|
@@ -158,206 +133,146 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
|
|
|
158
133
|
@property {Object | null} meta
|
|
159
134
|
@public
|
|
160
135
|
*/
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
/**
|
|
136
|
+
declare meta: Dict<unknown> | null;
|
|
137
|
+
/**
|
|
164
138
|
* Retrieve the links for this relationship
|
|
165
139
|
*
|
|
166
140
|
@property {Object | null} links
|
|
167
141
|
@public
|
|
168
142
|
*/
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this.currentState = [];
|
|
186
|
-
this._isUpdating = false;
|
|
187
|
-
this._isDirty = false;
|
|
188
|
-
/*
|
|
189
|
-
* Unfortunately ArrayProxy adds it's observers lazily,
|
|
190
|
-
* so in a first-render situation we may sometimes notify
|
|
191
|
-
* prior to the ArrayProxy having installed it's observers
|
|
192
|
-
* (which occurs during _revalidate()).
|
|
193
|
-
*
|
|
194
|
-
* This leads to the flush occuring on access, the flush takes
|
|
195
|
-
* the hasObservers codepath which in code out of our control
|
|
196
|
-
* notifies again leading to a glimmer rendering invalidation error.
|
|
197
|
-
*
|
|
198
|
-
* We use this flag to detect the case where we notified without
|
|
199
|
-
* array observers but observers were installed prior to flush.
|
|
200
|
-
*
|
|
201
|
-
* We do not need to fire array observers at all in this case
|
|
202
|
-
* since it will be the first-access for those observers.
|
|
203
|
-
*/
|
|
204
|
-
this._hasNotified = false;
|
|
205
|
-
// make sure we initialize to the correct state
|
|
206
|
-
// since the user has already accessed
|
|
207
|
-
this.retrieveLatest();
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// TODO refactor away _hasArrayObservers for tests
|
|
211
|
-
get _hasArrayObservers() {
|
|
212
|
-
// cast necessary because hasArrayObservers is typed as a ComputedProperty<boolean> vs a boolean;
|
|
213
|
-
return this.hasArrayObservers || this.__hasArrayObservers;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
notify() {
|
|
217
|
-
this._isDirty = true;
|
|
218
|
-
if (this._hasArrayObservers && !this._hasNotified) {
|
|
219
|
-
this.retrieveLatest();
|
|
220
|
-
} else {
|
|
221
|
-
this._hasNotified = true;
|
|
222
|
-
this.notifyPropertyChange('[]');
|
|
223
|
-
this.notifyPropertyChange('firstObject');
|
|
224
|
-
this.notifyPropertyChange('lastObject');
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
get length() {
|
|
229
|
-
if (this._isDirty) {
|
|
230
|
-
this.retrieveLatest();
|
|
231
|
-
}
|
|
232
|
-
// By using `get()`, the tracking system knows to pay attention to changes that occur.
|
|
233
|
-
get(this, '[]');
|
|
234
|
-
|
|
235
|
-
return this._length;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
set length(value) {
|
|
239
|
-
this._length = value;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
get links() {
|
|
243
|
-
get(this, '[]');
|
|
244
|
-
if (this._isDirty) {
|
|
245
|
-
this.retrieveLatest();
|
|
246
|
-
}
|
|
247
|
-
return this._links;
|
|
248
|
-
}
|
|
249
|
-
set links(v) {
|
|
250
|
-
this._links = v;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
get meta() {
|
|
254
|
-
get(this, '[]');
|
|
255
|
-
if (this._isDirty) {
|
|
256
|
-
this.retrieveLatest();
|
|
257
|
-
}
|
|
258
|
-
return this._meta;
|
|
259
|
-
}
|
|
260
|
-
set meta(v) {
|
|
261
|
-
this._meta = v;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
objectAt(index: number): RecordInstance | undefined {
|
|
265
|
-
if (this._isDirty) {
|
|
266
|
-
this.retrieveLatest();
|
|
267
|
-
}
|
|
268
|
-
let identifier = this.currentState[index];
|
|
269
|
-
if (identifier === undefined) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return this.store._instanceCache.getRecord(identifier);
|
|
143
|
+
declare links: Links | PaginationLinks | null;
|
|
144
|
+
declare identifier: StableRecordIdentifier;
|
|
145
|
+
declare recordData: RecordData;
|
|
146
|
+
// @ts-expect-error
|
|
147
|
+
declare _manager: LegacySupport;
|
|
148
|
+
declare store: Store;
|
|
149
|
+
declare key: string;
|
|
150
|
+
declare type: ShimModelClass;
|
|
151
|
+
|
|
152
|
+
constructor(options: ManyArrayCreateArgs) {
|
|
153
|
+
super(options as unknown as IdentifierArrayCreateOptions);
|
|
154
|
+
this.isLoaded = options.isLoaded || false;
|
|
155
|
+
this.isAsync = options.isAsync || false;
|
|
156
|
+
this.isPolymorphic = options.isPolymorphic || false;
|
|
157
|
+
this.identifier = options.identifier;
|
|
158
|
+
this.key = options.key;
|
|
274
159
|
}
|
|
275
160
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
identifiers = this.currentState.slice(idx, idx + amt);
|
|
287
|
-
this.recordData.removeFromHasMany(identifier, this.key, identifiers);
|
|
161
|
+
[MUTATE](prop: string, args: unknown[], result?: unknown) {
|
|
162
|
+
switch (prop) {
|
|
163
|
+
case 'length 0': {
|
|
164
|
+
this._manager.updateCache({
|
|
165
|
+
op: 'replaceRelatedRecords',
|
|
166
|
+
record: this.identifier,
|
|
167
|
+
field: this.key,
|
|
168
|
+
value: [],
|
|
169
|
+
});
|
|
170
|
+
break;
|
|
288
171
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
172
|
+
case 'replace cell': {
|
|
173
|
+
const [index, prior, value] = args as [number, StableRecordIdentifier, StableRecordIdentifier];
|
|
174
|
+
this._manager.updateCache({
|
|
175
|
+
op: 'replaceRelatedRecord',
|
|
176
|
+
record: this.identifier,
|
|
177
|
+
field: this.key,
|
|
178
|
+
value,
|
|
179
|
+
prior,
|
|
180
|
+
index,
|
|
181
|
+
});
|
|
182
|
+
break;
|
|
296
183
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
184
|
+
case 'push':
|
|
185
|
+
this._manager.updateCache({
|
|
186
|
+
op: 'addToRelatedRecords',
|
|
187
|
+
record: this.identifier,
|
|
188
|
+
field: this.key,
|
|
189
|
+
value: extractIdentifiersFromRecords(args as RecordInstance[]),
|
|
190
|
+
});
|
|
191
|
+
break;
|
|
192
|
+
case 'pop':
|
|
193
|
+
if (result) {
|
|
194
|
+
this._manager.updateCache({
|
|
195
|
+
op: 'removeFromRelatedRecords',
|
|
196
|
+
record: this.identifier,
|
|
197
|
+
field: this.key,
|
|
198
|
+
value: recordIdentifierFor(result as RecordInstance),
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case 'unshift':
|
|
204
|
+
this._manager.updateCache({
|
|
205
|
+
op: 'addToRelatedRecords',
|
|
206
|
+
record: this.identifier,
|
|
207
|
+
field: this.key,
|
|
208
|
+
value: extractIdentifiersFromRecords(args as RecordInstance[]),
|
|
209
|
+
index: 0,
|
|
210
|
+
});
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
case 'shift':
|
|
214
|
+
if (result) {
|
|
215
|
+
this._manager.updateCache({
|
|
216
|
+
op: 'removeFromRelatedRecords',
|
|
217
|
+
record: this.identifier,
|
|
218
|
+
field: this.key,
|
|
219
|
+
value: recordIdentifierFor(result as RecordInstance),
|
|
220
|
+
index: 0,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
case 'sort':
|
|
226
|
+
this._manager.updateCache({
|
|
227
|
+
op: 'sortRelatedRecords',
|
|
228
|
+
record: this.identifier,
|
|
229
|
+
field: this.key,
|
|
230
|
+
value: (result as RecordInstance[]).map(recordIdentifierFor),
|
|
231
|
+
});
|
|
232
|
+
break;
|
|
233
|
+
|
|
234
|
+
case 'splice': {
|
|
235
|
+
const [start, removeCount, ...adds] = args as [number, number, RecordInstance];
|
|
236
|
+
// detect a full replace
|
|
237
|
+
if (removeCount > 0 && adds.length === this[SOURCE].length) {
|
|
238
|
+
this._manager.updateCache({
|
|
239
|
+
op: 'replaceRelatedRecords',
|
|
240
|
+
record: this.identifier,
|
|
241
|
+
field: this.key,
|
|
242
|
+
value: extractIdentifiersFromRecords(adds),
|
|
243
|
+
});
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (removeCount > 0) {
|
|
247
|
+
this._manager.updateCache({
|
|
248
|
+
op: 'removeFromRelatedRecords',
|
|
249
|
+
record: this.identifier,
|
|
250
|
+
field: this.key,
|
|
251
|
+
value: (result as RecordInstance[]).map(recordIdentifierFor),
|
|
252
|
+
index: start,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (adds?.length) {
|
|
256
|
+
this._manager.updateCache({
|
|
257
|
+
op: 'addToRelatedRecords',
|
|
258
|
+
record: this.identifier,
|
|
259
|
+
field: this.key,
|
|
260
|
+
value: extractIdentifiersFromRecords(adds),
|
|
261
|
+
index: start,
|
|
262
|
+
});
|
|
325
263
|
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (jsonApi.meta) {
|
|
330
|
-
this._meta = jsonApi.meta;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (jsonApi.links) {
|
|
334
|
-
this._links = jsonApi.links;
|
|
335
|
-
}
|
|
336
264
|
|
|
337
|
-
|
|
338
|
-
// diff to find changes
|
|
339
|
-
let diff = diffArray(this.currentState, identifiers);
|
|
340
|
-
// it's null if no change found
|
|
341
|
-
if (diff.firstChangeIndex !== null) {
|
|
342
|
-
// we found a change
|
|
343
|
-
this.arrayContentWillChange(diff.firstChangeIndex, diff.removedCount, diff.addedCount);
|
|
344
|
-
this._length = identifiers.length;
|
|
345
|
-
this.currentState = identifiers;
|
|
346
|
-
this.arrayContentDidChange(diff.firstChangeIndex, diff.removedCount, diff.addedCount);
|
|
265
|
+
break;
|
|
347
266
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
this._length = identifiers.length;
|
|
351
|
-
this.currentState = identifiers;
|
|
267
|
+
default:
|
|
268
|
+
assert(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
352
269
|
}
|
|
353
|
-
|
|
354
|
-
this._isUpdating = false;
|
|
355
270
|
}
|
|
356
271
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
272
|
+
notify() {
|
|
273
|
+
const tag = this[IDENTIFIER_ARRAY_TAG];
|
|
274
|
+
tag.ref = null;
|
|
275
|
+
tag.shouldReset = true;
|
|
361
276
|
}
|
|
362
277
|
|
|
363
278
|
/**
|
|
@@ -384,7 +299,7 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
|
|
|
384
299
|
*/
|
|
385
300
|
reload(options?: FindOptions) {
|
|
386
301
|
// TODO this is odd, we don't ask the store for anything else like this?
|
|
387
|
-
return this.
|
|
302
|
+
return this._manager.reloadHasMany(this.key, options);
|
|
388
303
|
}
|
|
389
304
|
|
|
390
305
|
/**
|
|
@@ -405,18 +320,6 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
|
|
|
405
320
|
@public
|
|
406
321
|
@return {PromiseArray} promise
|
|
407
322
|
*/
|
|
408
|
-
save() {
|
|
409
|
-
let manyArray = this;
|
|
410
|
-
let promiseLabel = 'DS: ManyArray#save ' + this.type.modelName;
|
|
411
|
-
let promise = all(this.invoke('save'), promiseLabel).then(
|
|
412
|
-
() => manyArray,
|
|
413
|
-
null,
|
|
414
|
-
'DS: ManyArray#save return ManyArray'
|
|
415
|
-
);
|
|
416
|
-
|
|
417
|
-
// TODO deprecate returning a promiseArray here
|
|
418
|
-
return PromiseArray.create({ promise });
|
|
419
|
-
}
|
|
420
323
|
|
|
421
324
|
/**
|
|
422
325
|
Create a child record within the owner
|
|
@@ -427,11 +330,70 @@ export default class ManyArray extends MutableArrayWithObject<StableRecordIdenti
|
|
|
427
330
|
@return {Model} record
|
|
428
331
|
*/
|
|
429
332
|
createRecord(hash: CreateRecordProperties): RecordInstance {
|
|
430
|
-
const { store
|
|
333
|
+
const { store } = this;
|
|
431
334
|
|
|
432
|
-
const record = store.createRecord(
|
|
433
|
-
this.
|
|
335
|
+
const record = store.createRecord(this.modelName, hash);
|
|
336
|
+
this.push(record);
|
|
434
337
|
|
|
435
338
|
return record;
|
|
436
339
|
}
|
|
437
340
|
}
|
|
341
|
+
RelatedCollection.prototype.isAsync = false;
|
|
342
|
+
RelatedCollection.prototype.isPolymorphic = false;
|
|
343
|
+
RelatedCollection.prototype.identifier = null as unknown as StableRecordIdentifier;
|
|
344
|
+
RelatedCollection.prototype.recordData = null as unknown as RecordData;
|
|
345
|
+
RelatedCollection.prototype._inverseIsAsync = false;
|
|
346
|
+
RelatedCollection.prototype.key = '';
|
|
347
|
+
RelatedCollection.prototype.DEPRECATED_CLASS_NAME = 'ManyArray';
|
|
348
|
+
|
|
349
|
+
type PromiseProxyRecord = { then(): void; content: RecordInstance | null | undefined };
|
|
350
|
+
|
|
351
|
+
function assertRecordPassedToHasMany(record: RecordInstance | PromiseProxyRecord) {
|
|
352
|
+
assert(
|
|
353
|
+
`All elements of a hasMany relationship must be instances of Model, you passed $${typeof record}`,
|
|
354
|
+
(function () {
|
|
355
|
+
try {
|
|
356
|
+
recordIdentifierFor(record);
|
|
357
|
+
return true;
|
|
358
|
+
} catch {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
})()
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function extractIdentifiersFromRecords(records: RecordInstance[]): StableRecordIdentifier[] {
|
|
366
|
+
return records.map(extractIdentifierFromRecord);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function extractIdentifierFromRecord(recordOrPromiseRecord: PromiseProxyRecord | RecordInstance) {
|
|
370
|
+
if (DEPRECATE_PROMISE_PROXIES && isPromiseRecord(recordOrPromiseRecord)) {
|
|
371
|
+
let content = recordOrPromiseRecord.content;
|
|
372
|
+
assert(
|
|
373
|
+
'You passed in a promise that did not originate from an EmberData relationship. You can only pass promises that come from a belongsTo relationship.',
|
|
374
|
+
content !== undefined && content !== null
|
|
375
|
+
);
|
|
376
|
+
deprecate(
|
|
377
|
+
`You passed in a PromiseProxy to a Relationship API that now expects a resolved value. await the value before setting it.`,
|
|
378
|
+
false,
|
|
379
|
+
{
|
|
380
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
381
|
+
until: '5.0',
|
|
382
|
+
since: {
|
|
383
|
+
enabled: '4.8',
|
|
384
|
+
available: '4.8',
|
|
385
|
+
},
|
|
386
|
+
for: 'ember-data',
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
assertRecordPassedToHasMany(content);
|
|
390
|
+
return recordIdentifierFor(content);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
394
|
+
return recordIdentifierFor(recordOrPromiseRecord);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function isPromiseRecord(record: PromiseProxyRecord | RecordInstance): record is PromiseProxyRecord {
|
|
398
|
+
return !!record.then;
|
|
399
|
+
}
|