ember-data-source 2.1.0.beta.2 → 2.1.0.beta.3

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.
data/dist/ember-data.js CHANGED
@@ -340,10 +340,7 @@
340
340
  */
341
341
 
342
342
  function ember$data$lib$adapters$errors$$InvalidError(errors) {
343
- if (!Ember.isArray(errors)) {
344
- Ember.deprecate('`InvalidError` expects json-api formatted errors.', false, { id: 'ds.errors.invalid-error-expects-json-api-format', until: '2.0.0' });
345
- errors = ember$data$lib$adapters$errors$$errorsHashToArray(errors);
346
- }
343
+ Ember.assert('`InvalidError` expects json-api formatted errors array.', Ember.isArray(errors || []));
347
344
  ember$data$lib$adapters$errors$$AdapterError.call(this, errors, 'The adapter rejected the commit because it was invalid');
348
345
  }
349
346
 
@@ -953,6 +950,12 @@
953
950
  }
954
951
  ```
955
952
 
953
+ Note that the object root can be pluralized for both a single-object response
954
+ and an array response: the REST adapter is not strict on this. Further, if the
955
+ HTTP server responds to a `GET` request to `/posts/1` (e.g. the response to a
956
+ `findRecord` query) with more than one object in the array, Ember Data will
957
+ only display the object with the matching ID.
958
+
956
959
  ### Conventional Names
957
960
 
958
961
  Attribute names in your JSON payload should be the camelCased versions of
@@ -1227,8 +1230,7 @@
1227
1230
  of the records for a given type.
1228
1231
  The `findAll` method makes an Ajax (HTTP GET) request to a URL computed by `buildURL`, and returns a
1229
1232
  promise for the resulting payload.
1230
- @private
1231
- @method findAll
1233
+ @method findAll
1232
1234
  @param {DS.Store} store
1233
1235
  @param {DS.Model} type
1234
1236
  @param {String} sinceToken
@@ -1254,8 +1256,7 @@
1254
1256
  payload.
1255
1257
  The `query` argument is a simple JavaScript object that will be passed directly
1256
1258
  to the server as parameters.
1257
- @private
1258
- @method query
1259
+ @method query
1259
1260
  @param {DS.Store} store
1260
1261
  @param {DS.Model} type
1261
1262
  @param {Object} query
@@ -1279,8 +1280,7 @@
1279
1280
  payload.
1280
1281
  The `query` argument is a simple JavaScript object that will be passed directly
1281
1282
  to the server as parameters.
1282
- @private
1283
- @method queryRecord
1283
+ @method queryRecord
1284
1284
  @param {DS.Store} store
1285
1285
  @param {DS.Model} type
1286
1286
  @param {Object} query
@@ -1788,6 +1788,44 @@
1788
1788
  return hash;
1789
1789
  },
1790
1790
 
1791
+ /**
1792
+ By default the JSONAPIAdapter will send each find request coming from a `store.find`
1793
+ or from accessing a relationship separately to the server. If your server supports passing
1794
+ ids as a query string, you can set coalesceFindRequests to true to coalesce all find requests
1795
+ within a single runloop.
1796
+ For example, if you have an initial payload of:
1797
+ ```javascript
1798
+ {
1799
+ post: {
1800
+ id: 1,
1801
+ comments: [1, 2]
1802
+ }
1803
+ }
1804
+ ```
1805
+ By default calling `post.get('comments')` will trigger the following requests(assuming the
1806
+ comments haven't been loaded before):
1807
+ ```
1808
+ GET /comments/1
1809
+ GET /comments/2
1810
+ ```
1811
+ If you set coalesceFindRequests to `true` it will instead trigger the following request:
1812
+ ```
1813
+ GET /comments?filter[id]=1,2
1814
+ ```
1815
+ Setting coalesceFindRequests to `true` also works for `store.find` requests and `belongsTo`
1816
+ relationships accessed within the same runloop. If you set `coalesceFindRequests: true`
1817
+ ```javascript
1818
+ store.findRecord('comment', 1);
1819
+ store.findRecord('comment', 2);
1820
+ ```
1821
+ will also send a request to: `GET /comments?filter[id]=1,2`
1822
+ Note: Requests coalescing rely on URL building strategy. So if you override `buildURL` in your app
1823
+ `groupRecordsForFindMany` more likely should be overridden as well in order for coalescing to work.
1824
+ @property coalesceFindRequests
1825
+ @type {boolean}
1826
+ */
1827
+ coalesceFindRequests: false,
1828
+
1791
1829
  /**
1792
1830
  @method findMany
1793
1831
  @param {DS.Store} store
@@ -1833,7 +1871,7 @@
1833
1871
  });
1834
1872
 
1835
1873
  var ember$data$lib$core$$DS = Ember.Namespace.create({
1836
- VERSION: '2.1.0-beta.2'
1874
+ VERSION: '2.1.0-beta.3'
1837
1875
  });
1838
1876
 
1839
1877
  if (Ember.libraries) {
@@ -1846,6 +1884,28 @@
1846
1884
  Ember.merge(Ember.FEATURES, ember$data$lib$core$$EMBER_DATA_FEATURES);
1847
1885
 
1848
1886
  var ember$data$lib$core$$default = ember$data$lib$core$$DS;
1887
+ var ember$data$lib$system$normalize$link$$default = ember$data$lib$system$normalize$link$$_normalizeLink;
1888
+ /**
1889
+ This method normalizes a link to an "links object". If the passed link is
1890
+ already an object it's returned without any modifications.
1891
+
1892
+ See http://jsonapi.org/format/#document-links for more information.
1893
+
1894
+ @method _normalizeLink
1895
+ @private
1896
+ @param {String} link
1897
+ @return {Object|null}
1898
+ @for DS
1899
+ */
1900
+ function ember$data$lib$system$normalize$link$$_normalizeLink(link) {
1901
+ switch (typeof link) {
1902
+ case 'object':
1903
+ return link;
1904
+ case 'string':
1905
+ return { href: link };
1906
+ }
1907
+ return null;
1908
+ }
1849
1909
  var ember$data$lib$system$normalize$model$name$$default = ember$data$lib$system$normalize$model$name$$normalizeModelName;
1850
1910
  /**
1851
1911
  All modelNames are dasherized internally. Changing this function may
@@ -3115,7 +3175,7 @@
3115
3175
 
3116
3176
  var ember$data$lib$system$store$serializer$response$$get = Ember.get;
3117
3177
 
3118
- /**
3178
+ /*
3119
3179
  This is a helper method that validates a JSON API top-level document
3120
3180
 
3121
3181
  The format of a document is described here:
@@ -3173,7 +3233,7 @@
3173
3233
  return errors;
3174
3234
  }
3175
3235
 
3176
- /**
3236
+ /*
3177
3237
  This is a helper method that always returns a JSON-API Document.
3178
3238
 
3179
3239
  @method normalizeResponseHelper
@@ -3201,7 +3261,7 @@
3201
3261
  return normalizedResponse;
3202
3262
  }
3203
3263
 
3204
- /**
3264
+ /*
3205
3265
  Convert the payload from `serializer.extract` to a JSON-API Document.
3206
3266
 
3207
3267
  @method _normalizeSerializerPayload
@@ -3227,7 +3287,7 @@
3227
3287
  return { data: data };
3228
3288
  }
3229
3289
 
3230
- /**
3290
+ /*
3231
3291
  Convert the payload representing a single record from `serializer.extract` to
3232
3292
  a JSON-API Resource Object.
3233
3293
 
@@ -3313,7 +3373,7 @@
3313
3373
  return { id: '' + value, type: relationshipMeta.type };
3314
3374
  }
3315
3375
 
3316
- /**
3376
+ /*
3317
3377
  This method converts a JSON-API Resource Object to a format that DS.Store
3318
3378
  understands.
3319
3379
 
@@ -5133,6 +5193,7 @@
5133
5193
  this.linkPromise = null;
5134
5194
  this.meta = null;
5135
5195
  this.hasData = false;
5196
+ this.hasLoaded = false;
5136
5197
  }
5137
5198
 
5138
5199
  ember$data$lib$system$relationships$state$relationship$$Relationship.prototype = {
@@ -5317,6 +5378,7 @@
5317
5378
  if (link !== this.link) {
5318
5379
  this.link = link;
5319
5380
  this.linkPromise = null;
5381
+ this.setHasLoaded(false);
5320
5382
  this.record.notifyPropertyChange(this.key);
5321
5383
  }
5322
5384
  },
@@ -5338,13 +5400,35 @@
5338
5400
  //TODO Once we have adapter support, we need to handle updated and canonical changes
5339
5401
  this.computeChanges(records);
5340
5402
  this.setHasData(true);
5403
+ this.setHasLoaded(true);
5341
5404
  },
5342
5405
 
5343
5406
  notifyRecordRelationshipAdded: Ember.K,
5344
5407
  notifyRecordRelationshipRemoved: Ember.K,
5345
5408
 
5409
+ /*
5410
+ `hasData` for a relationship is a flag to indicate if we consider the
5411
+ content of this relationship "known". Snapshots uses this to tell the
5412
+ difference between unknown (`undefined`) or empty (`null`). The reason for
5413
+ this is that we wouldn't want to serialize unknown relationships as `null`
5414
+ as that might overwrite remote state.
5415
+ All relationships for a newly created (`store.createRecord()`) are
5416
+ considered known (`hasData === true`).
5417
+ */
5346
5418
  setHasData: function (value) {
5347
5419
  this.hasData = value;
5420
+ },
5421
+
5422
+ /*
5423
+ `hasLoaded` is a flag to indicate if we have gotten data from the adapter or
5424
+ not when the relationship has a link.
5425
+ This is used to be able to tell when to fetch the link and when to return
5426
+ the local data in scenarios where the local state is considered known
5427
+ (`hasData === true`).
5428
+ Updating the link will automatically set `hasLoaded` to `false`.
5429
+ */
5430
+ setHasLoaded: function (value) {
5431
+ this.hasLoaded = value;
5348
5432
  }
5349
5433
  };
5350
5434
 
@@ -5791,9 +5875,13 @@
5791
5875
  if (this.isAsync) {
5792
5876
  var promise;
5793
5877
  if (this.link) {
5794
- promise = this.findLink().then(function () {
5795
- return _this3.findRecords();
5796
- });
5878
+ if (this.hasLoaded) {
5879
+ promise = this.findRecords();
5880
+ } else {
5881
+ promise = this.findLink().then(function () {
5882
+ return _this3.findRecords();
5883
+ });
5884
+ }
5797
5885
  } else {
5798
5886
  promise = this.findRecords();
5799
5887
  }
@@ -5843,6 +5931,7 @@
5843
5931
  this.removeRecord(this.inverseRecord);
5844
5932
  }
5845
5933
  this.setHasData(true);
5934
+ this.setHasLoaded(true);
5846
5935
  };
5847
5936
 
5848
5937
  ember$data$lib$system$relationships$state$belongs$to$$BelongsToRelationship.prototype.setCanonicalRecord = function (newRecord) {
@@ -5852,6 +5941,7 @@
5852
5941
  this.removeCanonicalRecord(this.inverseRecord);
5853
5942
  }
5854
5943
  this.setHasData(true);
5944
+ this.setHasLoaded(true);
5855
5945
  };
5856
5946
 
5857
5947
  ember$data$lib$system$relationships$state$belongs$to$$BelongsToRelationship.prototype._super$addCanonicalRecord = ember$data$lib$system$relationships$state$relationship$$default.prototype.addCanonicalRecord;
@@ -5948,9 +6038,13 @@
5948
6038
  if (this.isAsync) {
5949
6039
  var promise;
5950
6040
  if (this.link) {
5951
- promise = this.findLink().then(function () {
5952
- return _this2.findRecord();
5953
- });
6041
+ if (this.hasLoaded) {
6042
+ promise = this.findRecord();
6043
+ } else {
6044
+ promise = this.findLink().then(function () {
6045
+ return _this2.findRecord();
6046
+ });
6047
+ }
5954
6048
  } else {
5955
6049
  promise = this.findRecord();
5956
6050
  }
@@ -7143,10 +7237,10 @@
7143
7237
  automatically created by their `Ember.Application`.
7144
7238
 
7145
7239
  You can retrieve models from the store in several ways. To retrieve a record
7146
- for a specific id, use `DS.Store`'s `find()` method:
7240
+ for a specific id, use `DS.Store`'s `findRecord()` method:
7147
7241
 
7148
7242
  ```javascript
