ember-data-source 1.13.7 → 1.13.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 23a24ca3a6f2edbabf4f58560597978f91a19c48
4
- data.tar.gz: 5dbf0be7c78fa4ba9244c7322eaef91d41fc3608
3
+ metadata.gz: 0719f6e05a5484e818ba9d779d3a78b1af0f5a73
4
+ data.tar.gz: 7e5572c7be9e921fa87080a74e95f5cc5a8a5649
5
5
  SHA512:
6
- metadata.gz: b0a8544b1dac75e7b5d6dc0ee284ed7d04ea42bd01cf3bdb575c1df8cecc9a6df69d372be0f50d8cca358b1d1dc8f456bfb5e960baa55695bdfed0a4ed4b0826
7
- data.tar.gz: a5d6639da554b718b147071e807bf9ffd175d7197b1b8d7a0638b2460052cc301af35e34a6cdf039f363ca0143ee9c2ab896f9f5a41060908c115babcd899882
6
+ metadata.gz: 0f5f790ef12949fb835f4bf5ff8b5f3b170564499e572283f542e5a75b286fd2e5ca80a8ac390dc1df23d6732859ca3bf4171ef127f16cd0a7fa1cc0b19209ef
7
+ data.tar.gz: 71feae780572611a1940e397efa55fc7dc66c9b49989b9d79602bc38a64c8990bf84750498dc491ccf36d692ac297de0b609fec460f2c92868734e5b51365975
@@ -19806,6 +19806,205 @@ define(
19806
19806
  );
19807
19807
 
19808
19808
 
19809
+ define(
19810
+ "ember-data/tests/integration/store/json-api-validation-test",
19811
+ ["exports"],
19812
+ function(__exports__) {
19813
+ "use strict";
19814
+
19815
+ function __es6_export__(name, value) {
19816
+ __exports__[name] = value;
19817
+ }
19818
+
19819
+ var Person, store, env;
19820
+ var run = Ember.run;
19821
+
19822
+ module('integration/store/json-validation', {
19823
+ setup: function () {
19824
+ Person = DS.Model.extend({
19825
+ updatedAt: DS.attr('string'),
19826
+ name: DS.attr('string'),
19827
+ firstName: DS.attr('string'),
19828
+ lastName: DS.attr('string')
19829
+ });
19830
+
19831
+ env = setupStore({
19832
+ person: Person
19833
+ });
19834
+ store = env.store;
19835
+ },
19836
+
19837
+ teardown: function () {
19838
+ run(store, 'destroy');
19839
+ }
19840
+ });
19841
+
19842
+ test('when normalizeResponse returns undefined (or doesn\'t return), throws an error', function () {
19843
+
19844
+ env.registry.register('serializer:person', DS.Serializer.extend({
19845
+ isNewSerializerAPI: true,
19846
+ normalizeResponse: function () {}
19847
+ }));
19848
+
19849
+ env.registry.register('adapter:person', DS.Adapter.extend({
19850
+ findRecord: function () {
19851
+ return Ember.RSVP.resolve({});
19852
+ }
19853
+ }));
19854
+
19855
+ throws(function () {
19856
+ run(function () {
19857
+ store.find('person', 1);
19858
+ });
19859
+ }, /Top level of a JSON API document must be an object/);
19860
+ });
19861
+
19862
+ test('when normalizeResponse returns null, throws an error', function () {
19863
+
19864
+ env.registry.register('serializer:person', DS.Serializer.extend({
19865
+ isNewSerializerAPI: true,
19866
+ normalizeResponse: function () {
19867
+ return null;
19868
+ }
19869
+ }));
19870
+
19871
+ env.registry.register('adapter:person', DS.Adapter.extend({
19872
+ findRecord: function () {
19873
+ return Ember.RSVP.resolve({});
19874
+ }
19875
+ }));
19876
+
19877
+ throws(function () {
19878
+ run(function () {
19879
+ store.find('person', 1);
19880
+ });
19881
+ }, /Top level of a JSON API document must be an object/);
19882
+ });
19883
+
19884
+ test('when normalizeResponse returns an empty object, throws an error', function () {
19885
+
19886
+ env.registry.register('serializer:person', DS.Serializer.extend({
19887
+ isNewSerializerAPI: true,
19888
+ normalizeResponse: function () {
19889
+ return {};
19890
+ }
19891
+ }));
19892
+
19893
+ env.registry.register('adapter:person', DS.Adapter.extend({
19894
+ findRecord: function () {
19895
+ return Ember.RSVP.resolve({});
19896
+ }
19897
+ }));
19898
+
19899
+ throws(function () {
19900
+ run(function () {
19901
+ store.find('person', 1);
19902
+ });
19903
+ }, /One or more of the following keys must be present/);
19904
+ });
19905
+
19906
+ test('when normalizeResponse returns a document with both data and errors, throws an error', function () {
19907
+
19908
+ env.registry.register('serializer:person', DS.Serializer.extend({
19909
+ isNewSerializerAPI: true,
19910
+ normalizeResponse: function () {
19911
+ return {
19912
+ data: [],
19913
+ errors: []
19914
+ };
19915
+ }
19916
+ }));
19917
+
19918
+ env.registry.register('adapter:person', DS.Adapter.extend({
19919
+ findRecord: function () {
19920
+ return Ember.RSVP.resolve({});
19921
+ }
19922
+ }));
19923
+
19924
+ throws(function () {
19925
+ run(function () {
19926
+ store.find('person', 1);
19927
+ });
19928
+ }, /cannot both be present/);
19929
+ });
19930
+
19931
+ function testPayloadError(payload, expectedError) {
19932
+ env.registry.register('serializer:person', DS.Serializer.extend({
19933
+ isNewSerializerAPI: true,
19934
+ normalizeResponse: function (store, type, pld) {
19935
+ return pld;
19936
+ }
19937
+ }));
19938
+ env.registry.register('adapter:person', DS.Adapter.extend({
19939
+ findRecord: function () {
19940
+ return Ember.RSVP.resolve(payload);
19941
+ }
19942
+ }));
19943
+ throws(function () {
19944
+ run(function () {
19945
+ store.find('person', 1);
19946
+ });
19947
+ }, expectedError, 'Payload ' + JSON.stringify(payload) + ' should throw error ' + expectedError);
19948
+ env.registry.unregister('serializer:person');
19949
+ env.registry.unregister('adapter:person');
19950
+ }
19951
+
19952
+ test('normalizeResponse \'data\' cannot be undefined, a number, a string or a boolean', function () {
19953
+
19954
+ testPayloadError({ data: undefined }, /data must be/);
19955
+ testPayloadError({ data: 1 }, /data must be/);
19956
+ testPayloadError({ data: 'lollerskates' }, /data must be/);
19957
+ testPayloadError({ data: true }, /data must be/);
19958
+ });
19959
+
19960
+ test('normalizeResponse \'meta\' cannot be an array, undefined, a number, a string or a boolean', function () {
19961
+
19962
+ testPayloadError({ meta: undefined }, /meta must be an object/);
19963
+ testPayloadError({ meta: [] }, /meta must be an object/);
19964
+ testPayloadError({ meta: 1 }, /meta must be an object/);
19965
+ testPayloadError({ meta: 'lollerskates' }, /meta must be an object/);
19966
+ testPayloadError({ meta: true }, /meta must be an object/);
19967
+ });
19968
+
19969
+ test('normalizeResponse \'links\' cannot be an array, undefined, a number, a string or a boolean', function () {
19970
+
19971
+ testPayloadError({ data: [], links: undefined }, /links must be an object/);
19972
+ testPayloadError({ data: [], links: [] }, /links must be an object/);
19973
+ testPayloadError({ data: [], links: 1 }, /links must be an object/);
19974
+ testPayloadError({ data: [], links: 'lollerskates' }, /links must be an object/);
19975
+ testPayloadError({ data: [], links: true }, /links must be an object/);
19976
+ });
19977
+
19978
+ test('normalizeResponse \'jsonapi\' cannot be an array, undefined, a number, a string or a boolean', function () {
19979
+
19980
+ testPayloadError({ data: [], jsonapi: undefined }, /jsonapi must be an object/);
19981
+ testPayloadError({ data: [], jsonapi: [] }, /jsonapi must be an object/);
19982
+ testPayloadError({ data: [], jsonapi: 1 }, /jsonapi must be an object/);
19983
+ testPayloadError({ data: [], jsonapi: 'lollerskates' }, /jsonapi must be an object/);
19984
+ testPayloadError({ data: [], jsonapi: true }, /jsonapi must be an object/);
19985
+ });
19986
+
19987
+ test('normalizeResponse \'included\' cannot be an object, undefined, a number, a string or a boolean', function () {
19988
+
19989
+ testPayloadError({ included: undefined }, /included must be an array/);
19990
+ testPayloadError({ included: {} }, /included must be an array/);
19991
+ testPayloadError({ included: 1 }, /included must be an array/);
19992
+ testPayloadError({ included: 'lollerskates' }, /included must be an array/);
19993
+ testPayloadError({ included: true }, /included must be an array/);
19994
+ });
19995
+
19996
+ test('normalizeResponse \'errors\' cannot be an object, undefined, a number, a string or a boolean', function () {
19997
+
19998
+ testPayloadError({ errors: undefined }, /errors must be an array/);
19999
+ testPayloadError({ errors: {} }, /errors must be an array/);
20000
+ testPayloadError({ errors: 1 }, /errors must be an array/);
20001
+ testPayloadError({ errors: 'lollerskates' }, /errors must be an array/);
20002
+ testPayloadError({ errors: true }, /errors must be an array/);
20003
+ });
20004
+ }
20005
+ );
20006
+
20007
+
19809
20008
  define(
19810
20009
  "ember-data/tests/integration/store/query-record-test",
19811
20010
  ["exports"],
@@ -20152,6 +20351,18 @@ define(
20152
20351
  equal(adapter.buildURL('super-user', null, null, 'query', queryStub), '/superUsers');
20153
20352
  });
