@ember-data/model 5.4.0-beta.2 → 5.4.0-beta.20
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/LICENSE.md +19 -7
- package/README.md +21 -2
- package/addon-main.cjs +5 -0
- package/blueprints/model/index.js +18 -5
- package/blueprints/model-test/index.js +16 -10
- package/blueprints/model-test/qunit-files/__root__/__path__/__test__.js +4 -5
- package/dist/-private.js +3 -0
- package/{addon → dist}/-private.js.map +1 -1
- package/dist/has-many-DT3JBYYG.js +674 -0
- package/dist/has-many-DT3JBYYG.js.map +1 -0
- package/dist/hooks-CNY5g4Ab.js +75 -0
- package/dist/hooks-CNY5g4Ab.js.map +1 -0
- package/dist/hooks.js +2 -0
- package/{addon → dist}/hooks.js.map +1 -1
- package/dist/index.js +5 -0
- package/{addon → dist}/index.js.map +1 -1
- package/dist/migration-support.js +213 -0
- package/dist/migration-support.js.map +1 -0
- package/{addon/model-YsOraZ6y.js → dist/model-rk3atPqV.js} +899 -936
- package/dist/model-rk3atPqV.js.map +1 -0
- package/dist/schema-provider-Bvogtzx9.js +259 -0
- package/dist/schema-provider-Bvogtzx9.js.map +1 -0
- package/logos/NCC-1701-a-blue.svg +4 -0
- package/logos/NCC-1701-a-gold.svg +4 -0
- package/logos/NCC-1701-a-gold_100.svg +1 -0
- package/logos/NCC-1701-a-gold_base-64.txt +1 -0
- package/logos/NCC-1701-a.svg +4 -0
- package/logos/README.md +4 -0
- package/logos/docs-badge.svg +2 -0
- package/logos/ember-data-logo-dark.svg +12 -0
- package/logos/ember-data-logo-light.svg +12 -0
- package/logos/github-header.svg +444 -0
- package/logos/social1.png +0 -0
- package/logos/social2.png +0 -0
- package/logos/warp-drive-logo-dark.svg +4 -0
- package/logos/warp-drive-logo-gold.svg +4 -0
- package/package.json +58 -103
- package/unstable-preview-types/-private/attr.d.ts +175 -0
- package/unstable-preview-types/-private/attr.d.ts.map +1 -0
- package/unstable-preview-types/-private/attr.type-test.d.ts +4 -0
- package/unstable-preview-types/-private/attr.type-test.d.ts.map +1 -0
- package/unstable-preview-types/-private/belongs-to.d.ts +181 -0
- package/unstable-preview-types/-private/belongs-to.d.ts.map +1 -0
- package/unstable-preview-types/-private/belongs-to.type-test.d.ts +4 -0
- package/unstable-preview-types/-private/belongs-to.type-test.d.ts.map +1 -0
- package/unstable-preview-types/-private/debug/assert-polymorphic-type.d.ts +8 -0
- package/unstable-preview-types/-private/debug/assert-polymorphic-type.d.ts.map +1 -0
- package/unstable-preview-types/-private/errors.d.ts +303 -0
- package/unstable-preview-types/-private/errors.d.ts.map +1 -0
- package/unstable-preview-types/-private/has-many.d.ts +169 -0
- package/unstable-preview-types/-private/has-many.d.ts.map +1 -0
- package/unstable-preview-types/-private/has-many.type-test.d.ts +4 -0
- package/unstable-preview-types/-private/has-many.type-test.d.ts.map +1 -0
- package/unstable-preview-types/-private/hooks.d.ts +13 -0
- package/unstable-preview-types/-private/hooks.d.ts.map +1 -0
- package/unstable-preview-types/-private/legacy-relationships-support.d.ts +60 -0
- package/unstable-preview-types/-private/legacy-relationships-support.d.ts.map +1 -0
- package/unstable-preview-types/-private/model-for-mixin.d.ts +6 -0
- package/unstable-preview-types/-private/model-for-mixin.d.ts.map +1 -0
- package/unstable-preview-types/-private/model-methods.d.ts +37 -0
- package/unstable-preview-types/-private/model-methods.d.ts.map +1 -0
- package/unstable-preview-types/-private/model.d.ts +1303 -0
- package/unstable-preview-types/-private/model.d.ts.map +1 -0
- package/unstable-preview-types/-private/model.type-test.d.ts +4 -0
- package/unstable-preview-types/-private/model.type-test.d.ts.map +1 -0
- package/unstable-preview-types/-private/notify-changes.d.ts +8 -0
- package/unstable-preview-types/-private/notify-changes.d.ts.map +1 -0
- package/unstable-preview-types/-private/promise-belongs-to.d.ts +46 -0
- package/unstable-preview-types/-private/promise-belongs-to.d.ts.map +1 -0
- package/unstable-preview-types/-private/promise-many-array.d.ts +131 -0
- package/unstable-preview-types/-private/promise-many-array.d.ts.map +1 -0
- package/unstable-preview-types/-private/promise-proxy-base.d.ts +5 -0
- package/unstable-preview-types/-private/promise-proxy-base.d.ts.map +1 -0
- package/unstable-preview-types/-private/record-state.d.ts +80 -0
- package/unstable-preview-types/-private/record-state.d.ts.map +1 -0
- package/unstable-preview-types/-private/references/belongs-to.d.ts +503 -0
- package/unstable-preview-types/-private/references/belongs-to.d.ts.map +1 -0
- package/unstable-preview-types/-private/references/has-many.d.ts +515 -0
- package/unstable-preview-types/-private/references/has-many.d.ts.map +1 -0
- package/unstable-preview-types/-private/schema-provider.d.ts +65 -0
- package/unstable-preview-types/-private/schema-provider.d.ts.map +1 -0
- package/unstable-preview-types/-private/type-utils.d.ts +64 -0
- package/unstable-preview-types/-private/type-utils.d.ts.map +1 -0
- package/unstable-preview-types/-private/util.d.ts +8 -0
- package/unstable-preview-types/-private/util.d.ts.map +1 -0
- package/unstable-preview-types/-private.d.ts +13 -0
- package/unstable-preview-types/-private.d.ts.map +1 -0
- package/unstable-preview-types/hooks.d.ts +5 -0
- package/unstable-preview-types/hooks.d.ts.map +1 -0
- package/unstable-preview-types/index.d.ts +76 -0
- package/unstable-preview-types/index.d.ts.map +1 -0
- package/unstable-preview-types/migration-support.d.ts +64 -0
- package/unstable-preview-types/migration-support.d.ts.map +1 -0
- package/addon/-private.js +0 -2
- package/addon/has-many-PdQBns8a.js +0 -323
- package/addon/has-many-PdQBns8a.js.map +0 -1
- package/addon/hooks-dXmQbIOF.js +0 -176
- package/addon/hooks-dXmQbIOF.js.map +0 -1
- package/addon/hooks.js +0 -1
- package/addon/index.js +0 -3
- package/addon/migration-support.js +0 -118
- package/addon/migration-support.js.map +0 -1
- package/addon/model-YsOraZ6y.js.map +0 -1
- package/addon/util-3DHZJC9h.js +0 -38
- package/addon/util-3DHZJC9h.js.map +0 -1
- package/addon-main.js +0 -93
|
@@ -1,496 +1,120 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { deprecate } from '@ember/debug';
|
|
2
|
+
import { dasherize } from '@ember-data/request-utils/string';
|
|
3
|
+
import { macroCondition, getGlobalConfig, dependencySatisfies, importSync } from '@embroider/macros';
|
|
2
4
|
import EmberObject, { computed, get } from '@ember/object';
|
|
3
5
|
import { recordIdentifierFor as recordIdentifierFor$1, storeFor as storeFor$1 } from '@ember-data/store';
|
|
4
|
-
import {
|
|
5
|
-
import { cached, compat } from '@ember-data/tracking';
|
|
6
|
-
import {
|
|
6
|
+
import { isStableIdentifier, recordIdentifierFor, storeFor, peekCache, SOURCE, fastPush, RelatedCollection, coerceId } from '@ember-data/store/-private';
|
|
7
|
+
import { cached, compat, notifySignal } from '@ember-data/tracking';
|
|
8
|
+
import { defineSignal, subscribed } from '@ember-data/tracking/-private';
|
|
7
9
|
import { RecordStore } from '@warp-drive/core-types/symbols';
|
|
8
10
|
import { A } from '@ember/array';
|
|
9
11
|
import ArrayProxy from '@ember/array/proxy';
|
|
10
12
|
import { mapBy, not } from '@ember/object/computed';
|
|
11
|
-
import { macroCondition, getOwnConfig, importSync } from '@embroider/macros';
|
|
12
13
|
import { upgradeStore } from '@ember-data/legacy-compat/-private';
|
|
14
|
+
import { getOrSetGlobal } from '@warp-drive/core-types/-private';
|
|
15
|
+
import { EnableHydration } from '@warp-drive/core-types/request';
|
|
13
16
|
import PromiseProxyMixin from '@ember/object/promise-proxy-mixin';
|
|
14
17
|
import ObjectProxy from '@ember/object/proxy';
|
|
15
18
|
import { cacheFor } from '@ember/object/internals';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
```app/models/comment.js
|
|
44
|
-
import Model, { belongsTo } from '@ember-data/model';
|
|
45
|
-
|
|
46
|
-
export default class CommentModel extends Model {
|
|
47
|
-
@belongsTo('post') post;
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
If you created a new instance of `Post` and added
|
|
52
|
-
a `Comment` record to its `comments` has-many
|
|
53
|
-
relationship, you would expect the comment's `post`
|
|
54
|
-
property to be set to the post that contained
|
|
55
|
-
the has-many.
|
|
56
|
-
|
|
57
|
-
We call the record to which a relationship belongs-to the
|
|
58
|
-
relationship's _owner_.
|
|
59
|
-
|
|
60
|
-
@class ManyArray
|
|
61
|
-
@public
|
|
62
|
-
*/
|
|
63
|
-
class RelatedCollection extends RecordArray {
|
|
64
|
-
/**
|
|
65
|
-
The loading state of this array
|
|
66
|
-
@property {Boolean} isLoaded
|
|
67
|
-
@public
|
|
68
|
-
*/
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
`true` if the relationship is polymorphic, `false` otherwise.
|
|
72
|
-
@property {Boolean} isPolymorphic
|
|
73
|
-
@private
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
Metadata associated with the request for async hasMany relationships.
|
|
78
|
-
Example
|
|
79
|
-
Given that the server returns the following JSON payload when fetching a
|
|
80
|
-
hasMany relationship:
|
|
81
|
-
```js
|
|
82
|
-
{
|
|
83
|
-
"comments": [{
|
|
84
|
-
"id": 1,
|
|
85
|
-
"comment": "This is the first comment",
|
|
86
|
-
}, {
|
|
87
|
-
// ...
|
|
88
|
-
}],
|
|
89
|
-
"meta": {
|
|
90
|
-
"page": 1,
|
|
91
|
-
"total": 5
|
|
19
|
+
function isElementDescriptor(args) {
|
|
20
|
+
const [maybeTarget, maybeKey, maybeDesc] = args;
|
|
21
|
+
return (
|
|
22
|
+
// Ensure we have the right number of args
|
|
23
|
+
args.length === 3 && (
|
|
24
|
+
// Make sure the target is a class or object (prototype)
|
|
25
|
+
typeof maybeTarget === 'function' || typeof maybeTarget === 'object' && maybeTarget !== null) &&
|
|
26
|
+
// Make sure the key is a string
|
|
27
|
+
typeof maybeKey === 'string' && (
|
|
28
|
+
// Make sure the descriptor is the right shape
|
|
29
|
+
typeof maybeDesc === 'object' && maybeDesc !== null && 'enumerable' in maybeDesc && 'configurable' in maybeDesc ||
|
|
30
|
+
// TS compatibility
|
|
31
|
+
maybeDesc === undefined)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
function normalizeModelName(type) {
|
|
35
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_NON_STRICT_TYPES)) {
|
|
36
|
+
const result = dasherize(type);
|
|
37
|
+
deprecate(`The resource type '${type}' is not normalized. Update your application code to use '${result}' instead of '${type}'.`, result === type, {
|
|
38
|
+
id: 'ember-data:deprecate-non-strict-types',
|
|
39
|
+
until: '6.0',
|
|
40
|
+
for: 'ember-data',
|
|
41
|
+
since: {
|
|
42
|
+
available: '4.13',
|
|
43
|
+
enabled: '5.3'
|
|
92
44
|
}
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
You can then access the meta data via the `meta` property:
|
|
96
|
-
```js
|
|
97
|
-
let comments = await post.comments;
|
|
98
|
-
let meta = comments.meta;
|
|
99
|
-
// meta.page => 1
|
|
100
|
-
// meta.total => 5
|
|
101
|
-
```
|
|
102
|
-
@property {Object | null} meta
|
|
103
|
-
@public
|
|
104
|
-
*/
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Retrieve the links for this relationship
|
|
108
|
-
*
|
|
109
|
-
@property {Object | null} links
|
|
110
|
-
@public
|
|
111
|
-
*/
|
|
112
|
-
|
|
113
|
-
// @ts-expect-error
|
|
114
|
-
|
|
115
|
-
constructor(options) {
|
|
116
|
-
super(options);
|
|
117
|
-
this.isLoaded = options.isLoaded || false;
|
|
118
|
-
this.isAsync = options.isAsync || false;
|
|
119
|
-
this.isPolymorphic = options.isPolymorphic || false;
|
|
120
|
-
this.identifier = options.identifier;
|
|
121
|
-
this.key = options.key;
|
|
122
|
-
}
|
|
123
|
-
[MUTATE](target, receiver, prop, args, _SIGNAL) {
|
|
124
|
-
switch (prop) {
|
|
125
|
-
case 'length 0':
|
|
126
|
-
{
|
|
127
|
-
Reflect.set(target, 'length', 0);
|
|
128
|
-
mutateReplaceRelatedRecords(this, [], _SIGNAL);
|
|
129
|
-
return true;
|
|
130
|
-
}
|
|
131
|
-
case 'replace cell':
|
|
132
|
-
{
|
|
133
|
-
const [index, prior, value] = args;
|
|
134
|
-
target[index] = value;
|
|
135
|
-
mutateReplaceRelatedRecord(this, {
|
|
136
|
-
value,
|
|
137
|
-
prior,
|
|
138
|
-
index
|
|
139
|
-
}, _SIGNAL);
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
case 'push':
|
|
143
|
-
{
|
|
144
|
-
const newValues = extractIdentifiersFromRecords(args);
|
|
145
|
-
assertNoDuplicates(this, target, currentState => currentState.push(...newValues), `Cannot push duplicates to a hasMany's state.`);
|
|
146
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
147
|
-
// dedupe
|
|
148
|
-
const seen = new Set(target);
|
|
149
|
-
const unique = new Set();
|
|
150
|
-
args.forEach(item => {
|
|
151
|
-
const identifier = recordIdentifierFor(item);
|
|
152
|
-
if (!seen.has(identifier)) {
|
|
153
|
-
seen.add(identifier);
|
|
154
|
-
unique.add(item);
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
const newArgs = Array.from(unique);
|
|
158
|
-
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
159
|
-
if (newArgs.length) {
|
|
160
|
-
mutateAddToRelatedRecords(this, {
|
|
161
|
-
value: extractIdentifiersFromRecords(newArgs)
|
|
162
|
-
}, _SIGNAL);
|
|
163
|
-
}
|
|
164
|
-
return result;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// else, no dedupe, error on duplicates
|
|
168
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
169
|
-
if (newValues.length) {
|
|
170
|
-
mutateAddToRelatedRecords(this, {
|
|
171
|
-
value: newValues
|
|
172
|
-
}, _SIGNAL);
|
|
173
|
-
}
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
|
-
case 'pop':
|
|
177
|
-
{
|
|
178
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
179
|
-
if (result) {
|
|
180
|
-
mutateRemoveFromRelatedRecords(this, {
|
|
181
|
-
value: recordIdentifierFor(result)
|
|
182
|
-
}, _SIGNAL);
|
|
183
|
-
}
|
|
184
|
-
return result;
|
|
185
|
-
}
|
|
186
|
-
case 'unshift':
|
|
187
|
-
{
|
|
188
|
-
const newValues = extractIdentifiersFromRecords(args);
|
|
189
|
-
assertNoDuplicates(this, target, currentState => currentState.unshift(...newValues), `Cannot unshift duplicates to a hasMany's state.`);
|
|
190
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
191
|
-
// dedupe
|
|
192
|
-
const seen = new Set(target);
|
|
193
|
-
const unique = new Set();
|
|
194
|
-
args.forEach(item => {
|
|
195
|
-
const identifier = recordIdentifierFor(item);
|
|
196
|
-
if (!seen.has(identifier)) {
|
|
197
|
-
seen.add(identifier);
|
|
198
|
-
unique.add(item);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
const newArgs = Array.from(unique);
|
|
202
|
-
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
203
|
-
if (newArgs.length) {
|
|
204
|
-
mutateAddToRelatedRecords(this, {
|
|
205
|
-
value: extractIdentifiersFromRecords(newArgs),
|
|
206
|
-
index: 0
|
|
207
|
-
}, _SIGNAL);
|
|
208
|
-
}
|
|
209
|
-
return result;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// else, no dedupe, error on duplicates
|
|
213
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
214
|
-
if (newValues.length) {
|
|
215
|
-
mutateAddToRelatedRecords(this, {
|
|
216
|
-
value: newValues,
|
|
217
|
-
index: 0
|
|
218
|
-
}, _SIGNAL);
|
|
219
|
-
}
|
|
220
|
-
return result;
|
|
221
|
-
}
|
|
222
|
-
case 'shift':
|
|
223
|
-
{
|
|
224
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
225
|
-
if (result) {
|
|
226
|
-
mutateRemoveFromRelatedRecords(this, {
|
|
227
|
-
value: recordIdentifierFor(result),
|
|
228
|
-
index: 0
|
|
229
|
-
}, _SIGNAL);
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
case 'sort':
|
|
234
|
-
{
|
|
235
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
236
|
-
mutateSortRelatedRecords(this, result.map(recordIdentifierFor), _SIGNAL);
|
|
237
|
-
return result;
|
|
238
|
-
}
|
|
239
|
-
case 'splice':
|
|
240
|
-
{
|
|
241
|
-
const [start, deleteCount, ...adds] = args;
|
|
242
|
-
|
|
243
|
-
// detect a full replace
|
|
244
|
-
if (start === 0 && deleteCount === this[SOURCE].length) {
|
|
245
|
-
const newValues = extractIdentifiersFromRecords(adds);
|
|
246
|
-
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot replace a hasMany's state with a new state that contains duplicates.`);
|
|
247
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
248
|
-
// dedupe
|
|
249
|
-
const current = new Set(adds);
|
|
250
|
-
const unique = Array.from(current);
|
|
251
|
-
const newArgs = [start, deleteCount].concat(unique);
|
|
252
|
-
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
253
|
-
mutateReplaceRelatedRecords(this, extractIdentifiersFromRecords(unique), _SIGNAL);
|
|
254
|
-
return result;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// else, no dedupe, error on duplicates
|
|
258
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
259
|
-
mutateReplaceRelatedRecords(this, newValues, _SIGNAL);
|
|
260
|
-
return result;
|
|
261
|
-
}
|
|
262
|
-
const newValues = extractIdentifiersFromRecords(adds);
|
|
263
|
-
assertNoDuplicates(this, target, currentState => currentState.splice(start, deleteCount, ...newValues), `Cannot splice a hasMany's state with a new state that contains duplicates.`);
|
|
264
|
-
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_MANY_ARRAY_DUPLICATES)) {
|
|
265
|
-
// dedupe
|
|
266
|
-
const currentState = target.slice();
|
|
267
|
-
currentState.splice(start, deleteCount);
|
|
268
|
-
const seen = new Set(currentState);
|
|
269
|
-
const unique = [];
|
|
270
|
-
adds.forEach(item => {
|
|
271
|
-
const identifier = recordIdentifierFor(item);
|
|
272
|
-
if (!seen.has(identifier)) {
|
|
273
|
-
seen.add(identifier);
|
|
274
|
-
unique.push(item);
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
const newArgs = [start, deleteCount, ...unique];
|
|
278
|
-
const result = Reflect.apply(target[prop], receiver, newArgs);
|
|
279
|
-
if (deleteCount > 0) {
|
|
280
|
-
mutateRemoveFromRelatedRecords(this, {
|
|
281
|
-
value: result.map(recordIdentifierFor),
|
|
282
|
-
index: start
|
|
283
|
-
}, _SIGNAL);
|
|
284
|
-
}
|
|
285
|
-
if (unique.length > 0) {
|
|
286
|
-
mutateAddToRelatedRecords(this, {
|
|
287
|
-
value: extractIdentifiersFromRecords(unique),
|
|
288
|
-
index: start
|
|
289
|
-
}, _SIGNAL);
|
|
290
|
-
}
|
|
291
|
-
return result;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// else, no dedupe, error on duplicates
|
|
295
|
-
const result = Reflect.apply(target[prop], receiver, args);
|
|
296
|
-
if (deleteCount > 0) {
|
|
297
|
-
mutateRemoveFromRelatedRecords(this, {
|
|
298
|
-
value: result.map(recordIdentifierFor),
|
|
299
|
-
index: start
|
|
300
|
-
}, _SIGNAL);
|
|
301
|
-
}
|
|
302
|
-
if (newValues.length > 0) {
|
|
303
|
-
mutateAddToRelatedRecords(this, {
|
|
304
|
-
value: newValues,
|
|
305
|
-
index: start
|
|
306
|
-
}, _SIGNAL);
|
|
307
|
-
}
|
|
308
|
-
return result;
|
|
309
|
-
}
|
|
310
|
-
default:
|
|
311
|
-
assert(`unable to convert ${prop} into a transaction that updates the cache state for this record array`);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
notify() {
|
|
315
|
-
const signal = this[ARRAY_SIGNAL];
|
|
316
|
-
signal.shouldReset = true;
|
|
317
|
-
// @ts-expect-error
|
|
318
|
-
notifyArray(this);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
Reloads all of the records in the manyArray. If the manyArray
|
|
323
|
-
holds a relationship that was originally fetched using a links url
|
|
324
|
-
Ember Data will revisit the original links url to repopulate the
|
|
325
|
-
relationship.
|
|
326
|
-
If the manyArray holds the result of a `store.query()` reload will
|
|
327
|
-
re-run the original query.
|
|
328
|
-
Example
|
|
329
|
-
```javascript
|
|
330
|
-
let user = store.peekRecord('user', '1')
|
|
331
|
-
await login(user);
|
|
332
|
-
let permissions = await user.permissions;
|
|
333
|
-
await permissions.reload();
|
|
334
|
-
```
|
|
335
|
-
@method reload
|
|
336
|
-
@public
|
|
337
|
-
*/
|
|
338
|
-
reload(options) {
|
|
339
|
-
// TODO this is odd, we don't ask the store for anything else like this?
|
|
340
|
-
return this._manager.reloadHasMany(this.key, options);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
Saves all of the records in the `ManyArray`.
|
|
345
|
-
Example
|
|
346
|
-
```javascript
|
|
347
|
-
let inbox = await store.findRecord('inbox', '1');
|
|
348
|
-
let messages = await inbox.messages;
|
|
349
|
-
messages.forEach((message) => {
|
|
350
|
-
message.isRead = true;
|
|
351
45
|
});
|
|
352
|
-
|
|
353
|
-
```
|
|
354
|
-
@method save
|
|
355
|
-
@public
|
|
356
|
-
@return {PromiseArray} promise
|
|
357
|
-
*/
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
Create a child record within the owner
|
|
361
|
-
@method createRecord
|
|
362
|
-
@public
|
|
363
|
-
@param {Object} hash
|
|
364
|
-
@return {Model} record
|
|
365
|
-
*/
|
|
366
|
-
createRecord(hash) {
|
|
367
|
-
const {
|
|
368
|
-
store
|
|
369
|
-
} = this;
|
|
370
|
-
assert(`Expected modelName to be set`, this.modelName);
|
|
371
|
-
const record = store.createRecord(this.modelName, hash);
|
|
372
|
-
this.push(record);
|
|
373
|
-
return record;
|
|
374
|
-
}
|
|
375
|
-
destroy() {
|
|
376
|
-
super.destroy(false);
|
|
46
|
+
return result;
|
|
377
47
|
}
|
|
48
|
+
return type;
|
|
378
49
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
try {
|
|
389
|
-
recordIdentifierFor(record);
|
|
390
|
-
return true;
|
|
391
|
-
} catch {
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
}());
|
|
395
|
-
}
|
|
396
|
-
function extractIdentifiersFromRecords(records) {
|
|
397
|
-
return records.map(extractIdentifierFromRecord$1);
|
|
398
|
-
}
|
|
399
|
-
function extractIdentifierFromRecord$1(recordOrPromiseRecord) {
|
|
400
|
-
assertRecordPassedToHasMany(recordOrPromiseRecord);
|
|
401
|
-
return recordIdentifierFor(recordOrPromiseRecord);
|
|
50
|
+
const PromiseObject = ObjectProxy.extend(PromiseProxyMixin);
|
|
51
|
+
const deferred = /* @__PURE__ */new WeakMap();
|
|
52
|
+
function deferDecorator(proto, prop, desc) {
|
|
53
|
+
let map = deferred.get(proto);
|
|
54
|
+
if (!map) {
|
|
55
|
+
map = /* @__PURE__ */new Map();
|
|
56
|
+
deferred.set(proto, map);
|
|
57
|
+
}
|
|
58
|
+
map.set(prop, desc);
|
|
402
59
|
}
|
|
403
|
-
function
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
if (
|
|
409
|
-
|
|
410
|
-
id: 'ember-data:deprecate-many-array-duplicates',
|
|
411
|
-
for: 'ember-data',
|
|
412
|
-
until: '6.0',
|
|
413
|
-
since: {
|
|
414
|
-
enabled: '5.3',
|
|
415
|
-
available: '5.3'
|
|
416
|
-
}
|
|
417
|
-
});
|
|
418
|
-
} else {
|
|
419
|
-
throw new Error(`${reason} Found duplicates for the following records within the new state provided to \`<${collection.identifier.type}:${collection.identifier.id || collection.identifier.lid}>.${collection.key}\`\n\t- ${Array.from(new Set(duplicates)).map(r => isStableIdentifier(r) ? r.lid : recordIdentifierFor(r).lid).sort((a, b) => a.localeCompare(b)).join('\n\t- ')}`);
|
|
60
|
+
function findDeferredDecorator(target, prop) {
|
|
61
|
+
var _a;
|
|
62
|
+
let cursor = target.prototype;
|
|
63
|
+
while (cursor) {
|
|
64
|
+
let desc = (_a = deferred.get(cursor)) == null ? void 0 : _a.get(prop);
|
|
65
|
+
if (desc) {
|
|
66
|
+
return desc;
|
|
420
67
|
}
|
|
68
|
+
cursor = cursor.prototype;
|
|
421
69
|
}
|
|
422
70
|
}
|
|
423
|
-
function
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
field: collection.key,
|
|
436
|
-
...operationInfo
|
|
437
|
-
}, _SIGNAL);
|
|
438
|
-
}
|
|
439
|
-
function mutateReplaceRelatedRecord(collection, operationInfo, _SIGNAL) {
|
|
440
|
-
mutate(collection, {
|
|
441
|
-
op: 'replaceRelatedRecord',
|
|
442
|
-
record: collection.identifier,
|
|
443
|
-
field: collection.key,
|
|
444
|
-
...operationInfo
|
|
445
|
-
}, _SIGNAL);
|
|
446
|
-
}
|
|
447
|
-
function mutateReplaceRelatedRecords(collection, value, _SIGNAL) {
|
|
448
|
-
mutate(collection, {
|
|
449
|
-
op: 'replaceRelatedRecords',
|
|
450
|
-
record: collection.identifier,
|
|
451
|
-
field: collection.key,
|
|
452
|
-
value
|
|
453
|
-
}, _SIGNAL);
|
|
454
|
-
}
|
|
455
|
-
function mutateSortRelatedRecords(collection, value, _SIGNAL) {
|
|
456
|
-
mutate(collection, {
|
|
457
|
-
op: 'sortRelatedRecords',
|
|
458
|
-
record: collection.identifier,
|
|
459
|
-
field: collection.key,
|
|
460
|
-
value
|
|
461
|
-
}, _SIGNAL);
|
|
462
|
-
}
|
|
463
|
-
function mutate(collection, mutation, _SIGNAL) {
|
|
464
|
-
collection._manager.mutate(mutation);
|
|
465
|
-
addToTransaction(_SIGNAL);
|
|
466
|
-
}
|
|
467
|
-
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
|
|
468
|
-
var desc = {};
|
|
469
|
-
Object.keys(descriptor).forEach(function (key) {
|
|
470
|
-
desc[key] = descriptor[key];
|
|
471
|
-
});
|
|
472
|
-
desc.enumerable = !!desc.enumerable;
|
|
473
|
-
desc.configurable = !!desc.configurable;
|
|
474
|
-
if ('value' in desc || desc.initializer) {
|
|
475
|
-
desc.writable = true;
|
|
476
|
-
}
|
|
477
|
-
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
|
|
478
|
-
return decorator(target, property, desc) || desc;
|
|
479
|
-
}, desc);
|
|
480
|
-
if (context && desc.initializer !== void 0) {
|
|
481
|
-
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
|
|
482
|
-
desc.initializer = undefined;
|
|
71
|
+
function decorateFieldV2(prototype, prop, decorators, initializer) {
|
|
72
|
+
let desc = {
|
|
73
|
+
configurable: true,
|
|
74
|
+
enumerable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
initializer: null
|
|
77
|
+
};
|
|
78
|
+
if (initializer) {
|
|
79
|
+
desc.initializer = initializer;
|
|
80
|
+
}
|
|
81
|
+
for (let decorator of decorators) {
|
|
82
|
+
desc = decorator(prototype, prop, desc) || desc;
|
|
483
83
|
}
|
|
484
84
|
if (desc.initializer === void 0) {
|
|
485
|
-
Object.defineProperty(
|
|
486
|
-
|
|
85
|
+
Object.defineProperty(prototype, prop, desc);
|
|
86
|
+
} else {
|
|
87
|
+
deferDecorator(prototype, prop, desc);
|
|
487
88
|
}
|
|
488
|
-
return desc;
|
|
489
89
|
}
|
|
490
|
-
|
|
491
|
-
|
|
90
|
+
function decorateMethodV2(prototype, prop, decorators) {
|
|
91
|
+
const origDesc = Object.getOwnPropertyDescriptor(prototype, prop);
|
|
92
|
+
let desc = {
|
|
93
|
+
...origDesc
|
|
94
|
+
};
|
|
95
|
+
for (let decorator of decorators) {
|
|
96
|
+
desc = decorator(prototype, prop, desc) || desc;
|
|
97
|
+
}
|
|
98
|
+
if (desc.initializer !== void 0) {
|
|
99
|
+
desc.value = desc.initializer ? desc.initializer.call(prototype) : void 0;
|
|
100
|
+
desc.initializer = void 0;
|
|
101
|
+
}
|
|
102
|
+
Object.defineProperty(prototype, prop, desc);
|
|
103
|
+
}
|
|
104
|
+
function initializeDeferredDecorator(target, prop) {
|
|
105
|
+
let desc = findDeferredDecorator(target.constructor, prop);
|
|
106
|
+
if (desc) {
|
|
107
|
+
Object.defineProperty(target, prop, {
|
|
108
|
+
enumerable: desc.enumerable,
|
|
109
|
+
configurable: desc.configurable,
|
|
110
|
+
writable: desc.writable,
|
|
111
|
+
value: desc.initializer ? desc.initializer.call(target) : void 0
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const LegacyPromiseProxy = Symbol.for('LegacyPromiseProxy');
|
|
492
116
|
|
|
493
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-extraneous-class
|
|
494
118
|
|
|
495
119
|
const Extended = PromiseObject;
|
|
496
120
|
|
|
@@ -507,7 +131,7 @@ const Extended = PromiseObject;
|
|
|
507
131
|
@extends PromiseObject
|
|
508
132
|
@private
|
|
509
133
|
*/
|
|
510
|
-
|
|
134
|
+
class PromiseBelongsTo extends Extended {
|
|
511
135
|
get id() {
|
|
512
136
|
const {
|
|
513
137
|
key,
|
|
@@ -520,15 +144,29 @@ let PromiseBelongsTo = (_dec$1 = computed(), (_class$6 = class PromiseBelongsTo
|
|
|
520
144
|
// we don't proxy meta because we would need to proxy it to the relationship state container
|
|
521
145
|
// however, meta on relationships does not trigger change notifications.
|
|
522
146
|
// if you need relationship meta, you should do `record.belongsTo(relationshipName).meta()`
|
|
147
|
+
static {
|
|
148
|
+
decorateMethodV2(this.prototype, "id", [cached]);
|
|
149
|
+
}
|
|
523
150
|
get meta() {
|
|
524
151
|
// eslint-disable-next-line no-constant-condition
|
|
525
152
|
{
|
|
526
|
-
|
|
153
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
154
|
+
{
|
|
155
|
+
throw new Error('You attempted to access meta on the promise for the async belongsTo relationship ' + `${this._belongsToState.modelName}:${this._belongsToState.key}'.` + '\nUse `record.belongsTo(relationshipName).meta()` instead.');
|
|
156
|
+
}
|
|
157
|
+
})() : {};
|
|
527
158
|
}
|
|
528
159
|
return;
|
|
529
160
|
}
|
|
161
|
+
static {
|
|
162
|
+
decorateMethodV2(this.prototype, "meta", [computed()]);
|
|
163
|
+
}
|
|
530
164
|
async reload(options) {
|
|
531
|
-
|
|
165
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
166
|
+
if (!test) {
|
|
167
|
+
throw new Error('You are trying to reload an async belongsTo before it has been created');
|
|
168
|
+
}
|
|
169
|
+
})(this.content !== undefined) : {};
|
|
532
170
|
const {
|
|
533
171
|
key,
|
|
534
172
|
legacySupport
|
|
@@ -536,8 +174,9 @@ let PromiseBelongsTo = (_dec$1 = computed(), (_class$6 = class PromiseBelongsTo
|
|
|
536
174
|
await legacySupport.reloadBelongsTo(key, options);
|
|
537
175
|
return this;
|
|
538
176
|
}
|
|
539
|
-
|
|
540
|
-
|
|
177
|
+
[LegacyPromiseProxy] = true;
|
|
178
|
+
}
|
|
179
|
+
|
|
541
180
|
/**
|
|
542
181
|
@module @ember-data/model
|
|
543
182
|
*/
|
|
@@ -557,14 +196,12 @@ var _class$5;
|
|
|
557
196
|
@class PromiseManyArray
|
|
558
197
|
@public
|
|
559
198
|
*/
|
|
560
|
-
|
|
199
|
+
class PromiseManyArray {
|
|
561
200
|
constructor(promise, content) {
|
|
562
201
|
this._update(promise, content);
|
|
563
202
|
this.isDestroyed = false;
|
|
564
203
|
}
|
|
565
204
|
|
|
566
|
-
//---- Methods/Properties on ArrayProxy that we will keep as our API
|
|
567
|
-
|
|
568
205
|
/**
|
|
569
206
|
* Retrieve the length of the content
|
|
570
207
|
* @property length
|
|
@@ -573,7 +210,8 @@ let PromiseManyArray = (_class$5 = class PromiseManyArray {
|
|
|
573
210
|
get length() {
|
|
574
211
|
// shouldn't be needed, but ends up being needed
|
|
575
212
|
// for computed chains even in 4.x
|
|
576
|
-
if (macroCondition(
|
|
213
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_COMPUTED_CHAINS)) {
|
|
214
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
577
215
|
this['[]'];
|
|
578
216
|
}
|
|
579
217
|
return this.content ? this.content.length : 0;
|
|
@@ -589,6 +227,9 @@ let PromiseManyArray = (_class$5 = class PromiseManyArray {
|
|
|
589
227
|
* @return
|
|
590
228
|
* @private
|
|
591
229
|
*/
|
|
230
|
+
static {
|
|
231
|
+
decorateMethodV2(this.prototype, "length", [compat]);
|
|
232
|
+
}
|
|
592
233
|
forEach(cb) {
|
|
593
234
|
if (this.content && this.length) {
|
|
594
235
|
this.content.forEach(cb);
|
|
@@ -603,7 +244,11 @@ let PromiseManyArray = (_class$5 = class PromiseManyArray {
|
|
|
603
244
|
* @return
|
|
604
245
|
*/
|
|
605
246
|
reload(options) {
|
|
606
|
-
|
|
247
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
248
|
+
if (!test) {
|
|
249
|
+
throw new Error('You are trying to reload an async manyArray before it has been created');
|
|
250
|
+
}
|
|
251
|
+
})(this.content) : {};
|
|
607
252
|
void this.content.reload(options);
|
|
608
253
|
return this;
|
|
609
254
|
}
|
|
@@ -698,12 +343,17 @@ let PromiseManyArray = (_class$5 = class PromiseManyArray {
|
|
|
698
343
|
* @property meta
|
|
699
344
|
* @public
|
|
700
345
|
*/
|
|
346
|
+
static {
|
|
347
|
+
decorateMethodV2(this.prototype, "links", [compat]);
|
|
348
|
+
}
|
|
701
349
|
get meta() {
|
|
702
350
|
return this.content ? this.content.meta : undefined;
|
|
703
351
|
}
|
|
704
352
|
|
|
705
353
|
//---- Our own stuff
|
|
706
|
-
|
|
354
|
+
static {
|
|
355
|
+
decorateMethodV2(this.prototype, "meta", [compat]);
|
|
356
|
+
}
|
|
707
357
|
_update(promise, content) {
|
|
708
358
|
if (content !== undefined) {
|
|
709
359
|
this.content = content;
|
|
@@ -716,7 +366,8 @@ let PromiseManyArray = (_class$5 = class PromiseManyArray {
|
|
|
716
366
|
}) {
|
|
717
367
|
return new this(promise, content);
|
|
718
368
|
}
|
|
719
|
-
|
|
369
|
+
[LegacyPromiseProxy] = true;
|
|
370
|
+
}
|
|
720
371
|
defineSignal(PromiseManyArray.prototype, 'content', null);
|
|
721
372
|
defineSignal(PromiseManyArray.prototype, 'isPending', false);
|
|
722
373
|
defineSignal(PromiseManyArray.prototype, 'isRejected', false);
|
|
@@ -727,7 +378,7 @@ defineSignal(PromiseManyArray.prototype, 'isSettled', false);
|
|
|
727
378
|
// A(identifierArray) since it is not configurable
|
|
728
379
|
// which is preferrable to the `meta` override we used
|
|
729
380
|
// before which required importing all of Ember
|
|
730
|
-
if (macroCondition(
|
|
381
|
+
if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_COMPUTED_CHAINS)) {
|
|
731
382
|
const desc = {
|
|
732
383
|
enumerable: true,
|
|
733
384
|
configurable: false,
|
|
@@ -741,7 +392,7 @@ if (macroCondition(getOwnConfig().deprecations.DEPRECATE_COMPUTED_CHAINS)) {
|
|
|
741
392
|
// requires that the tag `'[]'` be notified
|
|
742
393
|
// on the ArrayProxy in order for `{{#each}}`
|
|
743
394
|
// to recompute. We entangle the '[]' tag from content
|
|
744
|
-
|
|
395
|
+
|
|
745
396
|
Object.defineProperty(PromiseManyArray.prototype, '[]', desc);
|
|
746
397
|
}
|
|
747
398
|
function tapPromise(proxy, promise) {
|
|
@@ -777,21 +428,29 @@ function tapPromise(proxy, promise) {
|
|
|
777
428
|
`record.relationshipFor(key)`.
|
|
778
429
|
*/
|
|
779
430
|
let assertPolymorphicType;
|
|
780
|
-
if (macroCondition(
|
|
431
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
432
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
781
433
|
assertPolymorphicType = function assertPolymorphicType(parentIdentifier, parentDefinition, addedIdentifier, store) {
|
|
782
434
|
if (parentDefinition.inverseIsImplicit) {
|
|
783
435
|
return;
|
|
784
436
|
}
|
|
785
437
|
if (parentDefinition.isPolymorphic) {
|
|
786
|
-
|
|
787
|
-
|
|
438
|
+
const meta = store.schema.fields(addedIdentifier)?.get(parentDefinition.inverseKey);
|
|
439
|
+
if (meta) {
|
|
440
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
441
|
+
if (!test) {
|
|
442
|
+
throw new Error(`Expected the schema for the field ${parentDefinition.inverseKey} on ${addedIdentifier.type} to be for a legacy relationship`);
|
|
443
|
+
}
|
|
444
|
+
})(meta.kind === 'belongsTo' || meta.kind === 'hasMany') : {};
|
|
445
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
446
|
+
if (!test) {
|
|
447
|
+
throw new Error(`The schema for the relationship '${parentDefinition.inverseKey}' on '${addedIdentifier.type}' type does not implement '${parentDefinition.type}' and thus cannot be assigned to the '${parentDefinition.key}' relationship in '${parentIdentifier.type}'. The definition should specify 'as: "${parentDefinition.type}"' in options.`);
|
|
448
|
+
}
|
|
449
|
+
})(meta?.options?.as === parentDefinition.type) : {};
|
|
450
|
+
}
|
|
788
451
|
}
|
|
789
452
|
};
|
|
790
453
|
}
|
|
791
|
-
var _class$4;
|
|
792
|
-
/**
|
|
793
|
-
@module @ember-data/model
|
|
794
|
-
*/
|
|
795
454
|
function isResourceIdentiferWithRelatedLinks$1(value) {
|
|
796
455
|
return Boolean(value && value.links && value.links.related);
|
|
797
456
|
}
|
|
@@ -823,24 +482,26 @@ function isResourceIdentiferWithRelatedLinks$1(value) {
|
|
|
823
482
|
@class HasManyReference
|
|
824
483
|
@public
|
|
825
484
|
*/
|
|
826
|
-
|
|
485
|
+
class HasManyReference {
|
|
486
|
+
/**
|
|
487
|
+
* The field name on the parent record for this has-many relationship.
|
|
488
|
+
*
|
|
489
|
+
* @property {String} key
|
|
490
|
+
* @public
|
|
491
|
+
*/
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* The type of resource this relationship will contain.
|
|
495
|
+
*
|
|
496
|
+
* @property {String} type
|
|
497
|
+
* @public
|
|
498
|
+
*/
|
|
499
|
+
|
|
500
|
+
// unsubscribe tokens given to us by the notification manager
|
|
501
|
+
___token;
|
|
502
|
+
___identifier;
|
|
503
|
+
___relatedTokenMap;
|
|
827
504
|
constructor(store, graph, parentIdentifier, hasManyRelationship, key) {
|
|
828
|
-
/**
|
|
829
|
-
* The field name on the parent record for this has-many relationship.
|
|
830
|
-
*
|
|
831
|
-
* @property {String} key
|
|
832
|
-
* @public
|
|
833
|
-
*/
|
|
834
|
-
/**
|
|
835
|
-
* The type of resource this relationship will contain.
|
|
836
|
-
*
|
|
837
|
-
* @property {String} type
|
|
838
|
-
* @public
|
|
839
|
-
*/
|
|
840
|
-
// unsubscribe tokens given to us by the notification manager
|
|
841
|
-
this.___token = void 0;
|
|
842
|
-
this.___identifier = void 0;
|
|
843
|
-
this.___relatedTokenMap = void 0;
|
|
844
505
|
this.graph = graph;
|
|
845
506
|
this.key = key;
|
|
846
507
|
this.hasManyRelationship = hasManyRelationship;
|
|
@@ -876,8 +537,9 @@ let HasManyReference = (_class$4 = class HasManyReference {
|
|
|
876
537
|
* @public
|
|
877
538
|
*/
|
|
878
539
|
get identifiers() {
|
|
879
|
-
this
|
|
880
|
-
|
|
540
|
+
ensureRefCanSubscribe(this);
|
|
541
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
542
|
+
this._ref;
|
|
881
543
|
const resource = this._resource();
|
|
882
544
|
const map = this.___relatedTokenMap;
|
|
883
545
|
this.___relatedTokenMap = new Map();
|
|
@@ -904,6 +566,9 @@ let HasManyReference = (_class$4 = class HasManyReference {
|
|
|
904
566
|
map.clear();
|
|
905
567
|
return [];
|
|
906
568
|
}
|
|
569
|
+
static {
|
|
570
|
+
decorateMethodV2(this.prototype, "identifiers", [compat, cached]);
|
|
571
|
+
}
|
|
907
572
|
_resource() {
|
|
908
573
|
const cache = this.store.cache;
|
|
909
574
|
return cache.getRelationship(this.___identifier, this.key);
|
|
@@ -1173,12 +838,16 @@ let HasManyReference = (_class$4 = class HasManyReference {
|
|
|
1173
838
|
const isResourceData = Array.isArray(dataDoc.data) && dataDoc.data.length > 0 && isMaybeResource(dataDoc.data[0]);
|
|
1174
839
|
|
|
1175
840
|
// enforce that one of links, meta or data is present
|
|
1176
|
-
|
|
841
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
842
|
+
if (!test) {
|
|
843
|
+
throw new Error(`You must provide at least one of 'links', 'meta' or 'data' when calling hasManyReference.push`);
|
|
844
|
+
}
|
|
845
|
+
})('links' in dataDoc || 'meta' in dataDoc || 'data' in dataDoc) : {};
|
|
1177
846
|
const identifiers = !Array.isArray(dataDoc.data) ? [] : isResourceData ? store._push(dataDoc, true) : dataDoc.data.map(i => store.identifierCache.getOrCreateRecordIdentifier(i));
|
|
1178
847
|
const {
|
|
1179
848
|
identifier
|
|
1180
849
|
} = this.hasManyRelationship;
|
|
1181
|
-
if (macroCondition(
|
|
850
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
1182
851
|
const relationshipMeta = this.hasManyRelationship.definition;
|
|
1183
852
|
identifiers.forEach(added => {
|
|
1184
853
|
assertPolymorphicType(identifier, relationshipMeta, added, store);
|
|
@@ -1252,10 +921,8 @@ let HasManyReference = (_class$4 = class HasManyReference {
|
|
|
1252
921
|
*/
|
|
1253
922
|
value() {
|
|
1254
923
|
const support = LEGACY_SUPPORT.get(this.___identifier);
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
// subscribe to changes
|
|
1258
|
-
// for when we are not loaded yet
|
|
924
|
+
if (!ensureRefCanSubscribe(this)) {
|
|
925
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
1259
926
|
this._ref;
|
|
1260
927
|
return null;
|
|
1261
928
|
}
|
|
@@ -1368,13 +1035,32 @@ let HasManyReference = (_class$4 = class HasManyReference {
|
|
|
1368
1035
|
const support = LEGACY_SUPPORT.get(this.___identifier);
|
|
1369
1036
|
return support.reloadHasMany(this.key, options);
|
|
1370
1037
|
}
|
|
1371
|
-
}
|
|
1038
|
+
}
|
|
1372
1039
|
defineSignal(HasManyReference.prototype, '_ref', 0);
|
|
1373
1040
|
function isMaybeResource(object) {
|
|
1374
1041
|
const keys = Object.keys(object).filter(k => k !== 'id' && k !== 'type' && k !== 'lid');
|
|
1375
1042
|
return keys.length > 0;
|
|
1376
1043
|
}
|
|
1377
|
-
|
|
1044
|
+
function ensureRefCanSubscribe(rel) {
|
|
1045
|
+
const loaded = rel._isLoaded();
|
|
1046
|
+
if (!loaded) {
|
|
1047
|
+
// subscribe to changes
|
|
1048
|
+
// for when we are not loaded yet
|
|
1049
|
+
//
|
|
1050
|
+
// because the graph optimizes the case where a relationship has never been subscribed,
|
|
1051
|
+
// we force accessed to be true here. When we make the graph public we should create a
|
|
1052
|
+
// subscribe/unsubscribe API
|
|
1053
|
+
const edge = rel.graph.get(rel.___identifier, rel.key);
|
|
1054
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1055
|
+
if (!test) {
|
|
1056
|
+
throw new Error(`Expected a hasMany relationship for ${rel.___identifier.type}:${rel.key}`);
|
|
1057
|
+
}
|
|
1058
|
+
})('accessed' in edge) : {};
|
|
1059
|
+
edge.accessed = true;
|
|
1060
|
+
return false;
|
|
1061
|
+
}
|
|
1062
|
+
return true;
|
|
1063
|
+
}
|
|
1378
1064
|
function isResourceIdentiferWithRelatedLinks(value) {
|
|
1379
1065
|
return Boolean(value && value.links && value.links.related);
|
|
1380
1066
|
}
|
|
@@ -1407,7 +1093,7 @@ function isResourceIdentiferWithRelatedLinks(value) {
|
|
|
1407
1093
|
@class BelongsToReference
|
|
1408
1094
|
@public
|
|
1409
1095
|
*/
|
|
1410
|
-
|
|
1096
|
+
class BelongsToReference {
|
|
1411
1097
|
/**
|
|
1412
1098
|
* The field name on the parent record for this has-many relationship.
|
|
1413
1099
|
*
|
|
@@ -1510,6 +1196,9 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1510
1196
|
@public
|
|
1511
1197
|
@return {String} The id of the record in this belongsTo relationship.
|
|
1512
1198
|
*/
|
|
1199
|
+
static {
|
|
1200
|
+
decorateMethodV2(this.prototype, "identifier", [compat, cached]);
|
|
1201
|
+
}
|
|
1513
1202
|
id() {
|
|
1514
1203
|
return this.identifier?.id || null;
|
|
1515
1204
|
}
|
|
@@ -1613,6 +1302,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1613
1302
|
return meta;
|
|
1614
1303
|
}
|
|
1615
1304
|
_resource() {
|
|
1305
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
1616
1306
|
this._ref; // subscribe
|
|
1617
1307
|
const cache = this.store.cache;
|
|
1618
1308
|
return cache.getRelationship(this.___identifier, this.key);
|
|
@@ -1737,7 +1427,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1737
1427
|
@public
|
|
1738
1428
|
@param {Object} doc a JSONAPI document object describing the new value of this relationship.
|
|
1739
1429
|
@param {Boolean} [skipFetch] if `true`, do not attempt to fetch unloaded records
|
|
1740
|
-
@return {Promise<
|
|
1430
|
+
@return {Promise<OpaqueRecordInstance | null | void>}
|
|
1741
1431
|
*/
|
|
1742
1432
|
async push(doc, skipFetch) {
|
|
1743
1433
|
const {
|
|
@@ -1748,7 +1438,7 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1748
1438
|
const {
|
|
1749
1439
|
identifier
|
|
1750
1440
|
} = this.belongsToRelationship;
|
|
1751
|
-
if (macroCondition(
|
|
1441
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
1752
1442
|
if (added) {
|
|
1753
1443
|
assertPolymorphicType(identifier, this.belongsToRelationship.definition, added, store);
|
|
1754
1444
|
}
|
|
@@ -1929,15 +1619,23 @@ let BelongsToReference = (_class$3 = class BelongsToReference {
|
|
|
1929
1619
|
const support = LEGACY_SUPPORT.get(this.___identifier);
|
|
1930
1620
|
return support.reloadBelongsTo(this.key, options).then(() => this.value());
|
|
1931
1621
|
}
|
|
1932
|
-
}
|
|
1622
|
+
}
|
|
1933
1623
|
defineSignal(BelongsToReference.prototype, '_ref', 0);
|
|
1934
|
-
const LEGACY_SUPPORT = new Map();
|
|
1624
|
+
const LEGACY_SUPPORT = getOrSetGlobal('LEGACY_SUPPORT', new Map());
|
|
1935
1625
|
function lookupLegacySupport(record) {
|
|
1936
1626
|
const identifier = recordIdentifierFor(record);
|
|
1937
|
-
|
|
1627
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1628
|
+
if (!test) {
|
|
1629
|
+
throw new Error(`Expected a record`);
|
|
1630
|
+
}
|
|
1631
|
+
})(identifier) : {};
|
|
1938
1632
|
let support = LEGACY_SUPPORT.get(identifier);
|
|
1939
1633
|
if (!support) {
|
|
1940
|
-
|
|
1634
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1635
|
+
if (!test) {
|
|
1636
|
+
throw new Error(`Memory Leak Detected`);
|
|
1637
|
+
}
|
|
1638
|
+
})(!record.isDestroyed && !record.isDestroying) : {};
|
|
1941
1639
|
support = new LegacySupport(record);
|
|
1942
1640
|
LEGACY_SUPPORT.set(identifier, support);
|
|
1943
1641
|
LEGACY_SUPPORT.set(record, support);
|
|
@@ -1950,7 +1648,7 @@ class LegacySupport {
|
|
|
1950
1648
|
this.store = storeFor(record);
|
|
1951
1649
|
this.identifier = recordIdentifierFor(record);
|
|
1952
1650
|
this.cache = peekCache(record);
|
|
1953
|
-
if (macroCondition(
|
|
1651
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
1954
1652
|
const graphFor = importSync('@ember-data/graph/-private').graphFor;
|
|
1955
1653
|
this.graph = graphFor(this.store);
|
|
1956
1654
|
}
|
|
@@ -1991,7 +1689,11 @@ class LegacySupport {
|
|
|
1991
1689
|
return loadingPromise;
|
|
1992
1690
|
}
|
|
1993
1691
|
const relationship = this.graph.get(this.identifier, key);
|
|
1994
|
-
|
|
1692
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1693
|
+
if (!test) {
|
|
1694
|
+
throw new Error(`Expected ${key} to be a belongs-to relationship`);
|
|
1695
|
+
}
|
|
1696
|
+
})(isBelongsTo(relationship)) : {};
|
|
1995
1697
|
const resource = this.cache.getRelationship(this.identifier, key);
|
|
1996
1698
|
relationship.state.hasFailedLoadAttempt = false;
|
|
1997
1699
|
relationship.state.shouldForceReload = true;
|
|
@@ -2011,10 +1713,18 @@ class LegacySupport {
|
|
|
2011
1713
|
} = this;
|
|
2012
1714
|
const resource = cache.getRelationship(this.identifier, key);
|
|
2013
1715
|
const relatedIdentifier = resource && resource.data ? resource.data : null;
|
|
2014
|
-
|
|
1716
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1717
|
+
if (!test) {
|
|
1718
|
+
throw new Error(`Expected a stable identifier`);
|
|
1719
|
+
}
|
|
1720
|
+
})(!relatedIdentifier || isStableIdentifier(relatedIdentifier)) : {};
|
|
2015
1721
|
const store = this.store;
|
|
2016
1722
|
const relationship = this.graph.get(this.identifier, key);
|
|
2017
|
-
|
|
1723
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1724
|
+
if (!test) {
|
|
1725
|
+
throw new Error(`Expected ${key} to be a belongs-to relationship`);
|
|
1726
|
+
}
|
|
1727
|
+
})(isBelongsTo(relationship)) : {};
|
|
2018
1728
|
const isAsync = relationship.definition.isAsync;
|
|
2019
1729
|
const _belongsToState = {
|
|
2020
1730
|
key,
|
|
@@ -2037,9 +1747,12 @@ class LegacySupport {
|
|
|
2037
1747
|
if (relatedIdentifier === null) {
|
|
2038
1748
|
return null;
|
|
2039
1749
|
} else {
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
1750
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1751
|
+
if (!test) {
|
|
1752
|
+
throw new Error(`You looked up the '${key}' relationship on a '${identifier.type}' with id ${identifier.id || 'null'} but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (\`belongsTo(<type>, { async: true, inverse: <inverse> })\`)`);
|
|
1753
|
+
}
|
|
1754
|
+
})(store._instanceCache.recordIsLoaded(relatedIdentifier, true)) : {};
|
|
1755
|
+
return store._instanceCache.getRecord(relatedIdentifier);
|
|
2043
1756
|
}
|
|
2044
1757
|
}
|
|
2045
1758
|
}
|
|
@@ -2060,7 +1773,11 @@ class LegacySupport {
|
|
|
2060
1773
|
if (jsonApi.data) {
|
|
2061
1774
|
for (let i = 0; i < jsonApi.data.length; i++) {
|
|
2062
1775
|
const relatedIdentifier = jsonApi.data[i];
|
|
2063
|
-
|
|
1776
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1777
|
+
if (!test) {
|
|
1778
|
+
throw new Error(`Expected a stable identifier`);
|
|
1779
|
+
}
|
|
1780
|
+
})(isStableIdentifier(relatedIdentifier)) : {};
|
|
2064
1781
|
if (cache.recordIsLoaded(relatedIdentifier, true)) {
|
|
2065
1782
|
identifiers.push(relatedIdentifier);
|
|
2066
1783
|
}
|
|
@@ -2069,7 +1786,7 @@ class LegacySupport {
|
|
|
2069
1786
|
return [identifiers, jsonApi];
|
|
2070
1787
|
}
|
|
2071
1788
|
getManyArray(key, definition) {
|
|
2072
|
-
if (macroCondition(
|
|
1789
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
2073
1790
|
let manyArray = this._manyArrayCache[key];
|
|
2074
1791
|
if (!definition) {
|
|
2075
1792
|
definition = this.graph.get(this.identifier, key).definition;
|
|
@@ -2088,6 +1805,7 @@ class LegacySupport {
|
|
|
2088
1805
|
isPolymorphic: definition.isPolymorphic,
|
|
2089
1806
|
isAsync: definition.isAsync,
|
|
2090
1807
|
_inverseIsAsync: definition.inverseIsAsync,
|
|
1808
|
+
// @ts-expect-error Typescript doesn't have a way for us to thread the generic backwards so it infers unknown instead of T
|
|
2091
1809
|
manager: this,
|
|
2092
1810
|
isLoaded: !definition.isAsync,
|
|
2093
1811
|
allowMutation: true
|
|
@@ -2096,10 +1814,14 @@ class LegacySupport {
|
|
|
2096
1814
|
}
|
|
2097
1815
|
return manyArray;
|
|
2098
1816
|
}
|
|
2099
|
-
|
|
1817
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1818
|
+
{
|
|
1819
|
+
throw new Error('hasMany only works with the @ember-data/json-api package');
|
|
1820
|
+
}
|
|
1821
|
+
})() : {};
|
|
2100
1822
|
}
|
|
2101
1823
|
fetchAsyncHasMany(key, relationship, manyArray, options) {
|
|
2102
|
-
if (macroCondition(
|
|
1824
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
2103
1825
|
let loadingPromise = this._relationshipPromisesCache[key];
|
|
2104
1826
|
if (loadingPromise) {
|
|
2105
1827
|
return loadingPromise;
|
|
@@ -2114,10 +1836,14 @@ class LegacySupport {
|
|
|
2114
1836
|
this._relationshipPromisesCache[key] = loadingPromise;
|
|
2115
1837
|
return loadingPromise;
|
|
2116
1838
|
}
|
|
2117
|
-
|
|
1839
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1840
|
+
{
|
|
1841
|
+
throw new Error('hasMany only works with the @ember-data/json-api package');
|
|
1842
|
+
}
|
|
1843
|
+
})() : {};
|
|
2118
1844
|
}
|
|
2119
1845
|
reloadHasMany(key, options) {
|
|
2120
|
-
if (macroCondition(
|
|
1846
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
2121
1847
|
const loadingPromise = this._relationshipPromisesCache[key];
|
|
2122
1848
|
if (loadingPromise) {
|
|
2123
1849
|
return loadingPromise;
|
|
@@ -2138,10 +1864,14 @@ class LegacySupport {
|
|
|
2138
1864
|
}
|
|
2139
1865
|
return promise;
|
|
2140
1866
|
}
|
|
2141
|
-
|
|
1867
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1868
|
+
{
|
|
1869
|
+
throw new Error(`hasMany only works with the @ember-data/json-api package`);
|
|
1870
|
+
}
|
|
1871
|
+
})() : {};
|
|
2142
1872
|
}
|
|
2143
1873
|
getHasMany(key, options) {
|
|
2144
|
-
if (macroCondition(
|
|
1874
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
2145
1875
|
const relationship = this.graph.get(this.identifier, key);
|
|
2146
1876
|
const {
|
|
2147
1877
|
definition,
|
|
@@ -2158,11 +1888,19 @@ class LegacySupport {
|
|
|
2158
1888
|
content: manyArray
|
|
2159
1889
|
});
|
|
2160
1890
|
} else {
|
|
2161
|
-
|
|
1891
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1892
|
+
if (!test) {
|
|
1893
|
+
throw new Error(`You looked up the '${key}' relationship on a '${this.identifier.type}' with id ${this.identifier.id || 'null'} but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async ('hasMany(<type>, { async: true, inverse: <inverse> })')`);
|
|
1894
|
+
}
|
|
1895
|
+
})(!anyUnloaded(this.store, relationship)) : {};
|
|
2162
1896
|
return manyArray;
|
|
2163
1897
|
}
|
|
2164
1898
|
}
|
|
2165
|
-
|
|
1899
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1900
|
+
{
|
|
1901
|
+
throw new Error(`hasMany only works with the @ember-data/json-api package`);
|
|
1902
|
+
}
|
|
1903
|
+
})() : {};
|
|
2166
1904
|
}
|
|
2167
1905
|
_updatePromiseProxyFor(kind, key, args) {
|
|
2168
1906
|
let promiseProxy = this._relationshipProxyCache[key];
|
|
@@ -2172,7 +1910,11 @@ class LegacySupport {
|
|
|
2172
1910
|
content
|
|
2173
1911
|
} = args;
|
|
2174
1912
|
if (promiseProxy) {
|
|
2175
|
-
|
|
1913
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1914
|
+
if (!test) {
|
|
1915
|
+
throw new Error(`Expected a PromiseManyArray`);
|
|
1916
|
+
}
|
|
1917
|
+
})('_update' in promiseProxy) : {};
|
|
2176
1918
|
promiseProxy._update(promise, content);
|
|
2177
1919
|
} else {
|
|
2178
1920
|
promiseProxy = this._relationshipProxyCache[key] = new PromiseManyArray(promise, content);
|
|
@@ -2184,7 +1926,11 @@ class LegacySupport {
|
|
|
2184
1926
|
promise,
|
|
2185
1927
|
content
|
|
2186
1928
|
} = args;
|
|
2187
|
-
|
|
1929
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1930
|
+
if (!test) {
|
|
1931
|
+
throw new Error(`Expected a PromiseBelongsTo`);
|
|
1932
|
+
}
|
|
1933
|
+
})('_belongsToState' in promiseProxy) : {};
|
|
2188
1934
|
if (content !== undefined) {
|
|
2189
1935
|
promiseProxy.set('content', content);
|
|
2190
1936
|
}
|
|
@@ -2198,22 +1944,30 @@ class LegacySupport {
|
|
|
2198
1944
|
referenceFor(kind, name) {
|
|
2199
1945
|
let reference = this.references[name];
|
|
2200
1946
|
if (!reference) {
|
|
2201
|
-
if (macroCondition(!
|
|
1947
|
+
if (macroCondition(!dependencySatisfies('@ember-data/graph', '*'))) {
|
|
2202
1948
|
// TODO @runspired while this feels odd, it is not a regression in capability because we do
|
|
2203
1949
|
// not today support references pulling from RecordDatas other than our own
|
|
2204
1950
|
// because of the intimate API access involved. This is something we will need to redesign.
|
|
2205
|
-
|
|
1951
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1952
|
+
{
|
|
1953
|
+
throw new Error(`snapshot.belongsTo only supported for @ember-data/json-api`);
|
|
1954
|
+
}
|
|
1955
|
+
})() : {};
|
|
2206
1956
|
}
|
|
2207
1957
|
const {
|
|
2208
1958
|
graph,
|
|
2209
1959
|
identifier
|
|
2210
1960
|
} = this;
|
|
2211
1961
|
const relationship = graph.get(identifier, name);
|
|
2212
|
-
if (macroCondition(
|
|
1962
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
2213
1963
|
if (kind) {
|
|
2214
1964
|
const modelName = identifier.type;
|
|
2215
1965
|
const actualRelationshipKind = relationship.definition.kind;
|
|
2216
|
-
|
|
1966
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
1967
|
+
if (!test) {
|
|
1968
|
+
throw new Error(`You tried to get the '${name}' relationship on a '${modelName}' via record.${kind}('${name}'), but the relationship is of kind '${actualRelationshipKind}'. Use record.${actualRelationshipKind}('${name}') instead.`);
|
|
1969
|
+
}
|
|
1970
|
+
})(actualRelationshipKind === kind) : {};
|
|
2217
1971
|
}
|
|
2218
1972
|
}
|
|
2219
1973
|
const relationshipKind = relationship.definition.kind;
|
|
@@ -2227,7 +1981,7 @@ class LegacySupport {
|
|
|
2227
1981
|
return reference;
|
|
2228
1982
|
}
|
|
2229
1983
|
_findHasManyByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
2230
|
-
if (macroCondition(
|
|
1984
|
+
if (macroCondition(dependencySatisfies('@ember-data/graph', '*'))) {
|
|
2231
1985
|
if (!resource) {
|
|
2232
1986
|
return;
|
|
2233
1987
|
}
|
|
@@ -2236,7 +1990,7 @@ class LegacySupport {
|
|
|
2236
1990
|
state
|
|
2237
1991
|
} = relationship;
|
|
2238
1992
|
upgradeStore(this.store);
|
|
2239
|
-
const adapter = this.store.adapterFor(definition.type);
|
|
1993
|
+
const adapter = this.store.adapterFor?.(definition.type);
|
|
2240
1994
|
const {
|
|
2241
1995
|
isStale,
|
|
2242
1996
|
hasDematerializedInverse,
|
|
@@ -2246,13 +2000,18 @@ class LegacySupport {
|
|
|
2246
2000
|
} = state;
|
|
2247
2001
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
2248
2002
|
const identifiers = resource.data;
|
|
2249
|
-
const shouldFindViaLink = resource.links && resource.links.related && (typeof adapter
|
|
2250
|
-
const
|
|
2003
|
+
const shouldFindViaLink = resource.links && resource.links.related && (typeof adapter?.findHasMany === 'function' || typeof identifiers === 'undefined') && (shouldForceReload || hasDematerializedInverse || isStale || !allInverseRecordsAreLoaded && !isEmpty);
|
|
2004
|
+
const field = this.store.schema.fields({
|
|
2251
2005
|
type: definition.inverseType
|
|
2252
|
-
})
|
|
2006
|
+
}).get(definition.key);
|
|
2007
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2008
|
+
if (!test) {
|
|
2009
|
+
throw new Error(`Expected a hasMany field definition for ${definition.inverseType}.${definition.key}`);
|
|
2010
|
+
}
|
|
2011
|
+
})(field && field.kind === 'hasMany') : {};
|
|
2253
2012
|
const request = {
|
|
2254
2013
|
useLink: shouldFindViaLink,
|
|
2255
|
-
field
|
|
2014
|
+
field,
|
|
2256
2015
|
links: resource.links,
|
|
2257
2016
|
meta: resource.meta,
|
|
2258
2017
|
options,
|
|
@@ -2261,16 +2020,32 @@ class LegacySupport {
|
|
|
2261
2020
|
|
|
2262
2021
|
// fetch via link
|
|
2263
2022
|
if (shouldFindViaLink) {
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2023
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2024
|
+
if (!test) {
|
|
2025
|
+
throw new Error(`Expected collection to be an array`);
|
|
2026
|
+
}
|
|
2027
|
+
})(!identifiers || Array.isArray(identifiers)) : {};
|
|
2028
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2029
|
+
if (!test) {
|
|
2030
|
+
throw new Error(`Expected stable identifiers`);
|
|
2031
|
+
}
|
|
2032
|
+
})(!identifiers || identifiers.every(isStableIdentifier)) : {};
|
|
2033
|
+
const req = field.options.linksMode ? {
|
|
2034
|
+
url: getRelatedLink(resource),
|
|
2035
|
+
op: 'findHasMany',
|
|
2036
|
+
method: 'GET',
|
|
2037
|
+
records: identifiers || [],
|
|
2038
|
+
data: request,
|
|
2039
|
+
[EnableHydration]: false
|
|
2040
|
+
} : {
|
|
2267
2041
|
op: 'findHasMany',
|
|
2268
2042
|
records: identifiers || [],
|
|
2269
2043
|
data: request,
|
|
2270
2044
|
cacheOptions: {
|
|
2271
2045
|
[Symbol.for('wd:skip-cache')]: true
|
|
2272
2046
|
}
|
|
2273
|
-
}
|
|
2047
|
+
};
|
|
2048
|
+
return this.store.request(req);
|
|
2274
2049
|
}
|
|
2275
2050
|
const preferLocalCache = hasReceivedData && !isEmpty;
|
|
2276
2051
|
const hasLocalPartialData = hasDematerializedInverse || isEmpty && Array.isArray(identifiers) && identifiers.length > 0;
|
|
@@ -2280,8 +2055,16 @@ class LegacySupport {
|
|
|
2280
2055
|
}
|
|
2281
2056
|
const hasData = hasReceivedData && !isEmpty;
|
|
2282
2057
|
if (attemptLocalCache || hasData || hasLocalPartialData) {
|
|
2283
|
-
|
|
2284
|
-
|
|
2058
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2059
|
+
if (!test) {
|
|
2060
|
+
throw new Error(`Expected collection to be an array`);
|
|
2061
|
+
}
|
|
2062
|
+
})(Array.isArray(identifiers)) : {};
|
|
2063
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2064
|
+
if (!test) {
|
|
2065
|
+
throw new Error(`Expected stable identifiers`);
|
|
2066
|
+
}
|
|
2067
|
+
})(identifiers.every(isStableIdentifier)) : {};
|
|
2285
2068
|
options.reload = options.reload || !attemptLocalCache || undefined;
|
|
2286
2069
|
return this.store.request({
|
|
2287
2070
|
op: 'findHasMany',
|
|
@@ -2297,7 +2080,11 @@ class LegacySupport {
|
|
|
2297
2080
|
// TODO if the relationshipIsStale, should we hit the adapter anyway?
|
|
2298
2081
|
return;
|
|
2299
2082
|
}
|
|
2300
|
-
|
|
2083
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2084
|
+
{
|
|
2085
|
+
throw new Error(`hasMany only works with the @ember-data/json-api package`);
|
|
2086
|
+
}
|
|
2087
|
+
})() : {};
|
|
2301
2088
|
}
|
|
2302
2089
|
_findBelongsToByJsonApiResource(resource, parentIdentifier, relationship, options = {}) {
|
|
2303
2090
|
if (!resource) {
|
|
@@ -2312,7 +2099,11 @@ class LegacySupport {
|
|
|
2312
2099
|
return this._pending[key];
|
|
2313
2100
|
}
|
|
2314
2101
|
const identifier = resource.data ? resource.data : null;
|
|
2315
|
-
|
|
2102
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2103
|
+
if (!test) {
|
|
2104
|
+
throw new Error(`Expected a stable identifier`);
|
|
2105
|
+
}
|
|
2106
|
+
})(!identifier || isStableIdentifier(identifier)) : {};
|
|
2316
2107
|
const {
|
|
2317
2108
|
isStale,
|
|
2318
2109
|
hasDematerializedInverse,
|
|
@@ -2322,11 +2113,15 @@ class LegacySupport {
|
|
|
2322
2113
|
} = relationship.state;
|
|
2323
2114
|
const allInverseRecordsAreLoaded = areAllInverseRecordsLoaded(this.store, resource);
|
|
2324
2115
|
const shouldFindViaLink = resource.links?.related && (shouldForceReload || hasDematerializedInverse || isStale || !allInverseRecordsAreLoaded && !isEmpty);
|
|
2325
|
-
const
|
|
2326
|
-
|
|
2116
|
+
const field = this.store.schema.fields(this.identifier).get(relationship.definition.key);
|
|
2117
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2118
|
+
if (!test) {
|
|
2119
|
+
throw new Error(`Attempted to access a belongsTo relationship but no definition exists for it`);
|
|
2120
|
+
}
|
|
2121
|
+
})(field && field.kind === 'belongsTo') : {};
|
|
2327
2122
|
const request = {
|
|
2328
2123
|
useLink: shouldFindViaLink,
|
|
2329
|
-
field
|
|
2124
|
+
field,
|
|
2330
2125
|
links: resource.links,
|
|
2331
2126
|
meta: resource.meta,
|
|
2332
2127
|
options,
|
|
@@ -2335,15 +2130,23 @@ class LegacySupport {
|
|
|
2335
2130
|
|
|
2336
2131
|
// fetch via link
|
|
2337
2132
|
if (shouldFindViaLink) {
|
|
2338
|
-
const
|
|
2133
|
+
const req = field.options.linksMode ? {
|
|
2134
|
+
url: getRelatedLink(resource),
|
|
2135
|
+
op: 'findBelongsTo',
|
|
2136
|
+
method: 'GET',
|
|
2137
|
+
records: identifier ? [identifier] : [],
|
|
2138
|
+
data: request,
|
|
2139
|
+
[EnableHydration]: false
|
|
2140
|
+
} : {
|
|
2339
2141
|
op: 'findBelongsTo',
|
|
2340
2142
|
records: identifier ? [identifier] : [],
|
|
2341
2143
|
data: request,
|
|
2342
2144
|
cacheOptions: {
|
|
2343
2145
|
[Symbol.for('wd:skip-cache')]: true
|
|
2344
2146
|
}
|
|
2345
|
-
}
|
|
2346
|
-
|
|
2147
|
+
};
|
|
2148
|
+
const future = this.store.request(req);
|
|
2149
|
+
this._pending[key] = future.then(doc => field.options.linksMode ? doc.content.data : doc.content).finally(() => {
|
|
2347
2150
|
this._pending[key] = undefined;
|
|
2348
2151
|
});
|
|
2349
2152
|
return this._pending[key];
|
|
@@ -2367,7 +2170,11 @@ class LegacySupport {
|
|
|
2367
2170
|
|
|
2368
2171
|
// we may need to fetch
|
|
2369
2172
|
if (identifier) {
|
|
2370
|
-
|
|
2173
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2174
|
+
if (!test) {
|
|
2175
|
+
throw new Error(`Cannot fetch belongs-to relationship with no information`);
|
|
2176
|
+
}
|
|
2177
|
+
})(identifier) : {};
|
|
2371
2178
|
options.reload = options.reload || !attemptLocalCache || undefined;
|
|
2372
2179
|
this._pending[key] = this.store.request({
|
|
2373
2180
|
op: 'findBelongsTo',
|
|
@@ -2409,6 +2216,15 @@ class LegacySupport {
|
|
|
2409
2216
|
this.isDestroyed = true;
|
|
2410
2217
|
}
|
|
2411
2218
|
}
|
|
2219
|
+
function getRelatedLink(resource) {
|
|
2220
|
+
const related = resource.links?.related;
|
|
2221
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2222
|
+
if (!test) {
|
|
2223
|
+
throw new Error(`Expected a related link`);
|
|
2224
|
+
}
|
|
2225
|
+
})(related) : {};
|
|
2226
|
+
return typeof related === 'object' ? related.href : related;
|
|
2227
|
+
}
|
|
2412
2228
|
function handleCompletedRelationshipRequest(recordExt, key, relationship, value, error) {
|
|
2413
2229
|
delete recordExt._relationshipPromisesCache[key];
|
|
2414
2230
|
relationship.state.shouldForceReload = false;
|
|
@@ -2455,7 +2271,11 @@ function extractIdentifierFromRecord(record) {
|
|
|
2455
2271
|
}
|
|
2456
2272
|
function anyUnloaded(store, relationship) {
|
|
2457
2273
|
const graph = store._graph;
|
|
2458
|
-
|
|
2274
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2275
|
+
if (!test) {
|
|
2276
|
+
throw new Error(`Expected a Graph instance to be available`);
|
|
2277
|
+
}
|
|
2278
|
+
})(graph) : {};
|
|
2459
2279
|
const relationshipData = graph.getData(relationship.identifier, relationship.definition.key);
|
|
2460
2280
|
const state = relationshipData.data;
|
|
2461
2281
|
const cache = store._instanceCache;
|
|
@@ -2469,7 +2289,11 @@ function areAllInverseRecordsLoaded(store, resource) {
|
|
|
2469
2289
|
const instanceCache = store._instanceCache;
|
|
2470
2290
|
const identifiers = resource.data;
|
|
2471
2291
|
if (Array.isArray(identifiers)) {
|
|
2472
|
-
|
|
2292
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2293
|
+
if (!test) {
|
|
2294
|
+
throw new Error(`Expected stable identifiers`);
|
|
2295
|
+
}
|
|
2296
|
+
})(identifiers.every(isStableIdentifier)) : {};
|
|
2473
2297
|
// treat as collection
|
|
2474
2298
|
// check for unloaded records
|
|
2475
2299
|
return identifiers.every(identifier => instanceCache.recordIsLoaded(identifier));
|
|
@@ -2477,26 +2301,16 @@ function areAllInverseRecordsLoaded(store, resource) {
|
|
|
2477
2301
|
|
|
2478
2302
|
// treat as single resource
|
|
2479
2303
|
if (!identifiers) return true;
|
|
2480
|
-
|
|
2304
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2305
|
+
if (!test) {
|
|
2306
|
+
throw new Error(`Expected stable identifiers`);
|
|
2307
|
+
}
|
|
2308
|
+
})(isStableIdentifier(identifiers)) : {};
|
|
2481
2309
|
return instanceCache.recordIsLoaded(identifiers);
|
|
2482
2310
|
}
|
|
2483
2311
|
function isBelongsTo(relationship) {
|
|
2484
2312
|
return relationship.definition.kind === 'belongsTo';
|
|
2485
2313
|
}
|
|
2486
|
-
function _initializerDefineProperty(target, property, descriptor, context) {
|
|
2487
|
-
if (!descriptor) return;
|
|
2488
|
-
Object.defineProperty(target, property, {
|
|
2489
|
-
enumerable: descriptor.enumerable,
|
|
2490
|
-
configurable: descriptor.configurable,
|
|
2491
|
-
writable: descriptor.writable,
|
|
2492
|
-
value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
|
|
2493
|
-
});
|
|
2494
|
-
}
|
|
2495
|
-
var _dec, _dec2, _dec3, _dec4, _class$2, _descriptor, _descriptor2;
|
|
2496
|
-
|
|
2497
|
-
/**
|
|
2498
|
-
@module @ember-data/model
|
|
2499
|
-
*/
|
|
2500
2314
|
|
|
2501
2315
|
// we force the type here to our own construct because mixin and extend patterns
|
|
2502
2316
|
// lose generic signatures. We also do this because we need to Omit `clear` from
|
|
@@ -2578,40 +2392,7 @@ const ArrayProxyWithCustomOverrides = ArrayProxy;
|
|
|
2578
2392
|
@public
|
|
2579
2393
|
@extends Ember.ArrayProxy
|
|
2580
2394
|
*/
|
|
2581
|
-
|
|
2582
|
-
constructor(...args) {
|
|
2583
|
-
super(...args);
|
|
2584
|
-
/**
|
|
2585
|
-
An array containing all of the error messages for this
|
|
2586
|
-
record. This is useful for displaying all errors to the user.
|
|
2587
|
-
```handlebars
|
|
2588
|
-
{{#each @model.errors.messages as |message|}}
|
|
2589
|
-
<div class="error">
|
|
2590
|
-
{{message}}
|
|
2591
|
-
</div>
|
|
2592
|
-
{{/each}}
|
|
2593
|
-
```
|
|
2594
|
-
@property messages
|
|
2595
|
-
@public
|
|
2596
|
-
@type {Array}
|
|
2597
|
-
*/
|
|
2598
|
-
_initializerDefineProperty(this, "messages", _descriptor, this);
|
|
2599
|
-
/**
|
|
2600
|
-
Total number of errors.
|
|
2601
|
-
@property length
|
|
2602
|
-
@type {Number}
|
|
2603
|
-
@public
|
|
2604
|
-
@readOnly
|
|
2605
|
-
*/
|
|
2606
|
-
/**
|
|
2607
|
-
`true` if we have no errors.
|
|
2608
|
-
@property isEmpty
|
|
2609
|
-
@type {Boolean}
|
|
2610
|
-
@public
|
|
2611
|
-
@readOnly
|
|
2612
|
-
*/
|
|
2613
|
-
_initializerDefineProperty(this, "isEmpty", _descriptor2, this);
|
|
2614
|
-
}
|
|
2395
|
+
class Errors extends ArrayProxyWithCustomOverrides {
|
|
2615
2396
|
/**
|
|
2616
2397
|
@property errorsByAttributeName
|
|
2617
2398
|
@type {MapWithDefault}
|
|
@@ -2638,6 +2419,9 @@ let Errors = (_dec = computed(), _dec2 = mapBy('content', 'message'), _dec3 = co
|
|
|
2638
2419
|
@param {String} attribute
|
|
2639
2420
|
@return {Array}
|
|
2640
2421
|
*/
|
|
2422
|
+
static {
|
|
2423
|
+
decorateMethodV2(this.prototype, "errorsByAttributeName", [computed()]);
|
|
2424
|
+
}
|
|
2641
2425
|
errorsFor(attribute) {
|
|
2642
2426
|
const map = this.errorsByAttributeName;
|
|
2643
2427
|
let errors = map.get(attribute);
|
|
@@ -2653,6 +2437,25 @@ let Errors = (_dec = computed(), _dec2 = mapBy('content', 'message'), _dec3 = co
|
|
|
2653
2437
|
get(errors, '[]');
|
|
2654
2438
|
return errors;
|
|
2655
2439
|
}
|
|
2440
|
+
|
|
2441
|
+
/**
|
|
2442
|
+
An array containing all of the error messages for this
|
|
2443
|
+
record. This is useful for displaying all errors to the user.
|
|
2444
|
+
```handlebars
|
|
2445
|
+
{{#each @model.errors.messages as |message|}}
|
|
2446
|
+
<div class="error">
|
|
2447
|
+
{{message}}
|
|
2448
|
+
</div>
|
|
2449
|
+
{{/each}}
|
|
2450
|
+
```
|
|
2451
|
+
@property messages
|
|
2452
|
+
@public
|
|
2453
|
+
@type {Array}
|
|
2454
|
+
*/
|
|
2455
|
+
static {
|
|
2456
|
+
decorateFieldV2(this.prototype, "messages", [mapBy('content', 'message')]);
|
|
2457
|
+
}
|
|
2458
|
+
#messages = (initializeDeferredDecorator(this, "messages"), void 0);
|
|
2656
2459
|
/**
|
|
2657
2460
|
@property content
|
|
2658
2461
|
@type {Array}
|
|
@@ -2666,6 +2469,9 @@ let Errors = (_dec = computed(), _dec2 = mapBy('content', 'message'), _dec3 = co
|
|
|
2666
2469
|
@method unknownProperty
|
|
2667
2470
|
@private
|
|
2668
2471
|
*/
|
|
2472
|
+
static {
|
|
2473
|
+
decorateMethodV2(this.prototype, "content", [computed()]);
|
|
2474
|
+
}
|
|
2669
2475
|
unknownProperty(attribute) {
|
|
2670
2476
|
const errors = this.errorsFor(attribute);
|
|
2671
2477
|
if (errors.length === 0) {
|
|
@@ -2673,6 +2479,26 @@ let Errors = (_dec = computed(), _dec2 = mapBy('content', 'message'), _dec3 = co
|
|
|
2673
2479
|
}
|
|
2674
2480
|
return errors;
|
|
2675
2481
|
}
|
|
2482
|
+
|
|
2483
|
+
/**
|
|
2484
|
+
Total number of errors.
|
|
2485
|
+
@property length
|
|
2486
|
+
@type {Number}
|
|
2487
|
+
@public
|
|
2488
|
+
@readOnly
|
|
2489
|
+
*/
|
|
2490
|
+
|
|
2491
|
+
/**
|
|
2492
|
+
`true` if we have no errors.
|
|
2493
|
+
@property isEmpty
|
|
2494
|
+
@type {Boolean}
|
|
2495
|
+
@public
|
|
2496
|
+
@readOnly
|
|
2497
|
+
*/
|
|
2498
|
+
static {
|
|
2499
|
+
decorateFieldV2(this.prototype, "isEmpty", [not('length')]);
|
|
2500
|
+
}
|
|
2501
|
+
#isEmpty = (initializeDeferredDecorator(this, "isEmpty"), void 0);
|
|
2676
2502
|
/**
|
|
2677
2503
|
Manually adds errors to the record. This will trigger the `becameInvalid` event/ lifecycle method on
|
|
2678
2504
|
the record and transition the record into an `invalid` state.
|
|
@@ -2831,9 +2657,7 @@ let Errors = (_dec = computed(), _dec2 = mapBy('content', 'message'), _dec3 = co
|
|
|
2831
2657
|
/**
|
|
2832
2658
|
Checks if there are error messages for the given attribute.
|
|
2833
2659
|
```app/controllers/user/edit.js
|
|
2834
|
-
|
|
2835
|
-
import { action } from '@ember/object';
|
|
2836
|
-
export default class UserEditController extends Controller {
|
|
2660
|
+
export default class UserEditController extends Controller {
|
|
2837
2661
|
@action
|
|
2838
2662
|
save(user) {
|
|
2839
2663
|
if (user.errors.has('email')) {
|
|
@@ -2851,17 +2675,7 @@ let Errors = (_dec = computed(), _dec2 = mapBy('content', 'message'), _dec3 = co
|
|
|
2851
2675
|
has(attribute) {
|
|
2852
2676
|
return this.errorsFor(attribute).length > 0;
|
|
2853
2677
|
}
|
|
2854
|
-
}
|
|
2855
|
-
configurable: true,
|
|
2856
|
-
enumerable: true,
|
|
2857
|
-
writable: true,
|
|
2858
|
-
initializer: null
|
|
2859
|
-
}), _applyDecoratedDescriptor(_class$2.prototype, "content", [_dec3], Object.getOwnPropertyDescriptor(_class$2.prototype, "content"), _class$2.prototype), _descriptor2 = _applyDecoratedDescriptor(_class$2.prototype, "isEmpty", [_dec4], {
|
|
2860
|
-
configurable: true,
|
|
2861
|
-
enumerable: true,
|
|
2862
|
-
writable: true,
|
|
2863
|
-
initializer: null
|
|
2864
|
-
})), _class$2));
|
|
2678
|
+
}
|
|
2865
2679
|
function rollbackAttributes() {
|
|
2866
2680
|
const {
|
|
2867
2681
|
currentState
|
|
@@ -2894,7 +2708,11 @@ function reload(options = {}) {
|
|
|
2894
2708
|
options.isReloading = true;
|
|
2895
2709
|
options.reload = true;
|
|
2896
2710
|
const identifier = recordIdentifierFor$1(this);
|
|
2897
|
-
|
|
2711
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2712
|
+
if (!test) {
|
|
2713
|
+
throw new Error(`You cannot reload a record without an ID`);
|
|
2714
|
+
}
|
|
2715
|
+
})(identifier.id) : {};
|
|
2898
2716
|
this.isReloading = true;
|
|
2899
2717
|
const promise = this[RecordStore].request({
|
|
2900
2718
|
op: 'findRecord',
|
|
@@ -2953,29 +2771,40 @@ function createSnapshot() {
|
|
|
2953
2771
|
const FetchManager = importSync('@ember-data/legacy-compat/-private').FetchManager;
|
|
2954
2772
|
store._fetchManager = new FetchManager(store);
|
|
2955
2773
|
}
|
|
2774
|
+
|
|
2775
|
+
// @ts-expect-error Typescript isn't able to curry narrowed args that are divorced from each other.
|
|
2956
2776
|
return store._fetchManager.createSnapshot(recordIdentifierFor$1(this));
|
|
2957
2777
|
}
|
|
2958
2778
|
function notifyChanges(identifier, value, key, record, store) {
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2779
|
+
switch (value) {
|
|
2780
|
+
case 'added':
|
|
2781
|
+
case 'attributes':
|
|
2782
|
+
if (key) {
|
|
2783
|
+
notifyAttribute(store, identifier, key, record);
|
|
2784
|
+
} else {
|
|
2785
|
+
record.eachAttribute(name => {
|
|
2786
|
+
notifyAttribute(store, identifier, name, record);
|
|
2787
|
+
});
|
|
2788
|
+
}
|
|
2789
|
+
break;
|
|
2790
|
+
case 'relationships':
|
|
2791
|
+
if (key) {
|
|
2792
|
+
const meta = record.constructor.relationshipsByName.get(key);
|
|
2793
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2794
|
+
if (!test) {
|
|
2795
|
+
throw new Error(`Expected to find a relationship for ${key} on ${identifier.type}`);
|
|
2796
|
+
}
|
|
2797
|
+
})(meta) : {};
|
|
2798
|
+
notifyRelationship(identifier, key, record, meta);
|
|
2799
|
+
} else {
|
|
2800
|
+
record.eachRelationship((name, meta) => {
|
|
2801
|
+
notifyRelationship(identifier, name, record, meta);
|
|
2802
|
+
});
|
|
2803
|
+
}
|
|
2804
|
+
break;
|
|
2805
|
+
case 'identity':
|
|
2806
|
+
record.notifyPropertyChange('id');
|
|
2807
|
+
break;
|
|
2979
2808
|
}
|
|
2980
2809
|
}
|
|
2981
2810
|
function notifyRelationship(identifier, key, record, meta) {
|
|
@@ -2996,8 +2825,16 @@ function notifyRelationship(identifier, key, record, meta) {
|
|
|
2996
2825
|
//We need to notifyPropertyChange in the adding case because we need to make sure
|
|
2997
2826
|
//we fetch the newly added record in case it is unloaded
|
|
2998
2827
|
//TODO(Igor): Consider whether we could do this only if the record state is unloaded
|
|
2999
|
-
|
|
3000
|
-
|
|
2828
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2829
|
+
if (!test) {
|
|
2830
|
+
throw new Error(`Expected options to exist on relationship meta`);
|
|
2831
|
+
}
|
|
2832
|
+
})(meta.options) : {};
|
|
2833
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2834
|
+
if (!test) {
|
|
2835
|
+
throw new Error(`Expected async to exist on relationship meta options`);
|
|
2836
|
+
}
|
|
2837
|
+
})('async' in meta.options) : {};
|
|
3001
2838
|
if (meta.options.async) {
|
|
3002
2839
|
record.notifyPropertyChange(key);
|
|
3003
2840
|
}
|
|
@@ -3011,7 +2848,6 @@ function notifyAttribute(store, identifier, key, record) {
|
|
|
3011
2848
|
record.notifyPropertyChange(key);
|
|
3012
2849
|
}
|
|
3013
2850
|
}
|
|
3014
|
-
var _class$1;
|
|
3015
2851
|
const SOURCE_POINTER_REGEXP = /^\/?data\/(attributes|relationships)\/(.*)/;
|
|
3016
2852
|
const SOURCE_POINTER_PRIMARY_REGEXP = /^\/?data/;
|
|
3017
2853
|
const PRIMARY_ATTRIBUTE_KEY = 'base';
|
|
@@ -3019,44 +2855,6 @@ function isInvalidError(error) {
|
|
|
3019
2855
|
return !!error && error instanceof Error && 'isAdapterError' in error && error.isAdapterError === true && 'code' in error && error.code === 'InvalidError';
|
|
3020
2856
|
}
|
|
3021
2857
|
|
|
3022
|
-
/**
|
|
3023
|
-
* A decorator that caches a getter while
|
|
3024
|
-
* providing the ability to bust that cache
|
|
3025
|
-
* when we so choose in a way that notifies
|
|
3026
|
-
* tracking systems.
|
|
3027
|
-
*
|
|
3028
|
-
* @internal
|
|
3029
|
-
*/
|
|
3030
|
-
function tagged(_target, key, desc) {
|
|
3031
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
3032
|
-
const getter = desc.get;
|
|
3033
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
3034
|
-
const setter = desc.set;
|
|
3035
|
-
desc.get = function () {
|
|
3036
|
-
const signal = getSignal(this, key, true);
|
|
3037
|
-
subscribe(signal);
|
|
3038
|
-
if (signal.shouldReset) {
|
|
3039
|
-
signal.shouldReset = false;
|
|
3040
|
-
signal.lastValue = getter.call(this);
|
|
3041
|
-
}
|
|
3042
|
-
return signal.lastValue;
|
|
3043
|
-
};
|
|
3044
|
-
desc.set = function (v) {
|
|
3045
|
-
getSignal(this, key, true); // ensure signal is setup in case we want to use it.
|
|
3046
|
-
// probably notify here but not yet.
|
|
3047
|
-
setter.call(this, v);
|
|
3048
|
-
};
|
|
3049
|
-
compat(desc);
|
|
3050
|
-
return desc;
|
|
3051
|
-
}
|
|
3052
|
-
function notifySignal(obj, key) {
|
|
3053
|
-
const signal = peekSignal(obj, key);
|
|
3054
|
-
if (signal) {
|
|
3055
|
-
signal.shouldReset = true;
|
|
3056
|
-
addToTransaction(signal);
|
|
3057
|
-
}
|
|
3058
|
-
}
|
|
3059
|
-
|
|
3060
2858
|
/**
|
|
3061
2859
|
Historically EmberData managed a state machine
|
|
3062
2860
|
for each record, the localState for which
|
|
@@ -3096,7 +2894,7 @@ root
|
|
|
3096
2894
|
|
|
3097
2895
|
@internal
|
|
3098
2896
|
*/
|
|
3099
|
-
|
|
2897
|
+
class RecordState {
|
|
3100
2898
|
constructor(record) {
|
|
3101
2899
|
const store = storeFor$1(record);
|
|
3102
2900
|
const identity = recordIdentifierFor(record);
|
|
@@ -3193,7 +2991,11 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3193
2991
|
notifySignal(this, key);
|
|
3194
2992
|
}
|
|
3195
2993
|
updateInvalidErrors(errors) {
|
|
3196
|
-
|
|
2994
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
2995
|
+
if (!test) {
|
|
2996
|
+
throw new Error(`Expected the Cache instance for ${this.identifier.lid} to implement getErrors(identifier)`);
|
|
2997
|
+
}
|
|
2998
|
+
})(typeof this.cache.getErrors === 'function') : {};
|
|
3197
2999
|
const jsonApiErrors = this.cache.getErrors(this.identifier);
|
|
3198
3000
|
errors.clear();
|
|
3199
3001
|
for (let i = 0; i < jsonApiErrors.length; i++) {
|
|
@@ -3208,7 +3010,11 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3208
3010
|
}
|
|
3209
3011
|
if (key) {
|
|
3210
3012
|
const errMsg = error.detail || error.title;
|
|
3211
|
-
|
|
3013
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3014
|
+
if (!test) {
|
|
3015
|
+
throw new Error(`Expected field error to have a detail or title to use as the message`);
|
|
3016
|
+
}
|
|
3017
|
+
})(errMsg) : {};
|
|
3212
3018
|
errors.add(key, errMsg);
|
|
3213
3019
|
}
|
|
3214
3020
|
}
|
|
@@ -3224,16 +3030,26 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3224
3030
|
get isLoading() {
|
|
3225
3031
|
return !this.isLoaded && this.pendingCount > 0 && this.fulfilledCount === 0;
|
|
3226
3032
|
}
|
|
3033
|
+
static {
|
|
3034
|
+
decorateMethodV2(this.prototype, "isLoading", [subscribed]);
|
|
3035
|
+
}
|
|
3227
3036
|
get isLoaded() {
|
|
3228
3037
|
if (this.isNew) {
|
|
3229
3038
|
return true;
|
|
3230
3039
|
}
|
|
3231
3040
|
return this.fulfilledCount > 0 || !this.isEmpty;
|
|
3232
3041
|
}
|
|
3042
|
+
static {
|
|
3043
|
+
decorateMethodV2(this.prototype, "isLoaded", [subscribed]);
|
|
3044
|
+
}
|
|
3233
3045
|
get isSaved() {
|
|
3234
3046
|
const rd = this.cache;
|
|
3235
3047
|
if (this.isDeleted) {
|
|
3236
|
-
|
|
3048
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3049
|
+
if (!test) {
|
|
3050
|
+
throw new Error(`Expected Cache to implement isDeletionCommitted()`);
|
|
3051
|
+
}
|
|
3052
|
+
})(typeof rd.isDeletionCommitted === 'function') : {};
|
|
3237
3053
|
return rd.isDeletionCommitted(this.identifier);
|
|
3238
3054
|
}
|
|
3239
3055
|
if (this.isNew || this.isEmpty || !this.isValid || this.isDirty || this.isLoading) {
|
|
@@ -3241,26 +3057,53 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3241
3057
|
}
|
|
3242
3058
|
return true;
|
|
3243
3059
|
}
|
|
3060
|
+
static {
|
|
3061
|
+
decorateMethodV2(this.prototype, "isSaved", [subscribed]);
|
|
3062
|
+
}
|
|
3244
3063
|
get isEmpty() {
|
|
3245
3064
|
const rd = this.cache;
|
|
3246
3065
|
// TODO this is not actually an RFC'd concept. Determine the
|
|
3247
3066
|
// correct heuristic to replace this with.
|
|
3248
|
-
|
|
3067
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3068
|
+
if (!test) {
|
|
3069
|
+
throw new Error(`Expected Cache to implement isEmpty()`);
|
|
3070
|
+
}
|
|
3071
|
+
})(typeof rd.isEmpty === 'function') : {};
|
|
3249
3072
|
return !this.isNew && rd.isEmpty(this.identifier);
|
|
3250
3073
|
}
|
|
3074
|
+
static {
|
|
3075
|
+
decorateMethodV2(this.prototype, "isEmpty", [subscribed]);
|
|
3076
|
+
}
|
|
3251
3077
|
get isNew() {
|
|
3252
3078
|
const rd = this.cache;
|
|
3253
|
-
|
|
3079
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3080
|
+
if (!test) {
|
|
3081
|
+
throw new Error(`Expected Cache to implement isNew()`);
|
|
3082
|
+
}
|
|
3083
|
+
})(typeof rd.isNew === 'function') : {};
|
|
3254
3084
|
return rd.isNew(this.identifier);
|
|
3255
3085
|
}
|
|
3086
|
+
static {
|
|
3087
|
+
decorateMethodV2(this.prototype, "isNew", [subscribed]);
|
|
3088
|
+
}
|
|
3256
3089
|
get isDeleted() {
|
|
3257
3090
|
const rd = this.cache;
|
|
3258
|
-
|
|
3091
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3092
|
+
if (!test) {
|
|
3093
|
+
throw new Error(`Expected Cache to implement isDeleted()`);
|
|
3094
|
+
}
|
|
3095
|
+
})(typeof rd.isDeleted === 'function') : {};
|
|
3259
3096
|
return rd.isDeleted(this.identifier);
|
|
3260
3097
|
}
|
|
3098
|
+
static {
|
|
3099
|
+
decorateMethodV2(this.prototype, "isDeleted", [subscribed]);
|
|
3100
|
+
}
|
|
3261
3101
|
get isValid() {
|
|
3262
3102
|
return this.record.errors.length === 0;
|
|
3263
3103
|
}
|
|
3104
|
+
static {
|
|
3105
|
+
decorateMethodV2(this.prototype, "isValid", [subscribed]);
|
|
3106
|
+
}
|
|
3264
3107
|
get isDirty() {
|
|
3265
3108
|
const rd = this.cache;
|
|
3266
3109
|
if (this.isEmpty || rd.isDeletionCommitted(this.identifier) || this.isDeleted && this.isNew) {
|
|
@@ -3268,6 +3111,9 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3268
3111
|
}
|
|
3269
3112
|
return this.isDeleted || this.isNew || rd.hasChangedAttrs(this.identifier);
|
|
3270
3113
|
}
|
|
3114
|
+
static {
|
|
3115
|
+
decorateMethodV2(this.prototype, "isDirty", [subscribed]);
|
|
3116
|
+
}
|
|
3271
3117
|
get isError() {
|
|
3272
3118
|
const errorReq = this._errorRequests[this._errorRequests.length - 1];
|
|
3273
3119
|
if (!errorReq) {
|
|
@@ -3276,6 +3122,9 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3276
3122
|
return true;
|
|
3277
3123
|
}
|
|
3278
3124
|
}
|
|
3125
|
+
static {
|
|
3126
|
+
decorateMethodV2(this.prototype, "isError", [subscribed]);
|
|
3127
|
+
}
|
|
3279
3128
|
get adapterError() {
|
|
3280
3129
|
const request = this._lastError;
|
|
3281
3130
|
if (!request) {
|
|
@@ -3283,9 +3132,15 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3283
3132
|
}
|
|
3284
3133
|
return request.state === 'rejected' && request.response.data;
|
|
3285
3134
|
}
|
|
3135
|
+
static {
|
|
3136
|
+
decorateMethodV2(this.prototype, "adapterError", [subscribed]);
|
|
3137
|
+
}
|
|
3286
3138
|
get isPreloaded() {
|
|
3287
3139
|
return !this.isEmpty && this.isLoading;
|
|
3288
3140
|
}
|
|
3141
|
+
static {
|
|
3142
|
+
decorateMethodV2(this.prototype, "isPreloaded", [cached]);
|
|
3143
|
+
}
|
|
3289
3144
|
get stateName() {
|
|
3290
3145
|
// we might be empty while loading so check this first
|
|
3291
3146
|
if (this.isLoading) {
|
|
@@ -3330,6 +3185,9 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3330
3185
|
return 'root.loaded.saved';
|
|
3331
3186
|
}
|
|
3332
3187
|
}
|
|
3188
|
+
static {
|
|
3189
|
+
decorateMethodV2(this.prototype, "stateName", [cached]);
|
|
3190
|
+
}
|
|
3333
3191
|
get dirtyType() {
|
|
3334
3192
|
// we might be empty while loading so check this first
|
|
3335
3193
|
if (this.isLoading || this.isEmpty) {
|
|
@@ -3352,38 +3210,20 @@ let RecordState = (_class$1 = class RecordState {
|
|
|
3352
3210
|
return '';
|
|
3353
3211
|
}
|
|
3354
3212
|
}
|
|
3355
|
-
|
|
3213
|
+
static {
|
|
3214
|
+
decorateMethodV2(this.prototype, "dirtyType", [cached]);
|
|
3215
|
+
}
|
|
3216
|
+
}
|
|
3356
3217
|
defineSignal(RecordState.prototype, 'isSaving', false);
|
|
3357
3218
|
function notifyErrorsStateChanged(state) {
|
|
3358
3219
|
state.notify('isValid');
|
|
3359
3220
|
state.notify('isError');
|
|
3360
3221
|
state.notify('adapterError');
|
|
3361
3222
|
}
|
|
3362
|
-
var _class, _class2;
|
|
3363
|
-
function findPossibleInverses(type, inverseType, name, relationshipsSoFar) {
|
|
3364
|
-
const possibleRelationships = relationshipsSoFar || [];
|
|
3365
|
-
const relationshipMap = inverseType.relationships;
|
|
3366
|
-
if (!relationshipMap) {
|
|
3367
|
-
return possibleRelationships;
|
|
3368
|
-
}
|
|
3369
|
-
const relationshipsForType = relationshipMap.get(type.modelName);
|
|
3370
|
-
const relationships = Array.isArray(relationshipsForType) ? relationshipsForType.filter(relationship => {
|
|
3371
|
-
const optionsForRelationship = relationship.options;
|
|
3372
|
-
if (!optionsForRelationship.inverse && optionsForRelationship.inverse !== null) {
|
|
3373
|
-
return true;
|
|
3374
|
-
}
|
|
3375
|
-
return name === optionsForRelationship.inverse;
|
|
3376
|
-
}) : null;
|
|
3377
|
-
if (relationships) {
|
|
3378
|
-
possibleRelationships.push.apply(possibleRelationships, relationships);
|
|
3379
|
-
}
|
|
3380
3223
|
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
}
|
|
3385
|
-
return possibleRelationships;
|
|
3386
|
-
}
|
|
3224
|
+
/**
|
|
3225
|
+
@module @ember-data/model
|
|
3226
|
+
*/
|
|
3387
3227
|
|
|
3388
3228
|
/*
|
|
3389
3229
|
* This decorator allows us to lazily compute
|
|
@@ -3392,6 +3232,7 @@ function findPossibleInverses(type, inverseType, name, relationshipsSoFar) {
|
|
|
3392
3232
|
*/
|
|
3393
3233
|
function computeOnce(target, propertyName, desc) {
|
|
3394
3234
|
const cache = new WeakMap();
|
|
3235
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
3395
3236
|
const getter = desc.get;
|
|
3396
3237
|
desc.get = function () {
|
|
3397
3238
|
let meta = cache.get(this);
|
|
@@ -3430,14 +3271,13 @@ function computeOnce(target, propertyName, desc) {
|
|
|
3430
3271
|
@public
|
|
3431
3272
|
@extends Ember.EmberObject
|
|
3432
3273
|
*/
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
if (!options._secretInit && !options._createProps) {
|
|
3274
|
+
|
|
3275
|
+
class Model extends EmberObject {
|
|
3276
|
+
// set during create by the store
|
|
3277
|
+
|
|
3278
|
+
init(options) {
|
|
3279
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
3280
|
+
if (!options?._secretInit && !options?._createProps) {
|
|
3441
3281
|
throw new Error('You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.');
|
|
3442
3282
|
}
|
|
3443
3283
|
}
|
|
@@ -3450,13 +3290,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3450
3290
|
this[RecordStore] = store;
|
|
3451
3291
|
const identity = _secretInit.identifier;
|
|
3452
3292
|
_secretInit.cb(this, _secretInit.cache, identity, _secretInit.store);
|
|
3453
|
-
this.___recordState = macroCondition(
|
|
3293
|
+
this.___recordState = macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? new RecordState(this) : null;
|
|
3454
3294
|
this.setProperties(createProps);
|
|
3455
3295
|
const notifications = store.notifications;
|
|
3456
3296
|
this.___private_notifications = notifications.subscribe(identity, (identifier, type, field) => {
|
|
3457
3297
|
notifyChanges(identifier, type, field, this, store);
|
|
3458
3298
|
});
|
|
3459
3299
|
}
|
|
3300
|
+
|
|
3301
|
+
// @ts-expect-error destroy should not return a value, but ember's types force it to
|
|
3460
3302
|
destroy() {
|
|
3461
3303
|
const identifier = recordIdentifierFor$1(this);
|
|
3462
3304
|
this.___recordState?.destroy();
|
|
@@ -3507,6 +3349,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3507
3349
|
@type {Boolean}
|
|
3508
3350
|
@readOnly
|
|
3509
3351
|
*/
|
|
3352
|
+
static {
|
|
3353
|
+
decorateMethodV2(this.prototype, "isEmpty", [compat]);
|
|
3354
|
+
}
|
|
3510
3355
|
get isLoading() {
|
|
3511
3356
|
return this.currentState.isLoading;
|
|
3512
3357
|
}
|
|
@@ -3520,15 +3365,17 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3520
3365
|
```javascript
|
|
3521
3366
|
let record = store.createRecord('model');
|
|
3522
3367
|
record.isLoaded; // true
|
|
3523
|
-
store.findRecord('model', 1)
|
|
3524
|
-
|
|
3525
|
-
});
|
|
3368
|
+
const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
|
|
3369
|
+
model.isLoaded;
|
|
3526
3370
|
```
|
|
3527
3371
|
@property isLoaded
|
|
3528
3372
|
@public
|
|
3529
3373
|
@type {Boolean}
|
|
3530
3374
|
@readOnly
|
|
3531
3375
|
*/
|
|
3376
|
+
static {
|
|
3377
|
+
decorateMethodV2(this.prototype, "isLoading", [compat]);
|
|
3378
|
+
}
|
|
3532
3379
|
get isLoaded() {
|
|
3533
3380
|
return this.currentState.isLoaded;
|
|
3534
3381
|
}
|
|
@@ -3542,11 +3389,10 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3542
3389
|
```javascript
|
|
3543
3390
|
let record = store.createRecord('model');
|
|
3544
3391
|
record.hasDirtyAttributes; // true
|
|
3545
|
-
store.findRecord('model', 1)
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
});
|
|
3392
|
+
const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
|
|
3393
|
+
model.hasDirtyAttributes; // false
|
|
3394
|
+
model.foo = 'some value';
|
|
3395
|
+
model.hasDirtyAttributes; // true
|
|
3550
3396
|
```
|
|
3551
3397
|
@since 1.13.0
|
|
3552
3398
|
@property hasDirtyAttributes
|
|
@@ -3554,6 +3400,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3554
3400
|
@type {Boolean}
|
|
3555
3401
|
@readOnly
|
|
3556
3402
|
*/
|
|
3403
|
+
static {
|
|
3404
|
+
decorateMethodV2(this.prototype, "isLoaded", [compat]);
|
|
3405
|
+
}
|
|
3557
3406
|
get hasDirtyAttributes() {
|
|
3558
3407
|
return this.currentState.isDirty;
|
|
3559
3408
|
}
|
|
@@ -3578,6 +3427,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3578
3427
|
@type {Boolean}
|
|
3579
3428
|
@readOnly
|
|
3580
3429
|
*/
|
|
3430
|
+
static {
|
|
3431
|
+
decorateMethodV2(this.prototype, "hasDirtyAttributes", [compat]);
|
|
3432
|
+
}
|
|
3581
3433
|
get isSaving() {
|
|
3582
3434
|
return this.currentState.isSaving;
|
|
3583
3435
|
}
|
|
@@ -3614,6 +3466,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3614
3466
|
@type {Boolean}
|
|
3615
3467
|
@readOnly
|
|
3616
3468
|
*/
|
|
3469
|
+
static {
|
|
3470
|
+
decorateMethodV2(this.prototype, "isSaving", [compat]);
|
|
3471
|
+
}
|
|
3617
3472
|
get isDeleted() {
|
|
3618
3473
|
return this.currentState.isDeleted;
|
|
3619
3474
|
}
|
|
@@ -3636,6 +3491,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3636
3491
|
@type {Boolean}
|
|
3637
3492
|
@readOnly
|
|
3638
3493
|
*/
|
|
3494
|
+
static {
|
|
3495
|
+
decorateMethodV2(this.prototype, "isDeleted", [compat]);
|
|
3496
|
+
}
|
|
3639
3497
|
get isNew() {
|
|
3640
3498
|
return this.currentState.isNew;
|
|
3641
3499
|
}
|
|
@@ -3649,6 +3507,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3649
3507
|
@type {Boolean}
|
|
3650
3508
|
@readOnly
|
|
3651
3509
|
*/
|
|
3510
|
+
static {
|
|
3511
|
+
decorateMethodV2(this.prototype, "isNew", [compat]);
|
|
3512
|
+
}
|
|
3652
3513
|
get isValid() {
|
|
3653
3514
|
return this.currentState.isValid;
|
|
3654
3515
|
}
|
|
@@ -3670,6 +3531,9 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3670
3531
|
@type {String}
|
|
3671
3532
|
@readOnly
|
|
3672
3533
|
*/
|
|
3534
|
+
static {
|
|
3535
|
+
decorateMethodV2(this.prototype, "isValid", [compat]);
|
|
3536
|
+
}
|
|
3673
3537
|
get dirtyType() {
|
|
3674
3538
|
return this.currentState.dirtyType;
|
|
3675
3539
|
}
|
|
@@ -3691,11 +3555,17 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3691
3555
|
@type {Boolean}
|
|
3692
3556
|
@readOnly
|
|
3693
3557
|
*/
|
|
3558
|
+
static {
|
|
3559
|
+
decorateMethodV2(this.prototype, "dirtyType", [compat]);
|
|
3560
|
+
}
|
|
3694
3561
|
get isError() {
|
|
3695
3562
|
return this.currentState.isError;
|
|
3696
3563
|
}
|
|
3564
|
+
static {
|
|
3565
|
+
decorateMethodV2(this.prototype, "isError", [compat]);
|
|
3566
|
+
}
|
|
3697
3567
|
set isError(v) {
|
|
3698
|
-
if (macroCondition(
|
|
3568
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
3699
3569
|
throw new Error(`isError is not directly settable`);
|
|
3700
3570
|
}
|
|
3701
3571
|
}
|
|
@@ -3723,9 +3593,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3723
3593
|
```javascript
|
|
3724
3594
|
let record = store.createRecord('model');
|
|
3725
3595
|
record.id; // null
|
|
3726
|
-
store.findRecord('model', 1)
|
|
3727
|
-
|
|
3728
|
-
});
|
|
3596
|
+
const { content: { data: model } } = await store.request(findRecord({ type: 'model', id: '1' }));
|
|
3597
|
+
model.id; // '1'
|
|
3729
3598
|
```
|
|
3730
3599
|
@property id
|
|
3731
3600
|
@public
|
|
@@ -3735,20 +3604,27 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3735
3604
|
// this guard exists, because some dev-only deprecation code
|
|
3736
3605
|
// (addListener via validatePropertyInjections) invokes toString before the
|
|
3737
3606
|
// object is real.
|
|
3738
|
-
if (macroCondition(
|
|
3607
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
3739
3608
|
try {
|
|
3740
3609
|
return recordIdentifierFor$1(this).id;
|
|
3741
3610
|
} catch {
|
|
3742
|
-
return
|
|
3611
|
+
return null;
|
|
3743
3612
|
}
|
|
3744
3613
|
}
|
|
3745
3614
|
return recordIdentifierFor$1(this).id;
|
|
3746
3615
|
}
|
|
3616
|
+
static {
|
|
3617
|
+
decorateMethodV2(this.prototype, "id", [subscribed]);
|
|
3618
|
+
}
|
|
3747
3619
|
set id(id) {
|
|
3748
3620
|
const normalizedId = coerceId(id);
|
|
3749
3621
|
const identifier = recordIdentifierFor$1(this);
|
|
3750
3622
|
const didChange = normalizedId !== identifier.id;
|
|
3751
|
-
|
|
3623
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3624
|
+
if (!test) {
|
|
3625
|
+
throw new Error(`Cannot set ${identifier.type} record's id to ${id}, because id is already ${identifier.id}`);
|
|
3626
|
+
}
|
|
3627
|
+
})(!didChange || identifier.id === null) : {};
|
|
3752
3628
|
if (normalizedId !== null && didChange) {
|
|
3753
3629
|
this.store._instanceCache.setRecordId(identifier, normalizedId);
|
|
3754
3630
|
this.store.notifications.notify(identifier, 'identity');
|
|
@@ -3770,13 +3646,16 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3770
3646
|
// when using legacy/classic ember classes. Basically: lazy in prod and eager in dev.
|
|
3771
3647
|
// so we do this to try to steer folks to the nicer "dont user currentState"
|
|
3772
3648
|
// error.
|
|
3773
|
-
if (macroCondition(!
|
|
3649
|
+
if (macroCondition(!getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
3774
3650
|
if (!this.___recordState) {
|
|
3775
3651
|
this.___recordState = new RecordState(this);
|
|
3776
3652
|
}
|
|
3777
3653
|
}
|
|
3778
3654
|
return this.___recordState;
|
|
3779
3655
|
}
|
|
3656
|
+
static {
|
|
3657
|
+
decorateMethodV2(this.prototype, "currentState", [subscribed]);
|
|
3658
|
+
}
|
|
3780
3659
|
set currentState(_v) {
|
|
3781
3660
|
throw new Error('cannot set currentState');
|
|
3782
3661
|
}
|
|
@@ -3846,9 +3725,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3846
3725
|
@public
|
|
3847
3726
|
@type {AdapterError}
|
|
3848
3727
|
*/
|
|
3728
|
+
static {
|
|
3729
|
+
decorateMethodV2(this.prototype, "errors", [computeOnce]);
|
|
3730
|
+
}
|
|
3849
3731
|
get adapterError() {
|
|
3850
3732
|
return this.currentState.adapterError;
|
|
3851
3733
|
}
|
|
3734
|
+
static {
|
|
3735
|
+
decorateMethodV2(this.prototype, "adapterError", [compat]);
|
|
3736
|
+
}
|
|
3852
3737
|
set adapterError(v) {
|
|
3853
3738
|
throw new Error(`adapterError is not directly settable`);
|
|
3854
3739
|
}
|
|
@@ -3865,7 +3750,6 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3865
3750
|
@param {Object} options
|
|
3866
3751
|
@return {Object} an object whose values are primitive JSON values only
|
|
3867
3752
|
*/
|
|
3868
|
-
|
|
3869
3753
|
/*
|
|
3870
3754
|
We hook the default implementation to ensure
|
|
3871
3755
|
our tagged properties are properly notified
|
|
@@ -3874,6 +3758,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
3874
3758
|
to trigger their flush. We wouldn't need to
|
|
3875
3759
|
super in 4.0+ where sync observers are removed.
|
|
3876
3760
|
*/
|
|
3761
|
+
// @ts-expect-error no return is necessary, but Ember's types are forcing it
|
|
3877
3762
|
notifyPropertyChange(prop) {
|
|
3878
3763
|
notifySignal(this, prop);
|
|
3879
3764
|
super.notifyPropertyChange(prop);
|
|
@@ -4061,7 +3946,11 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4061
3946
|
*/
|
|
4062
3947
|
|
|
4063
3948
|
attr() {
|
|
4064
|
-
|
|
3949
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
3950
|
+
{
|
|
3951
|
+
throw new Error('The `attr` method is not available on Model, a Snapshot was probably expected. Are you passing a Model instead of a Snapshot to your serializer?');
|
|
3952
|
+
}
|
|
3953
|
+
})() : {};
|
|
4065
3954
|
}
|
|
4066
3955
|
|
|
4067
3956
|
/**
|
|
@@ -4178,7 +4067,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4178
4067
|
}
|
|
4179
4068
|
```
|
|
4180
4069
|
@method eachRelationship
|
|
4181
|
-
|
|
4070
|
+
@public
|
|
4182
4071
|
@param {Function} callback the callback to invoke
|
|
4183
4072
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
4184
4073
|
*/
|
|
@@ -4194,6 +4083,45 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4194
4083
|
eachAttribute(callback, binding) {
|
|
4195
4084
|
this.constructor.eachAttribute(callback, binding);
|
|
4196
4085
|
}
|
|
4086
|
+
static isModel = true;
|
|
4087
|
+
|
|
4088
|
+
/**
|
|
4089
|
+
Create should only ever be called by the store. To create an instance of a
|
|
4090
|
+
`Model` in a dirty state use `store.createRecord`.
|
|
4091
|
+
To create instances of `Model` in a clean state, use `store.push`
|
|
4092
|
+
@method create
|
|
4093
|
+
@private
|
|
4094
|
+
@static
|
|
4095
|
+
*/
|
|
4096
|
+
|
|
4097
|
+
/**
|
|
4098
|
+
Represents the model's class name as a string. This can be used to look up the model's class name through
|
|
4099
|
+
`Store`'s modelFor method.
|
|
4100
|
+
`modelName` is generated for you by EmberData. It will be a lowercased, dasherized string.
|
|
4101
|
+
For example:
|
|
4102
|
+
```javascript
|
|
4103
|
+
store.modelFor('post').modelName; // 'post'
|
|
4104
|
+
store.modelFor('blog-post').modelName; // 'blog-post'
|
|
4105
|
+
```
|
|
4106
|
+
The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
|
|
4107
|
+
keys to underscore (instead of dasherized), you might use the following code:
|
|
4108
|
+
```javascript
|
|
4109
|
+
import RESTSerializer from '@ember-data/serializer/rest';
|
|
4110
|
+
import { underscore } from '<app-name>/utils/string-utils';
|
|
4111
|
+
export default const PostSerializer = RESTSerializer.extend({
|
|
4112
|
+
payloadKeyFromModelName(modelName) {
|
|
4113
|
+
return underscore(modelName);
|
|
4114
|
+
}
|
|
4115
|
+
});
|
|
4116
|
+
```
|
|
4117
|
+
@property modelName
|
|
4118
|
+
@public
|
|
4119
|
+
@type String
|
|
4120
|
+
@readonly
|
|
4121
|
+
@static
|
|
4122
|
+
*/
|
|
4123
|
+
static modelName = null;
|
|
4124
|
+
|
|
4197
4125
|
/*
|
|
4198
4126
|
These class methods below provide relationship
|
|
4199
4127
|
introspection abilities about relationships.
|
|
@@ -4226,12 +4154,20 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4226
4154
|
@return {Model} the type of the relationship, or undefined
|
|
4227
4155
|
*/
|
|
4228
4156
|
static typeForRelationship(name, store) {
|
|
4229
|
-
|
|
4157
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4158
|
+
if (!test) {
|
|
4159
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4160
|
+
}
|
|
4161
|
+
})(this.modelName) : {};
|
|
4230
4162
|
const relationship = this.relationshipsByName.get(name);
|
|
4231
4163
|
return relationship && store.modelFor(relationship.type);
|
|
4232
4164
|
}
|
|
4233
4165
|
static get inverseMap() {
|
|
4234
|
-
|
|
4166
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4167
|
+
if (!test) {
|
|
4168
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4169
|
+
}
|
|
4170
|
+
})(this.modelName) : {};
|
|
4235
4171
|
return Object.create(null);
|
|
4236
4172
|
}
|
|
4237
4173
|
|
|
@@ -4251,8 +4187,8 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4251
4187
|
}
|
|
4252
4188
|
```
|
|
4253
4189
|
``` js
|
|
4254
|
-
store.modelFor('post').inverseFor('comments', store) // { type:
|
|
4255
|
-
store.modelFor('message').inverseFor('owner', store) // { type:
|
|
4190
|
+
store.modelFor('post').inverseFor('comments', store) // { type: 'message', name: 'owner', kind: 'belongsTo' }
|
|
4191
|
+
store.modelFor('message').inverseFor('owner', store) // { type: 'post', name: 'comments', kind: 'hasMany' }
|
|
4256
4192
|
```
|
|
4257
4193
|
@method inverseFor
|
|
4258
4194
|
@public
|
|
@@ -4261,8 +4197,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4261
4197
|
@param {Store} store
|
|
4262
4198
|
@return {Object} the inverse relationship, or null
|
|
4263
4199
|
*/
|
|
4200
|
+
static {
|
|
4201
|
+
decorateMethodV2(this, "inverseMap", [computeOnce]);
|
|
4202
|
+
}
|
|
4264
4203
|
static inverseFor(name, store) {
|
|
4265
|
-
|
|
4204
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4205
|
+
if (!test) {
|
|
4206
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4207
|
+
}
|
|
4208
|
+
})(this.modelName) : {};
|
|
4266
4209
|
const inverseMap = this.inverseMap;
|
|
4267
4210
|
if (inverseMap[name]) {
|
|
4268
4211
|
return inverseMap[name];
|
|
@@ -4275,83 +4218,47 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4275
4218
|
|
|
4276
4219
|
//Calculate the inverse, ignoring the cache
|
|
4277
4220
|
static _findInverseFor(name, store) {
|
|
4278
|
-
|
|
4221
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4222
|
+
if (!test) {
|
|
4223
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4224
|
+
}
|
|
4225
|
+
})(this.modelName) : {};
|
|
4279
4226
|
const relationship = this.relationshipsByName.get(name);
|
|
4227
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4228
|
+
if (!test) {
|
|
4229
|
+
throw new Error(`No relationship named '${name}' on '${this.modelName}' exists.`);
|
|
4230
|
+
}
|
|
4231
|
+
})(relationship) : {};
|
|
4232
|
+
if (!relationship) {
|
|
4233
|
+
return null;
|
|
4234
|
+
}
|
|
4280
4235
|
const {
|
|
4281
4236
|
options
|
|
4282
4237
|
} = relationship;
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
const isExplicitInverseNull = options.inverse === null;
|
|
4287
|
-
const isAbstractType = !isExplicitInverseNull && isPolymorphic && !store.getSchemaDefinitionService().doesTypeExist(relationship.type);
|
|
4288
|
-
if (isExplicitInverseNull || isAbstractType) {
|
|
4289
|
-
assert(`No schema for the abstract type '${relationship.type}' for the polymorphic relationship '${name}' on '${this.modelName}' was provided by the SchemaDefinitionService.`, !isPolymorphic || isExplicitInverseNull);
|
|
4290
|
-
return null;
|
|
4291
|
-
}
|
|
4292
|
-
let fieldOnInverse, inverseKind, inverseRelationship, inverseOptions;
|
|
4293
|
-
const inverseSchema = this.typeForRelationship(name, store);
|
|
4294
|
-
|
|
4295
|
-
// if the type does not exist and we are not polymorphic
|
|
4296
|
-
//If inverse is specified manually, return the inverse
|
|
4297
|
-
if (options.inverse !== undefined) {
|
|
4298
|
-
fieldOnInverse = options.inverse;
|
|
4299
|
-
inverseRelationship = inverseSchema && inverseSchema.relationshipsByName.get(fieldOnInverse);
|
|
4300
|
-
assert(`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.`, inverseRelationship);
|
|
4301
|
-
|
|
4302
|
-
// TODO probably just return the whole inverse here
|
|
4303
|
-
inverseKind = inverseRelationship.kind;
|
|
4304
|
-
inverseOptions = inverseRelationship.options;
|
|
4305
|
-
} else {
|
|
4306
|
-
//No inverse was specified manually, we need to use a heuristic to guess one
|
|
4307
|
-
if (relationship.type === relationship.parentModelName) {
|
|
4308
|
-
warn(`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.`, false, {
|
|
4309
|
-
id: 'ds.model.reflexive-relationship-without-inverse'
|
|
4310
|
-
});
|
|
4238
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4239
|
+
if (!test) {
|
|
4240
|
+
throw new Error(`Expected the relationship ${name} on ${this.modelName} to define an inverse.`);
|
|
4311
4241
|
}
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
}
|
|
4316
|
-
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4317
|
-
const filteredRelationships = possibleRelationships.filter(possibleRelationship => {
|
|
4318
|
-
const optionsForRelationship = possibleRelationship.options;
|
|
4319
|
-
return name === optionsForRelationship.inverse;
|
|
4320
|
-
});
|
|
4321
|
-
assert("You defined the '" + name + "' relationship on " + this + ', but you defined the inverse relationships of type ' + inverseSchema.toString() + ' multiple times. Look at https://guides.emberjs.com/current/models/relationships/#toc_explicit-inverses for how to explicitly specify inverses', filteredRelationships.length < 2);
|
|
4322
|
-
}
|
|
4323
|
-
const explicitRelationship = possibleRelationships.find(relationship => relationship.options.inverse === name);
|
|
4324
|
-
if (explicitRelationship) {
|
|
4325
|
-
possibleRelationships = [explicitRelationship];
|
|
4326
|
-
}
|
|
4327
|
-
assert("You defined the '" + name + "' relationship on " + this + ', but multiple possible inverse relationships of type ' + this + ' were found on ' + inverseSchema + '. Look at https://guides.emberjs.com/current/models/relationships/#toc_explicit-inverses for how to explicitly specify inverses', possibleRelationships.length === 1);
|
|
4328
|
-
fieldOnInverse = possibleRelationships[0].name;
|
|
4329
|
-
inverseKind = possibleRelationships[0].kind;
|
|
4330
|
-
inverseOptions = possibleRelationships[0].options;
|
|
4242
|
+
})(options.inverse === null || typeof options.inverse === 'string' && options.inverse.length > 0) : {};
|
|
4243
|
+
if (options.inverse === null) {
|
|
4244
|
+
return null;
|
|
4331
4245
|
}
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
assert(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${fieldOnInverse}' on type '${inverseSchema.modelName}' is misconfigured.`, inverseOptions.as);
|
|
4337
|
-
assert(`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}'`, !!inverseOptions.as && relationship.type === inverseOptions.as);
|
|
4246
|
+
const schemaExists = store.schema.hasResource(relationship);
|
|
4247
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4248
|
+
if (!test) {
|
|
4249
|
+
throw new Error(`No associated schema found for '${relationship.type}' while calculating the inverse of ${name} on ${this.modelName}`);
|
|
4338
4250
|
}
|
|
4251
|
+
})(schemaExists) : {};
|
|
4252
|
+
if (!schemaExists) {
|
|
4253
|
+
return null;
|
|
4339
4254
|
}
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
assert(`Relationships that satisfy polymorphic relationships MUST define which abstract-type they are satisfying using 'as'. The field '${name}' on type '${this.modelName}' is misconfigured.`, options.as);
|
|
4345
|
-
assert(`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}'`, !!options.as && inverseRelationship.type === options.as);
|
|
4255
|
+
const inverseField = store.schema.fields(relationship).get(options.inverse);
|
|
4256
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4257
|
+
if (!test) {
|
|
4258
|
+
throw new Error(`No inverse relationship found for '${name}' on '${this.modelName}'`);
|
|
4346
4259
|
}
|
|
4347
|
-
}
|
|
4348
|
-
|
|
4349
|
-
return {
|
|
4350
|
-
type: inverseSchema,
|
|
4351
|
-
name: fieldOnInverse,
|
|
4352
|
-
kind: inverseKind,
|
|
4353
|
-
options: inverseOptions
|
|
4354
|
-
};
|
|
4260
|
+
})(inverseField && (inverseField.kind === 'belongsTo' || inverseField.kind === 'hasMany')) : {};
|
|
4261
|
+
return inverseField || null;
|
|
4355
4262
|
}
|
|
4356
4263
|
|
|
4357
4264
|
/**
|
|
@@ -4389,7 +4296,11 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4389
4296
|
*/
|
|
4390
4297
|
|
|
4391
4298
|
static get relationships() {
|
|
4392
|
-
|
|
4299
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4300
|
+
if (!test) {
|
|
4301
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4302
|
+
}
|
|
4303
|
+
})(this.modelName) : {};
|
|
4393
4304
|
const map = new Map();
|
|
4394
4305
|
const relationshipsByName = this.relationshipsByName;
|
|
4395
4306
|
|
|
@@ -4433,14 +4344,21 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4433
4344
|
@type Object
|
|
4434
4345
|
@readOnly
|
|
4435
4346
|
*/
|
|
4347
|
+
static {
|
|
4348
|
+
decorateMethodV2(this, "relationships", [computeOnce]);
|
|
4349
|
+
}
|
|
4436
4350
|
static get relationshipNames() {
|
|
4437
|
-
|
|
4351
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4352
|
+
if (!test) {
|
|
4353
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4354
|
+
}
|
|
4355
|
+
})(this.modelName) : {};
|
|
4438
4356
|
const names = {
|
|
4439
4357
|
hasMany: [],
|
|
4440
4358
|
belongsTo: []
|
|
4441
4359
|
};
|
|
4442
4360
|
this.eachComputedProperty((name, meta) => {
|
|
4443
|
-
if (meta
|
|
4361
|
+
if (isRelationshipSchema(meta)) {
|
|
4444
4362
|
names[meta.kind].push(name);
|
|
4445
4363
|
}
|
|
4446
4364
|
});
|
|
@@ -4472,8 +4390,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4472
4390
|
@type Array
|
|
4473
4391
|
@readOnly
|
|
4474
4392
|
*/
|
|
4393
|
+
static {
|
|
4394
|
+
decorateMethodV2(this, "relationshipNames", [computeOnce]);
|
|
4395
|
+
}
|
|
4475
4396
|
static get relatedTypes() {
|
|
4476
|
-
|
|
4397
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4398
|
+
if (!test) {
|
|
4399
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4400
|
+
}
|
|
4401
|
+
})(this.modelName) : {};
|
|
4477
4402
|
const types = [];
|
|
4478
4403
|
const rels = this.relationshipsObject;
|
|
4479
4404
|
const relationships = Object.keys(rels);
|
|
@@ -4484,7 +4409,7 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4484
4409
|
const name = relationships[i];
|
|
4485
4410
|
const meta = rels[name];
|
|
4486
4411
|
const modelName = meta.type;
|
|
4487
|
-
if (types.
|
|
4412
|
+
if (!types.includes(modelName)) {
|
|
4488
4413
|
types.push(modelName);
|
|
4489
4414
|
}
|
|
4490
4415
|
}
|
|
@@ -4519,8 +4444,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4519
4444
|
@type Map
|
|
4520
4445
|
@readOnly
|
|
4521
4446
|
*/
|
|
4447
|
+
static {
|
|
4448
|
+
decorateMethodV2(this, "relatedTypes", [computeOnce]);
|
|
4449
|
+
}
|
|
4522
4450
|
static get relationshipsByName() {
|
|
4523
|
-
|
|
4451
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4452
|
+
if (!test) {
|
|
4453
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4454
|
+
}
|
|
4455
|
+
})(this.modelName) : {};
|
|
4524
4456
|
const map = new Map();
|
|
4525
4457
|
const rels = this.relationshipsObject;
|
|
4526
4458
|
const relationships = Object.keys(rels);
|
|
@@ -4531,19 +4463,35 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4531
4463
|
}
|
|
4532
4464
|
return map;
|
|
4533
4465
|
}
|
|
4466
|
+
static {
|
|
4467
|
+
decorateMethodV2(this, "relationshipsByName", [computeOnce]);
|
|
4468
|
+
}
|
|
4534
4469
|
static get relationshipsObject() {
|
|
4535
|
-
|
|
4470
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4471
|
+
if (!test) {
|
|
4472
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4473
|
+
}
|
|
4474
|
+
})(this.modelName) : {};
|
|
4536
4475
|
const relationships = Object.create(null);
|
|
4537
4476
|
const modelName = this.modelName;
|
|
4538
4477
|
this.eachComputedProperty((name, meta) => {
|
|
4539
|
-
if (meta
|
|
4540
|
-
|
|
4541
|
-
meta.key = name;
|
|
4542
|
-
meta.name = name;
|
|
4543
|
-
meta.parentModelName = modelName;
|
|
4544
|
-
relationships[name] = meta;
|
|
4545
|
-
assert(`You should not specify both options.as and options.inverse as null on ${modelName}.${meta.name}, as if there is no inverse field there is no abstract type to conform to. You may have intended for this relationship to be polymorphic, or you may have mistakenly set inverse to null.`, !(meta.options.inverse === null && meta.options.as?.length > 0));
|
|
4478
|
+
if (!isRelationshipSchema(meta)) {
|
|
4479
|
+
return;
|
|
4546
4480
|
}
|
|
4481
|
+
// TODO deprecate key being here
|
|
4482
|
+
meta.key = name;
|
|
4483
|
+
meta.name = name;
|
|
4484
|
+
relationships[name] = meta;
|
|
4485
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4486
|
+
if (!test) {
|
|
4487
|
+
throw new Error(`Expected options in meta`);
|
|
4488
|
+
}
|
|
4489
|
+
})(meta.options && typeof meta.options === 'object') : {};
|
|
4490
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4491
|
+
if (!test) {
|
|
4492
|
+
throw new Error(`You should not specify both options.as and options.inverse as null on ${modelName}.${meta.name}, as if there is no inverse field there is no abstract type to conform to. You may have intended for this relationship to be polymorphic, or you may have mistakenly set inverse to null.`);
|
|
4493
|
+
}
|
|
4494
|
+
})(!(meta.options.inverse === null && meta.options.as?.length)) : {};
|
|
4547
4495
|
});
|
|
4548
4496
|
return relationships;
|
|
4549
4497
|
}
|
|
@@ -4580,13 +4528,20 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4580
4528
|
@type Map
|
|
4581
4529
|
@readOnly
|
|
4582
4530
|
*/
|
|
4531
|
+
static {
|
|
4532
|
+
decorateMethodV2(this, "relationshipsObject", [computeOnce]);
|
|
4533
|
+
}
|
|
4583
4534
|
static get fields() {
|
|
4584
|
-
|
|
4535
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4536
|
+
if (!test) {
|
|
4537
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4538
|
+
}
|
|
4539
|
+
})(this.modelName) : {};
|
|
4585
4540
|
const map = new Map();
|
|
4586
4541
|
this.eachComputedProperty((name, meta) => {
|
|
4587
|
-
if (meta
|
|
4542
|
+
if (isRelationshipSchema(meta)) {
|
|
4588
4543
|
map.set(name, meta.kind);
|
|
4589
|
-
} else if (meta
|
|
4544
|
+
} else if (isAttributeSchema(meta)) {
|
|
4590
4545
|
map.set(name, 'attribute');
|
|
4591
4546
|
}
|
|
4592
4547
|
});
|
|
@@ -4603,8 +4558,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4603
4558
|
@param {Function} callback the callback to invoke
|
|
4604
4559
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
4605
4560
|
*/
|
|
4561
|
+
static {
|
|
4562
|
+
decorateMethodV2(this, "fields", [computeOnce]);
|
|
4563
|
+
}
|
|
4606
4564
|
static eachRelationship(callback, binding) {
|
|
4607
|
-
|
|
4565
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4566
|
+
if (!test) {
|
|
4567
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4568
|
+
}
|
|
4569
|
+
})(this.modelName) : {};
|
|
4608
4570
|
this.relationshipsByName.forEach((relationship, name) => {
|
|
4609
4571
|
callback.call(binding, name, relationship);
|
|
4610
4572
|
});
|
|
@@ -4622,15 +4584,30 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4622
4584
|
@param {any} binding the value to which the callback's `this` should be bound
|
|
4623
4585
|
*/
|
|
4624
4586
|
static eachRelatedType(callback, binding) {
|
|
4625
|
-
|
|
4587
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4588
|
+
if (!test) {
|
|
4589
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4590
|
+
}
|
|
4591
|
+
})(this.modelName) : {};
|
|
4626
4592
|
const relationshipTypes = this.relatedTypes;
|
|
4627
4593
|
for (let i = 0; i < relationshipTypes.length; i++) {
|
|
4628
4594
|
const type = relationshipTypes[i];
|
|
4629
4595
|
callback.call(binding, type);
|
|
4630
4596
|
}
|
|
4631
4597
|
}
|
|
4598
|
+
|
|
4599
|
+
/**
|
|
4600
|
+
*
|
|
4601
|
+
* @method determineRelationshipType
|
|
4602
|
+
* @private
|
|
4603
|
+
* @deprecated
|
|
4604
|
+
*/
|
|
4632
4605
|
static determineRelationshipType(knownSide, store) {
|
|
4633
|
-
|
|
4606
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4607
|
+
if (!test) {
|
|
4608
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4609
|
+
}
|
|
4610
|
+
})(this.modelName) : {};
|
|
4634
4611
|
const knownKey = knownSide.name;
|
|
4635
4612
|
const knownKind = knownSide.kind;
|
|
4636
4613
|
const inverse = this.inverseFor(knownKey, store);
|
|
@@ -4680,11 +4657,19 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4680
4657
|
@readOnly
|
|
4681
4658
|
*/
|
|
4682
4659
|
static get attributes() {
|
|
4683
|
-
|
|
4660
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4661
|
+
if (!test) {
|
|
4662
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4663
|
+
}
|
|
4664
|
+
})(this.modelName) : {};
|
|
4684
4665
|
const map = new Map();
|
|
4685
4666
|
this.eachComputedProperty((name, meta) => {
|
|
4686
|
-
if (meta
|
|
4687
|
-
|
|
4667
|
+
if (isAttributeSchema(meta)) {
|
|
4668
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4669
|
+
if (!test) {
|
|
4670
|
+
throw new Error("You may not set 'id' as an attribute on your model. Please remove any lines that look like: `id: attr('<type>')` from " + this.toString());
|
|
4671
|
+
}
|
|
4672
|
+
})(name !== 'id') : {};
|
|
4688
4673
|
|
|
4689
4674
|
// TODO deprecate key being here
|
|
4690
4675
|
meta.key = name;
|
|
@@ -4725,8 +4710,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4725
4710
|
@type {Map}
|
|
4726
4711
|
@readOnly
|
|
4727
4712
|
*/
|
|
4713
|
+
static {
|
|
4714
|
+
decorateMethodV2(this, "attributes", [computeOnce]);
|
|
4715
|
+
}
|
|
4728
4716
|
static get transformedAttributes() {
|
|
4729
|
-
|
|
4717
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4718
|
+
if (!test) {
|
|
4719
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4720
|
+
}
|
|
4721
|
+
})(this.modelName) : {};
|
|
4730
4722
|
const map = new Map();
|
|
4731
4723
|
this.eachAttribute((name, meta) => {
|
|
4732
4724
|
if (meta.type) {
|
|
@@ -4770,8 +4762,15 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4770
4762
|
@param {Object} [binding] the value to which the callback's `this` should be bound
|
|
4771
4763
|
@static
|
|
4772
4764
|
*/
|
|
4765
|
+
static {
|
|
4766
|
+
decorateMethodV2(this, "transformedAttributes", [computeOnce]);
|
|
4767
|
+
}
|
|
4773
4768
|
static eachAttribute(callback, binding) {
|
|
4774
|
-
|
|
4769
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4770
|
+
if (!test) {
|
|
4771
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4772
|
+
}
|
|
4773
|
+
})(this.modelName) : {};
|
|
4775
4774
|
this.attributes.forEach((meta, name) => {
|
|
4776
4775
|
callback.call(binding, name, meta);
|
|
4777
4776
|
});
|
|
@@ -4813,7 +4812,11 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4813
4812
|
@static
|
|
4814
4813
|
*/
|
|
4815
4814
|
static eachTransformedAttribute(callback, binding) {
|
|
4816
|
-
|
|
4815
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4816
|
+
if (!test) {
|
|
4817
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4818
|
+
}
|
|
4819
|
+
})(this.modelName) : {};
|
|
4817
4820
|
this.transformedAttributes.forEach((type, name) => {
|
|
4818
4821
|
callback.call(binding, name, type);
|
|
4819
4822
|
});
|
|
@@ -4826,11 +4829,18 @@ let Model = (_class = (_class2 = class Model extends EmberObject {
|
|
|
4826
4829
|
@static
|
|
4827
4830
|
*/
|
|
4828
4831
|
static toString() {
|
|
4829
|
-
|
|
4832
|
+
macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
|
|
4833
|
+
if (!test) {
|
|
4834
|
+
throw new Error(`Accessing schema information on Models without looking up the model via the store is disallowed.`);
|
|
4835
|
+
}
|
|
4836
|
+
})(this.modelName) : {};
|
|
4830
4837
|
return `model:${this.modelName}`;
|
|
4831
4838
|
}
|
|
4832
|
-
}
|
|
4839
|
+
}
|
|
4840
|
+
|
|
4841
|
+
// @ts-expect-error TS doesn't know how to do `this` function overloads
|
|
4833
4842
|
Model.prototype.save = save;
|
|
4843
|
+
// @ts-expect-error TS doesn't know how to do `this` function overloads
|
|
4834
4844
|
Model.prototype.destroyRecord = destroyRecord;
|
|
4835
4845
|
Model.prototype.unloadRecord = unloadRecord;
|
|
4836
4846
|
Model.prototype.hasMany = hasMany;
|
|
@@ -4847,64 +4857,7 @@ defineSignal(Model.prototype, 'isReloading', false);
|
|
|
4847
4857
|
// the values initialized during create to `setUnknownProperty`
|
|
4848
4858
|
Model.prototype._createProps = null;
|
|
4849
4859
|
Model.prototype._secretInit = null;
|
|
4850
|
-
if (macroCondition(
|
|
4851
|
-
/**
|
|
4852
|
-
Provides info about the model for debugging purposes
|
|
4853
|
-
by grouping the properties into more semantic groups.
|
|
4854
|
-
Meant to be used by debugging tools such as the Chrome Ember Extension.
|
|
4855
|
-
- Groups all attributes in "Attributes" group.
|
|
4856
|
-
- Groups all belongsTo relationships in "Belongs To" group.
|
|
4857
|
-
- Groups all hasMany relationships in "Has Many" group.
|
|
4858
|
-
- Groups all flags in "Flags" group.
|
|
4859
|
-
- Flags relationship CPs as expensive properties.
|
|
4860
|
-
@method _debugInfo
|
|
4861
|
-
@for Model
|
|
4862
|
-
@private
|
|
4863
|
-
*/
|
|
4864
|
-
Model.prototype._debugInfo = function () {
|
|
4865
|
-
const relationships = {};
|
|
4866
|
-
const expensiveProperties = [];
|
|
4867
|
-
const identifier = recordIdentifierFor$1(this);
|
|
4868
|
-
const schema = this.store.getSchemaDefinitionService();
|
|
4869
|
-
const attrDefs = schema.attributesDefinitionFor(identifier);
|
|
4870
|
-
const relDefs = schema.relationshipsDefinitionFor(identifier);
|
|
4871
|
-
const attributes = Object.keys(attrDefs);
|
|
4872
|
-
attributes.unshift('id');
|
|
4873
|
-
const groups = [{
|
|
4874
|
-
name: 'Attributes',
|
|
4875
|
-
properties: attributes,
|
|
4876
|
-
expand: true
|
|
4877
|
-
}];
|
|
4878
|
-
Object.keys(relDefs).forEach(name => {
|
|
4879
|
-
const relationship = relDefs[name];
|
|
4880
|
-
let properties = relationships[relationship.kind];
|
|
4881
|
-
if (properties === undefined) {
|
|
4882
|
-
properties = relationships[relationship.kind] = [];
|
|
4883
|
-
groups.push({
|
|
4884
|
-
name: relationship.kind,
|
|
4885
|
-
properties,
|
|
4886
|
-
expand: true
|
|
4887
|
-
});
|
|
4888
|
-
}
|
|
4889
|
-
properties.push(name);
|
|
4890
|
-
expensiveProperties.push(name);
|
|
4891
|
-
});
|
|
4892
|
-
groups.push({
|
|
4893
|
-
name: 'Flags',
|
|
4894
|
-
properties: ['isLoaded', 'hasDirtyAttributes', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
|
|
4895
|
-
});
|
|
4896
|
-
return {
|
|
4897
|
-
propertyInfo: {
|
|
4898
|
-
// include all other mixins / properties (not just the grouped ones)
|
|
4899
|
-
includeOtherProperties: true,
|
|
4900
|
-
groups: groups,
|
|
4901
|
-
// don't pre-calculate unless cached
|
|
4902
|
-
expensiveProperties: expensiveProperties
|
|
4903
|
-
}
|
|
4904
|
-
};
|
|
4905
|
-
};
|
|
4906
|
-
}
|
|
4907
|
-
if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
4860
|
+
if (macroCondition(getGlobalConfig().WarpDrive.env.DEBUG)) {
|
|
4908
4861
|
const lookupDescriptor = function lookupDescriptor(obj, keyName) {
|
|
4909
4862
|
let current = obj;
|
|
4910
4863
|
do {
|
|
@@ -4916,27 +4869,37 @@ if (macroCondition(getOwnConfig().env.DEBUG)) {
|
|
|
4916
4869
|
} while (current !== null);
|
|
4917
4870
|
return null;
|
|
4918
4871
|
};
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
}
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4872
|
+
|
|
4873
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
4874
|
+
const init = Model.prototype.init;
|
|
4875
|
+
Model.prototype.init = function (createArgs) {
|
|
4876
|
+
init.call(this, createArgs);
|
|
4877
|
+
const ourDescriptor = lookupDescriptor(Model.prototype, 'currentState');
|
|
4878
|
+
const theirDescriptor = lookupDescriptor(this, 'currentState');
|
|
4879
|
+
if (!ourDescriptor || !theirDescriptor) {
|
|
4880
|
+
throw new Error(`Unable to determine if 'currentState' is a reserved property name on instances of classes extending Model. Please ensure that 'currentState' is not defined as a property on ${this.constructor.toString()}`);
|
|
4881
|
+
}
|
|
4882
|
+
const realState = this.___recordState;
|
|
4883
|
+
if (ourDescriptor.get !== theirDescriptor.get || realState !== this.currentState) {
|
|
4884
|
+
throw new Error(`'currentState' is a reserved property name on instances of classes extending Model. Please choose a different property name for ${this.constructor.toString()}`);
|
|
4885
|
+
}
|
|
4886
|
+
const ID_DESCRIPTOR = lookupDescriptor(Model.prototype, 'id');
|
|
4887
|
+
const idDesc = lookupDescriptor(this, 'id');
|
|
4888
|
+
if (!ID_DESCRIPTOR || !idDesc) {
|
|
4889
|
+
throw new Error(`Unable to determine if 'id' is a reserved property name on instances of classes extending Model. Please ensure that 'id' is not defined as a property on ${this.constructor.toString()}`);
|
|
4890
|
+
}
|
|
4891
|
+
if (idDesc.get !== ID_DESCRIPTOR.get) {
|
|
4892
|
+
throw new Error(`You may not set 'id' as an attribute on your model. Please remove any lines that look like: \`id: attr('<type>')\` from ${this.constructor.toString()}`);
|
|
4933
4893
|
}
|
|
4934
|
-
});
|
|
4935
|
-
Model.reopen = function deprecatedReopen() {
|
|
4936
|
-
assert(`Model.reopen is deprecated. Use Foo extends Model to extend your class instead.`);
|
|
4937
|
-
};
|
|
4938
|
-
Model.reopenClass = function deprecatedReopenClass() {
|
|
4939
|
-
assert(`Model.reopenClass is deprecated. Use Foo extends Model to add static methods and properties to your class instead.`);
|
|
4940
4894
|
};
|
|
4895
|
+
delete Model.reopen;
|
|
4896
|
+
delete Model.reopenClass;
|
|
4897
|
+
}
|
|
4898
|
+
function isRelationshipSchema(meta) {
|
|
4899
|
+
const hasKind = typeof meta === 'object' && meta !== null && 'kind' in meta && 'options' in meta;
|
|
4900
|
+
return hasKind && (meta.kind === 'hasMany' || meta.kind === 'belongsTo');
|
|
4901
|
+
}
|
|
4902
|
+
function isAttributeSchema(meta) {
|
|
4903
|
+
return typeof meta === 'object' && meta !== null && 'kind' in meta && meta.kind === 'attribute';
|
|
4941
4904
|
}
|
|
4942
|
-
export { Errors as E, LEGACY_SUPPORT as L, Model as M, PromiseBelongsTo as P,
|
|
4905
|
+
export { Errors as E, LEGACY_SUPPORT as L, Model as M, PromiseBelongsTo as P, RecordState as R, PromiseManyArray as a, save as b, reload as c, destroyRecord as d, deleteRecord as e, changedAttributes as f, belongsTo as g, hasMany as h, createSnapshot as i, isElementDescriptor as j, lookupLegacySupport as l, normalizeModelName as n, rollbackAttributes as r, serialize as s, unloadRecord as u };
|