@tsed/core 8.0.0 → 8.0.2

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.
Files changed (110) hide show
  1. package/package.json +5 -4
  2. package/src/decorators/storeFn.ts +20 -0
  3. package/src/decorators/storeMerge.ts +8 -0
  4. package/src/decorators/storeSet.ts +8 -0
  5. package/src/domain/AnyToPromise.spec.ts +158 -0
  6. package/src/domain/AnyToPromise.ts +181 -0
  7. package/src/domain/DecoratorTypes.ts +10 -0
  8. package/src/domain/Env.ts +15 -0
  9. package/src/domain/Metadata.spec.ts +142 -0
  10. package/src/domain/Metadata.ts +523 -0
  11. package/src/domain/Store.spec.ts +164 -0
  12. package/src/domain/Store.ts +175 -0
  13. package/src/domain/Type.ts +20 -0
  14. package/src/errors/UnsupportedDecoratorType.spec.ts +81 -0
  15. package/src/errors/UnsupportedDecoratorType.ts +25 -0
  16. package/src/index.ts +75 -0
  17. package/src/interfaces/AnyDecorator.ts +1 -0
  18. package/src/interfaces/DecoratorParameters.ts +8 -0
  19. package/src/interfaces/MetadataTypes.ts +6 -0
  20. package/src/interfaces/Relation.ts +1 -0
  21. package/src/interfaces/ValueOf.ts +1 -0
  22. package/src/utils/catchError.spec.ts +17 -0
  23. package/src/utils/catchError.ts +15 -0
  24. package/src/utils/decorators/decorateMethodsOf.spec.ts +83 -0
  25. package/src/utils/decorators/decorateMethodsOf.ts +31 -0
  26. package/src/utils/decorators/decoratorArgs.spec.ts +15 -0
  27. package/src/utils/decorators/decoratorArgs.ts +6 -0
  28. package/src/utils/decorators/decoratorTypeOf.spec.ts +92 -0
  29. package/src/utils/decorators/decoratorTypeOf.ts +24 -0
  30. package/src/utils/decorators/inheritedDescriptorOf.ts +13 -0
  31. package/src/utils/decorators/useDecorators.spec.ts +61 -0
  32. package/src/utils/decorators/useDecorators.ts +21 -0
  33. package/src/utils/decorators/useMethodDecorator.spec.ts +45 -0
  34. package/src/utils/decorators/useMethodDecorators.ts +12 -0
  35. package/src/utils/getRandomId.spec.ts +7 -0
  36. package/src/utils/getRandomId.ts +3 -0
  37. package/src/utils/http/getHostInfoFromPort.spec.ts +25 -0
  38. package/src/utils/http/getHostInfoFromPort.ts +20 -0
  39. package/src/utils/objects/ObjectUtils.spec.ts +322 -0
  40. package/src/utils/objects/ancestorOf.ts +7 -0
  41. package/src/utils/objects/ancestorsOf.ts +21 -0
  42. package/src/utils/objects/classOf.ts +18 -0
  43. package/src/utils/objects/cleanObject.spec.ts +22 -0
  44. package/src/utils/objects/cleanObject.ts +20 -0
  45. package/src/utils/objects/constructorOf.ts +17 -0
  46. package/src/utils/objects/createInstance.ts +5 -0
  47. package/src/utils/objects/deepClone.spec.ts +130 -0
  48. package/src/utils/objects/deepClone.ts +85 -0
  49. package/src/utils/objects/deepMerge.spec.ts +196 -0
  50. package/src/utils/objects/deepMerge.ts +84 -0
  51. package/src/utils/objects/descriptorOf.spec.ts +16 -0
  52. package/src/utils/objects/descriptorOf.ts +13 -0
  53. package/src/utils/objects/getClassOrSymbol.ts +6 -0
  54. package/src/utils/objects/getConstructorArgNames.spec.ts +11 -0
  55. package/src/utils/objects/getConstructorArgNames.ts +10 -0
  56. package/src/utils/objects/getValue.spec.ts +62 -0
  57. package/src/utils/objects/getValue.ts +87 -0
  58. package/src/utils/objects/hasJsonMethod.spec.ts +11 -0
  59. package/src/utils/objects/hasJsonMethod.ts +3 -0
  60. package/src/utils/objects/isArray.ts +18 -0
  61. package/src/utils/objects/isArrowFn.ts +5 -0
  62. package/src/utils/objects/isBoolean.ts +12 -0
  63. package/src/utils/objects/isBuffer.spec.ts +14 -0
  64. package/src/utils/objects/isBuffer.ts +19 -0
  65. package/src/utils/objects/isClass.spec.ts +15 -0
  66. package/src/utils/objects/isClass.ts +28 -0
  67. package/src/utils/objects/isCollection.ts +20 -0
  68. package/src/utils/objects/isDate.ts +8 -0
  69. package/src/utils/objects/isEmpty.spec.ts +10 -0
  70. package/src/utils/objects/isEmpty.ts +10 -0
  71. package/src/utils/objects/isEnumerable.ts +21 -0
  72. package/src/utils/objects/isFunction.ts +3 -0
  73. package/src/utils/objects/isInheritedFrom.ts +26 -0
  74. package/src/utils/objects/isMomentObject.spec.ts +16 -0
  75. package/src/utils/objects/isMomentObject.ts +3 -0
  76. package/src/utils/objects/isMongooseObject.spec.ts +22 -0
  77. package/src/utils/objects/isMongooseObject.ts +9 -0
  78. package/src/utils/objects/isNil.spec.ts +10 -0
  79. package/src/utils/objects/isNil.ts +3 -0
  80. package/src/utils/objects/isNumber.ts +12 -0
  81. package/src/utils/objects/isObject.ts +3 -0
  82. package/src/utils/objects/isObservable.ts +3 -0
  83. package/src/utils/objects/isPlainObject.spec.ts +10 -0
  84. package/src/utils/objects/isPlainObject.ts +14 -0
  85. package/src/utils/objects/isPrimitive.spec.ts +17 -0
  86. package/src/utils/objects/isPrimitive.ts +26 -0
  87. package/src/utils/objects/isPromise.ts +13 -0
  88. package/src/utils/objects/isProtectedKey.spec.ts +14 -0
  89. package/src/utils/objects/isProtectedKey.ts +7 -0
  90. package/src/utils/objects/isRegExp.ts +3 -0
  91. package/src/utils/objects/isSerializable.spec.ts +14 -0
  92. package/src/utils/objects/isSerializable.ts +9 -0
  93. package/src/utils/objects/isStream.ts +3 -0
  94. package/src/utils/objects/isString.ts +11 -0
  95. package/src/utils/objects/isSymbol.spec.ts +11 -0
  96. package/src/utils/objects/isSymbol.ts +11 -0
  97. package/src/utils/objects/methodsOf.ts +25 -0
  98. package/src/utils/objects/nameOf.ts +27 -0
  99. package/src/utils/objects/objectKeys.spec.ts +10 -0
  100. package/src/utils/objects/objectKeys.ts +5 -0
  101. package/src/utils/objects/primitiveOf.ts +19 -0
  102. package/src/utils/objects/prototypeOf.ts +10 -0
  103. package/src/utils/objects/setValue.spec.ts +60 -0
  104. package/src/utils/objects/setValue.ts +35 -0
  105. package/src/utils/objects/toMap.spec.ts +211 -0
  106. package/src/utils/objects/toMap.ts +44 -0
  107. package/src/utils/objects/toStringConstructor.ts +9 -0
  108. package/src/utils/objects/toStringConstrutor.spec.ts +18 -0
  109. package/src/utils/objects/uniq.spec.ts +8 -0
  110. package/src/utils/objects/uniq.ts +16 -0
