1 | {
|
2 | defineModule, log, object, upperCamelCase, lowerCamelCase, each
|
3 | isPlainObject
|
4 | } = require 'art-standard-lib'
|
5 |
|
6 | # DEPRICATED: just use @declarable on BaseClass now (provided by the ExtendableProperyMixin)
|
7 | #
|
8 | # TODO: instead of the ad-hoc solution here, use ArtFoundation.Validator!
|
9 | # but, validator needs:
|
10 | # a) to be its own NPM
|
11 | # b) to support single-field create-tests and update-tests
|
12 | # Then we can just create one Validator from the declarable "map"
|
13 | # That's all pretty easy, but I need to stay focused today.
|
14 |
|
15 | # superClass must extend MinimalBaseObject at some point
|
16 | # to use 'extendable', superClass must also extend ExtendablePropertyMixin
|
17 | defineModule module, -> (superClass) -> class DeclarableMixin extends superClass
|
18 |
|
19 | ###
|
20 | define a declarable field
|
21 |
|
22 | IN:
|
23 | map:
|
24 | key: name: string
|
25 | value: true-ish OR
|
26 | options:
|
27 | preprocess: (v) -> newV
|
28 | validate: (v) -> truthish
|
29 | extendable: defaultValue
|
30 | If present, this is an extendable property.
|
31 | See: @extendableProperty
|
32 | passed to: @extendableProperty "#{key}": options.extendable
|
33 | NOTE: validate is evaluated BEFORE preprocess
|
34 |
|
35 | EFFECT:
|
36 | creates:
|
37 |
|
38 | # class declarator function, with preprocessing
|
39 | @name: (...)->
|
40 |
|
41 | # class getter-function
|
42 | @getName: ->
|
43 |
|
44 | # instance-getter
|
45 | @getter name: ->
|
46 | ###
|
47 |
|
48 | @declarable: (map) ->
|
49 | each map, (options, name) =>
|
50 | if isPlainObject options
|
51 | {preprocess, validate, extendable, getter} = options
|
52 |
|
53 | preprocess ||= (v) -> v
|
54 | validate ||= -> true
|
55 |
|
56 | name = lowerCamelCase name
|
57 | ucProp = upperCamelCase name
|
58 | internalName = @propInternalName name
|
59 | getterName = "get#{ucProp}"
|
60 |
|
61 | if extendable
|
62 | @extendableProperty "#{name}": extendable
|
63 |
|
64 | else
|
65 | ##############################
|
66 | # class-api API
|
67 | ##############################
|
68 |
|
69 | # declare (or extend, if extendable)
|
70 | @[name] = (value) ->
|
71 | unless validate value
|
72 | throw new Error "invalid value: #{formattedInspect {value, name}}"
|
73 |
|
74 | @[internalName] = preprocess value
|
75 |
|
76 | # get
|
77 | @[getterName] = getter || -> @[internalName]
|
78 |
|
79 | ##############################
|
80 | # instance-api
|
81 | ##############################
|
82 | @addGetter name, -> @class[internalName]
|