ende 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/component.json +4 -2
  3. data/ende.gemspec +1 -0
  4. data/lib/assets/javascripts/aura/extensions/devise.js.coffee +94 -15
  5. data/lib/assets/javascripts/aura/extensions/routes.js.coffee +21 -0
  6. data/lib/assets/javascripts/aura/extensions/states.js.coffee +3 -1
  7. data/lib/assets/javascripts/aura/extensions/widget/eventable.js.coffee +19 -21
  8. data/lib/assets/javascripts/aura/extensions/widget/lifecycleable.js.coffee +17 -1
  9. data/lib/assets/javascripts/config/initializers/jquery.js.coffee +4 -3
  10. data/lib/assets/javascripts/config/initializers/load_components.js.coffee +19 -0
  11. data/lib/assets/javascripts/ende.js.coffee +3 -1
  12. data/lib/assets/javascripts/widgets/authenticator/main.js.coffee +3 -3
  13. data/lib/assets/javascripts/widgets/viewer/main.js.coffee +189 -120
  14. data/lib/ende/users_controller_extensions.rb +14 -0
  15. data/lib/ende/version.rb +1 -1
  16. data/lib/ende.rb +5 -0
  17. data/vendor/assets/components/KapIT-observe-utils/component.json +16 -0
  18. data/vendor/assets/components/KapIT-observe-utils/lib/observe-utils.js +780 -0
  19. data/vendor/assets/components/chaijs-assertion-error/component.json +18 -0
  20. data/vendor/assets/components/chaijs-assertion-error/index.js +110 -0
  21. data/vendor/assets/components/chaijs-chai/component.json +47 -0
  22. data/vendor/assets/components/chaijs-chai/index.js +1 -0
  23. data/vendor/assets/components/chaijs-chai/lib/chai/assertion.js +130 -0
  24. data/vendor/assets/components/chaijs-chai/lib/chai/core/assertions.js +1270 -0
  25. data/vendor/assets/components/chaijs-chai/lib/chai/interface/assert.js +1080 -0
  26. data/vendor/assets/components/chaijs-chai/lib/chai/interface/expect.js +12 -0
  27. data/vendor/assets/components/chaijs-chai/lib/chai/interface/should.js +76 -0
  28. data/vendor/assets/components/chaijs-chai/lib/chai/utils/addChainableMethod.js +94 -0
  29. data/vendor/assets/components/chaijs-chai/lib/chai/utils/addMethod.js +37 -0
  30. data/vendor/assets/components/chaijs-chai/lib/chai/utils/addProperty.js +40 -0
  31. data/vendor/assets/components/chaijs-chai/lib/chai/utils/flag.js +32 -0
  32. data/vendor/assets/components/chaijs-chai/lib/chai/utils/getActual.js +19 -0
  33. data/vendor/assets/components/chaijs-chai/lib/chai/utils/getEnumerableProperties.js +25 -0
  34. data/vendor/assets/components/chaijs-chai/lib/chai/utils/getMessage.js +49 -0
  35. data/vendor/assets/components/chaijs-chai/lib/chai/utils/getName.js +20 -0
  36. data/vendor/assets/components/chaijs-chai/lib/chai/utils/getPathValue.js +102 -0
  37. data/vendor/assets/components/chaijs-chai/lib/chai/utils/getProperties.js +35 -0
  38. data/vendor/assets/components/chaijs-chai/lib/chai/utils/index.js +108 -0
  39. data/vendor/assets/components/chaijs-chai/lib/chai/utils/inspect.js +320 -0
  40. data/vendor/assets/components/chaijs-chai/lib/chai/utils/objDisplay.js +48 -0
  41. data/vendor/assets/components/chaijs-chai/lib/chai/utils/overwriteMethod.js +51 -0
  42. data/vendor/assets/components/chaijs-chai/lib/chai/utils/overwriteProperty.js +54 -0
  43. data/vendor/assets/components/chaijs-chai/lib/chai/utils/test.js +26 -0
  44. data/vendor/assets/components/chaijs-chai/lib/chai/utils/transferFlags.js +44 -0
  45. data/vendor/assets/components/chaijs-chai/lib/chai/utils/type.js +45 -0
  46. data/vendor/assets/components/chaijs-chai/lib/chai.js +80 -0
  47. data/vendor/assets/components/chaijs-deep-eql/component.json +18 -0
  48. data/vendor/assets/components/chaijs-deep-eql/lib/eql.js +257 -0
  49. data/vendor/assets/components/chaijs-type-detect/component.json +16 -0
  50. data/vendor/assets/components/chaijs-type-detect/lib/type.js +142 -0
  51. data/vendor/assets/components/component-bind/component.json +14 -0
  52. data/vendor/assets/components/component-bind/index.js +24 -0
  53. data/vendor/assets/components/component-delegate/component.json +19 -0
  54. data/vendor/assets/components/component-delegate/index.js +42 -0
  55. data/vendor/assets/components/component-event/component.json +13 -0
  56. data/vendor/assets/components/component-event/index.js +40 -0
  57. data/vendor/assets/components/component-jquery/component.json +14 -0
  58. data/vendor/assets/components/component-jquery/index.js +9601 -0
  59. data/vendor/assets/components/component-link-delegate/component.json +23 -0
  60. data/vendor/assets/components/component-link-delegate/index.js +60 -0
  61. data/vendor/assets/components/component-matches-selector/component.json +20 -0
  62. data/vendor/assets/components/component-matches-selector/index.js +45 -0
  63. data/vendor/assets/components/component-query/component.json +21 -0
  64. data/vendor/assets/components/component-query/index.js +21 -0
  65. data/vendor/assets/components/component-type/component.json +18 -0
  66. data/vendor/assets/components/component-type/index.js +32 -0
  67. data/vendor/assets/components/component-url/component.json +17 -0
  68. data/vendor/assets/components/component-url/index.js +63 -0
  69. data/vendor/assets/components/discore-closest/component.json +14 -0
  70. data/vendor/assets/components/discore-closest/index.js +18 -0
  71. data/vendor/assets/components/indefinido-advisable/component.json +21 -0
  72. data/vendor/assets/components/indefinido-advisable/index.js +1 -0
  73. data/vendor/assets/components/indefinido-advisable/lib/advisable.js +60 -0
  74. data/vendor/assets/components/indefinido-indemma/component.json +40 -0
  75. data/vendor/assets/components/indefinido-indemma/index.js +1 -0
  76. data/vendor/assets/components/indefinido-indemma/lib/extensions/rivets.js +23 -0
  77. data/vendor/assets/components/indefinido-indemma/lib/record/associable.js +217 -0
  78. data/vendor/assets/components/indefinido-indemma/lib/record/maid.js +24 -0
  79. data/vendor/assets/components/indefinido-indemma/lib/record/resource.js +104 -0
  80. data/vendor/assets/components/indefinido-indemma/lib/record/rest.js +36 -0
  81. data/vendor/assets/components/indefinido-indemma/lib/record/restfulable.js +326 -0
  82. data/vendor/assets/components/indefinido-indemma/lib/record/scopable.js +279 -0
  83. data/vendor/assets/components/indefinido-indemma/lib/record/translationable.js +19 -0
  84. data/vendor/assets/components/indefinido-indemma/lib/record/validatable.js +216 -0
  85. data/vendor/assets/components/indefinido-indemma/lib/record/validations/associated.js +30 -0
  86. data/vendor/assets/components/indefinido-indemma/lib/record/validations/confirmation.js +19 -0
  87. data/vendor/assets/components/indefinido-indemma/lib/record/validations/cpf.js +60 -0
  88. data/vendor/assets/components/indefinido-indemma/lib/record/validations/presence.js +19 -0
  89. data/vendor/assets/components/indefinido-indemma/lib/record/validations/remote.js +71 -0
  90. data/vendor/assets/components/indefinido-indemma/lib/record.js +167 -0
  91. data/vendor/assets/components/indefinido-indemma/vendor/sinon.js +4290 -0
  92. data/vendor/assets/components/indefinido-indemma/vendor/stampit.js +392 -0
  93. data/vendor/assets/components/indefinido-observable/component.json +25 -0
  94. data/vendor/assets/components/indefinido-observable/components/cjohansen-sinon/sinon.js +4290 -0
  95. data/vendor/assets/components/indefinido-observable/index.js +1 -0
  96. data/vendor/assets/components/indefinido-observable/lib/adapters/rivets.js +26 -0
  97. data/vendor/assets/components/indefinido-observable/lib/observable.js +320 -0
  98. data/vendor/assets/components/indefinido-observable/vendor/shims/accessors-legacy.js +92 -0
  99. data/vendor/assets/components/indefinido-observable/vendor/shims/accessors.js +173 -0
  100. data/vendor/assets/components/indefinido-observable/vendor/shims/array.indexOf.js +8 -0
  101. data/vendor/assets/components/indefinido-observable/vendor/shims/object.create.js +77 -0
  102. data/vendor/assets/components/mikeric-rivets/component.json +15 -0
  103. data/vendor/assets/components/mikeric-rivets/dist/rivets.js +1020 -0
  104. data/vendor/assets/components/paulmillr-es6-shim/component.json +17 -0
  105. data/vendor/assets/components/paulmillr-es6-shim/es6-shim.js +985 -0
  106. data/vendor/assets/components/pluma-assimilate/component.json +25 -0
  107. data/vendor/assets/components/pluma-assimilate/dist/assimilate.js +87 -0
  108. data/vendor/assets/components/segmentio-extend/component.json +13 -0
  109. data/vendor/assets/components/segmentio-extend/index.js +15 -0
  110. data/vendor/assets/javascripts/ende/build.js +30346 -0
  111. data/vendor/assets/javascripts/jquery/inview.js +125 -0
  112. data/vendor/assets/javascripts/lennon/lennon.js +184 -0
  113. metadata +114 -3
  114. data/lib/tasks/sprite.thor +0 -62
