@dangao/bun-server 1.0.0 → 1.0.3

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 (200) hide show
  1. package/package.json +4 -2
  2. package/readme.md +163 -2
  3. package/src/auth/controller.ts +148 -0
  4. package/src/auth/decorators.ts +81 -0
  5. package/src/auth/index.ts +12 -0
  6. package/src/auth/jwt.ts +169 -0
  7. package/src/auth/oauth2.ts +244 -0
  8. package/src/auth/types.ts +248 -0
  9. package/src/cache/cache-module.ts +67 -0
  10. package/src/cache/decorators.ts +202 -0
  11. package/src/cache/index.ts +27 -0
  12. package/src/cache/service.ts +151 -0
  13. package/src/cache/types.ts +420 -0
  14. package/src/config/config-module.ts +76 -0
  15. package/src/config/index.ts +8 -0
  16. package/src/config/service.ts +93 -0
  17. package/src/config/types.ts +27 -0
  18. package/src/controller/controller.ts +251 -0
  19. package/src/controller/decorators.ts +84 -0
  20. package/src/controller/index.ts +7 -0
  21. package/src/controller/metadata.ts +27 -0
  22. package/src/controller/param-binder.ts +157 -0
  23. package/src/core/application.ts +233 -0
  24. package/src/core/context.ts +228 -0
  25. package/src/core/index.ts +4 -0
  26. package/src/core/server.ts +128 -0
  27. package/src/core/types.ts +2 -0
  28. package/src/database/connection-manager.ts +239 -0
  29. package/src/database/connection-pool.ts +322 -0
  30. package/src/database/database-extension.ts +62 -0
  31. package/src/database/database-module.ts +115 -0
  32. package/src/database/health-indicator.ts +51 -0
  33. package/src/database/index.ts +47 -0
  34. package/src/database/orm/decorators.ts +155 -0
  35. package/src/database/orm/drizzle-repository.ts +39 -0
  36. package/src/database/orm/index.ts +23 -0
  37. package/src/database/orm/repository-decorator.ts +39 -0
  38. package/src/database/orm/repository.ts +103 -0
  39. package/src/database/orm/service.ts +49 -0
  40. package/src/database/orm/transaction-decorator.ts +45 -0
  41. package/src/database/orm/transaction-interceptor.ts +243 -0
  42. package/src/database/orm/transaction-manager.ts +276 -0
  43. package/src/database/orm/transaction-types.ts +140 -0
  44. package/src/database/orm/types.ts +99 -0
  45. package/src/database/service.ts +221 -0
  46. package/src/database/types.ts +171 -0
  47. package/src/di/container.ts +398 -0
  48. package/src/di/decorators.ts +228 -0
  49. package/src/di/index.ts +4 -0
  50. package/src/di/module-registry.ts +188 -0
  51. package/src/di/module.ts +65 -0
  52. package/src/di/types.ts +67 -0
  53. package/src/error/error-codes.ts +222 -0
  54. package/src/error/filter.ts +43 -0
  55. package/src/error/handler.ts +66 -0
  56. package/src/error/http-exception.ts +115 -0
  57. package/src/error/i18n.ts +217 -0
  58. package/src/error/index.ts +16 -0
  59. package/src/extensions/index.ts +5 -0
  60. package/src/extensions/logger-extension.ts +31 -0
  61. package/src/extensions/logger-module.ts +69 -0
  62. package/src/extensions/types.ts +14 -0
  63. package/src/files/index.ts +5 -0
  64. package/src/files/static-middleware.ts +53 -0
  65. package/src/files/storage.ts +67 -0
  66. package/src/files/types.ts +33 -0
  67. package/src/files/upload-middleware.ts +45 -0
  68. package/src/health/controller.ts +76 -0
  69. package/src/health/health-module.ts +51 -0
  70. package/src/health/index.ts +12 -0
  71. package/src/health/types.ts +28 -0
  72. package/src/index.ts +270 -0
  73. package/src/metrics/collector.ts +209 -0
  74. package/src/metrics/controller.ts +40 -0
  75. package/src/metrics/index.ts +15 -0
  76. package/src/metrics/metrics-module.ts +58 -0
  77. package/src/metrics/middleware.ts +46 -0
  78. package/src/metrics/prometheus.ts +79 -0
  79. package/src/metrics/types.ts +103 -0
  80. package/src/middleware/builtin/cors.ts +60 -0
  81. package/src/middleware/builtin/error-handler.ts +90 -0
  82. package/src/middleware/builtin/file-upload.ts +42 -0
  83. package/src/middleware/builtin/index.ts +14 -0
  84. package/src/middleware/builtin/logger.ts +91 -0
  85. package/src/middleware/builtin/rate-limit.ts +252 -0
  86. package/src/middleware/builtin/static-file.ts +88 -0
  87. package/src/middleware/decorators.ts +91 -0
  88. package/src/middleware/index.ts +11 -0
  89. package/src/middleware/middleware.ts +13 -0
  90. package/src/middleware/pipeline.ts +93 -0
  91. package/src/queue/decorators.ts +110 -0
  92. package/src/queue/index.ts +26 -0
  93. package/src/queue/queue-module.ts +64 -0
  94. package/src/queue/service.ts +302 -0
  95. package/src/queue/types.ts +341 -0
  96. package/src/request/body-parser.ts +133 -0
  97. package/src/request/file-handler.ts +46 -0
  98. package/src/request/index.ts +5 -0
  99. package/src/request/request.ts +107 -0
  100. package/src/request/response.ts +150 -0
  101. package/src/router/decorators.ts +122 -0
  102. package/src/router/index.ts +6 -0
  103. package/src/router/registry.ts +98 -0
  104. package/src/router/route.ts +140 -0
  105. package/src/router/router.ts +241 -0
  106. package/src/router/types.ts +27 -0
  107. package/src/security/access-decision-manager.ts +34 -0
  108. package/src/security/authentication-manager.ts +47 -0
  109. package/src/security/context.ts +92 -0
  110. package/src/security/filter.ts +162 -0
  111. package/src/security/index.ts +8 -0
  112. package/src/security/providers/index.ts +3 -0
  113. package/src/security/providers/jwt-provider.ts +60 -0
  114. package/src/security/providers/oauth2-provider.ts +70 -0
  115. package/src/security/security-module.ts +145 -0
  116. package/src/security/types.ts +165 -0
  117. package/src/session/decorators.ts +45 -0
  118. package/src/session/index.ts +19 -0
  119. package/src/session/middleware.ts +143 -0
  120. package/src/session/service.ts +218 -0
  121. package/src/session/session-module.ts +69 -0
  122. package/src/session/types.ts +373 -0
  123. package/src/swagger/decorators.ts +133 -0
  124. package/src/swagger/generator.ts +234 -0
  125. package/src/swagger/index.ts +7 -0
  126. package/src/swagger/swagger-extension.ts +41 -0
  127. package/src/swagger/swagger-module.ts +83 -0
  128. package/src/swagger/types.ts +188 -0
  129. package/src/swagger/ui.ts +98 -0
  130. package/src/testing/harness.ts +96 -0
  131. package/src/validation/decorators.ts +95 -0
  132. package/src/validation/errors.ts +28 -0
  133. package/src/validation/index.ts +14 -0
  134. package/src/validation/types.ts +35 -0
  135. package/src/validation/validator.ts +63 -0
  136. package/src/websocket/decorators.ts +51 -0
  137. package/src/websocket/index.ts +12 -0
  138. package/src/websocket/registry.ts +133 -0
  139. package/tests/cache/cache-module.test.ts +212 -0
  140. package/tests/config/config-module.test.ts +151 -0
  141. package/tests/controller/controller.test.ts +189 -0
  142. package/tests/core/application.test.ts +57 -0
  143. package/tests/core/context-body.test.ts +44 -0
  144. package/tests/core/context.test.ts +86 -0
  145. package/tests/core/edge-cases.test.ts +432 -0
  146. package/tests/database/database-module.test.ts +385 -0
  147. package/tests/database/orm.test.ts +164 -0
  148. package/tests/database/postgres-mysql-integration.test.ts +395 -0
  149. package/tests/database/transaction.test.ts +238 -0
  150. package/tests/di/container.test.ts +264 -0
  151. package/tests/di/module.test.ts +128 -0
  152. package/tests/error/error-codes.test.ts +121 -0
  153. package/tests/error/error-handler.test.ts +68 -0
  154. package/tests/error/error-handling.test.ts +254 -0
  155. package/tests/error/http-exception.test.ts +37 -0
  156. package/tests/error/i18n-integration.test.ts +175 -0
  157. package/tests/extensions/logger-extension.test.ts +40 -0
  158. package/tests/files/static-middleware.test.ts +67 -0
  159. package/tests/files/upload-middleware.test.ts +43 -0
  160. package/tests/health/health-module.test.ts +116 -0
  161. package/tests/integration/application-router.test.ts +85 -0
  162. package/tests/integration/body-parsing.test.ts +88 -0
  163. package/tests/integration/cache-e2e.test.ts +114 -0
  164. package/tests/integration/oauth2-e2e.test.ts +615 -0
  165. package/tests/integration/session-e2e.test.ts +207 -0
  166. package/tests/metrics/metrics-module.test.ts +178 -0
  167. package/tests/middleware/builtin.test.ts +206 -0
  168. package/tests/middleware/file-upload.test.ts +41 -0
  169. package/tests/middleware/middleware.test.ts +120 -0
  170. package/tests/middleware/pipeline.test.ts +72 -0
  171. package/tests/middleware/rate-limit.test.ts +314 -0
  172. package/tests/middleware/static-file.test.ts +62 -0
  173. package/tests/perf/harness.test.ts +48 -0
  174. package/tests/perf/optimization.test.ts +183 -0
  175. package/tests/perf/regression.test.ts +120 -0
  176. package/tests/queue/queue-module.test.ts +217 -0
  177. package/tests/request/body-parser.test.ts +96 -0
  178. package/tests/request/response.test.ts +99 -0
  179. package/tests/router/decorators.test.ts +48 -0
  180. package/tests/router/registry.test.ts +51 -0
  181. package/tests/router/route.test.ts +71 -0
  182. package/tests/router/router-normalization.test.ts +106 -0
  183. package/tests/router/router.test.ts +133 -0
  184. package/tests/security/access-decision-manager.test.ts +84 -0
  185. package/tests/security/authentication-manager.test.ts +81 -0
  186. package/tests/security/context.test.ts +302 -0
  187. package/tests/security/filter.test.ts +225 -0
  188. package/tests/security/jwt-provider.test.ts +106 -0
  189. package/tests/security/oauth2-provider.test.ts +269 -0
  190. package/tests/security/security-module.test.ts +143 -0
  191. package/tests/session/session-module.test.ts +307 -0
  192. package/tests/stress/di-stress.test.ts +30 -0
  193. package/tests/swagger/decorators.test.ts +153 -0
  194. package/tests/swagger/generator.test.ts +202 -0
  195. package/tests/swagger/swagger-extension.test.ts +72 -0
  196. package/tests/swagger/swagger-module.test.ts +79 -0
  197. package/tests/utils/test-port.ts +10 -0
  198. package/tests/validation/controller-validation.test.ts +64 -0
  199. package/tests/validation/validation.test.ts +42 -0
  200. package/tests/websocket/gateway.test.ts +68 -0
