@ember-data/model 4.8.0-alpha.5 → 4.9.0-alpha.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/deprecated-promise-proxy.ts +54 -0
- package/addon/-private/has-many.js +3 -1
- package/addon/-private/legacy-relationships-support.ts +168 -112
- package/addon/-private/many-array.ts +211 -249
- package/addon/-private/model.js +125 -55
- 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/references/belongs-to.ts +22 -3
- package/addon/-private/references/has-many.ts +22 -2
- package/addon/-private/relationship-meta.ts +3 -1
- package/index.js +2 -0
- package/package.json +5 -5
package/addon/-private/model.js
CHANGED
|
@@ -7,8 +7,6 @@ import EmberError from '@ember/error';
|
|
|
7
7
|
import EmberObject from '@ember/object';
|
|
8
8
|
import { dependentKeyCompat } from '@ember/object/compat';
|
|
9
9
|
import { run } from '@ember/runloop';
|
|
10
|
-
import { inject as service } from '@ember/service';
|
|
11
|
-
import { isNone } from '@ember/utils';
|
|
12
10
|
import { DEBUG } from '@glimmer/env';
|
|
13
11
|
import { tracked } from '@glimmer/tracking';
|
|
14
12
|
import Ember from 'ember';
|
|
@@ -19,12 +17,14 @@ import { HAS_DEBUG_PACKAGE } from '@ember-data/private-build-infra';
|
|
|
19
17
|
import {
|
|
20
18
|
DEPRECATE_EARLY_STATIC,
|
|
21
19
|
DEPRECATE_MODEL_REOPEN,
|
|
20
|
+
DEPRECATE_NON_EXPLICIT_POLYMORPHISM,
|
|
22
21
|
DEPRECATE_RELATIONSHIPS_WITHOUT_INVERSE,
|
|
23
22
|
DEPRECATE_SAVE_PROMISE_ACCESS,
|
|
24
23
|
} from '@ember-data/private-build-infra/deprecations';
|
|
25
24
|
import { recordIdentifierFor, storeFor } from '@ember-data/store';
|
|
26
|
-
import { coerceId,
|
|
25
|
+
import { coerceId, recordDataFor } from '@ember-data/store/-private';
|
|
27
26
|
|
|
27
|
+
import { deprecatedPromiseObject } from './deprecated-promise-proxy';
|
|
28
28
|
import Errors from './errors';
|
|
29
29
|
import { LegacySupport } from './legacy-relationships-support';
|
|
30
30
|
import notifyChanges from './notify-changes';
|
|
@@ -58,7 +58,7 @@ function findPossibleInverses(type, inverseType, name, relationshipsSoFar) {
|
|
|
58
58
|
let relationshipsForType = relationshipMap.get(type.modelName);
|
|
59
59
|
let relationships = Array.isArray(relationshipsForType)
|
|
60
60
|
? relationshipsForType.filter((relationship) => {
|
|
61
|
-
let optionsForRelationship =
|
|
61
|
+
let optionsForRelationship = relationship.options;
|
|
62
62
|
|
|
63
63
|
if (!optionsForRelationship.inverse && optionsForRelationship.inverse !== null) {
|
|
64
64
|
return true;
|
|
@@ -122,7 +122,6 @@ function computeOnce(target, key, desc) {
|
|
|
122
122
|
@extends Ember.EmberObject
|
|
123
123
|
*/
|
|
124
124
|
class Model extends EmberObject {
|
|
125
|
-
@service store;
|
|
126
125
|
___private_notifications;
|
|
127
126
|
|
|
128
127
|
init(options = {}) {
|
|
@@ -135,27 +134,27 @@ class Model extends EmberObject {
|
|
|
135
134
|
const _secretInit = options._secretInit;
|
|
136
135
|
options._createProps = null;
|
|
137
136
|
options._secretInit = null;
|
|
137
|
+
|
|
138
|
+
let store = (this.store = _secretInit.store);
|
|
138
139
|
super.init(options);
|
|
139
140
|
|
|
140
141
|
let identity = _secretInit.identifier;
|
|
141
142
|
_secretInit.cb(this, _secretInit.recordData, identity, _secretInit.store);
|
|
143
|
+
|
|
142
144
|
this.___recordState = DEBUG ? new RecordState(this) : null;
|
|
143
145
|
|
|
144
146
|
this.setProperties(createProps);
|
|
145
147
|
|
|
146
|
-
let store = storeFor(this);
|
|
147
148
|
let notifications = store._notificationManager;
|
|
148
|
-
|
|
149
149
|
this.___private_notifications = notifications.subscribe(identity, (identifier, type, key) => {
|
|
150
150
|
notifyChanges(identifier, type, key, this, store);
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
destroy() {
|
|
155
|
-
|
|
155
|
+
const identifier = recordIdentifierFor(this);
|
|
156
156
|
this.___recordState?.destroy();
|
|
157
157
|
const store = storeFor(this);
|
|
158
|
-
const identifier = recordIdentifierFor(this);
|
|
159
158
|
store._notificationManager.unsubscribe(this.___private_notifications);
|
|
160
159
|
// Legacy behavior is to notify the relationships on destroy
|
|
161
160
|
// such that they "clear". It's uncertain this behavior would
|
|
@@ -163,7 +162,16 @@ class Model extends EmberObject {
|
|
|
163
162
|
// to simply not notify, for this reason the store does not itself
|
|
164
163
|
// notify individual changes once the delete has been signaled,
|
|
165
164
|
// this decision is left to model instances.
|
|
166
|
-
|
|
165
|
+
|
|
166
|
+
this.eachRelationship((key, meta) => {
|
|
167
|
+
if (meta.kind === 'belongsTo') {
|
|
168
|
+
this.notifyPropertyChange(key);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
LEGACY_SUPPORT.get(this)?.destroy();
|
|
172
|
+
LEGACY_SUPPORT.delete(this);
|
|
173
|
+
LEGACY_SUPPORT.delete(identifier);
|
|
174
|
+
|
|
167
175
|
super.destroy();
|
|
168
176
|
}
|
|
169
177
|
|
|
@@ -840,6 +848,7 @@ class Model extends EmberObject {
|
|
|
840
848
|
rollbackAttributes() {
|
|
841
849
|
const { currentState } = this;
|
|
842
850
|
const { isNew } = currentState;
|
|
851
|
+
|
|
843
852
|
storeFor(this)._join(() => {
|
|
844
853
|
recordDataFor(this).rollbackAttrs(recordIdentifierFor(this));
|
|
845
854
|
this.errors.clear();
|
|
@@ -1146,7 +1155,7 @@ class Model extends EmberObject {
|
|
|
1146
1155
|
record.eachRelationship(function(name, descriptor) {
|
|
1147
1156
|
if (descriptor.kind === 'hasMany') {
|
|
1148
1157
|
let serializedHasManyName = name.toUpperCase() + '_IDS';
|
|
1149
|
-
json[serializedHasManyName] = record.get(name).
|
|
1158
|
+
json[serializedHasManyName] = record.get(name).map(r => r.id);
|
|
1150
1159
|
}
|
|
1151
1160
|
});
|
|
1152
1161
|
|
|
@@ -1385,42 +1394,46 @@ class Model extends EmberObject {
|
|
|
1385
1394
|
this.modelName
|
|
1386
1395
|
);
|
|
1387
1396
|
}
|
|
1388
|
-
let inverseType = this.typeForRelationship(name, store);
|
|
1389
|
-
if (!inverseType) {
|
|
1390
|
-
return null;
|
|
1391
|
-
}
|
|
1392
1397
|
|
|
1393
|
-
|
|
1398
|
+
const relationship = this.relationshipsByName.get(name);
|
|
1399
|
+
const { options } = relationship;
|
|
1400
|
+
const isPolymorphic = options.polymorphic;
|
|
1401
|
+
|
|
1394
1402
|
//If inverse is manually specified to be null, like `comments: hasMany('message', { inverse: null })`
|
|
1395
|
-
|
|
1396
|
-
|
|
1403
|
+
const isExplicitInverseNull = options.inverse === null;
|
|
1404
|
+
const isAbstractType =
|
|
1405
|
+
!isExplicitInverseNull && isPolymorphic && !store.getSchemaDefinitionService().doesTypeExist(relationship.type);
|
|
1406
|
+
|
|
1407
|
+
if (isExplicitInverseNull || isAbstractType) {
|
|
1408
|
+
assert(
|
|
1409
|
+
`No schema for the abstract type '${relationship.type}' for the polymorphic relationship '${name}' on '${this.modelName}' was provided by the SchemaDefinitionService.`,
|
|
1410
|
+
!isPolymorphic || isExplicitInverseNull
|
|
1411
|
+
);
|
|
1397
1412
|
return null;
|
|
1398
1413
|
}
|
|
1399
1414
|
|
|
1400
|
-
let
|
|
1415
|
+
let fieldOnInverse, inverseKind, inverseRelationship, inverseOptions;
|
|
1416
|
+
let inverseSchema = this.typeForRelationship(name, store);
|
|
1401
1417
|
|
|
1418
|
+
// if the type does not exist and we are not polymorphic
|
|
1402
1419
|
//If inverse is specified manually, return the inverse
|
|
1403
|
-
if (options.inverse) {
|
|
1404
|
-
|
|
1405
|
-
|
|
1420
|
+
if (options.inverse !== undefined) {
|
|
1421
|
+
fieldOnInverse = options.inverse;
|
|
1422
|
+
inverseRelationship = inverseSchema && inverseSchema.relationshipsByName.get(fieldOnInverse);
|
|
1406
1423
|
|
|
1407
1424
|
assert(
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
"' on the '" +
|
|
1411
|
-
inverseType.modelName +
|
|
1412
|
-
"' model. This is most likely due to a missing attribute on your model definition.",
|
|
1413
|
-
!isNone(inverse)
|
|
1425
|
+
`We found no field named '${fieldOnInverse}' on the schema for '${inverseSchema.modelName}' to be the inverse of the '${name}' relationship on '${this.modelName}'. This is most likely due to a missing field on your model definition.`,
|
|
1426
|
+
inverseRelationship
|
|
1414
1427
|
);
|
|
1415
1428
|
|
|
1416
1429
|
// TODO probably just return the whole inverse here
|
|
1417
|
-
inverseKind =
|
|
1418
|
-
inverseOptions =
|
|
1430
|
+
inverseKind = inverseRelationship.kind;
|
|
1431
|
+
inverseOptions = inverseRelationship.options;
|
|
1419
1432
|
} else {
|
|
1420
1433
|
//No inverse was specified manually, we need to use a heuristic to guess one
|
|
1421
|
-
if (
|
|
1434
|
+
if (relationship.type === relationship.parentModelName) {
|
|
1422
1435
|
warn(
|
|
1423
|
-
`Detected a reflexive relationship
|
|
1436
|
+
`Detected a reflexive relationship named '${name}' on the schema for '${relationship.type}' without an inverse option. Look at https://guides.emberjs.com/current/models/relationships/#toc_reflexive-relations for how to explicitly specify inverses.`,
|
|
1424
1437
|
false,
|
|
1425
1438
|
{
|
|
1426
1439
|
id: 'ds.model.reflexive-relationship-without-inverse',
|
|
@@ -1428,30 +1441,33 @@ class Model extends EmberObject {
|
|
|
1428
1441
|
);
|
|
1429
1442
|
}
|
|
1430
1443
|
|
|
1431
|
-
let possibleRelationships = findPossibleInverses(this,
|
|
1444
|
+
let possibleRelationships = findPossibleInverses(this, inverseSchema, name);
|
|
1432
1445
|
|
|
1433
1446
|
if (possibleRelationships.length === 0) {
|
|
1434
1447
|
return null;
|
|
1435
1448
|
}
|
|
1436
1449
|
|
|
1437
|
-
|
|
1438
|
-
let
|
|
1439
|
-
|
|
1440
|
-
|
|
1450
|
+
if (DEBUG) {
|
|
1451
|
+
let filteredRelationships = possibleRelationships.filter((possibleRelationship) => {
|
|
1452
|
+
let optionsForRelationship = possibleRelationship.options;
|
|
1453
|
+
return name === optionsForRelationship.inverse;
|
|
1454
|
+
});
|
|
1441
1455
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1456
|
+
assert(
|
|
1457
|
+
"You defined the '" +
|
|
1458
|
+
name +
|
|
1459
|
+
"' relationship on " +
|
|
1460
|
+
this +
|
|
1461
|
+
', but you defined the inverse relationships of type ' +
|
|
1462
|
+
inverseSchema.toString() +
|
|
1463
|
+
' multiple times. Look at https://guides.emberjs.com/current/models/relationships/#toc_explicit-inverses for how to explicitly specify inverses',
|
|
1464
|
+
filteredRelationships.length < 2
|
|
1465
|
+
);
|
|
1466
|
+
}
|
|
1452
1467
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1468
|
+
let explicitRelationship = possibleRelationships.find((relationship) => relationship.options.inverse === name);
|
|
1469
|
+
if (explicitRelationship) {
|
|
1470
|
+
possibleRelationships = [explicitRelationship];
|
|
1455
1471
|
}
|
|
1456
1472
|
|
|
1457
1473
|
assert(
|
|
@@ -1462,24 +1478,78 @@ class Model extends EmberObject {
|
|
|
1462
1478
|
', but multiple possible inverse relationships of type ' +
|
|
1463
1479
|
this +
|
|
1464
1480
|
' were found on ' +
|
|
1465
|
-
|
|
1481
|
+
inverseSchema +
|
|
1466
1482
|
'. Look at https://guides.emberjs.com/current/models/relationships/#toc_explicit-inverses for how to explicitly specify inverses',
|
|
1467
1483
|
possibleRelationships.length === 1
|
|
1468
1484
|
);
|
|
1469
1485
|
|
|
1470
|
-
|
|
1486
|
+
fieldOnInverse = possibleRelationships[0].name;
|
|
1471
1487
|
inverseKind = possibleRelationships[0].kind;
|
|
1472
1488
|
inverseOptions = possibleRelationships[0].options;
|
|
1473
1489
|
}
|
|
1474
1490
|
|
|
1491
|
+
// ensure inverse is properly configured
|
|
1492
|
+
if (DEBUG && isPolymorphic) {
|
|
1493
|
+
if (DEPRECATE_NON_EXPLICIT_POLYMORPHISM) {
|
|
1494
|
+
if (!inverseOptions.as) {
|
|
1495
|
+
deprecate(
|
|
1496
|
+
`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${fieldOnInverse}' on type '${inverseSchema.modelName}' is misconfigured.`,
|
|
1497
|
+
false,
|
|
1498
|
+
{
|
|
1499
|
+
id: 'ember-data:non-explicit-relationships',
|
|
1500
|
+
since: { enabled: '4.8', available: '4.8' },
|
|
1501
|
+
until: '5.0',
|
|
1502
|
+
for: 'ember-data',
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
} else {
|
|
1507
|
+
assert(
|
|
1508
|
+
`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${fieldOnInverse}' on type '${inverseSchema.modelName}' is misconfigured.`,
|
|
1509
|
+
inverseOptions.as
|
|
1510
|
+
);
|
|
1511
|
+
assert(
|
|
1512
|
+
`options.as should match the expected type of the polymorphic relationship. Expected field '${fieldOnInverse}' on type '${inverseSchema.modelName}' to specify '${relationship.type}' but found '${inverseOptions.as}'`,
|
|
1513
|
+
!!inverseOptions.as && relationship.type === inverseOptions.as
|
|
1514
|
+
);
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
// ensure we are properly configured
|
|
1519
|
+
if (DEBUG && inverseOptions.polymorphic) {
|
|
1520
|
+
if (DEPRECATE_NON_EXPLICIT_POLYMORPHISM) {
|
|
1521
|
+
if (!options.as) {
|
|
1522
|
+
deprecate(
|
|
1523
|
+
`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${name}' on type '${this.modelName}' is misconfigured.`,
|
|
1524
|
+
false,
|
|
1525
|
+
{
|
|
1526
|
+
id: 'ember-data:non-explicit-relationships',
|
|
1527
|
+
since: { enabled: '4.8', available: '4.8' },
|
|
1528
|
+
until: '5.0',
|
|
1529
|
+
for: 'ember-data',
|
|
1530
|
+
}
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1533
|
+
} else {
|
|
1534
|
+
assert(
|
|
1535
|
+
`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${name}' on type '${this.modelName}' is misconfigured.`,
|
|
1536
|
+
options.as
|
|
1537
|
+
);
|
|
1538
|
+
assert(
|
|
1539
|
+
`options.as should match the expected type of the polymorphic relationship. Expected field '${name}' on type '${this.modelName}' to specify '${inverseRelationship.type}' but found '${options.as}'`,
|
|
1540
|
+
!!options.as && inverseRelationship.type === options.as
|
|
1541
|
+
);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1475
1545
|
assert(
|
|
1476
|
-
`The ${
|
|
1477
|
-
|
|
1546
|
+
`The ${inverseSchema.modelName}:${fieldOnInverse} relationship declares 'inverse: null', but it was resolved as the inverse for ${this.modelName}:${name}.`,
|
|
1547
|
+
inverseOptions.inverse !== null
|
|
1478
1548
|
);
|
|
1479
1549
|
|
|
1480
1550
|
return {
|
|
1481
|
-
type:
|
|
1482
|
-
name:
|
|
1551
|
+
type: inverseSchema,
|
|
1552
|
+
name: fieldOnInverse,
|
|
1483
1553
|
kind: inverseKind,
|
|
1484
1554
|
options: inverseOptions,
|
|
1485
1555
|
};
|
|
@@ -4,11 +4,11 @@ import type PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
|
4
4
|
import type ObjectProxy from '@ember/object/proxy';
|
|
5
5
|
|
|
6
6
|
import type Store from '@ember-data/store';
|
|
7
|
-
import { PromiseObject } from '@ember-data/store/-private';
|
|
8
7
|
import type { RecordInstance } from '@ember-data/types/q/record-instance';
|
|
9
8
|
import type { Dict } from '@ember-data/types/q/utils';
|
|
10
9
|
|
|
11
10
|
import { LegacySupport } from './legacy-relationships-support';
|
|
11
|
+
import { PromiseObject } from './promise-proxy-base';
|
|
12
12
|
|
|
13
13
|
export interface BelongsToProxyMeta {
|
|
14
14
|
key: string;
|
|
@@ -2,18 +2,23 @@ import ArrayMixin, { NativeArray } from '@ember/array';
|
|
|
2
2
|
import type ArrayProxy from '@ember/array/proxy';
|
|
3
3
|
import { assert, deprecate } from '@ember/debug';
|
|
4
4
|
import { dependentKeyCompat } from '@ember/object/compat';
|
|
5
|
+
import { DEBUG } from '@glimmer/env';
|
|
5
6
|
import { tracked } from '@glimmer/tracking';
|
|
6
7
|
import Ember from 'ember';
|
|
7
8
|
|
|
8
9
|
import { resolve } from 'rsvp';
|
|
9
10
|
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
import {
|
|
12
|
+
DEPRECATE_A_USAGE,
|
|
13
|
+
DEPRECATE_COMPUTED_CHAINS,
|
|
14
|
+
DEPRECATE_PROMISE_MANY_ARRAY_BEHAVIORS,
|
|
15
|
+
} from '@ember-data/private-build-infra/deprecations';
|
|
13
16
|
import { StableRecordIdentifier } from '@ember-data/types/q/identifier';
|
|
14
17
|
import type { RecordInstance } from '@ember-data/types/q/record-instance';
|
|
15
18
|
import { FindOptions } from '@ember-data/types/q/store';
|
|
16
19
|
|
|
20
|
+
import type ManyArray from './many-array';
|
|
21
|
+
|
|
17
22
|
export interface HasManyProxyCreateArgs {
|
|
18
23
|
promise: Promise<ManyArray>;
|
|
19
24
|
content?: ManyArray;
|
|
@@ -53,13 +58,27 @@ export default class PromiseManyArray {
|
|
|
53
58
|
this.isDestroyed = false;
|
|
54
59
|
this.isDestroying = false;
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
if (DEPRECATE_A_USAGE) {
|
|
62
|
+
const meta = Ember.meta(this);
|
|
63
|
+
meta.hasMixin = (mixin: Object) => {
|
|
64
|
+
deprecate(`Do not use A() on an EmberData PromiseManyArray`, false, {
|
|
65
|
+
id: 'ember-data:no-a-with-array-like',
|
|
66
|
+
until: '5.0',
|
|
67
|
+
since: { enabled: '4.8', available: '4.8' },
|
|
68
|
+
for: 'ember-data',
|
|
69
|
+
});
|
|
70
|
+
// @ts-expect-error ArrayMixin is more than a type
|
|
71
|
+
if (mixin === NativeArray || mixin === ArrayMixin) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
};
|
|
76
|
+
} else if (DEBUG) {
|
|
77
|
+
const meta = Ember.meta(this);
|
|
78
|
+
meta.hasMixin = (mixin: Object) => {
|
|
79
|
+
assert(`Do not use A() on an EmberData PromiseManyArray`);
|
|
80
|
+
};
|
|
81
|
+
}
|
|
63
82
|
}
|
|
64
83
|
|
|
65
84
|
//---- Methods/Properties on ArrayProxy that we will keep as our API
|
|
@@ -75,7 +94,9 @@ export default class PromiseManyArray {
|
|
|
75
94
|
get length(): number {
|
|
76
95
|
// shouldn't be needed, but ends up being needed
|
|
77
96
|
// for computed chains even in 4.x
|
|
78
|
-
|
|
97
|
+
if (DEPRECATE_COMPUTED_CHAINS) {
|
|
98
|
+
this['[]'];
|
|
99
|
+
}
|
|
79
100
|
return this.content ? this.content.length : 0;
|
|
80
101
|
}
|
|
81
102
|
|
|
@@ -85,7 +106,9 @@ export default class PromiseManyArray {
|
|
|
85
106
|
// to recompute. We entangle the '[]' tag from
|
|
86
107
|
@dependentKeyCompat
|
|
87
108
|
get '[]'() {
|
|
88
|
-
|
|
109
|
+
if (DEPRECATE_COMPUTED_CHAINS) {
|
|
110
|
+
return this.content?.length && this.content;
|
|
111
|
+
}
|
|
89
112
|
}
|
|
90
113
|
|
|
91
114
|
/**
|
|
@@ -99,7 +122,6 @@ export default class PromiseManyArray {
|
|
|
99
122
|
* @private
|
|
100
123
|
*/
|
|
101
124
|
forEach(cb) {
|
|
102
|
-
this['[]']; // needed for < 3.23 support e.g. 3.20 lts
|
|
103
125
|
if (this.content && this.length) {
|
|
104
126
|
this.content.forEach(cb);
|
|
105
127
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { deprecate } from '@ember/debug';
|
|
1
2
|
import { dependentKeyCompat } from '@ember/object/compat';
|
|
2
3
|
import { cached, tracked } from '@glimmer/tracking';
|
|
3
4
|
|
|
4
5
|
import type { Object as JSONObject, Value as JSONValue } from 'json-typescript';
|
|
5
6
|
import { resolve } from 'rsvp';
|
|
6
7
|
|
|
7
|
-
import
|
|
8
|
+
import { DEPRECATE_PROMISE_PROXIES } from '@ember-data/private-build-infra/deprecations';
|
|
9
|
+
import type { Graph } from '@ember-data/record-data/-private/graph/graph';
|
|
8
10
|
import type BelongsToRelationship from '@ember-data/record-data/-private/relationships/state/belongs-to';
|
|
9
11
|
import type Store from '@ember-data/store';
|
|
10
12
|
import { assertPolymorphicType } from '@ember-data/store/-debug';
|
|
@@ -385,8 +387,25 @@ export default class BelongsToReference {
|
|
|
385
387
|
@return {Promise<record>} A promise that resolves with the new value in this belongs-to relationship.
|
|
386
388
|
*/
|
|
387
389
|
async push(data: SingleResourceDocument | Promise<SingleResourceDocument>): Promise<RecordInstance> {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
+
let jsonApiDoc: SingleResourceDocument = data as SingleResourceDocument;
|
|
391
|
+
if (DEPRECATE_PROMISE_PROXIES && (data as { then: unknown }).then) {
|
|
392
|
+
jsonApiDoc = await resolve(data);
|
|
393
|
+
if (jsonApiDoc !== data) {
|
|
394
|
+
deprecate(
|
|
395
|
+
`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`,
|
|
396
|
+
false,
|
|
397
|
+
{
|
|
398
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
399
|
+
until: '5.0',
|
|
400
|
+
since: {
|
|
401
|
+
enabled: '4.8',
|
|
402
|
+
available: '4.8',
|
|
403
|
+
},
|
|
404
|
+
for: 'ember-data',
|
|
405
|
+
}
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
390
409
|
let record = this.store.push(jsonApiDoc);
|
|
391
410
|
|
|
392
411
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { deprecate } from '@ember/debug';
|
|
1
2
|
import { dependentKeyCompat } from '@ember/object/compat';
|
|
2
3
|
import { DEBUG } from '@glimmer/env';
|
|
3
4
|
import { cached, tracked } from '@glimmer/tracking';
|
|
@@ -7,7 +8,8 @@ import { resolve } from 'rsvp';
|
|
|
7
8
|
|
|
8
9
|
import { ManyArray } from 'ember-data/-private';
|
|
9
10
|
|
|
10
|
-
import
|
|
11
|
+
import { DEPRECATE_PROMISE_PROXIES } from '@ember-data/private-build-infra/deprecations';
|
|
12
|
+
import type { Graph } from '@ember-data/record-data/-private/graph/graph';
|
|
11
13
|
import type ManyRelationship from '@ember-data/record-data/-private/relationships/state/has-many';
|
|
12
14
|
import type Store from '@ember-data/store';
|
|
13
15
|
import { recordIdentifierFor } from '@ember-data/store';
|
|
@@ -397,7 +399,25 @@ export default class HasManyReference {
|
|
|
397
399
|
async push(
|
|
398
400
|
objectOrPromise: ExistingResourceObject[] | CollectionResourceDocument | { data: SingleResourceDocument[] }
|
|
399
401
|
): Promise<ManyArray> {
|
|
400
|
-
|
|
402
|
+
let payload = objectOrPromise;
|
|
403
|
+
if (DEPRECATE_PROMISE_PROXIES && (objectOrPromise as unknown as { then: unknown }).then) {
|
|
404
|
+
payload = await resolve(objectOrPromise);
|
|
405
|
+
if (payload !== objectOrPromise) {
|
|
406
|
+
deprecate(
|
|
407
|
+
`You passed in a Promise to a Reference API that now expects a resolved value. await the value before setting it.`,
|
|
408
|
+
false,
|
|
409
|
+
{
|
|
410
|
+
id: 'ember-data:deprecate-promise-proxies',
|
|
411
|
+
until: '5.0',
|
|
412
|
+
since: {
|
|
413
|
+
enabled: '4.8',
|
|
414
|
+
available: '4.8',
|
|
415
|
+
},
|
|
416
|
+
for: 'ember-data',
|
|
417
|
+
}
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
401
421
|
let array: Array<ExistingResourceObject | SingleResourceDocument>;
|
|
402
422
|
|
|
403
423
|
if (!Array.isArray(payload) && typeof payload === 'object' && Array.isArray(payload.data)) {
|
|
@@ -75,7 +75,9 @@ class RelationshipDefinition implements RelationshipSchema {
|
|
|
75
75
|
|
|
76
76
|
if (shouldFindInverse(this.meta)) {
|
|
77
77
|
inverse = modelClass.inverseFor(this.key, store);
|
|
78
|
-
}
|
|
78
|
+
}
|
|
79
|
+
// TODO make this error again for the non-polymorphic case
|
|
80
|
+
if (DEBUG && !this.options.polymorphic) {
|
|
79
81
|
modelClass.typeForRelationship(this.key, store);
|
|
80
82
|
}
|
|
81
83
|
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ember-data/model",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0-alpha.0",
|
|
4
4
|
"description": "A presentation layer for apps built with @ember-data/store",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"test:node": "mocha"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@ember-data/canary-features": "4.
|
|
26
|
-
"@ember-data/private-build-infra": "4.
|
|
27
|
-
"@ember-data/store": "4.
|
|
25
|
+
"@ember-data/canary-features": "4.9.0-alpha.0",
|
|
26
|
+
"@ember-data/private-build-infra": "4.9.0-alpha.0",
|
|
27
|
+
"@ember-data/store": "4.9.0-alpha.0",
|
|
28
28
|
"@ember/edition-utils": "^1.2.0",
|
|
29
29
|
"@ember/string": "^3.0.0",
|
|
30
30
|
"@embroider/macros": "^1.8.3",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"inflection": "~1.13.2"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@ember-data/unpublished-test-infra": "4.
|
|
41
|
+
"@ember-data/unpublished-test-infra": "4.9.0-alpha.0",
|
|
42
42
|
"@ember/optional-features": "^2.0.0",
|
|
43
43
|
"@ember/test-helpers": "~2.7.0",
|
|
44
44
|
"broccoli-asset-rev": "^3.0.0",
|