epf-source 0.1.3 → 0.1.4

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 +1053 -1083
  2. data/dist/epf.js.map +1 -1
  3. metadata +2 -2
@@ -34,7 +34,7 @@
34
34
  var cwd = '/';
35
35
  return {
36
36
  title: 'browser',
37
- version: 'v0.10.13',
37
+ version: 'v0.10.17',
38
38
  browser: true,
39
39
  env: {},
40
40
  argv: [],
@@ -50,11 +50,15 @@
50
50
  };
51
51
  }();
52
52
  require.define('/lib/index.js', function (module, exports, __dirname, __filename) {
53
+ require('/vendor/ember-inflector.js', module);
54
+ Ember.Inflector.loadAll();
53
55
  global.Ep = Ember.Namespace.create();
56
+ require('/lib/version.js', module);
54
57
  require('/lib/initializer.js', module);
55
58
  require('/lib/model/index.js', module);
56
59
  require('/lib/session/index.js', module);
57
60
  require('/lib/serializer/index.js', module);
61
+ require('/lib/transforms/index.js', module);
58
62
  require('/lib/local/index.js', module);
59
63
  require('/lib/rest/index.js', module);
60
64
  });
@@ -66,18 +70,35 @@
66
70
  require('/lib/serializer/index.js', module);
67
71
  var get = Ember.get;
