@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,175 @@
|
|
|
1
|
+
import {DecoratorTypes} from "../domain/DecoratorTypes.js";
|
|
2
|
+
import {decoratorTypeOf} from "../utils/decorators/decoratorTypeOf.js";
|
|
3
|
+
import {deepClone} from "../utils/objects/deepClone.js";
|
|
4
|
+
import {deepMerge} from "../utils/objects/deepMerge.js";
|
|
5
|
+
import {descriptorOf} from "../utils/objects/descriptorOf.js";
|
|
6
|
+
import {isSymbol} from "../utils/objects/isSymbol.js";
|
|
7
|
+
import {nameOf} from "../utils/objects/nameOf.js";
|
|
8
|
+
import {Metadata} from "./Metadata.js";
|
|
9
|
+
import type {Type} from "./Type.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @ignore
|
|
13
|
+
*/
|
|
14
|
+
export const CLASS_STORE = "tsed:class:store";
|
|
15
|
+
/**
|
|
16
|
+
* @ignore
|
|
17
|
+
*/
|
|
18
|
+
export const METHOD_STORE = "tsed:method:store";
|
|
19
|
+
/**
|
|
20
|
+
* @ignore
|
|
21
|
+
*/
|
|
22
|
+
export const PROPERTY_STORE = "tsed:property:store";
|
|
23
|
+
/**
|
|
24
|
+
* @ignore
|
|
25
|
+
*/
|
|
26
|
+
export const PARAM_STORE = "tsed:param:store";
|
|
27
|
+
|
|
28
|
+
const stores = new Map<symbol, Store>();
|
|
29
|
+
|
|
30
|
+
function storeGet(key: string, ...args: any[]): Store {
|
|
31
|
+
if (isSymbol(args[0])) {
|
|
32
|
+
if (!stores.has(args[0])) {
|
|
33
|
+
stores.set(args[0], new Store());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return stores.get(args[0])!;
|
|
37
|
+
} else {
|
|
38
|
+
const registry = Metadata as any;
|
|
39
|
+
|
|
40
|
+
if (!registry.hasOwn(key, ...args)) {
|
|
41
|
+
registry.set(key, new Store(), ...args);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return registry.getOwn(key, ...args);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function defineStore(args: any[]): Store {
|
|
49
|
+
const [target, propertyKey, descriptor] = args;
|
|
50
|
+
|
|
51
|
+
switch (decoratorTypeOf(args)) {
|
|
52
|
+
case DecoratorTypes.PARAM_CTOR:
|
|
53
|
+
case DecoratorTypes.PARAM_STC:
|
|
54
|
+
case DecoratorTypes.PARAM:
|
|
55
|
+
const store = storeGet(PARAM_STORE, target, propertyKey);
|
|
56
|
+
if (!store.has("" + descriptor)) {
|
|
57
|
+
store.set("" + descriptor, new Store());
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return store.get("" + descriptor);
|
|
61
|
+
case DecoratorTypes.PROP:
|
|
62
|
+
case DecoratorTypes.PROP_STC:
|
|
63
|
+
return storeGet(PROPERTY_STORE, target, propertyKey);
|
|
64
|
+
case DecoratorTypes.METHOD:
|
|
65
|
+
case DecoratorTypes.METHOD_STC:
|
|
66
|
+
return storeGet(METHOD_STORE, target, propertyKey);
|
|
67
|
+
case DecoratorTypes.CLASS:
|
|
68
|
+
return storeGet(CLASS_STORE, target);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class Store {
|
|
73
|
+
private _entries = new Map<string, any>();
|
|
74
|
+
/**
|
|
75
|
+
* Create or get a Store from given args (target, property, descriptor).
|
|
76
|
+
* @param args
|
|
77
|
+
* @returns {Store}
|
|
78
|
+
*/
|
|
79
|
+
static from(...args: any[]): Store {
|
|
80
|
+
return defineStore(args);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Create store on the method.
|
|
85
|
+
* @param target
|
|
86
|
+
* @param {string} propertyKey
|
|
87
|
+
* @returns {Store}
|
|
88
|
+
*/
|
|
89
|
+
static fromMethod(target: any, propertyKey: string | symbol): Store {
|
|
90
|
+
return Store.from(target, propertyKey, descriptorOf(target, propertyKey));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static mergeStoreFrom(target: Type<any>, source: Type<any>, ...args: any[]) {
|
|
94
|
+
const store = Store.from(target, ...args);
|
|
95
|
+
|
|
96
|
+
Store.from(source, ...args)._entries.forEach((value, key) => {
|
|
97
|
+
store.merge(key, value);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return store;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static mergeStoreMethodFrom(target: Type<any>, source: Type<any>, propertyKey: string | symbol) {
|
|
104
|
+
return this.mergeStoreFrom(target, source, propertyKey, descriptorOf(target, propertyKey));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The get() method returns a specified element from a Map object.
|
|
109
|
+
* @param key Required. The key of the element to return from the Map object.
|
|
110
|
+
* @param defaultValue
|
|
111
|
+
* @returns {T} Returns the element associated with the specified key or undefined if the key can't be found in the Map object.
|
|
112
|
+
*/
|
|
113
|
+
get<T = any>(key: any, defaultValue?: any): T {
|
|
114
|
+
return this._entries.get(nameOf(key)) || defaultValue;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The has() method returns a boolean indicating whether an element with the specified key exists or not.
|
|
119
|
+
* @param key
|
|
120
|
+
* @returns {boolean}
|
|
121
|
+
*/
|
|
122
|
+
has(key: any): boolean {
|
|
123
|
+
return this._entries.has(nameOf(key));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The set() method adds or updates an element with a specified key and value to a Map object.
|
|
128
|
+
* @param key Required. The key of the element to add to the Map object.
|
|
129
|
+
* @param metadata Required. The value of the element to add to the Map object.
|
|
130
|
+
*/
|
|
131
|
+
set(key: any, metadata: any): Store {
|
|
132
|
+
this._entries.set(nameOf(key), metadata);
|
|
133
|
+
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The delete() method removes the specified element from a Map object.
|
|
139
|
+
* @param key Required. The key of the element to remove from the Map object.
|
|
140
|
+
* @returns {boolean} Returns true if an element in the Map object existed and has been removed, or false if the element does not exist.
|
|
141
|
+
*/
|
|
142
|
+
delete(key: string): boolean {
|
|
143
|
+
return this._entries.delete(nameOf(key));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Merge given value with existing value.
|
|
148
|
+
* @param key
|
|
149
|
+
* @param value
|
|
150
|
+
* @param inverse Change the merge order. Get the existing value and apply over given value
|
|
151
|
+
* @returns {Store}
|
|
152
|
+
*/
|
|
153
|
+
merge(key: any, value: any, inverse: boolean = false): Store {
|
|
154
|
+
let _value_ = this.get(key);
|
|
155
|
+
|
|
156
|
+
if (_value_) {
|
|
157
|
+
value = deepClone(value);
|
|
158
|
+
_value_ = deepClone(_value_);
|
|
159
|
+
value = inverse ? deepMerge(value, _value_) : deepMerge(_value_, value);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
this.set(key, value);
|
|
163
|
+
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
toJson() {
|
|
168
|
+
return [...this._entries.entries()].reduce((obj, [key, value]) => {
|
|
169
|
+
return {
|
|
170
|
+
...obj,
|
|
171
|
+
[key]: value
|
|
172
|
+
};
|
|
173
|
+
}, {});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An example of a `Type` is `MyCustomComponent` filters, which in JavaScript is represented by
|
|
3
|
+
* the `MyCustomComponent` constructor function.
|
|
4
|
+
*/
|
|
5
|
+
// tslint:disable-next-line: variable-name
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export interface Type<T = any> extends Function {
|
|
10
|
+
new (...args: any[]): T;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Type = Function;
|
|
14
|
+
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
global.Type = Type;
|
|
17
|
+
|
|
18
|
+
export interface AbstractType<T> extends Function {
|
|
19
|
+
prototype: T;
|
|
20
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {UnsupportedDecoratorType} from "./UnsupportedDecoratorType.js";
|
|
2
|
+
|
|
3
|
+
class Test {}
|
|
4
|
+
|
|
5
|
+
describe("UnsupportedDecoratorType", () => {
|
|
6
|
+
const createError = (args: any[]) => {
|
|
7
|
+
return new UnsupportedDecoratorType({name: "Decorator"}, args).message;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
it("should return class", () => {
|
|
11
|
+
expect(createError([Test])).toBe("Decorator cannot be used as class decorator on Test");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should return property (static)", () => {
|
|
15
|
+
expect(createError([Test, "props"])).toBe("Decorator cannot be used as property.static decorator on Test.props");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should return property (instance)", () => {
|
|
19
|
+
expect(createError([Test.prototype, "props"])).toBe("Decorator cannot be used as property decorator on Test.props");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should return method (instance, getter)", () => {
|
|
23
|
+
expect(
|
|
24
|
+
createError([
|
|
25
|
+
Test.prototype,
|
|
26
|
+
"props",
|
|
27
|
+
{
|
|
28
|
+
get: () => {}
|
|
29
|
+
}
|
|
30
|
+
])
|
|
31
|
+
).toBe("Decorator cannot be used as property decorator on Test.props");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("should return method (instance, setter)", () => {
|
|
35
|
+
expect(
|
|
36
|
+
createError([
|
|
37
|
+
Test.prototype,
|
|
38
|
+
"props",
|
|
39
|
+
{
|
|
40
|
+
set: () => {}
|
|
41
|
+
}
|
|
42
|
+
])
|
|
43
|
+
).toBe("Decorator cannot be used as property decorator on Test.props");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("should return method (static)", () => {
|
|
47
|
+
expect(
|
|
48
|
+
createError([
|
|
49
|
+
Test,
|
|
50
|
+
"props",
|
|
51
|
+
{
|
|
52
|
+
value: () => {}
|
|
53
|
+
}
|
|
54
|
+
])
|
|
55
|
+
).toBe("Decorator cannot be used as method.static decorator on Test.props");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should return method (instance)", () => {
|
|
59
|
+
expect(
|
|
60
|
+
createError([
|
|
61
|
+
Test.prototype,
|
|
62
|
+
"props",
|
|
63
|
+
{
|
|
64
|
+
value: () => {}
|
|
65
|
+
}
|
|
66
|
+
])
|
|
67
|
+
).toBe("Decorator cannot be used as method decorator on Test.props");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should return params (static)", () => {
|
|
71
|
+
expect(createError([Test, "props", 0])).toBe("Decorator cannot be used as parameter.static decorator on Test.props");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should return params (instance)", () => {
|
|
75
|
+
expect(createError([Test.prototype, "props", 0])).toBe("Decorator cannot be used as parameter decorator on Test.props.[0]");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should return params (constructor)", () => {
|
|
79
|
+
expect(createError([Test.prototype, undefined, 0])).toBe("Decorator cannot be used as parameter.constructor decorator on Test");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {decoratorTypeOf} from "../utils/decorators/decoratorTypeOf.js";
|
|
2
|
+
import {classOf} from "../utils/objects/classOf.js";
|
|
3
|
+
import {nameOf} from "../utils/objects/nameOf.js";
|
|
4
|
+
|
|
5
|
+
export class UnsupportedDecoratorType extends Error {
|
|
6
|
+
name: "UNSUPPORTED_DECORATOR_TYPE";
|
|
7
|
+
|
|
8
|
+
constructor(decorator: any, args: any[]) {
|
|
9
|
+
super(UnsupportedDecoratorType.buildMessage(decorator, args));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
private static buildMessage(decorator: any, args: any[]): string {
|
|
13
|
+
const [target, propertyKey, index] = args;
|
|
14
|
+
|
|
15
|
+
const bindingType = decoratorTypeOf(args);
|
|
16
|
+
const shortBinding = bindingType.split("/")[0];
|
|
17
|
+
const param = shortBinding === "parameter" ? ".[" + index + "]" : "";
|
|
18
|
+
const cstr = shortBinding === "parameter" ? ".constructor" : "";
|
|
19
|
+
const method = propertyKey ? "." + propertyKey : cstr;
|
|
20
|
+
|
|
21
|
+
const path = nameOf(classOf(target)) + method + param;
|
|
22
|
+
|
|
23
|
+
return `${decorator.name} cannot be used as ${bindingType} decorator on ${path}`;
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Automatically generated by @tsed/barrels.
|
|
3
|
+
*/
|
|
4
|
+
export * from "./decorators/storeFn.js";
|
|
5
|
+
export * from "./decorators/storeMerge.js";
|
|
6
|
+
export * from "./decorators/storeSet.js";
|
|
7
|
+
export * from "./domain/AnyToPromise.js";
|
|
8
|
+
export * from "./domain/DecoratorTypes.js";
|
|
9
|
+
export * from "./domain/Env.js";
|
|
10
|
+
export * from "./domain/Metadata.js";
|
|
11
|
+
export * from "./domain/Store.js";
|
|
12
|
+
export * from "./domain/Type.js";
|
|
13
|
+
export * from "./errors/UnsupportedDecoratorType.js";
|
|
14
|
+
export * from "./interfaces/AnyDecorator.js";
|
|
15
|
+
export * from "./interfaces/DecoratorParameters.js";
|
|
16
|
+
export * from "./interfaces/MetadataTypes.js";
|
|
17
|
+
export * from "./interfaces/Relation.js";
|
|
18
|
+
export * from "./interfaces/ValueOf.js";
|
|
19
|
+
export * from "./utils/catchError.js";
|
|
20
|
+
export * from "./utils/decorators/decorateMethodsOf.js";
|
|
21
|
+
export * from "./utils/decorators/decoratorArgs.js";
|
|
22
|
+
export * from "./utils/decorators/decoratorTypeOf.js";
|
|
23
|
+
export * from "./utils/decorators/inheritedDescriptorOf.js";
|
|
24
|
+
export * from "./utils/decorators/useDecorators.js";
|
|
25
|
+
export * from "./utils/decorators/useMethodDecorators.js";
|
|
26
|
+
export * from "./utils/getRandomId.js";
|
|
27
|
+
export * from "./utils/http/getHostInfoFromPort.js";
|
|
28
|
+
export * from "./utils/objects/ancestorOf.js";
|
|
29
|
+
export * from "./utils/objects/ancestorsOf.js";
|
|
30
|
+
export * from "./utils/objects/classOf.js";
|
|
31
|
+
export * from "./utils/objects/cleanObject.js";
|
|
32
|
+
export * from "./utils/objects/constructorOf.js";
|
|
33
|
+
export * from "./utils/objects/createInstance.js";
|
|
34
|
+
export * from "./utils/objects/deepClone.js";
|
|
35
|
+
export * from "./utils/objects/deepMerge.js";
|
|
36
|
+
export * from "./utils/objects/descriptorOf.js";
|
|
37
|
+
export * from "./utils/objects/getClassOrSymbol.js";
|
|
38
|
+
export * from "./utils/objects/getConstructorArgNames.js";
|
|
39
|
+
export * from "./utils/objects/getValue.js";
|
|
40
|
+
export * from "./utils/objects/hasJsonMethod.js";
|
|
41
|
+
export * from "./utils/objects/isArray.js";
|
|
42
|
+
export * from "./utils/objects/isArrowFn.js";
|
|
43
|
+
export * from "./utils/objects/isBoolean.js";
|
|
44
|
+
export * from "./utils/objects/isBuffer.js";
|
|
45
|
+
export * from "./utils/objects/isClass.js";
|
|
46
|
+
export * from "./utils/objects/isCollection.js";
|
|
47
|
+
export * from "./utils/objects/isDate.js";
|
|
48
|
+
export * from "./utils/objects/isEmpty.js";
|
|
49
|
+
export * from "./utils/objects/isEnumerable.js";
|
|
50
|
+
export * from "./utils/objects/isFunction.js";
|
|
51
|
+
export * from "./utils/objects/isInheritedFrom.js";
|
|
52
|
+
export * from "./utils/objects/isMomentObject.js";
|
|
53
|
+
export * from "./utils/objects/isMongooseObject.js";
|
|
54
|
+
export * from "./utils/objects/isNil.js";
|
|
55
|
+
export * from "./utils/objects/isNumber.js";
|
|
56
|
+
export * from "./utils/objects/isObject.js";
|
|
57
|
+
export * from "./utils/objects/isObservable.js";
|
|
58
|
+
export * from "./utils/objects/isPlainObject.js";
|
|
59
|
+
export * from "./utils/objects/isPrimitive.js";
|
|
60
|
+
export * from "./utils/objects/isPromise.js";
|
|
61
|
+
export * from "./utils/objects/isProtectedKey.js";
|
|
62
|
+
export * from "./utils/objects/isRegExp.js";
|
|
63
|
+
export * from "./utils/objects/isSerializable.js";
|
|
64
|
+
export * from "./utils/objects/isStream.js";
|
|
65
|
+
export * from "./utils/objects/isString.js";
|
|
66
|
+
export * from "./utils/objects/isSymbol.js";
|
|
67
|
+
export * from "./utils/objects/methodsOf.js";
|
|
68
|
+
export * from "./utils/objects/nameOf.js";
|
|
69
|
+
export * from "./utils/objects/objectKeys.js";
|
|
70
|
+
export * from "./utils/objects/primitiveOf.js";
|
|
71
|
+
export * from "./utils/objects/prototypeOf.js";
|
|
72
|
+
export * from "./utils/objects/setValue.js";
|
|
73
|
+
export * from "./utils/objects/toMap.js";
|
|
74
|
+
export * from "./utils/objects/toStringConstructor.js";
|
|
75
|
+
export * from "./utils/objects/uniq.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AnyDecorator = any | ClassDecorator | MethodDecorator | PropertyDescriptor | ParameterDecorator;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type DecoratorParameters = [any, string | symbol, number | PropertyDescriptor];
|
|
2
|
+
export type DecoratorMethodParameters = [any, string | symbol, PropertyDescriptor];
|
|
3
|
+
|
|
4
|
+
export type StaticMethodDecorator = <TFunction extends Function, T>(
|
|
5
|
+
target: TFunction,
|
|
6
|
+
propertyKey: string | symbol,
|
|
7
|
+
descriptor: TypedPropertyDescriptor<T>
|
|
8
|
+
) => TypedPropertyDescriptor<T> | void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Relation<T> = T;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ValueOf<T> = T[keyof T];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {catchAsyncError, catchError} from "./catchError.js";
|
|
2
|
+
|
|
3
|
+
describe("catchError", () => {
|
|
4
|
+
it("should catch error", () => {
|
|
5
|
+
expect(
|
|
6
|
+
catchError(() => {
|
|
7
|
+
throw new Error("message");
|
|
8
|
+
})?.message
|
|
9
|
+
).toEqual("message");
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe("catchAsyncError", () => {
|
|
14
|
+
it("should catch error", async () => {
|
|
15
|
+
expect((await catchAsyncError(() => Promise.reject(new Error("message"))))?.message).toEqual("message");
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function catchError<T extends Error>(cb: Function): T | undefined {
|
|
2
|
+
try {
|
|
3
|
+
cb();
|
|
4
|
+
} catch (er) {
|
|
5
|
+
return er;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export async function catchAsyncError<T extends Error>(cb: Function): Promise<T | undefined> {
|
|
10
|
+
try {
|
|
11
|
+
await cb();
|
|
12
|
+
} catch (er) {
|
|
13
|
+
return er;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {StoreMerge} from "../../decorators/storeMerge.js";
|
|
2
|
+
import {StoreSet} from "../../decorators/storeSet.js";
|
|
3
|
+
import {Store} from "../../domain/Store.js";
|
|
4
|
+
import {descriptorOf} from "../objects/descriptorOf.js";
|
|
5
|
+
import {decorateMethodsOf} from "./decorateMethodsOf.js";
|
|
6
|
+
|
|
7
|
+
describe("decorateMethodsOf", () => {
|
|
8
|
+
it("should decorate all methods", () => {
|
|
9
|
+
function decorate() {
|
|
10
|
+
return (target: any) => {
|
|
11
|
+
decorateMethodsOf(target, (klass: any, property: any, descriptor: any) => {
|
|
12
|
+
Store.from(klass, property, descriptor).set("test", property);
|
|
13
|
+
|
|
14
|
+
return descriptor;
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class TestParent {
|
|
20
|
+
test2(a: any) {
|
|
21
|
+
return "test" + a;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// WHEN
|
|
26
|
+
@decorate()
|
|
27
|
+
class Test extends TestParent {
|
|
28
|
+
test() {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// THEN
|
|
32
|
+
const result = Store.from(Test, "test", descriptorOf(Test, "test")).get("test");
|
|
33
|
+
expect(result).toBe("test");
|
|
34
|
+
|
|
35
|
+
const result2 = Store.from(Test, "test2", descriptorOf(Test, "test2")).get("test");
|
|
36
|
+
expect(result2).toBe("test2");
|
|
37
|
+
|
|
38
|
+
expect(new Test().test2("1")).toBe("test1");
|
|
39
|
+
});
|
|
40
|
+
it("should decorate all methods and copy store metadata to the new property", () => {
|
|
41
|
+
function decorate() {
|
|
42
|
+
return (target: any) => {
|
|
43
|
+
decorateMethodsOf(target, (klass: any, property: any, descriptor: any) => {
|
|
44
|
+
Store.from(klass, property, descriptor).set("test", property);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class TestParent {
|
|
50
|
+
@StoreSet("options", {parent: "test", override: "parent"})
|
|
51
|
+
test(a: any) {}
|
|
52
|
+
|
|
53
|
+
@StoreSet("options", {parent: "test2"})
|
|
54
|
+
test2(a: any) {}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// WHEN
|
|
58
|
+
@decorate()
|
|
59
|
+
class Test extends TestParent {
|
|
60
|
+
@StoreMerge("options", {children: "test", override: "child"})
|
|
61
|
+
test() {}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// THEN
|
|
65
|
+
const storeObj2 = Store.fromMethod(Test, "test2").toJson();
|
|
66
|
+
expect(storeObj2).toEqual({
|
|
67
|
+
options: {
|
|
68
|
+
parent: "test2"
|
|
69
|
+
},
|
|
70
|
+
test: "test2"
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const storeObj = Store.fromMethod(Test, "test").toJson();
|
|
74
|
+
// store aren't merged
|
|
75
|
+
expect(storeObj).toEqual({
|
|
76
|
+
options: {
|
|
77
|
+
children: "test",
|
|
78
|
+
override: "child"
|
|
79
|
+
},
|
|
80
|
+
test: "test"
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Store} from "../../domain/Store.js";
|
|
2
|
+
import {classOf} from "../objects/classOf.js";
|
|
3
|
+
import {descriptorOf} from "../objects/descriptorOf.js";
|
|
4
|
+
import {methodsOf} from "../objects/methodsOf.js";
|
|
5
|
+
import {prototypeOf} from "../objects/prototypeOf.js";
|
|
6
|
+
|
|
7
|
+
export function decorateMethodsOf(klass: any, decorator: any) {
|
|
8
|
+
methodsOf(klass).forEach(({target, propertyKey}) => {
|
|
9
|
+
const proto = prototypeOf(klass);
|
|
10
|
+
|
|
11
|
+
if (target !== classOf(klass)) {
|
|
12
|
+
Object.defineProperty(proto, propertyKey, {
|
|
13
|
+
writable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
value(...args: any[]) {
|
|
16
|
+
return prototypeOf(target)[propertyKey].apply(this, args);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Store.mergeStoreMethodFrom(klass, target, propertyKey);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let descriptor = descriptorOf(klass, propertyKey);
|
|
24
|
+
|
|
25
|
+
const newDescriptor = decorator(proto, propertyKey, descriptor) || descriptor;
|
|
26
|
+
|
|
27
|
+
if (newDescriptor) {
|
|
28
|
+
Object.defineProperty(proto, propertyKey, newDescriptor);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {descriptorOf} from "../objects/descriptorOf.js";
|
|
2
|
+
import {prototypeOf} from "../objects/prototypeOf.js";
|
|
3
|
+
import {decoratorArgs} from "./decoratorArgs.js";
|
|
4
|
+
|
|
5
|
+
describe("decoratorArgs", () => {
|
|
6
|
+
it("should return decorator arguments", () => {
|
|
7
|
+
class Test {
|
|
8
|
+
test() {}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const args = decoratorArgs(prototypeOf(Test), "test");
|
|
12
|
+
|
|
13
|
+
expect(args).toEqual([prototypeOf(Test), "test", descriptorOf(Test, "test")]);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import {DecoratorParameters} from "../../interfaces/DecoratorParameters.js";
|
|
2
|
+
import {descriptorOf} from "../objects/descriptorOf.js";
|
|
3
|
+
|
|
4
|
+
export function decoratorArgs(target: any, propertyKey: string): DecoratorParameters {
|
|
5
|
+
return [target, propertyKey, descriptorOf(target, propertyKey)!];
|
|
6
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {decoratorTypeOf} from "./decoratorTypeOf.js";
|
|
2
|
+
|
|
3
|
+
class Test {}
|
|
4
|
+
|
|
5
|
+
describe("decoratorTypeOf()", () => {
|
|
6
|
+
it("should return class", () => {
|
|
7
|
+
expect(decoratorTypeOf([Test])).toBe("class");
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("should return property (static)", () => {
|
|
11
|
+
expect(decoratorTypeOf([Test, "props"])).toBe("property.static");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("should return property (instance)", () => {
|
|
15
|
+
expect(decoratorTypeOf([Test.prototype, "props"])).toBe("property");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should return property (instance with descriptor from babel)", () => {
|
|
19
|
+
expect(
|
|
20
|
+
decoratorTypeOf([
|
|
21
|
+
Test.prototype,
|
|
22
|
+
"props",
|
|
23
|
+
{
|
|
24
|
+
configurable: true,
|
|
25
|
+
enumerable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
initializer: null
|
|
28
|
+
}
|
|
29
|
+
])
|
|
30
|
+
).toBe("property");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should return method (instance, getter)", () => {
|
|
34
|
+
expect(
|
|
35
|
+
decoratorTypeOf([
|
|
36
|
+
Test.prototype,
|
|
37
|
+
"props",
|
|
38
|
+
{
|
|
39
|
+
get: () => {}
|
|
40
|
+
}
|
|
41
|
+
])
|
|
42
|
+
).toBe("property");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should return method (instance, setter)", () => {
|
|
46
|
+
expect(
|
|
47
|
+
decoratorTypeOf([
|
|
48
|
+
Test.prototype,
|
|
49
|
+
"props",
|
|
50
|
+
{
|
|
51
|
+
set: () => {}
|
|
52
|
+
}
|
|
53
|
+
])
|
|
54
|
+
).toBe("property");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("should return method (static)", () => {
|
|
58
|
+
expect(
|
|
59
|
+
decoratorTypeOf([
|
|
60
|
+
Test,
|
|
61
|
+
"props",
|
|
62
|
+
{
|
|
63
|
+
value: () => {}
|
|
64
|
+
}
|
|
65
|
+
])
|
|
66
|
+
).toBe("method.static");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should return method (instance)", () => {
|
|
70
|
+
expect(
|
|
71
|
+
decoratorTypeOf([
|
|
72
|
+
Test.prototype,
|
|
73
|
+
"props",
|
|
74
|
+
{
|
|
75
|
+
value: () => {}
|
|
76
|
+
}
|
|
77
|
+
])
|
|
78
|
+
).toBe("method");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("should return params (static)", () => {
|
|
82
|
+
expect(decoratorTypeOf([Test, "props", 0])).toBe("parameter.static");
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("should return params (instance)", () => {
|
|
86
|
+
expect(decoratorTypeOf([Test.prototype, "props", 0])).toBe("parameter");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("should return params (constructor)", () => {
|
|
90
|
+
expect(decoratorTypeOf([Test.prototype, undefined, 0])).toBe("parameter.constructor");
|
|
91
|
+
});
|
|
92
|
+
});
|