epf-source 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/dist/epf.js +3474 -0
  2. data/lib/epf/source.rb +7 -0
  3. metadata +47 -0
data/dist/epf.js ADDED
@@ -0,0 +1,3474 @@
1
+ (function (global) {
2
+ function require(file, parentModule) {
3
+ if ({}.hasOwnProperty.call(require.cache, file))
4
+ return require.cache[file];
5
+ var resolved = require.resolve(file);
6
+ if (!resolved)
7
+ throw new Error('Failed to resolve module ' + file);
8
+ var module$ = {
9
+ id: file,
10
+ require: require,
11
+ filename: file,
12
+ exports: {},
13
+ loaded: false,
14
+ parent: parentModule,
15
+ children: []
16
+ };
17
+ if (parentModule)
18
+ parentModule.children.push(module$);
19
+ var dirname = file.slice(0, file.lastIndexOf('/') + 1);
20
+ require.cache[file] = module$.exports;
21
+ resolved.call(module$.exports, module$, module$.exports, dirname, file);
22
+ module$.loaded = true;
23
+ return require.cache[file] = module$.exports;
24
+ }
25
+ require.modules = {};
26
+ require.cache = {};
27
+ require.resolve = function (file) {
28
+ return {}.hasOwnProperty.call(require.modules, file) ? require.modules[file] : void 0;
29
+ };
30
+ require.define = function (file, fn) {
31
+ require.modules[file] = fn;
32
+ };
33
+ var process = function () {
34
+ var cwd = '/';
35
+ return {
36
+ title: 'browser',
37
+ version: 'v0.8.9',
38
+ browser: true,
39
+ env: {},
40
+ argv: [],
41
+ nextTick: global.setImmediate || function (fn) {
42
+ setTimeout(fn, 0);
43
+ },
44
+ cwd: function () {
45
+ return cwd;
46
+ },
47
+ chdir: function (dir) {
48
+ cwd = dir;
49
+ }
50
+ };
51
+ }();
52
+ require.define('/lib/index.js', function (module, exports, __dirname, __filename) {
53
+ global.Ep = Ember.Namespace.create();
54
+ require('/lib/initializer.js', module);
55
+ require('/lib/model/index.js', module);
56
+ require('/lib/session/index.js', module);
57
+ require('/lib/serializer/index.js', module);
58
+ require('/lib/session/index.js', module);
59
+ require('/lib/local/index.js', module);
60
+ require('/lib/rest/index.js', module);
61
+ });
62
+ require.define('/lib/rest/index.js', function (module, exports, __dirname, __filename) {
63
+ require('/lib/rest/rest_adapter.js', module);
64
+ require('/lib/rest/rest_serializer.js', module);
65
+ });
66
+ require.define('/lib/rest/rest_serializer.js', function (module, exports, __dirname, __filename) {
67
+ require('/lib/serializer/index.js', module);
68
+ var get = Ember.get;
69
+ Ep.RestSerializer = Ep.JsonSerializer.extend({
70
+ keyForAttributeName: function (type, name) {
71
+ return Ember.String.decamelize(name);
72
+ },
73
+ keyForBelongsTo: function (type, name) {
74
+ var key = this.keyForAttributeName(type, name);
75
+ if (this.embeddedType(type, name)) {
76
+ return key;
77
+ }
78
+ return key + '_id';
79
+ },
80
+ keyForHasMany: function (type, name) {
81
+ var key = this.keyForAttributeName(type, name);
82
+ if (this.embeddedType(type, name)) {
83
+ return key;
84
+ }
85
+ return this.singularize(key) + '_ids';
86
+ },
87
+ keyForPolymorphicId: function (key) {
88
+ return key;
89
+ },
90
+ keyForPolymorphicType: function (key) {
91
+ return key.replace(/_id$/, '_type');
92
+ },
93
+ extractValidationErrors: function (type, json) {
94
+ var errors = {};
95
+ get(type, 'attributes').forEach(function (name) {
96
+ var key = this._keyForAttributeName(type, name);
97
+ if (json['errors'].hasOwnProperty(key)) {
98
+ errors[name] = json['errors'][key];
99
+ }
100
+ }, this);
101
+ return errors;
102
+ }
103
+ });
104
+ });
105
+ require.define('/lib/serializer/index.js', function (module, exports, __dirname, __filename) {
106
+ require('/lib/serializer/serializer.js', module);
107
+ require('/lib/serializer/json_serializer.js', module);
108
+ });
109
+ require.define('/lib/serializer/json_serializer.js', function (module, exports, __dirname, __filename) {
110
+ require('/lib/serializer/serializer.js', module);
111
+ require('/lib/transforms/json_transforms.js', module);
112
+ var get = Ember.get, set = Ember.set;
113
+ Ep.JsonSerializer = Ep.Serializer.extend({
114
+ init: function () {
115
+ this._super.apply(this, arguments);
116
+ if (!get(this, 'transforms')) {
117
+ this.set('transforms', Ep.JsonTransforms);
118
+ }
119
+ this.sideloadMapping = Ember.Map.create();
120
+ this.metadataMapping = Ember.Map.create();
121
+ this.configure({
122
+ meta: 'meta',
123
+ since: 'since'
124
+ });
125
+ },
126
+ configure: function (type, configuration) {
127
+ var key;
128
+ if (type && !configuration) {
129
+ for (key in type) {
130
+ this.metadataMapping.set(get(type, key), key);
131
+ }
132
+ return this._super(type);
133
+ }
134
+ var sideloadAs = configuration.sideloadAs, sideloadMapping;
135
+ if (sideloadAs) {
136
+ sideloadMapping = this.aliases.sideloadMapping || Ember.Map.create();
137
+ sideloadMapping.set(sideloadAs, type);
138
+ this.aliases.sideloadMapping = sideloadMapping;
139
+ delete configuration.sideloadAs;
140
+ }
141
+ this._super.apply(this, arguments);
142
+ },
143
+ addId: function (data, key, id) {
144
+ data[key] = id;
145
+ },
146
+ addAttribute: function (hash, key, value) {
147
+ hash[key] = value;
148
+ },
149
+ extractAttribute: function (type, hash, attributeName) {
150
+ var key = this._keyForAttributeName(type, attributeName);
151
+ return hash[key];
152
+ },
153
+ extractId: function (type, hash) {
154
+ var primaryKey = this._primaryKey(type);
155
+ if (hash.hasOwnProperty(primaryKey)) {
156
+ return hash[primaryKey] + '';
157
+ } else {
158
+ return null;
159
+ }
160
+ },
161
+ extractClientId: function (type, hash) {
162
+ var clientKey = this._clientKey(type);
163
+ if (hash.hasOwnProperty(clientKey) && hash[clientKey] !== null) {
164
+ return hash[clientKey] + '';
165
+ } else {
166
+ return null;
167
+ }
168
+ },
169
+ extractHasMany: function (type, hash, key) {
170
+ return hash[key];
171
+ },
172
+ extractBelongsTo: function (type, hash, key) {
173
+ return hash[key];
174
+ },
175
+ extractBelongsToPolymorphic: function (type, hash, key) {
176
+ var keyForId = this.keyForPolymorphicId(key), keyForType, id = hash[keyForId];
177
+ if (id) {
178
+ keyForType = this.keyForPolymorphicType(key);
179
+ return {
180
+ id: id,
181
+ type: hash[keyForType]
182
+ };
183
+ }
184
+ return null;
185
+ },
186
+ addBelongsTo: function (hash, record, key, relationship) {
187
+ var type = record.constructor, name = relationship.key, value = null, includeType = relationship.options && relationship.options.polymorphic, embeddedChild, child, id;
188
+ if (this.embeddedType(type, name)) {
189
+ if (embeddedChild = get(record, name)) {
190
+ value = this.serialize(embeddedChild, {
191
+ includeId: true,
192
+ includeType: includeType
193
+ });
194
+ }
195
+ hash[key] = value;
196
+ } else {
197
+ child = get(record, relationship.key);
198
+ id = get(child, 'id');
199
+ if (relationship.options && relationship.options.polymorphic && !Ember.isNone(id)) {
200
+ type = get(child, 'type');
201
+ this.addBelongsToPolymorphic(hash, key, id, type);
202
+ } else {
203
+ hash[key] = id === undefined ? null : this.serializeId(id);
204
+ }
205
+ }
206
+ },
207
+ addBelongsToPolymorphic: function (hash, key, id, type) {
208
+ var keyForId = this.keyForPolymorphicId(key), keyForType = this.keyForPolymorphicType(key);
209
+ hash[keyForId] = id;
210
+ hash[keyForType] = this.rootForType(type);
211
+ },
212
+ addHasMany: function (hash, record, key, relationship) {
213
+ var type = record.constructor, name = relationship.key, serializedHasMany = [], includeType = relationship.options && relationship.options.polymorphic, manyArray, embeddedType;
214
+ embeddedType = this.embeddedType(type, name);
215
+ if (embeddedType !== 'always') {
216
+ return;
217
+ }
218
+ manyArray = get(record, name);
219
+ manyArray.forEach(function (record) {
220
+ serializedHasMany.push(this.serialize(record, {
221
+ includeId: true,
222
+ includeType: includeType
223
+ }));
224
+ }, this);
225
+ hash[key] = serializedHasMany;
226
+ },
227
+ addType: function (hash, type) {
228
+ var keyForType = this.keyForEmbeddedType();
229
+ hash[keyForType] = this.rootForType(type);
230
+ },
231
+ deserialize: function (data) {
232
+ var result = [];
233
+ for (var prop in data) {
234
+ if (!data.hasOwnProperty(prop) || !!this.metadataMapping.get(prop)) {
235
+ continue;
236
+ }
237
+ var type = this.typeFromAlias(prop);
238
+ Ember.assert('Your server returned a hash with the key ' + prop + ' but you have no mapping for it', !!type);
239
+ var value = data[prop];
240
+ if (value instanceof Array) {
241
+ for (var i = 0; i < value.length; i++) {
242
+ result.push(this.deserializeModel(type, value[i]));
243
+ }
244
+ } else {
245
+ result.push(this.deserializeModel(type, value));
246
+ }
247
+ }
248
+ return result;
249
+ },
250
+ extractMeta: function (type, json) {
251
+ var meta = this.configOption(type, 'meta'), data = json, value;
252
+ if (meta && json[meta]) {
253
+ data = json[meta];
254
+ }
255
+ var result = {};
256
+ this.metadataMapping.forEach(function (property, key) {
257
+ if (value = data[property]) {
258
+ result[key] = value;
259
+ }
260
+ });
261
+ return result;
262
+ },
263
+ extractEmbeddedType: function (relationship, data) {
264
+ var foundType = relationship.type;
265
+ if (relationship.options && relationship.options.polymorphic) {
266
+ var key = this.keyFor(relationship), keyForEmbeddedType = this.keyForEmbeddedType(key);
267
+ foundType = this.typeFromAlias(data[keyForEmbeddedType]);
268
+ delete data[keyForEmbeddedType];
269
+ }
270
+ return foundType;
271
+ },
272
+ configureSideloadMappingForType: function (type, configured) {
273
+ if (!configured) {
274
+ configured = Ember.A([]);
275
+ }
276
+ configured.pushObject(type);
277
+ type.eachRelatedType(function (relatedType) {
278
+ if (!configured.contains(relatedType)) {
279
+ var root = this.defaultSideloadRootForType(relatedType);
280
+ this.aliases.set(root, relatedType);
281
+ this.configureSideloadMappingForType(relatedType, configured);
282
+ }
283
+ }, this);
284
+ },
285
+ keyForPolymorphicId: Ember.K,
286
+ keyForPolymorphicType: Ember.K,
287
+ keyForEmbeddedType: function () {
288
+ return 'type';
289
+ },
290
+ rootForType: function (type) {
291
+ var typeString = type.toString();
292
+ Ember.assert('Your model must not be anonymous. It was ' + type, typeString.charAt(0) !== '(');
293
+ var parts = typeString.split('.');
294
+ var name = parts[parts.length - 1];
295
+ return name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
296
+ },
297
+ defaultSideloadRootForType: function (type) {
298
+ return this.pluralize(this.rootForType(type));
299
+ }
300
+ });
301
+ });
302
+ require.define('/lib/transforms/json_transforms.js', function (module, exports, __dirname, __filename) {
303
+ var none = Ember.isNone, empty = Ember.isEmpty;
304
+ require('/lib/ext/date.js', module);
305
+ Ep.JsonTransforms = {
306
+ string: {
307
+ deserialize: function (serialized) {
308
+ return none(serialized) ? null : String(serialized);
309
+ },
310
+ serialize: function (deserialized) {
311
+ return none(deserialized) ? null : String(deserialized);
312
+ }
313
+ },
314
+ number: {
315
+ deserialize: function (serialized) {
316
+ return empty(serialized) ? null : Number(serialized);
317
+ },
318
+ serialize: function (deserialized) {
319
+ return empty(deserialized) ? null : Number(deserialized);
320
+ }
321
+ },
322
+ 'boolean': {
323
+ deserialize: function (serialized) {
324
+ var type = typeof serialized;
325
+ if (type === 'boolean') {
326
+ return serialized;
327
+ } else if (type === 'string') {
328
+ return serialized.match(/^true$|^t$|^1$/i) !== null;
329
+ } else if (type === 'number') {
330
+ return serialized === 1;
331
+ } else {
332
+ return false;
333
+ }
334
+ },
335
+ serialize: function (deserialized) {
336
+ return Boolean(deserialized);
337
+ }
338
+ },
339
+ date: {
340
+ deserialize: function (serialized) {
341
+ var type = typeof serialized;
342
+ if (type === 'string') {
343
+ return new Date(Ember.Date.parse(serialized));
344
+ } else if (type === 'number') {
345
+ return new Date(serialized);
346
+ } else if (serialized === null || serialized === undefined) {
347
+ return serialized;
348
+ } else {
349
+ return null;
350
+ }
351
+ },
352
+ serialize: function (date) {
353
+ if (date instanceof Date) {
354
+ var days = [
355
+ 'Sun',
356
+ 'Mon',
357
+ 'Tue',
358
+ 'Wed',
359
+ 'Thu',
360
+ 'Fri',
361
+ 'Sat'
362
+ ];
363
+ var months = [
364
+ 'Jan',
365
+ 'Feb',
366
+ 'Mar',
367
+ 'Apr',
368
+ 'May',
369
+ 'Jun',
370
+ 'Jul',
371
+ 'Aug',
372
+ 'Sep',
373
+ 'Oct',
374
+ 'Nov',
375
+ 'Dec'
376
+ ];
377
+ var pad = function (num) {
378
+ return num < 10 ? '0' + num : '' + num;
379
+ };
380
+ var utcYear = date.getUTCFullYear(), utcMonth = date.getUTCMonth(), utcDayOfMonth = date.getUTCDate(), utcDay = date.getUTCDay(), utcHours = date.getUTCHours(), utcMinutes = date.getUTCMinutes(), utcSeconds = date.getUTCSeconds();
381
+ var dayOfWeek = days[utcDay];
382
+ var dayOfMonth = pad(utcDayOfMonth);
383
+ var month = months[utcMonth];
384
+ return dayOfWeek + ', ' + dayOfMonth + ' ' + month + ' ' + utcYear + ' ' + pad(utcHours) + ':' + pad(utcMinutes) + ':' + pad(utcSeconds) + ' GMT';
385
+ } else {
386
+ return null;
387
+ }
388
+ }
389
+ }
390
+ };
391
+ });
392
+ require.define('/lib/ext/date.js', function (module, exports, __dirname, __filename) {
393
+ Ember.Date = Ember.Date || {};
394
+ var origParse = Date.parse, numericKeys = [
395
+ 1,
396
+ 4,
397
+ 5,
398
+ 6,
399
+ 7,
400
+ 10,
401
+ 11
402
+ ];
403
+ Ember.Date.parse = function (date) {
404
+ var timestamp, struct, minutesOffset = 0;
405
+ 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)) {
406
+ for (var i = 0, k; k = numericKeys[i]; ++i) {
407
+ struct[k] = +struct[k] || 0;
408
+ }
409
+ struct[2] = (+struct[2] || 1) - 1;
410
+ struct[3] = +struct[3] || 1;
411
+ if (struct[8] !== 'Z' && struct[9] !== undefined) {
412
+ minutesOffset = struct[10] * 60 + struct[11];
413
+ if (struct[9] === '+') {
414
+ minutesOffset = 0 - minutesOffset;
415
+ }
416
+ }
417
+ timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
418
+ } else {
419
+ timestamp = origParse ? origParse(date) : NaN;
420
+ }
421
+ return timestamp;
422
+ };
423
+ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
424
+ Date.parse = Ember.Date.parse;
425
+ }
426
+ });
427
+ require.define('/lib/serializer/serializer.js', function (module, exports, __dirname, __filename) {
428
+ require('/lib/model/index.js', module);
429
+ var get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map, isNone = Ember.isNone;
430
+ function mustImplement(name) {
431
+ return function () {
432
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
433
+ };
434
+ }
435
+ Ep.Serializer = Ember.Object.extend({
436
+ init: function () {
437
+ this.mappings = Ember.Map.create();
438
+ this.aliases = Ember.Map.create();
439
+ this.configurations = Ember.Map.create();
440
+ this.globalConfigurations = {};
441
+ },
442
+ deserialize: mustImplement('deserialize'),
443
+ extractId: mustImplement('extractId'),
444
+ extractClientId: mustImplement('extractClientId'),
445
+ extractAttribute: mustImplement('extractAttribute'),
446
+ extractHasMany: mustImplement('extractHasMany'),
447
+ extractBelongsTo: mustImplement('extractBelongsTo'),
448
+ deserializeModel: function (type, hash) {
449
+ var model = this.createModel(type);
450
+ set(model, 'id', this.extractId(type, hash));
451
+ set(model, 'clientId', this.extractClientId(type, hash));
452
+ this.deserializeAttributes(model, hash);
453
+ this.deserializeRelationships(model, hash);
454
+ return model;
455
+ },
456
+ createModel: function (type) {
457
+ return type.create();
458
+ },
459
+ deserializeValue: function (value, attributeType) {
460
+ var transform = this.transforms ? this.transforms[attributeType] : null;
461
+ Ember.assert('You tried to use a attribute type (' + attributeType + ') that has not been registered', transform);
462
+ return transform.deserialize(value);
463
+ },
464
+ deserializeAttributes: function (model, data) {
465
+ model.eachAttribute(function (name, attribute) {
466
+ set(model, name, this.deserializeAttribute(model, data, name, attribute.type));
467
+ }, this);
468
+ },
469
+ deserializeAttribute: function (record, data, attributeName, attributeType) {
470
+ var value = this.extractAttribute(record.constructor, data, attributeName);
471
+ return this.deserializeValue(value, attributeType);
472
+ },
473
+ deserializeRelationships: function (model, hash) {
474
+ model.eachRelationship(function (name, relationship) {
475
+ if (relationship.kind === 'hasMany') {
476
+ this.deserializeHasMany(name, model, hash, relationship);
477
+ } else if (relationship.kind === 'belongsTo') {
478
+ this.deserializeBelongsTo(name, model, hash, relationship);
479
+ }
480
+ }, this);
481
+ },
482
+ deserializeHasMany: function (name, model, data, relationship) {
483
+ var type = get(model, 'type'), key = this._keyForHasMany(type, relationship.key), embeddedType = this.embeddedType(type, name), value = this.extractHasMany(type, data, key);
484
+ if (embeddedType) {
485
+ this.deserializeEmbeddedHasMany(name, model, value, relationship);
486
+ } else {
487
+ this.deserializeLazyHasMany(name, model, value, relationship);
488
+ }
489
+ },
490
+ deserializeEmbeddedHasMany: function (name, model, values, relationship) {
491
+ get(model, name).addObjects(values.map(function (data) {
492
+ var type = this.extractEmbeddedType(relationship, data);
493
+ return this.deserializeModel(type, data);
494
+ }, this));
495
+ },
496
+ deserializeLazyHasMany: function (name, model, values, relationship) {
497
+ if (!values) {
498
+ return;
499
+ }
500
+ get(model, name).addObjects(values.map(function (value) {
501
+ return Ep.LazyModel.create({
502
+ id: value && value.toString(),
503
+ type: relationship.type
504
+ });
505
+ }, this));
506
+ },
507
+ deserializeBelongsTo: function (name, model, hash, relationship) {
508
+ var type = get(model, 'type'), key = this._keyForBelongsTo(type, relationship.key), embeddedType = this.embeddedType(type, name), value;
509
+ if (embeddedType) {
510
+ if (relationship.options && relationship.options.polymorphic) {
511
+ value = this.extractBelongsToPolymorphic(type, hash, key);
512
+ } else {
513
+ value = this.extractBelongsTo(type, hash, key);
514
+ }
515
+ this.deserializeEmbeddedBelongsTo(name, model, value, relationship);
516
+ } else {
517
+ value = this.extractBelongsTo(type, hash, key);
518
+ this.deserializeLazyBelongsTo(name, model, value, relationship);
519
+ }
520
+ },
521
+ deserializeEmbeddedBelongsTo: function (name, model, value, relationship) {
522
+ if (!value) {
523
+ return;
524
+ }
525
+ var type = this.extractEmbeddedType(relationship, value);
526
+ var child = this.deserializeModel(type, value);
527
+ set(model, name, child);
528
+ },
529
+ deserializeLazyBelongsTo: function (name, model, value, relationship) {
530
+ if (!value) {
531
+ return;
532
+ }
533
+ set(model, name, Ep.LazyModel.create({
534
+ id: value && value.toString(),
535
+ type: relationship.type
536
+ }));
537
+ },
538
+ extractEmbeddedType: function (relationship, data) {
539
+ return relationship.type;
540
+ },
541
+ _convertPrematerializedHasMany: function (type, prematerializedHasMany) {
542
+ var tuplesOrReferencesOrOpaque;
543
+ if (typeof prematerializedHasMany === 'string') {
544
+ tuplesOrReferencesOrOpaque = prematerializedHasMany;
545
+ } else {
546
+ tuplesOrReferencesOrOpaque = this._convertTuples(type, prematerializedHasMany);
547
+ }
548
+ return tuplesOrReferencesOrOpaque;
549
+ },
550
+ _convertTuples: function (type, idsOrTuples) {
551
+ return map.call(idsOrTuples, function (idOrTuple) {
552
+ return this._convertTuple(type, idOrTuple);
553
+ }, this);
554
+ },
555
+ _convertTuple: function (type, idOrTuple) {
556
+ var foundType;
557
+ if (typeof idOrTuple === 'object') {
558
+ if (Ep.Model.detect(idOrTuple.type)) {
559
+ return idOrTuple;
560
+ } else {
561
+ foundType = this.typeFromAlias(idOrTuple.type);
562
+ Ember.assert('Unable to resolve type ' + idOrTuple.type + '. You may need to configure your serializer aliases.', !!foundType);
563
+ return {
564
+ id: idOrTuple.id,
565
+ type: foundType
566
+ };
567
+ }
568
+ }
569
+ return {
570
+ id: idOrTuple,
571
+ type: type
572
+ };
573
+ },
574
+ serialize: function (record, options) {
575
+ options = options || {};
576
+ var serialized = this.createSerializedForm(), id;
577
+ if (options.includeId) {
578
+ if (id = get(record, 'id')) {
579
+ this._addId(serialized, record.constructor, id);
580
+ }
581
+ this._addClientId(serialized, record.constructor, get(record, 'clientId'));
582
+ }
583
+ if (options.includeType) {
584
+ this.addType(serialized, record.constructor);
585
+ }
586
+ this.addAttributes(serialized, record);
587
+ this.addRelationships(serialized, record);
588
+ return serialized;
589
+ },
590
+ serializeValue: function (value, attributeType) {
591
+ var transform = this.transforms ? this.transforms[attributeType] : null;
592
+ Ember.assert('You tried to use an attribute type (' + attributeType + ') that has not been registered', transform);
593
+ return transform.serialize(value);
594
+ },
595
+ serializeId: function (id) {
596
+ if (isNaN(id)) {
597
+ return id;
598
+ }
599
+ return +id;
600
+ },
601
+ serializeClientId: function (clientId) {
602
+ return clientId;
603
+ },
604
+ addAttributes: function (data, record) {
605
+ record.eachAttribute(function (name, attribute) {
606
+ this._addAttribute(data, record, name, attribute.type);
607
+ }, this);
608
+ },
609
+ addAttribute: mustImplement('addAttribute'),
610
+ addId: mustImplement('addId'),
611
+ addType: Ember.K,
612
+ createSerializedForm: function () {
613
+ return {};
614
+ },
615
+ addRelationships: function (data, record) {
616
+ record.eachRelationship(function (name, relationship) {
617
+ if (relationship.kind === 'belongsTo') {
618
+ this._addBelongsTo(data, record, name, relationship);
619
+ } else if (relationship.kind === 'hasMany') {
620
+ this._addHasMany(data, record, name, relationship);
621
+ }
622
+ }, this);
623
+ },
624
+ addBelongsTo: mustImplement('addBelongsTo'),
625
+ addHasMany: mustImplement('addHasMany'),
626
+ keyForAttributeName: function (type, name) {
627
+ return name;
628
+ },
629
+ primaryKey: function (type) {
630
+ return 'id';
631
+ },
632
+ clientKey: function (type) {
633
+ return 'client_id';
634
+ },
635
+ keyForBelongsTo: function (type, name) {
636
+ return this.keyForAttributeName(type, name);
637
+ },
638
+ keyForHasMany: function (type, name) {
639
+ return this.keyForAttributeName(type, name);
640
+ },
641
+ _primaryKey: function (type) {
642
+ var config = this.configurationForType(type), primaryKey = config && config.primaryKey;
643
+ if (primaryKey) {
644
+ return primaryKey;
645
+ } else {
646
+ return this.primaryKey(type);
647
+ }
648
+ },
649
+ _clientKey: function (type) {
650
+ var config = this.configurationForType(type), clientKey = config && config.clientKey;
651
+ if (clientKey) {
652
+ return clientKey;
653
+ } else {
654
+ return this.clientKey(type);
655
+ }
656
+ },
657
+ _addAttribute: function (data, record, attributeName, attributeType) {
658
+ var key = this._keyForAttributeName(record.constructor, attributeName);
659
+ var value = get(record, attributeName);
660
+ this.addAttribute(data, key, this.serializeValue(value, attributeType));
661
+ },
662
+ _addId: function (hash, type, id) {
663
+ var primaryKey = this._primaryKey(type);
664
+ this.addId(hash, primaryKey, this.serializeId(id));
665
+ },
666
+ _addClientId: function (hash, type, id) {
667
+ var clientKey = this._clientKey(type);
668
+ this.addId(hash, clientKey, this.serializeClientId(id));
669
+ },
670
+ _keyForAttributeName: function (type, name) {
671
+ return this._keyFromMappingOrHook('keyForAttributeName', type, name);
672
+ },
673
+ _keyForBelongsTo: function (type, name) {
674
+ return this._keyFromMappingOrHook('keyForBelongsTo', type, name);
675
+ },
676
+ keyFor: function (description) {
677
+ var type = description.parentType, name = description.key;
678
+ switch (description.kind) {
679
+ case 'belongsTo':
680
+ return this._keyForBelongsTo(type, name);
681
+ case 'hasMany':
682
+ return this._keyForHasMany(type, name);
683
+ }
684
+ },
685
+ _keyForHasMany: function (type, name) {
686
+ return this._keyFromMappingOrHook('keyForHasMany', type, name);
687
+ },
688
+ _addBelongsTo: function (data, record, name, relationship) {
689
+ var key = this._keyForBelongsTo(record.constructor, name);
690
+ this.addBelongsTo(data, record, key, relationship);
691
+ },
692
+ _addHasMany: function (data, record, name, relationship) {
693
+ var key = this._keyForHasMany(record.constructor, name);
694
+ this.addHasMany(data, record, key, relationship);
695
+ },
696
+ _keyFromMappingOrHook: function (publicMethod, type, name) {
697
+ var key = this.mappingOption(type, name, 'key');
698
+ if (key) {
699
+ return key;
700
+ } else {
701
+ return this[publicMethod](type, name);
702
+ }
703
+ },
704
+ registerTransform: function (type, transform) {
705
+ this.transforms[type] = transform;
706
+ },
707
+ registerEnumTransform: function (type, objects) {
708
+ var transform = {
709
+ deserialize: function (serialized) {
710
+ return Ember.A(objects).objectAt(serialized);
711
+ },
712
+ serialize: function (deserialized) {
713
+ return Ember.EnumerableUtils.indexOf(objects, deserialized);
714
+ },
715
+ values: objects
716
+ };
717
+ this.registerTransform(type, transform);
718
+ },
719
+ map: function (type, mappings) {
720
+ this.mappings.set(type, mappings);
721
+ },
722
+ configure: function (type, configuration) {
723
+ if (type && !configuration) {
724
+ Ember.merge(this.globalConfigurations, type);
725
+ return;
726
+ }
727
+ var config, alias;
728
+ if (configuration.alias) {
729
+ alias = configuration.alias;
730
+ this.aliases.set(alias, type);
731
+ delete configuration.alias;
732
+ }
733
+ config = Ember.create(this.globalConfigurations);
734
+ Ember.merge(config, configuration);
735
+ this.configurations.set(type, config);
736
+ },
737
+ typeFromAlias: function (alias) {
738
+ this._completeAliases();
739
+ var singular = this.singularize(alias);
740
+ return this.container.lookup('model:' + singular);
741
+ },
742
+ mappingForType: function (type) {
743
+ this._reifyMappings();
744
+ return this.mappings.get(type) || {};
745
+ },
746
+ configurationForType: function (type) {
747
+ this._reifyConfigurations();
748
+ return this.configurations.get(type) || this.globalConfigurations;
749
+ },
750
+ _completeAliases: function () {
751
+ this._pluralizeAliases();
752
+ this._reifyAliases();
753
+ },
754
+ _pluralizeAliases: function () {
755
+ if (this._didPluralizeAliases) {
756
+ return;
757
+ }
758
+ var aliases = this.aliases, sideloadMapping = this.aliases.sideloadMapping, plural, self = this;
759
+ aliases.forEach(function (key, type) {
760
+ plural = self.pluralize(key);
761
+ Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(plural));
762
+ aliases.set(plural, type);
763
+ });
764
+ if (sideloadMapping) {
765
+ sideloadMapping.forEach(function (key, type) {
766
+ Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(key) || aliases.get(key) === type);
767
+ aliases.set(key, type);
768
+ });
769
+ delete this.aliases.sideloadMapping;
770
+ }
771
+ this._didPluralizeAliases = true;
772
+ },
773
+ _reifyAliases: function () {
774
+ if (this._didReifyAliases) {
775
+ return;
776
+ }
777
+ var aliases = this.aliases, reifiedAliases = Ember.Map.create(), foundType;
778
+ aliases.forEach(function (key, type) {
779
+ if (typeof type === 'string') {
780
+ foundType = Ember.get(Ember.lookup, type);
781
+ Ember.assert('Could not find model at path ' + key, type);
782
+ reifiedAliases.set(key, foundType);
783
+ } else {
784
+ reifiedAliases.set(key, type);
785
+ }
786
+ });
787
+ this.aliases = reifiedAliases;
788
+ this._didReifyAliases = true;
789
+ },
790
+ _reifyMappings: function () {
791
+ if (this._didReifyMappings) {
792
+ return;
793
+ }
794
+ var mappings = this.mappings, reifiedMappings = Ember.Map.create();
795
+ mappings.forEach(function (key, mapping) {
796
+ if (typeof key === 'string') {
797
+ var type = Ember.get(Ember.lookup, key);
798
+ Ember.assert('Could not find model at path ' + key, type);
799
+ reifiedMappings.set(type, mapping);
800
+ } else {
801
+ reifiedMappings.set(key, mapping);
802
+ }
803
+ });
804
+ this.mappings = reifiedMappings;
805
+ this._didReifyMappings = true;
806
+ },
807
+ _reifyConfigurations: function () {
808
+ if (this._didReifyConfigurations) {
809
+ return;
810
+ }
811
+ var configurations = this.configurations, reifiedConfigurations = Ember.Map.create();
812
+ configurations.forEach(function (key, mapping) {
813
+ if (typeof key === 'string' && key !== 'plurals') {
814
+ var type = Ember.get(Ember.lookup, key);
815
+ Ember.assert('Could not find model at path ' + key, type);
816
+ reifiedConfigurations.set(type, mapping);
817
+ } else {
818
+ reifiedConfigurations.set(key, mapping);
819
+ }
820
+ });
821
+ this.configurations = reifiedConfigurations;
822
+ this._didReifyConfigurations = true;
823
+ },
824
+ mappingOption: function (type, name, option) {
825
+ var mapping = this.mappingForType(type)[name];
826
+ return mapping && mapping[option];
827
+ },
828
+ configOption: function (type, option) {
829
+ var config = this.configurationForType(type);
830
+ return config[option];
831
+ },
832
+ embeddedType: function (type, name) {
833
+ return this.mappingOption(type, name, 'embedded');
834
+ },
835
+ eachEmbeddedRecord: function (record, callback, binding) {
836
+ this.eachEmbeddedBelongsToRecord(record, callback, binding);
837
+ this.eachEmbeddedHasManyRecord(record, callback, binding);
838
+ },
839
+ eachEmbeddedBelongsToRecord: function (record, callback, binding) {
840
+ this.eachEmbeddedBelongsTo(record.constructor, function (name, relationship, embeddedType) {
841
+ var embeddedRecord = get(record, name);
842
+ if (embeddedRecord) {
843
+ callback.call(binding, embeddedRecord, embeddedType);
844
+ }
845
+ });
846
+ },
847
+ eachEmbeddedHasManyRecord: function (record, callback, binding) {
848
+ this.eachEmbeddedHasMany(record.constructor, function (name, relationship, embeddedType) {
849
+ var array = get(record, name);
850
+ for (var i = 0, l = get(array, 'length'); i < l; i++) {
851
+ callback.call(binding, array.objectAt(i), embeddedType);
852
+ }
853
+ });
854
+ },
855
+ eachEmbeddedHasMany: function (type, callback, binding) {
856
+ this.eachEmbeddedRelationship(type, 'hasMany', callback, binding);
857
+ },
858
+ eachEmbeddedBelongsTo: function (type, callback, binding) {
859
+ this.eachEmbeddedRelationship(type, 'belongsTo', callback, binding);
860
+ },
861
+ eachEmbeddedRelationship: function (type, kind, callback, binding) {
862
+ type.eachRelationship(function (name, relationship) {
863
+ var embeddedType = this.embeddedType(type, name);
864
+ if (embeddedType) {
865
+ if (relationship.kind === kind) {
866
+ callback.call(binding, name, relationship, embeddedType);
867
+ }
868
+ }
869
+ }, this);
870
+ },
871
+ pluralize: function (name) {
872
+ var plurals = this.configurations.get('plurals');
873
+ return plurals && plurals[name] || name + 's';
874
+ },
875
+ singularize: function (name) {
876
+ var plurals = this.configurations.get('plurals');
877
+ if (plurals) {
878
+ for (var i in plurals) {
879
+ if (plurals[i] === name) {
880
+ return i;
881
+ }
882
+ }
883
+ }
884
+ if (name.lastIndexOf('s') === name.length - 1) {
885
+ return name.substring(0, name.length - 1);
886
+ } else {
887
+ return name;
888
+ }
889
+ }
890
+ });
891
+ });
892
+ require.define('/lib/model/index.js', function (module, exports, __dirname, __filename) {
893
+ require('/lib/model/model.js', module);
894
+ require('/lib/model/proxies.js', module);
895
+ require('/lib/model/attribute.js', module);
896
+ require('/lib/model/relationships/belongs_to.js', module);
897
+ require('/lib/model/relationships/has_many.js', module);
898
+ require('/lib/model/relationships/ext.js', module);
899
+ require('/lib/model/errors.js', module);
900
+ });
901
+ require.define('/lib/model/errors.js', function (module, exports, __dirname, __filename) {
902
+ var get = Ember.get, set = Ember.set;
903
+ Ep.Errors = Ember.ObjectProxy.extend(Ember.Copyable, {
904
+ init: function () {
905
+ this._super.apply(this, arguments);
906
+ if (!get(this, 'content'))
907
+ set(this, 'content', {});
908
+ },
909
+ forEach: function (callback, self) {
910
+ var keys = Ember.keys(this.content);
911
+ keys.forEach(function (key) {
912
+ var value = get(this.content, key);
913
+ callback.call(self, key, value);
914
+ }, this);
915
+ },
916
+ copy: function () {
917
+ return Ep.Errors.create({ content: Ember.copy(this.content) });
918
+ }
919
+ });
920
+ });
921
+ require.define('/lib/model/relationships/ext.js', function (module, exports, __dirname, __filename) {
922
+ var get = Ember.get, set = Ember.set;
923
+ Ep.Model.reopen({
924
+ didDefineProperty: function (proto, key, value) {
925
+ if (value instanceof Ember.Descriptor) {
926
+ var meta = value.meta();
927
+ if (meta.isRelationship && meta.kind === 'belongsTo') {
928
+ Ember.addObserver(proto, key, null, 'belongsToDidChange');
929
+ Ember.addBeforeObserver(proto, key, null, 'belongsToWillChange');
930
+ }
931
+ if (meta.isAttribute) {
932
+ Ember.addBeforeObserver(proto, key, null, 'attributeWillChange');
933
+ }
934
+ meta.parentType = proto.constructor;
935
+ }
936
+ },
937
+ _suspendedRelationships: false,
938
+ suspendRelationshipObservers: function (callback, binding) {
939
+ var observers = get(this.constructor, 'relationshipNames').belongsTo;
940
+ var self = this;
941
+ if (this._suspendedRelationships) {
942
+ return callback.call(binding || self);
943
+ }
944
+ try {
945
+ this._suspendedRelationships = true;
946
+ Ember._suspendObservers(self, observers, null, 'belongsToDidChange', function () {
947
+ Ember._suspendBeforeObservers(self, observers, null, 'belongsToWillChange', function () {
948
+ callback.call(binding || self);
949
+ });
950
+ });
951
+ } finally {
952
+ this._suspendedRelationships = false;
953
+ }
954
+ },
955
+ _registerRelationships: function () {
956
+ var session = get(this, 'session');
957
+ Ember.assert('Must be attached to a session', !!session);
958
+ this.eachRelationship(function (name, relationship) {
959
+ if (relationship.kind === 'belongsTo') {
960
+ var model = get(this, name);
961
+ if (model) {
962
+ session.belongsToManager.register(model, name, this);
963
+ }
964
+ } else if (relationship.kind === 'hasMany') {
965
+ var children = get(this, name);
966
+ children.forEach(function (model) {
967
+ session.collectionManager.register(children, model);
968
+ }, this);
969
+ }
970
+ }, this);
971
+ }
972
+ });
973
+ Ep.Model.reopenClass({
974
+ typeForRelationship: function (name) {
975
+ var relationship = get(this, 'relationshipsByName').get(name);
976
+ return relationship && relationship.type;
977
+ },
978
+ inverseFor: function (name) {
979
+ var inverseType = this.typeForRelationship(name);
980
+ if (!inverseType) {
981
+ return null;
982
+ }
983
+ var options = this.metaForProperty(name).options;
984
+ var inverseName, inverseKind;
985
+ if (options.inverse) {
986
+ inverseName = options.inverse;
987
+ inverseKind = Ember.get(inverseType, 'relationshipsByName').get(inverseName).kind;
988
+ } else {
989
+ var possibleRelationships = findPossibleInverses(this, inverseType);
990
+ if (possibleRelationships.length === 0) {
991
+ return null;
992
+ }
993
+ Ember.assert('You defined the \'' + name + '\' relationship on ' + this + ', but multiple possible inverse relationships of type ' + this + ' were found on ' + inverseType + '.', possibleRelationships.length === 1);
994
+ inverseName = possibleRelationships[0].name;
995
+ inverseKind = possibleRelationships[0].kind;
996
+ }
997
+ function findPossibleInverses(type, inverseType, possibleRelationships) {
998
+ possibleRelationships = possibleRelationships || [];
999
+ var relationshipMap = get(inverseType, 'relationships');
1000
+ if (!relationshipMap) {
1001
+ return;
1002
+ }
1003
+ var relationships = relationshipMap.get(type);
1004
+ if (relationships) {
1005
+ possibleRelationships.push.apply(possibleRelationships, relationshipMap.get(type));
1006
+ }
1007
+ if (type.superclass) {
1008
+ findPossibleInverses(type.superclass, inverseType, possibleRelationships);
1009
+ }
1010
+ return possibleRelationships;
1011
+ }
1012
+ return {
1013
+ type: inverseType,
1014
+ name: inverseName,
1015
+ kind: inverseKind
1016
+ };
1017
+ },
1018
+ relationships: Ember.computed(function () {
1019
+ var map = new Ember.MapWithDefault({
1020
+ defaultValue: function () {
1021
+ return [];
1022
+ }
1023
+ });
1024
+ this.eachComputedProperty(function (name, meta) {
1025
+ if (meta.isRelationship) {
1026
+ if (typeof meta.type === 'string') {
1027
+ meta.type = Ep.__container__.lookup('model:' + type);
1028
+ }
1029
+ var relationshipsForType = map.get(meta.type);
1030
+ relationshipsForType.push({
1031
+ name: name,
1032
+ kind: meta.kind
1033
+ });
1034
+ }
1035
+ });
1036
+ return map;
1037
+ }),
1038
+ relationshipNames: Ember.computed(function () {
1039
+ var names = {
1040
+ hasMany: [],
1041
+ belongsTo: []
1042
+ };
1043
+ this.eachComputedProperty(function (name, meta) {
1044
+ if (meta.isRelationship) {
1045
+ names[meta.kind].push(name);
1046
+ }
1047
+ });
1048
+ return names;
1049
+ }),
1050
+ relatedTypes: Ember.computed(function () {
1051
+ var type, types = Ember.A([]);
1052
+ this.eachComputedProperty(function (name, meta) {
1053
+ if (meta.isRelationship) {
1054
+ type = meta.type;
1055
+ if (typeof type === 'string') {
1056
+ type = Ep.__container__.lookup('model:' + type);
1057
+ }
1058
+ Ember.assert('You specified a hasMany (' + meta.type + ') on ' + meta.parentType + ' but ' + meta.type + ' was not found.', type);
1059
+ if (!types.contains(type)) {
1060
+ Ember.assert('Trying to sideload ' + name + ' on ' + this.toString() + ' but the type doesn\'t exist.', !!type);
1061
+ types.push(type);
1062
+ }
1063
+ }
1064
+ });
1065
+ return types;
1066
+ }),
1067
+ relationshipsByName: Ember.computed(function () {
1068
+ var map = Ember.Map.create(), type;
1069
+ this.eachComputedProperty(function (name, meta) {
1070
+ if (meta.isRelationship) {
1071
+ meta.key = name;
1072
+ type = meta.type;
1073
+ if (typeof type === 'string') {
1074
+ type = Ep.__container__.lookup('model:' + type);
1075
+ }
1076
+ map.set(name, meta);
1077
+ }
1078
+ });
1079
+ return map;
1080
+ }),
1081
+ fields: Ember.computed(function () {
1082
+ var map = Ember.Map.create();
1083
+ this.eachComputedProperty(function (name, meta) {
1084
+ if (meta.isRelationship) {
1085
+ map.set(name, meta.kind);
1086
+ } else if (meta.isAttribute) {
1087
+ map.set(name, 'attribute');
1088
+ }
1089
+ });
1090
+ return map;
1091
+ }),
1092
+ eachRelationship: function (callback, binding) {
1093
+ get(this, 'relationshipsByName').forEach(function (name, relationship) {
1094
+ callback.call(binding, name, relationship);
1095
+ });
1096
+ },
1097
+ eachRelatedType: function (callback, binding) {
1098
+ get(this, 'relatedTypes').forEach(function (type) {
1099
+ callback.call(binding, type);
1100
+ });
1101
+ }
1102
+ });
1103
+ Ep.Model.reopen({
1104
+ eachRelationship: function (callback, binding) {
1105
+ this.constructor.eachRelationship(callback, binding);
1106
+ },
1107
+ eachRelatedModel: function (callback, binding, cache) {
1108
+ if (!cache)
1109
+ cache = Ember.Set.create();
1110
+ if (cache.contains(this))
1111
+ return;
1112
+ cache.add(this);
1113
+ callback.call(binding || this, this);
1114
+ if (!get(this, 'isLoaded'))
1115
+ return;
1116
+ this.eachRelationship(function (name, relationship) {
1117
+ if (relationship.kind === 'belongsTo') {
1118
+ var child = get(this, name);
1119
+ if (!child)
1120
+ return;
1121
+ this.eachRelatedModel.call(child, callback, binding, cache);
1122
+ } else if (relationship.kind === 'hasMany') {
1123
+ var children = get(this, name);
1124
+ children.forEach(function (child) {
1125
+ this.eachRelatedModel.call(child, callback, binding, cache);
1126
+ }, this);
1127
+ }
1128
+ }, this);
1129
+ }
1130
+ });
1131
+ });
1132
+ require.define('/lib/model/relationships/has_many.js', function (module, exports, __dirname, __filename) {
1133
+ var get = Ember.get, set = Ember.set, forEach = Ember.ArrayPolyfills.forEach;
1134
+ require('/lib/model/model.js', module);
1135
+ require('/lib/collections/model_array.js', module);
1136
+ Ep.hasMany = function (type, options) {
1137
+ Ember.assert('The type passed to Ep.hasMany must be defined', !!type);
1138
+ options = options || {};
1139
+ var meta = {
1140
+ type: type,
1141
+ isRelationship: true,
1142
+ options: options,
1143
+ kind: 'hasMany'
1144
+ };
1145
+ return Ember.computed(function (key, value, cached) {
1146
+ var content;
1147
+ if (arguments.length === 1) {
1148
+ content = [];
1149
+ } else {
1150
+ content = value;
1151
+ }
1152
+ var session = get(this, 'session');
1153
+ if (session) {
1154
+ content = content.map(function (model) {
1155
+ return session.add(model);
1156
+ }, this);
1157
+ }
1158
+ if (cached) {
1159
+ set(cached, 'content', content);
1160
+ return cached;
1161
+ }
1162
+ return Ep.HasManyArray.create({
1163
+ owner: this,
1164
+ name: key,
1165
+ session: session,
1166
+ content: content
1167
+ });
1168
+ }).property().meta(meta);
1169
+ };
1170
+ Ep.HasManyArray = Ep.ModelArray.extend({
1171
+ name: null,
1172
+ owner: null,
1173
+ replaceContent: function (idx, amt, objects) {
1174
+ var session = get(this, 'session');
1175
+ if (session) {
1176
+ objects = objects.map(function (model) {
1177
+ return session.add(model);
1178
+ });
1179
+ }
1180
+ this._super(idx, amt, objects);
1181
+ },
1182
+ arrayContentWillChange: function (index, removed, added) {
1183
+ var owner = get(this, 'owner'), name = get(this, 'name'), session = get(owner, 'session');
1184
+ if (session) {
1185
+ session.modelWillBecomeDirty(owner);
1186
+ }
1187
+ if (!owner._suspendedRelationships) {
1188
+ var inverse = owner.constructor.inverseFor(name);
1189
+ if (inverse) {
1190
+ for (var i = index; i < index + removed; i++) {
1191
+ var model = this.objectAt(i);
1192
+ if (!get(model, 'isLoaded'))
1193
+ continue;
1194
+ model.suspendRelationshipObservers(function () {
1195
+ if (inverse.kind === 'hasMany') {
1196
+ get(model, inverse.name).removeObject(owner);
1197
+ } else if (inverse.kind === 'belongsTo') {
1198
+ set(model, inverse.name, null);
1199
+ if (session) {
1200
+ session.modelWillBecomeDirty(model);
1201
+ session.belongsToManager.unregister(model, inverse.name, owner);
1202
+ }
1203
+ }
1204
+ });
1205
+ }
1206
+ }
1207
+ }
1208
+ return this._super.apply(this, arguments);
1209
+ },
1210
+ arrayContentDidChange: function (index, removed, added) {
1211
+ this._super.apply(this, arguments);
1212
+ var owner = get(this, 'owner'), name = get(this, 'name');
1213
+ if (!owner._suspendedRelationships) {
1214
+ var inverse = owner.constructor.inverseFor(name);
1215
+ if (inverse) {
1216
+ for (var i = index; i < index + added; i++) {
1217
+ var model = this.objectAt(i);
1218
+ if (!get(model, 'isLoaded'))
1219
+ continue;
1220
+ model.suspendRelationshipObservers(function () {
1221
+ if (inverse.kind === 'hasMany') {
1222
+ get(model, inverse.name).addObject(owner);
1223
+ } else if (inverse.kind === 'belongsTo') {
1224
+ set(model, inverse.name, owner);
1225
+ var session = get(owner, 'session');
1226
+ if (session) {
1227
+ session.belongsToManager.register(model, inverse.name, owner);
1228
+ }
1229
+ }
1230
+ });
1231
+ }
1232
+ }
1233
+ }
1234
+ }
1235
+ });
1236
+ });
1237
+ require.define('/lib/collections/model_array.js', function (module, exports, __dirname, __filename) {
1238
+ var get = Ember.get, set = Ember.set;
1239
+ Ep.ModelArray = Ember.ArrayProxy.extend({
1240
+ session: null,
1241
+ meta: null,
1242
+ arrayContentWillChange: function (index, removed, added) {
1243
+ for (var i = index; i < index + removed; i++) {
1244
+ var model = this.objectAt(i);
1245
+ if (this.session) {
1246
+ this.session.collectionManager.unregister(this, model);
1247
+ }
1248
+ }
1249
+ this._super.apply(this, arguments);
1250
+ },
1251
+ arrayContentDidChange: function (index, removed, added) {
1252
+ this._super.apply(this, arguments);
1253
+ for (var i = index; i < index + added; i++) {
1254
+ var model = this.objectAt(i);
1255
+ if (this.session) {
1256
+ this.session.collectionManager.register(this, model);
1257
+ }
1258
+ }
1259
+ },
1260
+ removeObject: function (obj) {
1261
+ var loc = get(this, 'length') || 0;
1262
+ while (--loc >= 0) {
1263
+ var curObject = this.objectAt(loc);
1264
+ if (curObject.isEqual(obj))
1265
+ this.removeAt(loc);
1266
+ }
1267
+ return this;
1268
+ },
1269
+ contains: function (obj) {
1270
+ for (var i = 0; i < get(this, 'length'); i++) {
1271
+ var m = this.objectAt(i);
1272
+ if (obj.isEqual(m))
1273
+ return true;
1274
+ }
1275
+ return false;
1276
+ },
1277
+ copyTo: function (dest) {
1278
+ var existing = Ep.ModelSet.create();
1279
+ existing.addObjects(dest);
1280
+ this.forEach(function (model) {
1281
+ if (existing.contains(model)) {
1282
+ existing.remove(model);
1283
+ } else {
1284
+ dest.addObject(model);
1285
+ }
1286
+ });
1287
+ dest.removeObjects(existing);
1288
+ },
1289
+ diff: function (arr) {
1290
+ var diff = Ember.A();
1291
+ this.forEach(function (model) {
1292
+ if (!arr.contains(model)) {
1293
+ diff.push(model);
1294
+ }
1295
+ }, this);
1296
+ arr.forEach(function (model) {
1297
+ if (!this.contains(model)) {
1298
+ diff.push(model);
1299
+ }
1300
+ }, this);
1301
+ return diff;
1302
+ },
1303
+ isEqual: function (arr) {
1304
+ return this.diff(arr).length === 0;
1305
+ }
1306
+ });
1307
+ });
1308
+ require.define('/lib/model/model.js', function (module, exports, __dirname, __filename) {
1309
+ var get = Ember.get, set = Ember.set;
1310
+ require('/lib/collections/model_set.js', module);
1311
+ Ep.ModelMixin = Ember.Mixin.create({
1312
+ id: null,
1313
+ clientId: null,
1314
+ session: null,
1315
+ errors: null,
1316
+ isEqual: function (model) {
1317
+ var clientId = get(this, 'clientId');
1318
+ var otherClientId = get(model, 'clientId');
1319
+ if (clientId && otherClientId) {
1320
+ return clientId === otherClientId;
1321
+ }
1322
+ var id = get(this, 'id');
1323
+ var otherId = get(model, 'id');
1324
+ return this.isSameType(model) && id === otherId;
1325
+ },
1326
+ isSameType: function (model) {
1327
+ return this.hasType(get(model, 'type'));
1328
+ },
1329
+ hasType: function (type) {
1330
+ return get(this, 'type').detect(type);
1331
+ },
1332
+ type: Ember.computed(function (key, value) {
1333
+ return value || this.constructor;
1334
+ }),
1335
+ toStringExtension: function () {
1336
+ return '[' + get(this, 'id') + ', ' + get(this, 'clientId') + ']';
1337
+ },
1338
+ lazyCopy: function () {
1339
+ return Ep.LazyModel.create({
1340
+ id: get(this, 'id'),
1341
+ clientId: get(this, 'clientId'),
1342
+ type: get(this, 'type'),
1343
+ isDeleted: get(this, 'isDeleted'),
1344
+ errors: get(this, 'errors')
1345
+ });
1346
+ },
1347
+ hasErrors: Ember.computed(function () {
1348
+ return !!get(this, 'errors');
1349
+ }).volatile(),
1350
+ isDetached: Ember.computed(function () {
1351
+ return !get(this, 'session');
1352
+ }).volatile(),
1353
+ isManaged: Ember.computed(function () {
1354
+ return !!get(this, 'session');
1355
+ }).volatile()
1356
+ });
1357
+ Ep.Model = Ember.Object.extend(Ember.Copyable, Ep.ModelMixin, {
1358
+ isPromise: false,
1359
+ isProxy: false,
1360
+ isDeleted: false,
1361
+ isLoaded: true,
1362
+ isNew: Ember.computed(function () {
1363
+ return !get(this, 'id');
1364
+ }).property('id'),
1365
+ clientRevision: Ember.computed(function (key, value) {
1366
+ if (arguments.length === 1) {
1367
+ return 0;
1368
+ }
1369
+ return value;
1370
+ }),
1371
+ diff: function (model) {
1372
+ var diffs = [];
1373
+ this.eachAttribute(function (name, meta) {
1374
+ var left = get(this, name);
1375
+ var right = get(model, name);
1376
+ if (left instanceof Date && right instanceof Date) {
1377
+ left = left.getTime();
1378
+ right = right.getTime();
1379
+ }
1380
+ if (left !== right) {
1381
+ diffs.push({
1382
+ type: 'attr',
1383
+ name: name
1384
+ });
1385
+ }
1386
+ }, this);
1387
+ this.eachRelationship(function (name, relationship) {
1388
+ var left = get(this, name);
1389
+ var right = get(model, name);
1390
+ if (relationship.kind === 'belongsTo') {
1391
+ if (left && right) {
1392
+ if (!left.isEqual(right)) {
1393
+ diffs.push({
1394
+ type: 'belongsTo',
1395
+ name: name,
1396
+ relationship: relationship,
1397
+ oldValue: right
1398
+ });
1399
+ }
1400
+ } else if (left || right) {
1401
+ diffs.push({
1402
+ type: 'belongsTo',
1403
+ name: name,
1404
+ relationship: relationship,
1405
+ oldValue: right
1406
+ });
1407
+ }
1408
+ } else if (relationship.kind === 'hasMany') {
1409
+ var dirty = false;
1410
+ var cache = Ep.ModelSet.create();
1411
+ left.forEach(function (model) {
1412
+ cache.add(model);
1413
+ });
1414
+ right.forEach(function (model) {
1415
+ if (dirty)
1416
+ return;
1417
+ if (!cache.contains(model)) {
1418
+ dirty = true;
1419
+ } else {
1420
+ cache.remove(model);
1421
+ }
1422
+ });
1423
+ if (dirty || get(cache, 'length') > 0) {
1424
+ diffs.push({
1425
+ type: 'hasMany',
1426
+ name: name,
1427
+ relationship: relationship
1428
+ });
1429
+ }
1430
+ }
1431
+ }, this);
1432
+ return diffs;
1433
+ },
1434
+ copy: function () {
1435
+ var dest = this.constructor.create();
1436
+ dest.beginPropertyChanges();
1437
+ this.copyAttributes(dest);
1438
+ this.eachRelationship(function (name, relationship) {
1439
+ if (relationship.kind === 'belongsTo') {
1440
+ var child = get(this, name);
1441
+ if (child) {
1442
+ set(dest, name, child.lazyCopy());
1443
+ }
1444
+ } else if (relationship.kind === 'hasMany') {
1445
+ var children = get(this, name);
1446
+ var destChildren = get(dest, name);
1447
+ children.forEach(function (child) {
1448
+ destChildren.addObject(child.lazyCopy());
1449
+ });
1450
+ }
1451
+ }, this);
1452
+ dest.endPropertyChanges();
1453
+ return dest;
1454
+ },
1455
+ copyAttributes: function (dest) {
1456
+ dest.beginPropertyChanges();
1457
+ set(dest, 'id', get(this, 'id'));
1458
+ set(dest, 'clientId', get(this, 'clientId'));
1459
+ set(dest, 'errors', Ember.copy(get(this, 'errors')));
1460
+ set(dest, 'isDeleted', get(this, 'isDeleted'));
1461
+ this.eachAttribute(function (name, meta) {
1462
+ var left = get(this, name);
1463
+ var right = get(dest, name);
1464
+ set(dest, name, left);
1465
+ }, this);
1466
+ dest.endPropertyChanges();
1467
+ }
1468
+ });
1469
+ Ep.Model.reopenClass({
1470
+ find: function (id) {
1471
+ if (!Ep.__container__) {
1472
+ throw new Ember.Error('The Ep.__container__ property must be set in order to use static find methods.');
1473
+ }
1474
+ var container = Ep.__container__;
1475
+ var session = container.lookup('session:main');
1476
+ return session.find(this, id);
1477
+ }
1478
+ });
1479
+ });
1480
+ require.define('/lib/collections/model_set.js', function (module, exports, __dirname, __filename) {
1481
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone, fmt = Ember.String.fmt;
1482
+ function guidFor(model) {
1483
+ return get(model, 'clientId');
1484
+ }
1485
+ Ep.ModelSet = Ember.CoreObject.extend(Ember.MutableEnumerable, Ember.Copyable, Ember.Freezable, {
1486
+ length: 0,
1487
+ clear: function () {
1488
+ if (this.isFrozen) {
1489
+ throw new Error(Ember.FROZEN_ERROR);
1490
+ }
1491
+ var len = get(this, 'length');
1492
+ if (len === 0) {
1493
+ return this;
1494
+ }
1495
+ var guid;
1496
+ this.enumerableContentWillChange(len, 0);
1497
+ Ember.propertyWillChange(this, 'firstObject');
1498
+ Ember.propertyWillChange(this, 'lastObject');
1499
+ for (var i = 0; i < len; i++) {
1500
+ guid = guidFor(this[i]);
1501
+ delete this[guid];
1502
+ delete this[i];
1503
+ }
1504
+ set(this, 'length', 0);
1505
+ Ember.propertyDidChange(this, 'firstObject');
1506
+ Ember.propertyDidChange(this, 'lastObject');
1507
+ this.enumerableContentDidChange(len, 0);
1508
+ return this;
1509
+ },
1510
+ isEqual: function (obj) {
1511
+ if (!Ember.Enumerable.detect(obj))
1512
+ return false;
1513
+ var loc = get(this, 'length');
1514
+ if (get(obj, 'length') !== loc)
1515
+ return false;
1516
+ while (--loc >= 0) {
1517
+ if (!obj.contains(this[loc]))
1518
+ return false;
1519
+ }
1520
+ return true;
1521
+ },
1522
+ add: Ember.aliasMethod('addObject'),
1523
+ remove: Ember.aliasMethod('removeObject'),
1524
+ pop: function () {
1525
+ if (get(this, 'isFrozen'))
1526
+ throw new Error(Ember.FROZEN_ERROR);
1527
+ var obj = this.length > 0 ? this[this.length - 1] : null;
1528
+ this.remove(obj);
1529
+ return obj;
1530
+ },
1531
+ push: Ember.aliasMethod('addObject'),
1532
+ shift: Ember.aliasMethod('pop'),
1533
+ unshift: Ember.aliasMethod('push'),
1534
+ addEach: Ember.aliasMethod('addObjects'),
1535
+ removeEach: Ember.aliasMethod('removeObjects'),
1536
+ init: function (items) {
1537
+ this._super();
1538
+ if (items)
1539
+ this.addObjects(items);
1540
+ },
1541
+ nextObject: function (idx) {
1542
+ return this[idx];
1543
+ },
1544
+ firstObject: Ember.computed(function () {
1545
+ return this.length > 0 ? this[0] : undefined;
1546
+ }),
1547
+ lastObject: Ember.computed(function () {
1548
+ return this.length > 0 ? this[this.length - 1] : undefined;
1549
+ }),
1550
+ addObject: function (obj) {
1551
+ if (get(this, 'isFrozen'))
1552
+ throw new Error(Ember.FROZEN_ERROR);
1553
+ if (isNone(obj))
1554
+ return this;
1555
+ var guid = guidFor(obj), idx = this[guid], len = get(this, 'length'), added;
1556
+ if (idx >= 0 && idx < len && (this[idx] && this[idx].isEqual(obj))) {
1557
+ if (this[idx] !== obj) {
1558
+ this[idx] = obj;
1559
+ }
1560
+ return this;
1561
+ }
1562
+ added = [obj];
1563
+ this.enumerableContentWillChange(null, added);
1564
+ Ember.propertyWillChange(this, 'lastObject');
1565
+ len = get(this, 'length');
1566
+ this[guid] = len;
1567
+ this[len] = obj;
1568
+ set(this, 'length', len + 1);
1569
+ Ember.propertyDidChange(this, 'lastObject');
1570
+ this.enumerableContentDidChange(null, added);
1571
+ return this;
1572
+ },
1573
+ removeObject: function (obj) {
1574
+ if (get(this, 'isFrozen'))
1575
+ throw new Error(Ember.FROZEN_ERROR);
1576
+ if (isNone(obj))
1577
+ return this;
1578
+ var guid = guidFor(obj), idx = this[guid], len = get(this, 'length'), isFirst = idx === 0, isLast = idx === len - 1, last, removed;
1579
+ if (idx >= 0 && idx < len && (this[idx] && this[idx].isEqual(obj))) {
1580
+ removed = [obj];
1581
+ this.enumerableContentWillChange(removed, null);
1582
+ if (isFirst) {
1583
+ Ember.propertyWillChange(this, 'firstObject');
1584
+ }
1585
+ if (isLast) {
1586
+ Ember.propertyWillChange(this, 'lastObject');
1587
+ }
1588
+ if (idx < len - 1) {
1589
+ last = this[len - 1];
1590
+ this[idx] = last;
1591
+ this[guidFor(last)] = idx;
1592
+ }
1593
+ delete this[guid];
1594
+ delete this[len - 1];
1595
+ set(this, 'length', len - 1);
1596
+ if (isFirst) {
1597
+ Ember.propertyDidChange(this, 'firstObject');
1598
+ }
1599
+ if (isLast) {
1600
+ Ember.propertyDidChange(this, 'lastObject');
1601
+ }
1602
+ this.enumerableContentDidChange(removed, null);
1603
+ }
1604
+ return this;
1605
+ },
1606
+ contains: function (obj) {
1607
+ return this[guidFor(obj)] >= 0;
1608
+ },
1609
+ copy: function (deep) {
1610
+ var C = this.constructor, ret = new C(), loc = get(this, 'length');
1611
+ set(ret, 'length', loc);
1612
+ while (--loc >= 0) {
1613
+ ret[loc] = deep ? this[loc].copy() : this[loc];
1614
+ ret[guidFor(this[loc])] = loc;
1615
+ }
1616
+ return ret;
1617
+ },
1618
+ toString: function () {
1619
+ var len = this.length, idx, array = [];
1620
+ for (idx = 0; idx < len; idx++) {
1621
+ array[idx] = this[idx];
1622
+ }
1623
+ return fmt('Ep.ModelSet<%@>', [array.join(',')]);
1624
+ },
1625
+ getModel: function (model) {
1626
+ var idx = this[guidFor(model)];
1627
+ if (idx === undefined)
1628
+ return;
1629
+ return this[idx];
1630
+ },
1631
+ getForClientId: function (clientId) {
1632
+ var idx = this[clientId];
1633
+ if (idx === undefined)
1634
+ return;
1635
+ return this[idx];
1636
+ }
1637
+ });
1638
+ Ep.ModelSet.reopenClass({
1639
+ fromArray: function (models) {
1640
+ var res = this.create();
1641
+ res.addObjects(models);
1642
+ return res;
1643
+ }
1644
+ });
1645
+ });
1646
+ require.define('/lib/model/relationships/belongs_to.js', function (module, exports, __dirname, __filename) {
1647
+ var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
1648
+ Ep.belongsTo = function (type, options) {
1649
+ Ember.assert('The type passed to Ep.belongsTo must be defined', !!type);
1650
+ options = options || {};
1651
+ var meta = {
1652
+ type: type,
1653
+ isRelationship: true,
1654
+ options: options,
1655
+ kind: 'belongsTo'
1656
+ };
1657
+ return Ember.computed(function (key, value) {
1658
+ if (arguments.length === 1) {
1659
+ return null;
1660
+ } else {
1661
+ var session = get(this, 'session');
1662
+ if (value && session) {
1663
+ value = session.add(value);
1664
+ }
1665
+ return value;
1666
+ }
1667
+ }).property().meta(meta);
1668
+ };
1669
+ Ep.Model.reopen({
1670
+ belongsToWillChange: Ember.beforeObserver(function (model, key) {
1671
+ var oldParent = get(model, key);
1672
+ var session = get(model, 'session');
1673
+ if (session) {
1674
+ session.modelWillBecomeDirty(model);
1675
+ }
1676
+ if (oldParent && session) {
1677
+ session.belongsToManager.unregister(model, key, oldParent);
1678
+ }
1679
+ if (oldParent && get(oldParent, 'isLoaded')) {
1680
+ var inverse = get(model, 'type').inverseFor(key);
1681
+ if (inverse) {
1682
+ oldParent.suspendRelationshipObservers(function () {
1683
+ if (inverse.kind === 'hasMany' && model) {
1684
+ get(oldParent, inverse.name).removeObject(model);
1685
+ } else if (inverse.kind === 'belongsTo') {
1686
+ set(oldParent, inverse.name, null);
1687
+ if (session) {
1688
+ session.modelWillBecomeDirty(oldParent);
1689
+ session.belongsToManager.unregister(oldParent, inverse.name, model);
1690
+ }
1691
+ }
1692
+ });
1693
+ }
1694
+ }
1695
+ }),
1696
+ belongsToDidChange: Ember.immediateObserver(function (model, key) {
1697
+ var parent = get(model, key);
1698
+ var session = get(model, 'session');
1699
+ if (parent && session) {
1700
+ session.belongsToManager.register(model, key, parent);
1701
+ }
1702
+ if (parent && get(parent, 'isLoaded')) {
1703
+ var inverse = get(model, 'type').inverseFor(key);
1704
+ if (inverse) {
1705
+ parent.suspendRelationshipObservers(function () {
1706
+ if (inverse.kind === 'hasMany' && model) {
1707
+ get(parent, inverse.name).addObject(model);
1708
+ } else if (inverse.kind === 'belongsTo') {
1709
+ set(parent, inverse.name, model);
1710
+ if (session)
1711
+ session.belongsToManager.register(parent, inverse.name, model);
1712
+ }
1713
+ });
1714
+ }
1715
+ }
1716
+ })
1717
+ });
1718
+ });
1719
+ require.define('/lib/model/attribute.js', function (module, exports, __dirname, __filename) {
1720
+ var get = Ember.get, set = Ember.set;
1721
+ Ep.Model.reopenClass({
1722
+ attributes: Ember.computed(function () {
1723
+ var map = Ember.Map.create();
1724
+ this.eachComputedProperty(function (name, meta) {
1725
+ if (meta.isAttribute) {
1726
+ Ember.assert('You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: Ep.attr(\'<type>\')` from ' + this.toString(), name !== 'id');
1727
+ meta.name = name;
1728
+ map.set(name, meta);
1729
+ }
1730
+ });
1731
+ return map;
1732
+ })
1733
+ });
1734
+ Ep.Model.reopen({
1735
+ eachAttribute: function (callback, binding) {
1736
+ get(this.constructor, 'attributes').forEach(function (name, meta) {
1737
+ callback.call(binding, name, meta);
1738
+ }, binding);
1739
+ },
1740
+ attributeWillChange: Ember.beforeObserver(function (record, key) {
1741
+ var session = get(this, 'session');
1742
+ if (!session)
1743
+ return;
1744
+ session.modelWillBecomeDirty(this);
1745
+ })
1746
+ });
1747
+ Ep.attr = function (type, options) {
1748
+ options = options || {};
1749
+ var meta = {
1750
+ type: type,
1751
+ isAttribute: true,
1752
+ options: options
1753
+ };
1754
+ return Ember.computed(function (key, value, oldValue) {
1755
+ if (arguments.length > 1) {
1756
+ Ember.assert('You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: Ep.attr(\'<type>\')` from ' + this.constructor.toString(), key !== 'id');
1757
+ }
1758
+ return value;
1759
+ }).meta(meta);
1760
+ };
1761
+ });
1762
+ require.define('/lib/model/proxies.js', function (module, exports, __dirname, __filename) {
1763
+ var get = Ember.get, set = Ember.set;
1764
+ function triggerLoad(async) {
1765
+ return function () {
1766
+ if (!get(this, 'content') && !get(this, 'isLoading')) {
1767
+ if (async) {
1768
+ Ember.run.later(this, 'load', 0);
1769
+ } else {
1770
+ this.load();
1771
+ }
1772
+ }
1773
+ return this._super.apply(this, arguments);
1774
+ };
1775
+ }
1776
+ function passThrough(key, defaultValue) {
1777
+ return Ember.computed(function (key, value) {
1778
+ var content = get(this, 'content');
1779
+ if (arguments.length === 1) {
1780
+ if (content) {
1781
+ return get(content, key);
1782
+ } else {
1783
+ return defaultValue;
1784
+ }
1785
+ }
1786
+ if (content) {
1787
+ return set(content, key, value);
1788
+ }
1789
+ return value;
1790
+ }).property('content.' + key);
1791
+ }
1792
+ function passThroughMethod(name, defaultReturn) {
1793
+ return function () {
1794
+ var content = get(this, 'content');
1795
+ if (!content)
1796
+ return defaultReturn;
1797
+ return content[name].apply(content, arguments);
1798
+ };
1799
+ }
1800
+ Ep.ModelProxy = Ember.ObjectProxy.extend(Ember.Copyable, Ep.ModelMixin, {
1801
+ id: passThrough('id'),
1802
+ clientId: passThrough('clientId'),
1803
+ type: passThrough('type'),
1804
+ isPromise: false,
1805
+ isLoaded: passThrough('isLoaded', false),
1806
+ isLoading: false,
1807
+ isDeleted: passThrough('isDeleted', false),
1808
+ isNew: passThrough('isNew', false),
1809
+ isProxy: true,
1810
+ errors: passThrough('errors'),
1811
+ copy: function () {
1812
+ var content = get(this, 'content');
1813
+ if (content) {
1814
+ return content.copy();
1815
+ }
1816
+ return this.lazyCopy();
1817
+ }
1818
+ });
1819
+ Ep.LoadError = Ep.ModelProxy.extend({});
1820
+ Ep.ModelPromise = Ep.ModelProxy.extend(Ember.DeferredMixin, {
1821
+ isPromise: true,
1822
+ isNew: false,
1823
+ resolve: function (model) {
1824
+ set(this, 'content', model);
1825
+ return this._super.apply(this, arguments);
1826
+ },
1827
+ hasIdentifiers: Ember.computed(function () {
1828
+ return get(this, 'type') && (get(this, 'id') || get(this, 'clientId'));
1829
+ }).volatile(),
1830
+ toStringExtension: function () {
1831
+ var content = get(this, 'content');
1832
+ if (content) {
1833
+ return content.toString();
1834
+ } else if (get(this, 'hasIdentifiers')) {
1835
+ var type = get(this, 'type');
1836
+ return '(unloaded ' + type.toString() + '):' + this._super();
1837
+ } else {
1838
+ return '(no identifiers)';
1839
+ }
1840
+ },
1841
+ diff: passThroughMethod('diff', []),
1842
+ suspendRelationshipObservers: passThroughMethod('suspendRelationshipObservers'),
1843
+ eachAttribute: passThroughMethod('eachAttribute'),
1844
+ eachRelationship: passThroughMethod('eachRelationship'),
1845
+ _registerRelationships: passThroughMethod('_registerRelationships')
1846
+ });
1847
+ Ep.LazyModel = Ep.ModelPromise.extend({
1848
+ willWatchProperty: triggerLoad(true),
1849
+ unknownProperty: triggerLoad(),
1850
+ setUnknownProperty: triggerLoad(),
1851
+ then: triggerLoad(true),
1852
+ resolve: function () {
1853
+ set(this, 'isLoading', false);
1854
+ return this._super.apply(this, arguments);
1855
+ },
1856
+ load: function () {
1857
+ if (get(this, 'isLoading'))
1858
+ return this;
1859
+ var session = get(this, 'session');
1860
+ var type = get(this, 'type');
1861
+ var id = get(this, 'id');
1862
+ set(this, 'isLoading', true);
1863
+ Ember.assert('Must be attached to a session.', get(this, 'session'));
1864
+ Ember.assert('Must have an id to load.', id);
1865
+ var promise = this.session.load(type, id);
1866
+ if (get(promise, 'isLoaded')) {
1867
+ this.resolve(Ep.unwrap(promise));
1868
+ } else {
1869
+ var proxy = this;
1870
+ promise.then(function (model) {
1871
+ proxy.resolve(model);
1872
+ return model;
1873
+ }, function (err) {
1874
+ proxy.reject(err);
1875
+ return err;
1876
+ });
1877
+ }
1878
+ return this;
1879
+ }
1880
+ });
1881
+ Ep.unwrap = function (modelOrPromise) {
1882
+ if (get(modelOrPromise, 'isProxy')) {
1883
+ return get(modelOrPromise, 'content');
1884
+ }
1885
+ return modelOrPromise;
1886
+ };
1887
+ Ep.resolveModel = function (modelOrPromise, type, id, session) {
1888
+ if (modelOrPromise instanceof Ep.ModelPromise) {
1889
+ return modelOrPromise;
1890
+ }
1891
+ id = get(modelOrPromise, 'id') || id;
1892
+ var clientId = get(modelOrPromise, 'clientId');
1893
+ type = get(modelOrPromise, 'type') || type;
1894
+ session = get(modelOrPromise, 'session') || session;
1895
+ var promise = Ep.ModelPromise.create({
1896
+ id: id,
1897
+ clientId: clientId,
1898
+ type: type,
1899
+ session: session
1900
+ });
1901
+ if (typeof modelOrPromise.then !== 'function') {
1902
+ promise.resolve(modelOrPromise);
1903
+ } else {
1904
+ modelOrPromise.then(function (model) {
1905
+ promise.resolve(model);
1906
+ return model;
1907
+ }, function (err) {
1908
+ promise.reject(err);
1909
+ throw err;
1910
+ });
1911
+ }
1912
+ return promise;
1913
+ };
1914
+ });
1915
+ require.define('/lib/rest/rest_adapter.js', function (module, exports, __dirname, __filename) {
1916
+ require('/lib/adapter.js', module);
1917
+ require('/lib/rest/embedded_manager.js', module);
1918
+ require('/lib/rest/operation_graph.js', module);
1919
+ require('/lib/rest/rest_errors.js', module);
1920
+ var get = Ember.get, set = Ember.set;
1921
+ Ep.RestAdapter = Ep.Adapter.extend({
1922
+ init: function () {
1923
+ this._super.apply(this, arguments);
1924
+ this._embeddedManager = Ep.EmbeddedManager.create({ adapter: this });
1925
+ this._pendingOps = {};
1926
+ },
1927
+ load: function (type, id) {
1928
+ var root = this.rootForType(type), adapter = this;
1929
+ return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
1930
+ return Ember.run(adapter, 'didReceiveDataForLoad', json, type, id);
1931
+ }, function (xhr) {
1932
+ var model = Ep.LoadError.create({
1933
+ id: id,
1934
+ type: type
1935
+ });
1936
+ throw Ember.run(adapter, 'didError', xhr, model);
1937
+ });
1938
+ },
1939
+ refresh: function (model) {
1940
+ var type = get(model, 'type');
1941
+ var root = this.rootForType(type), adapter = this;
1942
+ var id = get(model, 'id');
1943
+ return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
1944
+ return Ember.run(adapter, 'didReceiveData', json, model);
1945
+ }, function (xhr) {
1946
+ throw Ember.run(adapter, 'didError', xhr, model);
1947
+ });
1948
+ },
1949
+ update: function (model) {
1950
+ var id, root, adapter, data, type = get(model, 'type');
1951
+ id = get(model, 'id');
1952
+ root = this.rootForType(type);
1953
+ adapter = this;
1954
+ data = {};
1955
+ data[root] = get(this, 'serializer').serialize(model);
1956
+ return this.ajax(this.buildURL(root, id), 'PUT', { data: data }).then(function (json) {
1957
+ return Ember.run(adapter, 'didReceiveData', json, model);
1958
+ }, function (xhr) {
1959
+ throw Ember.run(adapter, 'didError', xhr, model);
1960
+ });
1961
+ },
1962
+ create: function (model) {
1963
+ var type = get(model, 'type');
1964
+ var root = this.rootForType(type);
1965
+ var adapter = this;
1966
+ var data = {};
1967
+ data[root] = get(this, 'serializer').serialize(model, { includeId: true });
1968
+ return this.ajax(this.buildURL(root), 'POST', { data: data }).then(function (json) {
1969
+ return Ember.run(adapter, 'didReceiveDataForCreate', json, model);
1970
+ }, function (xhr) {
1971
+ throw Ember.run(adapter, 'didError', xhr, model);
1972
+ });
1973
+ },
1974
+ deleteModel: function (model) {
1975
+ var id, root, adapter, type = get(model, 'type');
1976
+ id = get(model, 'id');
1977
+ root = this.rootForType(type);
1978
+ adapter = this;
1979
+ return this.ajax(this.buildURL(root, id), 'DELETE').then(function (json) {
1980
+ return Ember.run(adapter, 'didReceiveData', json, model);
1981
+ }, function (xhr) {
1982
+ throw Ember.run(adapter, 'didError', xhr, model);
1983
+ });
1984
+ },
1985
+ query: function (type, query) {
1986
+ var root = this.rootForType(type), adapter = this;
1987
+ return this.ajax(this.buildURL(root), 'GET', { data: query }).then(function (json) {
1988
+ return Ember.run(adapter, 'didReceiveDataForFind', json, type);
1989
+ }, function (xhr) {
1990
+ throw xhr;
1991
+ });
1992
+ },
1993
+ remoteCall: function (context, name, params) {
1994
+ var url, adapter = this;
1995
+ if (typeof context === 'string') {
1996
+ context = this.lookupType(context);
1997
+ }
1998
+ if (typeof context === 'function') {
1999
+ url = this.buildURL(this.rootForType(context));
2000
+ } else {
2001
+ var id = get(context, 'id');
2002
+ Ember.assert('Cannot perform a remote call with a context that doesn\'t have an id', id);
2003
+ url = this.buildURL(this.rootForType(context.constructor), id);
2004
+ }
2005
+ url = url + '/' + name;
2006
+ var data = params;
2007
+ var method = 'POST';
2008
+ return this.ajax(url, method, { data: data }).then(function (json) {
2009
+ return Ember.run(adapter, 'didReceiveDataForRpc', json, context);
2010
+ }, function (xhr) {
2011
+ throw Ember.run(adapter, 'didError', xhr, context);
2012
+ });
2013
+ },
2014
+ lookupType: function (type) {
2015
+ return this.container.lookup('model:' + type);
2016
+ },
2017
+ didReceiveData: function (data, targetModel) {
2018
+ var result = null;
2019
+ this.processData(data, function (model) {
2020
+ if (targetModel && model.isEqual(targetModel)) {
2021
+ result = model;
2022
+ }
2023
+ });
2024
+ return result || targetModel;
2025
+ },
2026
+ didReceiveDataForCreate: function (data, targetModel) {
2027
+ var result = null;
2028
+ this.processData(data, function (model) {
2029
+ if (targetModel && model.isEqual(targetModel)) {
2030
+ result = model;
2031
+ }
2032
+ });
2033
+ set(targetModel, 'id', get(result, 'id'));
2034
+ return result;
2035
+ },
2036
+ didReceiveDataForLoad: function (data, type, id) {
2037
+ var result = null;
2038
+ this.processData(data, function (model) {
2039
+ if (model.hasType(type) && get(model, 'id') === id) {
2040
+ result = model;
2041
+ }
2042
+ });
2043
+ return result;
2044
+ },
2045
+ didReceiveDataForFind: function (data, type) {
2046
+ var result = [];
2047
+ this.processData(data, function (model) {
2048
+ if (model.hasType(type)) {
2049
+ result.pushObject(model);
2050
+ }
2051
+ });
2052
+ return Ep.ModelArray.create({ content: result });
2053
+ },
2054
+ didReceiveDataForRpc: function (data, context) {
2055
+ return this.didReceiveData(data, context);
2056
+ },
2057
+ processData: function (data, callback, binding) {
2058
+ var models = get(this, 'serializer').deserialize(data);
2059
+ models.forEach(function (model) {
2060
+ this.willLoadModel(model);
2061
+ }, this);
2062
+ models.forEach(function (model) {
2063
+ this.didLoadModel(model);
2064
+ callback.call(binding || this, model);
2065
+ }, this);
2066
+ this.materializeRelationships(models);
2067
+ },
2068
+ willLoadModel: function (model) {
2069
+ model.eachRelatedModel(function (relative) {
2070
+ if (get(relative, 'clientId')) {
2071
+ this.reifyClientId(model);
2072
+ }
2073
+ }, this);
2074
+ },
2075
+ didLoadModel: function (model) {
2076
+ model.eachRelatedModel(function (relative) {
2077
+ this.reifyClientId(relative);
2078
+ }, this);
2079
+ this._embeddedManager.updateParents(model);
2080
+ },
2081
+ didError: function (xhr, model) {
2082
+ var errors;
2083
+ if (xhr.status === 422) {
2084
+ var json = JSON.parse(xhr.responseText), serializer = get(this, 'serializer'), validationErrors = serializer.extractValidationErrors(get(model, 'type'), json);
2085
+ errors = Ep.RestErrors.create({ content: validationErrors });
2086
+ } else {
2087
+ errors = Ep.RestErrors.create();
2088
+ }
2089
+ set(errors, 'status', xhr.status);
2090
+ set(errors, 'xhr', xhr);
2091
+ set(model, 'errors', errors);
2092
+ throw model;
2093
+ },
2094
+ flush: function (session) {
2095
+ var models = get(session, 'dirtyModels').copy(true);
2096
+ var shadows = Ep.ModelSet.fromArray(models.map(function (model) {
2097
+ return session.shadows.getModel(model);
2098
+ }));
2099
+ this.dirtyEmbedded(models, shadows, session);
2100
+ this.materializeRelationships(models);
2101
+ var op = Ep.OperationGraph.create({
2102
+ models: models,
2103
+ shadows: shadows,
2104
+ adapter: this
2105
+ });
2106
+ return this._performFlush(op);
2107
+ },
2108
+ _performFlush: function (op) {
2109
+ var models = get(op, 'models'), pending = Ember.Set.create();
2110
+ models.forEach(function (model) {
2111
+ var op = this._pendingOps[model.clientId];
2112
+ if (op)
2113
+ pending.add(op);
2114
+ }, this);
2115
+ var adapter = this;
2116
+ if (get(pending, 'length') > 0) {
2117
+ return Ember.RSVP.all(pending.toArray()).then(function () {
2118
+ return adapter._performFlush(op);
2119
+ });
2120
+ }
2121
+ var promise = op.perform();
2122
+ models.forEach(function (model) {
2123
+ this._pendingOps[model.clientId] = promise;
2124
+ }, this);
2125
+ return promise.then(function (res) {
2126
+ models.forEach(function (model) {
2127
+ delete adapter._pendingOps[model.clientId];
2128
+ });
2129
+ return res;
2130
+ }, function (err) {
2131
+ models.forEach(function (model) {
2132
+ delete adapter._pendingOps[model.clientId];
2133
+ });
2134
+ throw err;
2135
+ });
2136
+ },
2137
+ rebuildRelationships: function (children, parent) {
2138
+ var serializer = get(this, 'serializer');
2139
+ parent.suspendRelationshipObservers(function () {
2140
+ for (var i = 0; i < children.length; i++) {
2141
+ var child = children[i];
2142
+ child.eachRelationship(function (name, relationship) {
2143
+ if (relationship.kind === 'belongsTo') {
2144
+ var value = get(child, name);
2145
+ var inverse = child.constructor.inverseFor(name);
2146
+ if (inverse) {
2147
+ if (serializer.embeddedType(inverse.type, inverse.name)) {
2148
+ return;
2149
+ }
2150
+ if (inverse.kind === 'hasMany') {
2151
+ var parentCollection = get(parent, inverse.name);
2152
+ if (child.get('isDeleted')) {
2153
+ parentCollection.removeObject(child);
2154
+ } else if (value && value.isEqual(parent)) {
2155
+ parentCollection.addObject(child);
2156
+ }
2157
+ }
2158
+ }
2159
+ }
2160
+ });
2161
+ }
2162
+ });
2163
+ },
2164
+ isRelationshipOwner: function (relationship) {
2165
+ var serializer = get(this, 'serializer');
2166
+ var owner = serializer.mappingOption(relationship.parentType, relationship.key, 'owner');
2167
+ return relationship.kind === 'belongsTo' && owner !== false || relationship.kind === 'hasMany' && owner === true;
2168
+ },
2169
+ isDirtyFromRelationships: function (model, cached, relDiff) {
2170
+ var serializer = get(this, 'serializer');
2171
+ for (var i = 0; i < relDiff.length; i++) {
2172
+ var diff = relDiff[i];
2173
+ if (this.isRelationshipOwner(diff.relationship) || serializer.embeddedType(model.constructor, diff.name) === 'always') {
2174
+ return true;
2175
+ }
2176
+ }
2177
+ return false;
2178
+ },
2179
+ shouldSave: function (model) {
2180
+ return !this.isEmbedded(model);
2181
+ },
2182
+ isEmbedded: function (model) {
2183
+ return this._embeddedManager.isEmbedded(model);
2184
+ },
2185
+ dirtyEmbedded: function (models, shadows, session) {
2186
+ this.dirtyEmbeddedParents(models, shadows, session);
2187
+ models.forEach(function (model) {
2188
+ this.dirtyEmbeddedTree(model, models, shadows, session);
2189
+ }, this);
2190
+ },
2191
+ dirtyEmbeddedParents: function (models, shadows, session) {
2192
+ models.forEach(function (model) {
2193
+ var parent;
2194
+ while (parent = this._embeddedManager.findParent(model)) {
2195
+ model = session.getModel(parent);
2196
+ if (!models.contains(model)) {
2197
+ var copy = model.copy();
2198
+ models.add(copy);
2199
+ shadows.add(copy);
2200
+ }
2201
+ }
2202
+ }, this);
2203
+ },
2204
+ dirtyEmbeddedTree: function (model, models, shadows, session) {
2205
+ get(this, 'serializer').eachEmbeddedRecord(model, function (embeddedRecord, embeddedType) {
2206
+ if (embeddedType !== 'always') {
2207
+ return;
2208
+ }
2209
+ if (models.contains(embeddedRecord)) {
2210
+ return;
2211
+ }
2212
+ embeddedRecord = session.getModel(embeddedRecord);
2213
+ if (!embeddedRecord)
2214
+ return;
2215
+ if (!models.contains(embeddedRecord)) {
2216
+ var copy = embeddedRecord.copy();
2217
+ models.add(copy);
2218
+ shadows.add(copy);
2219
+ }
2220
+ this.dirtyEmbeddedTree(embeddedRecord, models, shadows, session);
2221
+ }, this);
2222
+ },
2223
+ findEmbeddedRoot: function (model, models) {
2224
+ var parent = model;
2225
+ while (parent) {
2226
+ model = parent;
2227
+ parent = this._embeddedManager.findParent(model);
2228
+ }
2229
+ return models.getModel(model);
2230
+ },
2231
+ materializeRelationships: function (models) {
2232
+ if (!(models instanceof Ep.ModelSet)) {
2233
+ models = Ep.ModelSet.fromArray(models);
2234
+ }
2235
+ models.forEach(function (model) {
2236
+ model.eachRelationship(function (name, relationship) {
2237
+ if (relationship.kind === 'belongsTo') {
2238
+ var child = get(model, name);
2239
+ if (child) {
2240
+ child = models.getModel(child) || child;
2241
+ set(model, name, child);
2242
+ }
2243
+ } else if (relationship.kind === 'hasMany') {
2244
+ var children = get(model, name);
2245
+ var lazyChildren = Ep.ModelSet.create();
2246
+ lazyChildren.addObjects(children);
2247
+ children.clear();
2248
+ lazyChildren.forEach(function (child) {
2249
+ child = models.getModel(child) || child;
2250
+ children.addObject(child);
2251
+ });
2252
+ }
2253
+ }, this);
2254
+ }, this);
2255
+ },
2256
+ ajax: function (url, type, hash) {
2257
+ try {
2258
+ hash = hash || {};
2259
+ hash.url = url;
2260
+ hash.type = type;
2261
+ hash.dataType = 'json';
2262
+ hash.context = this;
2263
+ if (hash.data && type !== 'GET') {
2264
+ hash.contentType = 'application/json; charset=utf-8';
2265
+ hash.data = JSON.stringify(hash.data);
2266
+ }
2267
+ return Ember.RSVP.resolve(jQuery.ajax(hash));
2268
+ } catch (error) {
2269
+ return Ember.RSVP.resolve(error);
2270
+ }
2271
+ },
2272
+ url: '',
2273
+ rootForType: function (type) {
2274
+ var serializer = get(this, 'serializer');
2275
+ return serializer.rootForType(type);
2276
+ },
2277
+ pluralize: function (string) {
2278
+ var serializer = get(this, 'serializer');
2279
+ return serializer.pluralize(string);
2280
+ },
2281
+ buildURL: function (record, suffix) {
2282
+ var url = [this.url];
2283
+ Ember.assert('Namespace URL (' + this.namespace + ') must not start with slash', !this.namespace || this.namespace.toString().charAt(0) !== '/');
2284
+ Ember.assert('Record URL (' + record + ') must not start with slash', !record || record.toString().charAt(0) !== '/');
2285
+ Ember.assert('URL suffix (' + suffix + ') must not start with slash', !suffix || suffix.toString().charAt(0) !== '/');
2286
+ if (!Ember.isNone(this.namespace)) {
2287
+ url.push(this.namespace);
2288
+ }
2289
+ url.push(this.pluralize(record));
2290
+ if (suffix !== undefined) {
2291
+ url.push(suffix);
2292
+ }
2293
+ return url.join('/');
2294
+ }
2295
+ });
2296
+ });
2297
+ require.define('/lib/rest/rest_errors.js', function (module, exports, __dirname, __filename) {
2298
+ var get = Ember.get, set = Ember.set;
2299
+ Ep.RestErrors = Ep.Errors.extend({
2300
+ status: null,
2301
+ xhr: null,
2302
+ copy: function () {
2303
+ return Ep.RestErrors.create({
2304
+ content: Ember.copy(this.content),
2305
+ status: this.status,
2306
+ xhr: this.xhr
2307
+ });
2308
+ }
2309
+ });
2310
+ });
2311
+ require.define('/lib/rest/operation_graph.js', function (module, exports, __dirname, __filename) {
2312
+ require('/lib/rest/operation.js', module);
2313
+ var get = Ember.get, set = Ember.set;
2314
+ var Node = function (model) {
2315
+ this.op = null;
2316
+ this.children = Ember.Set.create();
2317
+ this.parents = Ember.Set.create();
2318
+ this.dirty = false;
2319
+ this.dirtyEmbeddedChildren = false;
2320
+ };
2321
+ Node.prototype = {
2322
+ addChild: function (childNode) {
2323
+ this.children.add(childNode);
2324
+ childNode.parents.add(this);
2325
+ },
2326
+ isRoot: function () {
2327
+ return this.parents.every(function (parent) {
2328
+ return !get(parent, 'dirty') && parent.isRoot();
2329
+ });
2330
+ },
2331
+ toString: function (depth) {
2332
+ if (!depth)
2333
+ depth = 0;
2334
+ var prefix = '';
2335
+ for (var i = 0; i < depth; i++) {
2336
+ prefix += ' ';
2337
+ }
2338
+ return prefix + this.op.toString() + this.children.map(function (child) {
2339
+ return '\n' + child.toString(depth + 1);
2340
+ });
2341
+ }
2342
+ };
2343
+ Ep.OperationGraph = Ember.Object.extend({
2344
+ models: null,
2345
+ shadows: null,
2346
+ rootNodes: null,
2347
+ adapter: null,
2348
+ nodes: null,
2349
+ init: function () {
2350
+ this.nodes = Ember.MapWithDefault.create({
2351
+ defaultValue: function (model) {
2352
+ return new Node(model);
2353
+ }
2354
+ });
2355
+ this.rootNodes = Ember.Set.create();
2356
+ this.build();
2357
+ },
2358
+ perform: function () {
2359
+ return this.createPromise();
2360
+ },
2361
+ build: function () {
2362
+ var adapter = get(this, 'adapter');
2363
+ var models = get(this, 'models');
2364
+ var shadows = get(this, 'shadows');
2365
+ var rootNodes = get(this, 'rootNodes');
2366
+ var nodes = get(this, 'nodes');
2367
+ models.forEach(function (model) {
2368
+ if (!get(model, 'isLoaded')) {
2369
+ return;
2370
+ }
2371
+ var shadow = shadows.getModel(model);
2372
+ var node = nodes.get(model);
2373
+ node.op = Ep.Operation.create({
2374
+ model: model,
2375
+ shadow: shadow,
2376
+ graph: this,
2377
+ adapter: adapter
2378
+ });
2379
+ node.dirty = node.dirty || !!get(node.op, 'dirtyType');
2380
+ if (node.dirty && adapter.isEmbedded(model) && !get(model, 'isNew')) {
2381
+ var root = adapter.findEmbeddedRoot(model, models);
2382
+ var rootNode = nodes.get(root);
2383
+ rootNode.dirty = true;
2384
+ rootNode.dirtyEmbeddedChildren = true;
2385
+ }
2386
+ var rels = get(node.op, 'dirtyRelationships');
2387
+ for (var i = 0; i < rels.length; i++) {
2388
+ var d = rels[i];
2389
+ var name = d.name;
2390
+ var parentModel = model.get(name) || shadows.getModel(d.oldValue);
2391
+ if (parentModel) {
2392
+ parentModel = models.getModel(parentModel);
2393
+ var parentNode = nodes.get(parentModel);
2394
+ parentNode.addChild(node);
2395
+ }
2396
+ }
2397
+ }, this);
2398
+ nodes.forEach(function (model, node) {
2399
+ if (node.dirty && node.isRoot()) {
2400
+ rootNodes.add(node);
2401
+ }
2402
+ }, this);
2403
+ },
2404
+ createPromise: function () {
2405
+ var rootNodes = get(this, 'rootNodes'), adapter = get(this, 'adapter'), cumulative = [];
2406
+ function createNestedPromise(node) {
2407
+ var promise = node.op.perform(node.dirtyEmbeddedChildren);
2408
+ promise = promise.then(function (model) {
2409
+ if (model === get(node.op, 'model')) {
2410
+ cumulative.push(model.lazyCopy());
2411
+ } else {
2412
+ cumulative.push(model);
2413
+ }
2414
+ return model;
2415
+ }, function (model) {
2416
+ cumulative.push(model);
2417
+ throw model;
2418
+ });
2419
+ if (node.children.length > 0) {
2420
+ promise = promise.then(function (model) {
2421
+ var childPromises = node.children.map(createNestedPromise);
2422
+ return Ember.RSVP.all(childPromises).then(function (models) {
2423
+ adapter.rebuildRelationships(models, model);
2424
+ return model;
2425
+ });
2426
+ });
2427
+ }
2428
+ return promise;
2429
+ }
2430
+ return Ember.RSVP.all(rootNodes.map(createNestedPromise)).then(function () {
2431
+ return cumulative;
2432
+ }, function (err) {
2433
+ throw cumulative;
2434
+ });
2435
+ },
2436
+ toStringExtension: function () {
2437
+ var result = '';
2438
+ var rootNodes = get(this, 'rootNodes');
2439
+ rootNodes.forEach(function (node) {
2440
+ result += '\n' + node.toString(1);
2441
+ });
2442
+ return result + '\n';
2443
+ }
2444
+ });
2445
+ });
2446
+ require.define('/lib/rest/operation.js', function (module, exports, __dirname, __filename) {
2447
+ var get = Ember.get, set = Ember.set;
2448
+ Ep.Operation = Ember.Object.extend({
2449
+ model: null,
2450
+ shadow: null,
2451
+ adapter: null,
2452
+ init: function () {
2453
+ this.children = Ember.Set.create();
2454
+ this.parents = Ember.Set.create();
2455
+ },
2456
+ dirtyRelationships: Ember.computed(function () {
2457
+ var adapter = get(this, 'adapter'), model = get(this, 'model'), rels = [], shadow = get(this, 'shadow');
2458
+ if (get(model, 'isNew')) {
2459
+ model.eachRelationship(function (name, relationship) {
2460
+ if (adapter.isRelationshipOwner(relationship)) {
2461
+ rels.push({
2462
+ name: name,
2463
+ type: relationship.kind,
2464
+ relationship: relationship,
2465
+ oldValue: null
2466
+ });
2467
+ }
2468
+ }, this);
2469
+ } else {
2470
+ var diff = model.diff(shadow);
2471
+ for (var i = 0; i < diff.length; i++) {
2472
+ var d = diff[i];
2473
+ if (d.relationship && adapter.isRelationshipOwner(d.relationship)) {
2474
+ rels.push(d);
2475
+ }
2476
+ }
2477
+ }
2478
+ return rels;
2479
+ }),
2480
+ isDirty: Ember.computed(function () {
2481
+ var model = get(this, 'model'), shadow = get(this, 'shadow'), adapter = get(this, 'adapter');
2482
+ var diff = model.diff(shadow);
2483
+ var dirty = false;
2484
+ var relDiff = [];
2485
+ for (var i = 0; i < diff.length; i++) {
2486
+ var d = diff[i];
2487
+ if (d.type == 'attr') {
2488
+ dirty = true;
2489
+ } else {
2490
+ relDiff.push(d);
2491
+ }
2492
+ }
2493
+ return dirty || adapter.isDirtyFromRelationships(model, shadow, relDiff);
2494
+ }),
2495
+ dirtyType: Ember.computed(function () {
2496
+ var model = get(this, 'model');
2497
+ if (get(model, 'isNew')) {
2498
+ return 'created';
2499
+ } else if (get(model, 'isDeleted')) {
2500
+ return 'deleted';
2501
+ } else if (get(this, 'isDirty')) {
2502
+ return 'updated';
2503
+ }
2504
+ }),
2505
+ perform: function (forceUpdate) {
2506
+ var adapter = get(this, 'adapter'), dirtyType = get(this, 'dirtyType'), model = get(this, 'model'), shadow = get(this, 'shadow'), promise;
2507
+ if (!dirtyType && forceUpdate) {
2508
+ dirtyType = 'updated';
2509
+ }
2510
+ if (!dirtyType || !adapter.shouldSave(model)) {
2511
+ promise = Ember.RSVP.resolve(model);
2512
+ } else if (dirtyType === 'created') {
2513
+ promise = adapter.create(model);
2514
+ } else if (dirtyType === 'updated') {
2515
+ promise = adapter.update(model);
2516
+ } else if (dirtyType === 'deleted') {
2517
+ promise = adapter.deleteModel(model);
2518
+ }
2519
+ return promise.then(null, function (model) {
2520
+ if (shadow) {
2521
+ shadow.set('errors', model.get('errors'));
2522
+ throw shadow;
2523
+ }
2524
+ throw model;
2525
+ });
2526
+ },
2527
+ toStringExtension: function () {
2528
+ return '( ' + get(this, 'dirtyType') + ' ' + get(this, 'model') + ' )';
2529
+ }
2530
+ });
2531
+ });
2532
+ require.define('/lib/rest/embedded_manager.js', function (module, exports, __dirname, __filename) {
2533
+ var get = Ember.get, set = Ember.set;
2534
+ Ep.EmbeddedManager = Ember.Object.extend({
2535
+ adapter: null,
2536
+ init: function () {
2537
+ this._super.apply(this, arguments);
2538
+ this._parentMap = {};
2539
+ this._cachedIsEmbedded = Ember.Map.create();
2540
+ },
2541
+ updateParents: function (model) {
2542
+ var serializer = get(this, 'adapter.serializer');
2543
+ var parentType = get(model, 'type');
2544
+ serializer.eachEmbeddedRecord(model, function (embedded, kind) {
2545
+ this._parentMap[get(embedded, 'clientId')] = model;
2546
+ }, this);
2547
+ },
2548
+ findParent: function (model) {
2549
+ var parent = this._parentMap[get(model, 'clientId')];
2550
+ return parent;
2551
+ },
2552
+ isEmbedded: function (model) {
2553
+ var type = get(model, 'type');
2554
+ var result = this._cachedIsEmbedded.get(type);
2555
+ if (result === true || result === false)
2556
+ return result;
2557
+ var adapter = get(this, 'adapter');
2558
+ var mappings = get(adapter, 'serializer.mappings');
2559
+ var result = false;
2560
+ mappings.forEach(function (parentType, value) {
2561
+ for (var name in value) {
2562
+ var embedded = value[name]['embedded'];
2563
+ result = result || embedded === 'always' && parentType.typeForRelationship(name).detect(type);
2564
+ }
2565
+ });
2566
+ this._cachedIsEmbedded.set(type, result);
2567
+ return result;
2568
+ }
2569
+ });
2570
+ });
2571
+ require.define('/lib/adapter.js', function (module, exports, __dirname, __filename) {
2572
+ var get = Ember.get, set = Ember.set, merge = Ember.merge;
2573
+ require('/lib/mixins/mappable.js', module);
2574
+ function mustImplement(name) {
2575
+ return function () {
2576
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
2577
+ };
2578
+ }
2579
+ var uuid = 1;
2580
+ Ep.Adapter = Ember.Object.extend(Ep._Mappable, {
2581
+ init: function () {
2582
+ this._super.apply(this, arguments);
2583
+ this.idMaps = Ember.MapWithDefault.create({
2584
+ defaultValue: function (type) {
2585
+ return Ember.Map.create();
2586
+ }
2587
+ });
2588
+ },
2589
+ newSession: function () {
2590
+ var session = this.container.lookup('session:base');
2591
+ set(session, 'adapter', this);
2592
+ return session;
2593
+ },
2594
+ serializer: Ember.computed(function (key, serializer) {
2595
+ this._attributesMap = this.createInstanceMapFor('attributes');
2596
+ this._configurationsMap = this.createInstanceMapFor('configurations');
2597
+ this.registerSerializerTransforms(this.constructor, serializer, {});
2598
+ this.registerSerializerMappings(serializer);
2599
+ return serializer;
2600
+ }),
2601
+ load: mustImplement('load'),
2602
+ query: mustImplement('find'),
2603
+ refresh: mustImplement('refresh'),
2604
+ flush: mustImplement('flush'),
2605
+ remoteCall: mustImplement('remoteCall'),
2606
+ isDirtyFromRelationships: function (model, cached, relDiff) {
2607
+ return relDiff.length > 0;
2608
+ },
2609
+ shouldSave: function (model) {
2610
+ return true;
2611
+ },
2612
+ registerSerializerTransforms: function (klass, serializer, seen) {
2613
+ var transforms = klass._registeredTransforms, superclass, prop;
2614
+ var enumTransforms = klass._registeredEnumTransforms;
2615
+ for (prop in transforms) {
2616
+ if (!transforms.hasOwnProperty(prop) || prop in seen) {
2617
+ continue;
2618
+ }
2619
+ seen[prop] = true;
2620
+ serializer.registerTransform(prop, transforms[prop]);
2621
+ }
2622
+ for (prop in enumTransforms) {
2623
+ if (!enumTransforms.hasOwnProperty(prop) || prop in seen) {
2624
+ continue;
2625
+ }
2626
+ seen[prop] = true;
2627
+ serializer.registerEnumTransform(prop, enumTransforms[prop]);
2628
+ }
2629
+ if (superclass = klass.superclass) {
2630
+ this.registerSerializerTransforms(superclass, serializer, seen);
2631
+ }
2632
+ },
2633
+ registerSerializerMappings: function (serializer) {
2634
+ var mappings = this._attributesMap, configurations = this._configurationsMap;
2635
+ mappings.forEach(serializer.map, serializer);
2636
+ configurations.forEach(serializer.configure, serializer);
2637
+ },
2638
+ reifyClientId: function (model) {
2639
+ var id = get(model, 'id'), clientId = get(model, 'clientId'), type = get(model, 'type'), idMap = this.idMaps.get(type);
2640
+ if (id && clientId) {
2641
+ var existingClientId = idMap.get(id);
2642
+ Ember.assert('clientId has changed for ' + model.toString(), !existingClientId || existingClientId === clientId);
2643
+ if (!existingClientId) {
2644
+ idMap.set(id, clientId);
2645
+ }
2646
+ } else if (!clientId) {
2647
+ if (id) {
2648
+ clientId = idMap.get(id);
2649
+ }
2650
+ if (!clientId) {
2651
+ clientId = this._generateClientId(type);
2652
+ }
2653
+ set(model, 'clientId', clientId);
2654
+ idMap.set(id, clientId);
2655
+ }
2656
+ return clientId;
2657
+ },
2658
+ getClientId: function (type, id) {
2659
+ var idMap = this.idMaps.get(type);
2660
+ return idMap.get(id);
2661
+ },
2662
+ _generateClientId: function (type) {
2663
+ return this._typeToString(type) + uuid++;
2664
+ },
2665
+ _typeToString: function (type) {
2666
+ return type.toString().split('.')[1].underscore();
2667
+ }
2668
+ });
2669
+ Ep.Adapter.reopenClass({
2670
+ registerTransform: function (attributeType, transform) {
2671
+ var registeredTransforms = this._registeredTransforms || {};
2672
+ registeredTransforms[attributeType] = transform;
2673
+ this._registeredTransforms = registeredTransforms;
2674
+ },
2675
+ registerEnumTransform: function (attributeType, objects) {
2676
+ var registeredEnumTransforms = this._registeredEnumTransforms || {};
2677
+ registeredEnumTransforms[attributeType] = objects;
2678
+ this._registeredEnumTransforms = registeredEnumTransforms;
2679
+ },
2680
+ map: Ep._Mappable.generateMapFunctionFor('attributes', function (key, newValue, map) {
2681
+ var existingValue = map.get(key);
2682
+ merge(existingValue, newValue);
2683
+ }),
2684
+ configure: Ep._Mappable.generateMapFunctionFor('configurations', function (key, newValue, map) {
2685
+ var existingValue = map.get(key);
2686
+ var mappings = newValue && newValue.mappings;
2687
+ if (mappings) {
2688
+ this.map(key, mappings);
2689
+ delete newValue.mappings;
2690
+ }
2691
+ merge(existingValue, newValue);
2692
+ }),
2693
+ resolveMapConflict: function (oldValue, newValue) {
2694
+ merge(newValue, oldValue);
2695
+ return newValue;
2696
+ }
2697
+ });
2698
+ });
2699
+ require.define('/lib/mixins/mappable.js', function (module, exports, __dirname, __filename) {
2700
+ var get = Ember.get;
2701
+ var resolveMapConflict = function (oldValue, newValue) {
2702
+ return oldValue;
2703
+ };
2704
+ var transformMapKey = function (key, value) {
2705
+ return key;
2706
+ };
2707
+ var transformMapValue = function (key, value) {
2708
+ return value;
2709
+ };
2710
+ Ep._Mappable = Ember.Mixin.create({
2711
+ createInstanceMapFor: function (mapName) {
2712
+ var instanceMeta = getMappableMeta(this);
2713
+ instanceMeta.values = instanceMeta.values || {};
2714
+ if (instanceMeta.values[mapName]) {
2715
+ return instanceMeta.values[mapName];
2716
+ }
2717
+ var instanceMap = instanceMeta.values[mapName] = new Ember.Map();
2718
+ var klass = this.constructor;
2719
+ while (klass && klass !== Ep.Store) {
2720
+ this._copyMap(mapName, klass, instanceMap);
2721
+ klass = klass.superclass;
2722
+ }
2723
+ instanceMeta.values[mapName] = instanceMap;
2724
+ return instanceMap;
2725
+ },
2726
+ _copyMap: function (mapName, klass, instanceMap) {
2727
+ var classMeta = getMappableMeta(klass);
2728
+ var classMap = classMeta[mapName];
2729
+ if (classMap) {
2730
+ classMap.forEach(eachMap, this);
2731
+ }
2732
+ function eachMap(key, value) {
2733
+ var transformedKey = (klass.transformMapKey || transformMapKey)(key, value);
2734
+ var transformedValue = (klass.transformMapValue || transformMapValue)(key, value);
2735
+ var oldValue = instanceMap.get(transformedKey);
2736
+ var newValue = transformedValue;
2737
+ if (oldValue) {
2738
+ newValue = (this.constructor.resolveMapConflict || resolveMapConflict)(oldValue, newValue);
2739
+ }
2740
+ instanceMap.set(transformedKey, newValue);
2741
+ }
2742
+ }
2743
+ });
2744
+ Ep._Mappable.generateMapFunctionFor = function (mapName, transform) {
2745
+ return function (key, value) {
2746
+ var meta = getMappableMeta(this);
2747
+ var map = meta[mapName] || Ember.MapWithDefault.create({
2748
+ defaultValue: function () {
2749
+ return {};
2750
+ }
2751
+ });
2752
+ transform.call(this, key, value, map);
2753
+ meta[mapName] = map;
2754
+ };
2755
+ };
2756
+ function getMappableMeta(obj) {
2757
+ var meta = Ember.meta(obj, true), keyName = 'Ep.Mappable', value = meta[keyName];
2758
+ if (!value) {
2759
+ meta[keyName] = {};
2760
+ }
2761
+ if (!meta.hasOwnProperty(keyName)) {
2762
+ meta[keyName] = Ember.create(meta[keyName]);
2763
+ }
2764
+ return meta[keyName];
2765
+ }
2766
+ });
2767
+ require.define('/lib/local/index.js', function (module, exports, __dirname, __filename) {
2768
+ require('/lib/local/local_adapter.js', module);
2769
+ });
2770
+ require.define('/lib/local/local_adapter.js', function (module, exports, __dirname, __filename) {
2771
+ require('/lib/adapter.js', module);
2772
+ var get = Ember.get, set = Ember.set;
2773
+ Ep.LocalAdapter = Ep.Adapter.extend({
2774
+ serializer: Ep.Serializer.create(),
2775
+ load: function (type, id) {
2776
+ return Ember.RSVP.resolve(null);
2777
+ },
2778
+ refresh: function (model) {
2779
+ return Ember.RSVP.resolve(model.copy());
2780
+ },
2781
+ flush: function (session) {
2782
+ var models = get(session, 'dirtyModels');
2783
+ return Ember.RSVP.resolve(models.copy(true));
2784
+ }
2785
+ });
2786
+ });
2787
+ require.define('/lib/session/index.js', function (module, exports, __dirname, __filename) {
2788
+ require('/lib/session/session.js', module);
2789
+ require('/lib/session/merge.js', module);
2790
+ require('/lib/session/child_session.js', module);
2791
+ });
2792
+ require.define('/lib/session/child_session.js', function (module, exports, __dirname, __filename) {
2793
+ var get = Ember.get, set = Ember.set;
2794
+ Ep.ChildSession = Ep.Session.extend({
2795
+ load: function (type, id) {
2796
+ if (typeof type === 'string') {
2797
+ type = this.lookupType(type);
2798
+ }
2799
+ id = id.toString();
2800
+ var cached = this.getForId(type, id);
2801
+ if (cached && get(cached, 'isLoaded')) {
2802
+ return Ep.resolveModel(cached);
2803
+ }
2804
+ var parentModel = get(this, 'parent').getForId(type, id);
2805
+ if (parentModel && get(parentModel, 'isLoaded')) {
2806
+ return Ep.resolveModel(this.merge(parentModel));
2807
+ }
2808
+ var session = this;
2809
+ return Ep.resolveModel(this.parent.load(type, id).then(function (model) {
2810
+ return session.merge(model);
2811
+ }, function (model) {
2812
+ throw session.merge(model);
2813
+ }), type, id, session);
2814
+ },
2815
+ query: function (type, query) {
2816
+ var session = this;
2817
+ return this.parent.query(type, query).then(function (models) {
2818
+ var merged = Ep.ModelArray.create({
2819
+ session: session,
2820
+ content: []
2821
+ });
2822
+ set(merged, 'meta', get(models, 'meta'));
2823
+ models.forEach(function (model) {
2824
+ merged.addObject(session.merge(model));
2825
+ });
2826
+ return merged;
2827
+ });
2828
+ },
2829
+ refresh: function (model) {
2830
+ var session = this;
2831
+ return this.parent.refresh(model).then(function (refreshedModel) {
2832
+ return session.merge(refreshedModel);
2833
+ }, function (refreshedModel) {
2834
+ throw session.merge(refreshedModel);
2835
+ });
2836
+ },
2837
+ flush: function () {
2838
+ var session = this, dirtyModels = get(this, 'dirtyModels'), shadows = get(this, 'shadows'), parent = this.parent;
2839
+ var dirty = get(this, 'dirtyModels');
2840
+ dirty.forEach(function (model) {
2841
+ parent.update(model);
2842
+ });
2843
+ var promise = parent.flush().then(function (models) {
2844
+ var res = models.map(function (model) {
2845
+ return session.merge(model);
2846
+ });
2847
+ return models;
2848
+ }, function (models) {
2849
+ var res = models.map(function (model) {
2850
+ return session.merge(model);
2851
+ });
2852
+ throw models;
2853
+ });
2854
+ dirtyModels.forEach(function (model) {
2855
+ this.shadows.add(model.copy());
2856
+ }, this);
2857
+ return promise;
2858
+ },
2859
+ reifyClientId: function (model) {
2860
+ return this.parent.reifyClientId(model);
2861
+ },
2862
+ getForId: function (type, id) {
2863
+ var adapter = get(this.parent, 'adapter');
2864
+ var clientId = adapter.getClientId(type, id);
2865
+ return this.models.getForClientId(clientId);
2866
+ },
2867
+ remoteCall: function (context, name) {
2868
+ var session = this;
2869
+ return this.parent.remoteCall.apply(this.parent, arguments).then(function (model) {
2870
+ return session.merge(model);
2871
+ }, function (model) {
2872
+ throw session.merge(model);
2873
+ });
2874
+ }
2875
+ });
2876
+ });
2877
+ require.define('/lib/session/merge.js', function (module, exports, __dirname, __filename) {
2878
+ var get = Ember.get, set = Ember.set;
2879
+ Ep.Session.reopen({
2880
+ merge: function (model, strategy) {
2881
+ var shadows = get(this, 'shadows'), newModels = get(this, 'newModels');
2882
+ this.reifyClientId(model);
2883
+ if (!strategy)
2884
+ strategy = get(this, 'mergeStrategy').create({ session: this });
2885
+ if (!get(model, 'hasErrors')) {
2886
+ var merged;
2887
+ this.suspendDirtyChecking(function () {
2888
+ merged = this.mergeModel(model, strategy);
2889
+ }, this);
2890
+ shadows.remove(model);
2891
+ newModels.remove(model);
2892
+ } else {
2893
+ this.suspendDirtyChecking(function () {
2894
+ merged = this.mergeErrors(model, strategy);
2895
+ }, this);
2896
+ shadows.add(model);
2897
+ }
2898
+ return merged;
2899
+ },
2900
+ mergeModel: function (model, strategy) {
2901
+ var dest = this.getModel(model);
2902
+ if (model === dest) {
2903
+ return model;
2904
+ }
2905
+ if (get(model, 'isPromise')) {
2906
+ return this.mergePromise(model, dest, strategy);
2907
+ }
2908
+ var promise;
2909
+ if (dest && get(dest, 'isPromise')) {
2910
+ promise = dest;
2911
+ dest = dest.content;
2912
+ }
2913
+ if (!dest) {
2914
+ dest = model.constructor.create();
2915
+ if (promise) {
2916
+ promise.resolve(dest);
2917
+ }
2918
+ }
2919
+ set(dest, 'id', get(model, 'id'));
2920
+ set(dest, 'clientId', get(model, 'clientId'));
2921
+ set(dest, 'isDeleted', get(model, 'isDeleted'));
2922
+ set(dest, 'errors', Ember.copy(get(model, 'errors')));
2923
+ this.adopt(dest);
2924
+ strategy.merge(model, dest);
2925
+ return dest;
2926
+ },
2927
+ mergePromise: function (promise, dest, strategy) {
2928
+ var content = get(promise, 'content');
2929
+ if (content) {
2930
+ return this.merge(content, strategy);
2931
+ }
2932
+ if (!dest) {
2933
+ dest = promise.lazyCopy();
2934
+ this.adopt(dest);
2935
+ }
2936
+ return dest;
2937
+ },
2938
+ mergeErrors: function (model, strategy) {
2939
+ var dest = this.getModel(model);
2940
+ if (!dest) {
2941
+ Ember.assert('Errors returned for non-existant model: ' + model.toString(), model instanceof Ep.LoadError);
2942
+ return model;
2943
+ }
2944
+ set(dest, 'errors', Ember.copy(get(model, 'errors')));
2945
+ return dest;
2946
+ }
2947
+ });
2948
+ });
2949
+ require.define('/lib/session/session.js', function (module, exports, __dirname, __filename) {
2950
+ require('/lib/collections/model_array.js', module);
2951
+ require('/lib/collections/model_set.js', module);
2952
+ require('/lib/session/collection_manager.js', module);
2953
+ require('/lib/session/belongs_to_manager.js', module);
2954
+ require('/lib/model/index.js', module);
2955
+ require('/lib/session/merge_strategies/index.js', module);
2956
+ var get = Ember.get, set = Ember.set;
2957
+ Ep.Session = Ember.Object.extend({
2958
+ mergeStrategy: Ep.PerField,
2959
+ _dirtyCheckingSuspended: false,
2960
+ init: function () {
2961
+ this._super.apply(this, arguments);
2962
+ this.models = Ep.ModelSet.create();
2963
+ this.collectionManager = Ep.CollectionManager.create();
2964
+ this.belongsToManager = Ep.BelongsToManager.create();
2965
+ this.shadows = Ep.ModelSet.create();
2966
+ this.newModels = Ep.ModelSet.create();
2967
+ },
2968
+ create: function (type, hash) {
2969
+ if (typeof type === 'string') {
2970
+ type = this.lookupType(type);
2971
+ }
2972
+ var model = type.create(hash);
2973
+ model = this.add(model);
2974
+ model._registerRelationships();
2975
+ return model;
2976
+ },
2977
+ adopt: function (model) {
2978
+ Ember.assert('Models instances cannot be moved between sessions. Use `add` or `update` instead.', !get(model, 'session') || get(model, 'session') === this);
2979
+ set(model, 'session', this);
2980
+ if (get(model, 'isNew')) {
2981
+ this.newModels.add(model);
2982
+ }
2983
+ this.models.add(model);
2984
+ model._registerRelationships();
2985
+ return model;
2986
+ },
2987
+ add: function (model, depth) {
2988
+ this.reifyClientId(model);
2989
+ var dest = this.getModel(model);
2990
+ if (dest && get(dest, 'isLoaded'))
2991
+ return dest;
2992
+ if (typeof depth === 'undefined') {
2993
+ depth = 2;
2994
+ }
2995
+ depth--;
2996
+ if (get(model, 'isProxy')) {
2997
+ var content = get(model, 'content');
2998
+ if (content) {
2999
+ return this.add(content);
3000
+ }
3001
+ dest = model.lazyCopy();
3002
+ return this.adopt(dest);
3003
+ }
3004
+ if (get(model, 'isDetached')) {
3005
+ dest = model;
3006
+ } else {
3007
+ dest = model.constructor.create();
3008
+ model.copyAttributes(dest);
3009
+ }
3010
+ this.adopt(dest);
3011
+ model.eachRelationship(function (name, relationship) {
3012
+ if (relationship.kind === 'belongsTo') {
3013
+ var child = get(model, name);
3014
+ if (child) {
3015
+ if (get(child, 'session') === this) {
3016
+ model.belongsToDidChange(model, name);
3017
+ } else {
3018
+ if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3019
+ child = this.add(child, depth);
3020
+ } else {
3021
+ child = child.lazyCopy();
3022
+ }
3023
+ dest.suspendRelationshipObservers(function () {
3024
+ set(dest, name, child);
3025
+ });
3026
+ }
3027
+ }
3028
+ } else if (relationship.kind === 'hasMany') {
3029
+ var children = get(model, name);
3030
+ var copied = children.map(function (child) {
3031
+ if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3032
+ child = this.add(child, depth);
3033
+ } else {
3034
+ child = child.lazyCopy();
3035
+ }
3036
+ return child;
3037
+ }, this);
3038
+ set(dest, name, copied);
3039
+ }
3040
+ }, this);
3041
+ return dest;
3042
+ },
3043
+ update: function (model) {
3044
+ this.reifyClientId(model);
3045
+ if (get(model, 'isProxy')) {
3046
+ var content = get(model, 'content');
3047
+ if (content) {
3048
+ return this.update(content);
3049
+ }
3050
+ throw new Ember.Error('Cannot update with an unloaded model: ' + model.toString());
3051
+ }
3052
+ var dest = this.getModel(model);
3053
+ if (get(model, 'isDetached') || !dest || !get(dest, 'isLoaded')) {
3054
+ return this.add(model);
3055
+ }
3056
+ if (get(model, 'isDeleted')) {
3057
+ if (!get(dest, 'isDeleted')) {
3058
+ this.deleteModel(dest);
3059
+ }
3060
+ return dest;
3061
+ }
3062
+ model.copyAttributes(dest);
3063
+ model.eachRelationship(function (name, relationship) {
3064
+ if (relationship.kind === 'belongsTo') {
3065
+ var child = get(model, name);
3066
+ if (child) {
3067
+ set(dest, name, child);
3068
+ }
3069
+ } else if (relationship.kind === 'hasMany') {
3070
+ var children = get(model, name);
3071
+ var destChildren = get(dest, name);
3072
+ children.copyTo(destChildren);
3073
+ }
3074
+ }, this);
3075
+ return dest;
3076
+ },
3077
+ deleteModel: function (model) {
3078
+ if (get(model, 'isNew')) {
3079
+ var newModels = get(this, 'newModels');
3080
+ newModels.remove(model);
3081
+ } else {
3082
+ this.modelWillBecomeDirty(model);
3083
+ }
3084
+ set(model, 'isDeleted', true);
3085
+ this.collectionManager.modelWasDeleted(model);
3086
+ this.belongsToManager.modelWasDeleted(model);
3087
+ },
3088
+ load: function (type, id) {
3089
+ if (typeof type === 'string') {
3090
+ type = this.lookupType(type);
3091
+ }
3092
+ id = id.toString();
3093
+ var cached = this.getForId(type, id);
3094
+ if (cached && get(cached, 'isLoaded')) {
3095
+ return Ep.resolveModel(cached);
3096
+ }
3097
+ var session = this;
3098
+ return Ep.resolveModel(this.adapter.load(type, id).then(function (model) {
3099
+ return session.merge(model);
3100
+ }, function (model) {
3101
+ throw session.merge(model);
3102
+ }), type, id, session);
3103
+ },
3104
+ find: function (type, query) {
3105
+ if (Ember.typeOf(query) === 'object') {
3106
+ return this.query(type, query);
3107
+ }
3108
+ return this.load(type, query);
3109
+ },
3110
+ query: function (type, query) {
3111
+ if (typeof type === 'string') {
3112
+ type = this.lookupType(type);
3113
+ }
3114
+ var session = this;
3115
+ return this.adapter.query(type, query).then(function (models) {
3116
+ var merged = Ep.ModelArray.create({
3117
+ session: session,
3118
+ content: []
3119
+ });
3120
+ set(merged, 'meta', get(models, 'meta'));
3121
+ models.forEach(function (model) {
3122
+ merged.addObject(session.merge(model));
3123
+ });
3124
+ return merged;
3125
+ });
3126
+ },
3127
+ refresh: function (model) {
3128
+ var session = this;
3129
+ return this.adapter.refresh(model).then(function (refreshedModel) {
3130
+ return session.merge(refreshedModel);
3131
+ }, function (refreshedModel) {
3132
+ throw session.merge(refreshedModel);
3133
+ });
3134
+ },
3135
+ flush: function () {
3136
+ var session = this, dirtyModels = get(this, 'dirtyModels'), shadows = get(this, 'shadows');
3137
+ var promise = this.adapter.flush(this).then(function (models) {
3138
+ var res = models.map(function (model) {
3139
+ return session.merge(model);
3140
+ });
3141
+ return res;
3142
+ }, function (models) {
3143
+ var res = models.map(function (model) {
3144
+ return session.merge(model);
3145
+ });
3146
+ throw res;
3147
+ });
3148
+ dirtyModels.forEach(function (model) {
3149
+ this.shadows.add(model.copy());
3150
+ }, this);
3151
+ return promise;
3152
+ },
3153
+ getModel: function (model) {
3154
+ return this.models.getModel(model);
3155
+ },
3156
+ getForId: function (type, id) {
3157
+ var clientId = this.adapter.getClientId(type, id);
3158
+ return this.models.getForClientId(clientId);
3159
+ },
3160
+ reifyClientId: function (model) {
3161
+ this.adapter.reifyClientId(model);
3162
+ },
3163
+ remoteCall: function (context, name) {
3164
+ var session = this;
3165
+ return this.adapter.remoteCall.apply(this.adapter, arguments).then(function (model) {
3166
+ return session.merge(model);
3167
+ }, function (model) {
3168
+ throw session.merge(model);
3169
+ });
3170
+ },
3171
+ modelWillBecomeDirty: function (model) {
3172
+ if (this._dirtyCheckingSuspended || get(model, 'isNew')) {
3173
+ return;
3174
+ }
3175
+ var shadow = this.shadows.getModel(model);
3176
+ if (!shadow) {
3177
+ shadow = model.copy();
3178
+ this.shadows.addObject(shadow);
3179
+ }
3180
+ },
3181
+ destroy: function () {
3182
+ this._super();
3183
+ this.models.forEach(function (model) {
3184
+ model.destroy();
3185
+ });
3186
+ this.models.destroy();
3187
+ this.collectionManager.destroy();
3188
+ this.belongsToManager.destroy();
3189
+ this.shadows.destroy();
3190
+ this.newModels.destroy();
3191
+ },
3192
+ dirtyModels: Ember.computed(function () {
3193
+ var models = Ep.ModelSet.fromArray(this.shadows.map(function (model) {
3194
+ return this.models.getModel(model);
3195
+ }, this));
3196
+ get(this, 'newModels').forEach(function (model) {
3197
+ models.add(model);
3198
+ });
3199
+ return models;
3200
+ }).volatile(),
3201
+ suspendDirtyChecking: function (callback, binding) {
3202
+ var self = this;
3203
+ if (this._dirtyCheckingSuspended) {
3204
+ return callback.call(binding || self);
3205
+ }
3206
+ try {
3207
+ this._dirtyCheckingSuspended = true;
3208
+ return callback.call(binding || self);
3209
+ } finally {
3210
+ this._dirtyCheckingSuspended = false;
3211
+ }
3212
+ },
3213
+ newSession: function () {
3214
+ var child = this.container.lookup('session:child');
3215
+ set(child, 'parent', this);
3216
+ return child;
3217
+ },
3218
+ lookupType: function (type) {
3219
+ return this.container.lookup('model:' + type);
3220
+ },
3221
+ getShadow: function (model) {
3222
+ var shadows = get(this, 'shadows');
3223
+ var models = get(this, 'models');
3224
+ return shadows.getModel(model) || models.getModel(model);
3225
+ }
3226
+ });
3227
+ });
3228
+ require.define('/lib/session/merge_strategies/index.js', function (module, exports, __dirname, __filename) {
3229
+ require('/lib/session/merge_strategies/merge_strategy.js', module);
3230
+ require('/lib/session/merge_strategies/theirs.js', module);
3231
+ require('/lib/session/merge_strategies/per_field.js', module);
3232
+ });
3233
+ require.define('/lib/session/merge_strategies/per_field.js', function (module, exports, __dirname, __filename) {
3234
+ var get = Ember.get, set = Ember.set, isEqual = Ember.isEqual;
3235
+ function mergeIfPresent(session, model, strategy) {
3236
+ if (!model)
3237
+ return null;
3238
+ return session.merge(model, strategy);
3239
+ }
3240
+ Ep.PerField = Ep.MergeStrategy.extend({
3241
+ init: function () {
3242
+ this.cache = Ep.ModelSet.create();
3243
+ },
3244
+ merge: function (theirs, ours) {
3245
+ if (this.cache.contains(ours))
3246
+ return ours;
3247
+ this.cache.addObject(theirs);
3248
+ ours.beginPropertyChanges();
3249
+ var session = get(this, 'session');
3250
+ var original = session.getShadow(ours);
3251
+ this.mergeAttributes(theirs, ours, original);
3252
+ this.mergeRelationships(theirs, ours, original);
3253
+ ours.endPropertyChanges();
3254
+ return ours;
3255
+ },
3256
+ mergeAttributes: function (theirs, ours, original) {
3257
+ ours.eachAttribute(function (name, meta) {
3258
+ var oursValue = get(ours, name);
3259
+ var theirsValue = get(theirs, name);
3260
+ var originalValue = get(original, name);
3261
+ if (oursValue === theirsValue)
3262
+ return;
3263
+ if (oursValue === originalValue) {
3264
+ set(ours, name, theirsValue);
3265
+ }
3266
+ });
3267
+ },
3268
+ mergeRelationships: function (theirs, ours, original) {
3269
+ var session = get(this, 'session');
3270
+ ours.eachRelationship(function (name, relationship) {
3271
+ if (relationship.kind === 'belongsTo') {
3272
+ var oursValue = get(ours, name);
3273
+ var theirsValue = get(theirs, name);
3274
+ var originalValue = get(original, name);
3275
+ var merged = mergeIfPresent(session, theirsValue, this);
3276
+ if (isEqual(oursValue, originalValue)) {
3277
+ set(ours, name, merged);
3278
+ }
3279
+ } else if (relationship.kind === 'hasMany') {
3280
+ var theirChildren = get(theirs, name);
3281
+ var ourChildren = get(ours, name);
3282
+ var originalChildren = get(original, name);
3283
+ if (isEqual(ourChildren, originalChildren)) {
3284
+ var existing = Ep.ModelSet.create();
3285
+ existing.addObjects(ourChildren);
3286
+ theirChildren.forEach(function (model) {
3287
+ if (existing.contains(model)) {
3288
+ session.merge(model, this);
3289
+ existing.remove(model);
3290
+ } else {
3291
+ ourChildren.addObject(session.merge(model, this));
3292
+ }
3293
+ }, this);
3294
+ ourChildren.removeObjects(existing);
3295
+ } else {
3296
+ theirChildren.forEach(function (model) {
3297
+ session.merge(model, this);
3298
+ }, this);
3299
+ }
3300
+ }
3301
+ }, this);
3302
+ }
3303
+ });
3304
+ });
3305
+ require.define('/lib/session/merge_strategies/theirs.js', function (module, exports, __dirname, __filename) {
3306
+ var get = Ember.get, set = Ember.set;
3307
+ Ep.Theirs = Ep.MergeStrategy.extend({
3308
+ init: function () {
3309
+ this.cache = Ep.ModelSet.create();
3310
+ },
3311
+ merge: function (model, dest) {
3312
+ if (this.cache.contains(model))
3313
+ return dest;
3314
+ this.cache.addObject(model);
3315
+ dest.beginPropertyChanges();
3316
+ this.copyAttributes(model, dest);
3317
+ this.copyRelationships(model, dest);
3318
+ dest.endPropertyChanges();
3319
+ return dest;
3320
+ },
3321
+ copyAttributes: function (model, dest) {
3322
+ model.eachAttribute(function (name, meta) {
3323
+ var left = get(model, name);
3324
+ var right = get(dest, name);
3325
+ if (left !== right)
3326
+ set(dest, name, left);
3327
+ });
3328
+ },
3329
+ copyRelationships: function (model, dest) {
3330
+ var session = get(this, 'session');
3331
+ model.eachRelationship(function (name, relationship) {
3332
+ if (relationship.kind === 'belongsTo') {
3333
+ var child = get(model, name);
3334
+ var destChild = get(dest, name);
3335
+ if (child && destChild) {
3336
+ session.merge(child, this);
3337
+ } else if (child) {
3338
+ set(dest, name, session.merge(child, this));
3339
+ } else if (destChild) {
3340
+ set(dest, name, null);
3341
+ }
3342
+ } else if (relationship.kind === 'hasMany') {
3343
+ var children = get(model, name);
3344
+ var destChildren = get(dest, name);
3345
+ var modelSet = Ep.ModelSet.create();
3346
+ modelSet.addObjects(destChildren);
3347
+ set(destChildren, 'meta', get(children, 'meta'));
3348
+ children.forEach(function (child) {
3349
+ if (modelSet.contains(child)) {
3350
+ session.merge(child, this);
3351
+ modelSet.remove(child);
3352
+ } else {
3353
+ destChildren.addObject(session.merge(child, this));
3354
+ }
3355
+ }, this);
3356
+ destChildren.removeObjects(modelSet);
3357
+ }
3358
+ }, this);
3359
+ }
3360
+ });
3361
+ });
3362
+ require.define('/lib/session/merge_strategies/merge_strategy.js', function (module, exports, __dirname, __filename) {
3363
+ var get = Ember.get, set = Ember.set;
3364
+ function mustImplement(name) {
3365
+ return function () {
3366
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
3367
+ };
3368
+ }
3369
+ Ep.MergeStrategy = Ember.Object.extend({
3370
+ session: null,
3371
+ merge: mustImplement('merge')
3372
+ });
3373
+ });
3374
+ require.define('/lib/session/belongs_to_manager.js', function (module, exports, __dirname, __filename) {
3375
+ var get = Ember.get, set = Ember.set;
3376
+ Ep.BelongsToManager = Ember.Object.extend({
3377
+ init: function () {
3378
+ this.modelMap = Ember.MapWithDefault.create({
3379
+ defaultValue: function () {
3380
+ return Ember.A([]);
3381
+ }
3382
+ });
3383
+ },
3384
+ register: function (parent, key, model) {
3385
+ var paths = this.modelMap.get(get(model, 'clientId'));
3386
+ var path = paths.find(function (p) {
3387
+ return p.parent.isEqual(parent) && p.key === key;
3388
+ });
3389
+ if (path)
3390
+ return;
3391
+ path = {
3392
+ parent: parent,
3393
+ key: key
3394
+ };
3395
+ paths.pushObject(path);
3396
+ },
3397
+ unregister: function (parent, key, model) {
3398
+ var paths = this.modelMap.get(get(model, 'clientId'));
3399
+ var path = paths.find(function (p) {
3400
+ return p.parent.isEqual(parent) && p.key === key;
3401
+ });
3402
+ paths.removeObject(path);
3403
+ if (paths.length === 0) {
3404
+ this.modelMap.remove(get(model, 'clientId'));
3405
+ }
3406
+ },
3407
+ modelWasDeleted: function (model) {
3408
+ var paths = this.modelMap.get(get(model, 'clientId')).copy();
3409
+ paths.forEach(function (path) {
3410
+ set(path.parent, path.key, null);
3411
+ });
3412
+ }
3413
+ });
3414
+ });
3415
+ require.define('/lib/session/collection_manager.js', function (module, exports, __dirname, __filename) {
3416
+ var get = Ember.get, set = Ember.set;
3417
+ Ep.CollectionManager = Ember.Object.extend({
3418
+ init: function () {
3419
+ this.modelMap = Ember.MapWithDefault.create({
3420
+ defaultValue: function () {
3421
+ return Ember.A([]);
3422
+ }
3423
+ });
3424
+ },
3425
+ register: function (array, model) {
3426
+ var arrays = this.modelMap.get(get(model, 'clientId'));
3427
+ if (arrays.contains(array))
3428
+ return;
3429
+ arrays.pushObject(array);
3430
+ },
3431
+ unregister: function (array, model) {
3432
+ var arrays = this.modelMap.get(get(model, 'clientId'));
3433
+ arrays.removeObject(array);
3434
+ if (arrays.length === 0) {
3435
+ this.modelMap.remove(get(model, 'clientId'));
3436
+ }
3437
+ },
3438
+ modelWasDeleted: function (model) {
3439
+ var arrays = this.modelMap.get(get(model, 'clientId')).copy();
3440
+ arrays.forEach(function (array) {
3441
+ array.removeObject(model);
3442
+ });
3443
+ }
3444
+ });
3445
+ });
3446
+ require.define('/lib/initializer.js', function (module, exports, __dirname, __filename) {
3447
+ var set = Ember.set;
3448
+ Ember.onLoad('Ember.Application', function (Application) {
3449
+ Application.initializer({
3450
+ name: 'epf',
3451
+ initialize: function (container, application) {
3452
+ Ep.__container__ = container;
3453
+ application.register('store:main', application.Store || Ep.Store);
3454
+ application.register('adapter:main', application.Adapter || Ep.RestAdapter);
3455
+ application.register('session:base', application.Session || Ep.Session, { singleton: false });
3456
+ application.register('session:child', application.ChildSession || Ep.ChildSession, { singleton: false });
3457
+ application.register('session:main', application.DefaultSession || Ep.Session);
3458
+ application.register('serializer:main', application.Serializer || Ep.RestSerializer);
3459
+ application.inject('adapter', 'serializer', 'serializer:main');
3460
+ application.inject('session', 'adapter', 'adapter:main');
3461
+ container.optionsForType('model', { instantiate: false });
3462
+ application.inject('controller', 'adapter', 'adapter:main');
3463
+ application.inject('controller', 'session', 'session:main');
3464
+ application.inject('route', 'adapter', 'adapter:main');
3465
+ application.inject('route', 'session', 'session:main');
3466
+ }
3467
+ });
3468
+ });
3469
+ });
3470
+ global.epf = require('/lib/index.js');
3471
+ }.call(this, this));
3472
+ /*
3473
+ //@ sourceMappingURL=eps.js.map
3474
+ */