20154
20353
 
20354
+ test('buildURL - queryRecord requestType delegates to urlForQueryRecord', function () {
20355
+ expect(3);
20356
+ var originalMethod = adapter.urlForQueryRecord;
20357
+ var queryStub = { companyId: 10 };
20358
+ adapter.urlForQueryRecord = function (query, type) {
20359
+ equal(query, queryStub);
20360
+ equal(type, 'super-user');
20361
+ return originalMethod.apply(this, arguments);
20362
+ };
20363
+ equal(adapter.buildURL('super-user', null, null, 'queryRecord', queryStub), '/superUsers');
20364
+ });
20365
+
20155
20366
  test('buildURL - findMany requestType delegates to urlForFindMany', function () {
20156
20367
  expect(3);
20157
20368
  var originalMethod = adapter.urlForFindMany;
@@ -24288,6 +24499,121 @@ define(
24288
24499
  });
24289
24500
  ok(promise.then && typeof promise.then === "function", "#update returns a promise");
24290
24501
  });
24502
+
24503
+ test("filterBy - returns a filtered subset", function () {
24504
+ var store = createStore({
24505
+ person: Person
24506
+ });
24507
+
24508
+ run(function () {
24509
+ store.push({ data: [{
24510
+ id: "1",
24511
+ type: "person",
24512
+ attributes: {
24513
+ name: "Tom"
24514
+ }
24515
+ }, {
24516
+ id: "2",
24517
+ type: "person",
24518
+ attributes: {
24519
+ name: "Yehuda"
24520
+ }
24521
+ }, {
24522
+ id: "2",
24523
+ type: "person",
24524
+ attributes: {
24525
+ name: "Yehuda"
24526
+ }
24527
+ }] });
24528
+ });
24529
+
24530
+ var all = store.peekAll("person");
24531
+ var toms = all.filterBy("name", "Tom");
24532
+ equal(toms.get("length"), 1);
24533
+ deepEqual(toms.getEach("id"), ["1"]);
24534
+
24535
+ // a new record is added if filter matches
24536
+ run(function () {
24537
+ store.push({ data: { type: "person", id: "4", attributes: { name: "Tom" } } });
24538
+ });
24539
+ equal(toms.get("length"), 2);
24540
+ deepEqual(toms.getEach("id"), ["1", "4"]);
24541
+
24542
+ // a new record is not added if filter doesn't match
24543
+ run(function () {
24544
+ store.push({ data: { type: "person", id: "5", attributes: { name: "Igor" } } });
24545
+ });
24546
+ equal(toms.get("length"), 2);
24547
+ deepEqual(toms.getEach("id"), ["1", "4"]);
24548
+
24549
+ // changing the filtered value remvoves the record from the list
24550
+ run(function () {
24551
+ // we are using a private method here to get the record immediatly
24552
+ store.recordForId("person", "1").set("name", "Thomas");
24553
+ });
24554
+ equal(toms.get("length"), 1);
24555
+ deepEqual(toms.getEach("id"), ["4"]);
24556
+
24557
+ // change value back to original
24558
+ run(function () {
24559
+ store.recordForId("person", "1").set("name", "Tom");
24560
+ });
24561
+ equal(toms.get("length"), 2);
24562
+ deepEqual(toms.getEach("id"), ["1", "4"]);
24563
+ });
24564
+
24565
+ test("filterBy - value is optional", function () {
24566
+ var store = createStore({
24567
+ person: Person
24568
+ });
24569
+
24570
+ run(function () {
24571
+ store.push({ data: [{
24572
+ id: "1",
24573
+ type: "person",
24574
+ attributes: {
24575
+ name: "Tom"
24576
+ }
24577
+ }, {
24578
+ id: "2",
24579
+ type: "person"
24580
+ }] });
24581
+ });
24582
+
24583
+ var all = store.peekAll("person");
24584
+ var allWithNames = all.filterBy("name");
24585
+ equal(allWithNames.get("length"), 1);
24586
+ deepEqual(allWithNames.getEach("id"), ["1"]);
24587
+
24588
+ // a new record is added if filter matches
24589
+ run(function () {
24590
+ store.push({ data: { type: "person", id: "3", attributes: { name: "Igor" } } });
24591
+ });
24592
+ equal(allWithNames.get("length"), 2);
24593
+ deepEqual(allWithNames.getEach("id"), ["1", "3"]);
24594
+
24595
+ // a new record is not added if filter doesn't match
24596
+ run(function () {
24597
+ store.push({ data: { type: "person", id: "4" } });
24598
+ });
24599
+ equal(allWithNames.get("length"), 2);
24600
+ deepEqual(allWithNames.getEach("id"), ["1", "3"]);
24601
+
24602
+ // changing the filtered value remvoves the record from the list
24603
+ run(function () {
24604
+ // we are using a private method here to get the record immediatly
24605
+ store.recordForId("person", "1").set("name", null);
24606
+ });
24607
+ equal(allWithNames.get("length"), 1);
24608
+ deepEqual(allWithNames.getEach("id"), ["3"]);
24609
+
24610
+ // change value back to original
24611
+ run(function () {
24612
+ store.recordForId("person", "1").set("name", "Tom");
24613
+ });
24614
+ equal(allWithNames.get("length"), 2);
24615
+ deepEqual(allWithNames.getEach("id"), ["1", "3"]);
24616
+ });
24291
24617
  }
