ende 0.5.20 → 0.5.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/component.json +1 -1
  3. data/components/indefinido/indemma/master/.gitignore +17 -0
  4. data/components/indefinido/indemma/master/.ruby-gemset +1 -0
  5. data/components/indefinido/indemma/master/.ruby-version +1 -0
  6. data/components/indefinido/indemma/master/Gemfile +12 -0
  7. data/components/indefinido/indemma/master/Guardfile +39 -0
  8. data/components/indefinido/indemma/master/History.md +0 -0
  9. data/components/indefinido/indemma/master/Readme.md +445 -0
  10. data/components/indefinido/indemma/master/build/development.js +26123 -0
  11. data/components/indefinido/indemma/master/build/release.js +16741 -0
  12. data/components/indefinido/indemma/master/build/test.js +26123 -0
  13. data/components/indefinido/indemma/master/component.json +1 -1
  14. data/components/indefinido/indemma/master/components/chaijs/assertion-error/1.0.0/component.json +18 -0
  15. data/components/indefinido/indemma/master/components/chaijs/assertion-error/1.0.0/index.js +110 -0
  16. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.gitignore +22 -0
  17. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.mailmap +1 -0
  18. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.npmignore +14 -0
  19. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.travis.yml +14 -0
  20. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/CONTRIBUTING.md +173 -0
  21. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/History.md +895 -0
  22. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/Makefile +93 -0
  23. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/README.md +99 -0
  24. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/ReleaseNotes.md +482 -0
  25. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/bower.json +27 -0
  26. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/chai.js +4782 -0
  27. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/component.json +50 -0
  28. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/index.js +1 -0
  29. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/karma.conf.js +28 -0
  30. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/karma.sauce.js +41 -0
  31. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/assertion.js +130 -0
  32. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/config.js +50 -0
  33. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/core/assertions.js +1314 -0
  34. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/interface/assert.js +1056 -0
  35. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/interface/expect.js +12 -0
  36. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/interface/should.js +78 -0
  37. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/addChainableMethod.js +111 -0
  38. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/addMethod.js +43 -0
  39. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/addProperty.js +40 -0
  40. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/flag.js +32 -0
  41. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getActual.js +18 -0
  42. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getEnumerableProperties.js +25 -0
  43. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getMessage.js +49 -0
  44. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getName.js +20 -0
  45. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getPathValue.js +102 -0
  46. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getProperties.js +35 -0
  47. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/index.js +114 -0
  48. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/inspect.js +320 -0
  49. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/objDisplay.js +49 -0
  50. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteChainableMethod.js +53 -0
  51. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteMethod.js +51 -0
  52. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteProperty.js +54 -0
  53. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/test.js +26 -0
  54. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/transferFlags.js +44 -0
  55. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/type.js +45 -0
  56. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai.js +87 -0
  57. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/package.json +42 -0
  58. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/sauce.browsers.js +128 -0
  59. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/support/sauce/sauce_connect_block.sh +7 -0
  60. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/support/sauce/sauce_connect_setup.sh +53 -0
  61. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/assert.js +638 -0
  62. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/auth/.gitkeep +0 -0
  63. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/bootstrap/index.js +22 -0
  64. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/bootstrap/karma.js +22 -0
  65. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/configuration.js +133 -0
  66. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/display/errors.js +14 -0
  67. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/display/message.js +47 -0
  68. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/expect.js +814 -0
  69. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/globalShould.js +15 -0
  70. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/plugins.js +24 -0
  71. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/should.js +744 -0
  72. data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/utilities.js +309 -0
  73. data/components/indefinido/indemma/master/components/chaijs/deep-eql/0.1.3/component.json +20 -0
  74. data/components/indefinido/indemma/master/components/chaijs/deep-eql/0.1.3/lib/eql.js +257 -0
  75. data/components/indefinido/indemma/master/components/chaijs/type-detect/0.1.1/component.json +18 -0
  76. data/components/indefinido/indemma/master/components/chaijs/type-detect/0.1.1/lib/type.js +142 -0
  77. data/components/indefinido/indemma/master/components/component/bind/1.0.0/component.json +14 -0
  78. data/components/indefinido/indemma/master/components/component/bind/1.0.0/index.js +23 -0
  79. data/components/indefinido/indemma/master/components/component/jquery/1.0.0/component.json +10 -0
  80. data/components/indefinido/indemma/master/components/component/jquery/1.0.0/index.js +10308 -0
  81. data/components/indefinido/indemma/master/components/component/type/1.0.0/component.json +20 -0
  82. data/components/indefinido/indemma/master/components/component/type/1.0.0/index.js +32 -0
  83. data/components/indefinido/indemma/master/components/indefinido/advisable/master/component.json +21 -0
  84. data/components/indefinido/indemma/master/components/indefinido/advisable/master/index.js +1 -0
  85. data/components/indefinido/indemma/master/components/indefinido/advisable/master/lib/advisable.js +60 -0
  86. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/component.json +39 -0
  87. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/index.js +1 -0
  88. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/adapters/rivets.js +40 -0
  89. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/legacy/notifierable.js +145 -0
  90. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/legacy/schedulerable.js +147 -0
  91. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/lookup.js +38 -0
  92. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/keypath_observer.js +38 -0
  93. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/observation.js +45 -0
  94. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/selection.js +57 -0
  95. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/self_observer.js +38 -0
  96. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable.js +97 -0
  97. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/platform.js +12 -0
  98. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/observe-js/observe.js +1631 -0
  99. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/accessors-legacy.js +92 -0
  100. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/accessors.js +248 -0
  101. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/array.indexOf.js +8 -0
  102. data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/object.create.js +77 -0
  103. data/components/indefinido/indemma/master/components/pluma/assimilate/0.4.0/component.json +25 -0
  104. data/components/indefinido/indemma/master/components/pluma/assimilate/0.4.0/dist/assimilate.js +127 -0
  105. data/components/indefinido/indemma/master/karma.conf.js +75 -0
  106. data/components/indefinido/indemma/master/lib/record/associable.js +4 -2
  107. data/components/indefinido/indemma/master/lib/record/dirtyable.js +1 -1
  108. data/components/indefinido/indemma/master/package.json +9 -0
  109. data/components/indefinido/indemma/master/spec/record/associable_spec.js +211 -0
  110. data/components/indefinido/indemma/master/spec/record/dirtyable_spec.js +57 -0
  111. data/components/indefinido/indemma/master/spec/record/maid_spec.js +40 -0
  112. data/components/indefinido/indemma/master/spec/record/persistable_spec.js +46 -0
  113. data/components/indefinido/indemma/master/spec/record/queryable_spec.js +39 -0
  114. data/components/indefinido/indemma/master/spec/record/resource_spec.js +93 -0
  115. data/components/indefinido/indemma/master/spec/record/rest_spec.js +32 -0
  116. data/components/indefinido/indemma/master/spec/record/restfulable_spec.js +346 -0
  117. data/components/indefinido/indemma/master/spec/record/scopable_spec.js +242 -0
  118. data/components/indefinido/indemma/master/spec/record/storable_spec.js +44 -0
  119. data/components/indefinido/indemma/master/spec/record/translationable.js +28 -0
  120. data/components/indefinido/indemma/master/spec/record/validatable_spec.js +142 -0
  121. data/components/indefinido/indemma/master/spec/record/validations/associated_spec.js +43 -0
  122. data/components/indefinido/indemma/master/spec/record/validations/confirmation_spec.js +36 -0
  123. data/components/indefinido/indemma/master/spec/record/validations/cpf_spec.js +34 -0
  124. data/components/indefinido/indemma/master/spec/record/validations/presence_spec.js +28 -0
  125. data/components/indefinido/indemma/master/spec/record/validations/remote_spec.js +87 -0
  126. data/components/indefinido/indemma/master/spec/record/validations/type_spec.js +48 -0
  127. data/components/indefinido/indemma/master/spec/record_spec.js +49 -0
  128. data/components/indefinido/indemma/master/spec/spec_helper.js +15 -0
  129. data/components/indefinido/indemma/master/spec/support/value_objects/phone.js +45 -0
  130. data/components/indefinido/indemma/master/src/lib/extensions/rivets.coffee +17 -0
  131. data/components/indefinido/indemma/master/src/lib/record/associable.coffee +419 -0
  132. data/components/indefinido/indemma/master/src/lib/record/dirtyable.coffee +47 -0
  133. data/components/indefinido/indemma/master/src/lib/record/errors.coffee +20 -0
  134. data/components/indefinido/indemma/master/src/lib/record/maid.coffee +16 -0
  135. data/components/indefinido/indemma/master/src/lib/record/persistable.coffee +34 -0
  136. data/components/indefinido/indemma/master/src/lib/record/queryable.coffee +29 -0
  137. data/components/indefinido/indemma/master/src/lib/record/resource.coffee +107 -0
  138. data/components/indefinido/indemma/master/src/lib/record/rest.coffee +34 -0
  139. data/components/indefinido/indemma/master/src/lib/record/restfulable.coffee +487 -0
  140. data/components/indefinido/indemma/master/src/lib/record/scopable.coffee +279 -0
  141. data/components/indefinido/indemma/master/src/lib/record/storable.coffee +49 -0
  142. data/components/indefinido/indemma/master/src/lib/record/translationable.coffee +18 -0
  143. data/components/indefinido/indemma/master/src/lib/record/validatable.coffee +241 -0
  144. data/components/indefinido/indemma/master/src/lib/record/validations/associated.coffee +34 -0
  145. data/components/indefinido/indemma/master/src/lib/record/validations/confirmation.coffee +17 -0
  146. data/components/indefinido/indemma/master/src/lib/record/validations/cpf.coffee +57 -0
  147. data/components/indefinido/indemma/master/src/lib/record/validations/presence.coffee +16 -0
  148. data/components/indefinido/indemma/master/src/lib/record/validations/remote.coffee +61 -0
  149. data/components/indefinido/indemma/master/src/lib/record/validations/type.coffee +31 -0
  150. data/components/indefinido/indemma/master/src/lib/record/validations/validatorable.coffee +5 -0
  151. data/components/indefinido/indemma/master/src/lib/record.coffee +143 -0
  152. data/components/indefinido/indemma/master/src/spec/record/associable_spec.coffee +205 -0
  153. data/components/indefinido/indemma/master/src/spec/record/dirtyable_spec.coffee +47 -0
  154. data/components/indefinido/indemma/master/src/spec/record/maid_spec.coffee +34 -0
  155. data/components/indefinido/indemma/master/src/spec/record/persistable_spec.coffee +39 -0
  156. data/components/indefinido/indemma/master/src/spec/record/queryable_spec.coffee +33 -0
  157. data/components/indefinido/indemma/master/src/spec/record/resource_spec.coffee +69 -0
  158. data/components/indefinido/indemma/master/src/spec/record/rest_spec.coffee +22 -0
  159. data/components/indefinido/indemma/master/src/spec/record/restfulable_spec.coffee +257 -0
  160. data/components/indefinido/indemma/master/src/spec/record/scopable_spec.coffee +227 -0
  161. data/components/indefinido/indemma/master/src/spec/record/storable_spec.coffee +39 -0
  162. data/components/indefinido/indemma/master/src/spec/record/translationable.coffee +19 -0
  163. data/components/indefinido/indemma/master/src/spec/record/validatable_spec.coffee +127 -0
  164. data/components/indefinido/indemma/master/src/spec/record/validations/associated_spec.coffee +35 -0
  165. data/components/indefinido/indemma/master/src/spec/record/validations/confirmation_spec.coffee +25 -0
  166. data/components/indefinido/indemma/master/src/spec/record/validations/cpf_spec.coffee +27 -0
  167. data/components/indefinido/indemma/master/src/spec/record/validations/presence_spec.coffee +24 -0
  168. data/components/indefinido/indemma/master/src/spec/record/validations/remote_spec.coffee +74 -0
  169. data/components/indefinido/indemma/master/src/spec/record/validations/type_spec.coffee +33 -0
  170. data/components/indefinido/indemma/master/src/spec/record_spec.coffee +29 -0
  171. data/components/indefinido/indemma/master/src/spec/spec_helper.coffee +11 -0
  172. data/components/indefinido/indemma/master/src/spec/support/value_objects/phone.coffee +30 -0
  173. data/components/indefinido/indemma/master/vendor/object/mixin.js +196 -0
  174. data/components/indefinido/indemma/master/vendor/spec/sinon/assert.js +199 -0
  175. data/components/indefinido/indemma/master/vendor/spec/sinon/behavior.js +334 -0
  176. data/components/indefinido/indemma/master/vendor/spec/sinon/call.js +205 -0
  177. data/components/indefinido/indemma/master/vendor/spec/sinon/collection.js +155 -0
  178. data/components/indefinido/indemma/master/vendor/spec/sinon/match.js +245 -0
  179. data/components/indefinido/indemma/master/vendor/spec/sinon/mock.js +451 -0
  180. data/components/indefinido/indemma/master/vendor/spec/sinon/sandbox.js +144 -0
  181. data/components/indefinido/indemma/master/vendor/spec/sinon/spy.js +413 -0
  182. data/components/indefinido/indemma/master/vendor/spec/sinon/stub.js +161 -0
  183. data/components/indefinido/indemma/master/vendor/spec/sinon/test.js +77 -0
  184. data/components/indefinido/indemma/master/vendor/spec/sinon/test_case.js +99 -0
  185. data/components/indefinido/indemma/master/vendor/spec/sinon/util/event.js +94 -0
  186. data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_server.js +212 -0
  187. data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_server_with_clock.js +83 -0
  188. data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_timers.js +405 -0
  189. data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_xdomain_request.js +206 -0
  190. data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_xml_http_request.js +575 -0
  191. data/components/indefinido/indemma/master/vendor/spec/sinon/util/timers_ie.js +31 -0
  192. data/components/indefinido/indemma/master/vendor/spec/sinon/util/xdr_ie.js +14 -0
  193. data/components/indefinido/indemma/master/vendor/spec/sinon/util/xhr_ie.js +19 -0
  194. data/components/indefinido/indemma/master/vendor/spec/sinon.js +383 -0
  195. data/lib/assets/javascripts/value_objects/phone.js.coffee +3 -1
  196. data/lib/assets/javascripts/widgets/viewer/plugins/scopable.js.coffee +5 -5
  197. data/lib/ende/version.rb +1 -1
  198. data/vendor/assets/components/ende_build.css +4 -4
  199. data/vendor/assets/components/ende_build.js +7974 -7889
  200. metadata +191 -5
  201. data/vendor/assets/component/build.css +0 -112
  202. data/vendor/assets/components/build.css +0 -112
  203. data/vendor/assets/components/indemma_with_none.js +0 -30553
