@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.
- package/package.json +5 -4
- package/readme.md +5 -5
- package/src/decorators/storeFn.ts +20 -0
- package/src/decorators/storeMerge.ts +8 -0
- package/src/decorators/storeSet.ts +8 -0
- package/src/domain/AnyToPromise.spec.ts +158 -0
- package/src/domain/AnyToPromise.ts +181 -0
- package/src/domain/DecoratorTypes.ts +10 -0
- package/src/domain/Env.ts +15 -0
- package/src/domain/Metadata.spec.ts +142 -0
- package/src/domain/Metadata.ts +523 -0
- package/src/domain/Store.spec.ts +164 -0
- package/src/domain/Store.ts +175 -0
- package/src/domain/Type.ts +20 -0
- package/src/errors/UnsupportedDecoratorType.spec.ts +81 -0
- package/src/errors/UnsupportedDecoratorType.ts +25 -0
- package/src/index.ts +75 -0
- package/src/interfaces/AnyDecorator.ts +1 -0
- package/src/interfaces/DecoratorParameters.ts +8 -0
- package/src/interfaces/MetadataTypes.ts +6 -0
- package/src/interfaces/Relation.ts +1 -0
- package/src/interfaces/ValueOf.ts +1 -0
- package/src/utils/catchError.spec.ts +17 -0
- package/src/utils/catchError.ts +15 -0
- package/src/utils/decorators/decorateMethodsOf.spec.ts +83 -0
- package/src/utils/decorators/decorateMethodsOf.ts +31 -0
- package/src/utils/decorators/decoratorArgs.spec.ts +15 -0
- package/src/utils/decorators/decoratorArgs.ts +6 -0
- package/src/utils/decorators/decoratorTypeOf.spec.ts +92 -0
- package/src/utils/decorators/decoratorTypeOf.ts +24 -0
- package/src/utils/decorators/inheritedDescriptorOf.ts +13 -0
- package/src/utils/decorators/useDecorators.spec.ts +61 -0
- package/src/utils/decorators/useDecorators.ts +21 -0
- package/src/utils/decorators/useMethodDecorator.spec.ts +45 -0
- package/src/utils/decorators/useMethodDecorators.ts +12 -0
- package/src/utils/getRandomId.spec.ts +7 -0
- package/src/utils/getRandomId.ts +3 -0
- package/src/utils/http/getHostInfoFromPort.spec.ts +25 -0
- package/src/utils/http/getHostInfoFromPort.ts +20 -0
- package/src/utils/objects/ObjectUtils.spec.ts +322 -0
- package/src/utils/objects/ancestorOf.ts +7 -0
- package/src/utils/objects/ancestorsOf.ts +21 -0
- package/src/utils/objects/classOf.ts +18 -0
- package/src/utils/objects/cleanObject.spec.ts +22 -0
- package/src/utils/objects/cleanObject.ts +20 -0
- package/src/utils/objects/constructorOf.ts +17 -0
- package/src/utils/objects/createInstance.ts +5 -0
- package/src/utils/objects/deepClone.spec.ts +130 -0
- package/src/utils/objects/deepClone.ts +85 -0
- package/src/utils/objects/deepMerge.spec.ts +196 -0
- package/src/utils/objects/deepMerge.ts +84 -0
- package/src/utils/objects/descriptorOf.spec.ts +16 -0
- package/src/utils/objects/descriptorOf.ts +13 -0
- package/src/utils/objects/getClassOrSymbol.ts +6 -0
- package/src/utils/objects/getConstructorArgNames.spec.ts +11 -0
- package/src/utils/objects/getConstructorArgNames.ts +10 -0
- package/src/utils/objects/getValue.spec.ts +62 -0
- package/src/utils/objects/getValue.ts +87 -0
- package/src/utils/objects/hasJsonMethod.spec.ts +11 -0
- package/src/utils/objects/hasJsonMethod.ts +3 -0
- package/src/utils/objects/isArray.ts +18 -0
- package/src/utils/objects/isArrowFn.ts +5 -0
- package/src/utils/objects/isBoolean.ts +12 -0
- package/src/utils/objects/isBuffer.spec.ts +14 -0
- package/src/utils/objects/isBuffer.ts +19 -0
- package/src/utils/objects/isClass.spec.ts +15 -0
- package/src/utils/objects/isClass.ts +28 -0
- package/src/utils/objects/isCollection.ts +20 -0
- package/src/utils/objects/isDate.ts +8 -0
- package/src/utils/objects/isEmpty.spec.ts +10 -0
- package/src/utils/objects/isEmpty.ts +10 -0
- package/src/utils/objects/isEnumerable.ts +21 -0
- package/src/utils/objects/isFunction.ts +3 -0
- package/src/utils/objects/isInheritedFrom.ts +26 -0
- package/src/utils/objects/isMomentObject.spec.ts +16 -0
- package/src/utils/objects/isMomentObject.ts +3 -0
- package/src/utils/objects/isMongooseObject.spec.ts +22 -0
- package/src/utils/objects/isMongooseObject.ts +9 -0
- package/src/utils/objects/isNil.spec.ts +10 -0
- package/src/utils/objects/isNil.ts +3 -0
- package/src/utils/objects/isNumber.ts +12 -0
- package/src/utils/objects/isObject.ts +3 -0
- package/src/utils/objects/isObservable.ts +3 -0
- package/src/utils/objects/isPlainObject.spec.ts +10 -0
- package/src/utils/objects/isPlainObject.ts +14 -0
- package/src/utils/objects/isPrimitive.spec.ts +17 -0
- package/src/utils/objects/isPrimitive.ts +26 -0
- package/src/utils/objects/isPromise.ts +13 -0
- package/src/utils/objects/isProtectedKey.spec.ts +14 -0
- package/src/utils/objects/isProtectedKey.ts +7 -0
- package/src/utils/objects/isRegExp.ts +3 -0
- package/src/utils/objects/isSerializable.spec.ts +14 -0
- package/src/utils/objects/isSerializable.ts +9 -0
- package/src/utils/objects/isStream.ts +3 -0
- package/src/utils/objects/isString.ts +11 -0
- package/src/utils/objects/isSymbol.spec.ts +11 -0
- package/src/utils/objects/isSymbol.ts +11 -0
- package/src/utils/objects/methodsOf.ts +25 -0
- package/src/utils/objects/nameOf.ts +27 -0
- package/src/utils/objects/objectKeys.spec.ts +10 -0
- package/src/utils/objects/objectKeys.ts +5 -0
- package/src/utils/objects/primitiveOf.ts +19 -0
- package/src/utils/objects/prototypeOf.ts +10 -0
- package/src/utils/objects/setValue.spec.ts +60 -0
- package/src/utils/objects/setValue.ts +35 -0
- package/src/utils/objects/toMap.spec.ts +211 -0
- package/src/utils/objects/toMap.ts +44 -0
- package/src/utils/objects/toStringConstructor.ts +9 -0
- package/src/utils/objects/toStringConstrutor.spec.ts +18 -0
- package/src/utils/objects/uniq.spec.ts +8 -0
- package/src/utils/objects/uniq.ts +16 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the provide name.
|
|
3
|
+
* @param targetClass
|
|
4
|
+
*/
|
|
5
|
+
export function nameOfClass(targetClass: any): string {
|
|
6
|
+
return typeof targetClass === "function" ? targetClass.name : targetClass.constructor.name;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get symbol name.
|
|
11
|
+
* @param sym
|
|
12
|
+
*/
|
|
13
|
+
export const nameOfSymbol = (sym: symbol): string => sym.toString().replace("Symbol(", "").replace(")", "");
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Get object name
|
|
17
|
+
*/
|
|
18
|
+
export function nameOf(obj: any): string {
|
|
19
|
+
switch (typeof obj) {
|
|
20
|
+
default:
|
|
21
|
+
return "" + obj;
|
|
22
|
+
case "symbol":
|
|
23
|
+
return nameOfSymbol(obj);
|
|
24
|
+
case "function":
|
|
25
|
+
return nameOfClass(obj);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {objectKeys} from "./objectKeys.js";
|
|
2
|
+
|
|
3
|
+
describe("objectKeys", () => {
|
|
4
|
+
it("should return only authorized keys", () => {
|
|
5
|
+
const obj = JSON.parse('{"__proto__": {"a": "vulnerable"}, "test": "test"}');
|
|
6
|
+
|
|
7
|
+
expect(objectKeys(obj)).toEqual(["test"]);
|
|
8
|
+
expect(({} as any).a).toBeUndefined();
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {isBooleanOrBooleanClass} from "./isBoolean.js";
|
|
2
|
+
import {isNumberOrNumberClass} from "./isNumber.js";
|
|
3
|
+
import {isStringOrStringClass} from "./isString.js";
|
|
4
|
+
|
|
5
|
+
export function primitiveOf(target: any): "string" | "number" | "boolean" | "any" {
|
|
6
|
+
if (isStringOrStringClass(target)) {
|
|
7
|
+
return "string";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (isNumberOrNumberClass(target)) {
|
|
11
|
+
return "number";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (isBooleanOrBooleanClass(target)) {
|
|
15
|
+
return "boolean";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return "any";
|
|
19
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {setValue} from "./setValue.js";
|
|
2
|
+
|
|
3
|
+
describe("setValue()", () => {
|
|
4
|
+
describe("when map", () => {
|
|
5
|
+
it("should set value", () => {
|
|
6
|
+
let map: Map<any, any> = new Map();
|
|
7
|
+
|
|
8
|
+
setValue(map, "test", "value");
|
|
9
|
+
|
|
10
|
+
expect(map.get("test")).toBe("value");
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe("when map with dep", () => {
|
|
15
|
+
it("should set value", () => {
|
|
16
|
+
let map: Map<any, any> = new Map();
|
|
17
|
+
map.set("test", {t1: "value"});
|
|
18
|
+
setValue(map, "test.t1", "value2");
|
|
19
|
+
|
|
20
|
+
expect(map.get("test").t1).toBe("value2");
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("when map with dep (without defined value)", () => {
|
|
25
|
+
it("should set value", () => {
|
|
26
|
+
let map: Map<any, any> = new Map();
|
|
27
|
+
setValue(map, "test.t1", "value2");
|
|
28
|
+
|
|
29
|
+
expect(map.get("test").t1).toBe("value2");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("when object with dep (without defined value)", () => {
|
|
34
|
+
it("should set value", () => {
|
|
35
|
+
const map: any = {test: {t1: "value"}};
|
|
36
|
+
setValue(map, "test.t1", "value2");
|
|
37
|
+
|
|
38
|
+
expect(map.test.t1).toBe("value2");
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("when object with dep (with object defined value)", () => {
|
|
43
|
+
it("should set value", () => {
|
|
44
|
+
const obj = {};
|
|
45
|
+
setValue(obj, "__proto__", "vulnerable");
|
|
46
|
+
expect(obj).toEqual({});
|
|
47
|
+
expect(({} as any).a).toBeUndefined();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe("when a function is given a value", () => {
|
|
52
|
+
it("should set value", () => {
|
|
53
|
+
let map: any = {};
|
|
54
|
+
|
|
55
|
+
setValue(map, "test.deep", () => {});
|
|
56
|
+
|
|
57
|
+
expect(map.test.deep).toBeInstanceOf(Function);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {isProtectedKey} from "./isProtectedKey.js";
|
|
2
|
+
|
|
3
|
+
export function setValue(scope: any, expression: string, value: any, separator = ".") {
|
|
4
|
+
const keys: string[] = expression.split(separator);
|
|
5
|
+
|
|
6
|
+
const setValue = (key: string, add: boolean) => {
|
|
7
|
+
if (isProtectedKey(key)) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (add) {
|
|
12
|
+
if (typeof scope.set === "function") {
|
|
13
|
+
scope.set(key, value);
|
|
14
|
+
} else {
|
|
15
|
+
scope[key] = value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof scope.set === "function") {
|
|
22
|
+
if (!scope.has(key)) {
|
|
23
|
+
scope.set(key, {});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
scope = scope.get(key);
|
|
27
|
+
} else {
|
|
28
|
+
scope = scope[key] = scope[key] || {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return true;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
while (setValue(keys.shift()!, !keys.length)) {}
|
|
35
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {toMap} from "./toMap.js";
|
|
2
|
+
|
|
3
|
+
describe("toMap", () => {
|
|
4
|
+
describe("from Object", () => {
|
|
5
|
+
it("should create map", () => {
|
|
6
|
+
const result = toMap({
|
|
7
|
+
test: {top: "test"},
|
|
8
|
+
test1: {top: "test1"}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
expect(result).toBeInstanceOf(Map);
|
|
12
|
+
expect(result.size).toBe(2);
|
|
13
|
+
expect([...result.keys()]).toEqual(["test", "test1"]);
|
|
14
|
+
expect([...result.values()]).toEqual([{top: "test"}, {top: "test1"}]);
|
|
15
|
+
});
|
|
16
|
+
it("should create map by id", () => {
|
|
17
|
+
const result = toMap(
|
|
18
|
+
{
|
|
19
|
+
test: {id: "1", top: "test"},
|
|
20
|
+
test1: {id: "2", top: "test1"},
|
|
21
|
+
test3: {id: "1", top: "test"}
|
|
22
|
+
},
|
|
23
|
+
"id"
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
expect(result).toBeInstanceOf(Map);
|
|
27
|
+
expect(result.size).toBe(2);
|
|
28
|
+
expect([...result.keys()]).toEqual(["1", "2"]);
|
|
29
|
+
expect([...result.values()]).toEqual([
|
|
30
|
+
{
|
|
31
|
+
id: "1",
|
|
32
|
+
top: "test"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "2",
|
|
36
|
+
top: "test1"
|
|
37
|
+
}
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
it("should create map by fn id", () => {
|
|
41
|
+
const result = toMap(
|
|
42
|
+
{
|
|
43
|
+
test: {id: "1", top: "test"},
|
|
44
|
+
test1: {id: "2", top: "test1"},
|
|
45
|
+
test3: {id: "1", top: "test"}
|
|
46
|
+
},
|
|
47
|
+
(item) => item.id
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
expect(result).toBeInstanceOf(Map);
|
|
51
|
+
expect(result.size).toBe(2);
|
|
52
|
+
expect([...result.keys()]).toEqual(["1", "2"]);
|
|
53
|
+
expect([...result.values()]).toEqual([
|
|
54
|
+
{
|
|
55
|
+
id: "1",
|
|
56
|
+
top: "test"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "2",
|
|
60
|
+
top: "test1"
|
|
61
|
+
}
|
|
62
|
+
]);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe("from Array", () => {
|
|
66
|
+
it("should create map", () => {
|
|
67
|
+
const result = toMap([
|
|
68
|
+
{
|
|
69
|
+
id: "1",
|
|
70
|
+
top: "test"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "2",
|
|
74
|
+
top: "test1"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "1",
|
|
78
|
+
top: "test"
|
|
79
|
+
}
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
expect(result).toBeInstanceOf(Map);
|
|
83
|
+
expect(result.size).toBe(2);
|
|
84
|
+
expect([...result.keys()]).toEqual(["1", "2"]);
|
|
85
|
+
expect([...result.values()]).toEqual([
|
|
86
|
+
{
|
|
87
|
+
id: "1",
|
|
88
|
+
top: "test"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "2",
|
|
92
|
+
top: "test1"
|
|
93
|
+
}
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
it("should create map by id", () => {
|
|
97
|
+
const result = toMap(
|
|
98
|
+
[
|
|
99
|
+
{
|
|
100
|
+
id: "1",
|
|
101
|
+
top: "test"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: "2",
|
|
105
|
+
top: "test1"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: "1",
|
|
109
|
+
top: "test"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"id"
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
expect(result).toBeInstanceOf(Map);
|
|
116
|
+
expect(result.size).toBe(2);
|
|
117
|
+
expect([...result.keys()]).toEqual(["1", "2"]);
|
|
118
|
+
expect([...result.values()]).toEqual([
|
|
119
|
+
{
|
|
120
|
+
id: "1",
|
|
121
|
+
top: "test"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: "2",
|
|
125
|
+
top: "test1"
|
|
126
|
+
}
|
|
127
|
+
]);
|
|
128
|
+
});
|
|
129
|
+
it("should create map by fn id", () => {
|
|
130
|
+
const result = toMap(
|
|
131
|
+
[
|
|
132
|
+
{
|
|
133
|
+
id: "1",
|
|
134
|
+
top: "test"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "2",
|
|
138
|
+
top: "test1"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: "1",
|
|
142
|
+
top: "test"
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
(item) => item.id
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
expect(result).toBeInstanceOf(Map);
|
|
149
|
+
expect(result.size).toBe(2);
|
|
150
|
+
expect([...result.keys()]).toEqual(["1", "2"]);
|
|
151
|
+
expect([...result.values()]).toEqual([
|
|
152
|
+
{
|
|
153
|
+
id: "1",
|
|
154
|
+
top: "test"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: "2",
|
|
158
|
+
top: "test1"
|
|
159
|
+
}
|
|
160
|
+
]);
|
|
161
|
+
});
|
|
162
|
+
it("should create map by fn id + merge", () => {
|
|
163
|
+
class Data {
|
|
164
|
+
id: string;
|
|
165
|
+
count: string;
|
|
166
|
+
|
|
167
|
+
constructor(opts: any) {
|
|
168
|
+
this.id = opts.id;
|
|
169
|
+
this.count = opts.count;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
merge(d: Data) {
|
|
173
|
+
this.count += d.count;
|
|
174
|
+
return this;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const result = toMap(
|
|
179
|
+
[
|
|
180
|
+
new Data({
|
|
181
|
+
id: "1",
|
|
182
|
+
count: 5
|
|
183
|
+
}),
|
|
184
|
+
new Data({
|
|
185
|
+
id: "2",
|
|
186
|
+
count: 5
|
|
187
|
+
}),
|
|
188
|
+
new Data({
|
|
189
|
+
id: "1",
|
|
190
|
+
count: 10
|
|
191
|
+
})
|
|
192
|
+
],
|
|
193
|
+
(item) => item.id
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
expect(result).toBeInstanceOf(Map);
|
|
197
|
+
expect(result.size).toBe(2);
|
|
198
|
+
expect([...result.keys()]).toEqual(["1", "2"]);
|
|
199
|
+
expect([...result.values()]).toEqual([
|
|
200
|
+
{
|
|
201
|
+
count: 15,
|
|
202
|
+
id: "1"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
count: 5,
|
|
206
|
+
id: "2"
|
|
207
|
+
}
|
|
208
|
+
]);
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {isArray} from "./isArray.js";
|
|
2
|
+
import {isString} from "./isString.js";
|
|
3
|
+
|
|
4
|
+
export type ToMapIdentityCB<V> = (item: V, index: string | number) => string | string[];
|
|
5
|
+
export type ToMapIdentity<V> = string | ToMapIdentityCB<V>;
|
|
6
|
+
|
|
7
|
+
function createIdentityFn<V>(keyOrFn?: ToMapIdentity<V>): ToMapIdentityCB<V> {
|
|
8
|
+
if (!keyOrFn) {
|
|
9
|
+
return (v, k) => String(k);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (isString(keyOrFn)) {
|
|
13
|
+
return (item: any) => {
|
|
14
|
+
return item[keyOrFn as string];
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return keyOrFn;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function toMap<K extends keyof any = any, V = any>(input: Record<K, V> | V[], keyOrFn?: ToMapIdentity<V>): Map<K, V> {
|
|
22
|
+
if (isArray<V>(input)) {
|
|
23
|
+
const identity = createIdentityFn<V>(keyOrFn || "id");
|
|
24
|
+
return input.reduce((map, value, index) => {
|
|
25
|
+
const ids = ([] as string[]).concat(identity(value, index));
|
|
26
|
+
|
|
27
|
+
ids.forEach((id) => {
|
|
28
|
+
const item = map.get(id);
|
|
29
|
+
|
|
30
|
+
value = item?.merge?.(value) || value;
|
|
31
|
+
|
|
32
|
+
map.set(id, value);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return map;
|
|
36
|
+
}, new Map());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const identity = createIdentityFn<V>(keyOrFn);
|
|
40
|
+
|
|
41
|
+
return Object.entries(input).reduce((map, [key, value]) => {
|
|
42
|
+
return map.set(identity(value as V, key), value);
|
|
43
|
+
}, new Map());
|
|
44
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {constructorOf} from "./constructorOf.js";
|
|
2
|
+
|
|
3
|
+
export function toStringConstructor(target: any): string {
|
|
4
|
+
const ctr = constructorOf(target);
|
|
5
|
+
const strings = ctr.toString().split("\n");
|
|
6
|
+
const ctrString = strings.find((s) => s.indexOf("constructor(") > -1) || "constructor()";
|
|
7
|
+
|
|
8
|
+
return `${ctrString.replace("{", "").trim()}`;
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {toStringConstructor} from "./toStringConstructor.js";
|
|
2
|
+
|
|
3
|
+
describe("toStringConstructor", () => {
|
|
4
|
+
it("should return the constructor signature (empty)", () => {
|
|
5
|
+
class Test {}
|
|
6
|
+
|
|
7
|
+
expect(toStringConstructor(Test)).toBe("constructor()");
|
|
8
|
+
});
|
|
9
|
+
it("should return the constructor signature", () => {
|
|
10
|
+
class Test {
|
|
11
|
+
constructor(test: string) {
|
|
12
|
+
console.log("test");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
expect(toStringConstructor(Test)).toBe("constructor(test)");
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import {uniq, uniqBy} from "./uniq.js";
|
|
2
|
+
|
|
3
|
+
describe("uniq", () => {
|
|
4
|
+
it("should return uniq item", () => {
|
|
5
|
+
expect(uniq(["test", "test1", "test"])).toEqual(["test", "test1"]);
|
|
6
|
+
expect(uniqBy([{id: "test"}, {id: "test1"}, {id: "test"}], "id")).toEqual([{id: "test"}, {id: "test1"}]);
|
|
7
|
+
});
|
|
8
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param list
|
|
3
|
+
*/
|
|
4
|
+
export function uniq<T = any>(list: T[]): T[] {
|
|
5
|
+
return Array.from(new Set(list).values());
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function uniqBy<T = any>(list: T[], key = "id"): T[] {
|
|
9
|
+
const map = new Map();
|
|
10
|
+
|
|
11
|
+
list.forEach((item: any) => {
|
|
12
|
+
map.set(item[key], item);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return Array.from(map.values());
|
|
16
|
+
}
|