Skip to content

Commit c0cd01a

Browse files
authored
feat: adds new decorators following the typescript v5 standard + updates to TypeScript v5 (#3951)
Signed-off-by: Simeon Nakov <simeon.nakov@limechain.tech>
1 parent b6cf64c commit c0cd01a

File tree

12 files changed

+89
-92
lines changed

12 files changed

+89
-92
lines changed

package-lock.json

Lines changed: 17 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"prettier": "^3.0.3",
3636
"replace": "^1.2.2",
3737
"ts-node": "^10.9.2",
38-
"typescript": "^4.6.3"
38+
"typescript": "^5.8.3"
3939
},
4040
"workspaces": {
4141
"packages": [

packages/config-service/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@
2222
"devDependencies": {
2323
"chai": "^4.3.6",
2424
"ts-mocha": "^9.0.2",
25-
"typescript": "^4.6.4"
25+
"typescript": "^5.8.3"
2626
}
2727
}

packages/relay/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"redis-memory-server": "^0.12.1",
1919
"sinon": "^14.0.0",
2020
"ts-mocha": "^9.0.2",
21-
"typescript": "^4.6.4"
21+
"typescript": "^5.8.3"
2222
},
2323
"scripts": {
2424
"build": "pnpm run clean && pnpm run compile",

packages/relay/src/lib/decorators/cache.decorator.ts

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,55 @@ interface CacheOptions {
2727
}
2828

2929
/**
30-
* Iterates through the provided 'params' array and checks if any argument in 'args' at the specified 'index'
31-
* matches one of the pipe-separated values in 'value'. If a match is found, caching should be skipped.
30+
* Uses a `CacheService` to attempt to retrieve a cached result before executing the original method. If
31+
* no cached response exists, the method is executed and its result may be stored in the cache depending on configurable
32+
* options. Caching can be conditionally skipped based on runtime arguments via `skipParams` (for positional args)
33+
* and `skipNamedParams` (for object args).
34+
*
35+
* @param cacheService - The caching service used to store and retrieve cache entries.
36+
* @param options - Optional configuration for caching behavior.
37+
* @property skipParams - An array of rules for skipping caching based on specific argument values.
38+
* @property skipNamedParams - An array of rules for skipping caching based on fields within argument objects.
39+
* @property ttl - Optional time-to-live for the cache entry; falls back to global config if not provided.
40+
*
41+
* @returns A method decorator function that wraps the original method with caching logic.
42+
*
43+
* @example
44+
* @cache(CacheService, { skipParams: [...], skipNamesParams: [...], ttl: 300 })
45+
*/
46+
export function cache(cacheService: CacheService, options: CacheOptions = {}) {
47+
return function (target: any, context: ClassMethodDecoratorContext) {
48+
const methodName = String(context.name);
49+
50+
return async function (this: any, ...args: unknown[]) {
51+
const requestDetails = extractRequestDetails(args);
52+
const cacheKey = generateCacheKey(methodName, args);
53+
54+
const cachedResponse = await cacheService.getAsync(cacheKey, methodName, requestDetails);
55+
if (cachedResponse) return cachedResponse;
56+
57+
const result = await target.apply(this, args);
58+
if (
59+
result &&
60+
!shouldSkipCachingForSingleParams(args, options.skipParams) &&
61+
!shouldSkipCachingForNamedParams(args, options.skipNamedParams)
62+
) {
63+
await cacheService.set(
64+
cacheKey,
65+
result,
66+
methodName,
67+
requestDetails,
68+
options.ttl ?? ConfigService.get('CACHE_TTL'),
69+
);
70+
}
71+
return result;
72+
};
73+
};
74+
}
75+
76+
/**
77+
* This is a predicate function that takes a list of arguments and parameters,
78+
* and it checks whether the given function should skip caching based on specific positional argument values.
3279
*
3380
* @param args - The arguments passed to the method in an array
3481
* @param params - An array of CacheSingleParam caching rules
@@ -151,56 +198,6 @@ const extractRequestDetails = (args: unknown[]): RequestDetails => {
151198
return new RequestDetails({ requestId: '', ipAddress: '' });
152199
};
153200

154-
/**
155-
* This decorator uses a `CacheService` to attempt to retrieve a cached result before executing the original method. If
156-
* no cached response exists, the method is executed and its result may be stored in the cache depending on configurable
157-
* options. Caching can be conditionally skipped based on runtime arguments via `skipParams` (for positional args)
158-
* and `skipNamedParams` (for object args).
159-
*
160-
* @param cacheService - The caching service used to store and retrieve cache entries.
161-
* @param options - Optional configuration for caching behavior.
162-
* @property skipParams - An array of rules for skipping caching based on specific argument values.
163-
* @property skipNamedParams - An array of rules for skipping caching based on fields within argument objects.
164-
* @property ttl - Optional time-to-live for the cache entry; falls back to global config if not provided.
165-
*
166-
* @returns A method decorator function that wraps the original method with caching logic.
167-
*
168-
* @example
169-
* @cache(CacheService, { skipParams: [...], skipNamesParams: [...], ttl: 300 })
170-
*/
171-
export function cache(cacheService: CacheService, options: CacheOptions = {}) {
172-
return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
173-
const method = descriptor.value;
174-
175-
descriptor.value = async function (...args: unknown[]) {
176-
const requestDetails = extractRequestDetails(args);
177-
const cacheKey = generateCacheKey(method.name, args);
178-
179-
const cachedResponse = await cacheService.getAsync(cacheKey, method, requestDetails);
180-
if (cachedResponse) {
181-
return cachedResponse;
182-
}
183-
184-
const result = await method.apply(this, args);
185-
if (
186-
result &&
187-
!shouldSkipCachingForSingleParams(args, options?.skipParams) &&
188-
!shouldSkipCachingForNamedParams(args, options?.skipNamedParams)
189-
) {
190-
await cacheService.set(
191-
cacheKey,
192-
result,
193-
method,
194-
requestDetails,
195-
options?.ttl ?? ConfigService.get('CACHE_TTL'),
196-
);
197-
}
198-
199-
return result;
200-
};
201-
};
202-
}
203-
204201
// export private methods under __test__ "namespace" but using const
205202
// due to `ES2015 module syntax is preferred over namespaces` eslint warning
206203
export const __test__ = {

packages/relay/src/lib/decorators/rpcMethod.decorator.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ export const RPC_METHOD_KEY = 'hedera-rpc-method';
2020
* }
2121
* ```
2222
*
23-
* @param _target - The prototype of the class (ignored in this implementation)
24-
* @param _propertyKey - The name of the method being decorated (ignored in this implementation)
25-
* @param descriptor - The property descriptor for the method
26-
* @returns The same property descriptor, allowing for decorator composition
23+
* @param target - The method function
24+
* @param context - The decorator context
25+
* @returns The method function with RPC metadata attached
2726
*/
28-
export function rpcMethod(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
29-
descriptor.value[RPC_METHOD_KEY] = true;
30-
return descriptor;
27+
export function rpcMethod(target: any, _context: ClassMethodDecoratorContext): any {
28+
target[RPC_METHOD_KEY] = true;
29+
30+
return target;
3131
}

packages/relay/src/lib/decorators/rpcParamLayoutConfig.decorator.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ export const RPC_LAYOUT = {
3636
* ```typescript
3737
* // Method that only needs requestDetails
3838
* @rpcMethod
39-
* @rpcParamSpecialLayout(RPC_LAYOUT.REQUEST_DETAILS_ONLY)
39+
* @rpcParamLayoutConfig(RPC_LAYOUT.REQUEST_DETAILS_ONLY)
4040
* blockNumber(requestDetails: RequestDetails): Promise<string> {
4141
* // Implementation
4242
* }
4343
*
4444
* // Method with specific parameter transformations
4545
* @rpcMethod
46-
* @rpcParamSpecialLayout(RPC_LAYOUT.custom(params => [params[0], params[1]]))
46+
* @rpcParamLayoutConfig(RPC_LAYOUT.custom(params => [params[0], params[1]]))
4747
* estimateGas(transaction: IContractCallRequest, _blockParam: string | null, requestDetails: RequestDetails,): Promise<string | JsonRpcError> {
4848
* // Implementation
4949
* }
@@ -52,8 +52,8 @@ export const RPC_LAYOUT = {
5252
* @param layout - Parameter layout specification
5353
*/
5454
export function rpcParamLayoutConfig(layout: string | ParamTransformFn) {
55-
return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
56-
descriptor.value[RPC_PARAM_LAYOUT_KEY] = layout;
57-
return descriptor;
55+
return function (target: any, _context: ClassMethodDecoratorContext): any {
56+
target[RPC_PARAM_LAYOUT_KEY] = layout;
57+
return target;
5858
};
5959
}

packages/relay/src/lib/validators/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ export const RPC_PARAM_VALIDATION_RULES_KEY = 'hedera-rpc-param-validation-rules
4949
* @returns Method decorator function
5050
*/
5151
export function rpcParamValidationRules(validationRules: Record<number, IParamValidation>) {
52-
return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
52+
return function (target: any, _context: ClassMethodDecoratorContext): any {
5353
// Store validation rules directly on the function as a property
54-
descriptor.value[RPC_PARAM_VALIDATION_RULES_KEY] = validationRules;
55-
return descriptor;
54+
target[RPC_PARAM_VALIDATION_RULES_KEY] = validationRules;
55+
56+
return target;
5657
};
5758
}
5859

packages/relay/tests/lib/decorators/rpcParamSchema.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,8 @@ describe('rpcParamValidationRules decorator', () => {
153153

154154
describe('Multiple decorators interaction', () => {
155155
it('should work alongside other decorators', () => {
156-
const mockDecorator = (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) => {
157-
descriptor.value.MOCK_KEY = 'mock-value';
158-
return descriptor;
156+
const mockDecorator = (target: any, _context: ClassMethodDecoratorContext): void => {
157+
target.MOCK_KEY = 'mock-value';
159158
};
160159

161160
class TestMultiDecoratorClass {

packages/relay/tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
"declaration": true,
1515
"strict": true,
1616
"sourceMap": true,
17-
"experimentalDecorators": true,
1817
"skipLibCheck": true
1918
},
2019
"include": ["src"]

0 commit comments

Comments
 (0)