active-model-adapter-source 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/dist/active-model-adapter.js +718 -0
- data/package.json +54 -0
- metadata +68 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
!binary "U0hBMQ==":
|
|
3
|
+
metadata.gz: !binary |-
|
|
4
|
+
YzUwYzQ2MjM4ZmZhNzlhNzNlNmNjOTEyZTQ2Yjg0ZmRlNGRmZGRkNQ==
|
|
5
|
+
data.tar.gz: !binary |-
|
|
6
|
+
ZTdjZDlmOWFhZWM3YTg0NGYxYzA2MjkzN2JmZTQ2NWQ3OWE0NjlhZQ==
|
|
7
|
+
SHA512:
|
|
8
|
+
metadata.gz: !binary |-
|
|
9
|
+
MjJlNmU4MDBkMWEyM2U1Y2RmZmU2YzE2NTliNjFjY2QzNWU1NzFhYTA1ZDQz
|
|
10
|
+
N2Y5MTkyMzJiODQxYWQ5MjdmZTk3YzhiYWM4NWRmYzRjYzEyZTFkZjA5ODk4
|
|
11
|
+
YzkzNzg2ZTM3ZDM2NGI4OGNkYjg0Y2JjNDQxMzdkNzdhMzU0NjQ=
|
|
12
|
+
data.tar.gz: !binary |-
|
|
13
|
+
ZTAwMTg3ODRlNTA4Nzk1Y2ZhYTc4YmVlM2E0NDk1OWYxYWRjYjc0Nzg5MGU4
|
|
14
|
+
YzNhZDhlNGE5NmU4YzQxOTNlMTJmODk3Yjg0NzhiYmY4YmQ1MGE3ZTE2Y2Rl
|
|
15
|
+
YTM4NGRkNGRjZGI4ZmU2YmFmNDEwMDlkMjM3Y2E2N2EzMzIzOTc=
|
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @overview ActiveModelAdapter
|
|
3
|
+
* @copyright Copyright 2011-2015 Tilde Inc. and contributors
|
|
4
|
+
* Portions Copyright 2006-2011 Strobe Inc.
|
|
5
|
+
* Portions Copyright 2008-2011 Apple Inc. All rights reserved.
|
|
6
|
+
* @license Licensed under MIT license
|
|
7
|
+
* See https://raw.github.com/emberjs/ember.js/master/LICENSE
|
|
8
|
+
* @version 0.1.3
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
(function() {
|
|
12
|
+
|
|
13
|
+
var define, requireModule, require, requirejs;
|
|
14
|
+
|
|
15
|
+
(function() {
|
|
16
|
+
|
|
17
|
+
var _isArray;
|
|
18
|
+
if (!Array.isArray) {
|
|
19
|
+
_isArray = function (x) {
|
|
20
|
+
return Object.prototype.toString.call(x) === "[object Array]";
|
|
21
|
+
};
|
|
22
|
+
} else {
|
|
23
|
+
_isArray = Array.isArray;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var registry = {}, seen = {};
|
|
27
|
+
var FAILED = false;
|
|
28
|
+
|
|
29
|
+
var uuid = 0;
|
|
30
|
+
|
|
31
|
+
function tryFinally(tryable, finalizer) {
|
|
32
|
+
try {
|
|
33
|
+
return tryable();
|
|
34
|
+
} finally {
|
|
35
|
+
finalizer();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function unsupportedModule(length) {
|
|
40
|
+
throw new Error("an unsupported module was defined, expected `define(name, deps, module)` instead got: `" + length + "` arguments to define`");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var defaultDeps = ['require', 'exports', 'module'];
|
|
44
|
+
|
|
45
|
+
function Module(name, deps, callback, exports) {
|
|
46
|
+
this.id = uuid++;
|
|
47
|
+
this.name = name;
|
|
48
|
+
this.deps = !deps.length && callback.length ? defaultDeps : deps;
|
|
49
|
+
this.exports = exports || { };
|
|
50
|
+
this.callback = callback;
|
|
51
|
+
this.state = undefined;
|
|
52
|
+
this._require = undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Module.prototype.makeRequire = function() {
|
|
57
|
+
var name = this.name;
|
|
58
|
+
|
|
59
|
+
return this._require || (this._require = function(dep) {
|
|
60
|
+
return require(resolve(dep, name));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
define = function(name, deps, callback) {
|
|
65
|
+
if (arguments.length < 2) {
|
|
66
|
+
unsupportedModule(arguments.length);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!_isArray(deps)) {
|
|
70
|
+
callback = deps;
|
|
71
|
+
deps = [];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
registry[name] = new Module(name, deps, callback);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// we don't support all of AMD
|
|
78
|
+
// define.amd = {};
|
|
79
|
+
// we will support petals...
|
|
80
|
+
define.petal = { };
|
|
81
|
+
|
|
82
|
+
function Alias(path) {
|
|
83
|
+
this.name = path;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
define.alias = function(path) {
|
|
87
|
+
return new Alias(path);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
function reify(mod, name, seen) {
|
|
91
|
+
var deps = mod.deps;
|
|
92
|
+
var length = deps.length;
|
|
93
|
+
var reified = new Array(length);
|
|
94
|
+
var dep;
|
|
95
|
+
// TODO: new Module
|
|
96
|
+
// TODO: seen refactor
|
|
97
|
+
var module = { };
|
|
98
|
+
|
|
99
|
+
for (var i = 0, l = length; i < l; i++) {
|
|
100
|
+
dep = deps[i];
|
|
101
|
+
if (dep === 'exports') {
|
|
102
|
+
module.exports = reified[i] = seen;
|
|
103
|
+
} else if (dep === 'require') {
|
|
104
|
+
reified[i] = mod.makeRequire();
|
|
105
|
+
} else if (dep === 'module') {
|
|
106
|
+
mod.exports = seen;
|
|
107
|
+
module = reified[i] = mod;
|
|
108
|
+
} else {
|
|
109
|
+
reified[i] = requireFrom(resolve(dep, name), name);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
deps: reified,
|
|
115
|
+
module: module
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function requireFrom(name, origin) {
|
|
120
|
+
var mod = registry[name];
|
|
121
|
+
if (!mod) {
|
|
122
|
+
throw new Error('Could not find module `' + name + '` imported from `' + origin + '`');
|
|
123
|
+
}
|
|
124
|
+
return require(name);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function missingModule(name) {
|
|
128
|
+
throw new Error('Could not find module ' + name);
|
|
129
|
+
}
|
|
130
|
+
requirejs = require = requireModule = function(name) {
|
|
131
|
+
var mod = registry[name];
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if (mod && mod.callback instanceof Alias) {
|
|
135
|
+
mod = registry[mod.callback.name];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!mod) { missingModule(name); }
|
|
139
|
+
|
|
140
|
+
if (mod.state !== FAILED &&
|
|
141
|
+
seen.hasOwnProperty(name)) {
|
|
142
|
+
return seen[name];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
var reified;
|
|
146
|
+
var module;
|
|
147
|
+
var loaded = false;
|
|
148
|
+
|
|
149
|
+
seen[name] = { }; // placeholder for run-time cycles
|
|
150
|
+
|
|
151
|
+
tryFinally(function() {
|
|
152
|
+
reified = reify(mod, name, seen[name]);
|
|
153
|
+
module = mod.callback.apply(this, reified.deps);
|
|
154
|
+
loaded = true;
|
|
155
|
+
}, function() {
|
|
156
|
+
if (!loaded) {
|
|
157
|
+
mod.state = FAILED;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
var obj;
|
|
162
|
+
if (module === undefined && reified.module.exports) {
|
|
163
|
+
obj = reified.module.exports;
|
|
164
|
+
} else {
|
|
165
|
+
obj = seen[name] = module;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (obj !== null &&
|
|
169
|
+
(typeof obj === 'object' || typeof obj === 'function') &&
|
|
170
|
+
obj['default'] === undefined) {
|
|
171
|
+
obj['default'] = obj;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return (seen[name] = obj);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
function resolve(child, name) {
|
|
178
|
+
if (child.charAt(0) !== '.') { return child; }
|
|
179
|
+
|
|
180
|
+
var parts = child.split('/');
|
|
181
|
+
var nameParts = name.split('/');
|
|
182
|
+
var parentBase = nameParts.slice(0, -1);
|
|
183
|
+
|
|
184
|
+
for (var i = 0, l = parts.length; i < l; i++) {
|
|
185
|
+
var part = parts[i];
|
|
186
|
+
|
|
187
|
+
if (part === '..') {
|
|
188
|
+
if (parentBase.length === 0) {
|
|
189
|
+
throw new Error('Cannot access parent module of root');
|
|
190
|
+
}
|
|
191
|
+
parentBase.pop();
|
|
192
|
+
} else if (part === '.') { continue; }
|
|
193
|
+
else { parentBase.push(part); }
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return parentBase.join('/');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
requirejs.entries = requirejs._eak_seen = registry;
|
|
200
|
+
requirejs.clear = function(){
|
|
201
|
+
requirejs.entries = requirejs._eak_seen = registry = {};
|
|
202
|
+
seen = state = {};
|
|
203
|
+
};
|
|
204
|
+
})();
|
|
205
|
+
|
|
206
|
+
define("ember", ["exports"], function (exports) {
|
|
207
|
+
exports["default"] = Ember;
|
|
208
|
+
});
|
|
209
|
+
define("ember-data", ["exports"], function (exports) {
|
|
210
|
+
exports["default"] = DS;
|
|
211
|
+
});
|
|
212
|
+
define('active-model-adapter', ['exports', 'ember', 'ember-data'], function (exports, _ember, _emberData) {
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
@module active-model-adapter
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
var decamelize = _ember["default"].String.decamelize;
|
|
219
|
+
var underscore = _ember["default"].String.underscore;
|
|
220
|
+
var pluralize = _ember["default"].String.pluralize;
|
|
221
|
+
var RESTAdapter = _emberData["default"].RESTAdapter;
|
|
222
|
+
var InvalidError = _emberData["default"].InvalidError;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
The ActiveModelAdapter is a subclass of the RESTAdapter designed to integrate
|
|
226
|
+
with a JSON API that uses an underscored naming convention instead of camelCasing.
|
|
227
|
+
It has been designed to work out of the box with the
|
|
228
|
+
[active\_model\_serializers](http://github.com/rails-api/active_model_serializers)
|
|
229
|
+
Ruby gem. This Adapter expects specific settings using ActiveModel::Serializers,
|
|
230
|
+
`embed :ids, embed_in_root: true` which sideloads the records.
|
|
231
|
+
|
|
232
|
+
This adapter extends the DS.RESTAdapter by making consistent use of the camelization,
|
|
233
|
+
decamelization and pluralization methods to normalize the serialized JSON into a
|
|
234
|
+
format that is compatible with a conventional Rails backend and Ember Data.
|
|
235
|
+
|
|
236
|
+
## JSON Structure
|
|
237
|
+
|
|
238
|
+
The ActiveModelAdapter expects the JSON returned from your server to follow
|
|
239
|
+
the REST adapter conventions substituting underscored keys for camelcased ones.
|
|
240
|
+
|
|
241
|
+
Unlike the DS.RESTAdapter, async relationship keys must be the singular form
|
|
242
|
+
of the relationship name, followed by "_id" for DS.belongsTo relationships,
|
|
243
|
+
or "_ids" for DS.hasMany relationships.
|
|
244
|
+
|
|
245
|
+
### Conventional Names
|
|
246
|
+
|
|
247
|
+
Attribute names in your JSON payload should be the underscored versions of
|
|
248
|
+
the attributes in your Ember.js models.
|
|
249
|
+
|
|
250
|
+
For example, if you have a `Person` model:
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
App.FamousPerson = DS.Model.extend({
|
|
254
|
+
firstName: DS.attr('string'),
|
|
255
|
+
lastName: DS.attr('string'),
|
|
256
|
+
occupation: DS.attr('string')
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The JSON returned should look like this:
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
{
|
|
264
|
+
"famous_person": {
|
|
265
|
+
"id": 1,
|
|
266
|
+
"first_name": "Barack",
|
|
267
|
+
"last_name": "Obama",
|
|
268
|
+
"occupation": "President"
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Let's imagine that `Occupation` is just another model:
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
App.Person = DS.Model.extend({
|
|
277
|
+
firstName: DS.attr('string'),
|
|
278
|
+
lastName: DS.attr('string'),
|
|
279
|
+
occupation: DS.belongsTo('occupation')
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
App.Occupation = DS.Model.extend({
|
|
283
|
+
name: DS.attr('string'),
|
|
284
|
+
salary: DS.attr('number'),
|
|
285
|
+
people: DS.hasMany('person')
|
|
286
|
+
});
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
The JSON needed to avoid extra server calls, should look like this:
|
|
290
|
+
|
|
291
|
+
```js
|
|
292
|
+
{
|
|
293
|
+
"people": [{
|
|
294
|
+
"id": 1,
|
|
295
|
+
"first_name": "Barack",
|
|
296
|
+
"last_name": "Obama",
|
|
297
|
+
"occupation_id": 1
|
|
298
|
+
}],
|
|
299
|
+
|
|
300
|
+
"occupations": [{
|
|
301
|
+
"id": 1,
|
|
302
|
+
"name": "President",
|
|
303
|
+
"salary": 100000,
|
|
304
|
+
"person_ids": [1]
|
|
305
|
+
}]
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
@class ActiveModelAdapter
|
|
310
|
+
@constructor
|
|
311
|
+
@namespace DS
|
|
312
|
+
@extends DS.RESTAdapter
|
|
313
|
+
**/
|
|
314
|
+
|
|
315
|
+
var ActiveModelAdapter = RESTAdapter.extend({
|
|
316
|
+
defaultSerializer: '-active-model',
|
|
317
|
+
/**
|
|
318
|
+
The ActiveModelAdapter overrides the `pathForType` method to build
|
|
319
|
+
underscored URLs by decamelizing and pluralizing the object type name.
|
|
320
|
+
```js
|
|
321
|
+
this.pathForType("famousPerson");
|
|
322
|
+
//=> "famous_people"
|
|
323
|
+
```
|
|
324
|
+
@method pathForType
|
|
325
|
+
@param {String} modelName
|
|
326
|
+
@return String
|
|
327
|
+
*/
|
|
328
|
+
pathForType: function (modelName) {
|
|
329
|
+
var decamelized = decamelize(modelName);
|
|
330
|
+
var underscored = underscore(decamelized);
|
|
331
|
+
return pluralize(underscored);
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
The ActiveModelAdapter overrides the `ajaxError` method
|
|
336
|
+
to return a DS.InvalidError for all 422 Unprocessable Entity
|
|
337
|
+
responses.
|
|
338
|
+
A 422 HTTP response from the server generally implies that the request
|
|
339
|
+
was well formed but the API was unable to process it because the
|
|
340
|
+
content was not semantically correct or meaningful per the API.
|
|
341
|
+
For more information on 422 HTTP Error code see 11.2 WebDAV RFC 4918
|
|
342
|
+
https://tools.ietf.org/html/rfc4918#section-11.2
|
|
343
|
+
@method ajaxError
|
|
344
|
+
@param {Object} jqXHR
|
|
345
|
+
@return error
|
|
346
|
+
*/
|
|
347
|
+
ajaxError: function (jqXHR) {
|
|
348
|
+
var error = this._super.apply(this, arguments);
|
|
349
|
+
|
|
350
|
+
if (jqXHR && jqXHR.status === 422) {
|
|
351
|
+
var response = _ember["default"].$.parseJSON(jqXHR.responseText);
|
|
352
|
+
return new InvalidError(response);
|
|
353
|
+
} else {
|
|
354
|
+
return error;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
exports["default"] = ActiveModelAdapter;
|
|
360
|
+
});
|
|
361
|
+
define('active-model-serializer', ['exports', 'ember', 'ember-data'], function (exports, _ember, _emberData) {
|
|
362
|
+
var forEach = _ember["default"].EnumerableUtils.forEach;
|
|
363
|
+
var _Ember$String = _ember["default"].String;
|
|
364
|
+
var singularize = _Ember$String.singularize;
|
|
365
|
+
var camelize = _Ember$String.camelize;
|
|
366
|
+
var classify = _Ember$String.classify;
|
|
367
|
+
var decamelize = _Ember$String.decamelize;
|
|
368
|
+
var underscore = _Ember$String.underscore;
|
|
369
|
+
var RESTSerializer = _emberData["default"].RESTSerializer;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
The ActiveModelSerializer is a subclass of the RESTSerializer designed to integrate
|
|
373
|
+
with a JSON API that uses an underscored naming convention instead of camelCasing.
|
|
374
|
+
It has been designed to work out of the box with the
|
|
375
|
+
[active\_model\_serializers](http://github.com/rails-api/active_model_serializers)
|
|
376
|
+
Ruby gem. This Serializer expects specific settings using ActiveModel::Serializers,
|
|
377
|
+
`embed :ids, embed_in_root: true` which sideloads the records.
|
|
378
|
+
|
|
379
|
+
This serializer extends the DS.RESTSerializer by making consistent
|
|
380
|
+
use of the camelization, decamelization and pluralization methods to
|
|
381
|
+
normalize the serialized JSON into a format that is compatible with
|
|
382
|
+
a conventional Rails backend and Ember Data.
|
|
383
|
+
|
|
384
|
+
## JSON Structure
|
|
385
|
+
|
|
386
|
+
The ActiveModelSerializer expects the JSON returned from your server
|
|
387
|
+
to follow the REST adapter conventions substituting underscored keys
|
|
388
|
+
for camelcased ones.
|
|
389
|
+
|
|
390
|
+
### Conventional Names
|
|
391
|
+
|
|
392
|
+
Attribute names in your JSON payload should be the underscored versions of
|
|
393
|
+
the attributes in your Ember.js models.
|
|
394
|
+
|
|
395
|
+
For example, if you have a `Person` model:
|
|
396
|
+
|
|
397
|
+
```js
|
|
398
|
+
App.FamousPerson = DS.Model.extend({
|
|
399
|
+
firstName: DS.attr('string'),
|
|
400
|
+
lastName: DS.attr('string'),
|
|
401
|
+
occupation: DS.attr('string')
|
|
402
|
+
});
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
The JSON returned should look like this:
|
|
406
|
+
|
|
407
|
+
```js
|
|
408
|
+
{
|
|
409
|
+
"famous_person": {
|
|
410
|
+
"id": 1,
|
|
411
|
+
"first_name": "Barack",
|
|
412
|
+
"last_name": "Obama",
|
|
413
|
+
"occupation": "President"
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Let's imagine that `Occupation` is just another model:
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
App.Person = DS.Model.extend({
|
|
422
|
+
firstName: DS.attr('string'),
|
|
423
|
+
lastName: DS.attr('string'),
|
|
424
|
+
occupation: DS.belongsTo('occupation')
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
App.Occupation = DS.Model.extend({
|
|
428
|
+
name: DS.attr('string'),
|
|
429
|
+
salary: DS.attr('number'),
|
|
430
|
+
people: DS.hasMany('person')
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
The JSON needed to avoid extra server calls, should look like this:
|
|
435
|
+
|
|
436
|
+
```js
|
|
437
|
+
{
|
|
438
|
+
"people": [{
|
|
439
|
+
"id": 1,
|
|
440
|
+
"first_name": "Barack",
|
|
441
|
+
"last_name": "Obama",
|
|
442
|
+
"occupation_id": 1
|
|
443
|
+
}],
|
|
444
|
+
|
|
445
|
+
"occupations": [{
|
|
446
|
+
"id": 1,
|
|
447
|
+
"name": "President",
|
|
448
|
+
"salary": 100000,
|
|
449
|
+
"person_ids": [1]
|
|
450
|
+
}]
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
@class ActiveModelSerializer
|
|
455
|
+
@namespace DS
|
|
456
|
+
@extends DS.RESTSerializer
|
|
457
|
+
*/
|
|
458
|
+
var ActiveModelSerializer = RESTSerializer.extend({
|
|
459
|
+
// SERIALIZE
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
Converts camelCased attributes to underscored when serializing.
|
|
463
|
+
@method keyForAttribute
|
|
464
|
+
@param {String} attribute
|
|
465
|
+
@return String
|
|
466
|
+
*/
|
|
467
|
+
keyForAttribute: function (attr) {
|
|
468
|
+
return decamelize(attr);
|
|
469
|
+
},
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
Underscores relationship names and appends "_id" or "_ids" when serializing
|
|
473
|
+
relationship keys.
|
|
474
|
+
@method keyForRelationship
|
|
475
|
+
@param {String} relationshipModelName
|
|
476
|
+
@param {String} kind
|
|
477
|
+
@return String
|
|
478
|
+
*/
|
|
479
|
+
keyForRelationship: function (relationshipModelName, kind) {
|
|
480
|
+
var key = decamelize(relationshipModelName);
|
|
481
|
+
if (kind === 'belongsTo') {
|
|
482
|
+
return key + '_id';
|
|
483
|
+
} else if (kind === 'hasMany') {
|
|
484
|
+
return singularize(key) + '_ids';
|
|
485
|
+
} else {
|
|
486
|
+
return key;
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
`keyForLink` can be used to define a custom key when deserializing link
|
|
492
|
+
properties. The `ActiveModelSerializer` camelizes link keys by default.
|
|
493
|
+
@method keyForLink
|
|
494
|
+
@param {String} key
|
|
495
|
+
@param {String} kind `belongsTo` or `hasMany`
|
|
496
|
+
@return {String} normalized key
|
|
497
|
+
*/
|
|
498
|
+
keyForLink: function (key, relationshipKind) {
|
|
499
|
+
return camelize(key);
|
|
500
|
+
},
|
|
501
|
+
|
|
502
|
+
/*
|
|
503
|
+
Does not serialize hasMany relationships by default.
|
|
504
|
+
*/
|
|
505
|
+
serializeHasMany: _ember["default"].K,
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
Underscores the JSON root keys when serializing.
|
|
509
|
+
@method payloadKeyFromModelName
|
|
510
|
+
@param {String} modelName
|
|
511
|
+
@return {String}
|
|
512
|
+
*/
|
|
513
|
+
payloadKeyFromModelName: function (modelName) {
|
|
514
|
+
return underscore(decamelize(modelName));
|
|
515
|
+
},
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
Serializes a polymorphic type as a fully capitalized model name.
|
|
519
|
+
@method serializePolymorphicType
|
|
520
|
+
@param {DS.Snapshot} snapshot
|
|
521
|
+
@param {Object} json
|
|
522
|
+
@param {Object} relationship
|
|
523
|
+
*/
|
|
524
|
+
serializePolymorphicType: function (snapshot, json, relationship) {
|
|
525
|
+
var key = relationship.key;
|
|
526
|
+
var belongsTo = snapshot.belongsTo(key);
|
|
527
|
+
var jsonKey = underscore(key + '_type');
|
|
528
|
+
|
|
529
|
+
if (_ember["default"].isNone(belongsTo)) {
|
|
530
|
+
json[jsonKey] = null;
|
|
531
|
+
} else {
|
|
532
|
+
json[jsonKey] = classify(belongsTo.modelName).replace(/(\/)([a-z])/g, function (match, separator, chr) {
|
|
533
|
+
return match.toUpperCase();
|
|
534
|
+
}).replace('/', '::');
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
|
|
538
|
+
// EXTRACT
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
Add extra step to `DS.RESTSerializer.normalize` so links are normalized.
|
|
542
|
+
If your payload looks like:
|
|
543
|
+
```js
|
|
544
|
+
{
|
|
545
|
+
"post": {
|
|
546
|
+
"id": 1,
|
|
547
|
+
"title": "Rails is omakase",
|
|
548
|
+
"links": { "flagged_comments": "api/comments/flagged" }
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
```
|
|
552
|
+
The normalized version would look like this
|
|
553
|
+
```js
|
|
554
|
+
{
|
|
555
|
+
"post": {
|
|
556
|
+
"id": 1,
|
|
557
|
+
"title": "Rails is omakase",
|
|
558
|
+
"links": { "flaggedComments": "api/comments/flagged" }
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
@method normalize
|
|
563
|
+
@param {subclass of DS.Model} typeClass
|
|
564
|
+
@param {Object} hash
|
|
565
|
+
@param {String} prop
|
|
566
|
+
@return Object
|
|
567
|
+
*/
|
|
568
|
+
normalize: function (typeClass, hash, prop) {
|
|
569
|
+
this.normalizeLinks(hash);
|
|
570
|
+
return this._super(typeClass, hash, prop);
|
|
571
|
+
},
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
Convert `snake_cased` links to `camelCase`
|
|
575
|
+
@method normalizeLinks
|
|
576
|
+
@param {Object} data
|
|
577
|
+
*/
|
|
578
|
+
|
|
579
|
+
normalizeLinks: function (data) {
|
|
580
|
+
if (data.links) {
|
|
581
|
+
var links = data.links;
|
|
582
|
+
|
|
583
|
+
for (var link in links) {
|
|
584
|
+
var camelizedLink = camelize(link);
|
|
585
|
+
|
|
586
|
+
if (camelizedLink !== link) {
|
|
587
|
+
links[camelizedLink] = links[link];
|
|
588
|
+
delete links[link];
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
},
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
Normalize the polymorphic type from the JSON.
|
|
596
|
+
Normalize:
|
|
597
|
+
```js
|
|
598
|
+
{
|
|
599
|
+
id: "1"
|
|
600
|
+
minion: { type: "evil_minion", id: "12"}
|
|
601
|
+
}
|
|
602
|
+
```
|
|
603
|
+
To:
|
|
604
|
+
```js
|
|
605
|
+
{
|
|
606
|
+
id: "1"
|
|
607
|
+
minion: { type: "evilMinion", id: "12"}
|
|
608
|
+
}
|
|
609
|
+
```
|
|
610
|
+
@param {Subclass of DS.Model} typeClass
|
|
611
|
+
@method normalizeRelationships
|
|
612
|
+
@private
|
|
613
|
+
*/
|
|
614
|
+
normalizeRelationships: function (typeClass, hash) {
|
|
615
|
+
|
|
616
|
+
if (this.keyForRelationship) {
|
|
617
|
+
typeClass.eachRelationship(function (key, relationship) {
|
|
618
|
+
var payloadKey, payload;
|
|
619
|
+
if (relationship.options.polymorphic) {
|
|
620
|
+
payloadKey = this.keyForAttribute(key, 'deserialize');
|
|
621
|
+
payload = hash[payloadKey];
|
|
622
|
+
if (payload && payload.type) {
|
|
623
|
+
payload.type = this.modelNameFromPayloadKey(payload.type);
|
|
624
|
+
} else if (payload && relationship.kind === 'hasMany') {
|
|
625
|
+
var self = this;
|
|
626
|
+
forEach(payload, function (single) {
|
|
627
|
+
single.type = self.modelNameFromPayloadKey(single.type);
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
} else {
|
|
631
|
+
payloadKey = this.keyForRelationship(key, relationship.kind, 'deserialize');
|
|
632
|
+
if (!hash.hasOwnProperty(payloadKey)) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
payload = hash[payloadKey];
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
hash[key] = payload;
|
|
639
|
+
|
|
640
|
+
if (key !== payloadKey) {
|
|
641
|
+
delete hash[payloadKey];
|
|
642
|
+
}
|
|
643
|
+
}, this);
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
modelNameFromPayloadKey: function (key) {
|
|
647
|
+
var convertedFromRubyModule = camelize(singularize(key)).replace(/(^|\:)([A-Z])/g, function (match, separator, chr) {
|
|
648
|
+
return match.toLowerCase();
|
|
649
|
+
}).replace('::', '/');
|
|
650
|
+
return this._super(convertedFromRubyModule);
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
exports["default"] = ActiveModelSerializer;
|
|
655
|
+
});
|
|
656
|
+
/**
|
|
657
|
+
@module active-model-adapter
|
|
658
|
+
*/
|
|
659
|
+
define('index', ['exports', './active-model-adapter', './active-model-serializer'], function (exports, _activeModelAdapter, _activeModelSerializer) {
|
|
660
|
+
exports["default"] = _activeModelAdapter["default"];
|
|
661
|
+
exports.ActiveModelAdapter = _activeModelAdapter["default"];
|
|
662
|
+
exports.ActiveModelSerializer = _activeModelSerializer["default"];
|
|
663
|
+
});
|
|
664
|
+
define("initializers/active-model-adapter", ["exports", "active-model-adapter", "active-model-serializer"], function (exports, _activeModelAdapter, _activeModelAdapterActiveModelSerializer) {
|
|
665
|
+
exports["default"] = {
|
|
666
|
+
name: "active-model-adapter",
|
|
667
|
+
initialize: function (registry, application) {
|
|
668
|
+
registry.register("adapter:-active-model", _activeModelAdapter["default"]);
|
|
669
|
+
registry.register("serializer:-active-model", _activeModelAdapterActiveModelSerializer["default"]);
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
});
|
|
673
|
+
define('instance-initializers/active-model-adapter', ['exports', 'active-model-adapter', 'active-model-serializer'], function (exports, _activeModelAdapter, _activeModelAdapterActiveModelSerializer) {
|
|
674
|
+
exports["default"] = {
|
|
675
|
+
name: 'active-model-adapter',
|
|
676
|
+
initialize: function (applicationOrRegistry) {
|
|
677
|
+
var registry, container;
|
|
678
|
+
if (applicationOrRegistry.registry && applicationOrRegistry.container) {
|
|
679
|
+
// initializeStoreService was registered with an
|
|
680
|
+
// instanceInitializer. The first argument is the application
|
|
681
|
+
// instance.
|
|
682
|
+
registry = applicationOrRegistry.registry;
|
|
683
|
+
container = applicationOrRegistry.container;
|
|
684
|
+
} else {
|
|
685
|
+
// initializeStoreService was called by an initializer instead of
|
|
686
|
+
// an instanceInitializer. The first argument is a registy. This
|
|
687
|
+
// case allows ED to support Ember pre 1.12
|
|
688
|
+
registry = applicationOrRegistry;
|
|
689
|
+
if (registry.container) {
|
|
690
|
+
// Support Ember 1.10 - 1.11
|
|
691
|
+
container = registry.container();
|
|
692
|
+
} else {
|
|
693
|
+
// Support Ember 1.9
|
|
694
|
+
container = registry;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
registry.register('adapter:-active-model', _activeModelAdapter["default"]);
|
|
699
|
+
registry.register('serializer:-active-model', _activeModelAdapterActiveModelSerializer["default"]);
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
});
|
|
703
|
+
define('globals', ['exports', './index', 'instance-initializers/active-model-adapter', 'initializers/active-model-adapter', 'ember', 'ember-data'], function (exports, _index, _instanceInitializersActiveModelAdapter, _initializersActiveModelAdapter, _ember, _emberData) {
|
|
704
|
+
|
|
705
|
+
_emberData["default"].ActiveModelAdapter = _index.ActiveModelAdapter;
|
|
706
|
+
_emberData["default"].ActiveModelSerializer = _index.ActiveModelSerializer;
|
|
707
|
+
|
|
708
|
+
if (_ember["default"].Application.instanceInitializer) {
|
|
709
|
+
_ember["default"].Application.instanceInitializer(_instanceInitializersActiveModelAdapter["default"]);
|
|
710
|
+
} else {
|
|
711
|
+
_ember["default"].Application.initializer(_initializersActiveModelAdapter["default"]);
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
// this file is used to generate the globals build.
|
|
715
|
+
// DO NOT try to use this in your app.
|
|
716
|
+
|
|
717
|
+
require("globals");
|
|
718
|
+
})();
|
data/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "active-model-adapter",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"repository": "https://github.com/ember-data/active-model-adapter.git",
|
|
5
|
+
"description": "The default blueprint for ember-cli addons.",
|
|
6
|
+
"directories": {
|
|
7
|
+
"doc": "doc",
|
|
8
|
+
"test": "tests"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "ember server",
|
|
12
|
+
"build": "ember build",
|
|
13
|
+
"test": "ember try:testall"
|
|
14
|
+
},
|
|
15
|
+
"repository": "",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">= 0.10.0"
|
|
18
|
+
},
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"broccoli-asset-rev": "^2.0.2",
|
|
23
|
+
"broccoli-babel-transpiler": "^5.1.1",
|
|
24
|
+
"broccoli-concat": "0.0.13",
|
|
25
|
+
"broccoli-es3-safe-recast": "^2.0.0",
|
|
26
|
+
"broccoli-funnel": "^0.2.3",
|
|
27
|
+
"broccoli-merge-trees": "^0.2.1",
|
|
28
|
+
"broccoli-stew": "^0.3.2",
|
|
29
|
+
"ember-cli": "0.2.7",
|
|
30
|
+
"ember-cli-app-version": "0.3.3",
|
|
31
|
+
"ember-cli-content-security-policy": "0.4.0",
|
|
32
|
+
"ember-cli-dependency-checker": "^1.0.0",
|
|
33
|
+
"ember-cli-htmlbars": "0.7.6",
|
|
34
|
+
"ember-cli-ic-ajax": "0.1.1",
|
|
35
|
+
"ember-cli-inject-live-reload": "^1.3.0",
|
|
36
|
+
"ember-cli-qunit": "0.3.13",
|
|
37
|
+
"ember-cli-uglify": "^1.0.1",
|
|
38
|
+
"ember-data": "1.0.0-beta.18",
|
|
39
|
+
"ember-disable-prototype-extensions": "^1.0.0",
|
|
40
|
+
"ember-disable-proxy-controllers": "^1.0.0",
|
|
41
|
+
"ember-export-application-global": "^1.0.2",
|
|
42
|
+
"ember-try": "0.0.6",
|
|
43
|
+
"broccoli-replace": "^0.3.1"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"ember-addon"
|
|
47
|
+
],
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"ember-cli-babel": "^5.0.0"
|
|
50
|
+
},
|
|
51
|
+
"ember-addon": {
|
|
52
|
+
"configPath": "tests/dummy/config"
|
|
53
|
+
}
|
|
54
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: active-model-adapter-source
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Igor Terzic
|
|
8
|
+
- Yehuda Katz
|
|
9
|
+
- Tom Dale
|
|
10
|
+
autorequire:
|
|
11
|
+
bindir: bin
|
|
12
|
+
cert_chain: []
|
|
13
|
+
date: 2015-06-14 00:00:00.000000000 Z
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: ember-source
|
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '1.8'
|
|
22
|
+
- - <
|
|
23
|
+
- !ruby/object:Gem::Version
|
|
24
|
+
version: '3.0'
|
|
25
|
+
type: :runtime
|
|
26
|
+
prerelease: false
|
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
28
|
+
requirements:
|
|
29
|
+
- - ! '>='
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '1.8'
|
|
32
|
+
- - <
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '3.0'
|
|
35
|
+
description: ember-data active-model-adapter code wrapper for use with Ruby libs.
|
|
36
|
+
email:
|
|
37
|
+
- wycats@gmail.com
|
|
38
|
+
executables: []
|
|
39
|
+
extensions: []
|
|
40
|
+
extra_rdoc_files: []
|
|
41
|
+
files:
|
|
42
|
+
- dist/active-model-adapter.js
|
|
43
|
+
- package.json
|
|
44
|
+
homepage: https://github.com/ember-data/active-model-adapter
|
|
45
|
+
licenses:
|
|
46
|
+
- MIT
|
|
47
|
+
metadata: {}
|
|
48
|
+
post_install_message:
|
|
49
|
+
rdoc_options: []
|
|
50
|
+
require_paths:
|
|
51
|
+
- lib
|
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ! '>='
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0'
|
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
requirements: []
|
|
63
|
+
rubyforge_project:
|
|
64
|
+
rubygems_version: 2.4.5
|
|
65
|
+
signing_key:
|
|
66
|
+
specification_version: 4
|
|
67
|
+
summary: active-model-adapter source code wrapper.
|
|
68
|
+
test_files: []
|