ende 0.2.9 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/assets/javascripts/aura/extensions/devise.js.coffee +2 -2
- data/lib/assets/javascripts/widgets/viewer/main.js.coffee +1 -1
- data/lib/ende/version.rb +1 -1
- data/vendor/assets/components/build.js +638 -133
- data/vendor/components/indefinido-indemma/.gitignore +14 -0
- data/vendor/components/indefinido-indemma/.gitignore~ +2 -0
- data/vendor/components/indefinido-indemma/.ruby-gemset +1 -0
- data/vendor/components/indefinido-indemma/.ruby-version +1 -0
- data/vendor/components/indefinido-indemma/Gemfile +13 -0
- data/vendor/components/indefinido-indemma/Guardfile +39 -0
- data/vendor/components/indefinido-indemma/History.md +0 -0
- data/vendor/components/indefinido-indemma/Readme.md +447 -0
- data/vendor/components/indefinido-indemma/build/development.js +340 -0
- data/vendor/components/indefinido-indemma/build/release.js +22039 -0
- data/vendor/components/indefinido-indemma/build/test.js +22039 -0
- data/vendor/components/indefinido-indemma/component.json +7 -3
- data/vendor/components/indefinido-indemma/components/chaijs-assertion-error/component.json +18 -0
- data/vendor/components/indefinido-indemma/components/chaijs-assertion-error/index.js +110 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/component.json +47 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/index.js +1 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/assertion.js +130 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/core/assertions.js +1270 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/interface/assert.js +1080 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/interface/expect.js +12 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/interface/should.js +76 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/addChainableMethod.js +94 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/addMethod.js +37 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/addProperty.js +40 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/eql.js +129 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/flag.js +32 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/getActual.js +19 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/getEnumerableProperties.js +25 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/getMessage.js +49 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/getName.js +20 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/getPathValue.js +102 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/getProperties.js +35 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/index.js +108 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/inspect.js +320 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/objDisplay.js +48 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/overwriteMethod.js +51 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/overwriteProperty.js +54 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/test.js +26 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/transferFlags.js +44 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai/utils/type.js +45 -0
- data/vendor/components/indefinido-indemma/components/chaijs-chai/lib/chai.js +80 -0
- data/vendor/components/indefinido-indemma/components/component-bind/component.json +14 -0
- data/vendor/components/indefinido-indemma/components/component-bind/index.js +24 -0
- data/vendor/components/indefinido-indemma/components/component-jquery/component.json +14 -0
- data/vendor/components/indefinido-indemma/components/component-jquery/index.js +9601 -0
- data/vendor/components/indefinido-indemma/components/component-type/component.json +18 -0
- data/vendor/components/indefinido-indemma/components/component-type/index.js +32 -0
- data/vendor/components/indefinido-indemma/components/indefinido-advisable/component.json +21 -0
- data/vendor/components/indefinido-indemma/components/indefinido-advisable/index.js +1 -0
- data/vendor/components/indefinido-indemma/components/indefinido-advisable/lib/advisable.js +60 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/component.json +25 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/components/cjohansen-sinon/sinon.js +4290 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/index.js +1 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/lib/adapters/rivets.js +26 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/lib/observable.js +323 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/vendor/shims/accessors-legacy.js +92 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/vendor/shims/accessors.js +173 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/vendor/shims/array.indexOf.js +8 -0
- data/vendor/components/indefinido-indemma/components/indefinido-observable/vendor/shims/object.create.js +77 -0
- data/vendor/components/indefinido-indemma/components/kapit-observe-utils/component.json +13 -0
- data/vendor/components/indefinido-indemma/components/paulmillr-es6-shim/component.json +17 -0
- data/vendor/components/indefinido-indemma/components/paulmillr-es6-shim/es6-shim.js +996 -0
- data/vendor/components/indefinido-indemma/components/pluma-assimilate/component.json +25 -0
- data/vendor/components/indefinido-indemma/components/pluma-assimilate/dist/assimilate.js +127 -0
- data/vendor/components/indefinido-indemma/karma.conf.js +86 -0
- data/vendor/components/indefinido-indemma/lib/record/associable.js +229 -82
- data/vendor/components/indefinido-indemma/lib/record/errors.js +1 -0
- data/vendor/components/indefinido-indemma/lib/record/persistable.js +32 -0
- data/vendor/components/indefinido-indemma/lib/record/queryable.js +32 -0
- data/vendor/components/indefinido-indemma/lib/record/resource.js +12 -4
- data/vendor/components/indefinido-indemma/lib/record/rest.js +1 -1
- data/vendor/components/indefinido-indemma/lib/record/restfulable.js +38 -27
- data/vendor/components/indefinido-indemma/lib/record/scopable.js +15 -2
- data/vendor/components/indefinido-indemma/lib/record/storable.js +48 -0
- data/vendor/components/indefinido-indemma/lib/record/validatable.js +10 -5
- data/vendor/components/indefinido-indemma/lib/record/validations/cpf.js +1 -1
- data/vendor/components/indefinido-indemma/lib/record.js +15 -12
- data/vendor/components/indefinido-indemma/spec/record/associable_spec.js +137 -0
- data/vendor/components/indefinido-indemma/spec/record/persistable_spec.js +36 -0
- data/vendor/components/indefinido-indemma/spec/record/queryable_spec.js +33 -0
- data/vendor/components/indefinido-indemma/spec/record/resource_spec.js +93 -0
- data/vendor/components/indefinido-indemma/spec/record/rest_spec.js +32 -0
- data/vendor/components/indefinido-indemma/spec/record/restfulable_spec.js +288 -0
- data/vendor/components/indefinido-indemma/spec/record/scopable_spec.js +212 -0
- data/vendor/components/indefinido-indemma/spec/record/storable_spec.js +53 -0
- data/vendor/components/indefinido-indemma/spec/record/translationable.js +28 -0
- data/vendor/components/indefinido-indemma/spec/record/validatable_spec.js +111 -0
- data/vendor/components/indefinido-indemma/spec/record/validations/associated_spec.js +43 -0
- data/vendor/components/indefinido-indemma/spec/record/validations/confirmation_spec.js +36 -0
- data/vendor/components/indefinido-indemma/spec/record/validations/cpf_spec.js +35 -0
- data/vendor/components/indefinido-indemma/spec/record/validations/presence_spec.js +28 -0
- data/vendor/components/indefinido-indemma/spec/record/validations/remote_spec.js +87 -0
- data/vendor/components/indefinido-indemma/spec/record/validations/type_spec.js +48 -0
- data/vendor/components/indefinido-indemma/spec/record_spec.js +37 -0
- data/vendor/components/indefinido-indemma/spec/spec_helper.js +11 -0
- data/vendor/components/indefinido-indemma/spec/support/value_objects/phone.js +45 -0
- data/vendor/components/indefinido-indemma/src/lib/extensions/rivets.coffee +17 -0
- data/vendor/components/indefinido-indemma/src/lib/record/associable.coffee +342 -0
- data/vendor/components/indefinido-indemma/src/lib/record/errors.coffee +20 -0
- data/vendor/components/indefinido-indemma/src/lib/record/maid.coffee +16 -0
- data/vendor/components/indefinido-indemma/src/lib/record/persistable.coffee +27 -0
- data/vendor/components/indefinido-indemma/src/lib/record/queryable.coffee +29 -0
- data/vendor/components/indefinido-indemma/src/lib/record/resource.coffee +106 -0
- data/vendor/components/indefinido-indemma/src/lib/record/rest.coffee +28 -0
- data/vendor/components/indefinido-indemma/src/lib/record/restfulable.coffee +348 -0
- data/vendor/components/indefinido-indemma/src/lib/record/scopable.coffee +275 -0
- data/vendor/components/indefinido-indemma/src/lib/record/storable.coffee +46 -0
- data/vendor/components/indefinido-indemma/src/lib/record/translationable.coffee +18 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validatable.coffee +217 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validations/associated.coffee +32 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validations/confirmation.coffee +19 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validations/cpf.coffee +58 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validations/presence.coffee +19 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validations/remote.coffee +65 -0
- data/vendor/components/indefinido-indemma/src/lib/record/validations/type.coffee +32 -0
- data/vendor/components/indefinido-indemma/src/lib/record.coffee +136 -0
- data/vendor/components/indefinido-indemma/src/spec/record/associable_spec.coffee +130 -0
- data/vendor/components/indefinido-indemma/src/spec/record/persistable_spec.coffee +30 -0
- data/vendor/components/indefinido-indemma/src/spec/record/queryable_spec.coffee +27 -0
- data/vendor/components/indefinido-indemma/src/spec/record/resource_spec.coffee +69 -0
- data/vendor/components/indefinido-indemma/src/spec/record/rest_spec.coffee +22 -0
- data/vendor/components/indefinido-indemma/src/spec/record/restfulable_spec.coffee +207 -0
- data/vendor/components/indefinido-indemma/src/spec/record/scopable_spec.coffee +191 -0
- data/vendor/components/indefinido-indemma/src/spec/record/storable_spec.coffee +40 -0
- data/vendor/components/indefinido-indemma/src/spec/record/translationable.coffee +19 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validatable_spec.coffee +100 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validations/associated_spec.coffee +35 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validations/confirmation_spec.coffee +25 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validations/cpf_spec.coffee +28 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validations/presence_spec.coffee +24 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validations/remote_spec.coffee +74 -0
- data/vendor/components/indefinido-indemma/src/spec/record/validations/type_spec.coffee +33 -0
- data/vendor/components/indefinido-indemma/src/spec/record_spec.coffee +23 -0
- data/vendor/components/indefinido-indemma/src/spec/spec_helper.coffee +9 -0
- data/vendor/components/indefinido-indemma/src/spec/support/value_objects/phone.coffee +30 -0
- data/vendor/components/indefinido-indemma/vendor/object/mixin.js +196 -0
- data/vendor/components/indefinido-indemma/vendor/owl/pluralize.js +190 -0
- metadata +130 -2
|
@@ -0,0 +1,342 @@
|
|
|
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
|
+
|
|
24
|
+
# TODO Setup a before save callback to generate route when there is no id
|
|
25
|
+
data.route ||= "#{@parent.route}/#{@parent._id}/#{model.pluralize @resource.toString()}" if @parent?
|
|
26
|
+
throw "associable.has_many: cannot redefine route of association #{@parent_resource}.#{@resource} from #{@route} to #{data.route}" if @route isnt data.route and @route
|
|
27
|
+
# Adds parent record to children side of association, if not set
|
|
28
|
+
# TODO check if this reference is unmade on instance elimination
|
|
29
|
+
data[@parent_resource] ||= @parent
|
|
30
|
+
|
|
31
|
+
# TODO store a singular copy of the resource for better performace
|
|
32
|
+
model[model.singularize @resource] data
|
|
33
|
+
push : ->
|
|
34
|
+
console.warn "#{@resource}.push is deprecated and will be removed, please use add instead"
|
|
35
|
+
Array.prototype.push.apply @, arguments
|
|
36
|
+
|
|
37
|
+
length : 0
|
|
38
|
+
json : (methods, omissions) -> record.json(methods, omissions) for record in @
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
singular = # belongs_to, has_one ## TODO embeds_one, embedded_in
|
|
42
|
+
# @ = record
|
|
43
|
+
create: (data) -> model[@resource].create extend {}, @, data
|
|
44
|
+
# @ = record
|
|
45
|
+
# TODO convert to association proxy
|
|
46
|
+
build : (data) ->
|
|
47
|
+
# Adds child record of association to parent, and returns new
|
|
48
|
+
# record
|
|
49
|
+
@owner[@resource.toString()] = model[@resource.toString()] extend {}, @, data
|
|
50
|
+
|
|
51
|
+
subscribers =
|
|
52
|
+
belongs_to:
|
|
53
|
+
foreign_key: (resource_id) ->
|
|
54
|
+
association_name = @resource.toString()
|
|
55
|
+
|
|
56
|
+
# TODO faster nullifing association check
|
|
57
|
+
# TODO only allow nullifying with null
|
|
58
|
+
if resource_id == null or resource_id == undefined
|
|
59
|
+
@dirty = true
|
|
60
|
+
@owner[association_name] = resource_id
|
|
61
|
+
return resource_id
|
|
62
|
+
|
|
63
|
+
# TODO Discover and update inverse side of association
|
|
64
|
+
# associated[@owner.resource.toString()] = @owner
|
|
65
|
+
current_resource_id = @owner[association_name]?._id
|
|
66
|
+
if resource_id != current_resource_id
|
|
67
|
+
# Update association with blank resource that will update
|
|
68
|
+
resource = model[association_name]
|
|
69
|
+
unless resource
|
|
70
|
+
console.warn "subscribers.belongs_to.foreign_key: associated factory not found for model: #{association_name}"
|
|
71
|
+
return resource_id
|
|
72
|
+
|
|
73
|
+
# TODO remote find or local find automatically, and implement find_or_initialize_by
|
|
74
|
+
associated = resource.find resource_id
|
|
75
|
+
associated ||= resource _id: resource_id
|
|
76
|
+
|
|
77
|
+
@owner.observed[association_name] = associated
|
|
78
|
+
|
|
79
|
+
resource_id
|
|
80
|
+
|
|
81
|
+
# Called when associated record changes, so we can silently update the id
|
|
82
|
+
associated_changed: (associated) ->
|
|
83
|
+
@owner.observed["#{@resource.toString()}_id"] = if associated then associated._id else null
|
|
84
|
+
|
|
85
|
+
modifiers =
|
|
86
|
+
# Called before record initialization to create the a lazy loader
|
|
87
|
+
# for other records
|
|
88
|
+
belongs_to:
|
|
89
|
+
associated_loader: ->
|
|
90
|
+
association_name = @resource.toString()
|
|
91
|
+
|
|
92
|
+
Object.defineProperty @owner, association_name,
|
|
93
|
+
# Observable already sets property for us
|
|
94
|
+
set: (associated) ->
|
|
95
|
+
@observed[association_name] = associated
|
|
96
|
+
|
|
97
|
+
get: =>
|
|
98
|
+
associated = @owner.observed[association_name]
|
|
99
|
+
associated_id = @owner.observed[association_name + '_id']
|
|
100
|
+
|
|
101
|
+
# Returns null or undefined depending on sustained state of
|
|
102
|
+
# resource and on retrievability of the resource
|
|
103
|
+
return associated unless associated?._id? or associated_id
|
|
104
|
+
|
|
105
|
+
# Retunrs imediatelly for resources on storage
|
|
106
|
+
# TODO make this extenxible
|
|
107
|
+
return associated if associated?.sustained
|
|
108
|
+
|
|
109
|
+
resource = model[association_name]
|
|
110
|
+
unless resource
|
|
111
|
+
console.warn "subscribers.belongs_to.foreign_key: associated factory not found for model: #{association_name}"
|
|
112
|
+
return associated
|
|
113
|
+
|
|
114
|
+
associated = resource.find associated_id || associated._id
|
|
115
|
+
associated ||= resource _id: associated_id
|
|
116
|
+
|
|
117
|
+
resource.storage.store associated._id, associated
|
|
118
|
+
associated.reload()
|
|
119
|
+
|
|
120
|
+
@owner.observed[association_name] = associated
|
|
121
|
+
|
|
122
|
+
configurable: true
|
|
123
|
+
enumerable: true
|
|
124
|
+
|
|
125
|
+
callbacks =
|
|
126
|
+
has_many:
|
|
127
|
+
# Forward association nested attributes
|
|
128
|
+
# TODO write attribute setter, and remove this code
|
|
129
|
+
nest_attributes: ->
|
|
130
|
+
# TODO only nest specified nested attributes on model definition
|
|
131
|
+
# TODO remove associations iteration, and pass throught parameter
|
|
132
|
+
# TODO DO not support '_attributes' property on instantiating!
|
|
133
|
+
association_names = model[@resource].has_many
|
|
134
|
+
if association_names
|
|
135
|
+
for association_name in association_names
|
|
136
|
+
associations_attributes = @["#{association_name}_attributes"]
|
|
137
|
+
if associations_attributes and associations_attributes.length
|
|
138
|
+
association = @[model.pluralize association_name]
|
|
139
|
+
|
|
140
|
+
unless association
|
|
141
|
+
message = "has_many.nest_attributes: Association not found for #{association_name}. \n"
|
|
142
|
+
message += "did you set it on model declaration? \n has_many: #{association_name} "
|
|
143
|
+
throw message
|
|
144
|
+
|
|
145
|
+
# TODO store a singular copy of the resource for better performace
|
|
146
|
+
association.resource = model.singularize association.resource
|
|
147
|
+
association.add.apply association, associations_attributes
|
|
148
|
+
association.resource = model.pluralize association.resource
|
|
149
|
+
|
|
150
|
+
# TODO Update route after setting the id
|
|
151
|
+
# TODO Update route association only once for each associated record
|
|
152
|
+
update_association: (data) ->
|
|
153
|
+
id = @_id || data && (data._id || data.id)
|
|
154
|
+
|
|
155
|
+
# Keep trying until we have a id
|
|
156
|
+
return unless id
|
|
157
|
+
|
|
158
|
+
for association_name in model[@resource.toString()].has_many
|
|
159
|
+
pluralized_association = model.pluralize association_name
|
|
160
|
+
association = @[pluralized_association]
|
|
161
|
+
# TODO setter of association.route
|
|
162
|
+
# to automatically update associated records
|
|
163
|
+
unless association.route
|
|
164
|
+
association.route = "/#{model.pluralize @resource.toString()}/#{id}/#{model.pluralize association.resource}"
|
|
165
|
+
|
|
166
|
+
for associated in association when not associated.route and associated.parent?
|
|
167
|
+
associated.route = "/#{model.pluralize @resource.toString()}/#{id}/#{model.pluralize association.resource}"
|
|
168
|
+
|
|
169
|
+
true
|
|
170
|
+
autosave: ->
|
|
171
|
+
throw 'Not implemented yet'
|
|
172
|
+
# @save()
|
|
173
|
+
|
|
174
|
+
has_one:
|
|
175
|
+
# Forward association nested attributes
|
|
176
|
+
# TODO write attribute setter, and remove this code
|
|
177
|
+
nest_attributes: ->
|
|
178
|
+
# TODO only nest specified nested attributes on model definition
|
|
179
|
+
# TODO convert to associations instead of association name
|
|
180
|
+
# TODO remove associations iteration, and pass throught parameter
|
|
181
|
+
# TODO DO not support '_attributes' property on instantiating!
|
|
182
|
+
association_names = model[@resource].has_one
|
|
183
|
+
if association_names
|
|
184
|
+
for association_name in association_names
|
|
185
|
+
associations_attributes = @["#{association_name}_attributes"]
|
|
186
|
+
if associations_attributes
|
|
187
|
+
@[association_name] = @["build_#{association_name}"] associations_attributes
|
|
188
|
+
delete @["#{association_name}_attributes"]
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# TODO Better association segregation
|
|
192
|
+
associable =
|
|
193
|
+
model:
|
|
194
|
+
|
|
195
|
+
# @ = model instance
|
|
196
|
+
# param definition modable
|
|
197
|
+
blender: (definition) ->
|
|
198
|
+
{model} = associable
|
|
199
|
+
|
|
200
|
+
@create_after_hooks = model.create_after_hooks
|
|
201
|
+
@create_before_hooks = model.create_before_hooks
|
|
202
|
+
|
|
203
|
+
# TODO better default definition of associations
|
|
204
|
+
@has_many = [@has_many ] if @has_many and $.type(@has_many) != 'array'
|
|
205
|
+
@has_one = [@has_one ] if @has_one and $.type(@has_one) != 'array'
|
|
206
|
+
@belongs_to = [@belongs_to] if @belongs_to and $.type(@belongs_to) != 'array'
|
|
207
|
+
|
|
208
|
+
@has_many ||= []
|
|
209
|
+
@has_one ||= []
|
|
210
|
+
@belongs_to ||= []
|
|
211
|
+
|
|
212
|
+
true
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
# TODO better organisation of this code
|
|
216
|
+
# inside this function: @ = record (running on after_initialize)
|
|
217
|
+
create_after_hooks: (definition) ->
|
|
218
|
+
|
|
219
|
+
# TODO Rename options to definition
|
|
220
|
+
options = model[@resource.name || @resource.toString()]
|
|
221
|
+
|
|
222
|
+
# Create association methods
|
|
223
|
+
# Setup one to many association in model
|
|
224
|
+
if options.has_many
|
|
225
|
+
|
|
226
|
+
# TODO accept more options on has_many association creation
|
|
227
|
+
for resource in options.has_many
|
|
228
|
+
# unless model[resource]
|
|
229
|
+
# throw "Model not found for association with resource '#{resource}', on association 'has_many' "
|
|
230
|
+
|
|
231
|
+
# TODO instantiate default resources in has_many association
|
|
232
|
+
# @resource = model[resource].resource
|
|
233
|
+
|
|
234
|
+
# TODO Remember to clear association proxy when object is destroyed
|
|
235
|
+
association_proxy = resource: resource, parent_resource: @resource, parent: @
|
|
236
|
+
association_name = model.pluralize resource
|
|
237
|
+
@[association_name] = $.extend association_proxy, plural
|
|
238
|
+
|
|
239
|
+
# Update association attribute
|
|
240
|
+
@after 'saved', callbacks.has_many.update_association
|
|
241
|
+
|
|
242
|
+
# Forward nested attributes
|
|
243
|
+
callbacks.has_many.nest_attributes.call @
|
|
244
|
+
|
|
245
|
+
if options.has_one
|
|
246
|
+
for resource in options.has_one
|
|
247
|
+
# unless model[resource]
|
|
248
|
+
# throw "Model not found for association with resource '#{resource}', on association 'has_one' "
|
|
249
|
+
|
|
250
|
+
# TODO deprecate parent_resource
|
|
251
|
+
association_proxy = resource: resource, parent_resource: @resource, owner: @
|
|
252
|
+
association_proxy[@resource.toString()] = @
|
|
253
|
+
|
|
254
|
+
@["build_#{resource}" ] = $.proxy singular.build , association_proxy
|
|
255
|
+
@["create_#{resource}"] = $.proxy singular.create, association_proxy
|
|
256
|
+
|
|
257
|
+
# Update association attribute
|
|
258
|
+
# TODO @after 'saved', callbacks.has_many.update_association
|
|
259
|
+
|
|
260
|
+
# Forward nested attributes
|
|
261
|
+
callbacks.has_one.nest_attributes.call @
|
|
262
|
+
|
|
263
|
+
# Externalize this to a file
|
|
264
|
+
if options.belongs_to
|
|
265
|
+
# TODO implement association reflection!
|
|
266
|
+
for resource in options.belongs_to
|
|
267
|
+
# unless model[resource]
|
|
268
|
+
# throw "Model not found for association with resource '#{resource}', on association 'belongs_to' "
|
|
269
|
+
|
|
270
|
+
# TODO put deprecation warning on parent key
|
|
271
|
+
association_proxy = resource: resource, parent_resource: @resource, parent: @, owner: @
|
|
272
|
+
|
|
273
|
+
# TODO see why this code is here, since we have the owner key
|
|
274
|
+
association_proxy[@resource.toString()] = @
|
|
275
|
+
|
|
276
|
+
@["build_#{resource}" ] = $.proxy singular.build , association_proxy
|
|
277
|
+
@["create_#{resource}"] = $.proxy singular.create, association_proxy
|
|
278
|
+
|
|
279
|
+
# TODO copy from active record and better modularization of
|
|
280
|
+
# this internals
|
|
281
|
+
# To prevent association loading request we must nullify the
|
|
282
|
+
# association when subscribing
|
|
283
|
+
old_resource_id = @["#{resource}_id"]
|
|
284
|
+
@["#{resource}_id"] = null
|
|
285
|
+
|
|
286
|
+
@subscribe "#{resource}_id" , $.proxy subscribers.belongs_to.foreign_key, association_proxy
|
|
287
|
+
@subscribe resource.toString(), $.proxy subscribers.belongs_to.associated_changed, association_proxy
|
|
288
|
+
|
|
289
|
+
# Restore id after loader prevention has passed
|
|
290
|
+
@resource_id = old_resource_id
|
|
291
|
+
|
|
292
|
+
# Execute relation attributes binding
|
|
293
|
+
# TODO validate bindings! When @resource._id != @["#{resource}_id"]
|
|
294
|
+
# TODO write test for this case
|
|
295
|
+
if @["#{resource}_id"] and not @[resource]
|
|
296
|
+
@publish "#{resource}_id", @["#{resource}_id"]
|
|
297
|
+
|
|
298
|
+
# TODO better organization of this code, probably transforming the
|
|
299
|
+
# association into a composable object inside this function: @ =
|
|
300
|
+
# record (running on before_initialize) Beware there is no
|
|
301
|
+
# advisable or observable features
|
|
302
|
+
# @ = model
|
|
303
|
+
# param record = record instance
|
|
304
|
+
create_before_hooks: (record) ->
|
|
305
|
+
definition = @
|
|
306
|
+
|
|
307
|
+
# TODO Externalize this to a file
|
|
308
|
+
if definition.belongs_to
|
|
309
|
+
|
|
310
|
+
# TODO implement association reflection!
|
|
311
|
+
for resource in definition.belongs_to
|
|
312
|
+
# unless model[resource]
|
|
313
|
+
# throw "Model not found for association with resource '#{resource}', on association 'belongs_to' "
|
|
314
|
+
|
|
315
|
+
# TODO put deprecation warning on parent key
|
|
316
|
+
association_proxy = resource: resource, parent_resource: @resource, owner: record
|
|
317
|
+
|
|
318
|
+
modifiers.belongs_to.associated_loader.call association_proxy
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
# @ = record
|
|
322
|
+
record:
|
|
323
|
+
after_initialize: (attributes) ->
|
|
324
|
+
throw new Error 'resource must be defined in order to associate' unless @resource?
|
|
325
|
+
model[@resource.name || @resource.toString()].create_after_hooks.call @
|
|
326
|
+
|
|
327
|
+
before_initialize: (creation) ->
|
|
328
|
+
throw new Error 'resource must be defined in order to associate' unless @resource
|
|
329
|
+
model[@resource.name || @resource.toString()].create_before_hooks creation
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
# Extend indemma
|
|
333
|
+
model = root.model # TODO better way to get parent
|
|
334
|
+
model.mix (modelable) ->
|
|
335
|
+
modelable.after_mix.push associable.model.blender
|
|
336
|
+
modelable.record.before_initialize.push associable.record.before_initialize
|
|
337
|
+
modelable.record.after_initialize.push associable.record.after_initialize
|
|
338
|
+
|
|
339
|
+
# This allows to extendind the associable mixin
|
|
340
|
+
model.associable =
|
|
341
|
+
mix : (blender) ->
|
|
342
|
+
blender singular, plural
|
|
@@ -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,27 @@
|
|
|
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
|
+
after_initialize: ->
|
|
16
|
+
# TODO check persistable configuration before attaching handlers
|
|
17
|
+
@after 'saved', handlers.store_after_saved
|
|
18
|
+
|
|
19
|
+
# Extend indemma
|
|
20
|
+
# TODO use stampit to extend record and model
|
|
21
|
+
model = window.model # TODO better way to get parent
|
|
22
|
+
record = window.record # TODO better way to get parent
|
|
23
|
+
|
|
24
|
+
model.persistable = true
|
|
25
|
+
|
|
26
|
+
model.mix (modelable) ->
|
|
27
|
+
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
|
+
@storage.store key
|
|
11
|
+
all: ->
|
|
12
|
+
@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,106 @@
|
|
|
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
|
+
resourceable =
|
|
28
|
+
pluralize: (word, count, plural) ->
|
|
29
|
+
throw new TypeError "Invalid string passed to pluralize '#{word}'" unless word and word.length
|
|
30
|
+
|
|
31
|
+
unless word.indexOf('s') == word.length - 1
|
|
32
|
+
owl.pluralize word, count, plural
|
|
33
|
+
else
|
|
34
|
+
word
|
|
35
|
+
|
|
36
|
+
singularize: (word) ->
|
|
37
|
+
throw new TypeError "Invalid string passed to singularize '#{word}'" unless word and word.length
|
|
38
|
+
|
|
39
|
+
if word.lastIndexOf('s') == word.length - 1
|
|
40
|
+
word.substring 0, word.length - 1
|
|
41
|
+
else
|
|
42
|
+
word
|
|
43
|
+
|
|
44
|
+
# TODO move to resourceable method
|
|
45
|
+
route:
|
|
46
|
+
get: ->
|
|
47
|
+
return @initial_route if @initial_route?
|
|
48
|
+
|
|
49
|
+
# TODO use resource object on associations!
|
|
50
|
+
@resource = name: @resource if typeof @resource == 'string'
|
|
51
|
+
|
|
52
|
+
route = '/'
|
|
53
|
+
route += "#{@parent.route}/#{@parent._id}/" if @parent?
|
|
54
|
+
route += @resource.scope + '/' if @resource.scope?
|
|
55
|
+
|
|
56
|
+
route += if @resource.singular then @resource.name else model.pluralize @resource.name
|
|
57
|
+
@initial_route = route
|
|
58
|
+
|
|
59
|
+
route
|
|
60
|
+
|
|
61
|
+
set: (value) -> @initial_route = value
|
|
62
|
+
|
|
63
|
+
parent_id:
|
|
64
|
+
get: -> @[@parent_resource]._id if @[@parent_resource]
|
|
65
|
+
set: -> console.error 'Warning changing associations throught parent_id not allowed for security and style guide purposes' # TODO
|
|
66
|
+
|
|
67
|
+
initialize: ->
|
|
68
|
+
# Set parent attribute and default nested route
|
|
69
|
+
if @parent_resource
|
|
70
|
+
Object.defineProperty @, "#{@parent_resource}_id",
|
|
71
|
+
value: resourceable.parent_id
|
|
72
|
+
configurable: true
|
|
73
|
+
enumerable: true
|
|
74
|
+
|
|
75
|
+
# Setup resource
|
|
76
|
+
resource_definition = {}
|
|
77
|
+
resource_definition = name: @resource if typeof @resource == 'string'
|
|
78
|
+
if typeof @resource == 'object'
|
|
79
|
+
# TODO deeper resource integration with record.coffee, and remove original reference
|
|
80
|
+
# To prevent reference lost and allow dinamic modification of resources
|
|
81
|
+
# we need to preserve the original reference
|
|
82
|
+
@resource.original_reference = @resource
|
|
83
|
+
|
|
84
|
+
resource_definition = @resource
|
|
85
|
+
|
|
86
|
+
# TODO remove mentions of @parent_resource and use only resource: {parent: ...}
|
|
87
|
+
resource_definition.parent = @parent_resource
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@resource = resource resource_definition
|
|
93
|
+
|
|
94
|
+
# TODO Support route parsing, and change route to /parents/:id/childrens
|
|
95
|
+
@route ? Object.defineProperty @, 'route', resourceable.route
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# Extend indemma
|
|
99
|
+
model = window.model # TODO better way to get parent
|
|
100
|
+
|
|
101
|
+
model.mix (modelable) ->
|
|
102
|
+
modelable.record.after_initialize.unshift resourceable.initialize
|
|
103
|
+
modelable.after_mix.unshift resourceable.initialize
|
|
104
|
+
|
|
105
|
+
model.singularize = resourceable.singularize
|
|
106
|
+
model.pluralize = resourceable.pluralize
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
$ = require 'jquery'
|
|
2
|
+
|
|
3
|
+
module.exports =
|
|
4
|
+
# TODO render route in the object itself with getter, and normalize this methods
|
|
5
|
+
get : (data) -> request.call @, 'get' , (if @_id then "#{@route}/#{@_id}" else @route), data
|
|
6
|
+
put : (data) -> request.call @, 'put' , (if @_id then "#{@route}/#{@_id}" else @route), data # TODO change from put to patch
|
|
7
|
+
post : (data) -> request.call @, 'post' , @route, data
|
|
8
|
+
delete: (data) -> request.call @, 'delete', (if @_id then "#{@route}/#{@_id}" else @route), data
|
|
9
|
+
|
|
10
|
+
request = (method, url, data) ->
|
|
11
|
+
param_name = @resource.param_name || @resource.toString()
|
|
12
|
+
|
|
13
|
+
# TODO optmize this serialization lookup
|
|
14
|
+
if not data and @json
|
|
15
|
+
data = {}
|
|
16
|
+
data[param_name] = @json()
|
|
17
|
+
|
|
18
|
+
if data and data[param_name]
|
|
19
|
+
delete data[param_name]['id']
|
|
20
|
+
delete data[param_name]['_id']
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
$.ajax
|
|
24
|
+
url : url
|
|
25
|
+
data : data
|
|
26
|
+
type : method
|
|
27
|
+
dataType: 'json'
|
|
28
|
+
context : @
|