1 |
|
2 |
|
3 |
|
4 | 'use strict';
|
5 |
|
6 | module.exports = class ClassHelper {
|
7 |
|
8 | static resolveSpawn (config, module, ...args) {
|
9 | config = this.normalizeSpawn(config, ...args);
|
10 | if (config && typeof config.Class !== 'function') {
|
11 | config.Class = module.getClass(config.Class) || module.require(config.Class) || require(config.Class);
|
12 | }
|
13 | return config;
|
14 | }
|
15 |
|
16 | static normalizeSpawn (config, params, defaults) {
|
17 | if (!config) {
|
18 | return params || defaults ? {...defaults, ...params} : config;
|
19 | }
|
20 | if (typeof config !== 'object') {
|
21 | config = {Class: config};
|
22 | }
|
23 | if (defaults) {
|
24 | config = {...defaults, ...config};
|
25 | }
|
26 | return Object.assign(config, params);
|
27 | }
|
28 |
|
29 | static spawn (config, params) {
|
30 | if (typeof config === 'function') {
|
31 | return new config(params);
|
32 | }
|
33 | if (typeof config === 'string') {
|
34 | return new (params.module.getClass(config))(params);
|
35 | }
|
36 | if (params) {
|
37 | config = {...config, ...params};
|
38 | }
|
39 | return typeof config.Class === 'function'
|
40 | ? new config.Class(config)
|
41 | : new (config.module.getClass(config.Class))(config);
|
42 | }
|
43 |
|
44 |
|
45 | static defineClassProperty (Class, name, value, writable) {
|
46 | Object.defineProperty(Class, name, {value, writable});
|
47 | Object.defineProperty(Class.prototype, name, {value, writable});
|
48 | }
|
49 |
|
50 | static defineConstantClassProperties (Class) {
|
51 | const data = this.getClassPropertyMap(Class, 'getConstants', Class, 'getExtendedClassProperties');
|
52 | for (const key of Object.keys(data)) {
|
53 | this.defineClassProperty(Class, key, data[key], false);
|
54 | }
|
55 | }
|
56 |
|
57 | static getClassPropertyMap (targetClass, method, chainClass, extendedMethod) {
|
58 | const parentClass = Object.getPrototypeOf(chainClass);
|
59 | const hasOwnMethod = chainClass[method] && chainClass[method] !== parentClass[method];
|
60 | const chainMap = hasOwnMethod ? chainClass[method].call(targetClass) : {};
|
61 | if (!Object.getPrototypeOf(parentClass)) {
|
62 | return chainMap;
|
63 | }
|
64 | const parentMap = this.getClassPropertyMap(targetClass, method, parentClass, extendedMethod);
|
65 | const data = {...parentMap, ...chainMap};
|
66 | if (typeof chainClass[extendedMethod] === 'function') {
|
67 | for (const name of chainClass[extendedMethod]()) {
|
68 | const property = this.getExtendedClassProperty(name, chainMap[name], parentMap[name]);
|
69 | if (property) {
|
70 | data[name] = property;
|
71 | }
|
72 | }
|
73 | }
|
74 | return data;
|
75 | }
|
76 |
|
77 | static getExtendedClassProperty (name, child, parent) {
|
78 | if (child && parent) {
|
79 | if (Array.isArray(child) && Array.isArray(parent)) {
|
80 | return [...parent, ...child];
|
81 | }
|
82 | if (typeof child === 'object' && typeof parent === 'object') {
|
83 | return {...parent, ...child};
|
84 | }
|
85 | }
|
86 | return null;
|
87 | }
|
88 | }; |
\ | No newline at end of file |