Skip to content

Commit 28badda

Browse files
feat(core) add more utility reflector methods
1 parent cfaa4d4 commit 28badda

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

packages/core/services/reflector.service.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Type } from '@nestjs/common';
2+
import { isObject } from '@nestjs/common/utils/shared.utils';
23

34
/**
45
* Helper class providing Nest reflection capabilities.
@@ -32,12 +33,55 @@ export class Reflector {
3233
* @param targets context (decorated objects) to retrieve metadata from
3334
*
3435
*/
35-
public getAll<TResult extends any[] = any, TKey = any>(
36+
public getAll<TResult extends any[] = any[], TKey = any>(
3637
metadataKey: TKey,
3738
targets: (Type<any> | Function)[],
3839
): TResult {
3940
return (targets || []).map(target =>
4041
Reflect.getMetadata(metadataKey, target),
4142
) as TResult;
4243
}
44+
45+
/**
46+
* Retrieve metadata for a specified key for a specified set of targets and concat results.
47+
*
48+
* @param metadataKey lookup key for metadata to retrieve
49+
* @param targets context (decorated objects) to retrieve metadata from
50+
*
51+
*/
52+
public getAllAndConcat<TResult extends any[] = any[], TKey = any>(
53+
metadataKey: TKey,
54+
targets: (Type<any> | Function)[],
55+
): TResult {
56+
const metadataCollection = this.getAll(metadataKey, targets);
57+
return metadataCollection.reduce((a, b) => {
58+
if (Array.isArray(a)) {
59+
return a.concat(b);
60+
}
61+
if (isObject(a) && isObject(b)) {
62+
return {
63+
...a,
64+
...b,
65+
};
66+
}
67+
return b;
68+
});
69+
}
70+
71+
/**
72+
* Retrieve metadata for a specified key for a specified set of targets and return a first not undefined value.
73+
*
74+
* @param metadataKey lookup key for metadata to retrieve
75+
* @param targets context (decorated objects) to retrieve metadata from
76+
*
77+
*/
78+
public getAllAndOverride<TResult = any, TKey = any>(
79+
metadataKey: TKey,
80+
targets: (Type<any> | Function)[],
81+
): TResult {
82+
const metadataCollection = this.getAll(metadataKey, targets).filter(
83+
item => item !== undefined,
84+
);
85+
return metadataCollection[0];
86+
}
4387
}

packages/core/test/services/reflector.service.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ describe('Reflector', () => {
1515
expect(reflector.get(key, Test)).to.eql(value);
1616
});
1717
});
18+
1819
describe('getAll', () => {
1920
it('should reflect metadata of all targets', () => {
2021
const key = 'key';
@@ -23,4 +24,25 @@ describe('Reflector', () => {
2324
expect(reflector.getAll(key, [Test])).to.eql([value]);
2425
});
2526
});
27+
28+
describe('getAllAndConcat', () => {
29+
it('should reflect metadata of all targets and concat arrays', () => {
30+
const key = 'key';
31+
const value = 'value';
32+
Reflect.defineMetadata(key, value, Test);
33+
expect(reflector.getAllAndConcat(key, [Test, Test])).to.eql([
34+
value,
35+
value,
36+
]);
37+
});
38+
});
39+
40+
describe('getAllAndOverride', () => {
41+
it('should reflect metadata of all targets and return a first not undefined value', () => {
42+
const key = 'key';
43+
const value = 'value';
44+
Reflect.defineMetadata(key, value, Test);
45+
expect(reflector.getAllAndOverride(key, [Test, Test])).to.eql(value);
46+
});
47+
});
2648
});

0 commit comments

Comments
 (0)