-
-
Notifications
You must be signed in to change notification settings - Fork 171
/
Copy pathindex.ts
107 lines (100 loc) · 3.64 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { GetterTree, Module as Mod, Store } from 'vuex'
import { DynamicModuleOptions, ModuleOptions } from '../moduleoptions'
import { stateFactory as sf } from './stateFactory'
import { addPropertiesToObject } from '../helpers'
import {
staticActionGenerators,
staticGetterGenerator,
staticMutationGenerator,
staticStateGenerator
} from './staticGenerators'
function moduleDecoratorFactory<S>(moduleOptions: ModuleOptions) {
return function<TFunction extends Function>(constructor: TFunction): TFunction | void {
const module: Function & Mod<S, any> = constructor
const stateFactory = () => sf(module)
if (!module.state) {
module.state = moduleOptions && moduleOptions.stateFactory ? stateFactory : stateFactory()
}
if (!module.getters) {
module.getters = {} as GetterTree<S, any>
}
if (!module.namespaced) {
module.namespaced = moduleOptions && moduleOptions.namespaced
}
Object.getOwnPropertyNames(module.prototype).forEach((funcName: string) => {
const descriptor = Object.getOwnPropertyDescriptor(
module.prototype,
funcName
) as PropertyDescriptor
if (descriptor.get && module.getters) {
module.getters[funcName] = function(
state: S,
getters: GetterTree<S, any>,
rootState: any,
rootGetters: GetterTree<any, any>
) {
const thisObj = { context: { state, getters, rootState, rootGetters } }
addPropertiesToObject(thisObj, state)
addPropertiesToObject(thisObj, getters)
const got = (descriptor.get as Function).call(thisObj)
return got
}
}
})
const modOpt = moduleOptions as DynamicModuleOptions
if (modOpt.name) {
Object.defineProperty(constructor, '_genStatic', {
value: (store?: Store<any>) => {
let statics = {}
modOpt.store = modOpt.store || store
if (!modOpt.store) {
throw new Error(`ERR_STORE_NOT_PROVIDED: To use getModule(), either the module
should be decorated with store in decorator, i.e. @Module({store: store}) or
store should be passed when calling getModule(), i.e. getModule(MyModule, this.$store)`)
}
// =========== For statics ==============
// ------ state -------
staticStateGenerator(module, modOpt, statics)
// ------- getters -------
if (module.getters) {
staticGetterGenerator(module, modOpt, statics)
}
// -------- mutations --------
if (module.mutations) {
staticMutationGenerator(module, modOpt, statics)
}
// -------- actions ---------
if (module.actions) {
staticActionGenerators(module, modOpt, statics)
}
return statics
}
})
}
if (modOpt.dynamic) {
if (!modOpt.name) {
throw new Error('Name of module not provided in decorator options')
}
modOpt.store.registerModule(
modOpt.name, // TODO: Handle nested modules too in future
module
)
}
return constructor
}
}
export function Module<S>(module: Function & Mod<S, any>): void
export function Module<S>(options: ModuleOptions): ClassDecorator
export function Module<S>(modOrOpt: ModuleOptions | Function & Mod<S, any>) {
if (typeof (modOrOpt as any) === 'function') {
/*
* @Module decorator called without options (directly on the class definition)
*/
moduleDecoratorFactory({})(modOrOpt as Function & Mod<S, any>)
} else {
/*
* @Module({...}) decorator called with options
*/
return moduleDecoratorFactory(modOrOpt)
}
}