@ember-data/model 4.4.0-alpha.8 → 4.4.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/{errors.ts → errors.js} +55 -82
- package/addon/-private/system/{diff-array.ts → diff-array.js} +2 -8
- package/addon/-private/system/{many-array.ts → many-array.js} +29 -72
- package/addon/-private/system/promise-belongs-to.js +41 -0
- package/addon/-private/system/promise-many-array.ts +5 -17
- package/package.json +7 -7
- package/addon/-private/system/promise-belongs-to.ts +0 -72
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
import { A } from '@ember/array';
|
|
2
|
-
import type NativeArray from '@ember/array/-private/native-array';
|
|
1
|
+
import { A, makeArray } from '@ember/array';
|
|
3
2
|
import ArrayProxy from '@ember/array/proxy';
|
|
4
3
|
import { computed, get } from '@ember/object';
|
|
5
4
|
import { mapBy, not } from '@ember/object/computed';
|
|
6
5
|
|
|
7
|
-
type ValidationError = {
|
|
8
|
-
attribute: string;
|
|
9
|
-
message: string;
|
|
10
|
-
};
|
|
11
6
|
/**
|
|
12
|
-
@module @ember-data/
|
|
7
|
+
@module @ember-data/store
|
|
13
8
|
*/
|
|
14
|
-
interface ArrayProxyWithCustomOverrides<T, M = T> extends Omit<ArrayProxy<T, M>, 'clear' | 'content'> {
|
|
15
|
-
// Omit causes `content` to be merged with the class def for ArrayProxy
|
|
16
|
-
// which then causes it to be seen as a property, disallowing defining it
|
|
17
|
-
// as an accessor. This restores our ability to define it as an accessor.
|
|
18
|
-
content: NativeArray<T>;
|
|
19
|
-
clear(): void;
|
|
20
|
-
_has(name: string): boolean;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// we force the type here to our own construct because mixin and extend patterns
|
|
24
|
-
// lose generic signatures. We also do this because we need to Omit `clear` from
|
|
25
|
-
// the type of ArrayProxy as we override it's signature.
|
|
26
|
-
const ArrayProxyWithCustomOverrides = ArrayProxy as unknown as new <T, M = T>() => ArrayProxyWithCustomOverrides<T, M>;
|
|
27
9
|
|
|
28
10
|
/**
|
|
29
11
|
Holds validation errors for a given record, organized by attribute names.
|
|
@@ -100,34 +82,28 @@ const ArrayProxyWithCustomOverrides = ArrayProxy as unknown as new <T, M = T>()
|
|
|
100
82
|
@public
|
|
101
83
|
@extends Ember.ArrayProxy
|
|
102
84
|
*/
|
|
103
|
-
export default
|
|
104
|
-
declare _registeredHandlers?: {
|
|
105
|
-
becameInvalid: () => void;
|
|
106
|
-
becameValid: () => void;
|
|
107
|
-
};
|
|
108
|
-
|
|
85
|
+
export default ArrayProxy.extend({
|
|
109
86
|
/**
|
|
110
87
|
Register with target handler
|
|
111
88
|
|
|
112
89
|
@method _registerHandlers
|
|
113
90
|
@private
|
|
114
91
|
*/
|
|
115
|
-
_registerHandlers(becameInvalid
|
|
92
|
+
_registerHandlers(becameInvalid, becameValid) {
|
|
116
93
|
this._registeredHandlers = {
|
|
117
94
|
becameInvalid,
|
|
118
95
|
becameValid,
|
|
119
96
|
};
|
|
120
|
-
}
|
|
97
|
+
},
|
|
121
98
|
|
|
122
99
|
/**
|
|
123
100
|
@property errorsByAttributeName
|
|
124
101
|
@type {MapWithDefault}
|
|
125
102
|
@private
|
|
126
103
|
*/
|
|
127
|
-
|
|
128
|
-
get errorsByAttributeName(): Map<string, NativeArray<ValidationError>> {
|
|
104
|
+
errorsByAttributeName: computed(function () {
|
|
129
105
|
return new Map();
|
|
130
|
-
}
|
|
106
|
+
}),
|
|
131
107
|
|
|
132
108
|
/**
|
|
133
109
|
Returns errors for a given attribute
|
|
@@ -148,13 +124,13 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
148
124
|
@param {String} attribute
|
|
149
125
|
@return {Array}
|
|
150
126
|
*/
|
|
151
|
-
errorsFor(attribute
|
|
152
|
-
let map = this
|
|
127
|
+
errorsFor(attribute) {
|
|
128
|
+
let map = get(this, 'errorsByAttributeName');
|
|
153
129
|
|
|
154
130
|
let errors = map.get(attribute);
|
|
155
131
|
|
|
156
132
|
if (errors === undefined) {
|
|
157
|
-
errors = A
|
|
133
|
+
errors = A();
|
|
158
134
|
map.set(attribute, errors);
|
|
159
135
|
}
|
|
160
136
|
|
|
@@ -165,7 +141,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
165
141
|
get(errors, '[]');
|
|
166
142
|
|
|
167
143
|
return errors;
|
|
168
|
-
}
|
|
144
|
+
},
|
|
169
145
|
|
|
170
146
|
/**
|
|
171
147
|
An array containing all of the error messages for this
|
|
@@ -183,30 +159,28 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
183
159
|
@public
|
|
184
160
|
@type {Array}
|
|
185
161
|
*/
|
|
186
|
-
|
|
187
|
-
declare messages: string[];
|
|
162
|
+
messages: mapBy('content', 'message'),
|
|
188
163
|
|
|
189
164
|
/**
|
|
190
165
|
@property content
|
|
191
166
|
@type {Array}
|
|
192
167
|
@private
|
|
193
168
|
*/
|
|
194
|
-
|
|
195
|
-
get content(): NativeArray<ValidationError> {
|
|
169
|
+
content: computed(function () {
|
|
196
170
|
return A();
|
|
197
|
-
}
|
|
171
|
+
}),
|
|
198
172
|
|
|
199
173
|
/**
|
|
200
174
|
@method unknownProperty
|
|
201
175
|
@private
|
|
202
176
|
*/
|
|
203
|
-
unknownProperty(attribute
|
|
177
|
+
unknownProperty(attribute) {
|
|
204
178
|
let errors = this.errorsFor(attribute);
|
|
205
179
|
if (errors.length === 0) {
|
|
206
180
|
return undefined;
|
|
207
181
|
}
|
|
208
182
|
return errors;
|
|
209
|
-
}
|
|
183
|
+
},
|
|
210
184
|
|
|
211
185
|
/**
|
|
212
186
|
Total number of errors.
|
|
@@ -225,8 +199,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
225
199
|
@public
|
|
226
200
|
@readOnly
|
|
227
201
|
*/
|
|
228
|
-
|
|
229
|
-
declare isEmpty: boolean;
|
|
202
|
+
isEmpty: not('length').readOnly(),
|
|
230
203
|
|
|
231
204
|
/**
|
|
232
205
|
Manually adds errors to the record. This will trigger the `becameInvalid` event/ lifecycle method on
|
|
@@ -260,20 +233,20 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
260
233
|
// { attribute: 'username', message: 'This field is required' },
|
|
261
234
|
// ]
|
|
262
235
|
```
|
|
263
|
-
|
|
236
|
+
@method add
|
|
264
237
|
@public
|
|
265
|
-
|
|
266
|
-
|
|
238
|
+
@param {string} attribute - the property name of an attribute or relationship
|
|
239
|
+
@param {string[]|string} messages - an error message or array of error messages for the attribute
|
|
267
240
|
*/
|
|
268
|
-
add(attribute
|
|
269
|
-
let wasEmpty
|
|
241
|
+
add(attribute, messages) {
|
|
242
|
+
let wasEmpty = get(this, 'isEmpty');
|
|
270
243
|
|
|
271
244
|
this._add(attribute, messages);
|
|
272
245
|
|
|
273
|
-
if (wasEmpty && !this
|
|
246
|
+
if (wasEmpty && !get(this, 'isEmpty')) {
|
|
274
247
|
this._registeredHandlers && this._registeredHandlers.becameInvalid();
|
|
275
248
|
}
|
|
276
|
-
}
|
|
249
|
+
},
|
|
277
250
|
|
|
278
251
|
/**
|
|
279
252
|
Adds error messages to a given attribute without sending event.
|
|
@@ -281,23 +254,23 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
281
254
|
@method _add
|
|
282
255
|
@private
|
|
283
256
|
*/
|
|
284
|
-
_add(attribute
|
|
285
|
-
|
|
286
|
-
this.addObjects(
|
|
257
|
+
_add(attribute, messages) {
|
|
258
|
+
messages = this._findOrCreateMessages(attribute, messages);
|
|
259
|
+
this.addObjects(messages);
|
|
287
260
|
|
|
288
|
-
this.errorsFor(attribute).addObjects(
|
|
261
|
+
this.errorsFor(attribute).addObjects(messages);
|
|
289
262
|
|
|
290
263
|
this.notifyPropertyChange(attribute);
|
|
291
|
-
}
|
|
264
|
+
},
|
|
292
265
|
|
|
293
266
|
/**
|
|
294
267
|
@method _findOrCreateMessages
|
|
295
268
|
@private
|
|
296
269
|
*/
|
|
297
|
-
_findOrCreateMessages(attribute
|
|
270
|
+
_findOrCreateMessages(attribute, messages) {
|
|
298
271
|
let errors = this.errorsFor(attribute);
|
|
299
|
-
let messagesArray =
|
|
300
|
-
let _messages
|
|
272
|
+
let messagesArray = makeArray(messages);
|
|
273
|
+
let _messages = new Array(messagesArray.length);
|
|
301
274
|
|
|
302
275
|
for (let i = 0; i < messagesArray.length; i++) {
|
|
303
276
|
let message = messagesArray[i];
|
|
@@ -307,13 +280,13 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
307
280
|
} else {
|
|
308
281
|
_messages[i] = {
|
|
309
282
|
attribute: attribute,
|
|
310
|
-
message,
|
|
283
|
+
message: message,
|
|
311
284
|
};
|
|
312
285
|
}
|
|
313
286
|
}
|
|
314
287
|
|
|
315
288
|
return _messages;
|
|
316
|
-
}
|
|
289
|
+
},
|
|
317
290
|
|
|
318
291
|
/**
|
|
319
292
|
Manually removes all errors for a given member from the record.
|
|
@@ -342,17 +315,17 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
342
315
|
@public
|
|
343
316
|
@param {string} member - the property name of an attribute or relationship
|
|
344
317
|
*/
|
|
345
|
-
remove(attribute
|
|
346
|
-
if (this
|
|
318
|
+
remove(attribute) {
|
|
319
|
+
if (get(this, 'isEmpty')) {
|
|
347
320
|
return;
|
|
348
321
|
}
|
|
349
322
|
|
|
350
323
|
this._remove(attribute);
|
|
351
324
|
|
|
352
|
-
if (this
|
|
325
|
+
if (get(this, 'isEmpty')) {
|
|
353
326
|
this._registeredHandlers && this._registeredHandlers.becameValid();
|
|
354
327
|
}
|
|
355
|
-
}
|
|
328
|
+
},
|
|
356
329
|
|
|
357
330
|
/**
|
|
358
331
|
Removes all error messages from the given attribute without sending event.
|
|
@@ -360,13 +333,13 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
360
333
|
@method _remove
|
|
361
334
|
@private
|
|
362
335
|
*/
|
|
363
|
-
_remove(attribute
|
|
364
|
-
if (this
|
|
336
|
+
_remove(attribute) {
|
|
337
|
+
if (get(this, 'isEmpty')) {
|
|
365
338
|
return;
|
|
366
339
|
}
|
|
367
340
|
|
|
368
341
|
let content = this.rejectBy('attribute', attribute);
|
|
369
|
-
this
|
|
342
|
+
get(this, 'content').setObjects(content);
|
|
370
343
|
|
|
371
344
|
// Although errorsByAttributeName.delete is technically enough to sync errors state, we also
|
|
372
345
|
// must mutate the array as well for autotracking
|
|
@@ -377,11 +350,11 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
377
350
|
errors.replace(i, 1);
|
|
378
351
|
}
|
|
379
352
|
}
|
|
380
|
-
this
|
|
353
|
+
get(this, 'errorsByAttributeName').delete(attribute);
|
|
381
354
|
|
|
382
355
|
this.notifyPropertyChange(attribute);
|
|
383
356
|
this.notifyPropertyChange('length');
|
|
384
|
-
}
|
|
357
|
+
},
|
|
385
358
|
|
|
386
359
|
/**
|
|
387
360
|
Manually clears all errors for the record.
|
|
@@ -420,16 +393,16 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
420
393
|
// => []
|
|
421
394
|
```
|
|
422
395
|
@method clear
|
|
423
|
-
|
|
396
|
+
@public
|
|
424
397
|
*/
|
|
425
|
-
clear()
|
|
426
|
-
if (this
|
|
398
|
+
clear() {
|
|
399
|
+
if (get(this, 'isEmpty')) {
|
|
427
400
|
return;
|
|
428
401
|
}
|
|
429
402
|
|
|
430
403
|
this._clear();
|
|
431
404
|
this._registeredHandlers && this._registeredHandlers.becameValid();
|
|
432
|
-
}
|
|
405
|
+
},
|
|
433
406
|
|
|
434
407
|
/**
|
|
435
408
|
Removes all error messages.
|
|
@@ -438,13 +411,13 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
438
411
|
@method _clear
|
|
439
412
|
@private
|
|
440
413
|
*/
|
|
441
|
-
_clear()
|
|
442
|
-
if (this
|
|
414
|
+
_clear() {
|
|
415
|
+
if (get(this, 'isEmpty')) {
|
|
443
416
|
return;
|
|
444
417
|
}
|
|
445
418
|
|
|
446
|
-
let errorsByAttributeName = this
|
|
447
|
-
let attributes
|
|
419
|
+
let errorsByAttributeName = get(this, 'errorsByAttributeName');
|
|
420
|
+
let attributes = [];
|
|
448
421
|
|
|
449
422
|
errorsByAttributeName.forEach(function (_, attribute) {
|
|
450
423
|
attributes.push(attribute);
|
|
@@ -456,7 +429,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
456
429
|
});
|
|
457
430
|
|
|
458
431
|
ArrayProxy.prototype.clear.call(this);
|
|
459
|
-
}
|
|
432
|
+
},
|
|
460
433
|
|
|
461
434
|
/**
|
|
462
435
|
Checks if there are error messages for the given attribute.
|
|
@@ -481,7 +454,7 @@ export default class Errors extends ArrayProxyWithCustomOverrides<ValidationErro
|
|
|
481
454
|
@param {String} attribute
|
|
482
455
|
@return {Boolean} true if there some errors on given attribute
|
|
483
456
|
*/
|
|
484
|
-
has(attribute
|
|
457
|
+
has(attribute) {
|
|
485
458
|
return this.errorsFor(attribute).length > 0;
|
|
486
|
-
}
|
|
487
|
-
}
|
|
459
|
+
},
|
|
460
|
+
});
|
|
@@ -2,12 +2,6 @@
|
|
|
2
2
|
@module @ember-data/model
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export interface ArrayDiffResult {
|
|
6
|
-
firstChangeIndex: number | null;
|
|
7
|
-
removedCount: number;
|
|
8
|
-
addedCount: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
5
|
/**
|
|
12
6
|
@method diffArray
|
|
13
7
|
@internal
|
|
@@ -19,12 +13,12 @@ export interface ArrayDiffResult {
|
|
|
19
13
|
removedCount: <integer> // 0 if no change
|
|
20
14
|
}
|
|
21
15
|
*/
|
|
22
|
-
export default function diffArray(oldArray
|
|
16
|
+
export default function diffArray(oldArray, newArray) {
|
|
23
17
|
const oldLength = oldArray.length;
|
|
24
18
|
const newLength = newArray.length;
|
|
25
19
|
|
|
26
20
|
const shortestLength = Math.min(oldLength, newLength);
|
|
27
|
-
let firstChangeIndex
|
|
21
|
+
let firstChangeIndex = null; // null signifies no changes
|
|
28
22
|
|
|
29
23
|
// find the first change
|
|
30
24
|
for (let i = 0; i < shortestLength; i++) {
|
|
@@ -8,36 +8,10 @@ import EmberObject, { get } from '@ember/object';
|
|
|
8
8
|
|
|
9
9
|
import { all } from 'rsvp';
|
|
10
10
|
|
|
11
|
-
import type { RelationshipRecordData } from '@ember-data/record-data/-private/ts-interfaces/relationship-record-data';
|
|
12
|
-
import type { InternalModel } from '@ember-data/store/-private';
|
|
13
11
|
import { PromiseArray, recordDataFor } from '@ember-data/store/-private';
|
|
14
|
-
import type CoreStore from '@ember-data/store/-private/system/core-store';
|
|
15
|
-
import type { CreateRecordProperties } from '@ember-data/store/-private/system/core-store';
|
|
16
|
-
import ShimModelClass from '@ember-data/store/-private/system/model/shim-model-class';
|
|
17
|
-
import type { DSModelSchema } from '@ember-data/store/-private/ts-interfaces/ds-model';
|
|
18
|
-
import type { Links, PaginationLinks } from '@ember-data/store/-private/ts-interfaces/ember-data-json-api';
|
|
19
|
-
import type { RecordInstance } from '@ember-data/store/-private/ts-interfaces/record-instance';
|
|
20
|
-
import type { Dict } from '@ember-data/store/-private/ts-interfaces/utils';
|
|
21
12
|
|
|
22
13
|
import diffArray from './diff-array';
|
|
23
14
|
|
|
24
|
-
interface MutableArrayWithObject<T, M = T> extends EmberObject, MutableArray<M> {}
|
|
25
|
-
const MutableArrayWithObject = EmberObject.extend(MutableArray) as unknown as new <
|
|
26
|
-
T,
|
|
27
|
-
M = T
|
|
28
|
-
>() => MutableArrayWithObject<T, M>;
|
|
29
|
-
|
|
30
|
-
export interface ManyArrayCreateArgs {
|
|
31
|
-
store: CoreStore;
|
|
32
|
-
type: ShimModelClass;
|
|
33
|
-
recordData: RelationshipRecordData;
|
|
34
|
-
key: string;
|
|
35
|
-
isPolymorphic: boolean;
|
|
36
|
-
isAsync: boolean;
|
|
37
|
-
_inverseIsAsync: boolean;
|
|
38
|
-
internalModel: InternalModel;
|
|
39
|
-
isLoaded: boolean;
|
|
40
|
-
}
|
|
41
15
|
/**
|
|
42
16
|
A `ManyArray` is a `MutableArray` that represents the contents of a has-many
|
|
43
17
|
relationship.
|
|
@@ -83,27 +57,12 @@ export interface ManyArrayCreateArgs {
|
|
|
83
57
|
@extends Ember.EmberObject
|
|
84
58
|
@uses Ember.MutableArray
|
|
85
59
|
*/
|
|
86
|
-
export default
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
declare isPolymorphic: boolean;
|
|
90
|
-
declare _isDirty: boolean;
|
|
91
|
-
declare _isUpdating: boolean;
|
|
92
|
-
declare _hasNotified: boolean;
|
|
93
|
-
declare __hasArrayObservers: boolean;
|
|
94
|
-
declare hasArrayObservers: boolean; // override the base declaration
|
|
95
|
-
declare _length: number;
|
|
96
|
-
declare _meta: Dict<unknown> | null;
|
|
97
|
-
declare _links: Links | PaginationLinks | null;
|
|
98
|
-
declare currentState: InternalModel[];
|
|
99
|
-
declare recordData: RelationshipRecordData;
|
|
100
|
-
declare internalModel: InternalModel;
|
|
101
|
-
declare store: CoreStore;
|
|
102
|
-
declare key: string;
|
|
103
|
-
declare type: DSModelSchema;
|
|
60
|
+
export default EmberObject.extend(MutableArray, {
|
|
61
|
+
isAsync: false,
|
|
62
|
+
isLoaded: false,
|
|
104
63
|
|
|
105
64
|
init() {
|
|
106
|
-
|
|
65
|
+
this._super(...arguments);
|
|
107
66
|
|
|
108
67
|
/**
|
|
109
68
|
The loading state of this array
|
|
@@ -112,7 +71,6 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
112
71
|
@public
|
|
113
72
|
*/
|
|
114
73
|
this.isLoaded = this.isLoaded || false;
|
|
115
|
-
this.isAsync = this.isAsync || false;
|
|
116
74
|
|
|
117
75
|
this._length = 0;
|
|
118
76
|
|
|
@@ -200,13 +158,12 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
200
158
|
// make sure we initialize to the correct state
|
|
201
159
|
// since the user has already accessed
|
|
202
160
|
this.retrieveLatest();
|
|
203
|
-
}
|
|
161
|
+
},
|
|
204
162
|
|
|
205
163
|
// TODO refactor away _hasArrayObservers for tests
|
|
206
164
|
get _hasArrayObservers() {
|
|
207
|
-
// cast necessary because hasArrayObservers is typed as a ComputedProperty<boolean> vs a boolean;
|
|
208
165
|
return this.hasArrayObservers || this.__hasArrayObservers;
|
|
209
|
-
}
|
|
166
|
+
},
|
|
210
167
|
|
|
211
168
|
notify() {
|
|
212
169
|
this._isDirty = true;
|
|
@@ -218,7 +175,7 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
218
175
|
this.notifyPropertyChange('firstObject');
|
|
219
176
|
this.notifyPropertyChange('lastObject');
|
|
220
177
|
}
|
|
221
|
-
}
|
|
178
|
+
},
|
|
222
179
|
|
|
223
180
|
get length() {
|
|
224
181
|
if (this._isDirty) {
|
|
@@ -228,11 +185,11 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
228
185
|
get(this, '[]');
|
|
229
186
|
|
|
230
187
|
return this._length;
|
|
231
|
-
}
|
|
188
|
+
},
|
|
232
189
|
|
|
233
190
|
set length(value) {
|
|
234
191
|
this._length = value;
|
|
235
|
-
}
|
|
192
|
+
},
|
|
236
193
|
|
|
237
194
|
get links() {
|
|
238
195
|
get(this, '[]');
|
|
@@ -240,10 +197,10 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
240
197
|
this.retrieveLatest();
|
|
241
198
|
}
|
|
242
199
|
return this._links;
|
|
243
|
-
}
|
|
200
|
+
},
|
|
244
201
|
set links(v) {
|
|
245
202
|
this._links = v;
|
|
246
|
-
}
|
|
203
|
+
},
|
|
247
204
|
|
|
248
205
|
get meta() {
|
|
249
206
|
get(this, '[]');
|
|
@@ -251,12 +208,12 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
251
208
|
this.retrieveLatest();
|
|
252
209
|
}
|
|
253
210
|
return this._meta;
|
|
254
|
-
}
|
|
211
|
+
},
|
|
255
212
|
set meta(v) {
|
|
256
213
|
this._meta = v;
|
|
257
|
-
}
|
|
214
|
+
},
|
|
258
215
|
|
|
259
|
-
objectAt(index
|
|
216
|
+
objectAt(index) {
|
|
260
217
|
if (this._isDirty) {
|
|
261
218
|
this.retrieveLatest();
|
|
262
219
|
}
|
|
@@ -266,12 +223,12 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
266
223
|
}
|
|
267
224
|
|
|
268
225
|
return internalModel.getRecord();
|
|
269
|
-
}
|
|
226
|
+
},
|
|
270
227
|
|
|
271
|
-
replace(idx
|
|
228
|
+
replace(idx, amt, objects) {
|
|
272
229
|
assert(`Cannot push mutations to the cache while updating the relationship from cache`, !this._isUpdating);
|
|
273
230
|
this.store._backburner.join(() => {
|
|
274
|
-
let internalModels
|
|
231
|
+
let internalModels;
|
|
275
232
|
if (amt > 0) {
|
|
276
233
|
internalModels = this.currentState.slice(idx, idx + amt);
|
|
277
234
|
this.recordData.removeFromHasMany(
|
|
@@ -286,13 +243,13 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
286
243
|
);
|
|
287
244
|
this.recordData.addToHasMany(
|
|
288
245
|
this.key,
|
|
289
|
-
objects.map((obj
|
|
246
|
+
objects.map((obj) => recordDataFor(obj)),
|
|
290
247
|
idx
|
|
291
248
|
);
|
|
292
249
|
}
|
|
293
250
|
this.notify();
|
|
294
251
|
});
|
|
295
|
-
}
|
|
252
|
+
},
|
|
296
253
|
|
|
297
254
|
retrieveLatest() {
|
|
298
255
|
// It’s possible the parent side of the relationship may have been destroyed by this point
|
|
@@ -303,7 +260,7 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
303
260
|
this._isUpdating = true;
|
|
304
261
|
let jsonApi = this.recordData.getHasMany(this.key);
|
|
305
262
|
|
|
306
|
-
let internalModels
|
|
263
|
+
let internalModels = [];
|
|
307
264
|
if (jsonApi.data) {
|
|
308
265
|
for (let i = 0; i < jsonApi.data.length; i++) {
|
|
309
266
|
let im = this.store._internalModelForResource(jsonApi.data[i]);
|
|
@@ -341,7 +298,7 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
341
298
|
}
|
|
342
299
|
|
|
343
300
|
this._isUpdating = false;
|
|
344
|
-
}
|
|
301
|
+
},
|
|
345
302
|
|
|
346
303
|
/**
|
|
347
304
|
Reloads all of the records in the manyArray. If the manyArray
|
|
@@ -367,8 +324,8 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
367
324
|
*/
|
|
368
325
|
reload(options) {
|
|
369
326
|
// TODO this is odd, we don't ask the store for anything else like this?
|
|
370
|
-
return this.
|
|
371
|
-
}
|
|
327
|
+
return this.store.reloadManyArray(this, this.internalModel, this.key, options);
|
|
328
|
+
},
|
|
372
329
|
|
|
373
330
|
/**
|
|
374
331
|
Saves all of the records in the `ManyArray`.
|
|
@@ -390,7 +347,7 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
390
347
|
*/
|
|
391
348
|
save() {
|
|
392
349
|
let manyArray = this;
|
|
393
|
-
let promiseLabel = 'DS: ManyArray#save ' + this.type
|
|
350
|
+
let promiseLabel = 'DS: ManyArray#save ' + this.type;
|
|
394
351
|
let promise = all(this.invoke('save'), promiseLabel).then(
|
|
395
352
|
() => manyArray,
|
|
396
353
|
null,
|
|
@@ -399,7 +356,7 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
399
356
|
|
|
400
357
|
// TODO deprecate returning a promiseArray here
|
|
401
358
|
return PromiseArray.create({ promise });
|
|
402
|
-
}
|
|
359
|
+
},
|
|
403
360
|
|
|
404
361
|
/**
|
|
405
362
|
Create a child record within the owner
|
|
@@ -409,12 +366,12 @@ export default class ManyArray extends MutableArrayWithObject<InternalModel, Rec
|
|
|
409
366
|
@param {Object} hash
|
|
410
367
|
@return {Model} record
|
|
411
368
|
*/
|
|
412
|
-
createRecord(hash
|
|
369
|
+
createRecord(hash) {
|
|
413
370
|
const { store, type } = this;
|
|
414
371
|
|
|
415
|
-
|
|
372
|
+
let record = store.createRecord(type.modelName, hash);
|
|
416
373
|
this.pushObject(record);
|
|
417
374
|
|
|
418
375
|
return record;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
376
|
+
},
|
|
377
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { assert } from '@ember/debug';
|
|
2
|
+
import { computed } from '@ember/object';
|
|
3
|
+
|
|
4
|
+
import { PromiseObject } from '@ember-data/store/-private';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
@module @ember-data/model
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
A PromiseBelongsTo is a PromiseObject that also proxies certain method calls
|
|
12
|
+
to the underlying belongsTo model.
|
|
13
|
+
Right now we proxy:
|
|
14
|
+
|
|
15
|
+
* `reload()`
|
|
16
|
+
|
|
17
|
+
@class PromiseBelongsTo
|
|
18
|
+
@extends PromiseObject
|
|
19
|
+
@private
|
|
20
|
+
*/
|
|
21
|
+
const PromiseBelongsTo = PromiseObject.extend({
|
|
22
|
+
// we don't proxy meta because we would need to proxy it to the relationship state container
|
|
23
|
+
// however, meta on relationships does not trigger change notifications.
|
|
24
|
+
// if you need relationship meta, you should do `record.belongsTo(relationshipName).meta()`
|
|
25
|
+
meta: computed(function () {
|
|
26
|
+
assert(
|
|
27
|
+
'You attempted to access meta on the promise for the async belongsTo relationship ' +
|
|
28
|
+
`${this.get('_belongsToState').modelName}:${this.get('_belongsToState').key}'.` +
|
|
29
|
+
'\nUse `record.belongsTo(relationshipName).meta()` instead.',
|
|
30
|
+
false
|
|
31
|
+
);
|
|
32
|
+
}),
|
|
33
|
+
|
|
34
|
+
reload(options) {
|
|
35
|
+
assert('You are trying to reload an async belongsTo before it has been created', this.get('content') !== undefined);
|
|
36
|
+
let { key, store, originatingInternalModel } = this._belongsToState;
|
|
37
|
+
return store.reloadBelongsTo(this, originatingInternalModel, key, options).then(() => this);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export default PromiseBelongsTo;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import ArrayMixin from '@ember/array';
|
|
2
|
-
import type ArrayProxy from '@ember/array/proxy';
|
|
3
2
|
import { assert } from '@ember/debug';
|
|
4
3
|
import { dependentKeyCompat } from '@ember/object/compat';
|
|
5
4
|
import { tracked } from '@glimmer/tracking';
|
|
@@ -7,16 +6,6 @@ import Ember from 'ember';
|
|
|
7
6
|
|
|
8
7
|
import { resolve } from 'rsvp';
|
|
9
8
|
|
|
10
|
-
import type { ManyArray } from 'ember-data/-private';
|
|
11
|
-
|
|
12
|
-
import type { InternalModel } from '@ember-data/store/-private';
|
|
13
|
-
import type { RecordInstance } from '@ember-data/store/-private/ts-interfaces/record-instance';
|
|
14
|
-
|
|
15
|
-
export interface HasManyProxyCreateArgs {
|
|
16
|
-
promise: Promise<ManyArray>;
|
|
17
|
-
content?: ManyArray;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
9
|
/**
|
|
21
10
|
@module @ember-data/model
|
|
22
11
|
*/
|
|
@@ -42,13 +31,12 @@ export interface HasManyProxyCreateArgs {
|
|
|
42
31
|
@class PromiseManyArray
|
|
43
32
|
@public
|
|
44
33
|
*/
|
|
45
|
-
export default interface PromiseManyArray extends Omit<ArrayProxy<InternalModel, RecordInstance>, 'destroy'> {}
|
|
46
34
|
export default class PromiseManyArray {
|
|
47
|
-
declare promise: Promise<
|
|
35
|
+
declare promise: Promise<any> | null;
|
|
48
36
|
declare isDestroyed: boolean;
|
|
49
37
|
declare isDestroying: boolean;
|
|
50
38
|
|
|
51
|
-
constructor(promise
|
|
39
|
+
constructor(promise, content) {
|
|
52
40
|
this._update(promise, content);
|
|
53
41
|
this.isDestroyed = false;
|
|
54
42
|
this.isDestroying = false;
|
|
@@ -216,7 +204,7 @@ export default class PromiseManyArray {
|
|
|
216
204
|
|
|
217
205
|
//---- Our own stuff
|
|
218
206
|
|
|
219
|
-
_update(promise
|
|
207
|
+
_update(promise, content) {
|
|
220
208
|
if (content !== undefined) {
|
|
221
209
|
this.content = content;
|
|
222
210
|
}
|
|
@@ -224,7 +212,7 @@ export default class PromiseManyArray {
|
|
|
224
212
|
this.promise = tapPromise(this, promise);
|
|
225
213
|
}
|
|
226
214
|
|
|
227
|
-
static create({ promise, content }
|
|
215
|
+
static create({ promise, content }) {
|
|
228
216
|
return new this(promise, content);
|
|
229
217
|
}
|
|
230
218
|
|
|
@@ -245,7 +233,7 @@ export default class PromiseManyArray {
|
|
|
245
233
|
}
|
|
246
234
|
}
|
|
247
235
|
|
|
248
|
-
function tapPromise(proxy
|
|
236
|
+
function tapPromise(proxy, promise) {
|
|
249
237
|
proxy.isPending = true;
|
|
250
238
|
proxy.isSettled = false;
|
|
251
239
|
proxy.isFulfilled = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ember-data/model",
|
|
3
|
-
"version": "4.4.0
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "The default blueprint for ember-cli addons.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"test:node": "mocha"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@ember-data/canary-features": "4.4.0
|
|
22
|
-
"@ember-data/private-build-infra": "4.4.0
|
|
23
|
-
"@ember-data/store": "4.4.0
|
|
21
|
+
"@ember-data/canary-features": "4.4.0",
|
|
22
|
+
"@ember-data/private-build-infra": "4.4.0",
|
|
23
|
+
"@ember-data/store": "4.4.0",
|
|
24
24
|
"@ember/edition-utils": "^1.2.0",
|
|
25
25
|
"@ember/string": "^3.0.0",
|
|
26
26
|
"ember-auto-import": "^2.2.4",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"inflection": "~1.13.1"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@ember-data/unpublished-test-infra": "4.4.0
|
|
36
|
+
"@ember-data/unpublished-test-infra": "4.4.0",
|
|
37
37
|
"@ember/optional-features": "^2.0.0",
|
|
38
38
|
"@ember/test-helpers": "^2.6.0",
|
|
39
39
|
"broccoli-asset-rev": "^3.0.0",
|
|
40
|
-
"ember-cli": "~4.
|
|
40
|
+
"ember-cli": "~4.3.0",
|
|
41
41
|
"ember-cli-blueprint-test-helpers": "^0.19.1",
|
|
42
42
|
"ember-cli-dependency-checker": "^3.2.0",
|
|
43
43
|
"ember-cli-htmlbars": "^6.0.1",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"ember-maybe-import-regenerator": "^1.0.0",
|
|
51
51
|
"ember-qunit": "^5.1.5",
|
|
52
52
|
"ember-resolver": "^8.0.3",
|
|
53
|
-
"ember-source": "~4.
|
|
53
|
+
"ember-source": "~4.4.0",
|
|
54
54
|
"ember-source-channel-url": "^3.0.0",
|
|
55
55
|
"ember-try": "^2.0.0",
|
|
56
56
|
"loader.js": "^4.7.0",
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { assert } from '@ember/debug';
|
|
2
|
-
import { computed } from '@ember/object';
|
|
3
|
-
import type PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
4
|
-
import type ObjectProxy from '@ember/object/proxy';
|
|
5
|
-
|
|
6
|
-
import type { InternalModel } from '@ember-data/store/-private';
|
|
7
|
-
import { PromiseObject } from '@ember-data/store/-private';
|
|
8
|
-
import type CoreStore from '@ember-data/store/-private/system/core-store';
|
|
9
|
-
import type { RecordInstance } from '@ember-data/store/-private/ts-interfaces/record-instance';
|
|
10
|
-
import type { Dict } from '@ember-data/store/-private/ts-interfaces/utils';
|
|
11
|
-
|
|
12
|
-
export interface BelongsToProxyMeta {
|
|
13
|
-
key: string;
|
|
14
|
-
store: CoreStore;
|
|
15
|
-
originatingInternalModel: InternalModel;
|
|
16
|
-
modelName: string;
|
|
17
|
-
}
|
|
18
|
-
export interface BelongsToProxyCreateArgs {
|
|
19
|
-
promise: Promise<RecordInstance | null>;
|
|
20
|
-
content?: RecordInstance | null;
|
|
21
|
-
_belongsToState: BelongsToProxyMeta;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface PromiseObjectType<T extends object> extends PromiseProxyMixin<T | null>, ObjectProxy<T> {
|
|
25
|
-
new <T extends object>(...args: unknown[]): PromiseObjectType<T>;
|
|
26
|
-
}
|
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
|
-
declare class PromiseObjectType<T extends object> {}
|
|
29
|
-
|
|
30
|
-
const Extended: PromiseObjectType<RecordInstance> = PromiseObject as unknown as PromiseObjectType<RecordInstance>;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
@module @ember-data/model
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
A PromiseBelongsTo is a PromiseObject that also proxies certain method calls
|
|
38
|
-
to the underlying belongsTo model.
|
|
39
|
-
Right now we proxy:
|
|
40
|
-
* `reload()`
|
|
41
|
-
@class PromiseBelongsTo
|
|
42
|
-
@extends PromiseObject
|
|
43
|
-
@private
|
|
44
|
-
*/
|
|
45
|
-
class PromiseBelongsTo extends Extended<RecordInstance> {
|
|
46
|
-
declare _belongsToState: BelongsToProxyMeta;
|
|
47
|
-
// we don't proxy meta because we would need to proxy it to the relationship state container
|
|
48
|
-
// however, meta on relationships does not trigger change notifications.
|
|
49
|
-
// if you need relationship meta, you should do `record.belongsTo(relationshipName).meta()`
|
|
50
|
-
@computed()
|
|
51
|
-
get meta() {
|
|
52
|
-
// eslint-disable-next-line no-constant-condition
|
|
53
|
-
if (1) {
|
|
54
|
-
assert(
|
|
55
|
-
'You attempted to access meta on the promise for the async belongsTo relationship ' +
|
|
56
|
-
`${this.get('_belongsToState').modelName}:${this.get('_belongsToState').key}'.` +
|
|
57
|
-
'\nUse `record.belongsTo(relationshipName).meta()` instead.',
|
|
58
|
-
false
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async reload(options: Dict<unknown>): Promise<this> {
|
|
65
|
-
assert('You are trying to reload an async belongsTo before it has been created', this.content !== undefined);
|
|
66
|
-
let { key, store, originatingInternalModel } = this._belongsToState;
|
|
67
|
-
await store.reloadBelongsTo(this, originatingInternalModel, key, options);
|
|
68
|
-
return this;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export default PromiseBelongsTo;
|