68
72
  Ep.RestSerializer = Ep.JsonSerializer.extend({
69
- keyForAttributeName: function (type, name) {
70
- return Ember.String.decamelize(name);
73
+ metaKey: 'meta',
74
+ deserializePayload: function (hash, context) {
75
+ var result = [], metaKey = get(this, 'metaKey');
76
+ for (var prop in hash) {
77
+ if (!hash.hasOwnProperty(prop) || prop === metaKey) {
78
+ continue;
79
+ }
80
+ var type = this.typeFor(prop);
81
+ Ember.assert('Your server returned a hash with the key ' + prop + ' but has no corresponding type.', !!type);
82
+ var value = hash[prop];
83
+ if (value instanceof Array) {
84
+ for (var i = 0; i < value.length; i++) {
85
+ result.push(this.deserialize(type, value[i]));
86
+ }
87
+ } else {
88
+ result.push(this.deserialize(type, value));
89
+ }
90
+ }
91
+ return result;
71
92
  },
72
- keyForBelongsTo: function (type, name) {
73
- var key = this.keyForAttributeName(type, name);
93
+ keyForBelongsTo: function (name, type) {
94
+ var key = this._super(name, type);
74
95
  if (this.embeddedType(type, name)) {
75
96
  return key;
76
97
  }
77
98
  return key + '_id';
78
99
  },
79
- keyForHasMany: function (type, name) {
80
- var key = this.keyForAttributeName(type, name);
100
+ keyForHasMany: function (name, type) {
101
+ var key = this._super(name, type);
81
102
  if (this.embeddedType(type, name)) {
82
103
  return key;
83
104
  }
@@ -92,7 +113,7 @@
92
113
  extractValidationErrors: function (type, json) {
93
114
  var errors = {};
94
115
  get(type, 'attributes').forEach(function (name) {
95
- var key = this._keyForAttributeName(type, name);
116
+ var key = this.keyFor(name, type);
96
117
  if (json['errors'].hasOwnProperty(key)) {
97
118
  errors[name] = json['errors'][key];
98
119
  }
@@ -103,366 +124,23 @@
103
124
  });
104
125
  require.define('/lib/serializer/index.js', function (module, exports, __dirname, __filename) {
105
126
  require('/lib/serializer/serializer.js', module);
106
- require('/lib/serializer/json_serializer.js', module);
107
- });
108
- require.define('/lib/serializer/json_serializer.js', function (module, exports, __dirname, __filename) {
109
- require('/lib/serializer/serializer.js', module);
110
- require('/lib/transforms/json_transforms.js', module);
111
- var get = Ember.get, set = Ember.set;
112
- Ep.JsonSerializer = Ep.Serializer.extend({
113
- init: function () {
114
- this._super.apply(this, arguments);
115
- if (!get(this, 'transforms')) {
116
- this.set('transforms', Ep.JsonTransforms);
117
- }
118
- this.sideloadMapping = Ember.Map.create();
119
- this.metadataMapping = Ember.Map.create();
120
- this.configure({
121
- meta: 'meta',
122
- since: 'since'
123
- });
124
- },
125
- configure: function (type, configuration) {
126
- var key;
127
- if (type && !configuration) {
128
- for (key in type) {
129
- this.metadataMapping.set(get(type, key), key);
130
- }
131
- return this._super(type);
132
- }
133
- var sideloadAs = configuration.sideloadAs, sideloadMapping;
134
- if (sideloadAs) {
135
- sideloadMapping = this.aliases.sideloadMapping || Ember.Map.create();
136
- sideloadMapping.set(sideloadAs, type);
137
- this.aliases.sideloadMapping = sideloadMapping;
138
- delete configuration.sideloadAs;
139
- }
140
- this._super.apply(this, arguments);
141
- },
142
- addId: function (data, key, id) {
143
- data[key] = id;
144
- },
145
- addAttribute: function (hash, key, value) {
146
- hash[key] = value;
147
- },
148
- extractAttribute: function (type, hash, attributeName) {
149
- var key = this._keyForAttributeName(type, attributeName);
150
- return hash[key];
151
- },
152
- extractId: function (type, hash) {
153
- var primaryKey = this._primaryKey(type);
154
- if (hash.hasOwnProperty(primaryKey)) {
155
- return hash[primaryKey] + '';
156
- } else {
157
- return null;
158
- }
159
- },
160
- extractClientId: function (type, hash) {
161
- var clientKey = this._clientKey(type);
162
- if (hash.hasOwnProperty(clientKey) && hash[clientKey] !== null) {
163
- return hash[clientKey] + '';
164
- } else {
165
- return null;
166
- }
167
- },
168
- extractRevision: function (type, hash) {
169
- var revision = this._revision(type);
170
- if (hash.hasOwnProperty(revision) && hash[revision] !== null) {
171
- return parseInt(hash[revision]);
172
- } else {
173
- return undefined;
174
- }
175
- },
176
- extractClientRevision: function (type, hash) {
177
- var revision = this._clientRevision(type);
178
- if (hash.hasOwnProperty(revision) && hash[revision] !== null) {
179
- return parseInt(hash[revision]);
180
- } else {
181
- return undefined;
182
- }
183
- },
184
- extractHasMany: function (type, hash, key) {
185
- return hash[key];
186
- },
187
- extractBelongsTo: function (type, hash, key) {
188
- return hash[key];
189
- },
190
- extractBelongsToPolymorphic: function (type, hash, key) {
191
- var keyForId = this.keyForPolymorphicId(key), keyForType, id = hash[keyForId];
192
- if (id) {
193
- keyForType = this.keyForPolymorphicType(key);
194
- return {
195
- id: id,
196
- type: hash[keyForType]
197
- };
198
- }
199
- return null;
200
- },
201
- addBelongsTo: function (hash, record, key, relationship) {
202
- var type = record.constructor, name = relationship.key, value = null, includeType = relationship.options && relationship.options.polymorphic, embeddedChild, child, id;
203
- if (this.embeddedType(type, name)) {
204
- if (embeddedChild = get(record, name)) {
205
- value = this.serialize(embeddedChild, {
206
- includeId: true,
207
- includeType: includeType
208
- });
209
- }
210
- hash[key] = value;
211
- } else {
212
- child = get(record, relationship.key);
213
- id = get(child, 'id');
214
- if (relationship.options && relationship.options.polymorphic && !Ember.isNone(id)) {
215
- type = get(child, 'type');
216
- this.addBelongsToPolymorphic(hash, key, id, type);
217
- } else {
218
- hash[key] = id === undefined ? null : this.serializeId(id);
219
- }
220
- }
221
- },
222
- addBelongsToPolymorphic: function (hash, key, id, type) {
223
- var keyForId = this.keyForPolymorphicId(key), keyForType = this.keyForPolymorphicType(key);
224
- hash[keyForId] = id;
225
- hash[keyForType] = this.rootForType(type);
226
- },
227
- addHasMany: function (hash, record, key, relationship) {
228
- var type = record.constructor, name = relationship.key, serializedHasMany = [], includeType = relationship.options && relationship.options.polymorphic, manyArray, embeddedType;
229
- embeddedType = this.embeddedType(type, name);
230
- if (embeddedType !== 'always') {
231
- return;
232
- }
233
- manyArray = get(record, name);
234
- manyArray.forEach(function (record) {
235
- serializedHasMany.push(this.serialize(record, {
236
- includeId: true,
237
- includeType: includeType
238
- }));
239
- }, this);
240
- hash[key] = serializedHasMany;
241
- },
242
- addType: function (hash, type) {
243
- var keyForType = this.keyForEmbeddedType();
244
- hash[keyForType] = this.rootForType(type);
245
- },
246
- deserialize: function (data) {
247
- var result = [];
248
- for (var prop in data) {
249
- if (!data.hasOwnProperty(prop) || !!this.metadataMapping.get(prop)) {
250
- continue;
251
- }
252
- var type = this.typeFromAlias(prop);
253
- Ember.assert('Your server returned a hash with the key ' + prop + ' but you have no mapping for it', !!type);
254
- var value = data[prop];
255
- if (value instanceof Array) {
256
- for (var i = 0; i < value.length; i++) {
257
- result.push(this.deserializeModel(type, value[i]));
258
- }
259
- } else {
260
- result.push(this.deserializeModel(type, value));
261
- }
262
- }
263
- return result;
264
- },
265
- extractMeta: function (type, json) {
266
- var meta = this.configOption(type, 'meta'), data = json, value;
267
- if (meta && json[meta]) {
268
- data = json[meta];
269
- }
270
- var result = {};
271
- this.metadataMapping.forEach(function (property, key) {
272
- if (value = data[property]) {
273
- result[key] = value;
274
- }
275
- });
276
- return result;
277
- },
278
- extractEmbeddedType: function (relationship, data) {
279
- var foundType = relationship.type;
280
- if (relationship.options && relationship.options.polymorphic) {
281
- var key = this.keyFor(relationship), keyForEmbeddedType = this.keyForEmbeddedType(key);
282
- foundType = this.typeFromAlias(data[keyForEmbeddedType]);
283
- delete data[keyForEmbeddedType];
284
- }
285
- return foundType;
286
- },
287
- configureSideloadMappingForType: function (type, configured) {
288
- if (!configured) {
289
- configured = Ember.A([]);
290
- }
291
- configured.pushObject(type);
292
- type.eachRelatedType(function (relatedType) {
293
- if (!configured.contains(relatedType)) {
294
- var root = this.defaultSideloadRootForType(relatedType);
295
- this.aliases.set(root, relatedType);
296
- this.configureSideloadMappingForType(relatedType, configured);
297
- }
298
- }, this);
299
- },
300
- keyForPolymorphicId: Ember.K,
301
- keyForPolymorphicType: Ember.K,
302
- keyForEmbeddedType: function () {
303
- return 'type';
304
- },
305
- rootForType: function (type) {
306
- var typeString = type.toString();
307
- Ember.assert('Your model must not be anonymous. It was ' + type, typeString.charAt(0) !== '(');
308
- var parts = typeString.split('.');
309
- var name = parts[parts.length - 1];
310
- return name.replace(/([A-Z])/g, '_$1').toLowerCase().slice(1);
311
- },
312
- defaultSideloadRootForType: function (type) {
313
- return this.pluralize(this.rootForType(type));
314
- }
315
- });
316
- });
317
- require.define('/lib/transforms/json_transforms.js', function (module, exports, __dirname, __filename) {
318
- var none = Ember.isNone, empty = Ember.isEmpty;
319
- require('/lib/ext/date.js', module);
320
- Ep.JsonTransforms = {
321
- string: {
322
- deserialize: function (serialized) {
323
- return none(serialized) ? null : String(serialized);
324
- },
325
- serialize: function (deserialized) {
326
- return none(deserialized) ? null : String(deserialized);
327
- }
328
- },
329
- number: {
330
- deserialize: function (serialized) {
331
- return empty(serialized) ? null : Number(serialized);
332
- },
333
- serialize: function (deserialized) {
334
- return empty(deserialized) ? null : Number(deserialized);
335
- }
336
- },
337
- 'boolean': {
338
- deserialize: function (serialized) {
339
- var type = typeof serialized;
340
- if (type === 'boolean') {
341
- return serialized;
342
- } else if (type === 'string') {
343
- return serialized.match(/^true$|^t$|^1$/i) !== null;
344
- } else if (type === 'number') {
345
- return serialized === 1;
346
- } else {
347
- return false;
348
- }
349
- },
350
- serialize: function (deserialized) {
351
- return Boolean(deserialized);
352
- }
353
- },
354
- date: {
355
- deserialize: function (serialized) {
356
- var type = typeof serialized;
357
- if (type === 'string') {
358
- return new Date(Ember.Date.parse(serialized));
359
- } else if (type === 'number') {
360
- return new Date(serialized);
361
- } else if (serialized === null || serialized === undefined) {
362
- return serialized;
363
- } else {
364
- return null;
365
- }
366
- },
367
- serialize: function (date) {
368
- if (date instanceof Date) {
369
- var days = [
370
- 'Sun',
371
- 'Mon',
372
- 'Tue',
373
- 'Wed',
374
- 'Thu',
375
- 'Fri',
376
- 'Sat'
377
- ];
378
- var months = [
379
- 'Jan',
380
- 'Feb',
381
- 'Mar',
382
- 'Apr',
383
- 'May',
384
- 'Jun',
385
- 'Jul',
386
- 'Aug',
387
- 'Sep',
388
- 'Oct',
389
- 'Nov',
390
- 'Dec'
391
- ];
392
- var pad = function (num) {
393
- return num < 10 ? '0' + num : '' + num;
394
- };
395
- var utcYear = date.getUTCFullYear(), utcMonth = date.getUTCMonth(), utcDayOfMonth = date.getUTCDate(), utcDay = date.getUTCDay(), utcHours = date.getUTCHours(), utcMinutes = date.getUTCMinutes(), utcSeconds = date.getUTCSeconds();
396
- var dayOfWeek = days[utcDay];
397
- var dayOfMonth = pad(utcDayOfMonth);
398
- var month = months[utcMonth];
399
- return dayOfWeek + ', ' + dayOfMonth + ' ' + month + ' ' + utcYear + ' ' + pad(utcHours) + ':' + pad(utcMinutes) + ':' + pad(utcSeconds) + ' GMT';
400
- } else {
401
- return null;
402
- }
403
- }
404
- }
405
- };
127
+ require('/lib/serializer/json_serializer/index.js', module);
406
128
  });
407
- require.define('/lib/ext/date.js', function (module, exports, __dirname, __filename) {
408
- Ember.Date = Ember.Date || {};
409
- var origParse = Date.parse, numericKeys = [
410
- 1,
411
- 4,
412
- 5,
413
- 6,
414
- 7,
415
- 10,
416
- 11
417
- ];
418
- Ember.Date.parse = function (date) {
419
- var timestamp, struct, minutesOffset = 0;
420
- 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)) {
421
- for (var i = 0, k; k = numericKeys[i]; ++i) {
422
- struct[k] = +struct[k] || 0;
423
- }
424
- struct[2] = (+struct[2] || 1) - 1;
425
- struct[3] = +struct[3] || 1;
426
- if (struct[8] !== 'Z' && struct[9] !== undefined) {
427
- minutesOffset = struct[10] * 60 + struct[11];
428
- if (struct[9] === '+') {
429
- minutesOffset = 0 - minutesOffset;
430
- }
431
- }
432
- timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
433
- } else {
434
- timestamp = origParse ? origParse(date) : NaN;
435
- }
436
- return timestamp;
437
- };
438
- if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
439
- Date.parse = Ember.Date.parse;
440
- }
129
+ require.define('/lib/serializer/json_serializer/index.js', function (module, exports, __dirname, __filename) {
130
+ require('/lib/serializer/json_serializer/embedded_helpers_mixin.js', module);
131
+ require('/lib/serializer/json_serializer/json_serializer.js', module);
132
+ require('/lib/serializer/json_serializer/serialize.js', module);
133
+ require('/lib/serializer/json_serializer/deserialize.js', module);
441
134
  });
442
- require.define('/lib/serializer/serializer.js', function (module, exports, __dirname, __filename) {
443
- require('/lib/model/index.js', module);
444
- var get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map, isNone = Ember.isNone;
445
- function mustImplement(name) {
446
- return function () {
447
- throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
135
+ require.define('/lib/serializer/json_serializer/deserialize.js', function (module, exports, __dirname, __filename) {
136
+ var get = Ember.get, set = Ember.set;
137
+ function extractPropertyHook(name) {
138
+ return function (type, hash) {
139
+ return this.extractProperty(type, hash, name);
448
140
  };
449
141
  }
450
- Ep.Serializer = Ember.Object.extend({
451
- init: function () {
452
- this.mappings = Ember.Map.create();
453
- this.aliases = Ember.Map.create();
454
- this.configurations = Ember.Map.create();
455
- this.globalConfigurations = {};
456
- },
457
- deserialize: mustImplement('deserialize'),
458
- extractId: mustImplement('extractId'),
459
- extractClientId: mustImplement('extractClientId'),
460
- extractRevision: mustImplement('extractRevision'),
461
- extractClientRevision: mustImplement('extractClientRevision'),
462
- extractAttribute: mustImplement('extractAttribute'),
463
- extractHasMany: mustImplement('extractHasMany'),
464
- extractBelongsTo: mustImplement('extractBelongsTo'),
465
- deserializeModel: function (type, hash) {
142
+ Ep.JsonSerializer.reopen({
143
+ deserialize: function (type, hash) {
466
144
  var model = this.createModel(type);
467
145
  set(model, 'id', this.extractId(type, hash));
468
146
  set(model, 'clientId', this.extractClientId(type, hash));
@@ -475,19 +153,34 @@
475
153
  createModel: function (type) {
476
154
  return type.create();
477
155
  },
478
- deserializeValue: function (value, attributeType) {
479
- var transform = this.transforms ? this.transforms[attributeType] : null;
480
- Ember.assert('You tried to use a attribute type (' + attributeType + ') that has not been registered', transform);
481
- return transform.deserialize(value);
156
+ extractProperty: function (type, hash, name) {
157
+ var key = this.keyFor(name, type);
158
+ return hash[key];
159
+ },
160
+ extractId: function (type, hash) {
161
+ var key = this.keyFor('id', type);
162
+ if (hash.hasOwnProperty(key)) {
163
+ return hash[key] + '';
164
+ } else {
165
+ return null;
166
+ }
482
167
  },
483
- deserializeAttributes: function (model, data) {
168
+ extractClientId: extractPropertyHook('clientId'),
169
+ extractRevision: extractPropertyHook('rev'),
170
+ extractClientRevision: extractPropertyHook('clientRev'),
171
+ deserializeAttributes: function (model, hash) {
484
172
  model.eachAttribute(function (name, attribute) {
485
- set(model, name, this.deserializeAttribute(model, data, name, attribute.type));
173
+ set(model, name, this.extractAttribute(model, hash, name, attribute));
486
174
  }, this);
487
175
  },
488
- deserializeAttribute: function (record, data, attributeName, attributeType) {
489
- var value = this.extractAttribute(record.constructor, data, attributeName);
490
- return this.deserializeValue(value, attributeType);
176
+ extractAttribute: function (model, hash, name, attribute) {
177
+ var key = this.keyFor(name, get(model, 'type'));
178
+ return this.deserializeValue(hash[key], attribute.type);
179
+ },
180
+ deserializeValue: function (value, attributeType) {
181
+ var transform = this.transformFor(attributeType);
182
+ Ember.assert('You tried to use a attribute type (' + attributeType + ') that has not been registered', transform);
183
+ return transform.deserialize(value);
491
184
  },
492
185
  deserializeRelationships: function (model, hash) {
493
186
  model.eachRelationship(function (name, relationship) {
@@ -499,7 +192,7 @@
499
192
  }, this);
500
193
  },
501
194
  deserializeHasMany: function (name, model, data, relationship) {
502
- var type = get(model, 'type'), key = this._keyForHasMany(type, relationship.key), embeddedType = this.embeddedType(type, name), value = this.extractHasMany(type, data, key);
195
+ var type = get(model, 'type'), key = this.keyForHasMany(name, type), embeddedType = this.embeddedType(type, name), value = this.extractHasMany(type, data, key);
503
196
  if (embeddedType) {
504
197
  this.deserializeEmbeddedHasMany(name, model, value, relationship);
505
198
  } else {
@@ -507,16 +200,19 @@
507
200
  }
508
201
  },
509
202
  deserializeEmbeddedHasMany: function (name, model, values, relationship) {
510
- get(model, name).addObjects(values.map(function (data) {
203
+ if (!values) {
204
+ return;
205
+ }
206
+ get(model, name).pushObjects(values.map(function (data) {
511
207
  var type = this.extractEmbeddedType(relationship, data);
512
- return this.deserializeModel(type, data);
208
+ return this.deserialize(type, data);
513
209
  }, this));
514
210
  },
515
211
  deserializeLazyHasMany: function (name, model, values, relationship) {
516
212
  if (!values) {
517
213
  return;
518
214
  }
519
- get(model, name).addObjects(values.map(function (value) {
215
+ get(model, name).pushObjects(values.map(function (value) {
520
216
  return Ep.LazyModel.create({
521
217
  id: value && value.toString(),
522
218
  type: relationship.type
@@ -524,7 +220,7 @@
524
220
  }, this));
525
221
  },
526
222
  deserializeBelongsTo: function (name, model, hash, relationship) {
527
- var type = get(model, 'type'), key = this._keyForBelongsTo(type, relationship.key), embeddedType = this.embeddedType(type, name), value;
223
+ var type = get(model, 'type'), key = this.keyForBelongsTo(name, type), embeddedType = this.embeddedType(type, name), value;
528
224
  if (embeddedType) {
529
225
  if (relationship.options && relationship.options.polymorphic) {
530
226
  value = this.extractBelongsToPolymorphic(type, hash, key);
@@ -542,7 +238,7 @@
542
238
  return;
543
239
  }
544
240
  var type = this.extractEmbeddedType(relationship, value);
545
- var child = this.deserializeModel(type, value);
241
+ var child = this.deserialize(type, value);
546
242
  set(model, name, child);
547
243
  },
548
244
  deserializeLazyBelongsTo: function (name, model, value, relationship) {
@@ -555,67 +251,52 @@
555
251
  }));
556
252
  },
557
253
  extractEmbeddedType: function (relationship, data) {
558
- return relationship.type;
559
- },
560
- _convertPrematerializedHasMany: function (type, prematerializedHasMany) {
561
- var tuplesOrReferencesOrOpaque;
562
- if (typeof prematerializedHasMany === 'string') {
563
- tuplesOrReferencesOrOpaque = prematerializedHasMany;
564
- } else {
565
- tuplesOrReferencesOrOpaque = this._convertTuples(type, prematerializedHasMany);
254
+ var foundType = relationship.type;
255
+ if (relationship.options && relationship.options.polymorphic) {
256
+ var key = this.keyForRelationship(relationship), keyForEmbeddedType = this.keyForEmbeddedType(key);
257
+ foundType = this.typeFromAlias(data[keyForEmbeddedType]);
258
+ delete data[keyForEmbeddedType];
566
259
  }
567
- return tuplesOrReferencesOrOpaque;
568
- },
569
- _convertTuples: function (type, idsOrTuples) {
570
- return map.call(idsOrTuples, function (idOrTuple) {
571
- return this._convertTuple(type, idOrTuple);
572
- }, this);
260
+ return foundType;
573
261
  },
574
- _convertTuple: function (type, idOrTuple) {
575
- var foundType;
576
- if (typeof idOrTuple === 'object') {
577
- if (Ep.Model.detect(idOrTuple.type)) {
578
- return idOrTuple;
579
- } else {
580
- foundType = this.typeFromAlias(idOrTuple.type);
581
- Ember.assert('Unable to resolve type ' + idOrTuple.type + '. You may need to configure your serializer aliases.', !!foundType);
582
- return {
583
- id: idOrTuple.id,
584
- type: foundType
585
- };
586
- }
262
+ extractHasMany: Ember.aliasMethod('extractProperty'),
263
+ extractBelongsTo: Ember.aliasMethod('extractProperty')
264
+ });
265
+ });
266
+ require.define('/lib/serializer/json_serializer/serialize.js', function (module, exports, __dirname, __filename) {
267
+ var get = Ember.get, set = Ember.set;
268
+ function addPropertyHook(name) {
269
+ return function (serialized, model) {
270
+ return this.addProperty(serialized, name, model);
271
+ };
272
+ }
273
+ Ep.JsonSerializer.reopen({
274
+ serialize: function (model, options) {
275
+ var serialized = {}, id, rev, clientRev;
276
+ if (id = get(model, 'id')) {
277
+ this.addId(serialized, model);
587
278
  }
588
- return {
589
- id: idOrTuple,
590
- type: type
591
- };
592
- },
593
- serialize: function (record, options) {
594
- options = options || {};
595
- var serialized = this.createSerializedForm(), id, rev, clientRev;
596
- if (options.includeId) {
597
- if (id = get(record, 'id')) {
598
- this._addId(serialized, record.constructor, id);
599
- }
600
- this._addClientId(serialized, record.constructor, get(record, 'clientId'));
601
- if (rev = get(record, 'rev')) {
602
- this._addRevision(serialized, record.constructor, get(record, 'rev'));
603
- }
604
- if (clientRev = get(record, 'clientRev')) {
605
- this._addClientRevision(serialized, record.constructor, get(record, 'clientRev'));
606
- }
279
+ this.addClientId(serialized, model);
280
+ if (rev = get(model, 'rev')) {
281
+ this.addRevision(serialized, model);
282
+ }
283
+ if (clientRev = get(model, 'clientRev')) {
284
+ this.addClientRevision(serialized, model);
607
285
  }
608
- if (options.includeType) {
609
- this.addType(serialized, record.constructor);
286
+ if (options && options.includeType) {
287
+ this.addType(serialized, model);
610
288
  }
611
- this.addAttributes(serialized, record);
612
- this.addRelationships(serialized, record);
289
+ this.addAttributes(serialized, model);
290
+ this.addRelationships(serialized, model);
613
291
  return serialized;
614
292
  },
615
- serializeValue: function (value, attributeType) {
616
- var transform = this.transforms ? this.transforms[attributeType] : null;
617
- Ember.assert('You tried to use an attribute type (' + attributeType + ') that has not been registered', transform);
618
- return transform.serialize(value);
293
+ addProperty: function (serialized, name, model) {
294
+ var key = this.keyFor(name);
295
+ serialized[key] = get(model, name);
296
+ },
297
+ addId: function (serialized, model) {
298
+ var key = this.keyFor('id');
299
+ serialized[key] = this.serializeId(get(model, 'id'));
619
300
  },
620
301
  serializeId: function (id) {
621
302
  if (isNaN(id)) {
@@ -623,337 +304,175 @@
623
304
  }
624
305
  return +id;
625
306
  },
626
- serializeClientId: function (clientId) {
627
- return clientId;
628
- },
629
- serializeRevision: function (rev) {
630
- return rev;
631
- },
632
- serializeClientRevision: function (rev) {
633
- return rev;
634
- },
635
- addAttributes: function (data, record) {
636
- record.eachAttribute(function (name, attribute) {
637
- this._addAttribute(data, record, name, attribute.type);
307
+ addClientId: addPropertyHook('clientId'),
308
+ addRevision: addPropertyHook('rev'),
309
+ addClientRevision: addPropertyHook('clientRev'),
310
+ addType: addPropertyHook('type'),
311
+ addAttributes: function (serialized, model) {
312
+ model.eachAttribute(function (name, attribute) {
313
+ this.addAttribute(serialized, name, model, attribute);
638
314
  }, this);
639
315
  },
640
- addAttribute: mustImplement('addAttribute'),
641
- addId: mustImplement('addId'),
642
- addType: Ember.K,
643
- createSerializedForm: function () {
644
- return {};
316
+ addAttribute: function (serialized, name, model, attribute) {
317
+ var key = this.keyFor(name);
318
+ serialized[key] = this.serializeValue(get(model, name), attribute.type);
319
+ },
320
+ serializeValue: function (value, attributeType) {
321
+ var transform = this.transformFor(attributeType);
322
+ Ember.assert('You tried to use an attribute type (' + attributeType + ') that has not been registered', transform);
323
+ return transform.serialize(value);
645
324
  },
646
- addRelationships: function (data, record) {
647
- record.eachRelationship(function (name, relationship) {
325
+ addRelationships: function (serialized, model) {
326
+ model.eachRelationship(function (name, relationship) {
648
327
  if (relationship.kind === 'belongsTo') {
649
- this._addBelongsTo(data, record, name, relationship);
328
+ this.addBelongsTo(serialized, model, name, relationship);
650
329
  } else if (relationship.kind === 'hasMany') {
651
- this._addHasMany(data, record, name, relationship);
330
+ this.addHasMany(serialized, model, name, relationship);
652
331
  }
653
332
  }, this);
654
333
  },
655
- addBelongsTo: mustImplement('addBelongsTo'),
656
- addHasMany: mustImplement('addHasMany'),
657
- keyForAttributeName: function (type, name) {
658
- return name;
659
- },
660
- primaryKey: function (type) {
661
- return 'id';
662
- },
663
- clientKey: function (type) {
664
- return 'client_id';
665
- },
666
- revision: function (type) {
667
- return 'rev';
668
- },
669
- clientRevision: function (type) {
670
- return 'client_rev';
671
- },
672
- keyForBelongsTo: function (type, name) {
673
- return this.keyForAttributeName(type, name);
674
- },
675
- keyForHasMany: function (type, name) {
676
- return this.keyForAttributeName(type, name);
677
- },
678
- _primaryKey: function (type) {
679
- var config = this.configurationForType(type), primaryKey = config && config.primaryKey;
680
- if (primaryKey) {
681
- return primaryKey;
682
- } else {
683
- return this.primaryKey(type);
684
- }
685
- },
686
- _clientKey: function (type) {
687
- var config = this.configurationForType(type), clientKey = config && config.clientKey;
688
- if (clientKey) {
689
- return clientKey;
690
- } else {
691
- return this.clientKey(type);
692
- }
693
- },
694
- _revision: function (type) {
695
- var config = this.configurationForType(type), revision = config && config.revision;
696
- if (revision) {
697
- return revision;
698
- } else {
699
- return this.revision(type);
700
- }
701
- },
702
- _clientRevision: function (type) {
703
- var config = this.configurationForType(type), clientRevision = config && config.clientRevision;
704
- if (clientRevision) {
705
- return clientRevision;
706
- } else {
707
- return this.clientRevision(type);
708
- }
709
- },
710
- _addAttribute: function (data, record, attributeName, attributeType) {
711
- var key = this._keyForAttributeName(record.constructor, attributeName);
712
- var value = get(record, attributeName);
713
- this.addAttribute(data, key, this.serializeValue(value, attributeType));
714
- },
715
- _addId: function (hash, type, id) {
716
- var primaryKey = this._primaryKey(type);
717
- this.addId(hash, primaryKey, this.serializeId(id));
718
- },
719
- _addClientId: function (hash, type, id) {
720
- var clientKey = this._clientKey(type);
721
- this.addId(hash, clientKey, this.serializeClientId(id));
722
- },
723
- _addRevision: function (hash, type, rev) {
724
- var revision = this._revision(type);
725
- this.addId(hash, revision, this.serializeRevision(rev));
726
- },
727
- _addClientRevision: function (hash, type, rev) {
728
- var revision = this._clientRevision(type);
729
- this.addId(hash, revision, this.serializeClientRevision(rev));
730
- },
731
- _keyForAttributeName: function (type, name) {
732
- return this._keyFromMappingOrHook('keyForAttributeName', type, name);
733
- },
734
- _keyForBelongsTo: function (type, name) {
735
- return this._keyFromMappingOrHook('keyForBelongsTo', type, name);
736
- },
737
- keyFor: function (description) {
738
- var type = description.parentType, name = description.key;
739
- switch (description.kind) {
740
- case 'belongsTo':
741
- return this._keyForBelongsTo(type, name);
742
- case 'hasMany':
743
- return this._keyForHasMany(type, name);
744
- }
745
- },
746
- _keyForHasMany: function (type, name) {
747
- return this._keyFromMappingOrHook('keyForHasMany', type, name);
748
- },
749
- _addBelongsTo: function (data, record, name, relationship) {
750
- var key = this._keyForBelongsTo(record.constructor, name);
751
- this.addBelongsTo(data, record, key, relationship);
752
- },
753
- _addHasMany: function (data, record, name, relationship) {
754
- var key = this._keyForHasMany(record.constructor, name);
755
- this.addHasMany(data, record, key, relationship);
756
- },
757
- _keyFromMappingOrHook: function (publicMethod, type, name) {
758
- var key = this.mappingOption(type, name, 'key');
759
- if (key) {
760
- return key;
334
+ addBelongsTo: function (serialized, model, name, relationship) {
335
+ var type = get(model, 'type'), key = this.keyForBelongsTo(name, type), value = null, includeType = relationship.options && relationship.options.polymorphic, embeddedChild, child, id;
336
+ if (this.embeddedType(type, name)) {
337
+ if (embeddedChild = get(model, name)) {
338
+ value = this.serialize(embeddedChild, { includeType: includeType });
339
+ }
340
+ serialized[key] = value;
761
341
  } else {
762
- return this[publicMethod](type, name);
342
+ child = get(model, relationship.key);
343
+ id = get(child, 'id');
344
+ if (relationship.options && relationship.options.polymorphic && !Ember.isNone(id)) {
345
+ throw 'Polymorphism is not quite ready';
346
+ } else {
347
+ serialized[key] = id === undefined ? null : this.serializeId(id);
348
+ }
763
349
  }
764
350
  },
765
- registerTransform: function (type, transform) {
766
- this.transforms[type] = transform;
767
- },
768
- registerEnumTransform: function (type, objects) {
769
- var transform = {
770
- deserialize: function (serialized) {
771
- return Ember.A(objects).objectAt(serialized);
772
- },
773
- serialize: function (deserialized) {
774
- return Ember.EnumerableUtils.indexOf(objects, deserialized);
775
- },
776
- values: objects
777
- };
778
- this.registerTransform(type, transform);
351
+ addBelongsToPolymorphic: function (hash, key, id, type) {
352
+ var keyForId = this.keyForPolymorphicId(key), keyForType = this.keyForPolymorphicType(key);
353
+ hash[keyForId] = id;
354
+ hash[keyForType] = this.rootForType(type);
779
355
  },
780
- map: function (type, mappings) {
781
- this.mappings.set(type, mappings);
356
+ rootForType: function (type) {
357
+ return get(type, 'typeKey');
782
358
  },
783
- configure: function (type, configuration) {
784
- if (type && !configuration) {
785
- Ember.merge(this.globalConfigurations, type);
359
+ addHasMany: function (serialized, model, name, relationship) {
360
+ var type = get(model, 'type'), key = this.keyForHasMany(name, type), serializedHasMany = [], includeType = relationship.options && relationship.options.polymorphic, manyArray, embeddedType;
361
+ embeddedType = this.embeddedType(type, name);
362
+ if (embeddedType !== 'always') {
786
363
  return;
787
364
  }
788
- var config, alias;
789
- if (configuration.alias) {
790
- alias = configuration.alias;
791
- this.aliases.set(alias, type);
792
- delete configuration.alias;
793
- }
794
- config = Ember.create(this.globalConfigurations);
795
- Ember.merge(config, configuration);
796
- this.configurations.set(type, config);
797
- },
798
- typeFromAlias: function (alias) {
799
- this._completeAliases();
800
- var singular = this.singularize(alias);
801
- return this.container.lookup('model:' + singular);
802
- },
803
- mappingForType: function (type) {
804
- this._reifyMappings();
805
- return this.mappings.get(type) || {};
806
- },
807
- configurationForType: function (type) {
808
- this._reifyConfigurations();
809
- return this.configurations.get(type) || this.globalConfigurations;
810
- },
811
- _completeAliases: function () {
812
- this._pluralizeAliases();
813
- this._reifyAliases();
365
+ manyArray = get(model, name);
366
+ manyArray.forEach(function (model) {
367
+ serializedHasMany.push(this.serialize(model, { includeType: includeType }));
368
+ }, this);
369
+ serialized[key] = serializedHasMany;
370
+ }
371
+ });
372
+ });
373
+ require.define('/lib/serializer/json_serializer/json_serializer.js', function (module, exports, __dirname, __filename) {
374
+ require('/lib/serializer/serializer.js', module);
375
+ var get = Ember.get, set = Ember.set;
376
+ Ep.JsonSerializer = Ep.Serializer.extend(Ep.EmbeddedHelpersMixin, {
377
+ mergedProperties: [
378
+ 'properties',
379
+ 'aliases'
380
+ ],
381
+ properties: {},
382
+ aliases: {},
383
+ _keyCache: null,
384
+ _nameCache: null,
385
+ init: function () {
386
+ this._super();
387
+ this._keyCache = {};
388
+ this._nameCache = {};
814
389
  },
815
- _pluralizeAliases: function () {
816
- if (this._didPluralizeAliases) {
817
- return;
390
+ nameFor: function (key) {
391
+ var name;
392
+ if (name = this._nameCache[key]) {
393
+ return name;
818
394
  }
819
- var aliases = this.aliases, sideloadMapping = this.aliases.sideloadMapping, plural, self = this;
820
- aliases.forEach(function (key, type) {
821
- plural = self.pluralize(key);
822
- Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(plural));
823
- aliases.set(plural, type);
824
- });
825
- if (sideloadMapping) {
826
- sideloadMapping.forEach(function (key, type) {
827
- Ember.assert('The \'' + key + '\' alias has already been defined', !aliases.get(key) || aliases.get(key) === type);
828
- aliases.set(key, type);
829
- });
830
- delete this.aliases.sideloadMapping;
395
+ var configs = get(this, 'properties');
396
+ for (var currentName in configs) {
397
+ var current = configs[name];
398
+ var keyName = current.key;
399
+ if (keyName && key === keyName) {
400
+ name = currentName;
401
+ }
831
402
  }
832
- this._didPluralizeAliases = true;
403
+ name = name || Ember.String.camelize(key);
404
+ this._nameCache[key] = name;
405
+ return name;
833
406
  },
834
- _reifyAliases: function () {
835
- if (this._didReifyAliases) {
836
- return;
837
- }
838
- var aliases = this.aliases, reifiedAliases = Ember.Map.create(), foundType;
839
- aliases.forEach(function (key, type) {
840
- if (typeof type === 'string') {
841
- foundType = Ember.get(Ember.lookup, type);
842
- Ember.assert('Could not find model at path ' + key, type);
843
- reifiedAliases.set(key, foundType);
844
- } else {
845
- reifiedAliases.set(key, type);
846
- }
847
- });
848
- this.aliases = reifiedAliases;
849
- this._didReifyAliases = true;
407
+ configFor: function (name) {
408
+ return this.properties[name] || {};
850
409
  },
851
- _reifyMappings: function () {
852
- if (this._didReifyMappings) {
853
- return;
410
+ keyFor: function (name, type) {
411
+ var key;
412
+ if (key = this._keyCache[name]) {
413
+ return key;
854
414
  }
855
- var mappings = this.mappings, reifiedMappings = Ember.Map.create();
856
- mappings.forEach(function (key, mapping) {
857
- if (typeof key === 'string') {
858
- var type = Ember.get(Ember.lookup, key);
859
- Ember.assert('Could not find model at path ' + key, type);
860
- reifiedMappings.set(type, mapping);
861
- } else {
862
- reifiedMappings.set(key, mapping);
863
- }
864
- });
865
- this.mappings = reifiedMappings;
866
- this._didReifyMappings = true;
415
+ var config = this.configFor(name);
416
+ key = config.key || Ember.String.underscore(name);
417
+ this._keyCache[name] = key;
418
+ return key;
867
419
  },
868
- _reifyConfigurations: function () {
869
- if (this._didReifyConfigurations) {
870
- return;
420
+ keyForBelongsTo: Ember.aliasMethod('keyFor'),
421
+ keyForHasMany: Ember.aliasMethod('keyFor'),
422
+ keyForRelationship: function (relationship) {
423
+ var type = relationship.parentType, name = relationship.key;
424
+ switch (description.kind) {
425
+ case 'belongsTo':
426
+ return this.keyForBelongsTo(name, type);
427
+ case 'hasMany':
428
+ return this.keyForHasMany(name, type);
871
429
  }
872
- var configurations = this.configurations, reifiedConfigurations = Ember.Map.create();
873
- configurations.forEach(function (key, mapping) {
874
- if (typeof key === 'string' && key !== 'plurals') {
875
- var type = Ember.get(Ember.lookup, key);
876
- Ember.assert('Could not find model at path ' + key, type);
877
- reifiedConfigurations.set(type, mapping);
878
- } else {
879
- reifiedConfigurations.set(key, mapping);
880
- }
881
- });
882
- this.configurations = reifiedConfigurations;
883
- this._didReifyConfigurations = true;
884
- },
885
- mappingOption: function (type, name, option) {
886
- var mapping = this.mappingForType(type)[name];
887
- return mapping && mapping[option];
888
- },
889
- configOption: function (type, option) {
890
- var config = this.configurationForType(type);
891
- return config[option];
892
- },
893
- embeddedType: function (type, name) {
894
- return this.mappingOption(type, name, 'embedded');
895
- },
896
- eachEmbeddedRecord: function (record, callback, binding) {
897
- this.eachEmbeddedBelongsToRecord(record, callback, binding);
898
- this.eachEmbeddedHasManyRecord(record, callback, binding);
899
- },
900
- eachEmbeddedBelongsToRecord: function (record, callback, binding) {
901
- this.eachEmbeddedBelongsTo(record.constructor, function (name, relationship, embeddedType) {
902
- var embeddedRecord = get(record, name);
903
- if (embeddedRecord) {
904
- callback.call(binding, embeddedRecord, embeddedType);
905
- }
906
- });
907
- },
908
- eachEmbeddedHasManyRecord: function (record, callback, binding) {
909
- this.eachEmbeddedHasMany(record.constructor, function (name, relationship, embeddedType) {
910
- var array = get(record, name);
911
- for (var i = 0, l = get(array, 'length'); i < l; i++) {
912
- callback.call(binding, array.objectAt(i), embeddedType);
913
- }
914
- });
915
- },
916
- eachEmbeddedHasMany: function (type, callback, binding) {
917
- this.eachEmbeddedRelationship(type, 'hasMany', callback, binding);
918
430
  },
919
- eachEmbeddedBelongsTo: function (type, callback, binding) {
920
- this.eachEmbeddedRelationship(type, 'belongsTo', callback, binding);
431
+ keyForEmbeddedType: function () {
432
+ return 'type';
921
433
  },
922
- eachEmbeddedRelationship: function (type, kind, callback, binding) {
923
- type.eachRelationship(function (name, relationship) {
924
- var embeddedType = this.embeddedType(type, name);
925
- if (embeddedType) {
926
- if (relationship.kind === kind) {
927
- callback.call(binding, name, relationship, embeddedType);
928
- }
929
- }
930
- }, this);
434
+ transformFor: function (attributeType) {
435
+ return this.container.lookup('transform:' + attributeType);
931
436
  },
932
437
  pluralize: function (name) {
933
- var plurals = this.configurations.get('plurals');
934
- return plurals && plurals[name] || name + 's';
438
+ return Ember.String.pluralize(name);
935
439
  },
936
440
  singularize: function (name) {
937
- var plurals = this.configurations.get('plurals');
938
- if (plurals) {
939
- for (var i in plurals) {
940
- if (plurals[i] === name) {
941
- return i;
942
- }
943
- }
441
+ return Ember.String.singularize(name);
442
+ },
443
+ typeFor: function (name) {
444
+ var type;
445
+ if (type = this.container.lookup('model:' + name)) {
446
+ return type;
944
447
  }
945
- if (name.lastIndexOf('s') === name.length - 1) {
946
- return name.substring(0, name.length - 1);
947
- } else {
948
- return name;
448
+ var singular = this.singularize(name);
449
+ if (type = this.container.lookup('model:' + singular)) {
450
+ return type;
949
451
  }
452
+ var aliases = get(this, 'aliases');
453
+ var alias = aliases[name];
454
+ return alias && this.container.lookup('model:' + alias);
950
455
  }
951
456
  });
952
457
  });
458
+ require.define('/lib/serializer/serializer.js', function (module, exports, __dirname, __filename) {
459
+ require('/lib/model/index.js', module);
460
+ var get = Ember.get, set = Ember.set, map = Ember.ArrayPolyfills.map, isNone = Ember.isNone;
461
+ function mustImplement(name) {
462
+ return function () {
463
+ throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
464
+ };
465
+ }
466
+ Ep.Serializer = Ember.Object.extend({
467
+ deserialize: mustImplement('deserialize'),
468
+ serialize: mustImplement('serialize')
469
+ });
470
+ });
953
471
  require.define('/lib/model/index.js', function (module, exports, __dirname, __filename) {
954
472
  require('/lib/model/model.js', module);
955
473
  require('/lib/model/proxies.js', module);
956
474
  require('/lib/model/attribute.js', module);
475
+ require('/lib/model/debug.js', module);
957
476
  require('/lib/model/relationships/belongs_to.js', module);
958
477
  require('/lib/model/relationships/has_many.js', module);
959
478
  require('/lib/model/relationships/ext.js', module);
@@ -1018,14 +537,16 @@
1018
537
  Ember.assert('Must be attached to a session', !!session);
1019
538
  this.eachRelationship(function (name, relationship) {
1020
539
  if (relationship.kind === 'belongsTo') {
1021
- var model = get(this, name);
1022
- if (model) {
1023
- session.belongsToManager.register(model, name, this);
540
+ var child = get(this, name);
541
+ if (child) {
542
+ session.reifyClientId(child);
543
+ session.belongsToManager.register(this, name, child);
1024
544
  }
1025
545
  } else if (relationship.kind === 'hasMany') {
1026
546
  var children = get(this, name);
1027
- children.forEach(function (model) {
1028
- session.collectionManager.register(children, model);
547
+ children.forEach(function (child) {
548
+ session.reifyClientId(child);
549
+ session.collectionManager.register(children, child);
1029
550
  }, this);
1030
551
  }
1031
552
  }, this);
@@ -1085,7 +606,7 @@
1085
606
  this.eachComputedProperty(function (name, meta) {
1086
607
  if (meta.isRelationship) {
1087
608
  if (typeof meta.type === 'string') {
1088
- meta.type = Ep.__container__.lookup('model:' + type);
609
+ meta.type = Ep.__container__.lookup('model:' + meta.type);
1089
610
  }
1090
611
  var relationshipsForType = map.get(meta.type);
1091
612
  relationshipsForType.push({
@@ -1132,7 +653,7 @@
1132
653
  meta.key = name;
1133
654
  type = meta.type;
1134
655
  if (typeof type === 'string') {
1135
- type = Ep.__container__.lookup('model:' + type);
656
+ meta.type = Ep.__container__.lookup('model:' + type);
1136
657
  }
1137
658
  map.set(name, meta);
1138
659
  }
@@ -1164,7 +685,9 @@
1164
685
  Ep.Model.reopen({
1165
686
  eachRelationship: function (callback, binding) {
1166
687
  this.constructor.eachRelationship(callback, binding);
1167
- },
688
+ }
689
+ });
690
+ Ep.ModelMixin.reopen({
1168
691
  eachRelatedModel: function (callback, binding, cache) {
1169
692
  if (!cache)
1170
693
  cache = Ember.Set.create();
@@ -1187,6 +710,21 @@
1187
710
  }, this);
1188
711
  }
1189
712
  }, this);
713
+ },
714
+ eachChild: function (callback, binding) {
715
+ this.eachRelationship(function (name, relationship) {
716
+ if (relationship.kind === 'belongsTo') {
717
+ var child = get(this, name);
718
+ if (child) {
719
+ callback.call(binding, child);
720
+ }
721
+ } else if (relationship.kind === 'hasMany') {
722
+ var children = get(this, name);
723
+ children.forEach(function (child) {
724
+ callback.call(binding, child);
725
+ }, this);
726
+ }
727
+ }, this);
1190
728
  }
1191
729
  });
1192
730
  });
@@ -1223,7 +761,6 @@
1223
761
  return Ep.HasManyArray.create({
1224
762
  owner: this,
1225
763
  name: key,
1226
- session: session,
1227
764
  content: content
1228
765
  });
1229
766
  }).property().meta(meta);
@@ -1231,6 +768,7 @@
1231
768
  Ep.HasManyArray = Ep.ModelArray.extend({
1232
769
  name: null,
1233
770
  owner: null,
771
+ session: Ember.computed.alias('owner.session'),
1234
772
  replaceContent: function (idx, amt, objects) {
1235
773
  var session = get(this, 'session');
1236
774
  if (session) {
@@ -1240,8 +778,15 @@
1240
778
  }
1241
779
  this._super(idx, amt, objects);
1242
780
  },
781
+ objectAtContent: function (index) {
782
+ var content = get(this, 'content'), model = content.objectAt(index), session = get(this, 'session');
783
+ if (session && model) {
784
+ return session.add(model);
785
+ }
786
+ return model;
787
+ },
1243
788
  arrayContentWillChange: function (index, removed, added) {
1244
- var owner = get(this, 'owner'), name = get(this, 'name'), session = get(owner, 'session');
789
+ var owner = get(this, 'owner'), name = get(this, 'name'), session = get(this, 'session');
1245
790
  if (session) {
1246
791
  session.modelWillBecomeDirty(owner);
1247
792
  }
@@ -1262,7 +807,7 @@
1262
807
  session.belongsToManager.unregister(model, inverse.name, owner);
1263
808
  }
1264
809
  }
1265
- });
810
+ }, this);
1266
811
  }
1267
812
  }
1268
813
  }
@@ -1283,12 +828,12 @@
1283
828
  get(model, inverse.name).addObject(owner);
1284
829
  } else if (inverse.kind === 'belongsTo') {
1285
830
  set(model, inverse.name, owner);
1286
- var session = get(owner, 'session');
831
+ var session = get(this, 'session');
1287
832
  if (session) {
1288
833
  session.belongsToManager.register(model, inverse.name, owner);
1289
834
  }
1290
835
  }
1291
- });
836
+ }, this);
1292
837
  }
1293
838
  }
1294
839
  }
@@ -1303,8 +848,9 @@
1303
848
  arrayContentWillChange: function (index, removed, added) {
1304
849
  for (var i = index; i < index + removed; i++) {
1305
850
  var model = this.objectAt(i);
1306
- if (this.session) {
1307
- this.session.collectionManager.unregister(this, model);
851
+ var session = get(this, 'session');
852
+ if (session) {
853
+ session.collectionManager.unregister(this, model);
1308
854
  }
1309
855
  }
1310
856
  this._super.apply(this, arguments);
@@ -1313,8 +859,9 @@
1313
859
  this._super.apply(this, arguments);
1314
860
  for (var i = index; i < index + added; i++) {
1315
861
  var model = this.objectAt(i);
1316
- if (this.session) {
1317
- this.session.collectionManager.register(this, model);
862
+ var session = get(this, 'session');
863
+ if (session) {
864
+ session.collectionManager.register(this, model);
1318
865
  }
1319
866
  }
1320
867
  },
@@ -1342,7 +889,7 @@
1342
889
  if (existing.contains(model)) {
1343
890
  existing.remove(model);
1344
891
  } else {
1345
- dest.addObject(model);
892
+ dest.pushObject(model);
1346
893
  }
1347
894
  });
1348
895
  dest.removeObjects(existing);
@@ -1420,9 +967,11 @@
1420
967
  Ep.Model = Ember.Object.extend(Ember.Copyable, Ep.ModelMixin, {
1421
968
  isPromise: false,
1422
969
  isProxy: false,
1423
- isNew: true,
1424
970
  isDeleted: false,
1425
971
  isLoaded: true,
972
+ isNew: Ember.computed(function () {
973
+ return !get(this, 'id');
974
+ }).property('id'),
1426
975
  isDirty: Ember.computed(function () {
1427
976
  var session = get(this, 'session');
1428
977
  if (!session)
@@ -1496,6 +1045,7 @@
1496
1045
  var dest = this.constructor.create();
1497
1046
  dest.beginPropertyChanges();
1498
1047
  this.copyAttributes(dest);
1048
+ this.copyMeta(dest);
1499
1049
  this.eachRelationship(function (name, relationship) {
1500
1050
  if (relationship.kind === 'belongsTo') {
1501
1051
  var child = get(this, name);
@@ -1506,7 +1056,7 @@
1506
1056
  var children = get(this, name);
1507
1057
  var destChildren = get(dest, name);
1508
1058
  children.forEach(function (child) {
1509
- destChildren.addObject(child.lazyCopy());
1059
+ destChildren.pushObject(child.lazyCopy());
1510
1060
  });
1511
1061
  }
1512
1062
  }, this);
@@ -1515,19 +1065,20 @@
1515
1065
  },
1516
1066
  copyAttributes: function (dest) {
1517
1067
  dest.beginPropertyChanges();
1518
- set(dest, 'id', get(this, 'id'));
1519
- set(dest, 'clientId', get(this, 'clientId'));
1520
- set(dest, 'rev', get(this, 'rev'));
1521
- set(dest, 'clientRev', get(this, 'clientRev'));
1522
- set(dest, 'errors', Ember.copy(get(this, 'errors')));
1523
- set(dest, 'isNew', get(this, 'isNew'));
1524
- set(dest, 'isDeleted', get(this, 'isDeleted'));
1525
1068
  this.eachAttribute(function (name, meta) {
1526
1069
  var left = get(this, name);
1527
1070
  var right = get(dest, name);
1528
1071
  set(dest, name, left);
1529
1072
  }, this);
1530
1073
  dest.endPropertyChanges();
1074
+ },
1075
+ copyMeta: function (dest) {
1076
+ set(dest, 'id', get(this, 'id'));
1077
+ set(dest, 'clientId', get(this, 'clientId'));
1078
+ set(dest, 'rev', get(this, 'rev'));
1079
+ set(dest, 'clientRev', get(this, 'clientRev'));
1080
+ set(dest, 'errors', Ember.copy(get(this, 'errors')));
1081
+ set(dest, 'isDeleted', get(this, 'isDeleted'));
1531
1082
  }
1532
1083
  });
1533
1084
  Ep.Model.reopenClass({
@@ -1538,7 +1089,10 @@
1538
1089
  var container = Ep.__container__;
1539
1090
  var session = container.lookup('session:main');
1540
1091
  return session.find(this, id);
1541
- }
1092
+ },
1093
+ typeKey: Ember.computed(function () {
1094
+ return Ember.String.underscore(this.toString().split('.')[1]);
1095
+ })
1542
1096
  });
1543
1097
  });
1544
1098
  require.define('/lib/collections/model_set.js', function (module, exports, __dirname, __filename) {
@@ -1709,6 +1263,22 @@
1709
1263
  });
1710
1264
  require.define('/lib/model/relationships/belongs_to.js', function (module, exports, __dirname, __filename) {
1711
1265
  var get = Ember.get, set = Ember.set, isNone = Ember.isNone;
1266
+ function BelongsToDescriptor(func, opts) {
1267
+ Ember.ComputedProperty.apply(this, arguments);
1268
+ }
1269
+ BelongsToDescriptor.prototype = new Ember.ComputedProperty();
1270
+ BelongsToDescriptor.prototype.get = function (obj, keyName) {
1271
+ if (!get(obj, 'isDetached') && this._suspended !== obj) {
1272
+ var ret, cache, cached, meta, session, existing;
1273
+ meta = Ember.meta(obj);
1274
+ cache = meta.cache;
1275
+ session = get(obj, 'session');
1276
+ if ((cached = cache[keyName]) && (existing = session.fetch(cached)) && existing !== cached) {
1277
+ cache[keyName] = existing;
1278
+ }
1279
+ }
1280
+ return Ember.ComputedProperty.prototype.get.apply(this, arguments);
1281
+ };
1712
1282
  Ep.belongsTo = function (type, options) {
1713
1283
  Ember.assert('The type passed to Ep.belongsTo must be defined', !!type);
1714
1284
  options = options || {};
@@ -1718,7 +1288,7 @@
1718
1288
  options: options,
1719
1289
  kind: 'belongsTo'
1720
1290
  };
1721
- return Ember.computed(function (key, value) {
1291
+ return new BelongsToDescriptor(function (key, value) {
1722
1292
  if (arguments.length === 1) {
1723
1293
  return null;
1724
1294
  } else {
@@ -1728,9 +1298,17 @@
1728
1298
  }
1729
1299
  return value;
1730
1300
  }
1731
- }).property().meta(meta);
1301
+ }).meta(meta);
1732
1302
  };
1733
1303
  Ep.Model.reopen({
1304
+ init: function () {
1305
+ this._super();
1306
+ this.eachRelationship(function (name, relationship) {
1307
+ if (relationship.kind === 'belongsTo') {
1308
+ this.belongsToDidChange(this, name);
1309
+ }
1310
+ }, this);
1311
+ },
1734
1312
  belongsToWillChange: Ember.beforeObserver(function (model, key) {
1735
1313
  var oldParent = get(model, key);
1736
1314
  var session = get(model, 'session');
@@ -1780,6 +1358,58 @@
1780
1358
  })
1781
1359
  });
1782
1360
  });
1361
+ require.define('/lib/model/debug.js', function (module, exports, __dirname, __filename) {
1362
+ Ep.Model.reopen({
1363
+ _debugInfo: function () {
1364
+ var attributes = ['id'], relationships = {
1365
+ belongsTo: [],
1366
+ hasMany: []
1367
+ }, expensiveProperties = [];
1368
+ this.eachAttribute(function (name, meta) {
1369
+ attributes.push(name);
1370
+ }, this);
1371
+ this.eachRelationship(function (name, relationship) {
1372
+ relationships[relationship.kind].push(name);
1373
+ expensiveProperties.push(name);
1374
+ });
1375
+ var groups = [
1376
+ {
1377
+ name: 'Attributes',
1378
+ properties: attributes,
1379
+ expand: true
1380
+ },
1381
+ {
1382
+ name: 'Belongs To',
1383
+ properties: relationships.belongsTo,
1384
+ expand: true
1385
+ },
1386
+ {
1387
+ name: 'Has Many',
1388
+ properties: relationships.hasMany,
1389
+ expand: true
1390
+ },
1391
+ {
1392
+ name: 'Flags',
1393
+ properties: [
1394
+ 'isLoaded',
1395
+ 'isDirty',
1396
+ 'isDeleted',
1397
+ 'isNew',
1398
+ 'isPromise',
1399
+ 'isProxy'
1400
+ ]
1401
+ }
1402
+ ];
1403
+ return {
1404
+ propertyInfo: {
1405
+ includeOtherProperties: true,
1406
+ groups: groups,
1407
+ expensiveProperties: expensiveProperties
1408
+ }
1409
+ };
1410
+ }
1411
+ });
1412
+ });
1783
1413
  require.define('/lib/model/attribute.js', function (module, exports, __dirname, __filename) {
1784
1414
  var get = Ember.get, set = Ember.set;
1785
1415
  Ep.Model.reopenClass({
@@ -1881,12 +1511,16 @@
1881
1511
  return content.copy();
1882
1512
  }
1883
1513
  return this.lazyCopy();
1884
- }
1514
+ },
1515
+ diff: passThroughMethod('diff', []),
1516
+ suspendRelationshipObservers: passThroughMethod('suspendRelationshipObservers'),
1517
+ eachAttribute: passThroughMethod('eachAttribute'),
1518
+ eachRelationship: passThroughMethod('eachRelationship'),
1519
+ _registerRelationships: passThroughMethod('_registerRelationships')
1885
1520
  });
1886
1521
  Ep.LoadError = Ep.ModelProxy.extend({});
1887
1522
  Ep.ModelPromise = Ep.ModelProxy.extend(Ember.DeferredMixin, {
1888
1523
  isPromise: true,
1889
- isNew: false,
1890
1524
  resolve: function (model) {
1891
1525
  set(this, 'content', model);
1892
1526
  return this._super.apply(this, arguments);
@@ -1904,12 +1538,7 @@
1904
1538
  } else {
1905
1539
  return '(no identifiers)';
1906
1540
  }
1907
- },
1908
- diff: passThroughMethod('diff', []),
1909
- suspendRelationshipObservers: passThroughMethod('suspendRelationshipObservers'),
1910
- eachAttribute: passThroughMethod('eachAttribute'),
1911
- eachRelationship: passThroughMethod('eachRelationship'),
1912
- _registerRelationships: passThroughMethod('_registerRelationships')
1541
+ }
1913
1542
  });
1914
1543
  Ep.LazyModel = Ep.ModelPromise.extend({
1915
1544
  willWatchProperty: triggerLoad(true),
@@ -1976,16 +1605,70 @@
1976
1605
  throw err;
1977
1606
  });
1978
1607
  }
1979
- return promise;
1980
- };
1608
+ return promise;
1609
+ };
1610
+ });
1611
+ require.define('/lib/serializer/json_serializer/embedded_helpers_mixin.js', function (module, exports, __dirname, __filename) {
1612
+ var get = Ember.get, set = Ember.set;
1613
+ Ep.EmbeddedHelpersMixin = Ember.Mixin.create({
1614
+ serializerFor: function (type) {
1615
+ var key = get(type, 'typeKey');
1616
+ return this.container.lookup('serializer:' + key) || this.container.lookup('serializer:main');
1617
+ },
1618
+ embeddedType: function (type, name) {
1619
+ var serializer = this.serializerFor(type);
1620
+ if (this === serializer) {
1621
+ var config = this.configFor(name);
1622
+ return config.embedded;
1623
+ }
1624
+ return serializer.embeddedType(type, name);
1625
+ },
1626
+ eachEmbeddedRecord: function (record, callback, binding) {
1627
+ this.eachEmbeddedBelongsToRecord(record, callback, binding);
1628
+ this.eachEmbeddedHasManyRecord(record, callback, binding);
1629
+ },
1630
+ eachEmbeddedBelongsToRecord: function (record, callback, binding) {
1631
+ this.eachEmbeddedBelongsTo(record.constructor, function (name, relationship, embeddedType) {
1632
+ var embeddedRecord = get(record, name);
1633
+ if (embeddedRecord) {
1634
+ callback.call(binding, embeddedRecord, embeddedType);
1635
+ }
1636
+ });
1637
+ },
1638
+ eachEmbeddedHasManyRecord: function (record, callback, binding) {
1639
+ this.eachEmbeddedHasMany(record.constructor, function (name, relationship, embeddedType) {
1640
+ var array = get(record, name);
1641
+ for (var i = 0, l = get(array, 'length'); i < l; i++) {
1642
+ callback.call(binding, array.objectAt(i), embeddedType);
1643
+ }
1644
+ });
1645
+ },
1646
+ eachEmbeddedHasMany: function (type, callback, binding) {
1647
+ this.eachEmbeddedRelationship(type, 'hasMany', callback, binding);
1648
+ },
1649
+ eachEmbeddedBelongsTo: function (type, callback, binding) {
1650
+ this.eachEmbeddedRelationship(type, 'belongsTo', callback, binding);
1651
+ },
1652
+ eachEmbeddedRelationship: function (type, kind, callback, binding) {
1653
+ type.eachRelationship(function (name, relationship) {
1654
+ var embeddedType = this.embeddedType(type, name);
1655
+ if (embeddedType) {
1656
+ if (relationship.kind === kind) {
1657
+ callback.call(binding, name, relationship, embeddedType);
1658
+ }
1659
+ }
1660
+ }, this);
1661
+ }
1662
+ });
1981
1663
  });
1982
1664
  require.define('/lib/rest/rest_adapter.js', function (module, exports, __dirname, __filename) {
1983
1665
  require('/lib/adapter.js', module);
1984
1666
  require('/lib/rest/embedded_manager.js', module);
1985
1667
  require('/lib/rest/operation_graph.js', module);
1986
1668
  require('/lib/rest/rest_errors.js', module);
1669
+ require('/lib/serializer/json_serializer/embedded_helpers_mixin.js', module);
1987
1670
  var get = Ember.get, set = Ember.set;
1988
- Ep.RestAdapter = Ep.Adapter.extend({
1671
+ Ep.RestAdapter = Ep.Adapter.extend(Ep.EmbeddedHelpersMixin, {
1989
1672
  init: function () {
1990
1673
  this._super.apply(this, arguments);
1991
1674
  this._embeddedManager = Ep.EmbeddedManager.create({ adapter: this });
@@ -1994,65 +1677,55 @@
1994
1677
  load: function (type, id) {
1995
1678
  var root = this.rootForType(type), adapter = this;
1996
1679
  return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
1997
- return Ember.run(adapter, 'didReceiveDataForLoad', json, type, id);
1680
+ return adapter.didReceiveDataForLoad(json, type, id);
1998
1681
  }, function (xhr) {
1999
1682
  var model = Ep.LoadError.create({
2000
1683
  id: id,
2001
1684
  type: type
2002
1685
  });
2003
- throw Ember.run(adapter, 'didError', xhr, model);
1686
+ throw adapter.didError(xhr, model);
2004
1687
  });
2005
1688
  },
2006
1689
  refresh: function (model) {
2007
- var type = get(model, 'type');
2008
- var root = this.rootForType(type), adapter = this;
2009
- var id = get(model, 'id');
1690
+ var type = get(model, 'type'), root = this.rootForType(type), id = get(model, 'id'), adapter = this;
2010
1691
  return this.ajax(this.buildURL(root, id), 'GET').then(function (json) {
2011
- return Ember.run(adapter, 'didReceiveData', json, model);
1692
+ return adapter.didReceiveData(json, model);
2012
1693
  }, function (xhr) {
2013
- throw Ember.run(adapter, 'didError', xhr, model);
1694
+ throw adapter.didError(xhr, model);
2014
1695
  });
2015
1696
  },
2016
1697
  update: function (model) {
2017
- var id, root, adapter, data, type = get(model, 'type');
2018
- id = get(model, 'id');
2019
- root = this.rootForType(type);
2020
- adapter = this;
2021
- data = {};
2022
- data[root] = get(this, 'serializer').serialize(model);
1698
+ var type = get(model, 'type'), root = this.rootForType(type), id = get(model, 'id'), adapter = this, serializer = this.serializerFor(type);
1699
+ var data = {};
1700
+ data[root] = serializer.serialize(model);
2023
1701
  return this.ajax(this.buildURL(root, id), 'PUT', { data: data }).then(function (json) {
2024
- return Ember.run(adapter, 'didReceiveData', json, model);
1702
+ return adapter.didReceiveData(json, model);
2025
1703
  }, function (xhr) {
2026
- throw Ember.run(adapter, 'didError', xhr, model);
1704
+ throw adapter.didError(xhr, model);
2027
1705
  });
2028
1706
  },
2029
1707
  create: function (model) {
2030
- var type = get(model, 'type');
2031
- var root = this.rootForType(type);
2032
- var adapter = this;
1708
+ var type = get(model, 'type'), root = this.rootForType(type), adapter = this, serializer = this.serializerFor(type);
2033
1709
  var data = {};
2034
- data[root] = get(this, 'serializer').serialize(model, { includeId: true });
1710
+ data[root] = serializer.serialize(model, { includeId: true });
2035
1711
  return this.ajax(this.buildURL(root), 'POST', { data: data }).then(function (json) {
2036
- return Ember.run(adapter, 'didReceiveData', json, model);
1712
+ return adapter.didReceiveData(json, model);
2037
1713
  }, function (xhr) {
2038
- throw Ember.run(adapter, 'didError', xhr, model);
1714
+ throw adapter.didError(xhr, model);
2039
1715
  });
2040
1716
  },
2041
1717
  deleteModel: function (model) {
2042
- var id, root, adapter, type = get(model, 'type');
2043
- id = get(model, 'id');
2044
- root = this.rootForType(type);
2045
- adapter = this;
1718
+ var type = get(model, 'type'), root = this.rootForType(type), id = get(model, 'id'), adapter = this;
2046
1719
  return this.ajax(this.buildURL(root, id), 'DELETE').then(function (json) {
2047
- return Ember.run(adapter, 'didReceiveData', json, model);
1720
+ return adapter.didReceiveData(json, model);
2048
1721
  }, function (xhr) {
2049
- throw Ember.run(adapter, 'didError', xhr, model);
1722
+ throw adapter.didError(xhr, model);
2050
1723
  });
2051
1724
  },
2052
1725
  query: function (type, query) {
2053
1726
  var root = this.rootForType(type), adapter = this;
2054
1727
  return this.ajax(this.buildURL(root), 'GET', { data: query }).then(function (json) {
2055
- return Ember.run(adapter, 'didReceiveDataForFind', json, type);
1728
+ return adapter.didReceiveDataForFind(json, type);
2056
1729
  }, function (xhr) {
2057
1730
  throw xhr;
2058
1731
  });
@@ -2060,26 +1733,26 @@
2060
1733
  remoteCall: function (context, name, params) {
2061
1734
  var url, adapter = this;
2062
1735
  if (typeof context === 'string') {
2063
- context = this.lookupType(context);
1736
+ context = this.typeFor(context);
2064
1737
  }
2065
1738
  if (typeof context === 'function') {
2066
1739
  url = this.buildURL(this.rootForType(context));
2067
1740
  } else {
2068
1741
  var id = get(context, 'id');
2069
1742
  Ember.assert('Cannot perform a remote call with a context that doesn\'t have an id', id);
2070
- url = this.buildURL(this.rootForType(context.constructor), id);
1743
+ url = this.buildURL(this.rootForType(get(context, 'type')), id);
2071
1744
  }
2072
1745
  url = url + '/' + name;
2073
1746
  var data = params;
2074
1747
  var method = 'POST';
2075
1748
  return this.ajax(url, method, { data: data }).then(function (json) {
2076
- return Ember.run(adapter, 'didReceiveDataForRpc', json, context);
1749
+ return adapter.didReceiveDataForRpc(json, context);
2077
1750
  }, function (xhr) {
2078
- throw Ember.run(adapter, 'didError', xhr, context);
1751
+ throw adapter.didError(xhr, context);
2079
1752
  });
2080
1753
  },
2081
- lookupType: function (type) {
2082
- return this.container.lookup('model:' + type);
1754
+ typeFor: function (typeName) {
1755
+ return this.container.lookup('model:' + typeName);
2083
1756
  },
2084
1757
  didReceiveData: function (data, targetModel) {
2085
1758
  var result = null;
@@ -2112,7 +1785,7 @@
2112
1785
  return this.didReceiveData(data, context);
2113
1786
  },
2114
1787
  processData: function (data, callback, binding) {
2115
- var models = get(this, 'serializer').deserialize(data);
1788
+ var models = get(this, 'serializer').deserializePayload(data);
2116
1789
  models.forEach(function (model) {
2117
1790
  this.willLoadModel(model);
2118
1791
  }, this);
@@ -2221,7 +1894,8 @@
2221
1894
  },
2222
1895
  isRelationshipOwner: function (relationship) {
2223
1896
  var serializer = get(this, 'serializer');
2224
- var owner = serializer.mappingOption(relationship.parentType, relationship.key, 'owner');
1897
+ var config = this.configFor(relationship.parentType);
1898
+ var owner = config[relationship.key] && config[relationship.key].owner;
2225
1899
  return relationship.kind === 'belongsTo' && owner !== false || relationship.kind === 'hasMany' && owner === true;
2226
1900
  },
2227
1901
  isDirtyFromRelationships: function (model, cached, relDiff) {
@@ -2254,42 +1928,17 @@
2254
1928
  shadows.removeObjects(orphans);
2255
1929
  },
2256
1930
  dirtyEmbedded: function (models, shadows, session) {
2257
- this.dirtyEmbeddedParents(models, shadows, session);
2258
1931
  models.forEach(function (model) {
2259
- this.dirtyEmbeddedTree(model, models, shadows, session);
2260
- }, this);
2261
- },
2262
- dirtyEmbeddedParents: function (models, shadows, session) {
2263
- models.forEach(function (model) {
2264
- var parent;
2265
- while (parent = this._embeddedManager.findParent(model)) {
2266
- model = session.getModel(parent);
2267
- if (!models.contains(model)) {
2268
- var copy = model.copy();
2269
- models.add(copy);
2270
- shadows.add(copy);
1932
+ this.eachEmbeddedRelative(model, function (embeddedModel) {
1933
+ this._embeddedManager.updateParents(embeddedModel);
1934
+ if (models.contains(embeddedModel)) {
1935
+ return;
2271
1936
  }
2272
- }
2273
- this._embeddedManager.updateParents(model);
2274
- }, this);
2275
- },
2276
- dirtyEmbeddedTree: function (model, models, shadows, session) {
2277
- get(this, 'serializer').eachEmbeddedRecord(model, function (embeddedRecord, embeddedType) {
2278
- if (embeddedType !== 'always') {
2279
- return;
2280
- }
2281
- if (models.contains(embeddedRecord)) {
2282
- return;
2283
- }
2284
- embeddedRecord = session.getModel(embeddedRecord);
2285
- if (!embeddedRecord)
2286
- return;
2287
- if (!models.contains(embeddedRecord)) {
2288
- var copy = embeddedRecord.copy();
1937
+ embeddedModel = session.getModel(embeddedModel);
1938
+ var copy = embeddedModel.copy();
2289
1939
  models.add(copy);
2290
1940
  shadows.add(copy);
2291
- }
2292
- this.dirtyEmbeddedTree(embeddedRecord, models, shadows, session);
1941
+ }, this);
2293
1942
  }, this);
2294
1943
  },
2295
1944
  findEmbeddedRoot: function (model, models) {
@@ -2300,6 +1949,23 @@
2300
1949
  }
2301
1950
  return models.getModel(model);
2302
1951
  },
1952
+ eachEmbeddedRelative: function (model, callback, binding, visited) {
1953
+ if (!get(model, 'isLoaded'))
1954
+ return;
1955
+ if (!visited)
1956
+ visited = new Ember.Set();
1957
+ if (visited.contains(model))
1958
+ return;
1959
+ visited.add(model);
1960
+ callback.call(binding, model);
1961
+ get(this, 'serializer').eachEmbeddedRecord(model, function (embeddedRecord, embeddedType) {
1962
+ this.eachEmbeddedRelative(embeddedRecord, callback, binding, visited);
1963
+ }, this);
1964
+ var parent = this._embeddedManager.findParent(model);
1965
+ if (parent) {
1966
+ this.eachEmbeddedRelative(parent, callback, binding, visited);
1967
+ }
1968
+ },
2303
1969
  materializeRelationships: function (models) {
2304
1970
  if (!(models instanceof Ep.ModelSet)) {
2305
1971
  models = Ep.ModelSet.fromArray(models);
@@ -2326,24 +1992,40 @@
2326
1992
  }, this);
2327
1993
  },
2328
1994
  ajax: function (url, type, hash) {
2329
- try {
1995
+ var adapter = this;
1996
+ return new Ember.RSVP.Promise(function (resolve, reject) {
2330
1997
  hash = hash || {};
2331
1998
  hash.url = url;
2332
1999
  hash.type = type;
2333
2000
  hash.dataType = 'json';
2334
- hash.context = this;
2001
+ hash.context = adapter;
2335
2002
  if (hash.data && type !== 'GET') {
2336
2003
  hash.contentType = 'application/json; charset=utf-8';
2337
2004
  hash.data = JSON.stringify(hash.data);
2338
2005
  }
2339
- return Ember.RSVP.resolve(jQuery.ajax(hash));
2340
- } catch (error) {
2341
- return Ember.RSVP.resolve(error);
2342
- }
2006
+ if (adapter.headers !== undefined) {
2007
+ var headers = adapter.headers;
2008
+ hash.beforeSend = function (xhr) {
2009
+ forEach.call(Ember.keys(headers), function (key) {
2010
+ xhr.setRequestHeader(key, headers[key]);
2011
+ });
2012
+ };
2013
+ }
2014
+ hash.success = function (json) {
2015
+ Ember.run(null, resolve, json);
2016
+ };
2017
+ hash.error = function (jqXHR, textStatus, errorThrown) {
2018
+ if (jqXHR) {
2019
+ jqXHR.then = null;
2020
+ }
2021
+ Ember.run(null, reject, jqXHR);
2022
+ };
2023
+ Ember.$.ajax(hash);
2024
+ });
2343
2025
  },
2344
2026
  url: '',
2345
2027
  rootForType: function (type) {
2346
- var serializer = get(this, 'serializer');
2028
+ var serializer = this.serializerFor(type);
2347
2029
  return serializer.rootForType(type);
2348
2030
  },
2349
2031
  pluralize: function (string) {
@@ -2363,7 +2045,10 @@
2363
2045
  url.push(suffix);
2364
2046
  }
2365
2047
  return url.join('/');
2366
- }
2048
+ },
2049
+ serializer: Ember.computed(function () {
2050
+ return container.lookup('serializer:main');
2051
+ })
2367
2052
  });
2368
2053
  });
2369
2054
  require.define('/lib/rest/rest_errors.js', function (module, exports, __dirname, __filename) {
@@ -2407,6 +2092,7 @@
2407
2092
  },
2408
2093
  build: function () {
2409
2094
  var adapter = get(this, 'adapter');
2095
+ var serializer = get(adapter, 'serializer');
2410
2096
  var models = get(this, 'models');
2411
2097
  var shadows = get(this, 'shadows');
2412
2098
  var rootOps = get(this, 'rootOps');
@@ -2433,7 +2119,8 @@
2433
2119
  var d = rels[i];
2434
2120
  var name = d.name;
2435
2121
  var parentModel = model.get(name) || shadows.getModel(d.oldValue);
2436
- if (parentModel) {
2122
+ var isEmbeddedRel = serializer.embeddedType(get(model, 'type'), name);
2123
+ if (parentModel && !isEmbeddedRel) {
2437
2124
  var parentOp = this.getOp(parentModel);
2438
2125
  parentOp.addChild(op);
2439
2126
  }
@@ -2638,8 +2325,7 @@
2638
2325
  this._cachedIsEmbedded = Ember.Map.create();
2639
2326
  },
2640
2327
  updateParents: function (model) {
2641
- var serializer = get(this, 'adapter.serializer');
2642
- var parentType = get(model, 'type');
2328
+ var type = get(model, 'type'), adapter = get(this, 'adapter'), serializer = adapter.serializerFor(type);
2643
2329
  serializer.eachEmbeddedRecord(model, function (embedded, kind) {
2644
2330
  this._parentMap[get(embedded, 'clientId')] = model;
2645
2331
  }, this);
@@ -2649,19 +2335,17 @@
2649
2335
  return parent;
2650
2336
  },
2651
2337
  isEmbedded: function (model) {
2652
- var type = get(model, 'type');
2653
- var result = this._cachedIsEmbedded.get(type);
2654
- if (result === true || result === false)
2338
+ var type = get(model, 'type'), result = this._cachedIsEmbedded.get(type);
2339
+ if (result !== undefined)
2655
2340
  return result;
2656
- var adapter = get(this, 'adapter');
2657
- var mappings = get(adapter, 'serializer.mappings');
2658
- var result = false;
2659
- mappings.forEach(function (parentType, value) {
2660
- for (var name in value) {
2661
- var embedded = value[name]['embedded'];
2662
- result = result || embedded === 'always' && parentType.typeForRelationship(name).detect(type);
2663
- }
2664
- });
2341
+ var adapter = get(this, 'adapter'), result = false;
2342
+ type.eachRelationship(function (name, relationship) {
2343
+ var parentType = relationship.type, serializer = adapter.serializerFor(parentType), inverse = type.inverseFor(relationship.key);
2344
+ if (!inverse)
2345
+ return;
2346
+ var config = serializer.configFor(inverse.name);
2347
+ result = result || config.embedded === 'always';
2348
+ }, this);
2665
2349
  this._cachedIsEmbedded.set(type, result);
2666
2350
  return result;
2667
2351
  }
@@ -2669,34 +2353,35 @@
2669
2353
  });
2670
2354
  require.define('/lib/adapter.js', function (module, exports, __dirname, __filename) {
2671
2355
  var get = Ember.get, set = Ember.set, merge = Ember.merge;
2672
- require('/lib/mixins/mappable.js', module);
2673
2356
  function mustImplement(name) {
2674
2357
  return function () {
2675
2358
  throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
2676
2359
  };
2677
2360
  }
2678
2361
  var uuid = 1;
2679
- Ep.Adapter = Ember.Object.extend(Ep._Mappable, {
2362
+ Ep.Adapter = Ember.Object.extend({
2363
+ mergedProperties: ['configs'],
2680
2364
  init: function () {
2681
2365
  this._super.apply(this, arguments);
2366
+ this.configs = {};
2682
2367
  this.idMaps = Ember.MapWithDefault.create({
2683
2368
  defaultValue: function (type) {
2684
2369
  return Ember.Map.create();
2685
2370
  }
2686
2371
  });
2687
2372
  },
2373
+ configFor: function (type) {
2374
+ var configs = get(this, 'configs'), typeKey = get(type, 'typeKey');
2375
+ return configs[typeKey] || {};
2376
+ },
2688
2377
  newSession: function () {
2689
2378
  var session = this.container.lookup('session:base');
2690
2379
  set(session, 'adapter', this);
2691
2380
  return session;
2692
2381
  },
2693
- serializer: Ember.computed(function (key, serializer) {
2694
- this._attributesMap = this.createInstanceMapFor('attributes');
2695
- this._configurationsMap = this.createInstanceMapFor('configurations');
2696
- this.registerSerializerTransforms(this.constructor, serializer, {});
2697
- this.registerSerializerMappings(serializer);
2698
- return serializer;
2699
- }),
2382
+ serializerFor: function (type) {
2383
+ return this.container.lookup('serializer:' + type) || this.container.lookup('serializer:main');
2384
+ },
2700
2385
  load: mustImplement('load'),
2701
2386
  query: mustImplement('find'),
2702
2387
  refresh: mustImplement('refresh'),
@@ -2708,32 +2393,6 @@
2708
2393
  shouldSave: function (model) {
2709
2394
  return true;
2710
2395
  },
2711
- registerSerializerTransforms: function (klass, serializer, seen) {
2712
- var transforms = klass._registeredTransforms, superclass, prop;
2713
- var enumTransforms = klass._registeredEnumTransforms;
2714
- for (prop in transforms) {
2715
- if (!transforms.hasOwnProperty(prop) || prop in seen) {
2716
- continue;
2717
- }
2718
- seen[prop] = true;
2719
- serializer.registerTransform(prop, transforms[prop]);
2720
- }
2721
- for (prop in enumTransforms) {
2722
- if (!enumTransforms.hasOwnProperty(prop) || prop in seen) {
2723
- continue;
2724
- }
2725
- seen[prop] = true;
2726
- serializer.registerEnumTransform(prop, enumTransforms[prop]);
2727
- }
2728
- if (superclass = klass.superclass) {
2729
- this.registerSerializerTransforms(superclass, serializer, seen);
2730
- }
2731
- },
2732
- registerSerializerMappings: function (serializer) {
2733
- var mappings = this._attributesMap, configurations = this._configurationsMap;
2734
- mappings.forEach(serializer.map, serializer);
2735
- configurations.forEach(serializer.configure, serializer);
2736
- },
2737
2396
  reifyClientId: function (model) {
2738
2397
  var id = get(model, 'id'), clientId = get(model, 'clientId'), type = get(model, 'type'), idMap = this.idMaps.get(type);
2739
2398
  if (id && clientId) {
@@ -2759,109 +2418,9 @@
2759
2418
  return idMap.get(id);
2760
2419
  },
2761
2420
  _generateClientId: function (type) {
2762
- return this._typeToString(type) + uuid++;
2763
- },
2764
- _typeToString: function (type) {
2765
- return type.toString().split('.')[1].underscore();
2766
- }
2767
- });
2768
- Ep.Adapter.reopenClass({
2769
- registerTransform: function (attributeType, transform) {
2770
- var registeredTransforms = this._registeredTransforms || {};
2771
- registeredTransforms[attributeType] = transform;
2772
- this._registeredTransforms = registeredTransforms;
2773
- },
2774
- registerEnumTransform: function (attributeType, objects) {
2775
- var registeredEnumTransforms = this._registeredEnumTransforms || {};
2776
- registeredEnumTransforms[attributeType] = objects;
2777
- this._registeredEnumTransforms = registeredEnumTransforms;
2778
- },
2779
- map: Ep._Mappable.generateMapFunctionFor('attributes', function (key, newValue, map) {
2780
- var existingValue = map.get(key);
2781
- merge(existingValue, newValue);
2782
- }),
2783
- configure: Ep._Mappable.generateMapFunctionFor('configurations', function (key, newValue, map) {
2784
- var existingValue = map.get(key);
2785
- var mappings = newValue && newValue.mappings;
2786
- if (mappings) {
2787
- this.map(key, mappings);
2788
- delete newValue.mappings;
2789
- }
2790
- merge(existingValue, newValue);
2791
- }),
2792
- resolveMapConflict: function (oldValue, newValue) {
2793
- merge(newValue, oldValue);
2794
- return newValue;
2795
- }
2796
- });
2797
- });
2798
- require.define('/lib/mixins/mappable.js', function (module, exports, __dirname, __filename) {
2799
- var get = Ember.get;
2800
- var resolveMapConflict = function (oldValue, newValue) {
2801
- return oldValue;
2802
- };
2803
- var transformMapKey = function (key, value) {
2804
- return key;
2805
- };
2806
- var transformMapValue = function (key, value) {
2807
- return value;
2808
- };
2809
- Ep._Mappable = Ember.Mixin.create({
2810
- createInstanceMapFor: function (mapName) {
2811
- var instanceMeta = getMappableMeta(this);
2812
- instanceMeta.values = instanceMeta.values || {};
2813
- if (instanceMeta.values[mapName]) {
2814
- return instanceMeta.values[mapName];
2815
- }
2816
- var instanceMap = instanceMeta.values[mapName] = new Ember.Map();
2817
- var klass = this.constructor;
2818
- while (klass && klass !== Ep.Store) {
2819
- this._copyMap(mapName, klass, instanceMap);
2820
- klass = klass.superclass;
2821
- }
2822
- instanceMeta.values[mapName] = instanceMap;
2823
- return instanceMap;
2824
- },
2825
- _copyMap: function (mapName, klass, instanceMap) {
2826
- var classMeta = getMappableMeta(klass);
2827
- var classMap = classMeta[mapName];
2828
- if (classMap) {
2829
- classMap.forEach(eachMap, this);
2830
- }
2831
- function eachMap(key, value) {
2832
- var transformedKey = (klass.transformMapKey || transformMapKey)(key, value);
2833
- var transformedValue = (klass.transformMapValue || transformMapValue)(key, value);
2834
- var oldValue = instanceMap.get(transformedKey);
2835
- var newValue = transformedValue;
2836
- if (oldValue) {
2837
- newValue = (this.constructor.resolveMapConflict || resolveMapConflict)(oldValue, newValue);
2838
- }
2839
- instanceMap.set(transformedKey, newValue);
2840
- }
2421
+ return get(type, 'typeKey') + uuid++;
2841
2422
  }
2842
2423
  });
2843
- Ep._Mappable.generateMapFunctionFor = function (mapName, transform) {
2844
- return function (key, value) {
2845
- var meta = getMappableMeta(this);
2846
- var map = meta[mapName] || Ember.MapWithDefault.create({
2847
- defaultValue: function () {
2848
- return {};
2849
- }
2850
- });
2851
- transform.call(this, key, value, map);
2852
- meta[mapName] = map;
2853
- };
2854
- };
2855
- function getMappableMeta(obj) {
2856
- var meta = Ember.meta(obj, true), keyName = 'Ep.Mappable', value = meta[keyName];
2857
- if (!value) {
2858
- meta[keyName] = {};
2859
- }
2860
- if (!meta.hasOwnProperty(keyName)) {
2861
- meta[keyName] = Ember.create(meta[keyName]);
2862
- }
2863
- return meta[keyName];
2864
- }
2865
2424
  });
2866
2425
  require.define('/lib/local/index.js', function (module, exports, __dirname, __filename) {
2867
2426
  require('/lib/local/local_adapter.js', module);
@@ -2883,6 +2442,149 @@
2883
2442
  }
2884
2443
  });
2885
2444
  });
2445
+ require.define('/lib/transforms/index.js', function (module, exports, __dirname, __filename) {
2446
+ require('/lib/transforms/base.js', module);
2447
+ require('/lib/transforms/boolean.js', module);
2448
+ require('/lib/transforms/date.js', module);
2449
+ require('/lib/transforms/number.js', module);
2450
+ require('/lib/transforms/string.js', module);
2451
+ });
2452
+ require.define('/lib/transforms/string.js', function (module, exports, __dirname, __filename) {
2453
+ var none = Ember.isNone, empty = Ember.isEmpty;
2454
+ Ep.StringTransform = Ep.Transform.extend({
2455
+ deserialize: function (serialized) {
2456
+ return none(serialized) ? null : String(serialized);
2457
+ },
2458
+ serialize: function (deserialized) {
2459
+ return none(deserialized) ? null : String(deserialized);
2460
+ }
2461
+ });
2462
+ });
2463
+ require.define('/lib/transforms/number.js', function (module, exports, __dirname, __filename) {
2464
+ var empty = Ember.isEmpty;
2465
+ Ep.NumberTransform = Ep.Transform.extend({
2466
+ deserialize: function (serialized) {
2467
+ return empty(serialized) ? null : Number(serialized);
2468
+ },
2469
+ serialize: function (deserialized) {
2470
+ return empty(deserialized) ? null : Number(deserialized);
2471
+ }
2472
+ });
2473
+ });
2474
+ require.define('/lib/transforms/date.js', function (module, exports, __dirname, __filename) {
2475
+ require('/lib/ext/date.js', module);
2476
+ Ep.DateTransform = Ep.Transform.extend({
2477
+ deserialize: function (serialized) {
2478
+ var type = typeof serialized;
2479
+ if (type === 'string') {
2480
+ return new Date(Ember.Date.parse(serialized));
2481
+ } else if (type === 'number') {
2482
+ return new Date(serialized);
2483
+ } else if (serialized === null || serialized === undefined) {
2484
+ return serialized;
2485
+ } else {
2486
+ return null;
2487
+ }
2488
+ },
2489
+ serialize: function (date) {
2490
+ if (date instanceof Date) {
2491
+ var days = [
2492
+ 'Sun',
2493
+ 'Mon',
2494
+ 'Tue',
2495
+ 'Wed',
2496
+ 'Thu',
2497
+ 'Fri',
2498
+ 'Sat'
2499
+ ];
2500
+ var months = [
2501
+ 'Jan',
2502
+ 'Feb',
2503
+ 'Mar',
2504
+ 'Apr',
2505
+ 'May',
2506
+ 'Jun',
2507
+ 'Jul',
2508
+ 'Aug',
2509
+ 'Sep',
2510
+ 'Oct',
2511
+ 'Nov',
2512
+ 'Dec'
2513
+ ];
2514
+ var pad = function (num) {
2515
+ return num < 10 ? '0' + num : '' + num;
2516
+ };
2517
+ var utcYear = date.getUTCFullYear(), utcMonth = date.getUTCMonth(), utcDayOfMonth = date.getUTCDate(), utcDay = date.getUTCDay(), utcHours = date.getUTCHours(), utcMinutes = date.getUTCMinutes(), utcSeconds = date.getUTCSeconds();
2518
+ var dayOfWeek = days[utcDay];
2519
+ var dayOfMonth = pad(utcDayOfMonth);
2520
+ var month = months[utcMonth];
2521
+ return dayOfWeek + ', ' + dayOfMonth + ' ' + month + ' ' + utcYear + ' ' + pad(utcHours) + ':' + pad(utcMinutes) + ':' + pad(utcSeconds) + ' GMT';
2522
+ } else {
2523
+ return null;
2524
+ }
2525
+ }
2526
+ });
2527
+ });
2528
+ require.define('/lib/ext/date.js', function (module, exports, __dirname, __filename) {
2529
+ Ember.Date = Ember.Date || {};
2530
+ var origParse = Date.parse, numericKeys = [
2531
+ 1,
2532
+ 4,
2533
+ 5,
2534
+ 6,
2535
+ 7,
2536
+ 10,
2537
+ 11
2538
+ ];
2539
+ Ember.Date.parse = function (date) {
2540
+ var timestamp, struct, minutesOffset = 0;
2541
+ 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)) {
2542
+ for (var i = 0, k; k = numericKeys[i]; ++i) {
2543
+ struct[k] = +struct[k] || 0;
2544
+ }
2545
+ struct[2] = (+struct[2] || 1) - 1;
2546
+ struct[3] = +struct[3] || 1;
2547
+ if (struct[8] !== 'Z' && struct[9] !== undefined) {
2548
+ minutesOffset = struct[10] * 60 + struct[11];
2549
+ if (struct[9] === '+') {
2550
+ minutesOffset = 0 - minutesOffset;
2551
+ }
2552
+ }
2553
+ timestamp = Date.UTC(struct[1], struct[2], struct[3], struct[4], struct[5] + minutesOffset, struct[6], struct[7]);
2554
+ } else {
2555
+ timestamp = origParse ? origParse(date) : NaN;
2556
+ }
2557
+ return timestamp;
2558
+ };
2559
+ if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Date) {
2560
+ Date.parse = Ember.Date.parse;
2561
+ }
2562
+ });
2563
+ require.define('/lib/transforms/boolean.js', function (module, exports, __dirname, __filename) {
2564
+ Ep.BooleanTransform = Ep.Transform.extend({
2565
+ deserialize: function (serialized) {
2566
+ var type = typeof serialized;
2567
+ if (type === 'boolean') {
2568
+ return serialized;
2569
+ } else if (type === 'string') {
2570
+ return serialized.match(/^true$|^t$|^1$/i) !== null;
2571
+ } else if (type === 'number') {
2572
+ return serialized === 1;
2573
+ } else {
2574
+ return false;
2575
+ }
2576
+ },
2577
+ serialize: function (deserialized) {
2578
+ return Boolean(deserialized);
2579
+ }
2580
+ });
2581
+ });
2582
+ require.define('/lib/transforms/base.js', function (module, exports, __dirname, __filename) {
2583
+ Ep.Transform = Ember.Object.extend({
2584
+ serialize: Ember.required(),
2585
+ deserialize: Ember.required()
2586
+ });
2587
+ });
2886
2588
  require.define('/lib/session/index.js', function (module, exports, __dirname, __filename) {
2887
2589
  require('/lib/session/session.js', module);
2888
2590
  require('/lib/session/merge.js', module);
@@ -2891,6 +2593,24 @@
2891
2593
  require.define('/lib/session/child_session.js', function (module, exports, __dirname, __filename) {
2892
2594
  var get = Ember.get, set = Ember.set;
2893
2595
  Ep.ChildSession = Ep.Session.extend({
2596
+ fetch: function (model) {
2597
+ var res = this._super(model);
2598
+ if (!res) {
2599
+ res = get(this, 'parent').fetch(model);
2600
+ if (res) {
2601
+ res = this.adopt(res.copy());
2602
+ res.eachRelationship(function (name, relationship) {
2603
+ if (relationship.kind === 'belongsTo') {
2604
+ var child = get(res, name);
2605
+ if (child) {
2606
+ set(child, 'session', this);
2607
+ }
2608
+ }
2609
+ }, this);
2610
+ }
2611
+ }
2612
+ return res;
2613
+ },
2894
2614
  load: function (type, id) {
2895
2615
  if (typeof type === 'string') {
2896
2616
  type = this.lookupType(type);
@@ -2920,7 +2640,7 @@
2920
2640
  });
2921
2641
  set(merged, 'meta', get(models, 'meta'));
2922
2642
  models.forEach(function (model) {
2923
- merged.addObject(session.merge(model));
2643
+ merged.pushObject(session.merge(model));
2924
2644
  });
2925
2645
  return merged;
2926
2646
  });
@@ -2943,12 +2663,12 @@
2943
2663
  var res = models.map(function (model) {
2944
2664
  return session.merge(model);
2945
2665
  });
2946
- return models;
2666
+ return res;
2947
2667
  }, function (models) {
2948
2668
  var res = models.map(function (model) {
2949
2669
  return session.merge(model);
2950
2670
  });
2951
- throw models;
2671
+ throw res;
2952
2672
  });
2953
2673
  dirtyModels.forEach(function (model) {
2954
2674
  this.shadows.add(model.copy());
@@ -2976,13 +2696,31 @@
2976
2696
  require.define('/lib/session/merge.js', function (module, exports, __dirname, __filename) {
2977
2697
  var get = Ember.get, set = Ember.set;
2978
2698
  Ep.Session.reopen({
2979
- merge: function (model, strategy) {
2699
+ merge: function (model, strategy, visited) {
2980
2700
  this.reifyClientId(model);
2701
+ if (!visited)
2702
+ visited = new Ember.Set();
2703
+ if (visited.contains(model)) {
2704
+ return this.getModel(model);
2705
+ }
2706
+ visited.add(model);
2707
+ var detachedChildren = [];
2708
+ model.eachChild(function (child) {
2709
+ if (get(child, 'isDetached')) {
2710
+ detachedChildren.push(child);
2711
+ }
2712
+ }, this);
2713
+ var merged;
2981
2714
  if (get(model, 'hasErrors')) {
2982
- return this._mergeError(model, strategy);
2715
+ merged = this._mergeError(model, strategy);
2983
2716
  } else {
2984
- return this._mergeSuccess(model, strategy);
2717
+ merged = this._mergeSuccess(model, strategy);
2718
+ }
2719
+ for (var i = 0; i < detachedChildren.length; i++) {
2720
+ var child = detachedChildren[i];
2721
+ this.merge(child, strategy, visited);
2985
2722
  }
2723
+ return merged;
2986
2724
  },
2987
2725
  _mergeSuccess: function (model, strategy) {
2988
2726
  var models = get(this, 'models'), shadows = get(this, 'shadows'), newModels = get(this, 'newModels'), originals = get(this, 'originals'), merged, ancestor, existing = models.getModel(model);
@@ -3038,9 +2776,6 @@
3038
2776
  _mergeModel: function (dest, ancestor, model, strategy) {
3039
2777
  if (!strategy)
3040
2778
  strategy = get(this, 'mergeStrategy').create({ session: this });
3041
- if (model === dest) {
3042
- return model;
3043
- }
3044
2779
  if (get(model, 'isPromise')) {
3045
2780
  return this._mergePromise(dest, ancestor, model, strategy);
3046
2781
  }
@@ -3050,13 +2785,16 @@
3050
2785
  dest = dest.content;
3051
2786
  }
3052
2787
  if (!dest) {
3053
- dest = model.constructor.create();
2788
+ if (get(model, 'isDetached')) {
2789
+ dest = model;
2790
+ } else {
2791
+ dest = model.copy();
2792
+ }
2793
+ this.adopt(dest);
3054
2794
  if (promise) {
3055
2795
  promise.resolve(dest);
3056
2796
  }
3057
- }
3058
- if (!get(model, 'hasErrors')) {
3059
- set(dest, 'isNew', false);
2797
+ return dest;
3060
2798
  }
3061
2799
  set(dest, 'id', get(model, 'id'));
3062
2800
  set(dest, 'clientId', get(model, 'clientId'));
@@ -3075,7 +2813,11 @@
3075
2813
  return this._mergeModel(dest, ancestor, content, strategy);
3076
2814
  }
3077
2815
  if (!dest) {
3078
- dest = promise.lazyCopy();
2816
+ if (get(promise, 'isDetached')) {
2817
+ dest = promise;
2818
+ } else {
2819
+ dest = promise.lazyCopy();
2820
+ }
3079
2821
  this.adopt(dest);
3080
2822
  }
3081
2823
  return dest;
@@ -3118,74 +2860,41 @@
3118
2860
  }
3119
2861
  var model = type.create(hash);
3120
2862
  model = this.add(model);
3121
- model._registerRelationships();
3122
2863
  return model;
3123
2864
  },
3124
2865
  adopt: function (model) {
2866
+ Ember.assert('Cannot adopt a model with a clientId!', get(model, 'clientId'));
3125
2867
  Ember.assert('Models instances cannot be moved between sessions. Use `add` or `update` instead.', !get(model, 'session') || get(model, 'session') === this);
2868
+ Ember.assert('An equivalent model already exists in the session!', !this.getModel(model) || this.getModel(model) === model);
3126
2869
  set(model, 'session', this);
3127
2870
  if (get(model, 'isNew')) {
3128
2871
  this.newModels.add(model);
3129
2872
  }
3130
- this.models.add(model);
3131
- model._registerRelationships();
2873
+ if (!get(model, 'isProxy')) {
2874
+ this.models.add(model);
2875
+ model._registerRelationships();
2876
+ }
3132
2877
  return model;
3133
2878
  },
3134
- add: function (model, depth) {
2879
+ add: function (model) {
3135
2880
  this.reifyClientId(model);
3136
- var dest = this.getModel(model);
2881
+ var dest = this.fetch(model);
3137
2882
  if (dest && get(dest, 'isLoaded'))
3138
2883
  return dest;
3139
- if (typeof depth === 'undefined') {
3140
- depth = 2;
3141
- }
3142
- depth--;
3143
2884
  if (get(model, 'isProxy')) {
3144
2885
  var content = get(model, 'content');
3145
2886
  if (content) {
3146
2887
  return this.add(content);
3147
2888
  }
3148
- dest = model.lazyCopy();
3149
- return this.adopt(dest);
3150
2889
  }
3151
- if (get(model, 'isDetached')) {
2890
+ if (get(model, 'isNew') && get(model, 'isDetached')) {
3152
2891
  dest = model;
2892
+ } else if (get(model, 'isNew')) {
2893
+ dest = model.copy();
3153
2894
  } else {
3154
- dest = model.constructor.create();
3155
- model.copyAttributes(dest);
2895
+ dest = model.lazyCopy();
3156
2896
  }
3157
- this.adopt(dest);
3158
- model.eachRelationship(function (name, relationship) {
3159
- if (relationship.kind === 'belongsTo') {
3160
- var child = get(model, name);
3161
- if (child) {
3162
- if (get(child, 'session') === this) {
3163
- model.belongsToDidChange(model, name);
3164
- } else {
3165
- if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3166
- child = this.add(child, depth);
3167
- } else {
3168
- child = child.lazyCopy();
3169
- }
3170
- dest.suspendRelationshipObservers(function () {
3171
- set(dest, name, child);
3172
- });
3173
- }
3174
- }
3175
- } else if (relationship.kind === 'hasMany') {
3176
- var children = get(model, name);
3177
- var copied = children.map(function (child) {
3178
- if (depth >= 0 || get(child, 'isDetached') || get(child, 'isNew')) {
3179
- child = this.add(child, depth);
3180
- } else {
3181
- child = child.lazyCopy();
3182
- }
3183
- return child;
3184
- }, this);
3185
- set(dest, name, copied);
3186
- }
3187
- }, this);
3188
- return dest;
2897
+ return this.adopt(dest);
3189
2898
  },
3190
2899
  remove: function (model) {
3191
2900
  get(this, 'models').remove(model);
@@ -3201,7 +2910,12 @@
3201
2910
  }
3202
2911
  throw new Ember.Error('Cannot update with an unloaded model: ' + model.toString());
3203
2912
  }
3204
- var dest = this.getModel(model);
2913
+ var dest = this.fetch(model);
2914
+ if (get(model, 'isNew') && !dest) {
2915
+ dest = get(model, 'type').create();
2916
+ set(dest, 'clientId', get(model, 'clientId'));
2917
+ this.adopt(dest);
2918
+ }
3205
2919
  if (get(model, 'isDetached') || !dest || !get(dest, 'isLoaded')) {
3206
2920
  return this.add(model);
3207
2921
  }
@@ -3212,6 +2926,7 @@
3212
2926
  return dest;
3213
2927
  }
3214
2928
  model.copyAttributes(dest);
2929
+ model.copyMeta(dest);
3215
2930
  model.eachRelationship(function (name, relationship) {
3216
2931
  if (relationship.kind === 'belongsTo') {
3217
2932
  var child = get(model, name);
@@ -3259,6 +2974,9 @@
3259
2974
  }
3260
2975
  return this.load(type, query);
3261
2976
  },
2977
+ fetch: function (model) {
2978
+ return this.getModel(model);
2979
+ },
3262
2980
  query: function (type, query) {
3263
2981
  if (typeof type === 'string') {
3264
2982
  type = this.lookupType(type);
@@ -3271,7 +2989,7 @@
3271
2989
  });
3272
2990
  set(merged, 'meta', get(models, 'meta'));
3273
2991
  models.forEach(function (model) {
3274
- merged.addObject(session.merge(model));
2992
+ merged.pushObject(session.merge(model));
3275
2993
  });
3276
2994
  return merged;
3277
2995
  });
@@ -3394,11 +3112,6 @@
3394
3112
  });
3395
3113
  require.define('/lib/session/merge_strategies/per_field.js', function (module, exports, __dirname, __filename) {
3396
3114
  var get = Ember.get, set = Ember.set, isEqual = Ember.isEqual;
3397
- function mergeIfPresent(session, model, strategy) {
3398
- if (!model)
3399
- return null;
3400
- return session.merge(model, strategy);
3401
- }
3402
3115
  Ep.PerField = Ep.MergeStrategy.extend({
3403
3116
  init: function () {
3404
3117
  this.cache = Ep.ModelSet.create();
@@ -3432,9 +3145,8 @@
3432
3145
  var oursValue = get(ours, name);
3433
3146
  var theirsValue = get(theirs, name);
3434
3147
  var originalValue = get(ancestor, name);
3435
- var merged = mergeIfPresent(session, theirsValue, this);
3436
3148
  if (isEqual(oursValue, originalValue)) {
3437
- set(ours, name, merged);
3149
+ set(ours, name, theirsValue);
3438
3150
  }
3439
3151
  } else if (relationship.kind === 'hasMany') {
3440
3152
  var theirChildren = get(theirs, name);
@@ -3445,17 +3157,12 @@
3445
3157
  existing.addObjects(ourChildren);
3446
3158
  theirChildren.forEach(function (model) {
3447
3159
  if (existing.contains(model)) {
3448
- session.merge(model, this);
3449
3160
  existing.remove(model);
3450
3161
  } else {
3451
- ourChildren.addObject(session.merge(model, this));
3162
+ ourChildren.pushObject(model);
3452
3163
  }
3453
3164
  }, this);
3454
3165
  ourChildren.removeObjects(existing);
3455
- } else {
3456
- theirChildren.forEach(function (model) {
3457
- session.merge(model, this);
3458
- }, this);
3459
3166
  }
3460
3167
  }
3461
3168
  }, this);
@@ -3465,15 +3172,10 @@
3465
3172
  require.define('/lib/session/merge_strategies/theirs.js', function (module, exports, __dirname, __filename) {
3466
3173
  var get = Ember.get, set = Ember.set;
3467
3174
  Ep.Theirs = Ep.MergeStrategy.extend({
3468
- init: function () {
3469
- this.cache = Ep.ModelSet.create();
3470
- },
3471
3175
  merge: function (dest, ancestor, model) {
3472
- if (this.cache.contains(model))
3473
- return dest;
3474
- this.cache.addObject(model);
3475
3176
  dest.beginPropertyChanges();
3476
3177
  this.copyAttributes(model, dest);
3178
+ this.copyMeta(model, dest);
3477
3179
  this.copyRelationships(model, dest);
3478
3180
  dest.endPropertyChanges();
3479
3181
  return dest;
@@ -3492,10 +3194,8 @@
3492
3194
  if (relationship.kind === 'belongsTo') {
3493
3195
  var child = get(model, name);
3494
3196
  var destChild = get(dest, name);
3495
- if (child && destChild) {
3496
- session.merge(child, this);
3497
- } else if (child) {
3498
- set(dest, name, session.merge(child, this));
3197
+ if (child) {
3198
+ set(dest, name, child);
3499
3199
  } else if (destChild) {
3500
3200
  set(dest, name, null);
3501
3201
  }
@@ -3503,14 +3203,13 @@
3503
3203
  var children = get(model, name);
3504
3204
  var destChildren = get(dest, name);
3505
3205
  var modelSet = Ep.ModelSet.create();
3506
- modelSet.addObjects(destChildren);
3206
+ modelSet.pushObjects(destChildren);
3507
3207
  set(destChildren, 'meta', get(children, 'meta'));
3508
3208
  children.forEach(function (child) {
3509
3209
  if (modelSet.contains(child)) {
3510
- session.merge(child, this);
3511
3210
  modelSet.remove(child);
3512
3211
  } else {
3513
- destChildren.addObject(session.merge(child, this));
3212
+ destChildren.addObject(child);
3514
3213
  }
3515
3214
  }, this);
3516
3215
  destChildren.removeObjects(modelSet);
@@ -3523,7 +3222,7 @@
3523
3222
  var get = Ember.get, set = Ember.set;
3524
3223
  function mustImplement(name) {
3525
3224
  return function () {
3526
- throw new Ember.Error('Your serializer ' + this.toString() + ' does not implement the required method ' + name);
3225
+ throw new Ember.Error('Your merge strategy ' + this.toString() + ' does not implement the required method ' + name);
3527
3226
  };
3528
3227
  }
3529
3228
  Ep.MergeStrategy = Ember.Object.extend({
@@ -3624,6 +3323,11 @@
3624
3323
  application.register('session:child', application.ChildSession || Ep.ChildSession, { singleton: false });
3625
3324
  application.register('session:main', application.DefaultSession || Ep.Session);
3626
3325
  application.register('serializer:main', application.Serializer || Ep.RestSerializer);
3326
+ require('/lib/transforms/index.js', module);
3327
+ application.register('transform:boolean', Ep.BooleanTransform);
3328
+ application.register('transform:date', Ep.DateTransform);
3329
+ application.register('transform:number', Ep.NumberTransform);
3330
+ application.register('transform:string', Ep.StringTransform);
3627
3331
  application.inject('adapter', 'serializer', 'serializer:main');
3628
3332
  application.inject('session', 'adapter', 'adapter:main');
3629
3333
  container.optionsForType('model', { instantiate: false });
@@ -3635,6 +3339,272 @@
3635
3339
  });
3636
3340
  });
3637
3341
  });
3342
+ require.define('/lib/version.js', function (module, exports, __dirname, __filename) {
3343
+ Ep.VERSION = '0.1.3';
3344
+ Ember.libraries && Ember.libraries.register('EPF', Ep.VERSION);
3345
+ });
3346
+ require.define('/vendor/ember-inflector.js', function (module, exports, __dirname, __filename) {
3347
+ (function () {
3348
+ Ember.INFLECTED_CLASSIFY = Ember.ENV.INFLECTED_CLASSIFY;
3349
+ if (typeof Ember.INFLECTED_CLASSIFY === 'undefined') {
3350
+ Ember.INFLECTED_CLASSIFY = false;
3351
+ }
3352
+ Ember.String.pluralize = function (word) {
3353
+ return Ember.Inflector.inflect(word, Ember.Inflector.rules.plurals);
3354
+ };
3355
+ Ember.String.singularize = function (word) {
3356
+ return Ember.Inflector.inflect(word, Ember.Inflector.rules.singular);
3357
+ };
3358
+ Ember.String.humanize = function (word) {
3359
+ var inflected = Ember.Inflector.inflect(word, Ember.Inflector.rules.humans);
3360
+ inflected = inflected.replace(Ember.Inflector.KEY_SUFFIX_REGEX, '');
3361
+ inflected = inflected.replace(Ember.Inflector.WHITESPACE_REGEX, ' ');
3362
+ inflected = inflected.replace(/_/g, ' ');
3363
+ return Ember.String.capitalize(inflected);
3364
+ };
3365
+ Ember.String.titleize = function (word) {
3366
+ var result = Ember.String.humanize(word);
3367
+ result = result.replace(/\b(?:<!['’`])[a-z]/).toLowerCase().replace(/^.|\s\S/g, function (a) {
3368
+ return a.toUpperCase();
3369
+ });
3370
+ return result;
3371
+ };
3372
+ Ember.String.capitalize = function (word) {
3373
+ return word.replace(Ember.Inflector.FIRST_LETTER_REGEX, function (match) {
3374
+ return match.toUpperCase();
3375
+ });
3376
+ };
3377
+ Ember.String.tableize = function (word) {
3378
+ return Ember.String.pluralize(Ember.String.underscore(word.toLowerCase()));
3379
+ };
3380
+ if (Ember.INFLECTED_CLASSIFY) {
3381
+ Ember.String.classify = function (word) {
3382
+ return Ember.String.capitalize(Ember.String.camelize(Ember.String.singularize(word)));
3383
+ };
3384
+ }
3385
+ }());
3386
+ (function () {
3387
+ Ember.Inflector = {
3388
+ FIRST_LETTER_REGEX: /^\w/,
3389
+ WHITESPACE_REGEX: /\s+/,
3390
+ KEY_SUFFIX_REGEX: /_id$/,
3391
+ BLANK_REGEX: /^\s*$/,
3392
+ _CACHE: {},
3393
+ cache: function (word, rules, value) {
3394
+ Ember.Inflector._CACHE[word] = Ember.Inflector._CACHE[word] || {};
3395
+ if (value) {
3396
+ Ember.Inflector._CACHE[word][rules] = value;
3397
+ }
3398
+ return Ember.Inflector._CACHE[word][rules];
3399
+ },
3400
+ clearCache: function () {
3401
+ Ember.Inflector._CACHE = {};
3402
+ },
3403
+ clearRules: function () {
3404
+ Ember.Inflector.rules.plurals = [];
3405
+ Ember.Inflector.rules.plurals = [];
3406
+ Ember.Inflector.rules.singular = [];
3407
+ Ember.Inflector.rules.humans = [];
3408
+ Ember.Inflector.rules.uncountable = {};
3409
+ Ember.Inflector.rules.irregular = {};
3410
+ Ember.Inflector.rules.irregularInverse = {};
3411
+ },
3412
+ rules: {
3413
+ plurals: [],
3414
+ singular: [],
3415
+ humans: [],
3416
+ irregular: {},
3417
+ irregularInverse: {},
3418
+ uncountable: {}
3419
+ },
3420
+ reset: function () {
3421
+ Ember.Inflector.clearCache();
3422
+ Ember.Inflector.clearRules();
3423
+ },
3424
+ plural: function (rule, substituion) {
3425
+ Ember.Inflector.rules.plurals.addObject([
3426
+ rule,
3427
+ substituion
3428
+ ]);
3429
+ },
3430
+ singular: function (rule, substituion) {
3431
+ Ember.Inflector.rules.singular.addObject([
3432
+ rule,
3433
+ substituion
3434
+ ]);
3435
+ },
3436
+ human: function (rule, substituion) {
3437
+ Ember.Inflector.rules.humans.addObject([
3438
+ rule,
3439
+ substituion
3440
+ ]);
3441
+ },
3442
+ irregular: function (rule, substituion) {
3443
+ Ember.Inflector.rules.irregular[rule] = substituion;
3444
+ Ember.Inflector.rules.irregularInverse[substituion] = rule;
3445
+ },
3446
+ uncountable: function (uncountable) {
3447
+ uncountable.forEach(function (word) {
3448
+ Ember.Inflector.rules.uncountable[word] = true;
3449
+ });
3450
+ },
3451
+ inflect: function (word, rules) {
3452
+ var inflection, substitution, result, lowercase, isCached, isIrregular, isIrregularInverse, rule;
3453
+ if (Ember.Inflector.BLANK_REGEX.test(word)) {
3454
+ return word;
3455
+ }
3456
+ lowercase = word.toLowerCase();
3457
+ isCached = Ember.Inflector.cache(lowercase, rules);
3458
+ if (isCached) {
3459
+ return isCached;
3460
+ }
3461
+ if (Ember.Inflector.rules.uncountable[lowercase]) {
3462
+ return word;
3463
+ }
3464
+ isIrregular = Ember.Inflector.rules.irregular[lowercase];
3465
+ if (isIrregular) {
3466
+ return isIrregular;
3467
+ }
3468
+ isIrregularInverse = Ember.Inflector.rules.irregularInverse[lowercase];
3469
+ if (isIrregularInverse) {
3470
+ return isIrregularInverse;
3471
+ }
3472
+ for (var i = rules.length, min = 0; i > min; i--) {
3473
+ inflection = rules[i - 1], rule = inflection[0];
3474
+ if (rule.test(word)) {
3475
+ break;
3476
+ }
3477
+ }
3478
+ inflection = inflection || [];
3479
+ rule = inflection[0];
3480
+ substitution = inflection[1];
3481
+ result = word.replace(rule, substitution);
3482
+ Ember.Inflector.cache(lowercase, rules, result);
3483
+ return result;
3484
+ }
3485
+ };
3486
+ }());
3487
+ (function () {
3488
+ Ember.Inflector.loadAll = function () {
3489
+ Ember.Inflector.plural(/$/, 's');
3490
+ Ember.Inflector.plural(/s$/i, 's');
3491
+ Ember.Inflector.plural(/^(ax|test)is$/i, '$1es');
3492
+ Ember.Inflector.plural(/(octop|vir)us$/i, '$1i');
3493
+ Ember.Inflector.plural(/(octop|vir)i$/i, '$1i');
3494
+ Ember.Inflector.plural(/(alias|status)$/i, '$1es');
3495
+ Ember.Inflector.plural(/(bu)s$/i, '$1ses');
3496
+ Ember.Inflector.plural(/(buffal|tomat)o$/i, '$1oes');
3497
+ Ember.Inflector.plural(/([ti])um$/i, '$1a');
3498
+ Ember.Inflector.plural(/([ti])a$/i, '$1a');
3499
+ Ember.Inflector.plural(/sis$/i, 'ses');
3500
+ Ember.Inflector.plural(/(?:([^f])fe|([lr])f)$/i, '$1$2ves');
3501
+ Ember.Inflector.plural(/(hive)$/i, '$1s');
3502
+ Ember.Inflector.plural(/([^aeiouy]|qu)y$/i, '$1ies');
3503
+ Ember.Inflector.plural(/(x|ch|ss|sh)$/i, '$1es');
3504
+ Ember.Inflector.plural(/(matr|vert|ind)(?:ix|ex)$/i, '$1ices');
3505
+ Ember.Inflector.plural(/^(m|l)ouse$/i, '$1ice');
3506
+ Ember.Inflector.plural(/^(m|l)ice$/i, '$1ice');
3507
+ Ember.Inflector.plural(/^(ox)$/i, '$1en');
3508
+ Ember.Inflector.plural(/^(oxen)$/i, '$1');
3509
+ Ember.Inflector.plural(/(quiz)$/i, '$1zes');
3510
+ Ember.Inflector.singular(/s$/i, '');
3511
+ Ember.Inflector.singular(/(ss)$/i, '$1');
3512
+ Ember.Inflector.singular(/(n)ews$/i, '$1ews');
3513
+ Ember.Inflector.singular(/([ti])a$/i, '$1um');
3514
+ Ember.Inflector.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '$1sis');
3515
+ Ember.Inflector.singular(/(^analy)(sis|ses)$/i, '$1sis');
3516
+ Ember.Inflector.singular(/([^f])ves$/i, '$1fe');
3517
+ Ember.Inflector.singular(/(hive)s$/i, '$1');
3518
+ Ember.Inflector.singular(/(tive)s$/i, '$1');
3519
+ Ember.Inflector.singular(/([lr])ves$/i, '$1f');
3520
+ Ember.Inflector.singular(/([^aeiouy]|qu)ies$/i, '$1y');
3521
+ Ember.Inflector.singular(/(s)eries$/i, '$1eries');
3522
+ Ember.Inflector.singular(/(m)ovies$/i, '$1ovie');
3523
+ Ember.Inflector.singular(/(x|ch|ss|sh)es$/i, '$1');
3524
+ Ember.Inflector.singular(/^(m|l)ice$/i, '$1ouse');
3525
+ Ember.Inflector.singular(/(bus)(es)?$/i, '$1');
3526
+ Ember.Inflector.singular(/(o)es$/i, '$1');
3527
+ Ember.Inflector.singular(/(shoe)s$/i, '$1');
3528
+ Ember.Inflector.singular(/(cris|test)(is|es)$/i, '$1is');
3529
+ Ember.Inflector.singular(/^(a)x[ie]s$/i, '$1xis');
3530
+ Ember.Inflector.singular(/(octop|vir)(us|i)$/i, '$1us');
3531
+ Ember.Inflector.singular(/(alias|status)(es)?$/i, '$1');
3532
+ Ember.Inflector.singular(/^(ox)en/i, '$1');
3533
+ Ember.Inflector.singular(/(vert|ind)ices$/i, '$1ex');
3534
+ Ember.Inflector.singular(/(matr)ices$/i, '$1ix');
3535
+ Ember.Inflector.singular(/(quiz)zes$/i, '$1');
3536
+ Ember.Inflector.singular(/(database)s$/i, '$1');
3537
+ Ember.Inflector.irregular('person', 'people');
3538
+ Ember.Inflector.irregular('man', 'men');
3539
+ Ember.Inflector.irregular('child', 'children');
3540
+ Ember.Inflector.irregular('sex', 'sexes');
3541
+ Ember.Inflector.irregular('move', 'moves');
3542
+ Ember.Inflector.irregular('cow', 'kine');
3543
+ Ember.Inflector.irregular('zombie', 'zombies');
3544
+ Ember.Inflector.uncountable('equipment information rice money species series fish sheep jeans police'.w());
3545
+ };
3546
+ }());
3547
+ (function () {
3548
+ Ember.Inflector.rules.ordinalization = {
3549
+ 'default': 'th',
3550
+ 0: '',
3551
+ 1: 'st',
3552
+ 2: 'nd',
3553
+ 3: 'rd',
3554
+ 11: 'th',
3555
+ 12: 'th',
3556
+ 13: 'th'
3557
+ };
3558
+ Ember.Inflector.ordinal = function (number) {
3559
+ number = parseInt(number, 10);
3560
+ number = Math.abs(number);
3561
+ if (number > 10 && number < 14) {
3562
+ number %= 100;
3563
+ } else {
3564
+ number %= 10;
3565
+ }
3566
+ var ordinalization = Ember.Inflector.rules.ordinalization;
3567
+ return ordinalization[number] || ordinalization['default'];
3568
+ };
3569
+ Ember.String.ordinalize = function (word) {
3570
+ var ordinalization = Ember.Inflector.ordinal(word);
3571
+ return [
3572
+ word,
3573
+ ordinalization
3574
+ ].join('');
3575
+ };
3576
+ }());
3577
+ (function () {
3578
+ var pluralize = Ember.String.pluralize, singularize = Ember.String.singularize, humanize = Ember.String.humanize, titleize = Ember.String.titleize, capitalize = Ember.String.capitalize, tableize = Ember.String.tableize, classify = Ember.String.classify;
3579
+ if (Ember.EXTEND_PROTOTYPES) {
3580
+ String.prototype.pluralize = function () {
3581
+ return pluralize(this, arguments);
3582
+ };
3583
+ String.prototype.singularize = function () {
3584
+ return singularize(this, arguments);
3585
+ };
3586
+ String.prototype.humanize = function () {
3587
+ return humanize(this, arguments);
3588
+ };
3589
+ String.prototype.titleize = function () {
3590
+ return titleize(this, arguments);
3591
+ };
3592
+ String.prototype.capitalize = function () {
3593
+ return capitalize(this, arguments);
3594
+ };
3595
+ String.prototype.tableize = function () {
3596
+ return tableize(this, arguments);
3597
+ };
3598
+ String.prototype.classify = function () {
3599
+ return classify(this, arguments);
3600
+ };
3601
+ }
3602
+ }());
3603
+ (function () {
3604
+ }());
3605
+ (function () {
3606
+ }());
3607
+ });
3638
3608
  global.epf = require('/lib/index.js');
3639
3609
  }.call(this, this));
3640
3610
  /*