@@ -0,0 +1,24 @@
1
+ import {DecoratorTypes} from "../../domain/DecoratorTypes.js";
2
+ import {classOf} from "../objects/classOf.js";
3
+
4
+ export function decoratorTypeOf(args: any[]): DecoratorTypes {
5
+ const [target, propertyKey, descriptor] = args;
6
+
7
+ const staticType = (type: string): any => {
8
+ return target !== classOf(target) ? type : `${type}.static`;
9
+ };
10
+
11
+ if (typeof descriptor === "number") {
12
+ return propertyKey ? staticType("parameter") : "parameter.constructor";
13
+ }
14
+
15
+ if (descriptor && descriptor.value) {
16
+ return staticType("method");
17
+ }
18
+
19
+ if ((propertyKey && descriptor === undefined) || descriptor) {
20
+ return staticType("property");
21
+ }
22
+
23
+ return DecoratorTypes.CLASS;
24
+ }
@@ -0,0 +1,13 @@
1
+ import {ancestorsOf} from "../objects/ancestorsOf.js";
2
+
3
+ export function inheritedDescriptorOf(target: any, propertyKey: string): PropertyDescriptor | undefined {
4
+ for (const klass of ancestorsOf(target)) {
5
+ const descriptor = Object.getOwnPropertyDescriptor((klass && klass.prototype) || klass, propertyKey)!;
6
+
7
+ if (descriptor) {
8
+ return descriptor;
9
+ }
10
+ }
11
+
12
+ return undefined;
13
+ }
@@ -0,0 +1,61 @@
1
+ import {StoreFn} from "../../decorators/storeFn.js";
2
+ import {Store} from "../../domain/Store.js";
3
+ import {AnyDecorator} from "../../interfaces/AnyDecorator.js";
4
+ import {useDecorators} from "./useDecorators.js";
5
+
6
+ describe("useDecorators", () => {
7
+ function decorator1(value: any) {
8
+ return StoreFn((store) => {
9
+ store.set("decorator1", value);
10
+ });
11
+ }
12
+
13
+ function decorator2(value: any) {
14
+ return StoreFn((store) => {
15
+ store.set("decorator2", value);
16
+ });
17
+ }
18
+
19
+ function decorator3(value: any) {
20
+ return (...args: any[]) => {
21
+ args[2].value = () => {
22
+ return "hello value";
23
+ };
24
+
25
+ return args[2];
26
+ };
27
+ }
28
+
29
+ function decorator4(value: any) {
30
+ return (...args: any[]) => {
31
+ args[2].value = () => {
32
+ return "hello value 4";
33
+ };
34
+ };
35
+ }
36
+
37
+ function decorate(): AnyDecorator {
38
+ return useDecorators(decorator1("test1"), decorator2("test2"));
39
+ }
40
+
41
+ function decorateMethod(): any {
42
+ return useDecorators(decorator3("test1"), decorator4("test2"));
43
+ }
44
+
45
+ @decorate()
46
+ class Test {
47
+ @decorateMethod()
48
+ test() {}
49
+ }
50
+
51
+ it("should apply all decorators", () => {
52
+ expect(Store.from(Test).get("decorator1")).toBe("test1");
53
+ expect(Store.from(Test).get("decorator2")).toBe("test2");
54
+ });
55
+
56
+ it("should apply all decorators and return descriptor", () => {
57
+ const result = new Test().test();
58
+
59
+ expect(result).toBe("hello value 4");
60
+ });
61
+ });
@@ -0,0 +1,21 @@
1
+ import {AnyDecorator} from "../../interfaces/AnyDecorator.js";
2
+ import {DecoratorParameters} from "../../interfaces/DecoratorParameters.js";
3
+
4
+ export function useDecorators(...decorators: AnyDecorator[]): any {
5
+ return (...args: DecoratorParameters) => {
6
+ const isMethod = typeof args[2] === "object";
7
+ decorators
8
+ .filter((o: any) => !!o)
9
+ .forEach((decorator: Function) => {
10
+ const descriptor = decorator(...args);
11
+
12
+ if (isMethod && typeof descriptor === "object") {
13
+ args[2] = descriptor;
14
+ }
15
+ });
16
+
17
+ if (isMethod) {
18
+ return args[2];
19
+ }
20
+ };
21
+ }
@@ -0,0 +1,45 @@
1
+ import {StoreFn} from "../../decorators/storeFn.js";
2
+ import {Store} from "../../domain/Store.js";
3
+ import {useDecorators} from "./useDecorators.js";
4
+ import {useMethodDecorator, useMethodDecorators} from "./useMethodDecorators.js";
5
+
6
+ describe("useMethodDecorators", () => {
7
+ it("should apply all decorators", () => {
8
+ function decorator1(value: any) {
9
+ return StoreFn((store) => {
10
+ store.set("decorator1", value);
11
+ });
12
+ }
13
+
14
+ function decorator2(value: any) {
15
+ return StoreFn((store) => {
16
+ store.set("decorator2", value);
17
+ });
18
+ }
19
+
20
+ function decorator3(value: any) {
21
+ return (...args: any) => {
22
+ args[2].value = () => {
23
+ return "hello value";
24
+ };
25
+ };
26
+ }
27
+
28
+ function decorate() {
29
+ return useDecorators(useMethodDecorator(decorator2("test3")), useMethodDecorators(decorator1("test1")), decorator2("test2"));
30
+ }
31
+
32
+ class Test {
33
+ method(@decorate() param: string) {
34
+ return "";
35
+ }
36
+ }
37
+
38
+ const method1 = Store.fromMethod(Test, "method").get("decorator1");
39
+ const method2 = Store.fromMethod(Test, "method").get("decorator2");
40
+ const param = Store.from(Test, "method", 0).get("decorator2");
41
+ expect(method1).toBe("test1");
42
+ expect(method2).toBe("test3");
43
+ expect(param).toBe("test2");
44
+ });
45
+ });
@@ -0,0 +1,12 @@
1
+ import {AnyDecorator} from "../../interfaces/AnyDecorator.js";
2
+ import {descriptorOf} from "../objects/descriptorOf.js";
3
+
4
+ export function useMethodDecorator(decorator: AnyDecorator) {
5
+ return (target: any, propertyKey: string | symbol) => decorator(target, propertyKey, descriptorOf(target, propertyKey));
6
+ }
7
+
8
+ export function useMethodDecorators(...decorators: AnyDecorator[]) {
9
+ return (target: any, propertyKey: string | symbol) => {
10
+ decorators.filter(Boolean).forEach((decorator) => decorator(target, propertyKey, descriptorOf(target, propertyKey)));
11
+ };
12
+ }
@@ -0,0 +1,7 @@
1
+ import {getRandomId} from "./getRandomId.js";
2
+
3
+ describe("getRandomId", () => {
4
+ it("should return random id", () => {
5
+ expect(getRandomId()).not.toEqual(getRandomId());
6
+ });
7
+ });
@@ -0,0 +1,3 @@
1
+ export function getRandomId() {
2
+ return `e${Math.random().toString(36).substring(7)}`;
3
+ }
@@ -0,0 +1,25 @@
1
+ import {getHostInfoFromPort} from "./getHostInfoFromPort.js";
2
+
3
+ describe("buildAddressAndPort()", () => {
4
+ it("should return address and port from a concatened address and port", () => {
5
+ const address = getHostInfoFromPort("http", "0.0.0.0:9000");
6
+ expect(address).toEqual({
7
+ address: "0.0.0.0",
8
+ port: 9000,
9
+ protocol: "http",
10
+ toString: address.toString
11
+ });
12
+ });
13
+
14
+ it("should return address and port from a port number", () => {
15
+ const address = getHostInfoFromPort("https", 9000);
16
+ expect(address).toEqual({
17
+ address: "0.0.0.0",
18
+ port: 9000,
19
+ protocol: "https",
20
+ toString: address.toString
21
+ });
22
+
23
+ expect(address.toString()).toBe("https://0.0.0.0:9000");
24
+ });
25
+ });
@@ -0,0 +1,20 @@
1
+ export function getHostInfoFromPort(protocol: string, addressPort: any) {
2
+ let address = "0.0.0.0";
3
+ let port = addressPort;
4
+
5
+ if (typeof addressPort === "string" && addressPort.indexOf(":") > -1) {
6
+ [address, port] = addressPort.split(":");
7
+ port = +port;
8
+ }
9
+
10
+ return {
11
+ protocol,
12
+ address,
13
+ port: port as number,
14
+ toString() {
15
+ return [`${this.protocol}://${this.address}`, typeof this.port === "number" && this.port].filter(Boolean).join(":");
16
+ }
17
+ };
18
+ }
19
+
20
+ export type ReturnHostInfoFromPort = ReturnType<typeof getHostInfoFromPort>;
@@ -0,0 +1,322 @@
1
+ import {
2
+ ancestorsOf,
3
+ classOf,
4
+ constructorOf,
5
+ getClass,
6
+ getClassOrSymbol,
7
+ getConstructor,
8
+ isArrayOrArrayClass,
9
+ isClass,
10
+ isCollection,
11
+ isEmpty,
12
+ isInheritedFrom,
13
+ isPrimitiveOrPrimitiveClass,
14
+ isPromise,
15
+ methodsOf,
16
+ nameOf,
17
+ nameOfClass,
18
+ primitiveOf
19
+ } from "../../index.js";
20
+
21
+ class Base {
22
+ test1() {}
23
+
24
+ test3() {}
25
+ }
26
+
27
+ class Test extends Base {
28
+ test1() {}
29
+
30
+ test2() {}
31
+ }
32
+
33
+ const sym = Symbol("test2");
34
+
35
+ describe("ObjectUtils", () => {
36
+ describe("getConstructor()", () => {
37
+ it("should return the constructor when class is given", () => {
38
+ expect(getConstructor(Test)).toBe(Test);
39
+ });
40
+ it("should return the constructor when instance is given", () => {
41
+ expect(getConstructor(new Test())).toBe(Test);
42
+ });
43
+ });
44
+
45
+ describe("getClass()", () => {
46
+ it("should return the class when class is given", () => {
47
+ expect(getClass(Test)).toBe(Test);
48
+ });
49
+
50
+ it("should return the class when instance is given", () => {
51
+ expect(getClass(new Test())).toBe(Test);
52
+ });
53
+
54
+ it("should return the class when prototype is given", () => {
55
+ expect(getClass(Test.prototype)).toBe(Test);
56
+ });
57
+ });
58
+
59
+ describe("getClassOrSymbol()", () => {
60
+ it("should return the class when class is given", () => {
61
+ expect(getClassOrSymbol(Test)).toBe(Test);
62
+ });
63
+ it("should return the class when class is symbol", () => {
64
+ expect(getClassOrSymbol(sym)).toBe(sym);
65
+ });
66
+ });
67
+
68
+ describe("isPrimitiveOrPrimitiveClass()", () => {
69
+ it("should return true when a primitive is given", () => {
70
+ expect(isPrimitiveOrPrimitiveClass("test")).toBe(true);
71
+ });
72
+ it("should return true when a PrimitiveClass is given", () => {
73
+ expect(isPrimitiveOrPrimitiveClass(String())).toBe(true);
74
+ });
75
+
76
+ it("should return false when a class is given", () => {
77
+ expect(isPrimitiveOrPrimitiveClass(Test)).toBe(false);
78
+ });
79
+ });
80
+
81
+ describe("isArrayOrArrayClass()", () => {
82
+ it("should return true when Array is given", () => {
83
+ expect(isArrayOrArrayClass(Array)).toBe(true);
84
+ });
85
+
86
+ it("should return true when [] is given", () => {
87
+ expect(isArrayOrArrayClass([])).toBe(true);
88
+ });
89
+
90
+ it("should return false when {} is given", () => {
91
+ expect(isArrayOrArrayClass({})).toBe(false);
92
+ });
93
+ });
94
+
95
+ describe("isCollection()", () => {
96
+ it("should return true when Array is given", () => {
97
+ expect(isCollection(Array)).toBe(true);
98
+ });
99
+
100
+ it("should return true when [] is given", () => {
101
+ expect(isCollection([])).toBe(true);
102
+ });
103
+
104
+ it("should return true when Map is given", () => {
105
+ expect(isCollection(Map)).toBe(true);
106
+ });
107
+
108
+ it("should return true when Set is given", () => {
109
+ expect(isCollection(Set)).toBe(true);
110
+ });
111
+
112
+ it("should return true when WeakMap is given", () => {
113
+ expect(isCollection(WeakMap)).toBe(true);
114
+ });
115
+
116
+ it("should return true when WeakSet is given", () => {
117
+ expect(isCollection(WeakSet)).toBe(true);
118
+ });
119
+
120
+ it("should return false when {} is given", () => {
121
+ expect(isCollection({})).toBe(false);
122
+ });
123
+ });
124
+
125
+ describe("isEmpty()", () => {
126
+ it("should return true when empty string is given", () => {
127
+ expect(isEmpty("")).toBe(true);
128
+ });
129
+ it("should return true when null is given", () => {
130
+ expect(isEmpty(null)).toBe(true);
131
+ });
132
+
133
+ it("should return true when undefined is given", () => {
134
+ expect(isEmpty(undefined)).toBe(true);
135
+ });
136
+ it("should return false when {} is given", () => {
137
+ expect(isEmpty({})).toBe(false);
138
+ });
139
+ it("should return false when [] is given", () => {
140
+ expect(isEmpty([])).toBe(false);
141
+ });
142
+
143
+ it("should return false when false is given", () => {
144
+ expect(isEmpty(false)).toBe(false);
145
+ });
146
+ });
147
+
148
+ describe("isClass()", () => {
149
+ it("should return true when is a class", () => {
150
+ expect(isClass(class {})).toBe(true);
151
+ });
152
+
153
+ it("should return true when is a function", () => {
154
+ expect(isClass(function t() {})).toBe(true);
155
+ });
156
+
157
+ it("should return false (arrow function)", () => {
158
+ expect(isClass(() => {})).toBe(false);
159
+ });
160
+
161
+ it("should return false (date)", () => {
162
+ expect(isClass(new Date())).toBe(false);
163
+ });
164
+
165
+ it("should return false (number)", () => {
166
+ expect(isClass(1)).toBe(false);
167
+ });
168
+
169
+ it("should return false (obj)", () => {
170
+ expect(isClass(Object)).toBe(false);
171
+ });
172
+
173
+ it("should return false (promise)", () => {
174
+ expect(isClass(Promise.resolve())).toBe(false);
175
+ });
176
+ });
177
+
178
+ describe("isPromise()", () => {
179
+ it("should return true", () => {
180
+ expect(isPromise(Promise)).toBe(true);
181
+ });
182
+
183
+ it("should return true when its promise resolved", () => {
184
+ expect(isPromise(Promise.resolve())).toBe(true);
185
+ });
186
+ });
187
+
188
+ describe("nameOf", () => {
189
+ it("should return 'Test' when class is given", () => {
190
+ expect(nameOf(Test)).toBe("Test");
191
+ });
192
+ it("should return 'test2' when symbol is given", () => {
193
+ expect(nameOf(sym)).toBe("test2");
194
+ });
195
+ it("should return 'test' when string is given", () => {
196
+ expect(nameOf("test")).toBe("test");
197
+ });
198
+ it("should return '1' when string is given", () => {
199
+ expect(nameOf(1)).toBe("1");
200
+ });
201
+ it("should return 'true' when boolean is given", () => {
202
+ expect(nameOf(true)).toBe("true");
203
+ });
204
+ it("should return 'null' when null is given", () => {
205
+ expect(nameOf(null)).toBe("null");
206
+ });
207
+ it("should return 'undefined' when undefined is given", () => {
208
+ expect(nameOf(undefined)).toBe("undefined");
209
+ });
210
+ });
211
+
212
+ describe("nameOfClass", () => {
213
+ it("should return name when class is given", () => {
214
+ expect(nameOfClass(Test)).toBe("Test");
215
+ });
216
+ it("should return name when instance is given", () => {
217
+ expect(nameOfClass(new Test())).toBe("Test");
218
+ });
219
+ });
220
+
221
+ describe("primitiveOf", () => {
222
+ it("should return string", () => {
223
+ expect(primitiveOf(String)).toBe("string");
224
+ });
225
+
226
+ it("should return number", () => {
227
+ expect(primitiveOf(Number)).toBe("number");
228
+ });
229
+
230
+ it("should return boolean", () => {
231
+ expect(primitiveOf(Boolean)).toBe("boolean");
232
+ });
233
+
234
+ it("should return any", () => {
235
+ expect(primitiveOf(Object)).toBe("any");
236
+ });
237
+ });
238
+
239
+ describe("constructorOf()", () => {
240
+ it("should return the constructor when class is given", () => {
241
+ expect(constructorOf(Test)).toBe(Test);
242
+ });
243
+ it("should return the constructor when instance is given", () => {
244
+ expect(constructorOf(new Test())).toBe(Test);
245
+ });
246
+ });
247
+
248
+ describe("classOf()", () => {
249
+ it("should return the class when class is given", () => {
250
+ expect(classOf(Test)).toBe(Test);
251
+ });
252
+
253
+ it("should return the class when instance is given", () => {
254
+ expect(classOf(new Test())).toBe(Test);
255
+ });
256
+
257
+ it("should return the class when prototype is given", () => {
258
+ expect(classOf(Test.prototype)).toBe(Test);
259
+ });
260
+ });
261
+ describe("ancestorsOf()", () => {
262
+ it("should returns ancestors", () => {
263
+ class Base {}
264
+
265
+ class Test extends Base {}
266
+
267
+ expect(ancestorsOf(Test)).toEqual([Base, Test]);
268
+ expect(ancestorsOf(Test).reverse()).toEqual([Test, Base]);
269
+ });
270
+ });
271
+
272
+ describe("methodsOf", () => {
273
+ it("should return all methods", () => {
274
+ const methods = methodsOf(Test);
275
+ expect(methods).toEqual([
276
+ {propertyKey: "test1", target: Test},
277
+ {propertyKey: "test3", target: Base},
278
+ {propertyKey: "test2", target: Test}
279
+ ]);
280
+ });
281
+ });
282
+ describe("isInheritedFrom", () => {
283
+ it("should return true when class inherit from another", () => {
284
+ class Test1 {}
285
+
286
+ class Test2 extends Test1 {}
287
+
288
+ expect(isInheritedFrom(Test2, Test1)).toBe(true);
289
+ });
290
+ it("should return false when deep is down", () => {
291
+ class Test1 {}
292
+
293
+ class Test2 extends Test1 {}
294
+
295
+ class Test3 extends Test2 {}
296
+
297
+ expect(isInheritedFrom(Test3, Test1, 1)).toBe(false);
298
+ });
299
+
300
+ it("should return true when deep is not down", () => {
301
+ class Test1 {}
302
+
303
+ class Test2 extends Test1 {}
304
+
305
+ class Test3 extends Test2 {}
306
+
307
+ expect(isInheritedFrom(Test3, Test1, 3)).toBe(true);
308
+ });
309
+
310
+ it("should return false when class isn't inherit from another", () => {
311
+ class Test1 {}
312
+
313
+ class Test3 {}
314
+
315
+ expect(isInheritedFrom(Test3, Test1)).toBe(false);
316
+ });
317
+
318
+ it("should return false when undefined is given", () => {
319
+ expect(isInheritedFrom(undefined, undefined)).toBe(false);
320
+ });
321
+ });
322
+ });
@@ -0,0 +1,7 @@
1
+ export function ancestorOf(target: any): any {
2
+ return target && Object.getPrototypeOf(target);
3
+ }
4
+
5
+ export function getInheritedClass(target: any): any {
6
+ return ancestorOf(target);
7
+ }
@@ -0,0 +1,21 @@
1
+ import {getInheritedClass} from "./ancestorOf.js";
2
+ import {classOf} from "./classOf.js";
3
+ import {nameOf} from "./nameOf.js";
4
+
5
+ /**
6
+ *
7
+ * @param target
8
+ * @returns {Array}
9
+ */
10
+ export function ancestorsOf(target: any) {
11
+ const classes = [];
12
+
13
+ let currentTarget = classOf(target);
14
+
15
+ while (currentTarget && nameOf(currentTarget) !== "") {
16
+ classes.unshift(currentTarget);
17
+ currentTarget = getInheritedClass(currentTarget);
18
+ }
19
+
20
+ return classes;
21
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Get the provide constructor if target is an instance.
3
+ * @param target
4
+ * @returns {*}
5
+ */
6
+ export function getClass(target: any): any {
7
+ return target.prototype ? target : target.constructor;
8
+ }
9
+
10
+ /**
11
+ * Get the provide constructor if target is an instance.
12
+ * @param target
13
+ * @returns {*}
14
+ * @alias getClass
15
+ */
16
+ export function classOf(target: any) {
17
+ return getClass(target);
18
+ }
@@ -0,0 +1,22 @@
1
+ import {cleanObject} from "./cleanObject.js";
2
+
3
+ describe("cleanObject", () => {
4
+ it("should clean undefined value from object", () => {
5
+ expect(
6
+ cleanObject(
7
+ {
8
+ test: undefined,
9
+ test2: false,
10
+ test3: null,
11
+ test4: "",
12
+ ignored: "key"
13
+ },
14
+ ["ignored"]
15
+ )
16
+ ).toEqual({
17
+ test2: false,
18
+ test3: null,
19
+ test4: ""
20
+ });
21
+ });
22
+ });
@@ -0,0 +1,20 @@
1
+ import {isProtectedKey} from "./isProtectedKey.js";
2
+ /**
3
+ * Remove undefined value
4
+ * @param obj
5
+ * @param ignore
6
+ */
7
+ export function cleanObject(obj: Record<string, unknown>, ignore: string[] = []): any {
8
+ return Object.entries(obj).reduce(
9
+ (obj, [key, value]) => {
10
+ if (isProtectedKey(key) || ignore.includes(key) || value === undefined) {
11
+ return obj;
12
+ }
13
+
14
+ obj[key] = value;
15
+
16
+ return obj;
17
+ },
18
+ {} as Record<string, unknown>
19
+ );
20
+ }
@@ -0,0 +1,17 @@
1
+ import type {Type} from "../../domain/Type.js";
2
+
3
+ /**
4
+ * Get the class constructor
5
+ * @param target
6
+ */
7
+ export function getConstructor(target: any): Type<any> {
8
+ return typeof target === "function" ? target : target.constructor;
9
+ }
10
+
11
+ /**
12
+ * Get the class constructor
13
+ * @param target
14
+ */
15
+ export function constructorOf(target: any): Type<any> {
16
+ return getConstructor(target);
17
+ }
@@ -0,0 +1,5 @@
1
+ import {classOf} from "./classOf.js";
2
+
3
+ export function createInstance(obj: any) {
4
+ return obj ? (classOf(obj) !== Object ? Object.create(obj) : {}) : {};
5
+ }