@@ -0,0 +1,217 @@
1
+ var $, associable, model, plural, root, singular,
2
+ __slice = [].slice;
3
+
4
+ root = window;
5
+
6
+ $ = require('jquery');
7
+
8
+ require('./resource');
9
+
10
+ plural = {
11
+ add: function() {
12
+ var attributes, params, _i, _len, _results;
13
+
14
+ params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
15
+ _results = [];
16
+ for (_i = 0, _len = params.length; _i < _len; _i++) {
17
+ attributes = params[_i];
18
+ _results.push(this.push(this.build(attributes)));
19
+ }
20
+ return _results;
21
+ },
22
+ create: function() {
23
+ var attributes, params, record, _i, _len, _results;
24
+
25
+ params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
26
+ _results = [];
27
+ for (_i = 0, _len = params.length; _i < _len; _i++) {
28
+ attributes = params[_i];
29
+ record = this.build(attributes);
30
+ this.push(record);
31
+ _results.push(record.save());
32
+ }
33
+ return _results;
34
+ },
35
+ build: function(data) {
36
+ var _name;
37
+
38
+ if (data == null) {
39
+ data = {};
40
+ }
41
+ data.parent_resource = this.parent_resource;
42
+ if (this.parent != null) {
43
+ data.route || (data.route = "" + this.parent.route + "/" + this.parent._id + "/" + (model.pluralize(this.resource.toString())));
44
+ }
45
+ if (this.route !== data.route && this.route) {
46
+ throw "associable.has_many: cannot redefine route of association " + this.parent_resource + "." + this.resource + " from " + this.route + " to " + data.route;
47
+ }
48
+ data[_name = this.parent_resource] || (data[_name] = this.parent);
49
+ return model[model.singularize(this.resource)](data);
50
+ },
51
+ push: Array.prototype.push,
52
+ length: 0,
53
+ json: function() {
54
+ var record, _i, _len, _results;
55
+
56
+ _results = [];
57
+ for (_i = 0, _len = this.length; _i < _len; _i++) {
58
+ record = this[_i];
59
+ _results.push(record.json());
60
+ }
61
+ return _results;
62
+ }
63
+ };
64
+
65
+ singular = {
66
+ create: function(data) {
67
+ return model[this.resource].create($.extend({}, this, data));
68
+ },
69
+ build: function(data) {
70
+ return this[this.parent_resource][this.resource] = model[this.resource]($.extend({}, this, data));
71
+ }
72
+ };
73
+
74
+ associable = {
75
+ model: function(options) {
76
+ var callbacks;
77
+
78
+ if (this.resource == null) {
79
+ console.error('resource must be defined in order to associate');
80
+ }
81
+ callbacks = {
82
+ has_many: {
83
+ nest_attributes: function() {
84
+ var association, association_name, association_names, associations_attributes, message, _i, _len, _results;
85
+
86
+ association_names = model[this.resource].has_many;
87
+ if (association_names) {
88
+ _results = [];
89
+ for (_i = 0, _len = association_names.length; _i < _len; _i++) {
90
+ association_name = association_names[_i];
91
+ associations_attributes = this["" + association_name + "_attributes"];
92
+ if (associations_attributes && associations_attributes.length) {
93
+ association = this[model.pluralize(association_name)];
94
+ if (!association) {
95
+ message = "has_many.nest_attributes: Association not found for " + association_name + ". \n";
96
+ message += "did you set it on model declaration? \n has_many: " + association_name + " ";
97
+ throw message;
98
+ }
99
+ association.resource = model.singularize(association.resource);
100
+ association.add.apply(association, associations_attributes);
101
+ _results.push(association.resource = model.pluralize(association.resource));
102
+ } else {
103
+ _results.push(void 0);
104
+ }
105
+ }
106
+ return _results;
107
+ }
108
+ },
109
+ update_association: function(data) {
110
+ var associated, association, association_name, id, pluralized_association, _i, _j, _len, _len1, _ref;
111
+
112
+ id = this._id || data._id || data.id;
113
+ if (!id) {
114
+ return;
115
+ }
116
+ _ref = model[this.resource].has_many;
117
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
118
+ association_name = _ref[_i];
119
+ pluralized_association = model.pluralize(association_name);
120
+ association = this[pluralized_association];
121
+ if (!association.route) {
122
+ association.route = "/" + (model.pluralize(this.resource)) + "/" + id + "/" + (model.pluralize(association.resource));
123
+ for (_j = 0, _len1 = association.length; _j < _len1; _j++) {
124
+ associated = association[_j];
125
+ if (!associated.route && (associated.parent != null)) {
126
+ associated.route = "/" + (model.pluralize(this.resource)) + "/" + id + "/" + (model.pluralize(association.resource));
127
+ }
128
+ }
129
+ }
130
+ }
131
+ return true;
132
+ },
133
+ autosave: function() {
134
+ return this.save();
135
+ }
136
+ }
137
+ };
138
+ if (this.has_many && $.type(this.has_many) !== 'array') {
139
+ this.has_many = [this.has_many];
140
+ }
141
+ if (this.has_one && $.type(this.has_one) !== 'array') {
142
+ this.has_one = [this.has_one];
143
+ }
144
+ if (this.belongs_to && $.type(this.belongs_to) !== 'array') {
145
+ this.belongs_to = [this.belongs_to];
146
+ }
147
+ this.has_many || (this.has_many = []);
148
+ this.has_one || (this.has_one = []);
149
+ this.belongs_to || (this.belongs_to = []);
150
+ return this.create_associations = function() {
151
+ var association_name, association_proxy, resource, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;
152
+
153
+ if (options.has_many) {
154
+ _ref = options.has_many;
155
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
156
+ resource = _ref[_i];
157
+ association_proxy = {
158
+ resource: resource,
159
+ parent_resource: this.resource,
160
+ parent: this
161
+ };
162
+ association_name = model.pluralize(resource);
163
+ this[association_name] = $.extend(association_proxy, plural);
164
+ }
165
+ this.after('saved', callbacks.has_many.update_association);
166
+ callbacks.has_many.nest_attributes.call(this);
167
+ }
168
+ if (options.has_one) {
169
+ _ref1 = options.has_one;
170
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
171
+ resource = _ref1[_j];
172
+ association_proxy = {
173
+ resource: resource,
174
+ parent_resource: this.resource
175
+ };
176
+ association_proxy[this.resource] = this;
177
+ this["build_" + resource] = $.proxy(singular.build, association_proxy);
178
+ this["create_" + resource] = $.proxy(singular.create, association_proxy);
179
+ }
180
+ }
181
+ if (options.belongs_to) {
182
+ _ref2 = options.belongs_to;
183
+ _results = [];
184
+ for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
185
+ resource = _ref2[_k];
186
+ association_proxy = {
187
+ resource: resource,
188
+ parent_resource: this.resource
189
+ };
190
+ association_proxy[this.resource] = this;
191
+ this["build_" + resource] = $.proxy(singular.build, association_proxy);
192
+ _results.push(this["create_" + resource] = $.proxy(singular.create, association_proxy));
193
+ }
194
+ return _results;
195
+ }
196
+ };
197
+ },
198
+ record: function(options) {
199
+ if (this.resource == null) {
200
+ console.error('resource must be defined in order to associate');
201
+ }
202
+ return model[this.resource.name || this.resource.toString()].create_associations.call(this);
203
+ }
204
+ };
205
+
206
+ model = root.model;
207
+
208
+ model.mix(function(modelable) {
209
+ modelable.after_mix.push(associable.model);
210
+ return modelable.record.after_initialize.push(associable.record);
211
+ });
212
+
213
+ model.associable = {
214
+ mix: function(blender) {
215
+ return blender(singular, plural);
216
+ }
217
+ };
@@ -0,0 +1,24 @@
1
+ var maid, model;
2
+
3
+ maid = {
4
+ model: function() {
5
+ if (this.washing != null) {
6
+ return this.record.after_initialize.push(maid.record);
7
+ }
8
+ },
9
+ record: function() {
10
+ return this.subscribe('dirty', function(dirty) {
11
+ var _this = this;
12
+
13
+ return dirty && setTimeout(function() {
14
+ return _this.save();
15
+ }, 500);
16
+ });
17
+ }
18
+ };
19
+
20
+ model = window.model;
21
+
22
+ model.mix(function(modelable) {
23
+ return modelable.after_mix.unshift(maid.model);
24
+ });
@@ -0,0 +1,104 @@
1
+ var model, resource, resourceable, stampit;
2
+
3
+ stampit = require('../../vendor/stampit');
4
+
5
+ resource = stampit({
6
+ toString: function() {
7
+ return this.name;
8
+ }
9
+ }, {
10
+ name: 'unknown',
11
+ scope: null,
12
+ singular: false
13
+ }, function() {
14
+ this.param_name || (this.param_name = this.name);
15
+ return this;
16
+ });
17
+
18
+ resourceable = {
19
+ pluralize: function(word) {
20
+ if (!(word && word.length)) {
21
+ throw new TypeError("Invalid string passed to pluralize '" + word + "'");
22
+ }
23
+ if (word.indexOf('s') !== word.length - 1) {
24
+ return word + 's';
25
+ } else {
26
+ return word;
27
+ }
28
+ },
29
+ singularize: function(word) {
30
+ if (!(word && word.length)) {
31
+ throw new TypeError("Invalid string passed to singularize '" + word + "'");
32
+ }
33
+ if (word.indexOf('s') === word.length - 1) {
34
+ return word.substring(0, word.length - 1);
35
+ } else {
36
+ return word;
37
+ }
38
+ },
39
+ route: {
40
+ get: function() {
41
+ var route;
42
+
43
+ if (this.initial_route != null) {
44
+ return this.initial_route;
45
+ }
46
+ if (typeof this.resource === 'string') {
47
+ this.resource = {
48
+ name: this.resource
49
+ };
50
+ }
51
+ route = '/';
52
+ if (this.parent != null) {
53
+ route += "" + this.parent.route + "/" + this.parent._id + "/";
54
+ }
55
+ if (this.resource.scope != null) {
56
+ route += this.resource.scope + '/';
57
+ }
58
+ route += this.resource.singular ? this.resource.name : model.pluralize(this.resource.name);
59
+ this.initial_route = route;
60
+ return route;
61
+ },
62
+ set: function(value) {
63
+ return this.initial_route = value;
64
+ }
65
+ },
66
+ parent_id: {
67
+ get: function() {
68
+ return this[this.parent_resource]._id;
69
+ },
70
+ set: function() {
71
+ return console.error('Warning changing associations throught parent_id not allowed for security and style guide purposes');
72
+ }
73
+ },
74
+ initialize: function() {
75
+ var resource_definition, _ref;
76
+
77
+ if (this.parent_resource) {
78
+ Object.defineProperty(this, "" + this.parent_resource + "_id", resourceable.parent_id);
79
+ }
80
+ resource_definition = {};
81
+ if (typeof this.resource === 'string') {
82
+ resource_definition = {
83
+ name: this.resource
84
+ };
85
+ }
86
+ if (typeof this.resource === 'object') {
87
+ resource_definition = this.resource;
88
+ }
89
+ resource_definition.parent = this.parent_resource;
90
+ this.resource = resource(resource_definition);
91
+ return (_ref = this.route) != null ? _ref : Object.defineProperty(this, 'route', resourceable.route);
92
+ }
93
+ };
94
+
95
+ model = window.model;
96
+
97
+ model.mix(function(modelable) {
98
+ modelable.record.after_initialize.unshift(resourceable.initialize);
99
+ return modelable.after_mix.unshift(resourceable.initialize);
100
+ });
101
+
102
+ model.singularize = resourceable.singularize;
103
+
104
+ model.pluralize = resourceable.pluralize;
@@ -0,0 +1,36 @@
1
+ var $, request;
2
+
3
+ $ = require('jquery');
4
+
5
+ module.exports = {
6
+ get: function(data) {
7
+ return request.call(this, 'get', (this._id ? "" + this.route + "/" + this._id : this.route), data);
8
+ },
9
+ put: function(data) {
10
+ return request.call(this, 'put', "" + this.route + "/" + this._id, data);
11
+ },
12
+ post: function(data) {
13
+ return request.call(this, 'post', this.route, data);
14
+ }
15
+ };
16
+
17
+ request = function(method, url, data) {
18
+ var param_name;
19
+
20
+ param_name = this.resource.param_name || this.resource.toString();
21
+ if (!data && this.json) {
22
+ data = {};
23
+ data[param_name] = this.json();
24
+ }
25
+ if (data[param_name]) {
26
+ delete data[param_name]._id;
27
+ delete data[param_name].id;
28
+ }
29
+ return $.ajax({
30
+ url: url,
31
+ data: data,
32
+ type: method,
33
+ dataType: 'json',
34
+ context: this
35
+ });
36
+ };
@@ -0,0 +1,326 @@
1
+ var $, merge, model, observable, record, rest, restful, type, util,
2
+ __slice = [].slice;
3
+
4
+ merge = require('assimilate').withStrategy('deep');
5
+
6
+ type = require('type');
7
+
8
+ observable = require('observable').mixin;
9
+
10
+ $ = require('jquery');
11
+
12
+ rest = require('./rest.js');
13
+
14
+ util = {
15
+ model: {
16
+ map: function(models) {
17
+ var model, _i, _len, _results;
18
+
19
+ _results = [];
20
+ for (_i = 0, _len = models.length; _i < _len; _i++) {
21
+ model = models[_i];
22
+ _results.push(this(model));
23
+ }
24
+ return _results;
25
+ }
26
+ }
27
+ };
28
+
29
+ restful = {
30
+ model: {
31
+ create: function() {
32
+ var attributes, callback, params, record, _i, _j, _len, _results;
33
+
34
+ params = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), callback = arguments[_i++];
35
+ if (!arguments.length) {
36
+ throw new TypeError("No arguments provided for " + this.resource + ".create");
37
+ }
38
+ if (typeof callback !== 'function') {
39
+ params.push(callback);
40
+ }
41
+ if (!params.length) {
42
+ params.unshift({});
43
+ }
44
+ _results = [];
45
+ for (_j = 0, _len = params.length; _j < _len; _j++) {
46
+ attributes = params[_j];
47
+ record = this(attributes);
48
+ record.dirty = true;
49
+ _results.push(record.save(callback));
50
+ }
51
+ return _results;
52
+ },
53
+ all: function(conditions, callback) {
54
+ if (conditions == null) {
55
+ conditions = {};
56
+ }
57
+ if (typeof conditions === 'function') {
58
+ callback = conditions;
59
+ conditions = {};
60
+ }
61
+ return $.when(rest.get.call(this, conditions)).then(util.model.map).done(callback);
62
+ },
63
+ first: function(conditions, callback) {
64
+ var namespaced;
65
+
66
+ if (conditions == null) {
67
+ conditions = {};
68
+ }
69
+ if (typeof conditions === 'function') {
70
+ callback = conditions;
71
+ conditions = {};
72
+ }
73
+ namespaced = conditions[this.resource] || {};
74
+ namespaced.limit = 1;
75
+ namespaced.order = 'desc';
76
+ return this.all(conditions, callback);
77
+ },
78
+ get: function(action, data) {
79
+ var old_route, payload, promise, resource, route;
80
+
81
+ old_route = this.route;
82
+ this.route = "/" + (model.pluralize(this.resource.name)) + "/" + action;
83
+ resource = data.resource;
84
+ if (data && data.json) {
85
+ data = data.json();
86
+ }
87
+ if (resource != null) {
88
+ payload = data;
89
+ data = {};
90
+ data[resource] = payload;
91
+ }
92
+ promise = rest.get.call(this, data);
93
+ route = old_route;
94
+ return promise;
95
+ }
96
+ },
97
+ record: {
98
+ reload: function() {
99
+ var argument, promise, _i, _len;
100
+
101
+ promise = rest.get.call(this);
102
+ promise.done(this.assign_attributes);
103
+ promise.fail(this.failed);
104
+ for (_i = 0, _len = arguments.length; _i < _len; _i++) {
105
+ argument = arguments[_i];
106
+ if (type(argument) === 'function') {
107
+ promise.done(argument);
108
+ }
109
+ }
110
+ return promise;
111
+ },
112
+ assign_attributes: function(attributes) {
113
+ var association, association_attributes, association_name, associations_attributes, attribute, message, singular_resource, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _results;
114
+
115
+ _ref = model[this.resource.toString()].has_many;
116
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
117
+ association_name = _ref[_i];
118
+ associations_attributes = attributes[association_name];
119
+ delete attributes[association_name];
120
+ association = this[association_name];
121
+ if (association == null) {
122
+ message = "Association '" + association_name + "' not found. \n";
123
+ message += "For record with resource " + this.resource + ". \n";
124
+ message += "Probably defined on server side but not on client side.\n";
125
+ message += "Skipping association assignment!";
126
+ console.warn(message);
127
+ continue;
128
+ }
129
+ if (association.length) {
130
+ Array.prototype.splice.call(association, 0);
131
+ }
132
+ if (!((associations_attributes != null) && associations_attributes.length)) {
133
+ continue;
134
+ }
135
+ singular_resource = model.singularize(association_name);
136
+ for (_j = 0, _len1 = associations_attributes.length; _j < _len1; _j++) {
137
+ association_attributes = associations_attributes[_j];
138
+ _ref1 = model[singular_resource].has_many;
139
+ for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
140
+ association_name = _ref1[_k];
141
+ association_attributes["" + association_name + "_attributes"] = association_attributes[association_name];
142
+ delete association_attributes[association_name];
143
+ }
144
+ }
145
+ association.add.apply(association, associations_attributes);
146
+ }
147
+ _ref2 = model[this.resource.toString()].has_one;
148
+ for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {
149
+ association_name = _ref2[_l];
150
+ association_attributes = attributes[association_name];
151
+ delete attributes[association_name];
152
+ if (association_attributes) {
153
+ this[association_name] = this["build_" + association_name](association_attributes);
154
+ }
155
+ }
156
+ _results = [];
157
+ for (attribute in attributes) {
158
+ _results.push(this[attribute] = attributes[attribute]);
159
+ }
160
+ return _results;
161
+ },
162
+ save: function(doned, failed, data) {
163
+ var promise;
164
+
165
+ if (!this.dirty) {
166
+ return $.Deferred().resolve();
167
+ }
168
+ promise = rest[this._id ? 'put' : 'post'].call(this, data);
169
+ promise.done(this.saved);
170
+ promise.fail(this.failed);
171
+ promise.done(doned);
172
+ promise.fail(failed);
173
+ this.lock = JSON.stringify(this.json());
174
+ return promise;
175
+ },
176
+ saved: function(data) {
177
+ var callback, _i, _len, _ref, _results;
178
+
179
+ if (this.lock === JSON.stringify(this.json())) {
180
+ this.dirty = false;
181
+ delete this.lock;
182
+ } else {
183
+ return this.save();
184
+ }
185
+ if (data != null) {
186
+ this.assign_attributes(data);
187
+ }
188
+ if (this.after_save) {
189
+ _ref = this.after_save;
190
+ _results = [];
191
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
192
+ callback = _ref[_i];
193
+ throw "Not supported after_save callback: " + callback;
194
+ }
195
+ return _results;
196
+ }
197
+ },
198
+ failed: function(xhr, error, status) {
199
+ var attribute_name, definition, e, message, messages, payload, _ref, _results;
200
+
201
+ payload = xhr.responseJSON;
202
+ try {
203
+ payload || (payload = JSON.parse(xhr.responseText));
204
+ } catch (_error) {
205
+ e = _error;
206
+ }
207
+ payload || (payload = xhr.responseText);
208
+ switch (xhr.status) {
209
+ case 422:
210
+ definition = model[this.resource];
211
+ _ref = payload.errors;
212
+ _results = [];
213
+ for (attribute_name in _ref) {
214
+ messages = _ref[attribute_name];
215
+ if (!(this.hasOwnProperty(attribute_name) || definition.hasOwnProperty(attribute_name))) {
216
+ message = "Server returned an validation error message for a attribute that is not defined in your model.\n";
217
+ message += "The attribute was '" + attribute_name + "', the model resource was '" + this.resource + "'.\n";
218
+ message += "The model definition keys were '" + (JSON.stringify(Object.keys(definition))) + "'.\n";
219
+ message += "Please remove server validation, or update your model definition.";
220
+ throw new TypeError(message);
221
+ }
222
+ _results.push((function() {
223
+ var _i, _len, _results1;
224
+
225
+ _results1 = [];
226
+ for (_i = 0, _len = messages.length; _i < _len; _i++) {
227
+ message = messages[_i];
228
+ _results1.push(this.errors.add(attribute_name, 'server', {
229
+ server_message: message
230
+ }));
231
+ }
232
+ return _results1;
233
+ }).call(this));
234
+ }
235
+ return _results;
236
+ break;
237
+ default:
238
+ message = "Fail in " + this.resource + ".save:\n";
239
+ message += "Record: " + this + "\n";
240
+ message += "Status: " + status + " (" + (payload.status || xhr.status) + ")\n";
241
+ return message += "Error : " + (payload.error || payload.message || payload);
242
+ }
243
+ },
244
+ toString: function() {
245
+ var serialized;
246
+
247
+ serialized = {};
248
+ serialized[this.resource] = this.json();
249
+ return JSON.stringify(serialized);
250
+ },
251
+ json: function() {
252
+ var attribute, json, name, value, _i, _len, _ref;
253
+
254
+ json = {};
255
+ for (name in this) {
256
+ value = this[name];
257
+ if (!(type(value) !== 'function')) {
258
+ continue;
259
+ }
260
+ if (value == null) {
261
+ continue;
262
+ }
263
+ if (type(value) === 'object') {
264
+ if (value.toJSON != null) {
265
+ json[name] = value.toJSON();
266
+ } else {
267
+ _ref = this.nested_attributes;
268
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
269
+ attribute = _ref[_i];
270
+ if (attribute === name) {
271
+ json["" + name + "_attributes"] = value.json();
272
+ }
273
+ }
274
+ }
275
+ } else {
276
+ json[name] = value;
277
+ }
278
+ }
279
+ observable.unobserve(json);
280
+ delete json.dirty;
281
+ delete json.resource;
282
+ delete json.route;
283
+ delete json.initial_route;
284
+ delete json.after_initialize;
285
+ delete json.parent_resource;
286
+ delete json.nested_attributes;
287
+ delete json.on_save;
288
+ delete json.element;
289
+ delete json["default"];
290
+ delete json.lock;
291
+ delete json.validated;
292
+ return json;
293
+ }
294
+ }
295
+ };
296
+
297
+ restful.toJSON = restful.json;
298
+
299
+ model = window.model;
300
+
301
+ record = window.record;
302
+
303
+ model.restfulable = true;
304
+
305
+ record.mix(function(recordable) {
306
+ return merge(recordable, restful.record);
307
+ });
308
+
309
+ model.mix(function(modelable) {
310
+ return merge(modelable, restful.model);
311
+ });
312
+
313
+ model.associable && model.associable.mix(function(singular_association, plural_association) {
314
+ plural_association.get = function() {
315
+ if (this.parent != null) {
316
+ this.route || (this.route = "" + this.parent.route + "/" + this.parent._id + "/" + (model.pluralize(this.resource.name)));
317
+ }
318
+ return rest.get.apply(this, arguments);
319
+ };
320
+ return plural_association.post = function() {
321
+ if (this.parent != null) {
322
+ this.route || (this.route = "" + this.parent.route + "/" + this.parent._id + "/" + (model.pluralize(this.resource.name)));
323
+ }
324
+ return rest.post.apply(this, arguments);
325
+ };
326
+ });