ende 0.5.20 → 0.5.21

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.
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,419 @@
1
+ root = window
2
+ $ = require 'jquery'
3
+ extend = require 'assimilate'
4
+
5
+ require './resource'
6
+
7
+ # Store association methods
8
+ # TODO Implement setter for route
9
+ plural = # has_many ## TODO embeds_many
10
+ add : (params...) ->
11
+ # TODO check for id and instantly add resource
12
+ # TODO Set foreign keys?
13
+ @push @build attributes for attributes in params
14
+
15
+ create: (params...) ->
16
+ for attributes in params
17
+ record = @build attributes
18
+ @push record
19
+ record.save()
20
+ build: (data = {}) ->
21
+ data.parent_resource = @parent_resource
22
+
23
+ # TODO Setup a before save callback to generate route when there is no id
24
+ data.route ||= "#{@parent.route}/#{@parent._id}/#{model.pluralize @resource.toString()}" if @parent?
25
+ throw "associable.has_many: cannot redefine route of association #{@parent_resource}.#{@resource} from #{@route} to #{data.route}" if @route isnt data.route and @route
26
+ # Adds parent record to children side of association, if not set
27
+ # TODO check if this reference is unmade on instance elimination
28
+ data[@parent_resource] ||= @parent
29
+
30
+ # TODO store a singular copy of the resource for better performace
31
+ model[model.singularize @resource] data
32
+ push : ->
33
+ console.warn "#{@resource}.push is deprecated and will be removed, please use add instead"
34
+ Array.prototype.push.apply @, arguments
35
+ arguments[0]
36
+
37
+ length : 0
38
+ json : (methods, omissions) -> record.json(methods, omissions) for record in @
39
+
40
+ find : (id) -> return resource for resource in @ when resource._id is id
41
+
42
+ # TODO better support searching
43
+ filter : Array.prototype.filter || _?.filter
44
+
45
+
46
+ singular = # belongs_to, has_one ## TODO embeds_one, embedded_in
47
+ # @ = record
48
+ create: (data) -> model[@resource].create extend {}, @, data
49
+ # @ = record
50
+ # TODO convert to association proxy
51
+ build : (data) ->
52
+ # Adds child record of association to parent, and returns new
53
+ # record
54
+ @owner[@resource.toString()] = model[@resource.toString()] extend {}, @, data
55
+
56
+ descriptors =
57
+ belongs_to:
58
+ # TODO store association observer in association proxy, also
59
+ # update observable to support creating empty observers on object
60
+ # attributes
61
+ resource_id:
62
+ getter: -> @owner.observed[@resource + '_id']
63
+ setter: (resource_id) ->
64
+ # TODO check for association name in association proxy
65
+ association_name = @resource.toString()
66
+
67
+ # TODO faster nullifing association check
68
+ # TODO check if its usefull to only allow disassociating with null
69
+ # TODO notify nullification of associations
70
+ unless resource_id?
71
+ # If there is anything to nullify, undefine or falsify, do it
72
+ if @owner[association_name] or @owner[association_name + '_id']
73
+ @dirty = true
74
+ @owner[association_name] = null
75
+
76
+ return resource_id
77
+
78
+ # TODO Discover and update inverse side of association
79
+ # associated[@owner.resource.toString()] = @owner
80
+ current_resource_id = @owner.observed[association_name]?._id
81
+ if resource_id != current_resource_id
82
+
83
+ # For getter to read, we store conveniently on observable
84
+ # repository
85
+ @owner.observed[association_name + '_id'] = resource_id
86
+
87
+ # Nullify associated object, so next time user accesses it,
88
+ # association loader loads the new object
89
+ @owner.observed[association_name] = null
90
+
91
+ # If we have any listener associated with this property,
92
+ # notify it
93
+ # TODO implement notification api on observable
94
+ unless Object.observe
95
+ @owner.observation.observers[association_name + '_id']?.check_()
96
+ else
97
+ change = oldValue: current_resource_id, type: 'update', name: association_name + '_id', object: @owner
98
+ Object.getNotifier(@owner).notify change
99
+
100
+ resource_id
101
+
102
+ resource:
103
+ # TODO Use Auto build and Auto load as association options
104
+ getter: ->
105
+ # TODO allow custom association names
106
+ association_name = @resource.toString()
107
+ associated = @owner.observed[association_name]
108
+ associated_id = @owner.observed[association_name + '_id']
109
+
110
+ # Returns null depending on sustained state of resource and on
111
+ # retrievability of the resource
112
+ return associated || null unless associated?._id? or associated_id
113
+
114
+ # Returns imediatelly for resources on storage
115
+ # TODO make this extensible
116
+ return associated if associated?.sustained
117
+
118
+ # Auto build
119
+ resource = model[association_name]
120
+ unless resource
121
+ console.warn "descriptors.belongs_to.resource.getter: associated factory not found for model '#{association_name}' belonging to '#{@owner.resource}'"
122
+ return associated
123
+
124
+ # Search through stored resources to see if it is stored
125
+ associated = resource.find associated_id || associated._id
126
+
127
+ # Found associated in storage, update this model and return associated
128
+ return @owner.observed[association_name] = associated if associated
129
+
130
+ # Auto load
131
+ # Not found associated in storage
132
+ # TODO remote find or local find automatically, and implement find_or_initialize_by
133
+ associated ||= resource _id: associated_id # initialize and store a new record
134
+ associated.reload() # fetch resource
135
+
136
+ # Store temporary unloaded resource in this model
137
+ @owner.observed[association_name] = associated
138
+
139
+ # Called when associated record changes, so we can silently update the id
140
+ # TODO Get observer and notify through them
141
+ setter: (associated) ->
142
+ association_name = @resource.toString()
143
+ current_value = @owner.observed[association_name]
144
+
145
+ # Do nothing if the values are not changing
146
+ return if current_value == associated and !(current_value || associated)
147
+
148
+ @owner.observed[association_name] = associated
149
+ @owner.observed[association_name + '_id'] = if associated then associated._id else null
150
+
151
+ # TODO implement notification api on observable
152
+ unless Object.observe
153
+ @owner.observation.observers[association_name]?.check_()
154
+ else
155
+ change = oldValue: current_value, type: 'update', name: association_name, object: @owner
156
+ Object.getNotifier(@owner).notify change
157
+
158
+ change = oldValue: associated?._id, type: 'update', name: association_name + '_id', object: @owner
159
+ Object.getNotifier(@owner).notify change
160
+
161
+ associated
162
+
163
+
164
+ callbacks =
165
+ has_many:
166
+ # Forward association nested attributes
167
+ # TODO write attribute setter, and remove this code
168
+ nest_attributes: ->
169
+ # TODO only nest specified nested attributes on model definition
170
+ # TODO remove associations iteration, and pass throught parameter
171
+ # TODO DO not support '_attributes' property on instantiating!
172
+ association_names = model[@resource].has_many
173
+ if association_names
174
+ for association_name in association_names
175
+
176
+ # Instantiate new records for the association attributes
177
+ # TODO DO not support '_attributes' property on instantiating!
178
+ # TODO define setter for attributes
179
+ associations_attributes = @["#{association_name}_attributes"]
180
+ association = @[model.pluralize association_name]
181
+
182
+ if associations_attributes and associations_attributes.length
183
+
184
+ unless association
185
+ message = "has_many.nest_attributes: Association not found for #{association_name}. \n"
186
+ message += "did you set it on model declaration? \n has_many: #{association_name} "
187
+ throw message
188
+
189
+ # TODO store a singular copy of the resource for better performace
190
+ association.resource = model.singularize association.resource
191
+ association.add.apply association, associations_attributes
192
+ association.resource = model.pluralize association.resource
193
+
194
+ delete @["#{association_name}_attributes"]
195
+
196
+ # TODO Update route after setting the id
197
+ # TODO Update route association only once for each associated record
198
+ update_association: (data) ->
199
+ id = @_id || data && (data._id || data.id)
200
+
201
+ # Keep trying until we have a id
202
+ return unless id
203
+
204
+ for association_name in model[@resource.toString()].has_many
205
+ pluralized_association = model.pluralize association_name
206
+ association = @[pluralized_association]
207
+ # TODO setter of association.route
208
+ # to automatically update associated records
209
+ unless association.route
210
+ association.route = "/#{model.pluralize @resource.toString()}/#{id}/#{model.pluralize association.resource}"
211
+
212
+ for associated in association when not associated.route and associated.parent?
213
+ associated.route = "/#{model.pluralize @resource.toString()}/#{id}/#{model.pluralize association.resource}"
214
+
215
+ true
216
+ autosave: ->
217
+ throw 'Not implemented yet'
218
+ # @save()
219
+
220
+ has_one:
221
+ # Forward association nested attributes
222
+ # TODO write attribute setter, and remove this code
223
+ nest_attributes: ->
224
+ # TODO only nest specified nested attributes on model definition
225
+ # TODO convert to associations instead of association name
226
+ # TODO remove associations iteration, and pass throught parameter
227
+ # TODO DO not support '_attributes' property on instantiating!
228
+ association_names = model[@resource].has_one
229
+ if association_names
230
+ for association_name in association_names
231
+ associations_attributes = @["#{association_name}_attributes"]
232
+ if associations_attributes
233
+ @[association_name] = @["build_#{association_name}"] associations_attributes
234
+ delete @["#{association_name}_attributes"]
235
+
236
+
237
+ # TODO Better association segregation
238
+ associable =
239
+ model:
240
+
241
+ # @ = model instance
242
+ # param definition modable
243
+ blender: (definition) ->
244
+ {model} = associable
245
+
246
+ @create_after_hooks = model.create_after_hooks
247
+ @create_before_hooks = model.create_before_hooks
248
+
249
+ # TODO better default definition of associations
250
+ @has_many = [@has_many ] if @has_many and $.type(@has_many) != 'array'
251
+ @has_one = [@has_one ] if @has_one and $.type(@has_one) != 'array'
252
+ @belongs_to = [@belongs_to] if @belongs_to and $.type(@belongs_to) != 'array'
253
+
254
+ @has_many ||= []
255
+ @has_one ||= []
256
+ @belongs_to ||= []
257
+
258
+ true
259
+
260
+
261
+ # TODO better organisation of this code
262
+ # inside this function: @ = record (running on after_initialize)
263
+ create_after_hooks: (definition) ->
264
+
265
+ # TODO Rename options to definition
266
+ options = model[@resource.name || @resource.toString()]
267
+
268
+ # Create association methods
269
+ # Setup one to many association in model
270
+ if options.has_many
271
+
272
+ # TODO accept more options on has_many association creation
273
+ for resource in options.has_many
274
+ # unless model[resource]
275
+ # throw "Model not found for association with resource '#{resource}', on association 'has_many' "
276
+
277
+ # TODO instantiate default resources in has_many association
278
+ # @resource = model[resource].resource
279
+
280
+ # TODO Remember to clear association proxy when object is destroyed
281
+ association_proxy = resource: resource, parent_resource: @resource, parent: @
282
+ association_name = model.pluralize resource
283
+
284
+ # When deserializing has many associated resources from
285
+ # server, it is common to send as the association without
286
+ # attributes suffix
287
+ association_attributes = @[association_name] || []
288
+ @["#{association_name}_attributes"] ||= []
289
+ @["#{association_name}_attributes"] = @["#{association_name}_attributes"].concat association_attributes if association_attributes.length
290
+
291
+ # Create or Override sent attributes by the association proxy
292
+ @[association_name] = $.extend association_proxy, plural
293
+
294
+
295
+ # Update association attribute
296
+ @after 'saved', callbacks.has_many.update_association
297
+
298
+ # Remove nested attributes and convert them into actual records
299
+ callbacks.has_many.nest_attributes.call @
300
+
301
+ if options.has_one
302
+ for resource in options.has_one
303
+ # unless model[resource]
304
+ # throw "Model not found for association with resource '#{resource}', on association 'has_one' "
305
+
306
+ # TODO deprecate parent_resource
307
+ association_proxy = resource: resource, parent_resource: @resource, owner: @
308
+ association_proxy[@resource.toString()] = @
309
+
310
+ @["build_#{resource}" ] = $.proxy singular.build , association_proxy
311
+ @["create_#{resource}"] = $.proxy singular.create, association_proxy
312
+
313
+
314
+ # When deserializing has one associated resources from
315
+ # server, it is common to send as the association without
316
+ # attributes suffix
317
+ @["#{association_name}_attributes"] = $.extend @[association_name], @["#{association_name}_attributes"]
318
+
319
+ # Update association attribute
320
+ # TODO @after 'saved', callbacks.has_one.update_association
321
+
322
+ # Remove nested attributes and convert them into actual records
323
+ callbacks.has_one.nest_attributes.call @
324
+
325
+ # Externalize this to a file
326
+ if options.belongs_to
327
+ # TODO implement association reflection!
328
+ for resource in options.belongs_to
329
+ # unless model[resource]
330
+ # throw "Model not found for association with resource '#{resource}', on association 'belongs_to' "
331
+
332
+ # TODO put deprecation warning on parent key
333
+ association_proxy = resource: resource, parent_resource: @resource, parent: @, owner: @
334
+
335
+ # TODO see why this code is here, since we have the owner key
336
+ association_proxy[@resource.toString()] = @
337
+
338
+ @["build_#{resource}"] = $.proxy singular.build , association_proxy
339
+ @["create_#{resource}"] = $.proxy singular.create, association_proxy
340
+
341
+ # TODO copy from active record and better modularization of
342
+ # this internals
343
+ # To prevent association loading request we must nullify the
344
+ # association when subscribing
345
+ old_resource_id = @["#{resource}_id"]
346
+ old_dirty = @dirty
347
+ @["#{resource}_id"] = null
348
+
349
+ # TODO implement as a class
350
+ Object.defineProperty @, "#{resource}_id",
351
+ get: $.proxy descriptors.belongs_to.resource_id.getter, association_proxy
352
+ set: $.proxy descriptors.belongs_to.resource_id.setter, association_proxy
353
+ configurable: true
354
+
355
+ # Restore id after loader prevention has passed
356
+ @["#{resource}_id"] = old_resource_id
357
+ @dirty = old_dirty
358
+
359
+ # Execute relation attributes binding
360
+ # TODO validate bindings! When @resource._id != @["#{resource}_id"]
361
+ # TODO write test for this case
362
+ # if @["#{resource}_id"] and not @[resource]
363
+ # @publish "#{resource}_id", @["#{resource}_id"]
364
+
365
+ # TODO better organization of this code, probably transforming the
366
+ # association into a composable object inside this function: @ =
367
+ # record (running on before_initialize) Beware there is no
368
+ # advisable or observable features
369
+ # @ = model
370
+ # param record = record instance
371
+ create_before_hooks: (record) ->
372
+ definition = @
373
+
374
+ # TODO Externalize this to a file
375
+ if definition.belongs_to
376
+
377
+ # TODO implement association reflection!
378
+ for resource in definition.belongs_to
379
+ # unless model[resource]
380
+ # throw "Model not found for association with resource '#{resource}', on association 'belongs_to' "
381
+
382
+ # TODO put deprecation warning on parent key
383
+ association_proxy = resource: resource, parent_resource: @resource, owner: record
384
+
385
+ old_resource = record[resource]
386
+ old_resource_id = record[resource + '_id']
387
+
388
+ Object.defineProperty record, resource.toString(),
389
+ get: $.proxy descriptors.belongs_to.resource.getter, association_proxy
390
+ set: $.proxy descriptors.belongs_to.resource.setter, association_proxy
391
+ configurable: true
392
+
393
+ # Execute setter in order to do the apropriate actions to
394
+ # the previoulsy stored value in the association property
395
+ # TODO fix the prototype chain and remove this code
396
+ record.after_initialize.push (-> (@[resource] = old_resource) or (@[resource + '_id'] = old_resource_id))
397
+
398
+ # @ = record
399
+ record:
400
+ after_initialize: (attributes) ->
401
+ throw new Error 'resource must be defined in order to associate' unless @resource?
402
+ model[@resource.name || @resource.toString()].create_after_hooks.call @
403
+
404
+ before_initialize: (creation) ->
405
+ throw new Error 'resource must be defined in order to associate' unless @resource
406
+ model[@resource.name || @resource.toString()].create_before_hooks creation
407
+
408
+
409
+ # Extend indemma
410
+ model = root.model # TODO better way to get parent
411
+ model.mix (modelable) ->
412
+ modelable.after_mix.push associable.model.blender
413
+ modelable.record.before_initialize.push associable.record.before_initialize
414
+ modelable.record.after_initialize.push associable.record.after_initialize
415
+
416
+ # This allows to extendind the associable mixin
417
+ model.associable =
418
+ mix : (blender) ->
419
+ blender singular, plural
@@ -0,0 +1,47 @@
1
+ 'use strict'
2
+
3
+ dirtyable =
4
+ # TODO move ignored diryifing properties to the record
5
+ ignores: ['dirty', 'resource', 'route', 'initial_route', 'after_initialize', 'before_initialize', 'parent_resource', 'nested_attributes', 'reloading', 'ready', 'saving', 'saved', 'failed', 'salvation', 'sustained', 'element', 'default', 'lock', 'validate', 'validated', 'validation', 'errors', 'dirty', 'json']
6
+ reserved_filter: (name) -> @ignores.indexOf(name) == -1
7
+ record:
8
+ after_initialize: [ ->
9
+ @subscribe (added, removed, changed, past) ->
10
+ @dirty ||= !!Object.keys($.extend {}, added, removed, changed).filter(dirtyable.reserved_filter, dirtyable).length
11
+ ]
12
+
13
+ # Shim browsers without Object.observe
14
+ unless Object.observe
15
+
16
+ $.extend dirtyable,
17
+ descriptor:
18
+ get: -> @observed.dirty
19
+ set: (value) ->
20
+ @observed.dirty = value
21
+ @observation.scheduler.schedule()
22
+ value
23
+
24
+ dirtyable.record.after_initialize.push ->
25
+ Object.defineProperty @, 'dirty', dirtyable.descriptor
26
+
27
+ # Automatically dirt records without id
28
+ # FIXME
29
+ dirtyable.record.after_initialize.push ->
30
+ # TODO rename _id to id
31
+ @dirty = !!@_id
32
+
33
+
34
+
35
+ # Extend indemma
36
+ model = window.model # TODO better way to get parent
37
+ record = window.record # TODO better way to get parent
38
+
39
+ model.dirtyable = true
40
+
41
+ record.mix (recordable) ->
42
+ recordable.after_initialize = recordable.after_initialize.concat dirtyable.record.after_initialize
43
+
44
+ model.mix (modelable ) ->
45
+ # merge modelable , restful.model
46
+
47
+ `export default dirtyable`
@@ -0,0 +1,20 @@
1
+ # TODO externalize errorsable from validatable
2
+ # errorsable = stampit
3
+ # add: (attribute, message_key, options) ->
4
+ #
5
+ # @push [attribute, message_key, options]
6
+ # @messages[attribute_name] messages[message_key](attribute_name)
7
+ #
8
+ # clear: ->
9
+ # if @length
10
+ # @length = 0
11
+ # @messages = {}
12
+ #
13
+ # push: Array.prototype.push
14
+ # splice: Array.prototype.splice
15
+ # ,
16
+ # messages: {}
17
+ # length: 0
18
+ # , ->
19
+ # @messages = []
20
+ # @
@@ -0,0 +1,16 @@
1
+ maid =
2
+
3
+ model : ->
4
+ @record.after_initialize.push maid.record if @washing?
5
+
6
+ record: ->
7
+
8
+ @subscribe 'dirty', (dirty) ->
9
+ dirty && setTimeout =>
10
+ @save()
11
+ , 500
12
+
13
+ # Extend indemma
14
+ model = window.model
15
+ model.mix (modelable) ->
16
+ modelable.after_mix.unshift maid.model
@@ -0,0 +1,34 @@
1
+ require './queryable'
2
+
3
+ handlers =
4
+ store_after_saved: ->
5
+ # TODO remove global model usage
6
+ {storage} = model[@resource.toString()]
7
+
8
+ # TODO check persistable configuration before attaching handlers
9
+ # and remove the @_id presence check
10
+ storage.store @_id, @ if @_id
11
+
12
+
13
+ persistable =
14
+ record:
15
+ # TODO better caching check after resource initialization
16
+ # TODO think how to retrieve already stored resources
17
+ after_initialize: ->
18
+ if @_id
19
+ # TODO remove global model usage
20
+ {storage} = model[@resource.toString()]
21
+ storage.store @_id, @
22
+ else
23
+ # TODO check persistable configuration before attaching handlers
24
+ @after 'saved', handlers.store_after_saved
25
+
26
+ # Extend indemma
27
+ # TODO use stampit to extend record and model
28
+ model = window.model # TODO better way to get parent
29
+ record = window.record # TODO better way to get parent
30
+
31
+ model.persistable = true
32
+
33
+ model.mix (modelable) ->
34
+ modelable.record.after_initialize.push persistable.record.after_initialize
@@ -0,0 +1,29 @@
1
+ extend = require 'assimilate'
2
+ storable = require './storable'
3
+ # merge = extend.withStrategy 'deep'
4
+ stampit = require '../../vendor/stampit'
5
+
6
+ queryable =
7
+ # FIXME don't let everyone use the same storage instance! or let it?
8
+ storage: storable()
9
+ find: (key) ->
10
+ throw new TypeError "InvalidFind: #{@resource.toString()}.find was called with a falsey value" unless key
11
+ @storage.store key
12
+ every: (callback) -> callback @storage.values()
13
+ where: ->
14
+ throw new Error 'queryable.where: Not implemented yet'
15
+
16
+ # Extend indemma
17
+ # TODO use stampit to extend record and model
18
+ model = window.model # TODO better way to get parent
19
+ record = window.record # TODO better way to get parent
20
+
21
+ # queryable = stampit.compose queryable, storable
22
+
23
+
24
+ model.queryable = true
25
+ module.exports = queryable
26
+
27
+ model.mix (modelable) ->
28
+ # TODO use stampit to extend record and model
29
+ extend modelable, queryable
@@ -0,0 +1,107 @@
1
+ stampit = require '../../vendor/stampit'
2
+ require '../../vendor/owl/pluralize'
3
+
4
+ # TODO Think of a better name
5
+ resource = stampit
6
+ toString: -> @name
7
+ # TODO move resourceable.route() to here
8
+ ,
9
+ name : 'unknown'
10
+ scope : null
11
+ singular: false
12
+ , ->
13
+
14
+ # TODO better integration with record.coffee, and stop storing
15
+ # original reference
16
+ if @original_reference
17
+ stampit.mixIn @original_reference, @
18
+ @original_reference.toString = @toString
19
+ @original_reference.param_name ||= @name
20
+
21
+ return @original_reference
22
+
23
+ @param_name ||= @name
24
+
25
+ @
26
+
27
+ # TODO Think of a better name, and move to a composable stampit item
28
+ # TODO Externalize route generatio so we can reuse in other files
29
+ descriptors =
30
+ route:
31
+ get: ->
32
+ # TODO use resource object on associations!
33
+ @resource = name: @resource if typeof @resource == 'string'
34
+
35
+ route = '/'
36
+ route += "#{@parent.route}/#{@parent._id}" + "/" if @parent?
37
+ route += @resource.scope + '/' if @resource.scope?
38
+
39
+ route += if @resource.singular then @resource.name else model.pluralize @resource.name
40
+
41
+ @route = route
42
+
43
+ configurable: true
44
+ # set: (value) -> @initial_route = value
45
+
46
+ # TODO Deprecated! Remove on 15/02/2014
47
+ # parent_id:
48
+ # get: -> @[@parent_resource]._id if @[@parent_resource]
49
+ # set: -> console.error 'Warning changing associations throught parent_id not allowed for security and style guide purposes' # TODO
50
+ # configurable: true
51
+ # enumerable: true
52
+
53
+ # TODO Think of a better name, and move to a composable stampit item
54
+ resourceable =
55
+ pluralize: (word, count, plural) ->
56
+ throw new TypeError "Invalid string passed to pluralize '#{word}'" unless word and word.length
57
+
58
+ unless word.indexOf('s') == word.length - 1
59
+ owl.pluralize word, count, plural
60
+ else
61
+ word
62
+
63
+ singularize: (word) ->
64
+ throw new TypeError "Invalid string passed to singularize '#{word}'" unless word and word.length
65
+
66
+ if word.lastIndexOf('s') == word.length - 1
67
+ word.substring 0, word.length - 1
68
+ else
69
+ word
70
+
71
+ initialize: ->
72
+
73
+ # Deprecated! Remove on 15/02/2014
74
+ # Set parent attribute and default nested route
75
+ # If you're using the associable plugin, this getter and setter will be overwritten!
76
+ # if @parent_resource
77
+ # Object.defineProperty @, "#{@parent_resource}_id", descriptors.parent_id
78
+
79
+ # Setup resource
80
+ resource_definition = {}
81
+ resource_definition = name: @resource if typeof @resource == 'string'
82
+ if typeof @resource == 'object'
83
+ # TODO deeper resource integration with record.coffee, and remove original reference
84
+ # To prevent reference lost and allow dinamic modification of resources
85
+ # we need to preserve the original reference
86
+ @resource.original_reference = @resource
87
+
88
+ resource_definition = @resource
89
+
90
+ # TODO remove mentions of @parent_resource and use only resource: {parent: ...}
91
+ resource_definition.parent = @parent_resource
92
+
93
+ @resource = resource resource_definition
94
+
95
+ # TODO Support route parsing, and change route to /parents/:id/childrens
96
+ @route ? Object.defineProperty @, 'route', descriptors.route
97
+
98
+
99
+ # Extend indemma
100
+ model = window.model # TODO better way to get parent
101
+
102
+ model.mix (modelable) ->
103
+ modelable.record.after_initialize.unshift resourceable.initialize
104
+ modelable.after_mix.unshift resourceable.initialize
105
+
106
+ model.singularize = resourceable.singularize
107
+ model.pluralize = resourceable.pluralize