@@ -0,0 +1,279 @@
1
+ require './restfulable'
2
+ require './resource'
3
+
4
+ stampit = require '../../vendor/stampit'
5
+ extend = require 'assimilate'
6
+ observable = require('observable').mixin
7
+ merge = extend.withStrategy 'deep'
8
+ $ = require 'jquery'
9
+ rest = require './rest'
10
+
11
+ # TODO merge all with fetch and remove this util object
12
+ util =
13
+ model:
14
+ map: (records) ->
15
+ return record if @build
16
+ @.call @, record for record, index in records
17
+
18
+ # TODO better responsibilty division for this code
19
+ scopable =
20
+ builder: stampit().enclose ->
21
+
22
+ # Builds a given scope
23
+ # {param} name Scope name also, the name of method used to invoke it
24
+ # {param} type Default value for scope, or base class to derive default for default type
25
+
26
+ stampit.mixIn (name, type) ->
27
+ if $.type(type) == 'function'
28
+ @["$#{name}"] = type() || new type
29
+ type = $.type @["$#{name}"]
30
+ else
31
+ @["$#{name}"] = defaults[type] || type
32
+
33
+ type = $.type type if $.type(type) != 'string' or type.toString() == ''
34
+ builder = builders[type]
35
+
36
+ throw "Unknown scope type: '#{type}', For model with resource: '#{@resource}'" unless builder?
37
+
38
+ @scope.declared.push name
39
+ @[name] = builder name: name
40
+ ,
41
+ data: {}
42
+ then: []
43
+ fail: []
44
+ declared: []
45
+ fetch: (data, done, fail) ->
46
+
47
+ if typeof data == 'function'
48
+ done = data
49
+ data = {}
50
+
51
+ # Copy current scope data for request
52
+ # TODO think in a better way to only copy scope data for the request
53
+ scope = extend {}, @scope.data
54
+ delete scope[method] for method of observable.methods
55
+
56
+
57
+ if scope.noned?
58
+ deferred = $.Deferred()
59
+ deferred.resolveWith @, [[]]
60
+ else
61
+ deferred = rest.get.call(@, extend scope, data)
62
+
63
+ deferred
64
+ .then(util.model.map)
65
+ .done(@scope.then.concat [done])
66
+ .fail(@scope.fail.concat [fail])
67
+
68
+ @scope.clear()
69
+
70
+ deferred
71
+
72
+ clear: ->
73
+ @data = {}
74
+ @callbacks = []
75
+
76
+ # Shared scope stuff
77
+ base: stampit().state
78
+ name: 'unamed_scope'
79
+
80
+ record:
81
+ # Parse error json if any
82
+ failed: (xhr, error, status) ->
83
+ payload = xhr.responseJSON
84
+ try payload ||= JSON.parse(xhr.responseText) catch e
85
+ payload ||= xhr.responseText
86
+
87
+ # When client fail
88
+ switch xhr.status
89
+ when 422
90
+ @valid = false
91
+ return @errors = payload.errors
92
+ # Unknown fail
93
+ else
94
+ message = "Fail in #{@resource}.save:\n"
95
+ message += "Record: #{@}\n"
96
+ message += "Status: #{status} (#{payload.status || xhr.status})\n"
97
+ message += "Error : #{payload.error || payload.message || payload}"
98
+
99
+ console.error message
100
+ model:
101
+ # TODO implement getter for none property!
102
+ none: ->
103
+ @scope.data.noned = true
104
+ @
105
+
106
+ # TODO merge with all object
107
+ fetch: (data, done, fail) ->
108
+ if typeof data == 'function'
109
+ done = data
110
+ data = null
111
+
112
+ @scope.fetch.call @, data, done, fail
113
+
114
+ # TODO optmize this iterations or add support for stampit on associable and merge factories
115
+ # TODO rename this method to forward extensions to association, and store extensions on has_many definitions
116
+ # @ = record instance
117
+ forward_scopes_to_associations: ->
118
+ factory = model[@resource.name]
119
+
120
+ for association_name in factory.has_many
121
+ associated_resource = model.singularize association_name
122
+ associated_factory = model[associated_resource]
123
+
124
+ # TODO change this warn message into a exception when
125
+ # associations are renamable
126
+ unless model[associated_resource]
127
+ console.warn("Associated factory not found for associated resource: #{associated_resource}")
128
+ continue
129
+
130
+ association = @[association_name]
131
+ association.scope = scopable.builder association
132
+
133
+ for scope in associated_factory.scope.declared
134
+ association.scope scope, associated_factory["$#{scope}"]
135
+
136
+ true
137
+ # @ = model instance
138
+ after_mix: ->
139
+ @scope = scopable.builder @
140
+
141
+ for property, type of @
142
+ if property.charAt(0) == '$'
143
+ name = property.substring 1
144
+ @scope name, type
145
+
146
+ builders =
147
+ # Builds a string scope builder
148
+ string: stampit().enclose ->
149
+ base = scopable.base @
150
+
151
+ stampit.mixIn (value, callbacks...) ->
152
+ callbacks.length and @scope.then = @scope.then.concat callbacks
153
+ @scope.data[base.name] ||= value ? @["$#{base.name}"]
154
+ @
155
+
156
+ # Builds a boolean scope builder
157
+ boolean: stampit().enclose ->
158
+ base = scopable.base @
159
+
160
+ stampit.mixIn (value, callbacks...) ->
161
+ callbacks.length and @scope.then = @scope.then.concat callbacks
162
+ @scope.data[base.name] ||= value ? @["$#{base.name}"]
163
+ @
164
+
165
+ # Builds a array scope builder
166
+ array: stampit().enclose ->
167
+ base = scopable.base @
168
+
169
+ stampit.mixIn (values...) ->
170
+ @scope.data[base.name] ||= values ? @["$#{base.name}"]
171
+ @
172
+
173
+ defaults =
174
+ boolean: true
175
+ array: []
176
+
177
+ # Extend indemma
178
+ model = window.model # TODO better way to get parent
179
+ record = window.record # TODO better way to get parent
180
+
181
+ model.scopable = true
182
+
183
+ # TODO use stampit to extend record and model
184
+ #record.mix (recordable) ->
185
+ # merge recordable, scopable.record
186
+
187
+ model.mix (modelable) ->
188
+ merge modelable, scopable.model
189
+
190
+ modelable.after_mix.push scopable.after_mix
191
+
192
+
193
+ # TODO create a deferred to better mix models
194
+ if model.associable
195
+ model.mix (modelable) ->
196
+ modelable.record.after_initialize.push ->
197
+ scopable.model.forward_scopes_to_associations.call @
198
+
199
+ model.associable.mix (singular_association, plural_association) ->
200
+
201
+ # reload (done callbacks...)
202
+ plural_association.every = plural_association.reload = (data, done, fail) ->
203
+ # TODO move route discovery to plural_association.after_mix
204
+ @route ||= "#{@parent.route}/#{@parent._id}/#{model.pluralize @resource}" if @parent?
205
+ promises = []
206
+
207
+ # TODO better calculate fetch settings
208
+ # dirty = 0
209
+ # if more than 5 records are dirty, we reftech all
210
+ # if dirty < 5
211
+ # for record in @
212
+ # promises.push record.reload()
213
+ # else we reload everthing!
214
+ # else
215
+ #
216
+ # for record in @
217
+ # dirty++ if record.dirty
218
+
219
+ if typeof data == 'function'
220
+ done = data
221
+ data = undefined
222
+
223
+ promises.push @scope.fetch.call @, data, null, scopable.record.failed
224
+
225
+ reload = $.when.apply jQuery, promises
226
+
227
+ # Update association with data sent from the server
228
+ # TODO implement setter on this association and let user to set
229
+ reload.done (records, status) ->
230
+
231
+ # if no records were found by the server on this association
232
+ unless records.length
233
+ # Clear current stored cache on this association
234
+ # it to an empty array
235
+ Array.prototype.splice.call @, 0 if @length
236
+
237
+ return true
238
+
239
+
240
+ singular_resource = model.singularize @resource
241
+
242
+ # Normalize json data for building on association
243
+ for record in records
244
+
245
+ # TODO only nest specified nested attributes on model definition
246
+ # TODO create special deserialization method no plural association
247
+ # TODO check if we need to nest attributes in other association tipes
248
+ for association_name in model[singular_resource].has_many
249
+ record["#{association_name}_attributes"] = record[association_name]
250
+ delete record[association_name]
251
+
252
+ # Update found records
253
+ # TODO create update method
254
+ create = []
255
+ for record, index in records
256
+ if target = @find record._id
257
+ target.assign_attributes record
258
+ else
259
+ create.push record
260
+
261
+ # Load new records on this association
262
+ @add.apply @, create
263
+
264
+ # Override the response records object with added to association records
265
+ records.splice 0
266
+ records.push.apply records, @
267
+
268
+
269
+ reload.done done
270
+ reload.fail fail
271
+
272
+ reload
273
+
274
+ plural_association.each = (callback) ->
275
+ @route ||= "#{@parent.route}/#{@parent._id}/#{model.pluralize @resource}" if @parent?
276
+
277
+ # TODO cache models
278
+ @get().done (records) =>
279
+ callback record for record in @
@@ -0,0 +1,49 @@
1
+ extend = require 'assimilate'
2
+ merge = extend.withStrategy 'deep'
3
+ stampit = require '../../vendor/stampit'
4
+
5
+ # TODO use this as an external component or shim
6
+ Object.values ||= _?.values || (object) -> value for key, value of object
7
+
8
+ storable = stampit
9
+ store: (keypath, value, options) ->
10
+ collection = @database
11
+ keypath = keypath.toString().split '.'
12
+ key = keypath.pop()
13
+
14
+ for entry in keypath
15
+ collection[entry] ||= {}
16
+ collection = collection[entry]
17
+
18
+ if arguments.length == 1
19
+ @reads++
20
+ collection[key]
21
+ else
22
+ @writes++
23
+
24
+ # TODO use object.defineProperty
25
+ value.sustained ||= true
26
+ collection[key] = value
27
+
28
+ values: ->
29
+ Object.values @database
30
+ ,
31
+ type: 'object'
32
+ writes: 0
33
+ reads: 0
34
+ , ->
35
+ @database ||= {}
36
+ @
37
+
38
+
39
+ # Extend indemma
40
+ # TODO use stampit to extend record and model
41
+ model = window.model # TODO better way to get parent
42
+ record = window.record # TODO better way to get parent
43
+
44
+ model.storable = true
45
+ module.exports = storable
46
+ #model.mix (modelable) ->
47
+ # merge modelable, storable.model
48
+
49
+
@@ -0,0 +1,18 @@
1
+ root = exports ? window
2
+
3
+ # TODO better way to get core model definition
4
+ # model = require ...
5
+
6
+ # TODO implement method
7
+ # model[resource].validators_on 'field' # Get all validators related to this field
8
+
9
+ extend = require('assimilate')
10
+
11
+ extensions =
12
+ model:
13
+ human_attribute_name: (attribute_name) ->
14
+ @translation?.attributes?[attribute_name] or attribute_name
15
+
16
+ model.mix (modelable) ->
17
+ extend modelable, extensions.model
18
+
@@ -0,0 +1,241 @@
1
+ require './translationable'
2
+
3
+ root = exports ? @
4
+ stampit = require '../../vendor/stampit'
5
+ observable = require 'observable'
6
+ type = require 'type'
7
+
8
+ # TODO better model require
9
+ # model = require ...
10
+
11
+ # TODO Add base settings to validation
12
+ # TODO implement method
13
+ # model[resource].validators_on 'field' # Get all validators related to this field
14
+
15
+ # TODO use http://validatejs.org for internal handling
16
+
17
+ messages =
18
+ blank: (attribute_name) ->
19
+ attribute_name = @human_attribute_name attribute_name
20
+ "O campo #{attribute_name} não pode ficar em branco."
21
+
22
+ cpf: (attribute_name) ->
23
+ attribute_name = @human_attribute_name attribute_name
24
+ "O campo #{attribute_name} não está válido."
25
+
26
+ confirmation: (attribute_name) ->
27
+ confirmation_attribute_name = @human_attribute_name attribute_name
28
+ attribute_name = @human_attribute_name attribute_name.replace '_confirmation', ''
29
+ "O campo #{attribute_name} não está de acordo com o campo #{confirmation_attribute_name}."
30
+
31
+ associated: (attribute_name) ->
32
+ attribute_name = @human_attribute_name attribute_name
33
+ "O registro associado #{attribute_name} não é válido."
34
+
35
+ server: (attribute_name, options) ->
36
+ # TODO Better checking of base attribute case, better yet remove
37
+ # checking from here, just like active record
38
+ if attribute_name == 'base'
39
+ options.server_message
40
+ else
41
+ attribute_name = @human_attribute_name attribute_name
42
+ "#{attribute_name} #{options.server_message}."
43
+
44
+ type: (attribute_name, options) ->
45
+ attribute_name = @human_attribute_name attribute_name
46
+ "O campo #{attribute_name} não está válido."
47
+
48
+ # TODO move to errorsable.coffee
49
+ errorsable = stampit
50
+ add: (attribute_name, message_key, options) ->
51
+
52
+ @push [attribute_name, message_key, options]
53
+ # TODO Also push to attribute named
54
+ # @[attribute_name].push message_key, message, options
55
+
56
+ @messages[attribute_name] = ''
57
+
58
+ translator = messages[message_key]
59
+
60
+ if translator?
61
+ @messages[attribute_name] += translator.call @model, attribute_name, options
62
+ else
63
+ @messages[attribute_name] += message_key
64
+
65
+ clear: ->
66
+ if @length
67
+ @length = 0
68
+ @messages[attribute_name] = null for attribute_name of @messages
69
+
70
+ push: Array.prototype.push
71
+ splice: Array.prototype.splice
72
+ indexOf: Array.prototype.indexOf
73
+ ,
74
+ model: null
75
+ messages: null
76
+ length: 0
77
+ , ->
78
+ @messages = {}
79
+ @
80
+
81
+
82
+ initializers =
83
+ # TODO move ignored properties to the record
84
+ ignores: ['dirty', 'resource', 'route', 'initial_route', 'after_initialize', 'before_initialize', 'parent_resource', 'nested_attributes', 'reloading', 'ready', 'saving', 'salvation', 'sustained', 'element', 'default', 'lock', 'validated', 'validation', 'errors', 'dirty']
85
+ reserved_filter: (name) -> @ignores.indexOf(name) == -1
86
+
87
+ define_triggers: ->
88
+
89
+ # TODO remove the extra inheritance level of model[@resource]
90
+ @errors = errorsable model: model[@resource]
91
+
92
+ # TODO only add before save when resourceable is included
93
+ # TODO @after_initialize validate_field_types
94
+ # TODO only execute save operation if record is valid
95
+ @before 'save', -> @validate() if @save
96
+
97
+ # TODO move this functionality control to validatable
98
+ @validated = false
99
+ @validation = null
100
+ # TODO subscribe and unsubscribe depending on validation state
101
+ @subscribe (added, removed, changed) ->
102
+ # When any property is added, removed or changed, we consider
103
+ # that the record has been modified
104
+ modified = !!Object.keys($.extend added, removed, changed).filter(initializers.reserved_filter, initializers).length
105
+
106
+ # To enable the future validations of this record, mark it as
107
+ # not validated, since it has changed
108
+ modified and @validated = false
109
+
110
+ Object.defineProperty @, 'valid',
111
+ get: ->
112
+ # To prevent multiple consecutive remote validations, if the
113
+ # record has not changed since last validation call, we
114
+ # schedule a validation
115
+ if @validation?.state() == 'pending'
116
+ @validation.done -> @valid if @dirty or !@validated
117
+ return null
118
+
119
+ @validate()
120
+
121
+ if @validation.state() == 'resolved'
122
+ !@errors.length
123
+ else
124
+ null
125
+
126
+ set: -> throw new TypeError "You can't set the value for the valid property."
127
+ enumerable: false
128
+
129
+ # The observable package reads the valid property when it's added
130
+ # to the model, causing it to validate unwatedly. So we need to
131
+ # stub some calls to prevent validation to
132
+ # TODO make deliver(true) really ignore the change records,
133
+ # better yet make it ignore only add records for valid property
134
+ original_validate = @validate
135
+ @validate = ->
136
+ @validation = $.Deferred()
137
+ @observation.deliver true
138
+ @validation = null
139
+ @validate = original_validate
140
+
141
+ create_validators: (definitions) ->
142
+
143
+ @validators = []
144
+
145
+ for name, validator of manager.validators
146
+ definition = definitions[validator.definition_key]
147
+
148
+ if definition
149
+ definition = [definition] unless type(definition) == 'array'
150
+
151
+ for validator_options in definition
152
+
153
+ # Parse validation definition
154
+ validator_options = attribute_name: validator_options unless type(validator_options) == 'object'
155
+ validator_options.model = @
156
+
157
+ # Instantiate validator
158
+ @validators.push validator validator_options
159
+
160
+ # Clear out definition to prevent validators from becoming
161
+ # attributes
162
+ delete definitions[validator.definition_key]
163
+
164
+ # Model and Record extensions
165
+ # TODO Use stampit!
166
+ extensions =
167
+ model:
168
+ validators: null
169
+
170
+ record:
171
+
172
+ validate_attribute: (attribute, doned, failed) ->
173
+ # TODO better clearing of single attribute error message
174
+ @errors.messages[attribute] = null
175
+
176
+ results = [@, attribute]
177
+
178
+ # TODO copy validators reference from model object to record object
179
+ # TODO update json serializer
180
+ # TODO filter validators for attribute
181
+ for validator in model[@resource.toString()].validators
182
+ if validator.attribute_name is attribute
183
+ results.push validator.validate_each @, validator.attribute_name, @[validator.attribute_name]
184
+
185
+ validation = jQuery.when.apply jQuery, results
186
+ validation.done doned
187
+ validation.fail failed
188
+
189
+ validation
190
+
191
+ validate: (doned, failed) ->
192
+ return @validation if @validated
193
+
194
+ @errors.clear()
195
+ results = [@]
196
+
197
+ # TODO copy validators reference from model object to record object
198
+ # TODO update json serializer
199
+ for validator in model[@resource.toString()].validators
200
+ results.push validator.validate_each @, validator.attribute_name, @[validator.attribute_name]
201
+
202
+ @validation = jQuery.when results...
203
+ @validation.done doned
204
+ @validation.fail failed
205
+
206
+ # TODO store this callback
207
+ @validation.done (record) -> record.validated ||= true
208
+
209
+ # Validators management
210
+ manager =
211
+
212
+ validators: {}
213
+
214
+ # TODO async validator loading
215
+ # for: (name) ->
216
+ # builder = @validators[name] ||= require "validations/#{name}"
217
+
218
+
219
+ # TODO better stampit integration
220
+ model.mix (modelable) ->
221
+
222
+ # TODO discover why component builder is including this file
223
+ # multiple times and remove this check
224
+ return if modelable.record.validate
225
+
226
+ jQuery.extend modelable, extensions.model
227
+
228
+ jQuery.extend modelable.record, extensions.record
229
+
230
+ modelable.after_mix.unshift initializers.create_validators
231
+ modelable.record.after_initialize.push initializers.define_triggers
232
+
233
+ model.validators = manager.validators
234
+
235
+ # TODO async validator loading
236
+ manager.validators.confirmation = require './validations/confirmation'
237
+ manager.validators.associated = require './validations/associated'
238
+ manager.validators.presence = require './validations/presence'
239
+ manager.validators.remote = require './validations/remote'
240
+ manager.validators.type = require './validations/type'
241
+ manager.validators.cpf = require './validations/cpf'
@@ -0,0 +1,34 @@
1
+ # TODO Add base settings to validation
2
+ # model = window.model
3
+ # TODO implement method
4
+
5
+ # model[resource].validators_on 'field' # Get all validators related to this field
6
+
7
+ stampit = require '../../../vendor/stampit'
8
+
9
+ associationable = stampit
10
+ validate_each: (record, attribute, value) ->
11
+ associated = record[attribute]
12
+
13
+ # TODO figure out why this method is being called twice
14
+ if associated
15
+
16
+ # TODO detect association type, and then validate
17
+ # current we only support has_one associations
18
+ # TODO better way to getting access to the global 'model' definition
19
+ unless model[record.resource].has_one.indexOf(attribute) != -1
20
+ throw new Error 'Only has_one associations are supported to validates_associated'
21
+
22
+ associated_validation = associated.validate()
23
+
24
+ # To have a complete view in parent record of associated errors,
25
+ # forward the messages to record
26
+ associated_validation.done ->
27
+ record.errors.add attribute, 'associated', @options if associated.errors.length
28
+
29
+ associated_validation
30
+
31
+
32
+ composed = stampit.compose(require('./validatorable'), associationable)
33
+ composed.definition_key = 'validates_associated'
34
+ module.exports = composed
@@ -0,0 +1,17 @@
1
+ # TODO Add base settings to validation
2
+ # model = window.model
3
+
4
+ # TODO implement method
5
+ # model[resource].validators_on 'field' # Get all validators related to this field
6
+
7
+ stampit = require '../../../vendor/stampit'
8
+
9
+ confirmationable = stampit
10
+ validate_each: (record, attribute, value) ->
11
+ if record[attribute] != record["#{attribute}_confirmation"]
12
+ record.errors.add "#{attribute}_confirmation", 'confirmation', @options
13
+
14
+
15
+ composed = stampit.compose require('./validatorable'), confirmationable
16
+ composed.definition_key = 'validates_confirmation_of'
17
+ module.exports = composed
@@ -0,0 +1,57 @@
1
+ # TODO Add base settings to validation
2
+ # model = window.model
3
+
4
+ # TODO implement method
5
+ # model[resource].validators_on 'field' # Get all validators related to this field
6
+
7
+ stampit = require '../../../vendor/stampit'
8
+
9
+ cpfable = stampit
10
+ validate_format: (value) ->
11
+ value = value.replace /[\.\-]/g, ""
12
+
13
+ # Wrong cpf size
14
+ return false if value.length < 11
15
+
16
+ # Dummy but valid values (000.000.000-00, 111.111.111-11, ...)
17
+ return false if value.match /^(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)$/
18
+
19
+ # Mod 11 validation
20
+ c = value.substr 0, 9
21
+ dv = value.substr 9, 2
22
+ d1 = 0
23
+ v = false
24
+ i = 0
25
+
26
+ for i in [0..9]
27
+ d1 += c.charAt(i) * (10 - i)
28
+
29
+ return false if d1 == 0
30
+
31
+ d1 = 11 - (d1 % 11)
32
+ d1 = 0 if (d1 > 9 )
33
+
34
+ return false if +dv.charAt(0) != d1
35
+
36
+ d1 *= 2
37
+ for i in [0..9]
38
+ d1 += c.charAt(i) * (11 - i)
39
+
40
+
41
+ d1 = 11 - (d1 % 11)
42
+ d1 = 0 if (d1 > 9 )
43
+
44
+ return false if +dv.charAt(1) != d1
45
+
46
+ true
47
+
48
+
49
+ validate_each: (record, attribute, value) ->
50
+ record.errors.add attribute, 'cpf', @options if value and not @validate_format value
51
+
52
+
53
+
54
+
55
+ composed = stampit.compose require('./validatorable'), cpfable
56
+ composed.definition_key = 'validates_cpf_format'
57
+ module.exports = composed