-
Notifications
You must be signed in to change notification settings - Fork 0
/
metadata.ts
93 lines (85 loc) · 2.31 KB
/
metadata.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
export class Metadata {
#metadata: Map<
unknown,
Map<symbol | string, Map<symbol | number | string, unknown>>
> = new Map();
public debug(): void {
console.log(...this.#metadata.entries());
}
/**
* Stores metadata for the specified {@link type}.
*
* @deprecated replaced by {@link Metadata.set}
* @param type Any class type metadata should get set on
* @param key Metadata key
* @param value Metadata value
*/
public defineMetadata(
type: unknown,
key: symbol | number | string,
value: unknown,
): void {
this.set(key, value, type);
}
/**
* Retrieves metadata for specified {@link type}
*
* @deprecated replaced by {@link Metadata.get}
* @param type Any class type metadata should get set on
* @param key Metadata key
* @returns Metadata value if exists, else undefined
*/
public getMetadata<T>(
type: unknown,
key: symbol | number | string,
): T | undefined {
return this.get(key, type);
}
//TODO(@DreamTexX): Add tests
public set(
key: symbol | number | string,
value: unknown,
type: unknown,
): void;
public set(
key: symbol | number | string,
value: unknown,
type: unknown,
propertyKey: symbol | string,
): void;
public set(
key: symbol | number | string,
value: unknown,
type: unknown,
propertyKey: symbol | string = 'prototype',
): void {
if (!this.#metadata.has(type)) {
this.#metadata.set(type, new Map());
}
const metaForType = this.#metadata.get(type)!;
if (!metaForType.has(propertyKey)) {
metaForType.set(propertyKey, new Map());
}
const metaForPropertyKey = metaForType.get(propertyKey)!;
metaForPropertyKey.set(key, value);
}
//TODO(@DreamTexX): Add tests
public get<T>(key: symbol | number | string, type: unknown): T | undefined;
public get<T>(
key: symbol | number | string,
type: unknown,
propertyKey: symbol | string,
): T | undefined;
public get<T>(
key: symbol | number | string,
type: unknown,
propertyKey: symbol | string = 'prototype',
): T | undefined {
return this.#metadata.get(type)?.get(propertyKey)?.get(key) as T;
}
public clear(): void {
this.#metadata.clear();
}
}
export const StaticMetadata = new Metadata();
// Add Reflect Metadata Polyfill for automatic type detection