ember-data-source 1.13.7 → 1.13.8

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.
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