@ember-data/serializer 5.5.0-alpha.9 → 5.5.0

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