UNPKG

3.3 kBJavaScriptView Raw
1/**
2 * @copyright Copyright (c) 2019 Maxim Khorin <maksimovichu@gmail.com>
3 */
4'use strict';
5
6module.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 // to get value from Class[name] and (new Class)[name]
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