@@ -0,0 +1,143 @@
1
+ import type { Context } from '../core/context';
2
+ import type { Middleware, NextFunction } from '../middleware/middleware';
3
+ import { SessionService } from './service';
4
+ import { SESSION_SERVICE_TOKEN } from './types';
5
+ import type { Container } from '../di/container';
6
+
7
+ /**
8
+ * Session 中间件
9
+ * 从 Cookie 中读取 Session ID,并将 Session 对象附加到 Context
10
+ */
11
+ export function createSessionMiddleware(
12
+ container: Container,
13
+ ): Middleware {
14
+ return async (context: Context, next: NextFunction): Promise<Response> => {
15
+ let sessionService: SessionService | undefined;
16
+ try {
17
+ sessionService = container.resolve<SessionService>(
18
+ SESSION_SERVICE_TOKEN,
19
+ );
20
+ } catch {
21
+ // 如果 SessionService 未注册,跳过 Session 处理
22
+ return await next();
23
+ }
24
+
25
+ if (!sessionService) {
26
+ return await next();
27
+ }
28
+
29
+ // 从 Cookie 中读取 Session ID
30
+ const cookieName = sessionService.getCookieName();
31
+ const cookieHeader = context.request.headers.get('cookie');
32
+ let sessionId: string | undefined;
33
+
34
+ if (cookieHeader) {
35
+ // Cookie 格式: "name=value; name2=value2" 或 "name=value"
36
+ // 需要正确处理多个 Cookie 的情况
37
+ const cookies = cookieHeader.split(';').map((c) => c.trim());
38
+ for (const cookie of cookies) {
39
+ if (cookie.startsWith(`${cookieName}=`)) {
40
+ sessionId = cookie.substring(cookieName.length + 1).trim();
41
+ break;
42
+ }
43
+ }
44
+ }
45
+
46
+ // 如果有 Session ID,获取 Session
47
+ if (sessionId) {
48
+ const session = await sessionService.get(sessionId);
49
+ if (session) {
50
+ // 将 Session 附加到 Context
51
+ (context as unknown as { session: typeof session }).session = session;
52
+ (context as unknown as { sessionId: string }).sessionId = sessionId;
53
+ } else {
54
+ // Session 已过期或不存在,清除 sessionId
55
+ sessionId = undefined;
56
+ }
57
+ }
58
+
59
+ // 如果没有 Session,创建一个新 Session
60
+ if (!sessionId) {
61
+ const newSession = await sessionService.create();
62
+ (context as unknown as { session: typeof newSession }).session =
63
+ newSession;
64
+ (context as unknown as { sessionId: string }).sessionId = newSession.id;
65
+ sessionId = newSession.id;
66
+ }
67
+
68
+ // 调用下一个中间件
69
+ const response = await next();
70
+
71
+ // 设置或更新 Cookie
72
+ const currentSessionId = (context as unknown as { sessionId?: string })
73
+ .sessionId;
74
+ if (currentSessionId) {
75
+ const cookieOptions = sessionService.getCookieOptions();
76
+ const maxAge = sessionService.getMaxAge();
77
+ const cookieValue = buildCookie(
78
+ cookieName,
79
+ currentSessionId,
80
+ {
81
+ ...cookieOptions,
82
+ maxAge,
83
+ },
84
+ );
85
+
86
+ // 创建新的 Response,添加 Set-Cookie 头
87
+ const newHeaders = new Headers(response.headers);
88
+ newHeaders.set('Set-Cookie', cookieValue);
89
+
90
+ return new Response(response.body, {
91
+ status: response.status,
92
+ statusText: response.statusText,
93
+ headers: newHeaders,
94
+ });
95
+ }
96
+
97
+ return response;
98
+ };
99
+ }
100
+
101
+ /**
102
+ * 构建 Cookie 字符串
103
+ */
104
+ function buildCookie(
105
+ name: string,
106
+ value: string,
107
+ options: {
108
+ secure?: boolean;
109
+ httpOnly?: boolean;
110
+ path?: string;
111
+ domain?: string;
112
+ sameSite?: 'strict' | 'lax' | 'none';
113
+ maxAge?: number;
114
+ },
115
+ ): string {
116
+ let cookie = `${name}=${value}`;
117
+
118
+ if (options.path) {
119
+ cookie += `; Path=${options.path}`;
120
+ }
121
+
122
+ if (options.domain) {
123
+ cookie += `; Domain=${options.domain}`;
124
+ }
125
+
126
+ if (options.maxAge) {
127
+ cookie += `; Max-Age=${Math.floor(options.maxAge / 1000)}`;
128
+ }
129
+
130
+ if (options.secure) {
131
+ cookie += '; Secure';
132
+ }
133
+
134
+ if (options.httpOnly) {
135
+ cookie += '; HttpOnly';
136
+ }
137
+
138
+ if (options.sameSite) {
139
+ cookie += `; SameSite=${options.sameSite}`;
140
+ }
141
+
142
+ return cookie;
143
+ }
@@ -0,0 +1,218 @@
1
+ import { Injectable } from '../di/decorators';
2
+ import { Inject } from '../di/decorators';
3
+ import type {
4
+ SessionStore,
5
+ SessionModuleOptions,
6
+ Session,
7
+ SessionData,
8
+ } from './types';
9
+ import { SESSION_OPTIONS_TOKEN } from './types';
10
+ import { randomBytes } from 'crypto';
11
+
12
+ /**
13
+ * Session 服务
14
+ */
15
+ @Injectable()
16
+ export class SessionService {
17
+ private store: SessionStore;
18
+ private name: string;
19
+ private maxAge: number;
20
+ private rolling: boolean;
21
+ private cookieOptions: Required<SessionModuleOptions>['cookie'];
22
+
23
+ public constructor(
24
+ @Inject(SESSION_OPTIONS_TOKEN) options: SessionModuleOptions,
25
+ ) {
26
+ this.store = options.store!;
27
+ this.name = options.name ?? 'sessionId';
28
+ this.maxAge = options.maxAge ?? 86400000; // 24 小时
29
+ this.rolling = options.rolling ?? true;
30
+ this.cookieOptions = {
31
+ secure: options.cookie?.secure ?? false,
32
+ httpOnly: options.cookie?.httpOnly ?? true,
33
+ path: options.cookie?.path ?? '/',
34
+ domain: options.cookie?.domain,
35
+ sameSite: options.cookie?.sameSite ?? 'lax',
36
+ };
37
+ }
38
+
39
+ /**
40
+ * 生成 Session ID
41
+ * @returns Session ID
42
+ */
43
+ private generateSessionId(): string {
44
+ return randomBytes(32).toString('hex');
45
+ }
46
+
47
+ /**
48
+ * 创建新 Session
49
+ * @param initialData - 初始数据
50
+ * @returns Session
51
+ */
52
+ public async create(initialData: SessionData = {}): Promise<Session> {
53
+ const now = Date.now();
54
+ const session: Session = {
55
+ id: this.generateSessionId(),
56
+ data: initialData,
57
+ createdAt: now,
58
+ lastAccessedAt: now,
59
+ expiresAt: now + this.maxAge,
60
+ };
61
+
62
+ await this.store.set(session, this.maxAge);
63
+ return session;
64
+ }
65
+
66
+ /**
67
+ * 获取 Session
68
+ * @param sessionId - Session ID
69
+ * @returns Session,如果不存在或已过期则返回 undefined
70
+ */
71
+ public async get(sessionId: string): Promise<Session | undefined> {
72
+ const session = await this.store.get(sessionId);
73
+ if (!session) {
74
+ return undefined;
75
+ }
76
+
77
+ // 如果启用了 rolling,更新最后访问时间和过期时间
78
+ if (this.rolling) {
79
+ await this.touch(sessionId);
80
+ }
81
+
82
+ return session;
83
+ }
84
+
85
+ /**
86
+ * 更新 Session 数据
87
+ * @param sessionId - Session ID
88
+ * @param data - 新数据
89
+ * @returns 是否更新成功
90
+ */
91
+ public async set(
92
+ sessionId: string,
93
+ data: SessionData,
94
+ ): Promise<boolean> {
95
+ const session = await this.store.get(sessionId);
96
+ if (!session) {
97
+ return false;
98
+ }
99
+
100
+ session.data = { ...session.data, ...data };
101
+ session.lastAccessedAt = Date.now();
102
+
103
+ if (this.rolling) {
104
+ session.expiresAt = Date.now() + this.maxAge;
105
+ }
106
+
107
+ return this.store.set(session, this.maxAge);
108
+ }
109
+
110
+ /**
111
+ * 获取 Session 数据中的某个值
112
+ * @param sessionId - Session ID
113
+ * @param key - 数据键
114
+ * @returns 数据值,如果不存在则返回 undefined
115
+ */
116
+ public async getValue<T = unknown>(
117
+ sessionId: string,
118
+ key: string,
119
+ ): Promise<T | undefined> {
120
+ const session = await this.store.get(sessionId);
121
+ if (!session) {
122
+ return undefined;
123
+ }
124
+
125
+ return session.data[key] as T | undefined;
126
+ }
127
+
128
+ /**
129
+ * 设置 Session 数据中的某个值
130
+ * @param sessionId - Session ID
131
+ * @param key - 数据键
132
+ * @param value - 数据值
133
+ * @returns 是否设置成功
134
+ */
135
+ public async setValue<T = unknown>(
136
+ sessionId: string,
137
+ key: string,
138
+ value: T,
139
+ ): Promise<boolean> {
140
+ const session = await this.store.get(sessionId);
141
+ if (!session) {
142
+ return false;
143
+ }
144
+
145
+ session.data[key] = value;
146
+ session.lastAccessedAt = Date.now();
147
+
148
+ if (this.rolling) {
149
+ session.expiresAt = Date.now() + this.maxAge;
150
+ }
151
+
152
+ return this.store.set(session, this.maxAge);
153
+ }
154
+
155
+ /**
156
+ * 删除 Session 数据中的某个值
157
+ * @param sessionId - Session ID
158
+ * @param key - 数据键
159
+ * @returns 是否删除成功
160
+ */
161
+ public async deleteValue(sessionId: string, key: string): Promise<boolean> {
162
+ const session = await this.store.get(sessionId);
163
+ if (!session) {
164
+ return false;
165
+ }
166
+
167
+ delete session.data[key];
168
+ session.lastAccessedAt = Date.now();
169
+
170
+ if (this.rolling) {
171
+ session.expiresAt = Date.now() + this.maxAge;
172
+ }
173
+
174
+ return this.store.set(session, this.maxAge);
175
+ }
176
+
177
+ /**
178
+ * 删除 Session
179
+ * @param sessionId - Session ID
180
+ * @returns 是否删除成功
181
+ */
182
+ public async delete(sessionId: string): Promise<boolean> {
183
+ return this.store.delete(sessionId);
184
+ }
185
+
186
+ /**
187
+ * 更新 Session 的最后访问时间
188
+ * @param sessionId - Session ID
189
+ * @returns 是否更新成功
190
+ */
191
+ public async touch(sessionId: string): Promise<boolean> {
192
+ return this.store.touch(sessionId);
193
+ }
194
+
195
+ /**
196
+ * 获取 Cookie 名称
197
+ * @returns Cookie 名称
198
+ */
199
+ public getCookieName(): string {
200
+ return this.name;
201
+ }
202
+
203
+ /**
204
+ * 获取 Cookie 选项
205
+ * @returns Cookie 选项
206
+ */
207
+ public getCookieOptions(): Required<SessionModuleOptions>['cookie'] {
208
+ return this.cookieOptions;
209
+ }
210
+
211
+ /**
212
+ * 获取最大存活时间
213
+ * @returns 最大存活时间(毫秒)
214
+ */
215
+ public getMaxAge(): number {
216
+ return this.maxAge;
217
+ }
218
+ }
@@ -0,0 +1,69 @@
1
+ import { Module, MODULE_METADATA_KEY, type ModuleProvider } from '../di/module';
2
+
3
+ import { SessionService } from './service';
4
+ import {
5
+ SESSION_OPTIONS_TOKEN,
6
+ SESSION_SERVICE_TOKEN,
7
+ MemorySessionStore,
8
+ type SessionModuleOptions,
9
+ type SessionStore,
10
+ } from './types';
11
+
12
+ @Module({
13
+ providers: [],
14
+ })
15
+ export class SessionModule {
16
+ /**
17
+ * 创建 Session 模块
18
+ * @param options - 模块配置
19
+ */
20
+ public static forRoot(
21
+ options: SessionModuleOptions = {},
22
+ ): typeof SessionModule {
23
+ const providers: ModuleProvider[] = [];
24
+
25
+ // 如果没有提供 store,使用默认的内存存储
26
+ const store: SessionStore =
27
+ options.store ??
28
+ new MemorySessionStore({
29
+ cleanupInterval: 60000, // 每分钟清理一次
30
+ });
31
+
32
+ const service = new SessionService({
33
+ store,
34
+ name: options.name,
35
+ maxAge: options.maxAge,
36
+ rolling: options.rolling,
37
+ cookie: options.cookie,
38
+ });
39
+
40
+ providers.push(
41
+ {
42
+ provide: SESSION_SERVICE_TOKEN,
43
+ useValue: service,
44
+ },
45
+ {
46
+ provide: SESSION_OPTIONS_TOKEN,
47
+ useValue: options,
48
+ },
49
+ SessionService,
50
+ );
51
+
52
+ // 动态更新模块元数据
53
+ const existingMetadata =
54
+ Reflect.getMetadata(MODULE_METADATA_KEY, SessionModule) || {};
55
+ const metadata = {
56
+ ...existingMetadata,
57
+ providers: [...(existingMetadata.providers || []), ...providers],
58
+ exports: [
59
+ ...(existingMetadata.exports || []),
60
+ SESSION_SERVICE_TOKEN,
61
+ SESSION_OPTIONS_TOKEN,
62
+ SessionService,
63
+ ],
64
+ };
65
+ Reflect.defineMetadata(MODULE_METADATA_KEY, metadata, SessionModule);
66
+
67
+ return SessionModule;
68
+ }
69
+ }