@ember-data/serializer 5.5.0-alpha.2 → 5.5.0-alpha.21

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.
Files changed (78) hide show
  1. package/LICENSE.md +19 -7
  2. package/README.md +16 -10
  3. package/addon-main.cjs +5 -0
  4. package/blueprints/serializer/index.js +71 -5
  5. package/blueprints/serializer-test/index.js +13 -7
  6. package/blueprints/serializer-test/qunit-files/__root__/__path__/__test__.js +8 -9
  7. package/blueprints/transform/index.js +14 -4
  8. package/blueprints/transform-test/index.js +13 -7
  9. package/blueprints/transform-test/qunit-files/__root__/__path__/__test__.js +3 -4
  10. package/dist/index.js +306 -0
  11. package/dist/index.js.map +1 -0
  12. package/{addon/json.js → dist/json-BwMH6O_R.js} +83 -63
  13. package/dist/json-BwMH6O_R.js.map +1 -0
  14. package/{addon → dist}/json-api.js +90 -188
  15. package/dist/json-api.js.map +1 -0
  16. package/dist/json.js +6 -0
  17. package/dist/json.js.map +1 -0
  18. package/dist/rest.js +1274 -0
  19. package/dist/rest.js.map +1 -0
  20. package/{addon/string-22572f80.js → dist/transform.js} +143 -20
  21. package/dist/transform.js.map +1 -0
  22. package/logos/NCC-1701-a-blue.svg +4 -0
  23. package/logos/NCC-1701-a-gold.svg +4 -0
  24. package/logos/NCC-1701-a-gold_100.svg +1 -0
  25. package/logos/NCC-1701-a-gold_base-64.txt +1 -0
  26. package/logos/NCC-1701-a.svg +4 -0
  27. package/logos/README.md +4 -0
  28. package/logos/docs-badge.svg +2 -0
  29. package/logos/github-header.svg +444 -0
  30. package/logos/social1.png +0 -0
  31. package/logos/social2.png +0 -0
  32. package/logos/warp-drive-logo-dark.svg +4 -0
  33. package/logos/warp-drive-logo-gold.svg +4 -0
  34. package/package.json +60 -45
  35. package/unstable-preview-types/-private/embedded-records-mixin.d.ts +102 -0
  36. package/unstable-preview-types/-private/embedded-records-mixin.d.ts.map +1 -0
  37. package/unstable-preview-types/-private/transforms/boolean.d.ts +52 -0
  38. package/unstable-preview-types/-private/transforms/boolean.d.ts.map +1 -0
  39. package/unstable-preview-types/-private/transforms/boolean.type-test.d.ts +4 -0
  40. package/unstable-preview-types/-private/transforms/boolean.type-test.d.ts.map +1 -0
  41. package/unstable-preview-types/-private/transforms/date.d.ts +33 -0
  42. package/unstable-preview-types/-private/transforms/date.d.ts.map +1 -0
  43. package/unstable-preview-types/-private/transforms/number.d.ts +34 -0
  44. package/unstable-preview-types/-private/transforms/number.d.ts.map +1 -0
  45. package/unstable-preview-types/-private/transforms/string.d.ts +34 -0
  46. package/unstable-preview-types/-private/transforms/string.d.ts.map +1 -0
  47. package/unstable-preview-types/-private/transforms/transform.d.ts +126 -0
  48. package/unstable-preview-types/-private/transforms/transform.d.ts.map +1 -0
  49. package/unstable-preview-types/-private/utils.d.ts +6 -0
  50. package/unstable-preview-types/-private/utils.d.ts.map +1 -0
  51. package/unstable-preview-types/index.d.ts +277 -0
  52. package/unstable-preview-types/index.d.ts.map +1 -0
  53. package/unstable-preview-types/json-api.d.ts +514 -0
  54. package/unstable-preview-types/json-api.d.ts.map +1 -0
  55. package/unstable-preview-types/json.d.ts +1093 -0
  56. package/unstable-preview-types/json.d.ts.map +1 -0
  57. package/unstable-preview-types/rest.d.ts +570 -0
  58. package/unstable-preview-types/rest.d.ts.map +1 -0
  59. package/unstable-preview-types/transform.d.ts +11 -0
  60. package/unstable-preview-types/transform.d.ts.map +1 -0
  61. package/addon/-private.js +0 -4
  62. package/addon/-private.js.map +0 -1
  63. package/addon/embedded-records-mixin-d75385ff.js +0 -575
  64. package/addon/embedded-records-mixin-d75385ff.js.map +0 -1
  65. package/addon/index.js +0 -180
  66. package/addon/index.js.map +0 -1
  67. package/addon/json-api.js.map +0 -1
  68. package/addon/json.js.map +0 -1
  69. package/addon/rest.js +0 -680
  70. package/addon/rest.js.map +0 -1
  71. package/addon/string-22572f80.js.map +0 -1
  72. package/addon/transform.js +0 -2
  73. package/addon/transform.js.map +0 -1
  74. package/addon/utils-075c5b79.js +0 -12
  75. package/addon/utils-075c5b79.js.map +0 -1
  76. package/addon-main.js +0 -93
  77. /package/{ember-data-logo-dark.svg → logos/ember-data-logo-dark.svg} +0 -0
  78. /package/{ember-data-logo-light.svg → logos/ember-data-logo-light.svg} +0 -0
