ember-data-source 2.3.1 → 2.3.2

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: 671f4ae89868e4d171d937d7495046adb6f9e954
4
- data.tar.gz: fdef859bb675a3e8882b798ddd80714245dbae0e
3
+ metadata.gz: ed8b1ee1f51872b0c75155ab0e7777b6fbe928e0
4
+ data.tar.gz: 19daaa0382df4b2779c3cf098d8c548fb3d9d409
5
5
  SHA512:
6
- metadata.gz: 9f0cc76c044b00819369e5c743bd72364abce6b7ec63e4044b82da2894a2f0130a267279d1ff523ddda213a8e36217e6b04a99c5ed28691a7c9c846bb1ce9541
7
- data.tar.gz: d703caa9eed0106286ee182a95013904468afb00dd1f274e2473cc9e14861ba0ebae799cfc0fd0b8762988b8bd7477dba7924c6248e5f211de5edd99f0854053
6
+ metadata.gz: 996585ff41d4c51546aa376b1b1a46ddd522c31fcfa391163825020c52ca3ac2d6c878e487f0fd65a52582a5c03b2bc955666ac7639e2fd38ea8889d94ba16aa
7
+ data.tar.gz: 35f2c0f3a6620690f4c09ab9d609b8a28f4e77ae6218d62a05bbc99a99d577358ac42013f8945886bd671c713f33e895cb70a28450dade85d9014aea82f73452
@@ -0,0 +1,15492 @@
1
+ (function(){
2
+ "use strict";
3
+
4
+ /*!
5
+ * @overview Ember Data
6
+ * @copyright Copyright 2011-2015 Tilde Inc. and contributors.
7
+ * Portions Copyright 2011 LivingSocial Inc.
8
+ * @license Licensed under MIT license (see license.js)
9
+ * @version 2.3.2
10
+ */
11
+
12
+ var define, requireModule, require, requirejs;
13
+
14
+ (function() {
15
+
16
+ var _isArray;
17
+ if (!Array.isArray) {
18
+ _isArray = function (x) {
19
+ return Object.prototype.toString.call(x) === "[object Array]";
20
+ };
21
+ } else {
22
+ _isArray = Array.isArray;
23
+ }
24
+
25
+ var registry = {};
26
+ var seen = {};
27
+ var FAILED = false;
28
+
29
+ var uuid = 0;
30
+
31
+ function tryFinally(tryable, finalizer) {
32
+ try {
33
+ return tryable();
34
+ } finally {
35
+ finalizer();
36
+ }
37
+ }
38
+
39
+ function unsupportedModule(length) {
40
+ throw new Error("an unsupported module was defined, expected `define(name, deps, module)` instead got: `" + length + "` arguments to define`");
41
+ }
42
+
43
+ var defaultDeps = ['require', 'exports', 'module'];
44
+
45
+ function Module(name, deps, callback, exports) {
46
+ this.id = uuid++;
47
+ this.name = name;
48
+ this.deps = !deps.length && callback.length ? defaultDeps : deps;
49
+ this.exports = exports || { };
50
+ this.callback = callback;
51
+ this.state = undefined;
52
+ this._require = undefined;
53
+ }
54
+
55
+
56
+ Module.prototype.makeRequire = function() {
57
+ var name = this.name;
58
+
59
+ return this._require || (this._require = function(dep) {
60
+ return require(resolve(dep, name));
61
+ });
62
+ }
63
+
64
+ define = function(name, deps, callback) {
65
+ if (arguments.length < 2) {
66
+ unsupportedModule(arguments.length);
67
+ }
68
+
69
+ if (!_isArray(deps)) {
70
+ callback = deps;
71
+ deps = [];
72
+ }
73
+
74
+ registry[name] = new Module(name, deps, callback);
75
+ };
76
+
77
+ // we don't support all of AMD
78
+ // define.amd = {};
79
+ // we will support petals...
80
+ define.petal = { };
81
+
82
+ function Alias(path) {
83
+ this.name = path;
84
+ }
85
+
86
+ define.alias = function(path) {
87
+ return new Alias(path);
88
+ };
89
+
90
+ function reify(mod, name, seen) {
91
+ var deps = mod.deps;
92
+ var length = deps.length;
93
+ var reified = new Array(length);
94
+ var dep;
95
+ // TODO: new Module
96
+ // TODO: seen refactor
97
+ var module = { };
98
+
99
+ for (var i = 0, l = length; i < l; i++) {
100
+ dep = deps[i];
101
+ if (dep === 'exports') {
102
+ module.exports = reified[i] = seen;
103
+ } else if (dep === 'require') {
104
+ reified[i] = mod.makeRequire();
105
+ } else if (dep === 'module') {
106
+ mod.exports = seen;
107
+ module = reified[i] = mod;
108
+ } else {
109
+ reified[i] = requireFrom(resolve(dep, name), name);
110
+ }
111
+ }
112
+
113
+ return {
114
+ deps: reified,
115
+ module: module
116
+ };
117
+ }
118
+
119
+ function requireFrom(name, origin) {
120
+ var mod = registry[name];
121
+ if (!mod) {
122
+ throw new Error('Could not find module `' + name + '` imported from `' + origin + '`');
123
+ }
124
+ return require(name);
125
+ }
126
+
127
+ function missingModule(name) {
128
+ throw new Error('Could not find module ' + name);
129
+ }
130
+ requirejs = require = requireModule = function(name) {
131
+ var mod = registry[name];
132
+
133
+ if (mod && mod.callback instanceof Alias) {
134
+ mod = registry[mod.callback.name];
135
+ }
136
+
137
+ if (!mod) { missingModule(name); }
138
+
139
+ if (mod.state !== FAILED &&
140
+ seen.hasOwnProperty(name)) {
141
+ return seen[name];
142
+ }
143
+
144
+ var reified;
145
+ var module;
146
+ var loaded = false;
147
+
148
+ seen[name] = { }; // placeholder for run-time cycles
149
+
150
+ tryFinally(function() {
151
+ reified = reify(mod, name, seen[name]);
152
+ module = mod.callback.apply(this, reified.deps);
153
+ loaded = true;
154
+ }, function() {
155
+ if (!loaded) {
156
+ mod.state = FAILED;
157
+ }
158
+ });
159
+
160
+ var obj;
161
+ if (module === undefined && reified.module.exports) {
162
+ obj = reified.module.exports;
163
+ } else {
164
+ obj = seen[name] = module;
165
+ }
166
+
167
+ if (obj !== null &&
168
+ (typeof obj === 'object' || typeof obj === 'function') &&
169
+ obj['default'] === undefined) {
170
+ obj['default'] = obj;
171
+ }
172
+
173
+ return (seen[name] = obj);
174
+ };
175
+
176
+ function resolve(child, name) {
177
+ if (child.charAt(0) !== '.') { return child; }
178
+
179
+ var parts = child.split('/');
180
+ var nameParts = name.split('/');
181
+ var parentBase = nameParts.slice(0, -1);
182
+
183
+ for (var i = 0, l = parts.length; i < l; i++) {
184
+ var part = parts[i];
185
+
186
+ if (part === '..') {
187
+ if (parentBase.length === 0) {
188
+ throw new Error('Cannot access parent module of root');
189
+ }
190
+ parentBase.pop();
191
+ } else if (part === '.') {
192
+ continue;
193
+ } else { parentBase.push(part); }
194
+ }
195
+
196
+ return parentBase.join('/');
197
+ }
198
+
199
+ requirejs.entries = requirejs._eak_seen = registry;
200
+ requirejs.unsee = function(moduleName) {
201
+ delete seen[moduleName];
202
+ };
203
+
204
+ requirejs.clear = function() {
205
+ requirejs.entries = requirejs._eak_seen = registry = {};
206
+ seen = state = {};
207
+ };
208
+ })();
209
+
210
+ define("ember-data/-private/adapters", ["exports", "ember-data/adapters/json-api", "ember-data/adapters/rest"], function (exports, _emberDataAdaptersJsonApi, _emberDataAdaptersRest) {
211
+ exports.JSONAPIAdapter = _emberDataAdaptersJsonApi.default;
212
+ exports.RESTAdapter = _emberDataAdaptersRest.default;
213
+ });
214
+ /**
215
+ @module ember-data
216
+ */
217
+ define('ember-data/-private/adapters/build-url-mixin', ['exports'], function (exports) {
218
+ var get = Ember.get;
219
+
220
+ /**
221
+
222
+ WARNING: This interface is likely to change in order to accomodate https://github.com/emberjs/rfcs/pull/4
223
+
224
+ ## Using BuildURLMixin
225
+
226
+ To use url building, include the mixin when extending an adapter, and call `buildURL` where needed.
227
+ The default behaviour is designed for RESTAdapter.
228
+
229
+ ### Example
230
+
231
+ ```javascript
232
+ export default DS.Adapter.extend(BuildURLMixin, {
233
+ findRecord: function(store, type, id, snapshot) {
234
+ var url = this.buildURL(type.modelName, id, snapshot, 'findRecord');
235
+ return this.ajax(url, 'GET');
236
+ }
237
+ });
238
+ ```
239
+
240
+ ### Attributes
241
+
242
+ The `host` and `namespace` attributes will be used if defined, and are optional.
243
+
244
+ @class BuildURLMixin
245
+ @namespace DS
246
+ */
247
+ exports.default = Ember.Mixin.create({
248
+ /**
249
+ Builds a URL for a given type and optional ID.
250
+ By default, it pluralizes the type's name (for example, 'post'
251
+ becomes 'posts' and 'person' becomes 'people'). To override the
252
+ pluralization see [pathForType](#method_pathForType).
253
+ If an ID is specified, it adds the ID to the path generated
254
+ for the type, separated by a `/`.
255
+ When called by RESTAdapter.findMany() the `id` and `snapshot` parameters
256
+ will be arrays of ids and snapshots.
257
+ @method buildURL
258
+ @param {String} modelName
259
+ @param {(String|Array|Object)} id single id or array of ids or query
260
+ @param {(DS.Snapshot|Array)} snapshot single snapshot or array of snapshots
261
+ @param {String} requestType
262
+ @param {Object} query object of query parameters to send for query requests.
263
+ @return {String} url
264
+ */
265
+ buildURL: function (modelName, id, snapshot, requestType, query) {
266
+ switch (requestType) {
267
+ case 'findRecord':
268
+ return this.urlForFindRecord(id, modelName, snapshot);
269
+ case 'findAll':
270
+ return this.urlForFindAll(modelName);
271
+ case 'query':
272
+ return this.urlForQuery(query, modelName);
273
+ case 'queryRecord':
274
+ return this.urlForQueryRecord(query, modelName);
275
+ case 'findMany':
276
+ return this.urlForFindMany(id, modelName, snapshot);
277
+ case 'findHasMany':
278
+ return this.urlForFindHasMany(id, modelName);
279
+ case 'findBelongsTo':
280
+ return this.urlForFindBelongsTo(id, modelName);
281
+ case 'createRecord':
282
+ return this.urlForCreateRecord(modelName, snapshot);
283
+ case 'updateRecord':
284
+ return this.urlForUpdateRecord(id, modelName, snapshot);
285
+ case 'deleteRecord':
286
+ return this.urlForDeleteRecord(id, modelName, snapshot);
287
+ default:
288
+ return this._buildURL(modelName, id);
289
+ }
290
+ },
291
+
292
+ /**
293
+ @method _buildURL
294
+ @private
295
+ @param {String} modelName
296
+ @param {String} id
297
+ @return {String} url
298
+ */
299
+ _buildURL: function (modelName, id) {
300
+ var url = [];
301
+ var host = get(this, 'host');
302
+ var prefix = this.urlPrefix();
303
+ var path;
304
+
305
+ if (modelName) {
306
+ path = this.pathForType(modelName);
307
+ if (path) {
308
+ url.push(path);
309
+ }
310
+ }
311
+
312
+ if (id) {
313
+ url.push(encodeURIComponent(id));
314
+ }
315
+ if (prefix) {
316
+ url.unshift(prefix);
317
+ }
318
+
319
+ url = url.join('/');
320
+ if (!host && url && url.charAt(0) !== '/') {
321
+ url = '/' + url;
322
+ }
323
+
324
+ return url;
325
+ },
326
+
327
+ /**
328
+ * @method urlForFindRecord
329
+ * @param {String} id
330
+ * @param {String} modelName
331
+ * @param {DS.Snapshot} snapshot
332
+ * @return {String} url
333
+ */
334
+ urlForFindRecord: function (id, modelName, snapshot) {
335
+ return this._buildURL(modelName, id);
336
+ },
337
+
338
+ /**
339
+ * @method urlForFindAll
340
+ * @param {String} modelName
341
+ * @return {String} url
342
+ */
343
+ urlForFindAll: function (modelName) {
344
+ return this._buildURL(modelName);
345
+ },
346
+
347
+ /**
348
+ * @method urlForQuery
349
+ * @param {Object} query
350
+ * @param {String} modelName
351
+ * @return {String} url
352
+ */
353
+ urlForQuery: function (query, modelName) {
354
+ return this._buildURL(modelName);
355
+ },
356
+
357
+ /**
358
+ * @method urlForQueryRecord
359
+ * @param {Object} query
360
+ * @param {String} modelName
361
+ * @return {String} url
362
+ */
363
+ urlForQueryRecord: function (query, modelName) {
364
+ return this._buildURL(modelName);
365
+ },
366
+
367
+ /**
368
+ * @method urlForFindMany
369
+ * @param {Array} ids
370
+ * @param {String} modelName
371
+ * @param {Array} snapshots
372
+ * @return {String} url
373
+ */
374
+ urlForFindMany: function (ids, modelName, snapshots) {
375
+ return this._buildURL(modelName);
376
+ },
377
+
378
+ /**
379
+ * @method urlForFindHasMany
380
+ * @param {String} id
381
+ * @param {String} modelName
382
+ * @return {String} url
383
+ */
384
+ urlForFindHasMany: function (id, modelName) {
385
+ return this._buildURL(modelName, id);
386
+ },
387
+
388
+ /**
389
+ * @method urlForFindBelongTo
390
+ * @param {String} id
391
+ * @param {String} modelName
392
+ * @return {String} url
393
+ */
394
+ urlForFindBelongsTo: function (id, modelName) {
395
+ return this._buildURL(modelName, id);
396
+ },
397
+
398
+ /**
399
+ * @method urlForCreateRecord
400
+ * @param {String} modelName
401
+ * @param {DS.Snapshot} snapshot
402
+ * @return {String} url
403
+ */
404
+ urlForCreateRecord: function (modelName, snapshot) {
405
+ return this._buildURL(modelName);
406
+ },
407
+
408
+ /**
409
+ * @method urlForUpdateRecord
410
+ * @param {String} id
411
+ * @param {String} modelName
412
+ * @param {DS.Snapshot} snapshot
413
+ * @return {String} url
414
+ */
415
+ urlForUpdateRecord: function (id, modelName, snapshot) {
416
+ return this._buildURL(modelName, id);
417
+ },
418
+
419
+ /**
420
+ * @method urlForDeleteRecord
421
+ * @param {String} id
422
+ * @param {String} modelName
423
+ * @param {DS.Snapshot} snapshot
424
+ * @return {String} url
425
+ */
426
+ urlForDeleteRecord: function (id, modelName, snapshot) {
427
+ return this._buildURL(modelName, id);
428
+ },
429
+
430
+ /**
431
+ @method urlPrefix
432
+ @private
433
+ @param {String} path
434
+ @param {String} parentURL
435
+ @return {String} urlPrefix
436
+ */
437
+ urlPrefix: function (path, parentURL) {
438
+ var host = get(this, 'host');
439
+ var namespace = get(this, 'namespace');
440
+ var url = [];
441
+
442
+ if (path) {
443
+ // Protocol relative url
444
+ //jscs:disable disallowEmptyBlocks
445
+ if (/^\/\//.test(path)) {
446
+ // Do nothing, the full host is already included. This branch
447
+ // avoids the absolute path logic and the relative path logic.
448
+
449
+ // Absolute path
450
+ } else if (path.charAt(0) === '/') {
451
+ //jscs:enable disallowEmptyBlocks
452
+ if (host) {
453
+ path = path.slice(1);
454
+ url.push(host);
455
+ }
456
+ // Relative path
457
+ } else if (!/^http(s)?:\/\//.test(path)) {
458
+ url.push(parentURL);
459
+ }
460
+ } else {
461
+ if (host) {
462
+ url.push(host);
463
+ }
464
+ if (namespace) {
465
+ url.push(namespace);
466
+ }
467
+ }
468
+
469
+ if (path) {
470
+ url.push(path);
471
+ }
472
+
473
+ return url.join('/');
474
+ },
475
+
476
+ /**
477
+ Determines the pathname for a given type.
478
+ By default, it pluralizes the type's name (for example,
479
+ 'post' becomes 'posts' and 'person' becomes 'people').
480
+ ### Pathname customization
481
+ For example if you have an object LineItem with an
482
+ endpoint of "/line_items/".
483
+ ```app/adapters/application.js
484
+ import DS from 'ember-data';
485
+ export default DS.RESTAdapter.extend({
486
+ pathForType: function(modelName) {
487
+ var decamelized = Ember.String.decamelize(modelName);
488
+ return Ember.String.pluralize(decamelized);
489
+ }
490
+ });
491
+ ```
492
+ @method pathForType
493
+ @param {String} modelName
494
+ @return {String} path
495
+ **/
496
+ pathForType: function (modelName) {
497
+ var camelized = Ember.String.camelize(modelName);
498
+ return Ember.String.pluralize(camelized);
499
+ }
500
+ });
501
+ });
502
+ define('ember-data/-private/adapters/errors', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
503
+ exports.AdapterError = AdapterError;
504
+ exports.InvalidError = InvalidError;
505
+ exports.TimeoutError = TimeoutError;
506
+ exports.AbortError = AbortError;
507
+ exports.errorsHashToArray = errorsHashToArray;
508
+ exports.errorsArrayToHash = errorsArrayToHash;
509
+
510
+ var EmberError = _ember.default.Error;
511
+
512
+ var SOURCE_POINTER_REGEXP = /^\/?data\/(attributes|relationships)\/(.*)/;
513
+ var SOURCE_POINTER_PRIMARY_REGEXP = /^\/?data/;
514
+ var PRIMARY_ATTRIBUTE_KEY = 'base';
515
+
516
+ /**
517
+ @class AdapterError
518
+ @namespace DS
519
+ */
520
+
521
+ function AdapterError(errors) {
522
+ var message = arguments.length <= 1 || arguments[1] === undefined ? 'Adapter operation failed' : arguments[1];
523
+
524
+ EmberError.call(this, message);
525
+
526
+ this.errors = errors || [{
527
+ title: 'Adapter Error',
528
+ detail: message
529
+ }];
530
+ }
531
+
532
+ AdapterError.prototype = Object.create(EmberError.prototype);
533
+
534
+ /**
535
+ A `DS.InvalidError` is used by an adapter to signal the external API
536
+ was unable to process a request because the content was not
537
+ semantically correct or meaningful per the API. Usually this means a
538
+ record failed some form of server side validation. When a promise
539
+ from an adapter is rejected with a `DS.InvalidError` the record will
540
+ transition to the `invalid` state and the errors will be set to the
541
+ `errors` property on the record.
542
+
543
+ For Ember Data to correctly map errors to their corresponding
544
+ properties on the model, Ember Data expects each error to be
545
+ a valid json-api error object with a `source/pointer` that matches
546
+ the property name. For example if you had a Post model that
547
+ looked like this.
548
+
549
+ ```app/models/post.js
550
+ import DS from 'ember-data';
551
+
552
+ export default DS.Model.extend({
553
+ title: DS.attr('string'),
554
+ content: DS.attr('string')
555
+ });
556
+ ```
557
+
558
+ To show an error from the server related to the `title` and
559
+ `content` properties your adapter could return a promise that
560
+ rejects with a `DS.InvalidError` object that looks like this:
561
+
562
+ ```app/adapters/post.js
563
+ import Ember from 'ember';
564
+ import DS from 'ember-data';
565
+
566
+ export default DS.RESTAdapter.extend({
567
+ updateRecord: function() {
568
+ // Fictional adapter that always rejects
569
+ return Ember.RSVP.reject(new DS.InvalidError([
570
+ {
571
+ detail: 'Must be unique',
572
+ source: { pointer: '/data/attributes/title' }
573
+ },
574
+ {
575
+ detail: 'Must not be blank',
576
+ source: { pointer: '/data/attributes/content'}
577
+ }
578
+ ]));
579
+ }
580
+ });
581
+ ```
582
+
583
+ Your backend may use different property names for your records the
584
+ store will attempt extract and normalize the errors using the
585
+ serializer's `extractErrors` method before the errors get added to
586
+ the the model. As a result, it is safe for the `InvalidError` to
587
+ wrap the error payload unaltered.
588
+
589
+ @class InvalidError
590
+ @namespace DS
591
+ */
592
+
593
+ function InvalidError(errors) {
594
+ (0, _emberDataPrivateDebug.assert)('`InvalidError` expects json-api formatted errors array.', _ember.default.isArray(errors || []));
595
+ AdapterError.call(this, errors, 'The adapter rejected the commit because it was invalid');
596
+ }
597
+
598
+ InvalidError.prototype = Object.create(AdapterError.prototype);
599
+
600
+ /**
601
+ @class TimeoutError
602
+ @namespace DS
603
+ */
604
+
605
+ function TimeoutError() {
606
+ AdapterError.call(this, null, 'The adapter operation timed out');
607
+ }
608
+
609
+ TimeoutError.prototype = Object.create(AdapterError.prototype);
610
+
611
+ /**
612
+ @class AbortError
613
+ @namespace DS
614
+ */
615
+
616
+ function AbortError() {
617
+ AdapterError.call(this, null, 'The adapter operation was aborted');
618
+ }
619
+
620
+ AbortError.prototype = Object.create(AdapterError.prototype);
621
+
622
+ /**
623
+ @method errorsHashToArray
624
+ @private
625
+ */
626
+
627
+ function errorsHashToArray(errors) {
628
+ var out = [];
629
+
630
+ if (_ember.default.isPresent(errors)) {
631
+ Object.keys(errors).forEach(function (key) {
632
+ var messages = _ember.default.makeArray(errors[key]);
633
+ for (var i = 0; i < messages.length; i++) {
634
+ var title = 'Invalid Attribute';
635
+ var pointer = '/data/attributes/' + key;
636
+ if (key === PRIMARY_ATTRIBUTE_KEY) {
637
+ title = 'Invalid Document';
638
+ pointer = '/data';
639
+ }
640
+ out.push({
641
+ title: title,
642
+ detail: messages[i],
643
+ source: {
644
+ pointer: pointer
645
+ }
646
+ });
647
+ }
648
+ });
649
+ }
650
+
651
+ return out;
652
+ }
653
+
654
+ /**
655
+ @method errorsArrayToHash
656
+ @private
657
+ */
658
+
659
+ function errorsArrayToHash(errors) {
660
+ var out = {};
661
+
662
+ if (_ember.default.isPresent(errors)) {
663
+ errors.forEach(function (error) {
664
+ if (error.source && error.source.pointer) {
665
+ var key = error.source.pointer.match(SOURCE_POINTER_REGEXP);
666
+
667
+ if (key) {
668
+ key = key[2];
669
+ } else if (error.source.pointer.search(SOURCE_POINTER_PRIMARY_REGEXP) !== -1) {
670
+ key = PRIMARY_ATTRIBUTE_KEY;
671
+ }
672
+
673
+ if (key) {
674
+ out[key] = out[key] || [];
675
+ out[key].push(error.detail || error.title);
676
+ }
677
+ }
678
+ });
679
+ }
680
+
681
+ return out;
682
+ }
683
+ });
684
+ define('ember-data/-private/core', ['exports', 'ember', 'ember-data/version'], function (exports, _ember, _emberDataVersion) {
685
+
686
+ /**
687
+ @module ember-data
688
+ */
689
+
690
+ /**
691
+ All Ember Data methods and functions are defined inside of this namespace.
692
+
693
+ @class DS
694
+ @static
695
+ */
696
+
697
+ /**
698
+ @property VERSION
699
+ @type String
700
+ @static
701
+ */
702
+ /*jshint -W079 */
703
+ var DS = _ember.default.Namespace.create({
704
+ VERSION: _emberDataVersion.default
705
+ });
706
+
707
+ if (_ember.default.libraries) {
708
+ _ember.default.libraries.registerCoreLibrary('Ember Data', DS.VERSION);
709
+ }
710
+
711
+ // var EMBER_DATA_FEATURES = EMBER_DATA_FEATURES_PLACEHOLDER; //jshint ignore: line
712
+
713
+ // Ember.merge(Ember.FEATURES, EMBER_DATA_FEATURES);
714
+
715
+ exports.default = DS;
716
+ });
717
+ define('ember-data/-private/debug', ['exports', 'ember'], function (exports, _ember) {
718
+ exports.assert = assert;
719
+ exports.debug = debug;
720
+ exports.deprecate = deprecate;
721
+ exports.info = info;
722
+ exports.runInDebug = runInDebug;
723
+ exports.warn = warn;
724
+ exports.debugSeal = debugSeal;
725
+
726
+ function assert() {
727
+ return _ember.default.assert.apply(_ember.default, arguments);
728
+ }
729
+
730
+ function debug() {
731
+ return _ember.default.debug.apply(_ember.default, arguments);
732
+ }
733
+
734
+ function deprecate() {
735
+ return _ember.default.deprecate.apply(_ember.default, arguments);
736
+ }
737
+
738
+ function info() {
739
+ return _ember.default.info.apply(_ember.default, arguments);
740
+ }
741
+
742
+ function runInDebug() {
743
+ return _ember.default.runInDebug.apply(_ember.default, arguments);
744
+ }
745
+
746
+ function warn() {
747
+ return _ember.default.warn.apply(_ember.default, arguments);
748
+ }
749
+
750
+ function debugSeal() {
751
+ return _ember.default.debugSeal.apply(_ember.default, arguments);
752
+ }
753
+ });
754
+ define('ember-data/-private/ext/date', ['exports'], function (exports) {
755
+ /**
756
+ @module ember-data
757
+ */
758
+
759
+ /**
760
+ Date.parse with progressive enhancement for ISO 8601 <https://github.com/csnover/js-iso8601>
761
+
762
+ © 2011 Colin Snover <http://zetafleet.com>
763
+
764
+ Released under MIT license.
765
+
766
+ @class Date
767
+ @namespace Ember
768
+ @static
769
+ */
770
+ Ember.Date = Ember.Date || {};
771
+
772
+ var origParse = Date.parse;
773
+ var numericKeys = [1, 4, 5, 6, 7, 10, 11];
774
+
775
+ /**
776
+ @method parse
777
+ @param {Date} date
778
+ @return {Number} timestamp
779
+ */
780
+ Ember.Date.parse = function (date) {
781
+ var timestamp, struct;
782
+ var minutesOffset = 0;
783
+
784
+ // ES5 §15.9.4.2 states that the string should attempt to be parsed as a Date Time String Format string
785
+ // before falling back to any implementation-specific date parsing, so that’s what we do, even if native
786
+ // implementations could be faster
787
+ // 1 YYYY 2 MM 3 DD 4 HH 5 mm 6 ss 7 msec 8 Z 9 ± 10 tzHH 11 tzmm
788
+ if (struct = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(date)) {
789
+ // avoid NaN timestamps caused by “undefined” values being passed to Date.UTC
790
+ for (var i = 0, k; k = numericKeys[i]; ++i) {
791
+ struct[k] = +struct[k] || 0;
792
+ }
793
+
794
+ // allow undefined days and months
795
+ struct[2] = (+struct[2] || 1) - 1;
796
+ struct[3] = +struct[3] || 1;
797
+
798
+ if (struct[8] !== 'Z' && struct[9] !== undefined) {
799
+ minutesOffset = struct[10] * 60 + struct[11];
800
+
801
+ if (struct[9] === '+') {
802
+ minutesOffset = 0 - minutesOffset;
803
+ }
804
+ }
805
+
806
+ timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
807
+ } else {
808
+ timestamp = origParse ? origParse(date) : NaN;
809
+ }
810
+
811
+ return timestamp;
812
+ };
813
+
814
+ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
815
+ Date.parse = Ember.Date.parse;
816
+ }
817
+ });
818
+ define('ember-data/-private/features', ['exports', 'ember'], function (exports, _ember) {
819
+ exports.default = isEnabled;
820
+
821
+ function isEnabled() {
822
+ var _Ember$FEATURES;
823
+
824
+ return (_Ember$FEATURES = _ember.default.FEATURES).isEnabled.apply(_Ember$FEATURES, arguments);
825
+ }
826
+ });
827
+ define("ember-data/-private/initializers/data-adapter", ["exports", "ember-data/-private/system/debug/debug-adapter"], function (exports, _emberDataPrivateSystemDebugDebugAdapter) {
828
+ exports.default = initializeDebugAdapter;
829
+
830
+ /**
831
+ Configures a registry with injections on Ember applications
832
+ for the Ember-Data store. Accepts an optional namespace argument.
833
+
834
+ @method initializeStoreInjections
835
+ @param {Ember.Registry} registry
836
+ */
837
+
838
+ function initializeDebugAdapter(registry) {
839
+ registry.register('data-adapter:main', _emberDataPrivateSystemDebugDebugAdapter.default);
840
+ }
841
+ });
842
+ define('ember-data/-private/initializers/store-injections', ['exports'], function (exports) {
843
+ exports.default = initializeStoreInjections;
844
+ /**
845
+ Configures a registry with injections on Ember applications
846
+ for the Ember-Data store. Accepts an optional namespace argument.
847
+
848
+ @method initializeStoreInjections
849
+ @param {Ember.Registry} registry
850
+ */
851
+
852
+ function initializeStoreInjections(registry) {
853
+ // registry.injection for Ember < 2.1.0
854
+ // application.inject for Ember 2.1.0+
855
+ var inject = registry.inject || registry.injection;
856
+ inject.call(registry, 'controller', 'store', 'service:store');
857
+ inject.call(registry, 'route', 'store', 'service:store');
858
+ inject.call(registry, 'data-adapter', 'store', 'service:store');
859
+ }
860
+ });
861
+ define("ember-data/-private/initializers/store", ["exports", "ember-data/-private/system/store", "ember-data/-private/serializers", "ember-data/-private/adapters"], function (exports, _emberDataPrivateSystemStore, _emberDataPrivateSerializers, _emberDataPrivateAdapters) {
862
+ exports.default = initializeStore;
863
+
864
+ function has(applicationOrRegistry, fullName) {
865
+ if (applicationOrRegistry.has) {
866
+ // < 2.1.0
867
+ return applicationOrRegistry.has(fullName);
868
+ } else {
869
+ // 2.1.0+
870
+ return applicationOrRegistry.hasRegistration(fullName);
871
+ }
872
+ }
873
+
874
+ /**
875
+ Configures a registry for use with an Ember-Data
876
+ store. Accepts an optional namespace argument.
877
+
878
+ @method initializeStore
879
+ @param {Ember.Registry} registry
880
+ */
881
+
882
+ function initializeStore(registry) {
883
+ // registry.optionsForType for Ember < 2.1.0
884
+ // application.registerOptionsForType for Ember 2.1.0+
885
+ var registerOptionsForType = registry.registerOptionsForType || registry.optionsForType;
886
+ registerOptionsForType.call(registry, 'serializer', { singleton: false });
887
+ registerOptionsForType.call(registry, 'adapter', { singleton: false });
888
+
889
+ registry.register('serializer:-default', _emberDataPrivateSerializers.JSONSerializer);
890
+ registry.register('serializer:-rest', _emberDataPrivateSerializers.RESTSerializer);
891
+ registry.register('adapter:-rest', _emberDataPrivateAdapters.RESTAdapter);
892
+
893
+ registry.register('adapter:-json-api', _emberDataPrivateAdapters.JSONAPIAdapter);
894
+ registry.register('serializer:-json-api', _emberDataPrivateSerializers.JSONAPISerializer);
895
+
896
+ if (!has(registry, 'service:store')) {
897
+ registry.register('service:store', _emberDataPrivateSystemStore.default);
898
+ }
899
+ }
900
+ });
901
+ define('ember-data/-private/initializers/transforms', ['exports', 'ember-data/-private/transforms'], function (exports, _emberDataPrivateTransforms) {
902
+ exports.default = initializeTransforms;
903
+
904
+ /**
905
+ Configures a registry for use with Ember-Data
906
+ transforms.
907
+
908
+ @method initializeTransforms
909
+ @param {Ember.Registry} registry
910
+ */
911
+
912
+ function initializeTransforms(registry) {
913
+ registry.register('transform:boolean', _emberDataPrivateTransforms.BooleanTransform);
914
+ registry.register('transform:date', _emberDataPrivateTransforms.DateTransform);
915
+ registry.register('transform:number', _emberDataPrivateTransforms.NumberTransform);
916
+ registry.register('transform:string', _emberDataPrivateTransforms.StringTransform);
917
+ }
918
+ });
919
+ define('ember-data/-private/instance-initializers/initialize-store-service', ['exports'], function (exports) {
920
+ exports.default = initializeStoreService;
921
+ /**
922
+ Configures a registry for use with an Ember-Data
923
+ store.
924
+
925
+ @method initializeStore
926
+ @param {Ember.ApplicationInstance} applicationOrRegistry
927
+ */
928
+
929
+ function initializeStoreService(application) {
930
+ var container = application.lookup ? application : application.container;
931
+ // Eagerly generate the store so defaultStore is populated.
932
+ container.lookup('service:store');
933
+ }
934
+ });
935
+ define("ember-data/-private/serializers", ["exports", "ember-data/serializers/json-api", "ember-data/serializers/json", "ember-data/serializers/rest"], function (exports, _emberDataSerializersJsonApi, _emberDataSerializersJson, _emberDataSerializersRest) {
936
+ exports.JSONAPISerializer = _emberDataSerializersJsonApi.default;
937
+ exports.JSONSerializer = _emberDataSerializersJson.default;
938
+ exports.RESTSerializer = _emberDataSerializersRest.default;
939
+ });
940
+ /**
941
+ @module ember-data
942
+ */
943
+ define('ember-data/-private/serializers/embedded-records-mixin', ['exports', 'ember', 'ember-data/-private/debug'], function (exports, _ember, _emberDataPrivateDebug) {
944
+ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
945
+
946
+ var get = _ember.default.get;
947
+ var set = _ember.default.set;
948
+ var camelize = _ember.default.String.camelize;
949
+
950
+ /**
951
+ ## Using Embedded Records
952
+
953
+ `DS.EmbeddedRecordsMixin` supports serializing embedded records.
954
+
955
+ To set up embedded records, include the mixin when extending a serializer,
956
+ then define and configure embedded (model) relationships.
957
+
958
+ Below is an example of a per-type serializer (`post` type).
959
+
960
+ ```app/serializers/post.js
961
+ import DS from 'ember-data';
962
+
963
+ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
964
+ attrs: {
965
+ author: { embedded: 'always' },
966
+ comments: { serialize: 'ids' }
967
+ }
968
+ });
969
+ ```
970
+ Note that this use of `{ embedded: 'always' }` is unrelated to
971
+ the `{ embedded: 'always' }` that is defined as an option on `DS.attr` as part of
972
+ defining a model while working with the `ActiveModelSerializer`. Nevertheless,
973
+ using `{ embedded: 'always' }` as an option to `DS.attr` is not a valid way to setup
974
+ embedded records.
975
+
976
+ The `attrs` option for a resource `{ embedded: 'always' }` is shorthand for:
977
+
978
+ ```js
979
+ {
980
+ serialize: 'records',
981
+ deserialize: 'records'
982
+ }
983
+ ```
984
+
985
+ ### Configuring Attrs
986
+
987
+ A resource's `attrs` option may be set to use `ids`, `records` or false for the
988
+ `serialize` and `deserialize` settings.
989
+
990
+ The `attrs` property can be set on the `ApplicationSerializer` or a per-type
991
+ serializer.
992
+
993
+ In the case where embedded JSON is expected while extracting a payload (reading)
994
+ the setting is `deserialize: 'records'`, there is no need to use `ids` when
995
+ extracting as that is the default behavior without this mixin if you are using
996
+ the vanilla `EmbeddedRecordsMixin`. Likewise, to embed JSON in the payload while
997
+ serializing `serialize: 'records'` is the setting to use. There is an option of
998
+ not embedding JSON in the serialized payload by using `serialize: 'ids'`. If you
999
+ do not want the relationship sent at all, you can use `serialize: false`.
1000
+
1001
+
1002
+ ### EmbeddedRecordsMixin defaults
1003
+ If you do not overwrite `attrs` for a specific relationship, the `EmbeddedRecordsMixin`
1004
+ will behave in the following way:
1005
+
1006
+ BelongsTo: `{ serialize: 'id', deserialize: 'id' }`
1007
+ HasMany: `{ serialize: false, deserialize: 'ids' }`
1008
+
1009
+ ### Model Relationships
1010
+
1011
+ Embedded records must have a model defined to be extracted and serialized. Note that
1012
+ when defining any relationships on your model such as `belongsTo` and `hasMany`, you
1013
+ should not both specify `async: true` and also indicate through the serializer's
1014
+ `attrs` attribute that the related model should be embedded for deserialization.
1015
+ If a model is declared embedded for deserialization (`embedded: 'always'` or `deserialize: 'records'`),
1016
+ then do not use `async: true`.
1017
+
1018
+ To successfully extract and serialize embedded records the model relationships
1019
+ must be setup correcty. See the
1020
+ [defining relationships](/guides/models/defining-models/#toc_defining-relationships)
1021
+ section of the **Defining Models** guide page.
1022
+
1023
+ Records without an `id` property are not considered embedded records, model
1024
+ instances must have an `id` property to be used with Ember Data.
1025
+
1026
+ ### Example JSON payloads, Models and Serializers
1027
+
1028
+ **When customizing a serializer it is important to grok what the customizations
1029
+ are. Please read the docs for the methods this mixin provides, in case you need
1030
+ to modify it to fit your specific needs.**
1031
+
1032
+ For example review the docs for each method of this mixin:
1033
+ * [normalize](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_normalize)
1034
+ * [serializeBelongsTo](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeBelongsTo)
1035
+ * [serializeHasMany](/api/data/classes/DS.EmbeddedRecordsMixin.html#method_serializeHasMany)
1036
+
1037
+ @class EmbeddedRecordsMixin
1038
+ @namespace DS
1039
+ */
1040
+ exports.default = _ember.default.Mixin.create({
1041
+
1042
+ /**
1043
+ Normalize the record and recursively normalize/extract all the embedded records
1044
+ while pushing them into the store as they are encountered
1045
+ A payload with an attr configured for embedded records needs to be extracted:
1046
+ ```js
1047
+ {
1048
+ "post": {
1049
+ "id": "1"
1050
+ "title": "Rails is omakase",
1051
+ "comments": [{
1052
+ "id": "1",
1053
+ "body": "Rails is unagi"
1054
+ }, {
1055
+ "id": "2",
1056
+ "body": "Omakase O_o"
1057
+ }]
1058
+ }
1059
+ }
1060
+ ```
1061
+ @method normalize
1062
+ @param {DS.Model} typeClass
1063
+ @param {Object} hash to be normalized
1064
+ @param {String} prop the hash has been referenced by
1065
+ @return {Object} the normalized hash
1066
+ **/
1067
+ normalize: function (typeClass, hash, prop) {
1068
+ var normalizedHash = this._super(typeClass, hash, prop);
1069
+ return this._extractEmbeddedRecords(this, this.store, typeClass, normalizedHash);
1070
+ },
1071
+
1072
+ keyForRelationship: function (key, typeClass, method) {
1073
+ if (method === 'serialize' && this.hasSerializeRecordsOption(key) || method === 'deserialize' && this.hasDeserializeRecordsOption(key)) {
1074
+ return this.keyForAttribute(key, method);
1075
+ } else {
1076
+ return this._super(key, typeClass, method) || key;
1077
+ }
1078
+ },
1079
+
1080
+ /**
1081
+ Serialize `belongsTo` relationship when it is configured as an embedded object.
1082
+ This example of an author model belongs to a post model:
1083
+ ```js
1084
+ Post = DS.Model.extend({
1085
+ title: DS.attr('string'),
1086
+ body: DS.attr('string'),
1087
+ author: DS.belongsTo('author')
1088
+ });
1089
+ Author = DS.Model.extend({
1090
+ name: DS.attr('string'),
1091
+ post: DS.belongsTo('post')
1092
+ });
1093
+ ```
1094
+ Use a custom (type) serializer for the post model to configure embedded author
1095
+ ```app/serializers/post.js
1096
+ import DS from 'ember-data;
1097
+ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
1098
+ attrs: {
1099
+ author: { embedded: 'always' }
1100
+ }
1101
+ })
1102
+ ```
1103
+ A payload with an attribute configured for embedded records can serialize
1104
+ the records together under the root attribute's payload:
1105
+ ```js
1106
+ {
1107
+ "post": {
1108
+ "id": "1"
1109
+ "title": "Rails is omakase",
1110
+ "author": {
1111
+ "id": "2"
1112
+ "name": "dhh"
1113
+ }
1114
+ }
1115
+ }
1116
+ ```
1117
+ @method serializeBelongsTo
1118
+ @param {DS.Snapshot} snapshot
1119
+ @param {Object} json
1120
+ @param {Object} relationship
1121
+ */
1122
+ serializeBelongsTo: function (snapshot, json, relationship) {
1123
+ var attr = relationship.key;
1124
+ if (this.noSerializeOptionSpecified(attr)) {
1125
+ this._super(snapshot, json, relationship);
1126
+ return;
1127
+ }
1128
+ var includeIds = this.hasSerializeIdsOption(attr);
1129
+ var includeRecords = this.hasSerializeRecordsOption(attr);
1130
+ var embeddedSnapshot = snapshot.belongsTo(attr);
1131
+ var key;
1132
+ if (includeIds) {
1133
+ key = this.keyForRelationship(attr, relationship.kind, 'serialize');
1134
+ if (!embeddedSnapshot) {
1135
+ json[key] = null;
1136
+ } else {
1137
+ json[key] = embeddedSnapshot.id;
1138
+
1139
+ if (relationship.options.polymorphic) {
1140
+ this.serializePolymorphicType(snapshot, json, relationship);
1141
+ }
1142
+ }
1143
+ } else if (includeRecords) {
1144
+ this._serializeEmbeddedBelongsTo(snapshot, json, relationship);
1145
+ }
1146
+ },
1147
+
1148
+ _serializeEmbeddedBelongsTo: function (snapshot, json, relationship) {
1149
+ var embeddedSnapshot = snapshot.belongsTo(relationship.key);
1150
+ var serializedKey = this.keyForRelationship(relationship.key, 'serialize');
1151
+ if (!embeddedSnapshot) {
1152
+ json[serializedKey] = null;
1153
+ } else {
1154
+ json[serializedKey] = embeddedSnapshot.record.serialize({ includeId: true });
1155
+ this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, json[serializedKey]);
1156
+
1157
+ if (relationship.options.polymorphic) {
1158
+ this.serializePolymorphicType(snapshot, json, relationship);
1159
+ }
1160
+ }
1161
+ },
1162
+
1163
+ /**
1164
+ Serialize `hasMany` relationship when it is configured as embedded objects.
1165
+ This example of a post model has many comments:
1166
+ ```js
1167
+ Post = DS.Model.extend({
1168
+ title: DS.attr('string'),
1169
+ body: DS.attr('string'),
1170
+ comments: DS.hasMany('comment')
1171
+ });
1172
+ Comment = DS.Model.extend({
1173
+ body: DS.attr('string'),
1174
+ post: DS.belongsTo('post')
1175
+ });
1176
+ ```
1177
+ Use a custom (type) serializer for the post model to configure embedded comments
1178
+ ```app/serializers/post.js
1179
+ import DS from 'ember-data;
1180
+ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
1181
+ attrs: {
1182
+ comments: { embedded: 'always' }
1183
+ }
1184
+ })
1185
+ ```
1186
+ A payload with an attribute configured for embedded records can serialize
1187
+ the records together under the root attribute's payload:
1188
+ ```js
1189
+ {
1190
+ "post": {
1191
+ "id": "1"
1192
+ "title": "Rails is omakase",
1193
+ "body": "I want this for my ORM, I want that for my template language..."
1194
+ "comments": [{
1195
+ "id": "1",
1196
+ "body": "Rails is unagi"
1197
+ }, {
1198
+ "id": "2",
1199
+ "body": "Omakase O_o"
1200
+ }]
1201
+ }
1202
+ }
1203
+ ```
1204
+ The attrs options object can use more specific instruction for extracting and
1205
+ serializing. When serializing, an option to embed `ids` or `records` can be set.
1206
+ When extracting the only option is `records`.
1207
+ So `{ embedded: 'always' }` is shorthand for:
1208
+ `{ serialize: 'records', deserialize: 'records' }`
1209
+ To embed the `ids` for a related object (using a hasMany relationship):
1210
+ ```app/serializers/post.js
1211
+ import DS from 'ember-data;
1212
+ export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
1213
+ attrs: {
1214
+ comments: { serialize: 'ids', deserialize: 'records' }
1215
+ }
1216
+ })
1217
+ ```
1218
+ ```js
1219
+ {
1220
+ "post": {
1221
+ "id": "1"
1222
+ "title": "Rails is omakase",
1223
+ "body": "I want this for my ORM, I want that for my template language..."
1224
+ "comments": ["1", "2"]
1225
+ }
1226
+ }
1227
+ ```
1228
+ @method serializeHasMany
1229
+ @param {DS.Snapshot} snapshot
1230
+ @param {Object} json
1231
+ @param {Object} relationship
1232
+ */
1233
+ serializeHasMany: function (snapshot, json, relationship) {
1234
+ var attr = relationship.key;
1235
+ if (this.noSerializeOptionSpecified(attr)) {
1236
+ this._super(snapshot, json, relationship);
1237
+ return;
1238
+ }
1239
+ var includeIds = this.hasSerializeIdsOption(attr);
1240
+ var includeRecords = this.hasSerializeRecordsOption(attr);
1241
+ if (includeIds) {
1242
+ var serializedKey = this.keyForRelationship(attr, relationship.kind, 'serialize');
1243
+ json[serializedKey] = snapshot.hasMany(attr, { ids: true });
1244
+ } else if (includeRecords) {
1245
+ this._serializeEmbeddedHasMany(snapshot, json, relationship);
1246
+ }
1247
+ },
1248
+
1249
+ _serializeEmbeddedHasMany: function (snapshot, json, relationship) {
1250
+ var serializedKey = this.keyForRelationship(relationship.key, 'serialize');
1251
+
1252
+ (0, _emberDataPrivateDebug.warn)('The embedded relationship \'' + serializedKey + '\' is undefined for \'' + snapshot.modelName + '\' with id \'' + snapshot.id + '\'. Please include it in your original payload.', _ember.default.typeOf(snapshot.hasMany(relationship.key)) !== 'undefined', { id: 'ds.serializer.embedded-relationship-undefined' });
1253
+
1254
+ json[serializedKey] = this._generateSerializedHasMany(snapshot, relationship);
1255
+ },
1256
+
1257
+ /*
1258
+ Returns an array of embedded records serialized to JSON
1259
+ */
1260
+ _generateSerializedHasMany: function (snapshot, relationship) {
1261
+ var _this = this;
1262
+
1263
+ var hasMany = snapshot.hasMany(relationship.key);
1264
+ return _ember.default.A(hasMany).map(function (embeddedSnapshot) {
1265
+ var embeddedJson = embeddedSnapshot.record.serialize({ includeId: true });
1266
+ _this.removeEmbeddedForeignKey(snapshot, embeddedSnapshot, relationship, embeddedJson);
1267
+ return embeddedJson;
1268
+ });
1269
+ },
1270
+
1271
+ /**
1272
+ When serializing an embedded record, modify the property (in the json payload)
1273
+ that refers to the parent record (foreign key for relationship).
1274
+ Serializing a `belongsTo` relationship removes the property that refers to the
1275
+ parent record
1276
+ Serializing a `hasMany` relationship does not remove the property that refers to
1277
+ the parent record.
1278
+ @method removeEmbeddedForeignKey
1279
+ @param {DS.Snapshot} snapshot
1280
+ @param {DS.Snapshot} embeddedSnapshot
1281
+ @param {Object} relationship
1282
+ @param {Object} json
1283
+ */
1284
+ removeEmbeddedForeignKey: function (snapshot, embeddedSnapshot, relationship, json) {
1285
+ if (relationship.kind === 'hasMany') {
1286
+ return;
1287
+ } else if (relationship.kind === 'belongsTo') {
1288
+ var parentRecord = snapshot.type.inverseFor(relationship.key, this.store);
1289
+ if (parentRecord) {
1290
+ var name = parentRecord.name;
1291
+ var embeddedSerializer = this.store.serializerFor(embeddedSnapshot.modelName);
1292
+ var parentKey = embeddedSerializer.keyForRelationship(name, parentRecord.kind, 'deserialize');
1293
+ if (parentKey) {
1294
+ delete json[parentKey];
1295
+ }
1296
+ }
1297
+ }
1298
+ },
1299
+
1300
+ // checks config for attrs option to embedded (always) - serialize and deserialize
1301
+ hasEmbeddedAlwaysOption: function (attr) {
1302
+ var option = this.attrsOption(attr);
1303
+ return option && option.embedded === 'always';
1304
+ },
1305
+
1306
+ // checks config for attrs option to serialize ids
1307
+ hasSerializeRecordsOption: function (attr) {
1308
+ var alwaysEmbed = this.hasEmbeddedAlwaysOption(attr);
1309
+ var option = this.attrsOption(attr);
1310
+ return alwaysEmbed || option && option.serialize === 'records';
1311
+ },
1312
+
1313
+ // checks config for attrs option to serialize records
1314
+ hasSerializeIdsOption: function (attr) {
1315
+ var option = this.attrsOption(attr);
1316
+ return option && (option.serialize === 'ids' || option.serialize === 'id');
1317
+ },
1318
+
1319
+ // checks config for attrs option to serialize records
1320
+ noSerializeOptionSpecified: function (attr) {
1321
+ var option = this.attrsOption(attr);
1322
+ return !(option && (option.serialize || option.embedded));
1323
+ },
1324
+
1325
+ // checks config for attrs option to deserialize records
1326
+ // a defined option object for a resource is treated the same as
1327
+ // `deserialize: 'records'`
1328
+ hasDeserializeRecordsOption: function (attr) {
1329
+ var alwaysEmbed = this.hasEmbeddedAlwaysOption(attr);
1330
+ var option = this.attrsOption(attr);
1331
+ return alwaysEmbed || option && option.deserialize === 'records';
1332
+ },
1333
+
1334
+ attrsOption: function (attr) {
1335
+ var attrs = this.get('attrs');
1336
+ return attrs && (attrs[camelize(attr)] || attrs[attr]);
1337
+ },
1338
+
1339
+ /**
1340
+ @method _extractEmbeddedRecords
1341
+ @private
1342
+ */
1343
+ _extractEmbeddedRecords: function (serializer, store, typeClass, partial) {
1344
+ var _this2 = this;
1345
+
1346
+ typeClass.eachRelationship(function (key, relationship) {
1347
+ if (serializer.hasDeserializeRecordsOption(key)) {
1348
+ if (relationship.kind === "hasMany") {
1349
+ _this2._extractEmbeddedHasMany(store, key, partial, relationship);
1350
+ }
1351
+ if (relationship.kind === "belongsTo") {
1352
+ _this2._extractEmbeddedBelongsTo(store, key, partial, relationship);
1353
+ }
1354
+ }
1355
+ });
1356
+ return partial;
1357
+ },
1358
+
1359
+ /**
1360
+ @method _extractEmbeddedHasMany
1361
+ @private
1362
+ */
1363
+ _extractEmbeddedHasMany: function (store, key, hash, relationshipMeta) {
1364
+ var _this3 = this;
1365
+
1366
+ var relationshipHash = get(hash, 'data.relationships.' + key + '.data');
1367
+ if (!relationshipHash) {
1368
+ return;
1369
+ }
1370
+
1371
+ var hasMany = relationshipHash.map(function (item) {
1372
+ var _normalizeEmbeddedRelationship = _this3._normalizeEmbeddedRelationship(store, relationshipMeta, item);
1373
+
1374
+ var data = _normalizeEmbeddedRelationship.data;
1375
+ var included = _normalizeEmbeddedRelationship.included;
1376
+
1377
+ hash.included = hash.included || [];
1378
+ hash.included.push(data);
1379
+ if (included) {
1380
+ var _hash$included;
1381
+
1382
+ (_hash$included = hash.included).push.apply(_hash$included, _toConsumableArray(included));
1383
+ }
1384
+
1385
+ return { id: data.id, type: data.type };
1386
+ });
1387
+
1388
+ var relationship = { data: hasMany };
1389
+ set(hash, 'data.relationships.' + key, relationship);
1390
+ },
1391
+
1392
+ /**
1393
+ @method _extractEmbeddedBelongsTo
1394
+ @private
1395
+ */
1396
+ _extractEmbeddedBelongsTo: function (store, key, hash, relationshipMeta) {
1397
+ var relationshipHash = get(hash, 'data.relationships.' + key + '.data');
1398
+ if (!relationshipHash) {
1399
+ return;
1400
+ }
1401
+
1402
+ var _normalizeEmbeddedRelationship2 = this._normalizeEmbeddedRelationship(store, relationshipMeta, relationshipHash);
1403
+
1404
+ var data = _normalizeEmbeddedRelationship2.data;
1405
+ var included = _normalizeEmbeddedRelationship2.included;
1406
+
1407
+ hash.included = hash.included || [];
1408
+ hash.included.push(data);
1409
+ if (included) {
1410
+ var _hash$included2;
1411
+
1412
+ (_hash$included2 = hash.included).push.apply(_hash$included2, _toConsumableArray(included));
1413
+ }
1414
+
1415
+ var belongsTo = { id: data.id, type: data.type };
1416
+ var relationship = { data: belongsTo };
1417
+
1418
+ set(hash, 'data.relationships.' + key, relationship);
1419
+ },
1420
+
1421
+ /**
1422
+ @method _normalizeEmbeddedRelationship
1423
+ @private
1424
+ */
1425
+ _normalizeEmbeddedRelationship: function (store, relationshipMeta, relationshipHash) {
1426
+ var modelName = relationshipMeta.type;
1427
+ if (relationshipMeta.options.polymorphic) {
1428
+ modelName = relationshipHash.type;
1429
+ }
1430
+ var modelClass = store.modelFor(modelName);
1431
+ var serializer = store.serializerFor(modelName);
1432
+
1433
+ return serializer.normalize(modelClass, relationshipHash, null);
1434
+ }
1435
+ });
1436
+ });
1437
+ define("ember-data/-private/system/clone-null", ["exports", "ember-data/-private/system/empty-object"], function (exports, _emberDataPrivateSystemEmptyObject) {
1438
+ exports.default = cloneNull;
1439
+
1440
+ function cloneNull(source) {
1441
+ var clone = new _emberDataPrivateSystemEmptyObject.default();
1442
+ for (var key in source) {
1443
+ clone[key] = source[key];
1444
+ }
1445
+ return clone;
1446
+ }
1447
+ });
1448
+ define('ember-data/-private/system/coerce-id', ['exports'], function (exports) {
1449
+ exports.default = coerceId;
1450
+ // Used by the store to normalize IDs entering the store. Despite the fact
1451
+ // that developers may provide IDs as numbers (e.g., `store.findRecord('person', 1)`),
1452
+ // it is important that internally we use strings, since IDs may be serialized
1453
+ // and lose type information. For example, Ember's router may put a record's
1454
+ // ID into the URL, and if we later try to deserialize that URL and find the
1455
+ // corresponding record, we will not know if it is a string or a number.
1456
+
1457
+ function coerceId(id) {
1458
+ return id == null || id === '' ? null : id + '';
1459
+ }
1460
+ });
1461
+ define('ember-data/-private/system/container-proxy', ['exports', 'ember-data/-private/debug'], function (exports, _emberDataPrivateDebug) {
1462
+ exports.default = ContainerProxy;
1463
+
1464
+ /*
1465
+ This is used internally to enable deprecation of container paths and provide
1466
+ a decent message to the user indicating how to fix the issue.
1467
+
1468
+ @class ContainerProxy
1469
+ @namespace DS
1470
+ @private
1471
+ */
1472
+
1473
+ function ContainerProxy(container) {
1474
+ this.container = container;
1475
+ }
1476
+
1477
+ ContainerProxy.prototype.aliasedFactory = function (path, preLookup) {
1478
+ var _this = this;
1479
+
1480
+ return {
1481
+ create: function () {
1482
+ if (preLookup) {
1483
+ preLookup();
1484
+ }
1485
+
1486
+ return _this.container.lookup(path);
1487
+ }
1488
+ };
1489
+ };
1490
+
1491
+ ContainerProxy.prototype.registerAlias = function (source, dest, preLookup) {
1492
+ var factory = this.aliasedFactory(dest, preLookup);
1493
+
1494
+ return this.container.register(source, factory);
1495
+ };
1496
+
1497
+ ContainerProxy.prototype.registerDeprecation = function (deprecated, valid) {
1498
+ var preLookupCallback = function () {
1499
+ (0, _emberDataPrivateDebug.deprecate)('You tried to look up \'' + deprecated + '\', but this has been deprecated in favor of \'' + valid + '\'.', false, {
1500
+ id: 'ds.store.deprecated-lookup',
1501
+ until: '2.0.0'
1502
+ });
1503
+ };
1504
+
1505
+ return this.registerAlias(deprecated, valid, preLookupCallback);
1506
+ };
1507
+
1508
+ ContainerProxy.prototype.registerDeprecations = function (proxyPairs) {
1509
+ var i, proxyPair, deprecated, valid;
1510
+
1511
+ for (i = proxyPairs.length; i > 0; i--) {
1512
+ proxyPair = proxyPairs[i - 1];
1513
+ deprecated = proxyPair['deprecated'];
1514
+ valid = proxyPair['valid'];
1515
+
1516
+ this.registerDeprecation(deprecated, valid);
1517
+ }
1518
+ };
1519
+ });
1520
+ define("ember-data/-private/system/debug", ["exports", "ember-data/-private/system/debug/debug-adapter"], function (exports, _emberDataPrivateSystemDebugDebugAdapter) {
1521
+ exports.default = _emberDataPrivateSystemDebugDebugAdapter.default;
1522
+ });
1523
+ /**
1524
+ @module ember-data
1525
+ */
1526
+ define('ember-data/-private/system/debug/debug-adapter', ['exports', 'ember', 'ember-data/model'], function (exports, _ember, _emberDataModel) {
1527
+ var get = _ember.default.get;
1528
+ var capitalize = _ember.default.String.capitalize;
1529
+ var underscore = _ember.default.String.underscore;
1530
+ var assert = _ember.default.assert;
1531
+
1532
+ /*
1533
+ Extend `Ember.DataAdapter` with ED specific code.
1534
+
1535
+ @class DebugAdapter
1536
+ @namespace DS
1537
+ @extends Ember.DataAdapter
1538
+ @private
1539
+ */
1540
+ exports.default = _ember.default.DataAdapter.extend({
1541
+ getFilters: function () {
1542
+ return [{ name: 'isNew', desc: 'New' }, { name: 'isModified', desc: 'Modified' }, { name: 'isClean', desc: 'Clean' }];
1543
+ },
1544
+
1545
+ detect: function (typeClass) {
1546
+ return typeClass !== _emberDataModel.default && _emberDataModel.default.detect(typeClass);
1547
+ },
1548
+
1549
+ columnsForType: function (typeClass) {
1550
+ var columns = [{
1551
+ name: 'id',
1552
+ desc: 'Id'
1553
+ }];
1554
+ var count = 0;
1555
+ var self = this;
1556
+ get(typeClass, 'attributes').forEach(function (meta, name) {
1557
+ if (count++ > self.attributeLimit) {
1558
+ return false;
1559
+ }
1560
+ var desc = capitalize(underscore(name).replace('_', ' '));
1561
+ columns.push({ name: name, desc: desc });
1562
+ });
1563
+ return columns;
1564
+ },
1565
+
1566
+ getRecords: function (modelClass, modelName) {
1567
+ if (arguments.length < 2) {
1568
+ // Legacy Ember.js < 1.13 support
1569
+ var containerKey = modelClass._debugContainerKey;
1570
+ if (containerKey) {
1571
+ var match = containerKey.match(/model:(.*)/);
1572
+ if (match) {
1573
+ modelName = match[1];
1574
+ }
1575
+ }
1576
+ }
1577
+ assert("Cannot find model name. Please upgrade to Ember.js >= 1.13 for Ember Inspector support", !!modelName);
1578
+ return this.get('store').peekAll(modelName);
1579
+ },
1580
+
1581
+ getRecordColumnValues: function (record) {
1582
+ var _this = this;
1583
+
1584
+ var count = 0;
1585
+ var columnValues = { id: get(record, 'id') };
1586
+
1587
+ record.eachAttribute(function (key) {
1588
+ if (count++ > _this.attributeLimit) {
1589
+ return false;
1590
+ }
1591
+ var value = get(record, key);
1592
+ columnValues[key] = value;
1593
+ });
1594
+ return columnValues;
1595
+ },
1596
+
1597
+ getRecordKeywords: function (record) {
1598
+ var keywords = [];
1599
+ var keys = _ember.default.A(['id']);
1600
+ record.eachAttribute(function (key) {
1601
+ return keys.push(key);
1602
+ });
1603
+ keys.forEach(function (key) {
1604
+ return keywords.push(get(record, key));
1605
+ });
1606
+ return keywords;
1607
+ },
1608
+
1609
+ getRecordFilterValues: function (record) {
1610
+ return {
1611
+ isNew: record.get('isNew'),
1612
+ isModified: record.get('hasDirtyAttributes') && !record.get('isNew'),
1613
+ isClean: !record.get('hasDirtyAttributes')
1614
+ };
1615
+ },
1616
+
1617
+ getRecordColor: function (record) {
1618
+ var color = 'black';
1619
+ if (record.get('isNew')) {
1620
+ color = 'green';
1621
+ } else if (record.get('hasDirtyAttributes')) {
1622
+ color = 'blue';
1623
+ }
1624
+ return color;
1625
+ },
1626
+
1627
+ observeRecord: function (record, recordUpdated) {
1628
+ var releaseMethods = _ember.default.A();
1629
+ var keysToObserve = _ember.default.A(['id', 'isNew', 'hasDirtyAttributes']);
1630
+
1631
+ record.eachAttribute(function (key) {
1632
+ return keysToObserve.push(key);
1633
+ });
1634
+ var adapter = this;
1635
+
1636
+ keysToObserve.forEach(function (key) {
1637
+ var handler = function () {
1638
+ recordUpdated(adapter.wrapRecord(record));
1639
+ };
1640
+ _ember.default.addObserver(record, key, handler);
1641
+ releaseMethods.push(function () {
1642
+ _ember.default.removeObserver(record, key, handler);
1643
+ });
1644
+ });
1645
+
1646
+ var release = function () {
1647
+ releaseMethods.forEach(function (fn) {
1648
+ return fn();
1649
+ });
1650
+ };
1651
+
1652
+ return release;
1653
+ }
1654
+ });
1655
+ });
1656
+ /**
1657
+ @module ember-data
1658
+ */
1659
+ define('ember-data/-private/system/debug/debug-info', ['exports', 'ember'], function (exports, _ember) {
1660
+ exports.default = _ember.default.Mixin.create({
1661
+
1662
+ /**
1663
+ Provides info about the model for debugging purposes
1664
+ by grouping the properties into more semantic groups.
1665
+ Meant to be used by debugging tools such as the Chrome Ember Extension.
1666
+ - Groups all attributes in "Attributes" group.
1667
+ - Groups all belongsTo relationships in "Belongs To" group.
1668
+ - Groups all hasMany relationships in "Has Many" group.
1669
+ - Groups all flags in "Flags" group.
1670
+ - Flags relationship CPs as expensive properties.
1671
+ @method _debugInfo
1672
+ @for DS.Model
1673
+ @private
1674
+ */
1675
+ _debugInfo: function () {
1676
+ var attributes = ['id'];
1677
+ var relationships = { belongsTo: [], hasMany: [] };
1678
+ var expensiveProperties = [];
1679
+
1680
+ this.eachAttribute(function (name, meta) {
1681
+ return attributes.push(name);
1682
+ });
1683
+
1684
+ this.eachRelationship(function (name, relationship) {
1685
+ relationships[relationship.kind].push(name);
1686
+ expensiveProperties.push(name);
1687
+ });
1688
+
1689
+ var groups = [{
1690
+ name: 'Attributes',
1691
+ properties: attributes,
1692
+ expand: true
1693
+ }, {
1694
+ name: 'Belongs To',
1695
+ properties: relationships.belongsTo,
1696
+ expand: true
1697
+ }, {
1698
+ name: 'Has Many',
1699
+ properties: relationships.hasMany,
1700
+ expand: true
1701
+ }, {
1702
+ name: 'Flags',
1703
+ properties: ['isLoaded', 'hasDirtyAttributes', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid']
1704
+ }];
1705
+
1706
+ return {
1707
+ propertyInfo: {
1708
+ // include all other mixins / properties (not just the grouped ones)
1709
+ includeOtherProperties: true,
1710
+ groups: groups,
1711
+ // don't pre-calculate unless cached
1712
+ expensiveProperties: expensiveProperties
1713
+ }
1714
+ };
1715
+ }
1716
+ });
1717
+ });
1718
+ define("ember-data/-private/system/empty-object", ["exports"], function (exports) {
1719
+ exports.default = EmptyObject;
1720
+ // This exists because `Object.create(null)` is absurdly slow compared
1721
+ // to `new EmptyObject()`. In either case, you want a null prototype
1722
+ // when you're treating the object instances as arbitrary dictionaries
1723
+ // and don't want your keys colliding with build-in methods on the
1724
+ // default object prototype.
1725
+ var proto = Object.create(null, {
1726
+ // without this, we will always still end up with (new
1727
+ // EmptyObject()).constructor === Object
1728
+ constructor: {
1729
+ value: undefined,
1730
+ enumerable: false,
1731
+ writable: true
1732
+ }
1733
+ });
1734
+
1735
+ function EmptyObject() {}
1736
+
1737
+ EmptyObject.prototype = proto;
1738
+ });
1739
+ define('ember-data/-private/system/is-array-like', ['exports'], function (exports) {
1740
+ exports.default = isArrayLike;
1741
+ /*
1742
+ We're using this to detect arrays and "array-like" objects.
1743
+
1744
+ This is a copy of the `isArray` method found in `ember-runtime/utils` as we're
1745
+ currently unable to import non-exposed modules.
1746
+
1747
+ This method was previously exposed as `Ember.isArray` but since
1748
+ https://github.com/emberjs/ember.js/pull/11463 `Ember.isArray` is an alias of
1749
+ `Array.isArray` hence removing the "array-like" part.
1750
+ */
1751
+
1752
+ function isArrayLike(obj) {
1753
+ if (!obj || obj.setInterval) {
1754
+ return false;
1755
+ }
1756
+ if (Array.isArray(obj)) {
1757
+ return true;
1758
+ }
1759
+ if (Ember.Array.detect(obj)) {
1760
+ return true;
1761
+ }
1762
+
1763
+ var type = Ember.typeOf(obj);
1764
+ if ('array' === type) {
1765
+ return true;
1766
+ }
1767
+ if (obj.length !== undefined && 'object' === type) {
1768
+ return true;
1769
+ }
1770
+ return false;
1771
+ }
1772
+ });
1773
+ define("ember-data/-private/system/many-array", ["exports", "ember", "ember-data/-private/debug", "ember-data/-private/system/promise-proxies"], function (exports, _ember, _emberDataPrivateDebug, _emberDataPrivateSystemPromiseProxies) {
1774
+
1775
+ var get = _ember.default.get;
1776
+ var set = _ember.default.set;
1777
+
1778
+ /**
1779
+ A `ManyArray` is a `MutableArray` that represents the contents of a has-many
1780
+ relationship.
1781
+
1782
+ The `ManyArray` is instantiated lazily the first time the relationship is
1783
+ requested.
1784
+
1785
+ ### Inverses
1786
+
1787
+ Often, the relationships in Ember Data applications will have
1788
+ an inverse. For example, imagine the following models are
1789
+ defined:
1790
+
1791
+ ```app/models/post.js
1792
+ import DS from 'ember-data';
1793
+
1794
+ export default DS.Model.extend({
1795
+ comments: DS.hasMany('comment')
1796
+ });
1797
+ ```
1798
+
1799
+ ```app/models/comment.js
1800
+ import DS from 'ember-data';
1801
+
1802
+ export default DS.Model.extend({
1803
+ post: DS.belongsTo('post')
1804
+ });
1805
+ ```
1806
+
1807
+ If you created a new instance of `App.Post` and added
1808
+ a `App.Comment` record to its `comments` has-many
1809
+ relationship, you would expect the comment's `post`
1810
+ property to be set to the post that contained
1811
+ the has-many.
1812
+
1813
+ We call the record to which a relationship belongs the
1814
+ relationship's _owner_.
1815
+
1816
+ @class ManyArray
1817
+ @namespace DS
1818
+ @extends Ember.Object
1819
+ @uses Ember.MutableArray, Ember.Evented
1820
+ */
1821
+ exports.default = _ember.default.Object.extend(_ember.default.MutableArray, _ember.default.Evented, {
1822
+ init: function () {
1823
+ this._super.apply(this, arguments);
1824
+ this.currentState = _ember.default.A([]);
1825
+ },
1826
+
1827
+ record: null,
1828
+
1829
+ canonicalState: null,
1830
+ currentState: null,
1831
+
1832
+ length: 0,
1833
+
1834
+ objectAt: function (index) {
1835
+ //Ember observers such as 'firstObject', 'lastObject' might do out of bounds accesses
1836
+ if (!this.currentState[index]) {
1837
+ return undefined;
1838
+ }
1839
+ return this.currentState[index].getRecord();
1840
+ },
1841
+
1842
+ flushCanonical: function () {
1843
+ //TODO make this smarter, currently its plenty stupid
1844
+ var toSet = this.canonicalState.filter(function (internalModel) {
1845
+ return !internalModel.isDeleted();
1846
+ });
1847
+
1848
+ //a hack for not removing new records
1849
+ //TODO remove once we have proper diffing
1850
+ var newRecords = this.currentState.filter(function (internalModel) {
1851
+ return internalModel.isNew();
1852
+ });
1853
+ toSet = toSet.concat(newRecords);
1854
+ var oldLength = this.length;
1855
+ this.arrayContentWillChange(0, this.length, toSet.length);
1856
+ this.set('length', toSet.length);
1857
+ this.currentState = toSet;
1858
+ this.arrayContentDidChange(0, oldLength, this.length);
1859
+ //TODO Figure out to notify only on additions and maybe only if unloaded
1860
+ this.relationship.notifyHasManyChanged();
1861
+ this.record.updateRecordArrays();
1862
+ },
1863
+ /**
1864
+ `true` if the relationship is polymorphic, `false` otherwise.
1865
+ @property {Boolean} isPolymorphic
1866
+ @private
1867
+ */
1868
+ isPolymorphic: false,
1869
+
1870
+ /**
1871
+ The loading state of this array
1872
+ @property {Boolean} isLoaded
1873
+ */
1874
+ isLoaded: false,
1875
+
1876
+ /**
1877
+ The relationship which manages this array.
1878
+ @property {ManyRelationship} relationship
1879
+ @private
1880
+ */
1881
+ relationship: null,
1882
+
1883
+ /**
1884
+ Metadata associated with the request for async hasMany relationships.
1885
+ Example
1886
+ Given that the server returns the following JSON payload when fetching a
1887
+ hasMany relationship:
1888
+ ```js
1889
+ {
1890
+ "comments": [{
1891
+ "id": 1,
1892
+ "comment": "This is the first comment",
1893
+ }, {
1894
+ // ...
1895
+ }],
1896
+ "meta": {
1897
+ "page": 1,
1898
+ "total": 5
1899
+ }
1900
+ }
1901
+ ```
1902
+ You can then access the metadata via the `meta` property:
1903
+ ```js
1904
+ post.get('comments').then(function(comments) {
1905
+ var meta = comments.get('meta');
1906
+ // meta.page => 1
1907
+ // meta.total => 5
1908
+ });
1909
+ ```
1910
+ @property {Object} meta
1911
+ @public
1912
+ */
1913
+ meta: null,
1914
+
1915
+ internalReplace: function (idx, amt, objects) {
1916
+ if (!objects) {
1917
+ objects = [];
1918
+ }
1919
+ this.arrayContentWillChange(idx, amt, objects.length);
1920
+ this.currentState.splice.apply(this.currentState, [idx, amt].concat(objects));
1921
+ this.set('length', this.currentState.length);
1922
+ this.arrayContentDidChange(idx, amt, objects.length);
1923
+ if (objects) {
1924
+ //TODO(Igor) probably needed only for unloaded records
1925
+ this.relationship.notifyHasManyChanged();
1926
+ }
1927
+ this.record.updateRecordArrays();
1928
+ },
1929
+
1930
+ //TODO(Igor) optimize
1931
+ internalRemoveRecords: function (records) {
1932
+ var index;
1933
+ for (var i = 0; i < records.length; i++) {
1934
+ index = this.currentState.indexOf(records[i]);
1935
+ this.internalReplace(index, 1);
1936
+ }
1937
+ },
1938
+
1939
+ //TODO(Igor) optimize
1940
+ internalAddRecords: function (records, idx) {
1941
+ if (idx === undefined) {
1942
+ idx = this.currentState.length;
1943
+ }
1944
+ this.internalReplace(idx, 0, records);
1945
+ },
1946
+
1947
+ replace: function (idx, amt, objects) {
1948
+ var records;
1949
+ if (amt > 0) {
1950
+ records = this.currentState.slice(idx, idx + amt);
1951
+ this.get('relationship').removeRecords(records);
1952
+ }
1953
+ if (objects) {
1954
+ this.get('relationship').addRecords(objects.map(function (obj) {
1955
+ return obj._internalModel;
1956
+ }), idx);
1957
+ }
1958
+ },
1959
+ /**
1960
+ Used for async `hasMany` arrays
1961
+ to keep track of when they will resolve.
1962
+ @property {Ember.RSVP.Promise} promise
1963
+ @private
1964
+ */
1965
+ promise: null,
1966
+
1967
+ /**
1968
+ @method loadingRecordsCount
1969
+ @param {Number} count
1970
+ @private
1971
+ */
1972
+ loadingRecordsCount: function (count) {
1973
+ this.loadingRecordsCount = count;
1974
+ },
1975
+
1976
+ /**
1977
+ @method loadedRecord
1978
+ @private
1979
+ */
1980
+ loadedRecord: function () {
1981
+ this.loadingRecordsCount--;
1982
+ if (this.loadingRecordsCount === 0) {
1983
+ set(this, 'isLoaded', true);
1984
+ this.trigger('didLoad');
1985
+ }
1986
+ },
1987
+
1988
+ /**
1989
+ @method reload
1990
+ @public
1991
+ */
1992
+ reload: function () {
1993
+ return this.relationship.reload();
1994
+ },
1995
+
1996
+ /**
1997
+ Saves all of the records in the `ManyArray`.
1998
+ Example
1999
+ ```javascript
2000
+ store.findRecord('inbox', 1).then(function(inbox) {
2001
+ inbox.get('messages').then(function(messages) {
2002
+ messages.forEach(function(message) {
2003
+ message.set('isRead', true);
2004
+ });
2005
+ messages.save()
2006
+ });
2007
+ });
2008
+ ```
2009
+ @method save
2010
+ @return {DS.PromiseArray} promise
2011
+ */
2012
+ save: function () {
2013
+ var manyArray = this;
2014
+ var promiseLabel = "DS: ManyArray#save " + get(this, 'type');
2015
+ var promise = _ember.default.RSVP.all(this.invoke("save"), promiseLabel).then(function (array) {
2016
+ return manyArray;
2017
+ }, null, "DS: ManyArray#save return ManyArray");
2018
+
2019
+ return _emberDataPrivateSystemPromiseProxies.PromiseArray.create({ promise: promise });
2020
+ },
2021
+
2022
+ /**
2023
+ Create a child record within the owner
2024
+ @method createRecord
2025
+ @private
2026
+ @param {Object} hash
2027
+ @return {DS.Model} record
2028
+ */
2029
+ createRecord: function (hash) {
2030
+ var store = get(this, 'store');
2031
+ var type = get(this, 'type');
2032
+ var record;
2033
+
2034
+ (0, _emberDataPrivateDebug.assert)("You cannot add '" + type.modelName + "' records to this polymorphic relationship.", !get(this, 'isPolymorphic'));
2035
+ record = store.createRecord(type.modelName, hash);
2036
+ this.pushObject(record);
2037
+
2038
+ return record;
2039
+ }
2040
+ });
2041
+ });
2042
+ /**
2043
+ @module ember-data
2044
+ */
2045
+ define('ember-data/-private/system/merge', ['exports'], function (exports) {
2046
+ exports.default = merge;
2047
+
2048
+ function merge(original, updates) {
2049
+ if (!updates || typeof updates !== 'object') {
2050
+ return original;
2051
+ }
2052
+
2053
+ var props = Object.keys(updates);
2054
+ var prop;
2055
+ var length = props.length;
2056
+
2057
+ for (var i = 0; i < length; i++) {
2058
+ prop = props[i];
2059
+ original[prop] = updates[prop];
2060
+ }
2061
+
2062
+ return original;
2063
+ }
2064
+ });
2065
+ define("ember-data/-private/system/model", ["exports", "ember-data/-private/system/model/model", "ember-data/attr", "ember-data/-private/system/model/states", "ember-data/-private/system/model/errors"], function (exports, _emberDataPrivateSystemModelModel, _emberDataAttr, _emberDataPrivateSystemModelStates, _emberDataPrivateSystemModelErrors) {
2066
+ exports.RootState = _emberDataPrivateSystemModelStates.default;
2067
+ exports.attr = _emberDataAttr.default;
2068
+ exports.Errors = _emberDataPrivateSystemModelErrors.default;
2069
+ exports.default = _emberDataPrivateSystemModelModel.default;
2070
+ });
2071
+ /**
2072
+ @module ember-data
2073
+ */
2074
+ define("ember-data/-private/system/model/attr", ["exports", "ember", "ember-data/-private/debug"], function (exports, _ember, _emberDataPrivateDebug) {
2075
+
2076
+ var get = _ember.default.get;
2077
+ var Map = _ember.default.Map;
2078
+
2079
+ /**
2080
+ @module ember-data
2081
+ */
2082
+
2083
+ /**
2084
+ @class Model
2085
+ @namespace DS
2086
+ */
2087
+
2088
+ var AttrClassMethodsMixin = _ember.default.Mixin.create({
2089
+ /**
2090
+ A map whose keys are the attributes of the model (properties
2091
+ described by DS.attr) and whose values are the meta object for the
2092
+ property.
2093
+ Example
2094
+ ```app/models/person.js
2095
+ import DS from 'ember-data';
2096
+ export default DS.Model.extend({
2097
+ firstName: attr('string'),
2098
+ lastName: attr('string'),
2099
+ birthday: attr('date')
2100
+ });
2101
+ ```
2102
+ ```javascript
2103
+ import Ember from 'ember';
2104
+ import Person from 'app/models/person';
2105
+ var attributes = Ember.get(Person, 'attributes')
2106
+ attributes.forEach(function(meta, name) {
2107
+ console.log(name, meta);
2108
+ });
2109
+ // prints:
2110
+ // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
2111
+ // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
2112
+ // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
2113
+ ```
2114
+ @property attributes
2115
+ @static
2116
+ @type {Ember.Map}
2117
+ @readOnly
2118
+ */
2119
+ attributes: _ember.default.computed(function () {
2120
+ var _this = this;
2121
+
2122
+ var map = Map.create();
2123
+
2124
+ this.eachComputedProperty(function (name, meta) {
2125
+ if (meta.isAttribute) {
2126
+ (0, _emberDataPrivateDebug.assert)("You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: DS.attr('<type>')` from " + _this.toString(), name !== 'id');
2127
+
2128
+ meta.name = name;
2129
+ map.set(name, meta);
2130
+ }
2131
+ });
2132
+
2133
+ return map;
2134
+ }).readOnly(),
2135
+
2136
+ /**
2137
+ A map whose keys are the attributes of the model (properties
2138
+ described by DS.attr) and whose values are type of transformation
2139
+ applied to each attribute. This map does not include any
2140
+ attributes that do not have an transformation type.
2141
+ Example
2142
+ ```app/models/person.js
2143
+ import DS from 'ember-data';
2144
+ export default DS.Model.extend({
2145
+ firstName: attr(),
2146
+ lastName: attr('string'),
2147
+ birthday: attr('date')
2148
+ });
2149
+ ```
2150
+ ```javascript
2151
+ import Ember from 'ember';
2152
+ import Person from 'app/models/person';
2153
+ var transformedAttributes = Ember.get(Person, 'transformedAttributes')
2154
+ transformedAttributes.forEach(function(field, type) {
2155
+ console.log(field, type);
2156
+ });
2157
+ // prints:
2158
+ // lastName string
2159
+ // birthday date
2160
+ ```
2161
+ @property transformedAttributes
2162
+ @static
2163
+ @type {Ember.Map}
2164
+ @readOnly
2165
+ */
2166
+ transformedAttributes: _ember.default.computed(function () {
2167
+ var map = Map.create();
2168
+
2169
+ this.eachAttribute(function (key, meta) {
2170
+ if (meta.type) {
2171
+ map.set(key, meta.type);
2172
+ }
2173
+ });
2174
+
2175
+ return map;
2176
+ }).readOnly(),
2177
+
2178
+ /**
2179
+ Iterates through the attributes of the model, calling the passed function on each
2180
+ attribute.
2181
+ The callback method you provide should have the following signature (all
2182
+ parameters are optional):
2183
+ ```javascript
2184
+ function(name, meta);
2185
+ ```
2186
+ - `name` the name of the current property in the iteration
2187
+ - `meta` the meta object for the attribute property in the iteration
2188
+ Note that in addition to a callback, you can also pass an optional target
2189
+ object that will be set as `this` on the context.
2190
+ Example
2191
+ ```javascript
2192
+ import DS from 'ember-data';
2193
+ var Person = DS.Model.extend({
2194
+ firstName: attr('string'),
2195
+ lastName: attr('string'),
2196
+ birthday: attr('date')
2197
+ });
2198
+ Person.eachAttribute(function(name, meta) {
2199
+ console.log(name, meta);
2200
+ });
2201
+ // prints:
2202
+ // firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
2203
+ // lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
2204
+ // birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
2205
+ ```
2206
+ @method eachAttribute
2207
+ @param {Function} callback The callback to execute
2208
+ @param {Object} [binding] the value to which the callback's `this` should be bound
2209
+ @static
2210
+ */
2211
+ eachAttribute: function (callback, binding) {
2212
+ get(this, 'attributes').forEach(function (meta, name) {
2213
+ callback.call(binding, name, meta);
2214
+ });
2215
+ },
2216
+
2217
+ /**
2218
+ Iterates through the transformedAttributes of the model, calling
2219
+ the passed function on each attribute. Note the callback will not be
2220
+ called for any attributes that do not have an transformation type.
2221
+ The callback method you provide should have the following signature (all
2222
+ parameters are optional):
2223
+ ```javascript
2224
+ function(name, type);
2225
+ ```
2226
+ - `name` the name of the current property in the iteration
2227
+ - `type` a string containing the name of the type of transformed
2228
+ applied to the attribute
2229
+ Note that in addition to a callback, you can also pass an optional target
2230
+ object that will be set as `this` on the context.
2231
+ Example
2232
+ ```javascript
2233
+ import DS from 'ember-data';
2234
+ var Person = DS.Model.extend({
2235
+ firstName: attr(),
2236
+ lastName: attr('string'),
2237
+ birthday: attr('date')
2238
+ });
2239
+ Person.eachTransformedAttribute(function(name, type) {
2240
+ console.log(name, type);
2241
+ });
2242
+ // prints:
2243
+ // lastName string
2244
+ // birthday date
2245
+ ```
2246
+ @method eachTransformedAttribute
2247
+ @param {Function} callback The callback to execute
2248
+ @param {Object} [binding] the value to which the callback's `this` should be bound
2249
+ @static
2250
+ */
2251
+ eachTransformedAttribute: function (callback, binding) {
2252
+ get(this, 'transformedAttributes').forEach(function (type, name) {
2253
+ callback.call(binding, name, type);
2254
+ });
2255
+ }
2256
+ });
2257
+
2258
+ exports.AttrClassMethodsMixin = AttrClassMethodsMixin;
2259
+ var AttrInstanceMethodsMixin = _ember.default.Mixin.create({
2260
+ eachAttribute: function (callback, binding) {
2261
+ this.constructor.eachAttribute(callback, binding);
2262
+ }
2263
+ });
2264
+ exports.AttrInstanceMethodsMixin = AttrInstanceMethodsMixin;
2265
+ });
2266
+ define('ember-data/-private/system/model/errors', ['exports', 'ember'], function (exports, _ember) {
2267
+
2268
+ var get = _ember.default.get;
2269
+ var set = _ember.default.set;
2270
+ var isEmpty = _ember.default.isEmpty;
2271
+ var makeArray = _ember.default.makeArray;
2272
+
2273
+ var MapWithDefault = _ember.default.MapWithDefault;
2274
+
2275
+ /**
2276
+ @module ember-data
2277
+ */
2278
+
2279
+ /**
2280
+ Holds validation errors for a given record organized by attribute names.
2281
+
2282
+ Every DS.Model has an `errors` property that is an instance of
2283
+ `DS.Errors`. This can be used to display validation error
2284
+ messages returned from the server when a `record.save()` rejects.
2285
+
2286
+ For Example, if you had an `User` model that looked like this:
2287
+
2288
+ ```app/models/user.js
2289
+ import DS from 'ember-data';
2290
+
2291
+ export default DS.Model.extend({
2292
+ username: attr('string'),
2293
+ email: attr('string')
2294
+ });
2295
+ ```
2296
+ And you attempted to save a record that did not validate on the backend.
2297
+
2298
+ ```javascript
2299
+ var user = store.createRecord('user', {
2300
+ username: 'tomster',
2301
+ email: 'invalidEmail'
2302
+ });
2303
+ user.save();
2304
+ ```
2305
+
2306
+ Your backend data store might return a response that looks like
2307
+ this. This response will be used to populate the error object.
2308
+
2309
+ ```javascript
2310
+ {
2311
+ "errors": [
2312
+ {
2313
+ "detail": "This username is already taken!",
2314
+ "source": {
2315
+ "pointer": "data/attributes/username"
2316
+ }
2317
+ }, {
2318
+ "detail": "Doesn't look like a valid email.",
2319
+ "source": {
2320
+ "pointer": "data/attributes/email"
2321
+ }
2322
+ }
2323
+ ]
2324
+ }
2325
+ ```
2326
+
2327
+ For additional information on the error object, see the [JSON API spec](http://jsonapi.org/format/#error-objects).
2328
+
2329
+ Errors can be displayed to the user by accessing their property name
2330
+ to get an array of all the error objects for that property. Each
2331
+ error object is a JavaScript object with two keys:
2332
+
2333
+ - `message` A string containing the error message from the backend
2334
+ - `attribute` The name of the property associated with this error message
2335
+
2336
+ ```handlebars
2337
+ <label>Username: {{input value=username}} </label>
2338
+ {{#each model.errors.username as |error|}}
2339
+ <div class="error">
2340
+ {{error.message}}
2341
+ </div>
2342
+ {{/each}}
2343
+
2344
+ <label>Email: {{input value=email}} </label>
2345
+ {{#each model.errors.email as |error|}}
2346
+ <div class="error">
2347
+ {{error.message}}
2348
+ </div>
2349
+ {{/each}}
2350
+ ```
2351
+
2352
+ You can also access the special `messages` property on the error
2353
+ object to get an array of all the error strings.
2354
+
2355
+ ```handlebars
2356
+ {{#each model.errors.messages as |message|}}
2357
+ <div class="error">
2358
+ {{message}}
2359
+ </div>
2360
+ {{/each}}
2361
+ ```
2362
+
2363
+ @class Errors
2364
+ @namespace DS
2365
+ @extends Ember.Object
2366
+ @uses Ember.Enumerable
2367
+ @uses Ember.Evented
2368
+ */
2369
+ exports.default = _ember.default.ArrayProxy.extend(_ember.default.Evented, {
2370
+ /**
2371
+ Register with target handler
2372
+ @method registerHandlers
2373
+ @param {Object} target
2374
+ @param {Function} becameInvalid
2375
+ @param {Function} becameValid
2376
+ */
2377
+ registerHandlers: function (target, becameInvalid, becameValid) {
2378
+ this.on('becameInvalid', target, becameInvalid);
2379
+ this.on('becameValid', target, becameValid);
2380
+ },
2381
+
2382
+ /**
2383
+ @property errorsByAttributeName
2384
+ @type {Ember.MapWithDefault}
2385
+ @private
2386
+ */
2387
+ errorsByAttributeName: _ember.default.computed(function () {
2388
+ return MapWithDefault.create({
2389
+ defaultValue: function () {
2390
+ return _ember.default.A();
2391
+ }
2392
+ });
2393
+ }),
2394
+
2395
+ /**
2396
+ Returns errors for a given attribute
2397
+ ```javascript
2398
+ var user = store.createRecord('user', {
2399
+ username: 'tomster',
2400
+ email: 'invalidEmail'
2401
+ });
2402
+ user.save().catch(function(){
2403
+ user.get('errors').errorsFor('email'); // returns:
2404
+ // [{attribute: "email", message: "Doesn't look like a valid email."}]
2405
+ });
2406
+ ```
2407
+ @method errorsFor
2408
+ @param {String} attribute
2409
+ @return {Array}
2410
+ */
2411
+ errorsFor: function (attribute) {
2412
+ return get(this, 'errorsByAttributeName').get(attribute);
2413
+ },
2414
+
2415
+ /**
2416
+ An array containing all of the error messages for this
2417
+ record. This is useful for displaying all errors to the user.
2418
+ ```handlebars
2419
+ {{#each model.errors.messages as |message|}}
2420
+ <div class="error">
2421
+ {{message}}
2422
+ </div>
2423
+ {{/each}}
2424
+ ```
2425
+ @property messages
2426
+ @type {Array}
2427
+ */
2428
+ messages: _ember.default.computed.mapBy('content', 'message'),
2429
+
2430
+ /**
2431
+ @property content
2432
+ @type {Array}
2433
+ @private
2434
+