@tsed/core 8.0.1 → 8.0.3

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 (111) hide show
  1. package/package.json +5 -4
  2. package/readme.md +5 -5
  3. package/src/decorators/storeFn.ts +20 -0
  4. package/src/decorators/storeMerge.ts +8 -0
  5. package/src/decorators/storeSet.ts +8 -0
  6. package/src/domain/AnyToPromise.spec.ts +158 -0
  7. package/src/domain/AnyToPromise.ts +181 -0
  8. package/src/domain/DecoratorTypes.ts +10 -0
  9. package/src/domain/Env.ts +15 -0
  10. package/src/domain/Metadata.spec.ts +142 -0
  11. package/src/domain/Metadata.ts +523 -0
  12. package/src/domain/Store.spec.ts +164 -0
  13. package/src/domain/Store.ts +175 -0
  14. package/src/domain/Type.ts +20 -0
  15. package/src/errors/UnsupportedDecoratorType.spec.ts +81 -0
  16. package/src/errors/UnsupportedDecoratorType.ts +25 -0
  17. package/src/index.ts +75 -0
  18. package/src/interfaces/AnyDecorator.ts +1 -0
  19. package/src/interfaces/DecoratorParameters.ts +8 -0
  20. package/src/interfaces/MetadataTypes.ts +6 -0
  21. package/src/interfaces/Relation.ts +1 -0
  22. package/src/interfaces/ValueOf.ts +1 -0
  23. package/src/utils/catchError.spec.ts +17 -0
  24. package/src/utils/catchError.ts +15 -0
  25. package/src/utils/decorators/decorateMethodsOf.spec.ts +83 -0
  26. package/src/utils/decorators/decorateMethodsOf.ts +31 -0
  27. package/src/utils/decorators/decoratorArgs.spec.ts +15 -0
  28. package/src/utils/decorators/decoratorArgs.ts +6 -0
  29. package/src/utils/decorators/decoratorTypeOf.spec.ts +92 -0
  30. package/src/utils/decorators/decoratorTypeOf.ts +24 -0
  31. package/src/utils/decorators/inheritedDescriptorOf.ts +13 -0
  32. package/src/utils/decorators/useDecorators.spec.ts +61 -0
  33. package/src/utils/decorators/useDecorators.ts +21 -0
  34. package/src/utils/decorators/useMethodDecorator.spec.ts +45 -0
  35. package/src/utils/decorators/useMethodDecorators.ts +12 -0
  36. package/src/utils/getRandomId.spec.ts +7 -0
  37. package/src/utils/getRandomId.ts +3 -0
  38. package/src/utils/http/getHostInfoFromPort.spec.ts +25 -0
  39. package/src/utils/http/getHostInfoFromPort.ts +20 -0
  40. package/src/utils/objects/ObjectUtils.spec.ts +322 -0
  41. package/src/utils/objects/ancestorOf.ts +7 -0
  42. package/src/utils/objects/ancestorsOf.ts +21 -0
  43. package/src/utils/objects/classOf.ts +18 -0
  44. package/src/utils/objects/cleanObject.spec.ts +22 -0
  45. package/src/utils/objects/cleanObject.ts +20 -0
  46. package/src/utils/objects/constructorOf.ts +17 -0
  47. package/src/utils/objects/createInstance.ts +5 -0
  48. package/src/utils/objects/deepClone.spec.ts +130 -0
  49. package/src/utils/objects/deepClone.ts +85 -0
  50. package/src/utils/objects/deepMerge.spec.ts +196 -0
  51. package/src/utils/objects/deepMerge.ts +84 -0
  52. package/src/utils/objects/descriptorOf.spec.ts +16 -0
  53. package/src/utils/objects/descriptorOf.ts +13 -0
  54. package/src/utils/objects/getClassOrSymbol.ts +6 -0
  55. package/src/utils/objects/getConstructorArgNames.spec.ts +11 -0
  56. package/src/utils/objects/getConstructorArgNames.ts +10 -0
  57. package/src/utils/objects/getValue.spec.ts +62 -0
  58. package/src/utils/objects/getValue.ts +87 -0
  59. package/src/utils/objects/hasJsonMethod.spec.ts +11 -0
  60. package/src/utils/objects/hasJsonMethod.ts +3 -0
  61. package/src/utils/objects/isArray.ts +18 -0
  62. package/src/utils/objects/isArrowFn.ts +5 -0
  63. package/src/utils/objects/isBoolean.ts +12 -0
  64. package/src/utils/objects/isBuffer.spec.ts +14 -0
  65. package/src/utils/objects/isBuffer.ts +19 -0
  66. package/src/utils/objects/isClass.spec.ts +15 -0
  67. package/src/utils/objects/isClass.ts +28 -0
  68. package/src/utils/objects/isCollection.ts +20 -0
  69. package/src/utils/objects/isDate.ts +8 -0
  70. package/src/utils/objects/isEmpty.spec.ts +10 -0
  71. package/src/utils/objects/isEmpty.ts +10 -0
  72. package/src/utils/objects/isEnumerable.ts +21 -0
  73. package/src/utils/objects/isFunction.ts +3 -0
  74. package/src/utils/objects/isInheritedFrom.ts +26 -0
  75. package/src/utils/objects/isMomentObject.spec.ts +16 -0
  76. package/src/utils/objects/isMomentObject.ts +3 -0
  77. package/src/utils/objects/isMongooseObject.spec.ts +22 -0
  78. package/src/utils/objects/isMongooseObject.ts +9 -0
  79. package/src/utils/objects/isNil.spec.ts +10 -0
  80. package/src/utils/objects/isNil.ts +3 -0
  81. package/src/utils/objects/isNumber.ts +12 -0
  82. package/src/utils/objects/isObject.ts +3 -0
  83. package/src/utils/objects/isObservable.ts +3 -0
  84. package/src/utils/objects/isPlainObject.spec.ts +10 -0
  85. package/src/utils/objects/isPlainObject.ts +14 -0
  86. package/src/utils/objects/isPrimitive.spec.ts +17 -0
  87. package/src/utils/objects/isPrimitive.ts +26 -0
  88. package/src/utils/objects/isPromise.ts +13 -0
  89. package/src/utils/objects/isProtectedKey.spec.ts +14 -0
  90. package/src/utils/objects/isProtectedKey.ts +7 -0
  91. package/src/utils/objects/isRegExp.ts +3 -0
  92. package/src/utils/objects/isSerializable.spec.ts +14 -0
  93. package/src/utils/objects/isSerializable.ts +9 -0
  94. package/src/utils/objects/isStream.ts +3 -0
  95. package/src/utils/objects/isString.ts +11 -0
  96. package/src/utils/objects/isSymbol.spec.ts +11 -0
  97. package/src/utils/objects/isSymbol.ts +11 -0
  98. package/src/utils/objects/methodsOf.ts +25 -0
  99. package/src/utils/objects/nameOf.ts +27 -0
  100. package/src/utils/objects/objectKeys.spec.ts +10 -0
  101. package/src/utils/objects/objectKeys.ts +5 -0
  102. package/src/utils/objects/primitiveOf.ts +19 -0
  103. package/src/utils/objects/prototypeOf.ts +10 -0
  104. package/src/utils/objects/setValue.spec.ts +60 -0
  105. package/src/utils/objects/setValue.ts +35 -0
  106. package/src/utils/objects/toMap.spec.ts +211 -0
  107. package/src/utils/objects/toMap.ts +44 -0
  108. package/src/utils/objects/toStringConstructor.ts +9 -0
  109. package/src/utils/objects/toStringConstrutor.spec.ts +18 -0
  110. package/src/utils/objects/uniq.spec.ts +8 -0
  111. package/src/utils/objects/uniq.ts +16 -0