package/addon/rest.js DELETED
@@ -1,680 +0,0 @@
1
- import { macroCondition, getOwnConfig } from '@embroider/macros';
2
- import { assert, warn } from '@ember/debug';
3
- import { dasherize, camelize } from '@ember/string';
4
- import { singularize } from 'ember-inflector';
5
- export { e as EmbeddedRecordsMixin } from "./embedded-records-mixin-d75385ff";
6
- import { c as coerceId } from "./utils-075c5b79";
7
- import JSONSerializer from "./json";
8
- function makeArray(value) {
9
- return Array.isArray(value) ? value : [value];
10
- }
11
-
12
- /**
13
- * <blockquote style="margin: 1em; padding: .1em 1em .1em 1em; border-left: solid 1em #E34C32; background: #e0e0e0;">
14
- <p>
15
- ⚠️ <strong>This is LEGACY documentation</strong> for a feature that is no longer encouraged to be used.
16
- If starting a new app or thinking of implementing a new adapter, consider writing a
17
- <a href="/ember-data/release/classes/%3CInterface%3E%20Handler">Handler</a> instead to be used with the <a href="https://github.com/emberjs/data/tree/main/packages/request#readme">RequestManager</a>
18
- </p>
19
- </blockquote>
20
-
21
- Normally, applications will use the `RESTSerializer` by implementing
22
- the `normalize` method.
23
-
24
- This allows you to do whatever kind of munging you need and is
25
- especially useful if your server is inconsistent and you need to
26
- do munging differently for many different kinds of responses.
27
-
28
- See the `normalize` documentation for more information.
29
-
30
- ## Across the Board Normalization
31
-
32
- There are also a number of hooks that you might find useful to define
33
- across-the-board rules for your payload. These rules will be useful
34
- if your server is consistent, or if you're building an adapter for
35
- an infrastructure service, like Firebase, and want to encode service
36
- conventions.
37
-
38
- For example, if all of your keys are underscored and all-caps, but
39
- otherwise consistent with the names you use in your models, you
40
- can implement across-the-board rules for how to convert an attribute
41
- name in your model to a key in your JSON.
42
-
43
- ```app/serializers/application.js
44
- import RESTSerializer from '@ember-data/serializer/rest';
45
- import { underscore } from '<app-name>/utils/string-utils';
46
-
47
- export default class ApplicationSerializer extends RESTSerializer {
48
- keyForAttribute(attr, method) {
49
- return underscore(attr).toUpperCase();
50
- }
51
- }
52
- ```
53
-
54
- You can also implement `keyForRelationship`, which takes the name
55
- of the relationship as the first parameter, the kind of
56
- relationship (`hasMany` or `belongsTo`) as the second parameter, and
57
- the method (`serialize` or `deserialize`) as the third parameter.
58
-
59
- @class RESTSerializer
60
- @main @ember-data/serializer/rest
61
- @public
62
- @extends JSONSerializer
63
- */
64
- const RESTSerializer = JSONSerializer.extend({
65
- /**
66
- `keyForPolymorphicType` can be used to define a custom key when
67
- serializing and deserializing a polymorphic type. By default, the
68
- returned key is `${key}Type`.
69
- Example
70
- ```app/serializers/post.js
71
- import RESTSerializer from '@ember-data/serializer/rest';
72
- export default class ApplicationSerializer extends RESTSerializer {
73
- keyForPolymorphicType(key, relationship) {
74
- let relationshipKey = this.keyForRelationship(key);
75
- return 'type-' + relationshipKey;
76
- }
77
- }
78
- ```
79
- @method keyForPolymorphicType
80
- @public
81
- @param {String} key
82
- @param {String} typeClass
83
- @param {String} method
84
- @return {String} normalized key
85
- */
86
- keyForPolymorphicType(key, typeClass, method) {
87
- let relationshipKey = this.keyForRelationship(key);
88
- return `${relationshipKey}Type`;
89
- },
90
- /**
91
- Normalizes a part of the JSON payload returned by
92
- the server. You should override this method, munge the hash
93
- and call super if you have generic normalization to do.
94
- It takes the type of the record that is being normalized
95
- (as a Model class), the property where the hash was
96
- originally found, and the hash to normalize.
97
- For example, if you have a payload that looks like this:
98
- ```js
99
- {
100
- "post": {
101
- "id": 1,
102
- "title": "Rails is omakase",
103
- "comments": [ 1, 2 ]
104
- },
105
- "comments": [{
106
- "id": 1,
107
- "body": "FIRST"
108
- }, {
109
- "id": 2,
110
- "body": "Rails is unagi"
111
- }]
112
- }
113
- ```
114
- The `normalize` method will be called three times:
115
- * With `App.Post`, `"posts"` and `{ id: 1, title: "Rails is omakase", ... }`
116
- * With `App.Comment`, `"comments"` and `{ id: 1, body: "FIRST" }`
117
- * With `App.Comment`, `"comments"` and `{ id: 2, body: "Rails is unagi" }`
118
- You can use this method, for example, to normalize underscored keys to camelized
119
- or other general-purpose normalizations. You will only need to implement
120
- `normalize` and manipulate the payload as desired.
121
- For example, if the `IDs` under `"comments"` are provided as `_id` instead of
122
- `id`, you can specify how to normalize just the comments:
123
- ```app/serializers/post.js
124
- import RESTSerializer from '@ember-data/serializer/rest';
125
- export default class ApplicationSerializer extends RESTSerializer {
126
- normalize(model, hash, prop) {
127
- if (prop === 'comments') {
128
- hash.id = hash._id;
129
- delete hash._id;
130
- }
131
- return super.normalize(...arguments);
132
- }
133
- }
134
- ```
135
- On each call to the `normalize` method, the third parameter (`prop`) is always
136
- one of the keys that were in the original payload or in the result of another
137
- normalization as `normalizeResponse`.
138
- @method normalize
139
- @public
140
- @param {Model} modelClass
141
- @param {Object} resourceHash
142
- @param {String} prop
143
- @return {Object}
144
- */
145
-
146
- /**
147
- Normalizes an array of resource payloads and returns a JSON-API Document
148
- with primary data and, if any, included data as `{ data, included }`.
149
- @method _normalizeArray
150
- @param {Store} store
151
- @param {String} modelName
152
- @param {Object} arrayHash
153
- @param {String} prop
154
- @return {Object}
155
- @private
156
- */
157
- _normalizeArray(store, modelName, arrayHash, prop) {
158
- let documentHash = {
159
- data: [],
160
- included: []
161
- };
162
- let modelClass = store.modelFor(modelName);
163
- let serializer = store.serializerFor(modelName);
164
- makeArray(arrayHash).forEach(hash => {
165
- let {
166
- data,
167
- included
168
- } = this._normalizePolymorphicRecord(store, hash, prop, modelClass, serializer);
169
- documentHash.data.push(data);
170
- if (included) {
171
- documentHash.included = documentHash.included.concat(included);
172
- }
173
- });
174
- return documentHash;
175
- },
176
- _normalizePolymorphicRecord(store, hash, prop, primaryModelClass, primarySerializer) {
177
- let serializer = primarySerializer;
178
- let modelClass = primaryModelClass;
179
- let primaryHasTypeAttribute = primaryModelClass.fields.has('type');
180
- if (!primaryHasTypeAttribute && hash.type) {
181
- // Support polymorphic records in async relationships
182
- let modelName = this.modelNameFromPayloadKey(hash.type);
183
- if (store.getSchemaDefinitionService().doesTypeExist(modelName)) {
184
- serializer = store.serializerFor(modelName);
185
- modelClass = store.modelFor(modelName);
186
- }
187
- }
188
- return serializer.normalize(modelClass, hash, prop);
189
- },
190
- /**
191
- @method _normalizeResponse
192
- @param {Store} store
193
- @param {Model} primaryModelClass
194
- @param {Object} payload
195
- @param {String|Number} id
196
- @param {String} requestType
197
- @param {Boolean} isSingle
198
- @return {Object} JSON-API Document
199
- @private
200
- */
201
- _normalizeResponse(store, primaryModelClass, payload, id, requestType, isSingle) {
202
- let documentHash = {
203
- data: null,
204
- included: []
205
- };
206
- let meta = this.extractMeta(store, primaryModelClass, payload);
207
- if (meta) {
208
- assert('The `meta` returned from `extractMeta` has to be an object, not "' + typeof meta + '".', typeof meta === 'object');
209
- documentHash.meta = meta;
210
- }
211
- let keys = Object.keys(payload);
212
- for (var i = 0, length = keys.length; i < length; i++) {
213
- var prop = keys[i];
214
- var modelName = prop;
215
- var forcedSecondary = false;
216
-
217
- /*
218
- If you want to provide sideloaded records of the same type that the
219
- primary data you can do that by prefixing the key with `_`.
220
- Example
221
- ```
222
- {
223
- users: [
224
- { id: 1, title: 'Tom', manager: 3 },
225
- { id: 2, title: 'Yehuda', manager: 3 }
226
- ],
227
- _users: [
228
- { id: 3, title: 'Tomster' }
229
- ]
230
- }
231
- ```
232
- This forces `_users` to be added to `included` instead of `data`.
233
- */
234
- if (prop.charAt(0) === '_') {
235
- forcedSecondary = true;
236
- modelName = prop.substr(1);
237
- }
238
- var typeName = this.modelNameFromPayloadKey(modelName);
239
- if (!store.getSchemaDefinitionService().doesTypeExist(typeName)) {
240
- warn(this.warnMessageNoModelForKey(modelName, typeName), false, {
241
- id: 'ds.serializer.model-for-key-missing'
242
- });
243
- continue;
244
- }
245
- var isPrimary = !forcedSecondary && this.isPrimaryType(store, typeName, primaryModelClass);
246
- var value = payload[prop];
247
- if (value === null) {
248
- continue;
249
- }
250
- assert('The adapter returned an array for the primary data of a `queryRecord` response. `queryRecord` should return a single record.', !(requestType === 'queryRecord' && isPrimary && Array.isArray(value)));
251
-
252
- /*
253
- Support primary data as an object instead of an array.
254
- Example
255
- ```
256
- {
257
- user: { id: 1, title: 'Tom', manager: 3 }
258
- }
259
- ```
260
- */
261
- if (isPrimary && !Array.isArray(value)) {
262
- let {
263
- data,
264
- included
265
- } = this._normalizePolymorphicRecord(store, value, prop, primaryModelClass, this);
266
- documentHash.data = data;
267
- if (included) {
268
- documentHash.included = documentHash.included.concat(included);
269
- }
270
- continue;
271
- }
272
- let {
273
- data,
274
- included
275
- } = this._normalizeArray(store, typeName, value, prop);
276
- if (included) {
277
- documentHash.included = documentHash.included.concat(included);
278
- }
279
- if (isSingle) {
280
- data.forEach(resource => {
281
- /*
282
- Figures out if this is the primary record or not.
283
- It's either:
284
- 1. The record with the same ID as the original request
285
- 2. If it's a newly created record without an ID, the first record
286
- in the array
287
- */
288
- let isUpdatedRecord = isPrimary && coerceId(resource.id) === id;
289
- let isFirstCreatedRecord = isPrimary && !id && !documentHash.data;
290
- if (isFirstCreatedRecord || isUpdatedRecord) {
291
- documentHash.data = resource;
292
- } else {
293
- documentHash.included.push(resource);
294
- }
295
- });
296
- } else {
297
- if (isPrimary) {
298
- documentHash.data = data;
299
- } else {
300
- if (data) {
301
- documentHash.included = documentHash.included.concat(data);
302
- }
303
- }
304
- }
305
- }
306
- return documentHash;
307
- },
308
- isPrimaryType(store, modelName, primaryModelClass) {
309
- return dasherize(modelName) === primaryModelClass.modelName;
310
- },
311
- /**
312
- This method allows you to push a payload containing top-level
313
- collections of records organized per type.
314
- ```js
315
- {
316
- "posts": [{
317
- "id": "1",
318
- "title": "Rails is omakase",
319
- "author", "1",
320
- "comments": [ "1" ]
321
- }],
322
- "comments": [{
323
- "id": "1",
324
- "body": "FIRST"
325
- }],
326
- "users": [{
327
- "id": "1",
328
- "name": "@d2h"
329
- }]
330
- }
331
- ```
332
- It will first normalize the payload, so you can use this to push
333
- in data streaming in from your server structured the same way
334
- that fetches and saves are structured.
335
- @method pushPayload
336
- @public
337
- @param {Store} store
338
- @param {Object} payload
339
- */
340
- pushPayload(store, payload) {
341
- let documentHash = {
342
- data: [],
343
- included: []
344
- };
345
- for (var prop in payload) {
346
- var modelName = this.modelNameFromPayloadKey(prop);
347
- if (!store.getSchemaDefinitionService().doesTypeExist(modelName)) {
348
- warn(this.warnMessageNoModelForKey(prop, modelName), false, {
349
- id: 'ds.serializer.model-for-key-missing'
350
- });
351
- continue;
352
- }
353
- var type = store.modelFor(modelName);
354
- var typeSerializer = store.serializerFor(type.modelName);
355
- makeArray(payload[prop]).forEach(hash => {
356
- let {
357
- data,
358
- included
359
- } = typeSerializer.normalize(type, hash, prop);
360
- documentHash.data.push(data);
361
- if (included) {
362
- documentHash.included = documentHash.included.concat(included);
363
- }
364
- });
365
- }
366
- store.push(documentHash);
367
- },
368
- /**
369
- This method is used to convert each JSON root key in the payload
370
- into a modelName that it can use to look up the appropriate model for
371
- that part of the payload.
372
- For example, your server may send a model name that does not correspond with
373
- the name of the model in your app. Let's take a look at an example model,
374
- and an example payload:
375
- ```app/models/post.js
376
- import Model from '@ember-data/model';
377
- export default class Post extends Model {}
378
- ```
379
- ```javascript
380
- {
381
- "blog/post": {
382
- "id": "1
383
- }
384
- }
385
- ```
386
- Ember Data is going to normalize the payload's root key for the modelName. As a result,
387
- it will try to look up the "blog/post" model. Since we don't have a model called "blog/post"
388
- (or a file called app/models/blog/post.js in ember-cli), Ember Data will throw an error
389
- because it cannot find the "blog/post" model.
390
- Since we want to remove this namespace, we can define a serializer for the application that will
391
- remove "blog/" from the payload key whenver it's encountered by Ember Data:
392
- ```app/serializers/application.js
393
- import RESTSerializer from '@ember-data/serializer/rest';
394
- export default class ApplicationSerializer extends RESTSerializer {
395
- modelNameFromPayloadKey(payloadKey) {
396
- if (payloadKey === 'blog/post') {
397
- return super.modelNameFromPayloadKey(payloadKey.replace('blog/', ''));
398
- } else {
399
- return super.modelNameFromPayloadKey(payloadKey);
400
- }
401
- }
402
- }
403
- ```
404
- After refreshing, Ember Data will appropriately look up the "post" model.
405
- By default the modelName for a model is its
406
- name in dasherized form. This means that a payload key like "blogPost" would be
407
- normalized to "blog-post" when Ember Data looks up the model. Usually, Ember Data
408
- can use the correct inflection to do this for you. Most of the time, you won't
409
- need to override `modelNameFromPayloadKey` for this purpose.
410
- @method modelNameFromPayloadKey
411
- @public
412
- @param {String} key
413
- @return {String} the model's modelName
414
- */
415
- modelNameFromPayloadKey(key) {
416
- return dasherize(singularize(key));
417
- },
418
- // SERIALIZE
419
-
420
- /**
421
- Called when a record is saved in order to convert the
422
- record into JSON.
423
- By default, it creates a JSON object with a key for
424
- each attribute and belongsTo relationship.
425
- For example, consider this model:
426
- ```app/models/comment.js
427
- import Model, { attr, belongsTo } from '@ember-data/model';
428
- export default class Comment extends Model {
429
- @attr title
430
- @attr body
431
- @belongsTo('user') author
432
- }
433
- ```
434
- The default serialization would create a JSON object like:
435
- ```js
436
- {
437
- "title": "Rails is unagi",
438
- "body": "Rails? Omakase? O_O",
439
- "author": 12
440
- }
441
- ```
442
- By default, attributes are passed through as-is, unless
443
- you specified an attribute type (`attr('date')`). If
444
- you specify a transform, the JavaScript value will be
445
- serialized when inserted into the JSON hash.
446
- By default, belongs-to relationships are converted into
447
- IDs when inserted into the JSON hash.
448
- ## IDs
449
- `serialize` takes an options hash with a single option:
450
- `includeId`. If this option is `true`, `serialize` will,
451
- by default include the ID in the JSON object it builds.
452
- The adapter passes in `includeId: true` when serializing
453
- a record for `createRecord`, but not for `updateRecord`.
454
- ## Customization
455
- Your server may expect a different JSON format than the
456
- built-in serialization format.
457
- In that case, you can implement `serialize` yourself and
458
- return a JSON hash of your choosing.
459
- ```app/serializers/post.js
460
- import RESTSerializer from '@ember-data/serializer/rest';
461
- export default class ApplicationSerializer extends RESTSerializer {
462
- serialize(snapshot, options) {
463
- let json = {
464
- POST_TTL: snapshot.attr('title'),
465
- POST_BDY: snapshot.attr('body'),
466
- POST_CMS: snapshot.hasMany('comments', { ids: true })
467
- };
468
- if (options.includeId) {
469
- json.POST_ID_ = snapshot.id;
470
- }
471
- return json;
472
- }
473
- }
474
- ```
475
- ## Customizing an App-Wide Serializer
476
- If you want to define a serializer for your entire
477
- application, you'll probably want to use `eachAttribute`
478
- and `eachRelationship` on the record.
479
- ```app/serializers/application.js
480
- import RESTSerializer from '@ember-data/serializer/rest';
481
- import { pluralize } from '<app-name>/utils/string-utils';
482
- export default class ApplicationSerializer extends RESTSerializer {
483
- serialize(snapshot, options) {
484
- let json = {};
485
- snapshot.eachAttribute(function(name) {
486
- json[serverAttributeName(name)] = snapshot.attr(name);
487
- });
488
- snapshot.eachRelationship(function(name, relationship) {
489
- if (relationship.kind === 'hasMany') {
490
- json[serverHasManyName(name)] = snapshot.hasMany(name, { ids: true });
491
- }
492
- });
493
- if (options.includeId) {
494
- json.ID_ = snapshot.id;
495
- }
496
- return json;
497
- }
498
- }
499
- function serverAttributeName(attribute) {
500
- return attribute.underscore().toUpperCase();
501
- }
502
- function serverHasManyName(name) {
503
- return serverAttributeName(singularize(name)) + "_IDS";
504
- }
505
- ```
506
- This serializer will generate JSON that looks like this:
507
- ```js
508
- {
509
- "TITLE": "Rails is omakase",
510
- "BODY": "Yep. Omakase.",
511
- "COMMENT_IDS": [ 1, 2, 3 ]
512
- }
513
- ```
514
- ## Tweaking the Default JSON
515
- If you just want to do some small tweaks on the default JSON,
516
- you can call super first and make the tweaks on the returned
517
- JSON.
518
- ```app/serializers/post.js
519
- import RESTSerializer from '@ember-data/serializer/rest';
520
- export default class ApplicationSerializer extends RESTSerializer {
521
- serialize(snapshot, options) {
522
- let json = super.serialize(snapshot, options);
523
- json.subject = json.title;
524
- delete json.title;
525
- return json;
526
- }
527
- }
528
- ```
529
- @method serialize
530
- @public
531
- @param {Snapshot} snapshot
532
- @param {Object} options
533
- @return {Object} json
534
- */
535
- serialize(snapshot, options) {
536
- return this._super(...arguments);
537
- },
538
- /**
539
- You can use this method to customize the root keys serialized into the JSON.
540
- The hash property should be modified by reference (possibly using something like _.extend)
541
- By default the REST Serializer sends the modelName of a model, which is a camelized
542
- version of the name.
543
- For example, your server may expect underscored root objects.
544
- ```app/serializers/application.js
545
- import RESTSerializer from '@ember-data/serializer/rest';
546
- import { decamelize } from '<app-name>/utils/string-utils';
547
- export default class ApplicationSerializer extends RESTSerializer {
548
- serializeIntoHash(data, type, record, options) {
549
- let root = decamelize(type.modelName);
550
- data[root] = this.serialize(record, options);
551
- }
552
- }
553
- ```
554
- @method serializeIntoHash
555
- @public
556
- @param {Object} hash
557
- @param {Model} typeClass
558
- @param {Snapshot} snapshot
559
- @param {Object} options
560
- */
561
- serializeIntoHash(hash, typeClass, snapshot, options) {
562
- let normalizedRootKey = this.payloadKeyFromModelName(typeClass.modelName);
563
- hash[normalizedRootKey] = this.serialize(snapshot, options);
564
- },
565
- /**
566
- You can use `payloadKeyFromModelName` to override the root key for an outgoing
567
- request. By default, the RESTSerializer returns a camelized version of the
568
- model's name.
569
- For a model called TacoParty, its `modelName` would be the string `taco-party`. The RESTSerializer
570
- will send it to the server with `tacoParty` as the root key in the JSON payload:
571
- ```js
572
- {
573
- "tacoParty": {
574
- "id": "1",
575
- "location": "Matthew Beale's House"
576
- }
577
- }
578
- ```
579
- For example, your server may expect dasherized root objects:
580
- ```app/serializers/application.js
581
- import RESTSerializer from '@ember-data/serializer/rest';
582
- import { dasherize } from '<app-name>/utils/string-utils';
583
- export default class ApplicationSerializer extends RESTSerializer {
584
- payloadKeyFromModelName(modelName) {
585
- return dasherize(modelName);
586
- }
587
- }
588
- ```
589
- Given a `TacoParty` model, calling `save` on it would produce an outgoing
590
- request like:
591
- ```js
592
- {
593
- "taco-party": {
594
- "id": "1",
595
- "location": "Matthew Beale's House"
596
- }
597
- }
598
- ```
599
- @method payloadKeyFromModelName
600
- @public
601
- @param {String} modelName
602
- @return {String}
603
- */
604
- payloadKeyFromModelName(modelName) {
605
- return camelize(modelName);
606
- },
607
- /**
608
- You can use this method to customize how polymorphic objects are serialized.
609
- By default the REST Serializer creates the key by appending `Type` to
610
- the attribute and value from the model's camelcased model name.
611
- @method serializePolymorphicType
612
- @public
613
- @param {Snapshot} snapshot
614
- @param {Object} json
615
- @param {Object} relationship
616
- */
617
- serializePolymorphicType(snapshot, json, relationship) {
618
- let key = relationship.key;
619
- let typeKey = this.keyForPolymorphicType(key, relationship.type, 'serialize');
620
- let belongsTo = snapshot.belongsTo(key);
621
- if (!belongsTo) {
622
- json[typeKey] = null;
623
- } else {
624
- json[typeKey] = camelize(belongsTo.modelName);
625
- }
626
- },
627
- /**
628
- You can use this method to customize how a polymorphic relationship should
629
- be extracted.
630
- @method extractPolymorphicRelationship
631
- @public
632
- @param {Object} relationshipType
633
- @param {Object} relationshipHash
634
- @param {Object} relationshipOptions
635
- @return {Object}
636
- */
637
- extractPolymorphicRelationship(relationshipType, relationshipHash, relationshipOptions) {
638
- let {
639
- key,
640
- resourceHash,
641
- relationshipMeta
642
- } = relationshipOptions;
643
-
644
- // A polymorphic belongsTo relationship can be present in the payload
645
- // either in the form where the `id` and the `type` are given:
646
- //
647
- // {
648
- // message: { id: 1, type: 'post' }
649
- // }
650
- //
651
- // or by the `id` and a `<relationship>Type` attribute:
652
- //
653
- // {
654
- // message: 1,
655
- // messageType: 'post'
656
- // }
657
- //
658
- // The next code checks if the latter case is present and returns the
659
- // corresponding JSON-API representation. The former case is handled within
660
- // the base class JSONSerializer.
661
- let isPolymorphic = relationshipMeta.options.polymorphic;
662
- let typeProperty = this.keyForPolymorphicType(key, relationshipType, 'deserialize');
663
- if (isPolymorphic && resourceHash[typeProperty] !== undefined && typeof relationshipHash !== 'object') {
664
- let type = this.modelNameFromPayloadKey(resourceHash[typeProperty]);
665
- return {
666
- id: coerceId(relationshipHash),
667
- type: type
668
- };
669
- }
670
- return this._super(...arguments);
671
- }
672
- });
673
- if (macroCondition(getOwnConfig().env.DEBUG)) {
674
- RESTSerializer.reopen({
675
- warnMessageNoModelForKey(prop, typeKey) {
676
- return 'Encountered "' + prop + '" in payload, but no model was found for model name "' + typeKey + '" (resolved model name using ' + this.constructor.toString() + '.modelNameFromPayloadKey("' + prop + '"))';
677
- }
678
- });
679
- }
680
- export { RESTSerializer as default };