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.
- checksums.yaml +4 -4
- data/component.json +1 -1
- data/components/indefinido/indemma/master/.gitignore +17 -0
- data/components/indefinido/indemma/master/.ruby-gemset +1 -0
- data/components/indefinido/indemma/master/.ruby-version +1 -0
- data/components/indefinido/indemma/master/Gemfile +12 -0
- data/components/indefinido/indemma/master/Guardfile +39 -0
- data/components/indefinido/indemma/master/History.md +0 -0
- data/components/indefinido/indemma/master/Readme.md +445 -0
- data/components/indefinido/indemma/master/build/development.js +26123 -0
- data/components/indefinido/indemma/master/build/release.js +16741 -0
- data/components/indefinido/indemma/master/build/test.js +26123 -0
- data/components/indefinido/indemma/master/component.json +1 -1
- data/components/indefinido/indemma/master/components/chaijs/assertion-error/1.0.0/component.json +18 -0
- data/components/indefinido/indemma/master/components/chaijs/assertion-error/1.0.0/index.js +110 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.gitignore +22 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.mailmap +1 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.npmignore +14 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/.travis.yml +14 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/CONTRIBUTING.md +173 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/History.md +895 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/Makefile +93 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/README.md +99 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/ReleaseNotes.md +482 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/bower.json +27 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/chai.js +4782 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/component.json +50 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/index.js +1 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/karma.conf.js +28 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/karma.sauce.js +41 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/assertion.js +130 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/config.js +50 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/core/assertions.js +1314 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/interface/assert.js +1056 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/interface/expect.js +12 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/interface/should.js +78 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/addChainableMethod.js +111 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/addMethod.js +43 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/addProperty.js +40 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/flag.js +32 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getActual.js +18 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getEnumerableProperties.js +25 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getMessage.js +49 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getName.js +20 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getPathValue.js +102 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/getProperties.js +35 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/index.js +114 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/inspect.js +320 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/objDisplay.js +49 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteChainableMethod.js +53 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteMethod.js +51 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/overwriteProperty.js +54 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/test.js +26 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/transferFlags.js +44 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai/utils/type.js +45 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/lib/chai.js +87 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/package.json +42 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/sauce.browsers.js +128 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/support/sauce/sauce_connect_block.sh +7 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/support/sauce/sauce_connect_setup.sh +53 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/assert.js +638 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/auth/.gitkeep +0 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/bootstrap/index.js +22 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/bootstrap/karma.js +22 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/configuration.js +133 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/display/errors.js +14 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/display/message.js +47 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/expect.js +814 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/globalShould.js +15 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/plugins.js +24 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/should.js +744 -0
- data/components/indefinido/indemma/master/components/chaijs/chai/1.9.1/test/utilities.js +309 -0
- data/components/indefinido/indemma/master/components/chaijs/deep-eql/0.1.3/component.json +20 -0
- data/components/indefinido/indemma/master/components/chaijs/deep-eql/0.1.3/lib/eql.js +257 -0
- data/components/indefinido/indemma/master/components/chaijs/type-detect/0.1.1/component.json +18 -0
- data/components/indefinido/indemma/master/components/chaijs/type-detect/0.1.1/lib/type.js +142 -0
- data/components/indefinido/indemma/master/components/component/bind/1.0.0/component.json +14 -0
- data/components/indefinido/indemma/master/components/component/bind/1.0.0/index.js +23 -0
- data/components/indefinido/indemma/master/components/component/jquery/1.0.0/component.json +10 -0
- data/components/indefinido/indemma/master/components/component/jquery/1.0.0/index.js +10308 -0
- data/components/indefinido/indemma/master/components/component/type/1.0.0/component.json +20 -0
- data/components/indefinido/indemma/master/components/component/type/1.0.0/index.js +32 -0
- data/components/indefinido/indemma/master/components/indefinido/advisable/master/component.json +21 -0
- data/components/indefinido/indemma/master/components/indefinido/advisable/master/index.js +1 -0
- data/components/indefinido/indemma/master/components/indefinido/advisable/master/lib/advisable.js +60 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/component.json +39 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/index.js +1 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/adapters/rivets.js +40 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/legacy/notifierable.js +145 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/legacy/schedulerable.js +147 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/lookup.js +38 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/keypath_observer.js +38 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/observation.js +45 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/selection.js +57 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable/self_observer.js +38 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/observable.js +97 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/lib/platform.js +12 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/observe-js/observe.js +1631 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/accessors-legacy.js +92 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/accessors.js +248 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/array.indexOf.js +8 -0
- data/components/indefinido/indemma/master/components/indefinido/observable/es6-modules/vendor/shims/object.create.js +77 -0
- data/components/indefinido/indemma/master/components/pluma/assimilate/0.4.0/component.json +25 -0
- data/components/indefinido/indemma/master/components/pluma/assimilate/0.4.0/dist/assimilate.js +127 -0
- data/components/indefinido/indemma/master/karma.conf.js +75 -0
- data/components/indefinido/indemma/master/lib/record/associable.js +4 -2
- data/components/indefinido/indemma/master/lib/record/dirtyable.js +1 -1
- data/components/indefinido/indemma/master/package.json +9 -0
- data/components/indefinido/indemma/master/spec/record/associable_spec.js +211 -0
- data/components/indefinido/indemma/master/spec/record/dirtyable_spec.js +57 -0
- data/components/indefinido/indemma/master/spec/record/maid_spec.js +40 -0
- data/components/indefinido/indemma/master/spec/record/persistable_spec.js +46 -0
- data/components/indefinido/indemma/master/spec/record/queryable_spec.js +39 -0
- data/components/indefinido/indemma/master/spec/record/resource_spec.js +93 -0
- data/components/indefinido/indemma/master/spec/record/rest_spec.js +32 -0
- data/components/indefinido/indemma/master/spec/record/restfulable_spec.js +346 -0
- data/components/indefinido/indemma/master/spec/record/scopable_spec.js +242 -0
- data/components/indefinido/indemma/master/spec/record/storable_spec.js +44 -0
- data/components/indefinido/indemma/master/spec/record/translationable.js +28 -0
- data/components/indefinido/indemma/master/spec/record/validatable_spec.js +142 -0
- data/components/indefinido/indemma/master/spec/record/validations/associated_spec.js +43 -0
- data/components/indefinido/indemma/master/spec/record/validations/confirmation_spec.js +36 -0
- data/components/indefinido/indemma/master/spec/record/validations/cpf_spec.js +34 -0
- data/components/indefinido/indemma/master/spec/record/validations/presence_spec.js +28 -0
- data/components/indefinido/indemma/master/spec/record/validations/remote_spec.js +87 -0
- data/components/indefinido/indemma/master/spec/record/validations/type_spec.js +48 -0
- data/components/indefinido/indemma/master/spec/record_spec.js +49 -0
- data/components/indefinido/indemma/master/spec/spec_helper.js +15 -0
- data/components/indefinido/indemma/master/spec/support/value_objects/phone.js +45 -0
- data/components/indefinido/indemma/master/src/lib/extensions/rivets.coffee +17 -0
- data/components/indefinido/indemma/master/src/lib/record/associable.coffee +419 -0
- data/components/indefinido/indemma/master/src/lib/record/dirtyable.coffee +47 -0
- data/components/indefinido/indemma/master/src/lib/record/errors.coffee +20 -0
- data/components/indefinido/indemma/master/src/lib/record/maid.coffee +16 -0
- data/components/indefinido/indemma/master/src/lib/record/persistable.coffee +34 -0
- data/components/indefinido/indemma/master/src/lib/record/queryable.coffee +29 -0
- data/components/indefinido/indemma/master/src/lib/record/resource.coffee +107 -0
- data/components/indefinido/indemma/master/src/lib/record/rest.coffee +34 -0
- data/components/indefinido/indemma/master/src/lib/record/restfulable.coffee +487 -0
- data/components/indefinido/indemma/master/src/lib/record/scopable.coffee +279 -0
- data/components/indefinido/indemma/master/src/lib/record/storable.coffee +49 -0
- data/components/indefinido/indemma/master/src/lib/record/translationable.coffee +18 -0
- data/components/indefinido/indemma/master/src/lib/record/validatable.coffee +241 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/associated.coffee +34 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/confirmation.coffee +17 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/cpf.coffee +57 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/presence.coffee +16 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/remote.coffee +61 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/type.coffee +31 -0
- data/components/indefinido/indemma/master/src/lib/record/validations/validatorable.coffee +5 -0
- data/components/indefinido/indemma/master/src/lib/record.coffee +143 -0
- data/components/indefinido/indemma/master/src/spec/record/associable_spec.coffee +205 -0
- data/components/indefinido/indemma/master/src/spec/record/dirtyable_spec.coffee +47 -0
- data/components/indefinido/indemma/master/src/spec/record/maid_spec.coffee +34 -0
- data/components/indefinido/indemma/master/src/spec/record/persistable_spec.coffee +39 -0
- data/components/indefinido/indemma/master/src/spec/record/queryable_spec.coffee +33 -0
- data/components/indefinido/indemma/master/src/spec/record/resource_spec.coffee +69 -0
- data/components/indefinido/indemma/master/src/spec/record/rest_spec.coffee +22 -0
- data/components/indefinido/indemma/master/src/spec/record/restfulable_spec.coffee +257 -0
- data/components/indefinido/indemma/master/src/spec/record/scopable_spec.coffee +227 -0
- data/components/indefinido/indemma/master/src/spec/record/storable_spec.coffee +39 -0
- data/components/indefinido/indemma/master/src/spec/record/translationable.coffee +19 -0
- data/components/indefinido/indemma/master/src/spec/record/validatable_spec.coffee +127 -0
- data/components/indefinido/indemma/master/src/spec/record/validations/associated_spec.coffee +35 -0
- data/components/indefinido/indemma/master/src/spec/record/validations/confirmation_spec.coffee +25 -0
- data/components/indefinido/indemma/master/src/spec/record/validations/cpf_spec.coffee +27 -0
- data/components/indefinido/indemma/master/src/spec/record/validations/presence_spec.coffee +24 -0
- data/components/indefinido/indemma/master/src/spec/record/validations/remote_spec.coffee +74 -0
- data/components/indefinido/indemma/master/src/spec/record/validations/type_spec.coffee +33 -0
- data/components/indefinido/indemma/master/src/spec/record_spec.coffee +29 -0
- data/components/indefinido/indemma/master/src/spec/spec_helper.coffee +11 -0
- data/components/indefinido/indemma/master/src/spec/support/value_objects/phone.coffee +30 -0
- data/components/indefinido/indemma/master/vendor/object/mixin.js +196 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/assert.js +199 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/behavior.js +334 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/call.js +205 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/collection.js +155 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/match.js +245 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/mock.js +451 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/sandbox.js +144 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/spy.js +413 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/stub.js +161 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/test.js +77 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/test_case.js +99 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/event.js +94 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_server.js +212 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_server_with_clock.js +83 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_timers.js +405 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_xdomain_request.js +206 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/fake_xml_http_request.js +575 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/timers_ie.js +31 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/xdr_ie.js +14 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon/util/xhr_ie.js +19 -0
- data/components/indefinido/indemma/master/vendor/spec/sinon.js +383 -0
- data/lib/assets/javascripts/value_objects/phone.js.coffee +3 -1
- data/lib/assets/javascripts/widgets/viewer/plugins/scopable.js.coffee +5 -5
- data/lib/ende/version.rb +1 -1
- data/vendor/assets/components/ende_build.css +4 -4
- data/vendor/assets/components/ende_build.js +7974 -7889
- metadata +191 -5
- data/vendor/assets/component/build.css +0 -112
- data/vendor/assets/components/build.css +0 -112
- 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
|