@@ -0,0 +1,130 @@
1
+ import {deepClone} from "./deepClone.js";
2
+
3
+ describe("deepClone", () => {
4
+ class Base {
5
+ public test2: string;
6
+
7
+ constructor(test: string) {
8
+ this.test2 = test + "2";
9
+ }
10
+
11
+ get test3(): string {
12
+ return this.test2;
13
+ }
14
+ }
15
+
16
+ class Test extends Base {
17
+ constructor(private _test: string) {
18
+ super(_test);
19
+ }
20
+
21
+ get test(): string {
22
+ return this._test;
23
+ }
24
+ }
25
+
26
+ it("should clone object", () => {
27
+ const externalObject = {
28
+ color: "red"
29
+ };
30
+ const symbol = Symbol("test");
31
+ const original = {
32
+ a: new Date(),
33
+ b: NaN,
34
+ c: new Function(),
35
+ d: undefined,
36
+ e: function name() {},
37
+ f: Number,
38
+ g: false,
39
+ h: Infinity,
40
+ i: externalObject,
41
+ j: new Test("test"),
42
+ k: [new Test("test"), false, 1, Test],
43
+ l: new RegExp(/test/i),
44
+ m: null,
45
+ n: symbol
46
+ };
47
+
48
+ const cloned = deepClone(original);
49
+
50
+ expect(cloned).toEqual(original);
51
+ expect(cloned).not.toBe(original);
52
+
53
+ expect(cloned.j).toBeInstanceOf(Test);
54
+ expect(cloned.j.test).toBe("test");
55
+ expect(cloned.j.test2).toBe("test2");
56
+
57
+ expect(cloned.k).toBeInstanceOf(Array);
58
+ expect(cloned.k.length).toBe(4);
59
+ expect(cloned.k[0]).toBeInstanceOf(Test);
60
+ expect(cloned.k[3]).toBe(Test);
61
+
62
+ expect(cloned.l).toBeInstanceOf(RegExp);
63
+ expect(cloned.l.source).toBe("test");
64
+ expect(cloned.l.flags).toBe("i");
65
+
66
+ expect(cloned.m).toBeNull();
67
+ expect(cloned.n).toBe(symbol);
68
+
69
+ expect(deepClone(new Test("test"))).toBeInstanceOf(Test);
70
+ });
71
+
72
+ it("should clone object with circular obj", () => {
73
+ const original = {
74
+ posts: [
75
+ {
76
+ id: 0,
77
+ user: {}
78
+ }
79
+ ],
80
+ user: {
81
+ id: 1,
82
+ posts: [] as any[]
83
+ }
84
+ };
85
+
86
+ original.posts[0].user = original.user;
87
+ original.user.posts.push(original.posts[0]);
88
+
89
+ expect(deepClone(original)).toEqual(original);
90
+ });
91
+
92
+ it("should clone a buffer", () => {
93
+ class FakeStorage {
94
+ testBuffer: Buffer;
95
+
96
+ constructor() {
97
+ this.testBuffer = Buffer.from("Hello");
98
+ }
99
+
100
+ get() {
101
+ return this.testBuffer.toString("utf-8");
102
+ }
103
+ }
104
+
105
+ const result = deepClone({storage: new FakeStorage()});
106
+ expect(result.storage.get()).toEqual("Hello");
107
+ });
108
+
109
+ it("should clone Map, Set, and Array", () => {
110
+ class FakeStorage {
111
+ set = new Set([new Test("test")]);
112
+ map = new Map([["test", Test]]);
113
+ array = [new Test("test"), Test, new Map([["test", new Test("test")]])];
114
+ }
115
+
116
+ const expected = {storage: new FakeStorage()};
117
+ const result = deepClone(expected);
118
+
119
+ expect(result).toEqual(expected);
120
+ expect(result).not.toBe(expected);
121
+ });
122
+
123
+ it("should clone typed arrays", () => {
124
+ const original = new Int8Array([1, 2, 3]);
125
+ const result = deepClone(original);
126
+
127
+ expect(result).toEqual(original);
128
+ expect(result).toBeInstanceOf(Int8Array);
129
+ });
130
+ });
@@ -0,0 +1,85 @@
1
+ import {classOf} from "./classOf.js";
2
+ import {isDate} from "./isDate.js";
3
+ import {isFunction} from "./isFunction.js";
4
+ import {isNil} from "./isNil.js";
5
+ import {isPrimitive} from "./isPrimitive.js";
6
+ import {isRegExp} from "./isRegExp.js";
7
+ import {isSymbol} from "./isSymbol.js";
8
+
9
+ const isBasicType = (source: any) => isNil(source) || isPrimitive(source) || isSymbol(source) || isFunction(source);
10
+
11
+ /**
12
+ * Return a cloned value
13
+ * @param source
14
+ * @param stack
15
+ */
16
+ export const deepClone = (source: any, stack = new WeakMap()): any => {
17
+ // provides an early exit for simple cases
18
+ if (isBasicType(source)) {
19
+ return source;
20
+ }
21
+
22
+ const stacked = stack.get(source);
23
+
24
+ if (stacked) {
25
+ // See issue #1619
26
+ return stacked;
27
+ }
28
+
29
+ if (ArrayBuffer.isView(source)) {
30
+ return Buffer.isBuffer(source)
31
+ ? Buffer.from(source)
32
+ : // adds support for all kind of TypedArray such as Int8Array, Uint8Array, etc
33
+ new (classOf(source))(source.buffer.slice(0), source.byteOffset, source.byteLength);
34
+ }
35
+
36
+ if (isDate(source)) {
37
+ return new Date(source);
38
+ }
39
+
40
+ if (isRegExp(source)) {
41
+ return new RegExp(source);
42
+ }
43
+
44
+ if (Array.isArray(source)) {
45
+ const clone: unknown[] = [];
46
+ stack.set(source, clone);
47
+ source.forEach((item, idx) => (clone[idx] = deepClone(item, stack)));
48
+ return clone;
49
+ }
50
+
51
+ if (source instanceof Map) {
52
+ const clone = new Map();
53
+ stack.set(source, clone);
54
+ source.forEach((value, key) => clone.set(deepClone(key, stack), deepClone(value, stack)));
55
+ return clone;
56
+ }
57
+
58
+ if (source instanceof Set) {
59
+ const clone = new Set();
60
+ stack.set(source, clone);
61
+ source.forEach((value) => clone.add(deepClone(value, stack)));
62
+ return clone;
63
+ }
64
+
65
+ const clone = Object.create(Reflect.getPrototypeOf(source));
66
+ stack.set(source, clone);
67
+
68
+ Reflect.ownKeys(source).forEach((key) => {
69
+ // respects property descriptors and the prototype chain more explicitly, which is important for objects with getter/setter.
70
+ const descriptor = Object.getOwnPropertyDescriptor(source, key);
71
+
72
+ if (descriptor) {
73
+ if (!isFunction(descriptor.value)) {
74
+ Object.defineProperty(clone, key, {
75
+ ...descriptor,
76
+ value: deepClone(descriptor.value, stack)
77
+ });
78
+ } else {
79
+ Object.defineProperty(clone, key, descriptor);
80
+ }
81
+ }
82
+ });
83
+
84
+ return clone;
85
+ };
@@ -0,0 +1,196 @@
1
+ import {deepMerge} from "./deepMerge.js";
2
+
3
+ describe("deepMerge", () => {
4
+ describe("without reducers", () => {
5
+ describe("when is an object", () => {
6
+ it("should merge data (1)", () => {
7
+ expect(
8
+ deepMerge(
9
+ {
10
+ security: ["o"]
11
+ },
12
+ undefined
13
+ )
14
+ ).toEqual({
15
+ security: ["o"]
16
+ });
17
+ });
18
+ it("should merge data (2)", () => {
19
+ const klass = class {
20
+ test = "test";
21
+ };
22
+ const result = deepMerge(
23
+ {
24
+ security: ["o"]
25
+ },
26
+ {
27
+ security: ["o", "o1"],
28
+ withClass: new klass()
29
+ }
30
+ );
31
+ expect(result).toEqual({
32
+ security: ["o", "o1"],
33
+ withClass: {
34
+ test: "test"
35
+ }
36
+ });
37
+
38
+ expect(result.withClass).toBeInstanceOf(klass);
39
+ });
40
+ it("should merge data (3)", () => {
41
+ expect(
42
+ deepMerge(
43
+ {
44
+ security: [{"1": "o"}]
45
+ },
46
+ {
47
+ security: [{"1": "o"}, {"2": "o1"}]
48
+ }
49
+ )
50
+ ).toEqual({
51
+ security: [{"1": "o"}, {"1": "o"}, {"2": "o1"}]
52
+ });
53
+ });
54
+ it("should merge data (4)", () => {
55
+ expect(
56
+ deepMerge(
57
+ {
58
+ prop: {}
59
+ },
60
+ {
61
+ prop: ""
62
+ }
63
+ )
64
+ ).toEqual({
65
+ prop: {}
66
+ });
67
+ });
68
+ it("should merge data and prevent prototype pollution", () => {
69
+ const obj = JSON.parse('{"__proto__": {"a": "vulnerable"}, "security": [{"1": "o"}, {"2": "o1"}]}');
70
+
71
+ expect(
72
+ deepMerge(
73
+ {
74
+ security: [{"1": "o"}]
75
+ },
76
+ obj
77
+ )
78
+ ).toEqual({
79
+ security: [{"1": "o"}, {"1": "o"}, {"2": "o1"}]
80
+ });
81
+
82
+ expect(({} as any).a).toBeUndefined();
83
+ });
84
+ });
85
+
86
+ describe("when is an array", () => {
87
+ it("should merge data (1)", () => {
88
+ expect(deepMerge(["1", "2", "4"], ["1", "2", "3"])).toEqual(["1", "2", "4", "3"]);
89
+ });
90
+
91
+ it("should merge data (2)", () => {
92
+ expect(deepMerge([{"1": "1"}, {"2": "2"}, {"4": "4"}], [{"1": "1"}, {"2": "2"}, {"3": "3"}])).toEqual([
93
+ {"1": "1"},
94
+ {"2": "2"},
95
+ {"4": "4"},
96
+ {"1": "1"},
97
+ {"2": "2"},
98
+ {"3": "3"}
99
+ ]);
100
+ });
101
+ });
102
+ });
103
+
104
+ describe("with reducers", () => {
105
+ describe("when is an object", () => {
106
+ it("should merge data", () => {
107
+ expect(
108
+ deepMerge(
109
+ {
110
+ security: ["o"]
111
+ },
112
+ {
113
+ security: ["o", "o1"]
114
+ },
115
+ {
116
+ reducers: {
117
+ default: (collection, value) => {
118
+ if (collection.indexOf(value) === -1) {
119
+ collection.push(value);
120
+ }
121
+
122
+ return collection;
123
+ }
124
+ }
125
+ }
126
+ )
127
+ ).toEqual({
128
+ security: ["o", "o1"]
129
+ });
130
+ });
131
+ it("should merge data (2)", () => {
132
+ expect(
133
+ deepMerge(
134
+ {
135
+ parameters: [
136
+ {in: "test", name: "get", description: "test"},
137
+ {
138
+ in: "test",
139
+ name: "post",
140
+ description: "test"
141
+ }
142
+ ]
143
+ },
144
+ {
145
+ parameters: [
146
+ {in: "test", name: "get", description: "test2"},
147
+ {
148
+ in: "test",
149
+ name: "util",
150
+ description: "test2"
151
+ }
152
+ ]
153
+ },
154
+ {
155
+ reducers: {
156
+ parameters: (collection, value, options) => {
157
+ const index = collection.findIndex((current) => current.in === value.in && current.name === value.name);
158
+
159
+ if (index === -1) {
160
+ return [...collection, value];
161
+ }
162
+
163
+ collection[index] = deepMerge(collection[index], value, options);
164
+
165
+ return collection;
166
+ }
167
+ }
168
+ }
169
+ )
170
+ ).toEqual({
171
+ parameters: [
172
+ {in: "test", name: "get", description: "test2"},
173
+ {in: "test", name: "post", description: "test"},
174
+ {in: "test", name: "util", description: "test2"}
175
+ ]
176
+ });
177
+ });
178
+ });
179
+
180
+ describe("when is an array", () => {
181
+ it("should merge data", () => {
182
+ expect(deepMerge(["1", "2", "4"], ["1", "2", "3"])).toEqual(["1", "2", "4", "3"]);
183
+ });
184
+ it("should merge data (2)", () => {
185
+ expect(deepMerge([{"1": "1"}, {"2": "2"}, {"4": "4"}], [{"1": "1"}, {"2": "2"}, {"3": "3"}])).toEqual([
186
+ {"1": "1"},
187
+ {"2": "2"},
188
+ {"4": "4"},
189
+ {"1": "1"},
190
+ {"2": "2"},
191
+ {"3": "3"}
192
+ ]);
193
+ });
194
+ });
195
+ });
196
+ });
@@ -0,0 +1,84 @@
1
+ import {createInstance} from "./createInstance.js";
2
+ import {isFunction} from "./isFunction.js";
3
+ import {isPrimitive} from "./isPrimitive.js";
4
+ import {isSymbol} from "./isSymbol.js";
5
+ import {objectKeys} from "./objectKeys.js";
6
+
7
+ export type DeepMergeReducerCB = (collection: any[], value: any, options?: DeepMergeOptions) => any;
8
+ export type DeepMergeComparatorCB = (item: any, ref: any) => boolean;
9
+
10
+ export interface DeepMergeOptions {
11
+ reducers?: Record<string, DeepMergeReducerCB>;
12
+ parentKey?: string;
13
+ cleanUndefinedProps?: boolean;
14
+ }
15
+
16
+ export function mergeReducerBuilder(cb: DeepMergeComparatorCB) {
17
+ return (collection: any[], value: any, options: DeepMergeOptions) => {
18
+ const index = collection.findIndex((item) => cb(item, value));
19
+
20
+ if (index === -1) {
21
+ return [...collection, value];
22
+ }
23
+
24
+ collection[index] = deepMerge(collection[index], value, options);
25
+
26
+ return collection;
27
+ };
28
+ }
29
+
30
+ const defaultReducer = mergeReducerBuilder((a, b) => a === b);
31
+
32
+ function getReducer({reducers, parentKey}: DeepMergeOptions) {
33
+ if (!reducers) {
34
+ return defaultReducer;
35
+ }
36
+
37
+ if (parentKey && reducers[parentKey]) {
38
+ return reducers[parentKey];
39
+ }
40
+
41
+ return reducers["default"] || defaultReducer;
42
+ }
43
+
44
+ function shouldReturnObj(obj: any, source: any) {
45
+ return isPrimitive(obj) || isSymbol(obj) || isFunction(obj) || source === undefined;
46
+ }
47
+
48
+ function shouldReturnSource(obj: any, source: any) {
49
+ return obj === undefined || obj === null || (obj === "" && source !== "");
50
+ }
51
+
52
+ export function deepMerge<T = any, C = any>(source: T & any, obj: C & any, options: DeepMergeOptions = {}): (T & C) | undefined | null {
53
+ if (shouldReturnSource(obj, source)) {
54
+ return source as any;
55
+ }
56
+
57
+ if (shouldReturnObj(obj, source)) {
58
+ return obj;
59
+ }
60
+
61
+ if (Array.isArray(source)) {
62
+ const reducer = getReducer(options);
63
+
64
+ return [].concat(obj).reduce((out: any[], value: any) => reducer(out, value, options), [...source]);
65
+ }
66
+
67
+ const newObj = createInstance(source);
68
+
69
+ return [...objectKeys(source), ...objectKeys(obj)].reduce((out: any, key: string) => {
70
+ const src = source && source[key];
71
+ const value = deepMerge(src, obj && obj[key], {
72
+ ...options,
73
+ parentKey: key
74
+ });
75
+
76
+ if (options.cleanUndefinedProps && value === undefined) {
77
+ return out;
78
+ }
79
+
80
+ out[key] = value;
81
+
82
+ return out;
83
+ }, newObj);
84
+ }
@@ -0,0 +1,16 @@
1
+ import {isMethodDescriptor} from "./descriptorOf.js";
2
+
3
+ describe("isMethodDescriptor()", () => {
4
+ it("should return true", () => {
5
+ class Test {
6
+ test() {}
7
+ }
8
+ expect(isMethodDescriptor(Test, "test")).toBeTruthy();
9
+ });
10
+ it("should return false", () => {
11
+ class Test {
12
+ test: string;
13
+ }
14
+ expect(isMethodDescriptor(Test, "test")).toBeFalsy();
15
+ });
16
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Return the descriptor for a given class and propertyKey
3
+ * @param target
4
+ * @param {string} propertyKey
5
+ * @returns {PropertyDescriptor}
6
+ */
7
+ export function descriptorOf(target: any, propertyKey: string | symbol): PropertyDescriptor {
8
+ return Reflect.getOwnPropertyDescriptor((target && target.prototype) || target, propertyKey)!;
9
+ }
10
+
11
+ export function isMethodDescriptor(target: any, propertyKey: string | symbol) {
12
+ return descriptorOf(target, propertyKey)?.value;
13
+ }
@@ -0,0 +1,6 @@
1
+ import {classOf} from "./classOf.js";
2
+ import {isClass} from "./isClass.js";
3
+
4
+ export function getClassOrSymbol(target: any): any {
5
+ return isClass(target) ? classOf(target) : target;
6
+ }
@@ -0,0 +1,11 @@
1
+ import {getConstructorArgNames} from "./getConstructorArgNames.js";
2
+
3
+ describe("getConstructorArgNames", () => {
4
+ it("should return the constructor args names", () => {
5
+ class Test {
6
+ constructor(test: string) {}
7
+ }
8
+
9
+ expect(getConstructorArgNames(Test)).toEqual(["test"]);
10
+ });
11
+ });
@@ -0,0 +1,10 @@
1
+ import {toStringConstructor} from "./toStringConstructor.js";
2
+
3
+ export function getConstructorArgNames(target: any) {
4
+ return toStringConstructor(target)
5
+ .split("constructor(")[1]
6
+ .split(")")[0]
7
+ .split(", ")
8
+ .filter(Boolean)
9
+ .map((s) => s.trim());
10
+ }
@@ -0,0 +1,62 @@
1
+ import {getValue} from "./getValue.js";
2
+
3
+ describe("getValue()", () => {
4
+ it("should return given value when expression is undefined", () => {
5
+ expect(getValue(undefined, {})).toEqual({});
6
+ expect(getValue({}, undefined)).toEqual({});
7
+ });
8
+ it("should return given value when expression is undefined 2", () => {
9
+ expect(getValue(undefined, undefined)).toEqual(undefined);
10
+ });
11
+ it("should return given undefined when expression is given but scope doesn't have value", () => {
12
+ expect(getValue("user", {})).toEqual(undefined);
13
+ expect(getValue({}, "user")).toEqual(undefined);
14
+ });
15
+ it("should return given value when expression is given and scope have value", () => {
16
+ expect(getValue("user", {user: "name"})).toEqual("name");
17
+ expect(getValue({user: "name"}, "user")).toEqual("name");
18
+ });
19
+ it("should return given value when expression is given but scope have value (2)", () => {
20
+ expect(getValue("user.name", {user: {name: "name"}})).toEqual("name");
21
+ expect(getValue({user: {name: "name"}}, "user.name")).toEqual("name");
22
+ });
23
+ it("should return given value when expression is given but scope have value (3)", () => {
24
+ expect(getValue("users.0", {users: [{user: {name: "name"}}]})).toEqual({user: {name: "name"}});
25
+ expect(getValue({users: [{user: {name: "name"}}]}, "users.0")).toEqual({user: {name: "name"}});
26
+ });
27
+ it("should return given value when expression is given but scope have value (4)", () => {
28
+ const map = new Map([["user", "name"]]);
29
+ expect(getValue("user", map)).toEqual("name");
30
+ expect(getValue(map, "user")).toEqual("name");
31
+ });
32
+ it("should return from an object with get method", () => {
33
+ const map = {
34
+ get() {
35
+ return "name";
36
+ }
37
+ };
38
+ expect(getValue("user", map)).toEqual("name");
39
+ expect(getValue(map, "user")).toEqual("name");
40
+ });
41
+ it("should return undefined", () => {
42
+ expect(getValue("user", undefined)).toEqual(undefined);
43
+ expect(getValue(undefined, "user")).toEqual(undefined);
44
+ });
45
+
46
+ it("should return undefined from getter", () => {
47
+ expect(
48
+ getValue(
49
+ {
50
+ get test() {
51
+ return undefined;
52
+ },
53
+
54
+ get() {
55
+ return "test";
56
+ }
57
+ },
58
+ "test"
59
+ )
60
+ ).toEqual(undefined);
61
+ });
62
+ });