@carno.js/core 1.1.1 → 1.1.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.
- package/LICENSE +21 -21
- package/README.md +188 -188
- package/dist/Carno.js +46 -26
- package/dist/Carno.mjs +46 -26
- package/dist/bun/index.js +4 -4
- package/dist/bun/index.js.map +29 -29
- package/package.json +2 -2
- package/src/Carno.ts +718 -673
- package/src/DefaultRoutes.ts +34 -34
- package/src/cache/CacheDriver.ts +50 -50
- package/src/cache/CacheService.ts +139 -139
- package/src/cache/MemoryDriver.ts +104 -104
- package/src/cache/RedisDriver.ts +116 -116
- package/src/compiler/JITCompiler.ts +167 -167
- package/src/container/Container.ts +168 -168
- package/src/context/Context.ts +130 -130
- package/src/cors/CorsHandler.ts +145 -145
- package/src/decorators/Controller.ts +63 -63
- package/src/decorators/Inject.ts +16 -16
- package/src/decorators/Middleware.ts +22 -22
- package/src/decorators/Service.ts +18 -18
- package/src/decorators/methods.ts +58 -58
- package/src/decorators/params.ts +47 -47
- package/src/events/Lifecycle.ts +97 -97
- package/src/exceptions/HttpException.ts +99 -99
- package/src/index.ts +95 -95
- package/src/metadata.ts +46 -46
- package/src/middleware/CarnoMiddleware.ts +14 -14
- package/src/router/RadixRouter.ts +225 -225
- package/src/testing/TestHarness.ts +185 -185
- package/src/utils/Metadata.ts +43 -43
- package/src/utils/parseQuery.ts +161 -161
- package/src/validation/ValibotAdapter.ts +95 -95
- package/src/validation/ValidatorAdapter.ts +69 -69
- package/src/validation/ZodAdapter.ts +102 -102
- package/dist/Carno.d.js +0 -14
- package/dist/Carno.d.mjs +0 -1
- package/dist/DefaultRoutes.d.js +0 -13
- package/dist/DefaultRoutes.d.mjs +0 -0
- package/dist/cache/CacheDriver.d.js +0 -13
- package/dist/cache/CacheDriver.d.mjs +0 -0
- package/dist/cache/CacheService.d.js +0 -13
- package/dist/cache/CacheService.d.mjs +0 -0
- package/dist/cache/MemoryDriver.d.js +0 -13
- package/dist/cache/MemoryDriver.d.mjs +0 -0
- package/dist/cache/RedisDriver.d.js +0 -13
- package/dist/cache/RedisDriver.d.mjs +0 -0
- package/dist/compiler/JITCompiler.d.js +0 -13
- package/dist/compiler/JITCompiler.d.mjs +0 -0
- package/dist/container/Container.d.js +0 -13
- package/dist/container/Container.d.mjs +0 -0
- package/dist/context/Context.d.js +0 -13
- package/dist/context/Context.d.mjs +0 -0
- package/dist/cors/CorsHandler.d.js +0 -13
- package/dist/cors/CorsHandler.d.mjs +0 -0
- package/dist/decorators/Controller.d.js +0 -13
- package/dist/decorators/Controller.d.mjs +0 -0
- package/dist/decorators/Inject.d.js +0 -13
- package/dist/decorators/Inject.d.mjs +0 -0
- package/dist/decorators/Middleware.d.js +0 -13
- package/dist/decorators/Middleware.d.mjs +0 -0
- package/dist/decorators/Service.d.js +0 -13
- package/dist/decorators/Service.d.mjs +0 -0
- package/dist/decorators/methods.d.js +0 -13
- package/dist/decorators/methods.d.mjs +0 -0
- package/dist/decorators/params.d.js +0 -13
- package/dist/decorators/params.d.mjs +0 -0
- package/dist/events/Lifecycle.d.js +0 -13
- package/dist/events/Lifecycle.d.mjs +0 -0
- package/dist/exceptions/HttpException.d.js +0 -13
- package/dist/exceptions/HttpException.d.mjs +0 -0
- package/dist/index.d.js +0 -130
- package/dist/index.d.mjs +0 -78
- package/dist/metadata.d.js +0 -13
- package/dist/metadata.d.mjs +0 -0
- package/dist/middleware/CarnoMiddleware.d.js +0 -13
- package/dist/middleware/CarnoMiddleware.d.mjs +0 -0
- package/dist/router/RadixRouter.d.js +0 -13
- package/dist/router/RadixRouter.d.mjs +0 -0
- package/dist/testing/TestHarness.d.js +0 -13
- package/dist/testing/TestHarness.d.mjs +0 -0
- package/dist/utils/Metadata.d.js +0 -13
- package/dist/utils/Metadata.d.mjs +0 -0
- package/dist/utils/parseQuery.d.js +0 -13
- package/dist/utils/parseQuery.d.mjs +0 -0
- package/dist/validation/ValibotAdapter.d.js +0 -13
- package/dist/validation/ValibotAdapter.d.mjs +0 -0
- package/dist/validation/ValidatorAdapter.d.js +0 -13
- package/dist/validation/ValidatorAdapter.d.mjs +0 -0
- package/dist/validation/ZodAdapter.d.js +0 -13
- package/dist/validation/ZodAdapter.d.mjs +0 -0
- package/src/Carno.d.ts +0 -135
- package/src/DefaultRoutes.d.ts +0 -19
- package/src/cache/CacheDriver.d.ts +0 -43
- package/src/cache/CacheService.d.ts +0 -89
- package/src/cache/MemoryDriver.d.ts +0 -32
- package/src/cache/RedisDriver.d.ts +0 -34
- package/src/compiler/JITCompiler.d.ts +0 -36
- package/src/container/Container.d.ts +0 -38
- package/src/context/Context.d.ts +0 -36
- package/src/cors/CorsHandler.d.ts +0 -47
- package/src/decorators/Controller.d.ts +0 -13
- package/src/decorators/Inject.d.ts +0 -6
- package/src/decorators/Middleware.d.ts +0 -5
- package/src/decorators/Service.d.ts +0 -9
- package/src/decorators/methods.d.ts +0 -7
- package/src/decorators/params.d.ts +0 -13
- package/src/events/Lifecycle.d.ts +0 -54
- package/src/exceptions/HttpException.d.ts +0 -43
- package/src/index.d.ts +0 -42
- package/src/metadata.d.ts +0 -41
- package/src/middleware/CarnoMiddleware.d.ts +0 -12
- package/src/router/RadixRouter.d.ts +0 -19
- package/src/testing/TestHarness.d.ts +0 -71
- package/src/utils/Metadata.d.ts +0 -20
- package/src/utils/parseQuery.d.ts +0 -23
- package/src/validation/ValibotAdapter.d.ts +0 -30
- package/src/validation/ValidatorAdapter.d.ts +0 -54
- package/src/validation/ZodAdapter.d.ts +0 -35
|
@@ -1,185 +1,185 @@
|
|
|
1
|
-
import type { Server } from 'bun';
|
|
2
|
-
import { Carno, type CarnoConfig } from '../Carno';
|
|
3
|
-
import { Container, type Token } from '../container/Container';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Test configuration options.
|
|
7
|
-
*/
|
|
8
|
-
export interface TestOptions {
|
|
9
|
-
config?: CarnoConfig;
|
|
10
|
-
listen?: boolean | number;
|
|
11
|
-
port?: number;
|
|
12
|
-
controllers?: (new (...args: any[]) => any)[];
|
|
13
|
-
services?: (Token | any)[];
|
|
14
|
-
plugins?: Carno[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Test harness - provides utilities for testing Carno applications.
|
|
19
|
-
*/
|
|
20
|
-
export interface TestHarness {
|
|
21
|
-
/** The Carno app instance */
|
|
22
|
-
app: Carno;
|
|
23
|
-
|
|
24
|
-
/** The internal DI container */
|
|
25
|
-
container: Container;
|
|
26
|
-
|
|
27
|
-
/** The HTTP server (if listening) */
|
|
28
|
-
server?: Server<any>;
|
|
29
|
-
|
|
30
|
-
/** The port the server is running on */
|
|
31
|
-
port?: number;
|
|
32
|
-
|
|
33
|
-
/** Resolve a service from the container */
|
|
34
|
-
resolve<T>(token: Token<T>): T;
|
|
35
|
-
|
|
36
|
-
/** Make an HTTP request to the app */
|
|
37
|
-
request(path: string, init?: RequestInit): Promise<Response>;
|
|
38
|
-
|
|
39
|
-
/** Make a GET request */
|
|
40
|
-
get(path: string, init?: Omit<RequestInit, 'method'>): Promise<Response>;
|
|
41
|
-
|
|
42
|
-
/** Make a POST request */
|
|
43
|
-
post(path: string, body?: any, init?: Omit<RequestInit, 'method' | 'body'>): Promise<Response>;
|
|
44
|
-
|
|
45
|
-
/** Make a PUT request */
|
|
46
|
-
put(path: string, body?: any, init?: Omit<RequestInit, 'method' | 'body'>): Promise<Response>;
|
|
47
|
-
|
|
48
|
-
/** Make a DELETE request */
|
|
49
|
-
delete(path: string, init?: Omit<RequestInit, 'method'>): Promise<Response>;
|
|
50
|
-
|
|
51
|
-
/** Close the test harness and cleanup */
|
|
52
|
-
close(): Promise<void>;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Create a test harness for Turbo applications.
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```typescript
|
|
60
|
-
* const harness = await createTestHarness({
|
|
61
|
-
* controllers: [UserController],
|
|
62
|
-
* services: [UserService],
|
|
63
|
-
* listen: true
|
|
64
|
-
* });
|
|
65
|
-
*
|
|
66
|
-
* const response = await harness.get('/users');
|
|
67
|
-
* expect(response.status).toBe(200);
|
|
68
|
-
*
|
|
69
|
-
* await harness.close();
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
export async function createTestHarness(options: TestOptions = {}): Promise<TestHarness> {
|
|
73
|
-
const config: CarnoConfig = {
|
|
74
|
-
...options.config,
|
|
75
|
-
disableStartupLog: true
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const app = new Carno(config);
|
|
79
|
-
|
|
80
|
-
// Register plugins
|
|
81
|
-
if (options.plugins) {
|
|
82
|
-
for (const plugin of options.plugins) {
|
|
83
|
-
app.use(plugin);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Register controllers
|
|
88
|
-
if (options.controllers) {
|
|
89
|
-
app.controllers(options.controllers);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Register services
|
|
93
|
-
if (options.services) {
|
|
94
|
-
app.services(options.services);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const port = resolvePort(options);
|
|
98
|
-
let server: Server<any> | undefined;
|
|
99
|
-
|
|
100
|
-
if (shouldListen(options.listen)) {
|
|
101
|
-
app.listen(port);
|
|
102
|
-
server = (app as any).server;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const actualPort = server?.port ?? port;
|
|
106
|
-
const container = (app as any).container as Container;
|
|
107
|
-
|
|
108
|
-
// Pre-bind methods for performance
|
|
109
|
-
const baseUrl = `http://127.0.0.1:${actualPort}`;
|
|
110
|
-
|
|
111
|
-
const request = async (path: string, init?: RequestInit): Promise<Response> => {
|
|
112
|
-
if (!server) {
|
|
113
|
-
throw new Error('Server not running. Set listen: true in options.');
|
|
114
|
-
}
|
|
115
|
-
const url = path.startsWith('http') ? path : `${baseUrl}${path.startsWith('/') ? path : '/' + path}`;
|
|
116
|
-
return fetch(url, init);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
return {
|
|
120
|
-
app,
|
|
121
|
-
container,
|
|
122
|
-
server,
|
|
123
|
-
port: actualPort,
|
|
124
|
-
|
|
125
|
-
resolve: <T>(token: Token<T>): T => container.get(token),
|
|
126
|
-
|
|
127
|
-
request,
|
|
128
|
-
|
|
129
|
-
get: (path, init) => request(path, { ...init, method: 'GET' }),
|
|
130
|
-
|
|
131
|
-
post: (path, body, init) => request(path, {
|
|
132
|
-
...init,
|
|
133
|
-
method: 'POST',
|
|
134
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
135
|
-
headers: { 'Content-Type': 'application/json', ...init?.headers }
|
|
136
|
-
}),
|
|
137
|
-
|
|
138
|
-
put: (path, body, init) => request(path, {
|
|
139
|
-
...init,
|
|
140
|
-
method: 'PUT',
|
|
141
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
142
|
-
headers: { 'Content-Type': 'application/json', ...init?.headers }
|
|
143
|
-
}),
|
|
144
|
-
|
|
145
|
-
delete: (path, init) => request(path, { ...init, method: 'DELETE' }),
|
|
146
|
-
|
|
147
|
-
close: async () => {
|
|
148
|
-
app.stop();
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Run a test routine with automatic harness cleanup.
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* await withTestApp(async (harness) => {
|
|
159
|
-
* const response = await harness.get('/health');
|
|
160
|
-
* expect(response.status).toBe(200);
|
|
161
|
-
* }, { controllers: [HealthController], listen: true });
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
export async function withTestApp(
|
|
165
|
-
routine: (harness: TestHarness) => Promise<void>,
|
|
166
|
-
options: TestOptions = {}
|
|
167
|
-
): Promise<void> {
|
|
168
|
-
const harness = await createTestHarness(options);
|
|
169
|
-
|
|
170
|
-
try {
|
|
171
|
-
await routine(harness);
|
|
172
|
-
} finally {
|
|
173
|
-
await harness.close();
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function shouldListen(value: TestOptions['listen']): boolean {
|
|
178
|
-
return typeof value === 'number' || Boolean(value);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function resolvePort(options: TestOptions): number {
|
|
182
|
-
if (typeof options.listen === 'number') return options.listen;
|
|
183
|
-
if (typeof options.port === 'number') return options.port;
|
|
184
|
-
return 0; // Random port
|
|
185
|
-
}
|
|
1
|
+
import type { Server } from 'bun';
|
|
2
|
+
import { Carno, type CarnoConfig } from '../Carno';
|
|
3
|
+
import { Container, type Token } from '../container/Container';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Test configuration options.
|
|
7
|
+
*/
|
|
8
|
+
export interface TestOptions {
|
|
9
|
+
config?: CarnoConfig;
|
|
10
|
+
listen?: boolean | number;
|
|
11
|
+
port?: number;
|
|
12
|
+
controllers?: (new (...args: any[]) => any)[];
|
|
13
|
+
services?: (Token | any)[];
|
|
14
|
+
plugins?: Carno[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Test harness - provides utilities for testing Carno applications.
|
|
19
|
+
*/
|
|
20
|
+
export interface TestHarness {
|
|
21
|
+
/** The Carno app instance */
|
|
22
|
+
app: Carno;
|
|
23
|
+
|
|
24
|
+
/** The internal DI container */
|
|
25
|
+
container: Container;
|
|
26
|
+
|
|
27
|
+
/** The HTTP server (if listening) */
|
|
28
|
+
server?: Server<any>;
|
|
29
|
+
|
|
30
|
+
/** The port the server is running on */
|
|
31
|
+
port?: number;
|
|
32
|
+
|
|
33
|
+
/** Resolve a service from the container */
|
|
34
|
+
resolve<T>(token: Token<T>): T;
|
|
35
|
+
|
|
36
|
+
/** Make an HTTP request to the app */
|
|
37
|
+
request(path: string, init?: RequestInit): Promise<Response>;
|
|
38
|
+
|
|
39
|
+
/** Make a GET request */
|
|
40
|
+
get(path: string, init?: Omit<RequestInit, 'method'>): Promise<Response>;
|
|
41
|
+
|
|
42
|
+
/** Make a POST request */
|
|
43
|
+
post(path: string, body?: any, init?: Omit<RequestInit, 'method' | 'body'>): Promise<Response>;
|
|
44
|
+
|
|
45
|
+
/** Make a PUT request */
|
|
46
|
+
put(path: string, body?: any, init?: Omit<RequestInit, 'method' | 'body'>): Promise<Response>;
|
|
47
|
+
|
|
48
|
+
/** Make a DELETE request */
|
|
49
|
+
delete(path: string, init?: Omit<RequestInit, 'method'>): Promise<Response>;
|
|
50
|
+
|
|
51
|
+
/** Close the test harness and cleanup */
|
|
52
|
+
close(): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Create a test harness for Turbo applications.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* const harness = await createTestHarness({
|
|
61
|
+
* controllers: [UserController],
|
|
62
|
+
* services: [UserService],
|
|
63
|
+
* listen: true
|
|
64
|
+
* });
|
|
65
|
+
*
|
|
66
|
+
* const response = await harness.get('/users');
|
|
67
|
+
* expect(response.status).toBe(200);
|
|
68
|
+
*
|
|
69
|
+
* await harness.close();
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export async function createTestHarness(options: TestOptions = {}): Promise<TestHarness> {
|
|
73
|
+
const config: CarnoConfig = {
|
|
74
|
+
...options.config,
|
|
75
|
+
disableStartupLog: true
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const app = new Carno(config);
|
|
79
|
+
|
|
80
|
+
// Register plugins
|
|
81
|
+
if (options.plugins) {
|
|
82
|
+
for (const plugin of options.plugins) {
|
|
83
|
+
app.use(plugin);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Register controllers
|
|
88
|
+
if (options.controllers) {
|
|
89
|
+
app.controllers(options.controllers);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Register services
|
|
93
|
+
if (options.services) {
|
|
94
|
+
app.services(options.services);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const port = resolvePort(options);
|
|
98
|
+
let server: Server<any> | undefined;
|
|
99
|
+
|
|
100
|
+
if (shouldListen(options.listen)) {
|
|
101
|
+
app.listen(port);
|
|
102
|
+
server = (app as any).server;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const actualPort = server?.port ?? port;
|
|
106
|
+
const container = (app as any).container as Container;
|
|
107
|
+
|
|
108
|
+
// Pre-bind methods for performance
|
|
109
|
+
const baseUrl = `http://127.0.0.1:${actualPort}`;
|
|
110
|
+
|
|
111
|
+
const request = async (path: string, init?: RequestInit): Promise<Response> => {
|
|
112
|
+
if (!server) {
|
|
113
|
+
throw new Error('Server not running. Set listen: true in options.');
|
|
114
|
+
}
|
|
115
|
+
const url = path.startsWith('http') ? path : `${baseUrl}${path.startsWith('/') ? path : '/' + path}`;
|
|
116
|
+
return fetch(url, init);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
app,
|
|
121
|
+
container,
|
|
122
|
+
server,
|
|
123
|
+
port: actualPort,
|
|
124
|
+
|
|
125
|
+
resolve: <T>(token: Token<T>): T => container.get(token),
|
|
126
|
+
|
|
127
|
+
request,
|
|
128
|
+
|
|
129
|
+
get: (path, init) => request(path, { ...init, method: 'GET' }),
|
|
130
|
+
|
|
131
|
+
post: (path, body, init) => request(path, {
|
|
132
|
+
...init,
|
|
133
|
+
method: 'POST',
|
|
134
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
135
|
+
headers: { 'Content-Type': 'application/json', ...init?.headers }
|
|
136
|
+
}),
|
|
137
|
+
|
|
138
|
+
put: (path, body, init) => request(path, {
|
|
139
|
+
...init,
|
|
140
|
+
method: 'PUT',
|
|
141
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
142
|
+
headers: { 'Content-Type': 'application/json', ...init?.headers }
|
|
143
|
+
}),
|
|
144
|
+
|
|
145
|
+
delete: (path, init) => request(path, { ...init, method: 'DELETE' }),
|
|
146
|
+
|
|
147
|
+
close: async () => {
|
|
148
|
+
app.stop();
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Run a test routine with automatic harness cleanup.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* await withTestApp(async (harness) => {
|
|
159
|
+
* const response = await harness.get('/health');
|
|
160
|
+
* expect(response.status).toBe(200);
|
|
161
|
+
* }, { controllers: [HealthController], listen: true });
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export async function withTestApp(
|
|
165
|
+
routine: (harness: TestHarness) => Promise<void>,
|
|
166
|
+
options: TestOptions = {}
|
|
167
|
+
): Promise<void> {
|
|
168
|
+
const harness = await createTestHarness(options);
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
await routine(harness);
|
|
172
|
+
} finally {
|
|
173
|
+
await harness.close();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function shouldListen(value: TestOptions['listen']): boolean {
|
|
178
|
+
return typeof value === 'number' || Boolean(value);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function resolvePort(options: TestOptions): number {
|
|
182
|
+
if (typeof options.listen === 'number') return options.listen;
|
|
183
|
+
if (typeof options.port === 'number') return options.port;
|
|
184
|
+
return 0; // Random port
|
|
185
|
+
}
|
package/src/utils/Metadata.ts
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility class for handling metadata operations.
|
|
3
|
-
* Wraps Reflect.getMetadata and Reflect.defineMetadata.
|
|
4
|
-
*/
|
|
5
|
-
export class Metadata {
|
|
6
|
-
static get<T = any>(key: string | symbol, target: any): T | undefined {
|
|
7
|
-
return Reflect.getMetadata(key, target);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
static set(key: string | symbol, value: any, target: any): void {
|
|
11
|
-
Reflect.defineMetadata(key, value, target);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
static has(key: string | symbol, target: any): boolean {
|
|
15
|
-
return Reflect.hasMetadata(key, target);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
static delete(key: string | symbol, target: any): boolean {
|
|
19
|
-
return Reflect.deleteMetadata(key, target);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static keys(target: any): (string | symbol)[] {
|
|
23
|
-
return Reflect.getMetadataKeys(target);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
static getType(target: any, propertyKey: string | symbol): any {
|
|
27
|
-
return Reflect.getMetadata('design:type', target, propertyKey);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Type guard for checking if value is an object.
|
|
33
|
-
*/
|
|
34
|
-
export function isObject(value: unknown): value is Record<string, any> {
|
|
35
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Type guard for checking if value is a string.
|
|
40
|
-
*/
|
|
41
|
-
export function isString(value: unknown): value is string {
|
|
42
|
-
return typeof value === 'string';
|
|
43
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Utility class for handling metadata operations.
|
|
3
|
+
* Wraps Reflect.getMetadata and Reflect.defineMetadata.
|
|
4
|
+
*/
|
|
5
|
+
export class Metadata {
|
|
6
|
+
static get<T = any>(key: string | symbol, target: any): T | undefined {
|
|
7
|
+
return Reflect.getMetadata(key, target);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static set(key: string | symbol, value: any, target: any): void {
|
|
11
|
+
Reflect.defineMetadata(key, value, target);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static has(key: string | symbol, target: any): boolean {
|
|
15
|
+
return Reflect.hasMetadata(key, target);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static delete(key: string | symbol, target: any): boolean {
|
|
19
|
+
return Reflect.deleteMetadata(key, target);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static keys(target: any): (string | symbol)[] {
|
|
23
|
+
return Reflect.getMetadataKeys(target);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static getType(target: any, propertyKey: string | symbol): any {
|
|
27
|
+
return Reflect.getMetadata('design:type', target, propertyKey);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Type guard for checking if value is an object.
|
|
33
|
+
*/
|
|
34
|
+
export function isObject(value: unknown): value is Record<string, any> {
|
|
35
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Type guard for checking if value is a string.
|
|
40
|
+
*/
|
|
41
|
+
export function isString(value: unknown): value is string {
|
|
42
|
+
return typeof value === 'string';
|
|
43
|
+
}
|