@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,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,6 @@
1
+ import type {Type} from "../domain/Type.js";
2
+
3
+ export interface MetadataTypes<T = any, C = any> {
4
+ type?: Type<T> | T;
5
+ collectionType?: Type<C> | C;
6
+ }
@@ -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
+ });