7149
- store.find('person', 123).then(function (person) {
7243
+ store.findRecord('person', 123).then(function (person) {
7150
7244
  });
7151
7245
  ```
7152
7246
 
@@ -8083,11 +8177,7 @@
8083
8177
  Ember.assert('Passing classes to store methods has been removed. Please pass a dasherized string instead of ' + Ember.inspect(modelName), typeof modelName === 'string');
8084
8178
 
8085
8179
  if (!Ember.ENV.ENABLE_DS_FILTER) {
8086
- Ember.deprecate('The filter API will be moved into a plugin soon. To enable store.filter using an environment flag, or to use an alternative, you can visit the ember-data-filter addon page', false, {
8087
- url: 'https://github.com/ember-data/ember-data-filter',
8088
- id: 'ds.store.filter-deprecated',
8089
- until: '2.0.0'
8090
- });
8180
+ Ember.assert('The filter API has been moved to a plugin. To enable store.filter using an environment flag, or to use an alternative, you can visit the ember-data-filter addon page. https://github.com/ember-data/ember-data-filter', false);
8091
8181
  }
8092
8182
 
8093
8183
  var promise;
@@ -8579,9 +8669,6 @@
8579
8669
  serializer (the application serializer if it exists).
8580
8670
  Alternatively, `pushPayload` will accept a model type which
8581
8671
  will determine which serializer will process the payload.
8582
- However, the serializer itself (processing this data via
8583
- `normalizePayload`) will not know which model it is
8584
- deserializing.
8585
8672
  ```app/serializers/application.js
8586
8673
  import DS from 'ember-data';
8587
8674
  export default DS.ActiveModelSerializer;
@@ -8721,15 +8808,9 @@
8721
8808
  @param {String} modelName
8722
8809
  @return DS.Adapter
8723
8810
  */
8724
- adapterFor: function (modelOrClass) {
8725
- var modelName;
8811
+ adapterFor: function (modelName) {
8726
8812
 
8727
- if (typeof modelOrClass === 'string') {
8728
- modelName = modelOrClass;
8729
- } else {
8730
- Ember.deprecate("Passing classes to store methods has been removed. Please pass a dasherized string instead of " + Ember.inspect(modelName), false, { id: 'ds.store.passing-classes-deprecated', until: '2.0.0' });
8731
- modelName = modelOrClass.modelName;
8732
- }
8813
+ Ember.assert("Passing classes to store.adapterFor has been removed. Please pass a dasherized string instead of " + Ember.inspect(modelName), typeof modelName === 'string');
8733
8814
 
8734
8815
  return this.lookupAdapter(modelName);
8735
8816
  },
@@ -8759,15 +8840,9 @@
8759
8840
  @param {String} modelName the record to serialize
8760
8841
  @return {DS.Serializer}
8761
8842
  */
8762
- serializerFor: function (modelOrClass) {
8763
- var modelName;
8843
+ serializerFor: function (modelName) {
8764
8844
 
8765
- if (typeof modelOrClass === 'string') {
8766
- modelName = modelOrClass;
8767
- } else {
8768
- Ember.deprecate("Passing classes to store methods has been removed. Please pass a dasherized string instead of " + Ember.inspect(modelName), false, { id: 'ds.store.passing-classes-deprecated', until: '2.0.0' });
8769
- modelName = modelOrClass.modelName;
8770
- }
8845
+ Ember.assert("Passing classes to store.serializerFor has been removed. Please pass a dasherized string instead of " + Ember.inspect(modelName), typeof modelName === 'string');
8771
8846
 
8772
8847
  var fallbacks = ['application', this.adapterFor(modelName).get('defaultSerializer'), '-default'];
8773
8848
 
@@ -8926,8 +9001,11 @@
8926
9001
  var relationship;
8927
9002
 
8928
9003
  if (data.relationships[key].links && data.relationships[key].links.related) {
8929
- relationship = record._relationships.get(key);
8930
- relationship.updateLink(data.relationships[key].links.related);
9004
+ var relatedLink = ember$data$lib$system$normalize$link$$default(data.relationships[key].links.related);
9005
+ if (relatedLink && relatedLink.href) {
9006
+ relationship = record._relationships.get(key);
9007
+ relationship.updateLink(relatedLink.href);
9008
+ }
8931
9009
  }
8932
9010
 
8933
9011
  if (data.relationships[key].meta) {
@@ -9582,7 +9660,7 @@
9582
9660
  if (relationshipMeta.kind === 'belongsTo') {
9583
9661
  data = _this4.extractRelationship(relationshipMeta.type, relationshipHash);
9584
9662
  } else if (relationshipMeta.kind === 'hasMany') {
9585
- data = relationshipHash.map(function (item) {
9663
+ data = Ember.isNone(relationshipHash) ? null : relationshipHash.map(function (item) {
9586
9664
  return _this4.extractRelationship(relationshipMeta.type, item);
9587
9665
  });
9588
9666
  }
@@ -9613,28 +9691,6 @@
9613
9691
  return ember$data$lib$system$normalize$model$name$$default(key);
9614
9692
  },
9615
9693
 
9616
- /**
9617
- You can use this method to normalize all payloads, regardless of whether they
9618
- represent single records or an array.
9619
- For example, you might want to remove some extraneous data from the payload:
9620
- ```app/serializers/application.js
9621
- import DS from 'ember-data';
9622
- export default DS.JSONSerializer.extend({
9623
- normalizePayload: function(payload) {
9624
- delete payload.version;
9625
- delete payload.status;
9626
- return payload;
9627
- }
9628
- });
9629
- ```
9630
- @method normalizePayload
9631
- @param {Object} payload
9632
- @return {Object} the normalized payload
9633
- */
9634
- normalizePayload: function (payload) {
9635
- return payload;
9636
- },
9637
-
9638
9694
  /**
9639
9695
  @method normalizeAttributes
9640
9696
  @private
@@ -10078,16 +10134,18 @@
10078
10134
  var key = relationship.key;
10079
10135
 
10080
10136
  if (this._shouldSerializeHasMany(snapshot, key, relationship)) {
10081
- var payloadKey;
10137
+ var hasMany = snapshot.hasMany(key, { ids: true });
10138
+ if (hasMany !== undefined) {
10139
+ // if provided, use the mapping provided by `attrs` in
10140
+ // the serializer
10141
+ var payloadKey = this._getMappedKey(key);
10142
+ if (payloadKey === key && this.keyForRelationship) {
10143
+ payloadKey = this.keyForRelationship(key, "hasMany", "serialize");
10144
+ }
10082
10145
 
10083
- // if provided, use the mapping provided by `attrs` in
10084
- // the serializer
10085
- payloadKey = this._getMappedKey(key);
10086
- if (payloadKey === key && this.keyForRelationship) {
10087
- payloadKey = this.keyForRelationship(key, "hasMany", "serialize");
10146
+ json[payloadKey] = hasMany;
10147
+ // TODO support for polymorphic manyToNone and manyToMany relationships
10088
10148
  }
10089
- json[payloadKey] = snapshot.hasMany(key, { ids: true });
10090
- // TODO support for polymorphic manyToNone and manyToMany relationships
10091
10149
  }
10092
10150
  },
10093
10151
 
@@ -10588,7 +10646,93 @@
10588
10646
 
10589
10647
  var ember$data$lib$serializers$json$api$serializer$$dasherize = Ember.String.dasherize;
10590
10648
 
10591
- var ember$data$lib$serializers$json$api$serializer$$default = ember$data$lib$serializers$json$serializer$$default.extend({
10649
+ /**
10650
+ Ember Data 2.0 Serializer:
10651
+
10652
+ In Ember Data a Serializer is used to serialize and deserialize
10653
+ records when they are transferred in and out of an external source.
10654
+ This process involves normalizing property names, transforming
10655
+ attribute values and serializing relationships.
10656
+
10657
+ `JSONAPISerializer` supports the http://jsonapi.org/ spec and is the
10658
+ serializer recommended by Ember Data.
10659
+
10660
+ This serializer normalizes a JSON API payload that looks like:
10661
+
10662
+ ```js
10663
+
10664
+ // models/player.js
10665
+ import DS from "ember-data";
10666
+
10667
+ export default DS.Model.extend({
10668
+ name: DS.attr(),
10669
+ skill: DS.attr(),
10670
+ gamesPlayed: DS.attr(),
10671
+ club: DS.belongsTo('club')
10672
+ });
10673
+
10674
+ // models/club.js
10675
+ import DS from "ember-data";
10676
+
10677
+ export default DS.Model.extend({
10678
+ name: DS.attr(),
10679
+ location: DS.attr(),
10680
+ players: DS.hasMany('player')
10681
+ });
10682
+ ```
10683
+
10684
+ ```js
10685
+
10686
+ {
10687
+ "data": [
10688
+ {
10689
+ "attributes": {
10690
+ "name": "Benfica",
10691
+ "location": "Portugal"
10692
+ },
10693
+ "id": "1",
10694
+ "relationships": {
10695
+ "players": {
10696
+ "data": [
10697
+ {
10698
+ "id": "3",
10699
+ "type": "players"
10700
+ }
10701
+ ]
10702
+ }
10703
+ },
10704
+ "type": "clubs"
10705
+ }
10706
+ ],
10707
+ "included": [
10708
+ {
10709
+ "attributes": {
10710
+ "name": "Eusebio Silva Ferreira",
10711
+ "skill": "Rocket shot",
10712
+ "games-played": 431
10713
+ },
10714
+ "id": "3",
10715
+ "relationships": {
10716
+ "club": {
10717
+ "data": {
10718
+ "id": "1",
10719
+ "type": "clubs"
10720
+ }
10721
+ }
10722
+ },
10723
+ "type": "players"
10724
+ }
10725
+ ]
10726
+ }
10727
+ ```
10728
+
10729
+ to the format that the Ember Data store expects.
10730
+
10731
+ @class JSONAPISerializer
10732
+ @namespace DS
10733
+ @extends DS.JSONSerializer
10734
+ */
10735
+ var ember$data$lib$serializers$json$api$serializer$$JSONAPISerializer = ember$data$lib$serializers$json$serializer$$default.extend({
10592
10736
 
10593
10737
  /**
10594
10738
  @method _normalizeDocumentHelper
@@ -10631,6 +10775,14 @@
10631
10775
  */
10632
10776
  _normalizeResourceHelper: function (resourceHash) {
10633
10777
  var modelName = this.modelNameFromPayloadKey(resourceHash.type);
10778
+
10779
+ if (!this.store._hasModelFor(modelName)) {
10780
+ Ember.warn(this.warnMessageNoModelForType(modelName, resourceHash.type), false, {
10781
+ id: 'ds.serializer.model-for-type-missing'
10782
+ });
10783
+ return null;
10784
+ }
10785
+
10634
10786
  var modelClass = this.store.modelFor(modelName);
10635
10787
  var serializer = this.store.serializerFor(modelName);
10636
10788
 
@@ -10942,6 +11094,16 @@
10942
11094
  }
10943
11095
  });
10944
11096
 
11097
+ Ember.runInDebug(function () {
11098
+ ember$data$lib$serializers$json$api$serializer$$JSONAPISerializer.reopen({
11099
+ warnMessageNoModelForType: function (modelName, originalType) {
11100
+ return 'Encountered a resource object with type "' + originalType + '", but no model was found for model name "' + modelName + '" (resolved model name using ' + this.constructor.toString() + '.modelNameFromPayloadKey("' + originalType + '"))';
11101
+ }
11102
+ });
11103
+ });
11104
+
11105
+ var ember$data$lib$serializers$json$api$serializer$$default = ember$data$lib$serializers$json$api$serializer$$JSONAPISerializer;
11106
+
10945
11107
  var ember$data$lib$serializers$rest$serializer$$camelize = Ember.String.camelize;
10946
11108
 
10947
11109
  /**