24292
24618
  );
24293
24619
 
@@ -27732,6 +28058,13 @@ test('ember-data/lib/system/record-arrays/filtered-record-array.js should pass j
27732
28058
  ok(true, 'ember-data/lib/system/record-arrays/filtered-record-array.js should pass jshint.');
27733
28059
  });
27734
28060
 
28061
+ }
28062
+ if (!QUnit.urlParams.nojshint) {
28063
+ module('JSHint - ember-data/lib/system/record-arrays');
28064
+ test('ember-data/lib/system/record-arrays/filtered-subset.js should pass jshint', function() {
28065
+ ok(true, 'ember-data/lib/system/record-arrays/filtered-subset.js should pass jshint.');
28066
+ });
28067
+
27735
28068
  }
27736
28069
  if (!QUnit.urlParams.nojshint) {
27737
28070
  module('JSHint - ember-data/lib/system/record-arrays');
@@ -28243,6 +28576,13 @@ test('ember-data/tests/integration/store-test.js should pass jshint', function()
28243
28576
  ok(true, 'ember-data/tests/integration/store-test.js should pass jshint.');
28244
28577
  });
28245
28578
 
28579
+ }
28580
+ if (!QUnit.urlParams.nojshint) {
28581
+ module('JSHint - ember-data/tests/integration/store');
28582
+ test('ember-data/tests/integration/store/json-api-validation-test.js should pass jshint', function() {
28583
+ ok(true, 'ember-data/tests/integration/store/json-api-validation-test.js should pass jshint.');
28584
+ });
28585
+
28246
28586
  }
28247
28587
  if (!QUnit.urlParams.nojshint) {
28248
28588
  module('JSHint - ember-data/tests/integration/store');
@@ -331,12 +331,14 @@
331
331
  to push the record into the store.
332
332
  Here is an example `queryRecord` implementation:
333
333
  Example
334
- ```javascript
335
- App.ApplicationAdapter = DS.Adapter.extend({
336
- queryRecord: function(store, typeClass, query) {
337
- var url = [type.typeKey, id].join('/');
334
+ ```app/adapters/application.js
335
+ import DS from 'ember-data';
336
+ import Ember from 'ember';
337
+ export default DS.Adapter.extend(DS.BuildURLMixin, {
338
+ queryRecord: function(store, type, query) {
339
+ var urlForQueryRecord = this.buildURL(type.modelName, null, null, 'queryRecord', query);
338
340
  return new Ember.RSVP.Promise(function(resolve, reject) {
339
- jQuery.getJSON(url, query).then(function(data) {
341
+ Ember.$.getJSON(urlForQueryRecord, query).then(function(data) {
340
342
  Ember.run(null, resolve, data);
341
343
  }, function(jqXHR) {
342
344
  jqXHR.then = null; // tame jQuery's ill mannered promises
@@ -350,7 +352,6 @@
350
352
  @param {DS.Store} store
351
353
  @param {subclass of DS.Model} type
352
354
  @param {Object} query
353
- @param {String} id
354
355
  @return {Promise} promise
355
356
  */
356
357
  queryRecord: null,
@@ -682,6 +683,8 @@
682
683
  return this.urlForFindQuery(query, modelName);
683
684
  case 'query':
684
685
  return this.urlForQuery(query, modelName);
686
+ case 'queryRecord':
687
+ return this.urlForQueryRecord(query, modelName);
685
688
  case 'findMany':
686
689
  return this.urlForFindMany(id, modelName, snapshot);
687
690
  case 'findHasMany':
@@ -735,7 +738,7 @@
735
738
  },
736
739
 
737
740
  /**
738
- * @method urlForFind
741
+ * @method urlForFindRecord
739
742
  * @param {String} id
740
743
  * @param {String} modelName
741
744
  * @param {DS.Snapshot} snapshot
@@ -797,6 +800,16 @@
797
800
  return this._buildURL(modelName);
798
801
  },
799
802
 
803
+ /**
804
+ * @method urlForQueryRecord
805
+ * @param {Object} query
806
+ * @param {String} modelName
807
+ * @return {String} url
808
+ */
809
+ urlForQueryRecord: function (query, modelName) {
810
+ return this._buildURL(modelName);
811
+ },
812
+
800
813
  /**
801
814
  * @method urlForFindMany
802
815
  * @param {Array} ids
@@ -2612,7 +2625,7 @@
2612
2625
  var ember$data$lib$serializers$json$serializer$$map = Ember.ArrayPolyfills.map;
2613
2626
  var ember$data$lib$serializers$json$serializer$$merge = Ember.merge;
2614
2627
 
2615
- /*
2628
+ /**
2616
2629
  Ember Data 2.0 Serializer:
2617
2630
 
2618
2631
  In Ember Data a Serializer is used to serialize and deserialize
@@ -2634,8 +2647,10 @@
2634
2647
  house: DS.belongsTo('location'),
2635
2648
  });
2636
2649
  ```
2650
+
2637
2651
  ```js
2638
- { id: 1,
2652
+ {
2653
+ id: 1,
2639
2654
  name: 'Sebastian',
2640
2655
  friends: [3, 4],
2641
2656
  links: {
@@ -2643,6 +2658,7 @@
2643
2658
  }
2644
2659
  }
2645
2660
  ```
2661
+
2646
2662
  to JSONApi format that the Ember Data store expects.
2647
2663
 
2648
2664
  You can customize how JSONSerializer processes it's payload by passing options in
@@ -2670,23 +2686,6 @@
2670
2686
  @namespace DS
2671
2687
  @extends DS.Serializer
2672
2688
  */
2673
-
2674
- /**
2675
- In Ember Data a Serializer is used to serialize and deserialize
2676
- records when they are transferred in and out of an external source.
2677
- This process involves normalizing property names, transforming
2678
- attribute values and serializing relationships.
2679
-
2680
- For maximum performance Ember Data recommends you use the
2681
- [RESTSerializer](DS.RESTSerializer.html) or one of its subclasses.
2682
-
2683
- `JSONSerializer` is useful for simpler or legacy backends that may
2684
- not support the http://jsonapi.org/ spec.
2685
-
2686
- @class JSONSerializer
2687
- @namespace DS
2688
- @extends DS.Serializer
2689
- */
2690
2689
  var ember$data$lib$serializers$json$serializer$$JSONSerializer = ember$data$lib$system$serializer$$default.extend({
2691
2690
 
2692
2691
  /**
@@ -2785,7 +2784,7 @@
2785
2784
  return data;
2786
2785
  },
2787
2786
 
2788
- /*
2787
+ /**
2789
2788
  The `normalizeResponse` method is used to normalize a payload from the
2790
2789
  server to a JSON-API Document.
2791
2790
  http://jsonapi.org/format/#document-structure
@@ -2837,7 +2836,7 @@
2837
2836
  }
2838
2837
  },
2839
2838
 
2840
- /*
2839
+ /**
2841
2840
  @method normalizeFindRecordResponse
2842
2841
  @param {DS.Store} store
2843
2842
  @param {DS.Model} primaryModelClass
@@ -2850,7 +2849,7 @@
2850
2849
  return this.normalizeSingleResponse.apply(this, arguments);
2851
2850
  },
2852
2851
 
2853
- /*
2852
+ /**
2854
2853
  @method normalizeQueryRecordResponse
2855
2854
  @param {DS.Store} store
2856
2855
  @param {DS.Model} primaryModelClass
@@ -2863,7 +2862,7 @@
2863
2862
  return this.normalizeSingleResponse.apply(this, arguments);
2864
2863
  },
2865
2864
 
2866
- /*
2865
+ /**
2867
2866
  @method normalizeFindAllResponse
2868
2867
  @param {DS.Store} store
2869
2868
  @param {DS.Model} primaryModelClass
@@ -2876,7 +2875,7 @@
2876
2875
  return this.normalizeArrayResponse.apply(this, arguments);
2877
2876
  },
2878
2877
 
2879
- /*
2878
+ /**
2880
2879
  @method normalizeFindBelongsToResponse
2881
2880
  @param {DS.Store} store
2882
2881
  @param {DS.Model} primaryModelClass
@@ -2889,7 +2888,7 @@
2889
2888
  return this.normalizeSingleResponse.apply(this, arguments);
2890
2889
  },
2891
2890
 
2892
- /*
2891
+ /**
2893
2892
  @method normalizeFindHasManyResponse
2894
2893
  @param {DS.Store} store
2895
2894
  @param {DS.Model} primaryModelClass
@@ -2902,7 +2901,7 @@
2902
2901
  return this.normalizeArrayResponse.apply(this, arguments);
2903
2902
  },
2904
2903
 
2905
- /*
2904
+ /**
2906
2905
  @method normalizeFindManyResponse
2907
2906
  @param {DS.Store} store
2908
2907
  @param {DS.Model} primaryModelClass
@@ -2915,7 +2914,7 @@
2915
2914
  return this.normalizeArrayResponse.apply(this, arguments);
2916
2915
  },
2917
2916
 
2918
- /*
2917
+ /**
2919
2918
  @method normalizeQueryResponse
2920
2919
  @param {DS.Store} store
2921
2920
  @param {DS.Model} primaryModelClass
@@ -2928,7 +2927,7 @@
2928
2927
  return this.normalizeArrayResponse.apply(this, arguments);
2929
2928
  },
2930
2929
 
2931
- /*
2930
+ /**
2932
2931
  @method normalizeCreateRecordResponse
2933
2932
  @param {DS.Store} store
2934
2933
  @param {DS.Model} primaryModelClass
@@ -2941,7 +2940,7 @@
2941
2940
  return this.normalizeSaveResponse.apply(this, arguments);
2942
2941
  },
2943
2942
 
2944
- /*
2943
+ /**
2945
2944
  @method normalizeDeleteRecordResponse
2946
2945
  @param {DS.Store} store
2947
2946
  @param {DS.Model} primaryModelClass
@@ -2954,7 +2953,7 @@
2954
2953
  return this.normalizeSaveResponse.apply(this, arguments);
2955
2954
  },
2956
2955
 
2957
- /*
2956
+ /**
2958
2957
  @method normalizeUpdateRecordResponse
2959
2958
  @param {DS.Store} store
2960
2959
  @param {DS.Model} primaryModelClass
@@ -2967,7 +2966,7 @@
2967
2966
  return this.normalizeSaveResponse.apply(this, arguments);
2968
2967
  },
2969
2968
 
2970
- /*
2969
+ /**
2971
2970
  @method normalizeSaveResponse
2972
2971
  @param {DS.Store} store
2973
2972
  @param {DS.Model} primaryModelClass
@@ -2980,7 +2979,7 @@
2980
2979
  return this.normalizeSingleResponse.apply(this, arguments);
2981
2980
  },
2982
2981
 
2983
- /*
2982
+ /**
2984
2983
  @method normalizeSingleResponse
2985
2984
  @param {DS.Store} store
2986
2985
  @param {DS.Model} primaryModelClass
@@ -2993,7 +2992,7 @@
2993
2992
  return this._normalizeResponse(store, primaryModelClass, payload, id, requestType, true);
2994
2993
  },
2995
2994
 
2996
- /*
2995
+ /**
2997
2996
  @method normalizeArrayResponse
2998
2997
  @param {DS.Store} store
2999
2998
  @param {DS.Model} primaryModelClass
@@ -3006,7 +3005,7 @@
3006
3005
  return this._normalizeResponse(store, primaryModelClass, payload, id, requestType, false);
3007
3006
  },
3008
3007
 
3009
- /*
3008
+ /**
3010
3009
  @method _normalizeResponse
3011
3010
  @param {DS.Store} store
3012
3011
  @param {DS.Model} primaryModelClass
@@ -3108,7 +3107,7 @@
3108
3107
  return hash;
3109
3108
  },
3110
3109
 
3111
- /*
3110
+ /**
3112
3111
  Returns the resource's ID.
3113
3112
  @method extractId
3114
3113
  @param {Object} modelClass
@@ -3121,7 +3120,7 @@
3121
3120
  return ember$data$lib$system$coerce$id$$default(id);
3122
3121
  },
3123
3122
 
3124
- /*
3123
+ /**
3125
3124
  Returns the resource's attributes formatted as a JSON-API "attributes object".
3126
3125
  http://jsonapi.org/format/#document-resource-object-attributes
3127
3126
  @method extractAttributes
@@ -3143,7 +3142,7 @@
3143
3142
  return attributes;
3144
3143
  },
3145
3144
 
3146
- /*
3145
+ /**
3147
3146
  Returns a relationship formatted as a JSON-API "relationship object".
3148
3147
  http://jsonapi.org/format/#document-resource-object-relationships
3149
3148
  @method extractRelationship
@@ -3172,7 +3171,7 @@
3172
3171
  return { id: ember$data$lib$system$coerce$id$$default(relationshipHash), type: relationshipModelName };
3173
3172
  },
3174
3173
 
3175
- /*
3174
+ /**
3176
3175
  Returns the resource's relationships formatted as a JSON-API "relationships object".
3177
3176
  http://jsonapi.org/format/#document-resource-object-relationships
3178
3177
  @method extractRelationships
@@ -5458,6 +5457,63 @@
5458
5457
  var ember$data$lib$system$store$serializer$response$$map = Ember.ArrayPolyfills.map;
5459
5458
  var ember$data$lib$system$store$serializer$response$$get = Ember.get;
5460
5459
 
5460
+ /**
5461
+ This is a helper method that validates a JSON API top-level document
5462
+
5463
+ The format of a document is described here:
5464
+ http://jsonapi.org/format/#document-top-level
5465
+
5466
+ @method validateDocumentStructure
5467
+ @param {Object} doc JSON API document
5468
+ @return {array} An array of errors found in the document structure
5469
+ */
5470
+ function ember$data$lib$system$store$serializer$response$$validateDocumentStructure(doc) {
5471
+ var errors = [];
5472
+ if (!doc || typeof doc !== 'object') {
5473
+ errors.push('Top level of a JSON API document must be an object');
5474
+ } else {
5475
+ if (!('data' in doc) && !('errors' in doc) && !('meta' in doc)) {
5476
+ errors.push('One or more of the following keys must be present: "data", "errors", "meta".');
5477
+ } else {
5478
+ if ('data' in doc && 'errors' in doc) {
5479
+ errors.push('Top level keys "errors" and "data" cannot both be present in a JSON API document');
5480
+ }
5481
+ }
5482
+ if ('data' in doc) {
5483
+ if (!(doc.data === null || Ember.isArray(doc.data) || typeof doc.data === 'object')) {
5484
+ errors.push('data must be null, an object, or an array');
5485
+ }
5486
+ }
5487
+ if ('meta' in doc) {
5488
+ if (typeof doc.meta !== 'object') {
5489
+ errors.push('meta must be an object');
5490
+ }
5491
+ }
5492
+ if ('errors' in doc) {
5493
+ if (!Ember.isArray(doc.errors)) {
5494
+ errors.push('errors must be an array');
5495
+ }
5496
+ }
5497
+ if ('links' in doc) {
5498
+ if (typeof doc.links !== 'object') {
5499
+ errors.push('links must be an object');
5500
+ }
5501
+ }
5502
+ if ('jsonapi' in doc) {
5503
+ if (typeof doc.jsonapi !== 'object') {
5504
+ errors.push('jsonapi must be an object');
5505
+ }
5506
+ }
5507
+ if ('included' in doc) {
5508
+ if (typeof doc.included !== 'object') {
5509
+ errors.push('included must be an array');
5510
+ }
5511
+ }
5512
+ }
5513
+
5514
+ return errors;
5515
+ }
5516
+
5461
5517
  /**
5462
5518
  This is a helper method that always returns a JSON-API Document.
5463
5519
 
@@ -5478,12 +5534,23 @@
5478
5534
  */
5479
5535
  function ember$data$lib$system$store$serializer$response$$normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
5480
5536
  if (ember$data$lib$system$store$serializer$response$$get(serializer, 'isNewSerializerAPI')) {
5481
- var normalizedResponse = serializer.normalizeResponse(store, modelClass, payload, id, requestType);
5482
- // TODO: Remove after metadata refactor
5483
- if (normalizedResponse.meta) {
5484
- store._setMetadataFor(modelClass.modelName, normalizedResponse.meta);
5485
- }
5486
- return normalizedResponse;
5537
+ var _ret = (function () {
5538
+ var normalizedResponse = serializer.normalizeResponse(store, modelClass, payload, id, requestType);
5539
+ var validationErrors = [];
5540
+ Ember.runInDebug(function () {
5541
+ validationErrors = ember$data$lib$system$store$serializer$response$$validateDocumentStructure(normalizedResponse);
5542
+ });
5543
+ Ember.assert('normalizeResponse must return a valid JSON API document:\n\t* ' + validationErrors.join('\n\t* '), Ember.isEmpty(validationErrors));
5544
+ // TODO: Remove after metadata refactor
5545
+ if (normalizedResponse.meta) {
5546
+ store._setMetadataFor(modelClass.modelName, normalizedResponse.meta);
5547
+ }
5548
+ return {
5549
+ v: normalizedResponse
5550
+ };
5551
+ })();
5552
+
5553
+ if (typeof _ret === 'object') return _ret.v;
5487
5554
  } else {
5488
5555
  Ember.deprecate('Your custom serializer uses the old version of the Serializer API, with `extract` hooks. Please upgrade your serializers to the new Serializer API using `normalizeResponse` hooks instead.', false, {
5489
5556
  id: 'ds.serializer.extract-hooks-deprecated',
@@ -5897,7 +5964,7 @@
5897
5964
  return hash;
5898
5965
  },
5899
5966
 
5900
- /*
5967
+ /**
5901
5968
  Normalizes an array of resource payloads and returns a JSON-API Document
5902
5969
  with primary data and, if any, included data as `{ data, included }`.
5903
5970
  @method normalizeArray
@@ -5936,7 +6003,7 @@
5936
6003
  return documentHash;
5937
6004
  },
5938
6005
 
5939
- /*
6006
+ /**
5940
6007
  @method _normalizeResponse
5941
6008
  @param {DS.Store} store
5942
6009
  @param {DS.Model} primaryModelClass
@@ -7542,7 +7609,7 @@
7542
7609
  });
7543
7610
 
7544
7611
  var ember$data$lib$core$$DS = Ember.Namespace.create({
7545
- VERSION: '1.13.7'
7612
+ VERSION: '1.13.8'
7546
7613
  });
7547
7614
 
7548
7615
  if (Ember.libraries) {
@@ -7852,6 +7919,24 @@
7852
7919
  };
7853
7920
 
7854
7921
  var ember$data$lib$system$snapshot$record$array$$default = ember$data$lib$system$snapshot$record$array$$SnapshotRecordArray;
7922
+ var ember$data$lib$system$record$arrays$filtered$subset$$FilteredSubset = Ember.ArrayProxy.extend({
7923
+ init: function () {
7924
+ this._super.apply(this, arguments);
7925
+
7926
+ var _getProperties = this.getProperties('filterByArgs', 'recordArray');
7927
+
7928
+ var filterByArgs = _getProperties.filterByArgs;
7929
+ var recordArray = _getProperties.recordArray;
7930
+ var key = filterByArgs[0];
7931
+
7932
+ var path = 'recordArray.@each.' + key;
7933
+ Ember.defineProperty(this, 'content', Ember.computed(path, function () {
7934
+ return this.filterBy.apply(recordArray, filterByArgs);
7935
+ }));
7936
+ }
7937
+ });
7938
+
7939
+ var ember$data$lib$system$record$arrays$filtered$subset$$default = ember$data$lib$system$record$arrays$filtered$subset$$FilteredSubset;
7855
7940
 
7856
7941
  var ember$data$lib$system$record$arrays$record$array$$get = Ember.get;
7857
7942
  var ember$data$lib$system$record$arrays$record$array$$set = Ember.set;
@@ -7921,6 +8006,37 @@
7921
8006
  return internalModel && internalModel.getRecord();
7922
8007
  },
7923
8008
 
8009
+ /**
8010
+ Get a filtered subset of the underlying `RecordArray`.
8011
+ The subset updates when a record would match or mismatch the
8012
+ specified filter parameters.
8013
+ Example
8014
+ ```javascript
8015
+ var allToms = store.all('person').filterBy('name', 'Tom');
8016
+ allToms.get('length'); // 0, since no toms yet in store
8017
+ var tom = store.push('person', { id: 1, name: 'Tom' });
8018
+ allToms.get('length'); // Tom is added
8019
+ tom.set('name', 'Thomas');
8020
+ allToms.get('length'); // 0, since no more records with name === 'Tom'
8021
+ ```
8022
+ @method filterBy
8023
+ @param {String} key property path
8024
+ @param {*} value optional
8025
+ */
8026
+ filterBy: function (key, value) {
8027
+ // only pass value to the arguments if it is present; this mimics the same
8028
+ // behavior for `filterBy`: http://git.io/vIurH
8029
+ var filterByArgs = [key];
8030
+ if (arguments.length === 2) {
8031
+ filterByArgs.push(value);
8032
+ }
8033
+
8034
+ return ember$data$lib$system$record$arrays$filtered$subset$$default.create({
8035
+ filterByArgs: filterByArgs,
8036
+ recordArray: this
8037
+ });
8038
+ },
8039
+
7924
8040
  /**
7925
8041
  Used to get the latest version of all of the records in this array
7926
8042
  from the adapter.
@@ -9644,7 +9760,7 @@
9644
9760
  toSet = toSet.concat(newRecords);
9645
9761
  var oldLength = this.length;
9646
9762
  this.arrayContentWillChange(0, this.length, toSet.length);
9647
- this.set('length', toSet.length);
9763
+ this.set("length", toSet.length);
9648
9764
  this.currentState = toSet;
9649
9765
  this.arrayContentDidChange(0, oldLength, this.length);
9650
9766
  //TODO Figure out to notify only on additions and maybe only if unloaded
@@ -9709,7 +9825,7 @@
9709
9825
  }
9710
9826
  this.arrayContentWillChange(idx, amt, objects.length);
9711
9827
  this.currentState.splice.apply(this.currentState, [idx, amt].concat(objects));
9712
- this.set('length', this.currentState.length);
9828
+ this.set("length", this.currentState.length);
9713
9829
  this.arrayContentDidChange(idx, amt, objects.length);
9714
9830
  if (objects) {
9715
9831
  //TODO(Igor) probably needed only for unloaded records
@@ -9739,11 +9855,11 @@
9739
9855
  var records;
9740
9856
  if (amt > 0) {
9741
9857
  records = this.currentState.slice(idx, idx + amt);
9742
- this.get('relationship').removeRecords(records);
9858
+ this.get("relationship").removeRecords(records);
9743
9859
  }
9744
9860
  var map = objects.map || Ember.ArrayPolyfills.map;
9745
9861
  if (objects) {
9746
- this.get('relationship').addRecords(map.call(objects, function (obj) {
9862
+ this.get("relationship").addRecords(map.call(objects, function (obj) {
9747
9863
  return obj._internalModel;
9748
9864
  }), idx);
9749
9865
  }
@@ -9772,8 +9888,8 @@
9772
9888
  loadedRecord: function () {
9773
9889
  this.loadingRecordsCount--;
9774
9890
  if (this.loadingRecordsCount === 0) {
9775
- ember$data$lib$system$many$array$$set(this, 'isLoaded', true);
9776
- this.trigger('didLoad');
9891
+ ember$data$lib$system$many$array$$set(this, "isLoaded", true);
9892
+ this.trigger("didLoad");
9777
9893
  }
9778
9894
  },
9779
9895
 
@@ -9803,10 +9919,10 @@
9803
9919
  */
9804
9920
  save: function () {
9805
9921
  var manyArray = this;
9806
- var promiseLabel = 'DS: ManyArray#save ' + ember$data$lib$system$many$array$$get(this, 'type');
9807
- var promise = Ember.RSVP.all(this.invoke('save'), promiseLabel).then(function (array) {
9922
+ var promiseLabel = "DS: ManyArray#save " + ember$data$lib$system$many$array$$get(this, "type");
9923
+ var promise = Ember.RSVP.all(this.invoke("save"), promiseLabel).then(function (array) {
9808
9924
  return manyArray;
9809
- }, null, 'DS: ManyArray#save return ManyArray');
9925
+ }, null, "DS: ManyArray#save return ManyArray");
9810
9926
 
9811
9927
  return ember$data$lib$system$promise$proxies$$PromiseArray.create({ promise: promise });
9812
9928
  },
@@ -9819,11 +9935,11 @@
9819
9935
  @return {DS.Model} record
9820
9936
  */
9821
9937
  createRecord: function (hash) {
9822
- var store = ember$data$lib$system$many$array$$get(this, 'store');
9823
- var type = ember$data$lib$system$many$array$$get(this, 'type');
9938
+ var store = ember$data$lib$system$many$array$$get(this, "store");
9939
+ var type = ember$data$lib$system$many$array$$get(this, "type");
9824
9940
  var record;
9825
9941
 
9826
- Ember.assert('You cannot add \'' + type.modelName + '\' records to this polymorphic relationship.', !ember$data$lib$system$many$array$$get(this, 'isPolymorphic'));
9942
+ Ember.assert("You cannot add '" + type.modelName + "' records to this polymorphic relationship.", !ember$data$lib$system$many$array$$get(this, "isPolymorphic"));
9827
9943
 
9828
9944
  record = store.createRecord(type.modelName, hash);
9829
9945
  this.pushObject(record);
@@ -9837,9 +9953,9 @@
9837
9953
  @deprecated Use `addObject()` instead
9838
9954
  */
9839
9955
  addRecord: function (record) {
9840
- Ember.deprecate('Using manyArray.addRecord() has been deprecated. You should use manyArray.addObject() instead.', false, {
9841
- id: 'ds.many-array.add-record-deprecated',
9842
- until: '2.0.0'
9956
+ Ember.deprecate("Using manyArray.addRecord() has been deprecated. You should use manyArray.addObject() instead.", false, {
9957
+ id: "ds.many-array.add-record-deprecated",
9958
+ until: "2.0.0"
9843
9959
  });
9844
9960
  this.addObject(record);
9845
9961
  },
@@ -9850,11 +9966,39 @@
9850
9966
  @deprecated Use `removeObject()` instead
9851
9967
  */
9852
9968
  removeRecord: function (record) {
9853
- Ember.deprecate('Using manyArray.removeRecord() has been deprecated. You should use manyArray.removeObject() instead.', false, {
9854
- id: 'ds.many-array.remove-record-deprecated',
9855
- until: '2.0.0'
9969
+ Ember.deprecate("Using manyArray.removeRecord() has been deprecated. You should use manyArray.removeObject() instead.", false, {
9970
+ id: "ds.many-array.remove-record-deprecated",
9971
+ until: "2.0.0"
9856
9972
  });
9857
9973
  this.removeObject(record);
9974
+ },
9975
+
9976
+ /**
9977
+ Get a filtered subset of the underlying `ManyArray`.
9978
+ The subset updates when a record would match or mismatch the
9979
+ specified filter parameters.
9980
+ Example
9981
+ ```javascript
9982
+ var post = store.peekRecord('post', 1)
9983
+ // All the comments that are deleted locally but not yet saved to the server.
9984
+ var deletedComments = post.get('comments').filterBy('isDeleted');
9985
+ ```
9986
+ @method filterBy
9987
+ @param {String} key property path
9988
+ @param {*} value optional
9989
+ */
9990
+ filterBy: function (key, value) {
9991
+ // only pass value to the arguments if it is present; this mimics the same
9992
+ // behavior for `filterBy`: http://git.io/vIurH
9993
+ var filterByArgs = [key];
9994
+ if (arguments.length === 2) {
9995
+ filterByArgs.push(value);
9996
+ }
9997
+
9998
+ return ember$data$lib$system$record$arrays$filtered$subset$$default.create({
9999
+ filterByArgs: filterByArgs,
10000
+ recordArray: this
10001
+ });
9858
10002
  }
9859
10003
  });
9860
10004
 
@@ -12460,7 +12604,7 @@
12460
12604
  implement them.
12461
12605
  This method returns a promise, which is resolved with a `RecordArray`
12462
12606
  once the server returns.
12463
- @method query
12607
+ @method findQuery
12464
12608
  @param {String} modelName
12465
12609
  @param {any} query an opaque query to be used by the adapter
12466
12610
  @return {Promise} promise
@@ -13716,7 +13860,7 @@
13716
13860
 
13717
13861
  var ember$data$lib$serializers$json$api$serializer$$default = ember$data$lib$serializers$json$serializer$$default.extend({
13718
13862
 
13719
- /*
13863
+ /**
13720
13864
  This is only to be used temporarily during the transition from the old
13721
13865
  serializer API to the new one.
13722
13866
  `JSONAPISerializer` only supports the new Serializer API.
@@ -13724,7 +13868,7 @@
13724
13868
  */
13725
13869
  isNewSerializerAPI: true,
13726
13870
 
13727
- /*
13871
+ /**
13728
13872
  @method _normalizeDocumentHelper
13729
13873
  @param {Object} documentHash
13730
13874
  @return {Object}
@@ -13745,7 +13889,7 @@
13745
13889
  return documentHash;
13746
13890
  },
13747
13891
 
13748
- /*
13892
+ /**
13749
13893
  @method _normalizeRelationshipDataHelper
13750
13894
  @param {Object} relationshipDataHash
13751
13895
  @return {Object}
@@ -13757,7 +13901,7 @@
13757
13901
  return relationshipDataHash;
13758
13902
  },
13759
13903
 
13760
- /*
13904
+ /**
13761
13905
  @method _normalizeResourceHelper
13762
13906
  @param {Object} resourceHash
13763
13907
  @return {Object}
@@ -13804,7 +13948,7 @@
13804
13948
  return normalizedPayload;
13805
13949
  },
13806
13950
 
13807
- /*
13951
+ /**
13808
13952
  @method extractAttributes
13809
13953
  @param {DS.Model} modelClass
13810
13954
  @param {Object} resourceHash
@@ -13827,7 +13971,7 @@
13827
13971
  return attributes;
13828
13972
  },
13829
13973
 
13830
- /*
13974
+ /**
13831
13975
  @method extractRelationship
13832
13976
  @param {Object} relationshipHash
13833
13977
  @return {Object}
@@ -13845,7 +13989,7 @@
13845
13989
  return relationshipHash;
13846
13990
  },
13847
13991
 
13848
- /*
13992
+ /**
13849
13993
  @method extractRelationships
13850
13994
  @param {Object} modelClass
13851
13995
  @param {Object} resourceHash
@@ -13870,8 +14014,8 @@
13870
14014
  return relationships;
13871
14015
  },
13872
14016
 
13873
- /*
13874
- @method extractType
14017
+ /**
14018
+ @method _extractType
13875
14019
  @param {DS.Model} modelClass
13876
14020
  @param {Object} resourceHash
13877
14021
  @return {String}
@@ -13899,7 +14043,7 @@
13899
14043
  return ember$inflector$lib$lib$system$string$$pluralize(modelName);
13900
14044
  },
13901
14045
 
13902
- /*
14046
+ /**
13903
14047
  @method normalize
13904
14048
  @param {DS.Model} modelClass
13905
14049
  @param {Object} resourceHash