@engjts/nexus 0.1.7 → 0.1.9

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 (259) hide show
  1. package/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
  2. package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
  3. package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
  4. package/dist/advanced/playground/playground.d.ts +19 -0
  5. package/dist/advanced/playground/playground.d.ts.map +1 -1
  6. package/dist/advanced/playground/playground.js +70 -0
  7. package/dist/advanced/playground/playground.js.map +1 -1
  8. package/dist/advanced/playground/types.d.ts +20 -0
  9. package/dist/advanced/playground/types.d.ts.map +1 -1
  10. package/dist/core/application.d.ts +14 -0
  11. package/dist/core/application.d.ts.map +1 -1
  12. package/dist/core/application.js +173 -71
  13. package/dist/core/application.js.map +1 -1
  14. package/dist/core/context-pool.d.ts +2 -13
  15. package/dist/core/context-pool.d.ts.map +1 -1
  16. package/dist/core/context-pool.js +7 -45
  17. package/dist/core/context-pool.js.map +1 -1
  18. package/dist/core/context.d.ts +108 -5
  19. package/dist/core/context.d.ts.map +1 -1
  20. package/dist/core/context.js +449 -53
  21. package/dist/core/context.js.map +1 -1
  22. package/dist/core/index.d.ts +1 -0
  23. package/dist/core/index.d.ts.map +1 -1
  24. package/dist/core/index.js +9 -1
  25. package/dist/core/index.js.map +1 -1
  26. package/dist/core/middleware.d.ts +6 -0
  27. package/dist/core/middleware.d.ts.map +1 -1
  28. package/dist/core/middleware.js +83 -84
  29. package/dist/core/middleware.js.map +1 -1
  30. package/dist/core/performance/fast-json.d.ts +149 -0
  31. package/dist/core/performance/fast-json.d.ts.map +1 -0
  32. package/dist/core/performance/fast-json.js +473 -0
  33. package/dist/core/performance/fast-json.js.map +1 -0
  34. package/dist/core/router/file-router.d.ts +20 -7
  35. package/dist/core/router/file-router.d.ts.map +1 -1
  36. package/dist/core/router/file-router.js +41 -13
  37. package/dist/core/router/file-router.js.map +1 -1
  38. package/dist/core/router/index.d.ts +6 -0
  39. package/dist/core/router/index.d.ts.map +1 -1
  40. package/dist/core/router/index.js +33 -6
  41. package/dist/core/router/index.js.map +1 -1
  42. package/dist/core/router/radix-tree.d.ts +4 -1
  43. package/dist/core/router/radix-tree.d.ts.map +1 -1
  44. package/dist/core/router/radix-tree.js +7 -3
  45. package/dist/core/router/radix-tree.js.map +1 -1
  46. package/dist/core/serializer.d.ts +251 -0
  47. package/dist/core/serializer.d.ts.map +1 -0
  48. package/dist/core/serializer.js +290 -0
  49. package/dist/core/serializer.js.map +1 -0
  50. package/dist/core/types.d.ts +39 -1
  51. package/dist/core/types.d.ts.map +1 -1
  52. package/dist/core/types.js.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +12 -2
  56. package/dist/index.js.map +1 -1
  57. package/package.json +3 -1
  58. package/documentation/01-getting-started.md +0 -240
  59. package/documentation/02-context.md +0 -335
  60. package/documentation/03-routing.md +0 -397
  61. package/documentation/04-middleware.md +0 -483
  62. package/documentation/05-validation.md +0 -514
  63. package/documentation/06-error-handling.md +0 -465
  64. package/documentation/07-performance.md +0 -364
  65. package/documentation/08-adapters.md +0 -470
  66. package/documentation/09-api-reference.md +0 -548
  67. package/documentation/10-examples.md +0 -582
  68. package/documentation/11-deployment.md +0 -477
  69. package/documentation/12-sentry.md +0 -620
  70. package/documentation/13-sentry-data-storage.md +0 -996
  71. package/documentation/14-sentry-data-reference.md +0 -457
  72. package/documentation/15-sentry-summary.md +0 -409
  73. package/documentation/16-alerts-system.md +0 -745
  74. package/documentation/17-alert-adapters.md +0 -696
  75. package/documentation/18-alerts-implementation-summary.md +0 -385
  76. package/documentation/19-class-based-routing.md +0 -840
  77. package/documentation/20-websocket-realtime.md +0 -813
  78. package/documentation/21-cache-system.md +0 -510
  79. package/documentation/22-job-queue.md +0 -772
  80. package/documentation/23-sentry-plugin.md +0 -551
  81. package/documentation/24-testing-utilities.md +0 -1287
  82. package/documentation/25-api-versioning.md +0 -533
  83. package/documentation/26-context-store.md +0 -607
  84. package/documentation/27-dependency-injection.md +0 -329
  85. package/documentation/28-lifecycle-hooks.md +0 -521
  86. package/documentation/29-package-structure.md +0 -196
  87. package/documentation/30-plugin-system.md +0 -414
  88. package/documentation/31-jwt-authentication.md +0 -597
  89. package/documentation/32-cli.md +0 -268
  90. package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
  91. package/documentation/ALERTS-INDEX.md +0 -330
  92. package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
  93. package/documentation/README.md +0 -178
  94. package/documentation/index.html +0 -34
  95. package/modern_framework_paper.md +0 -1870
  96. package/public/css/style.css +0 -87
  97. package/public/index.html +0 -34
  98. package/public/js/app.js +0 -27
  99. package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
  100. package/src/advanced/cache/MultiTierCache.ts +0 -194
  101. package/src/advanced/cache/RedisCacheStore.ts +0 -341
  102. package/src/advanced/cache/index.ts +0 -5
  103. package/src/advanced/cache/types.ts +0 -40
  104. package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
  105. package/src/advanced/graphql/index.ts +0 -22
  106. package/src/advanced/graphql/server.ts +0 -252
  107. package/src/advanced/graphql/types.ts +0 -42
  108. package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
  109. package/src/advanced/jobs/JobQueue.ts +0 -556
  110. package/src/advanced/jobs/RedisQueueStore.ts +0 -367
  111. package/src/advanced/jobs/index.ts +0 -5
  112. package/src/advanced/jobs/types.ts +0 -70
  113. package/src/advanced/observability/APMManager.ts +0 -163
  114. package/src/advanced/observability/AlertManager.ts +0 -109
  115. package/src/advanced/observability/MetricRegistry.ts +0 -151
  116. package/src/advanced/observability/ObservabilityCenter.ts +0 -304
  117. package/src/advanced/observability/StructuredLogger.ts +0 -154
  118. package/src/advanced/observability/TracingManager.ts +0 -117
  119. package/src/advanced/observability/adapters.ts +0 -304
  120. package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
  121. package/src/advanced/observability/index.ts +0 -11
  122. package/src/advanced/observability/types.ts +0 -174
  123. package/src/advanced/playground/extractPathParams.ts +0 -6
  124. package/src/advanced/playground/generateFieldExample.ts +0 -31
  125. package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1849
  126. package/src/advanced/playground/generateSummary.ts +0 -19
  127. package/src/advanced/playground/getTagFromPath.ts +0 -9
  128. package/src/advanced/playground/index.ts +0 -8
  129. package/src/advanced/playground/playground.ts +0 -170
  130. package/src/advanced/playground/types.ts +0 -20
  131. package/src/advanced/playground/zodToExample.ts +0 -16
  132. package/src/advanced/playground/zodToParams.ts +0 -15
  133. package/src/advanced/postman/buildAuth.ts +0 -31
  134. package/src/advanced/postman/buildBody.ts +0 -15
  135. package/src/advanced/postman/buildQueryParams.ts +0 -27
  136. package/src/advanced/postman/buildRequestItem.ts +0 -36
  137. package/src/advanced/postman/buildResponses.ts +0 -11
  138. package/src/advanced/postman/buildUrl.ts +0 -33
  139. package/src/advanced/postman/capitalize.ts +0 -4
  140. package/src/advanced/postman/generateCollection.ts +0 -59
  141. package/src/advanced/postman/generateEnvironment.ts +0 -34
  142. package/src/advanced/postman/generateExampleFromZod.ts +0 -21
  143. package/src/advanced/postman/generateFieldExample.ts +0 -45
  144. package/src/advanced/postman/generateName.ts +0 -20
  145. package/src/advanced/postman/generateUUID.ts +0 -11
  146. package/src/advanced/postman/getTagFromPath.ts +0 -10
  147. package/src/advanced/postman/index.ts +0 -28
  148. package/src/advanced/postman/postman.ts +0 -156
  149. package/src/advanced/postman/slugify.ts +0 -7
  150. package/src/advanced/postman/types.ts +0 -140
  151. package/src/advanced/realtime/index.ts +0 -18
  152. package/src/advanced/realtime/websocket.ts +0 -231
  153. package/src/advanced/sentry/index.ts +0 -1236
  154. package/src/advanced/sentry/types.ts +0 -355
  155. package/src/advanced/static/generateDirectoryListing.ts +0 -47
  156. package/src/advanced/static/generateETag.ts +0 -7
  157. package/src/advanced/static/getMimeType.ts +0 -9
  158. package/src/advanced/static/index.ts +0 -32
  159. package/src/advanced/static/isSafePath.ts +0 -13
  160. package/src/advanced/static/publicDir.ts +0 -21
  161. package/src/advanced/static/serveStatic.ts +0 -225
  162. package/src/advanced/static/spa.ts +0 -24
  163. package/src/advanced/static/types.ts +0 -159
  164. package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
  165. package/src/advanced/swagger/buildOperation.ts +0 -61
  166. package/src/advanced/swagger/buildParameters.ts +0 -61
  167. package/src/advanced/swagger/buildRequestBody.ts +0 -21
  168. package/src/advanced/swagger/buildResponses.ts +0 -54
  169. package/src/advanced/swagger/capitalize.ts +0 -5
  170. package/src/advanced/swagger/convertPath.ts +0 -9
  171. package/src/advanced/swagger/createSwagger.ts +0 -12
  172. package/src/advanced/swagger/generateOperationId.ts +0 -21
  173. package/src/advanced/swagger/generateSpec.ts +0 -105
  174. package/src/advanced/swagger/generateSummary.ts +0 -24
  175. package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
  176. package/src/advanced/swagger/generateThemeCss.ts +0 -53
  177. package/src/advanced/swagger/index.ts +0 -25
  178. package/src/advanced/swagger/swagger.ts +0 -237
  179. package/src/advanced/swagger/types.ts +0 -206
  180. package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
  181. package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
  182. package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
  183. package/src/advanced/testing/factory.ts +0 -509
  184. package/src/advanced/testing/harness.ts +0 -612
  185. package/src/advanced/testing/index.ts +0 -430
  186. package/src/advanced/testing/load-test.ts +0 -618
  187. package/src/advanced/testing/mock-server.ts +0 -498
  188. package/src/advanced/testing/mock.ts +0 -670
  189. package/src/cli/bin.ts +0 -9
  190. package/src/cli/cli.ts +0 -158
  191. package/src/cli/commands/add.ts +0 -178
  192. package/src/cli/commands/build.ts +0 -73
  193. package/src/cli/commands/create.ts +0 -166
  194. package/src/cli/commands/dev.ts +0 -85
  195. package/src/cli/commands/generate.ts +0 -99
  196. package/src/cli/commands/help.ts +0 -95
  197. package/src/cli/commands/init.ts +0 -91
  198. package/src/cli/commands/version.ts +0 -38
  199. package/src/cli/index.ts +0 -6
  200. package/src/cli/templates/generators.ts +0 -359
  201. package/src/cli/templates/index.ts +0 -680
  202. package/src/cli/utils/exec.ts +0 -52
  203. package/src/cli/utils/file-system.ts +0 -78
  204. package/src/cli/utils/logger.ts +0 -111
  205. package/src/core/adapter.ts +0 -88
  206. package/src/core/application.ts +0 -1335
  207. package/src/core/context-pool.ts +0 -127
  208. package/src/core/context.ts +0 -412
  209. package/src/core/index.ts +0 -80
  210. package/src/core/middleware.ts +0 -262
  211. package/src/core/performance/buffer-pool.ts +0 -108
  212. package/src/core/performance/middleware-optimizer.ts +0 -162
  213. package/src/core/plugin/PluginManager.ts +0 -435
  214. package/src/core/plugin/builder.ts +0 -358
  215. package/src/core/plugin/index.ts +0 -50
  216. package/src/core/plugin/types.ts +0 -214
  217. package/src/core/router/file-router.ts +0 -594
  218. package/src/core/router/index.ts +0 -227
  219. package/src/core/router/radix-tree.ts +0 -226
  220. package/src/core/store/index.ts +0 -30
  221. package/src/core/store/registry.ts +0 -178
  222. package/src/core/store/request-store.ts +0 -240
  223. package/src/core/store/types.ts +0 -233
  224. package/src/core/types.ts +0 -574
  225. package/src/database/adapter.ts +0 -35
  226. package/src/database/adapters/index.ts +0 -1
  227. package/src/database/adapters/mysql.ts +0 -669
  228. package/src/database/database.ts +0 -70
  229. package/src/database/dialect.ts +0 -388
  230. package/src/database/index.ts +0 -12
  231. package/src/database/migrations.ts +0 -86
  232. package/src/database/optimizer.ts +0 -125
  233. package/src/database/query-builder.ts +0 -404
  234. package/src/database/realtime.ts +0 -53
  235. package/src/database/schema.ts +0 -71
  236. package/src/database/transactions.ts +0 -56
  237. package/src/database/types.ts +0 -87
  238. package/src/deployment/cluster.ts +0 -471
  239. package/src/deployment/config.ts +0 -454
  240. package/src/deployment/docker.ts +0 -599
  241. package/src/deployment/graceful-shutdown.ts +0 -373
  242. package/src/deployment/index.ts +0 -56
  243. package/src/index.ts +0 -264
  244. package/src/security/adapter.ts +0 -318
  245. package/src/security/auth/JWTPlugin.ts +0 -234
  246. package/src/security/auth/JWTProvider.ts +0 -316
  247. package/src/security/auth/adapter.ts +0 -12
  248. package/src/security/auth/jwt.ts +0 -234
  249. package/src/security/auth/middleware.ts +0 -188
  250. package/src/security/csrf.ts +0 -220
  251. package/src/security/headers.ts +0 -108
  252. package/src/security/index.ts +0 -60
  253. package/src/security/rate-limit/adapter.ts +0 -7
  254. package/src/security/rate-limit/memory.ts +0 -108
  255. package/src/security/rate-limit/middleware.ts +0 -181
  256. package/src/security/sanitization.ts +0 -75
  257. package/src/security/types.ts +0 -240
  258. package/src/security/utils.ts +0 -52
  259. package/tsconfig.json +0 -39
@@ -1,670 +0,0 @@
1
- /**
2
- * Mock utilities for testing - database mocks, fetch mocks, and more
3
- */
4
-
5
- import { EventEmitter } from 'events';
6
-
7
- export type MockFn<T = any> = {
8
- (...args: any[]): T;
9
- calls: any[][];
10
- results: T[];
11
- mockReturnValue(value: T): MockFn<T>;
12
- mockReturnValueOnce(value: T): MockFn<T>;
13
- mockResolvedValue(value: T): MockFn<Promise<T>>;
14
- mockResolvedValueOnce(value: T): MockFn<Promise<T>>;
15
- mockRejectedValue(error: Error): MockFn<Promise<never>>;
16
- mockRejectedValueOnce(error: Error): MockFn<Promise<never>>;
17
- mockImplementation(fn: (...args: any[]) => T): MockFn<T>;
18
- mockImplementationOnce(fn: (...args: any[]) => T): MockFn<T>;
19
- mockClear(): void;
20
- mockReset(): void;
21
- toHaveBeenCalled(): boolean;
22
- toHaveBeenCalledTimes(count: number): boolean;
23
- toHaveBeenCalledWith(...args: any[]): boolean;
24
- toHaveBeenLastCalledWith(...args: any[]): boolean;
25
- };
26
-
27
- /**
28
- * Create a mock function
29
- */
30
- export function createMockFn<T = any>(defaultImpl?: (...args: any[]) => T): MockFn<T> {
31
- let returnValue: T | undefined;
32
- let returnQueue: T[] = [];
33
- let implementation: ((...args: any[]) => T) | undefined = defaultImpl;
34
- let implementationQueue: Array<(...args: any[]) => T> = [];
35
-
36
- const fn = ((...args: any[]): T => {
37
- fn.calls.push(args);
38
-
39
- // Check implementation queue first
40
- if (implementationQueue.length > 0) {
41
- const impl = implementationQueue.shift()!;
42
- const result = impl(...args);
43
- fn.results.push(result);
44
- return result;
45
- }
46
-
47
- // Check return value queue
48
- if (returnQueue.length > 0) {
49
- const result = returnQueue.shift()!;
50
- fn.results.push(result);
51
- return result;
52
- }
53
-
54
- // Use implementation if set
55
- if (implementation) {
56
- const result = implementation(...args);
57
- fn.results.push(result);
58
- return result;
59
- }
60
-
61
- // Return static value
62
- fn.results.push(returnValue as T);
63
- return returnValue as T;
64
- }) as MockFn<T>;
65
-
66
- fn.calls = [];
67
- fn.results = [];
68
-
69
- fn.mockReturnValue = (value: T) => {
70
- returnValue = value;
71
- return fn;
72
- };
73
-
74
- fn.mockReturnValueOnce = (value: T) => {
75
- returnQueue.push(value);
76
- return fn;
77
- };
78
-
79
- fn.mockResolvedValue = (value: T) => {
80
- returnValue = Promise.resolve(value) as any;
81
- return fn as any;
82
- };
83
-
84
- fn.mockResolvedValueOnce = (value: T) => {
85
- returnQueue.push(Promise.resolve(value) as any);
86
- return fn as any;
87
- };
88
-
89
- fn.mockRejectedValue = (error: Error) => {
90
- returnValue = Promise.reject(error) as any;
91
- return fn as any;
92
- };
93
-
94
- fn.mockRejectedValueOnce = (error: Error) => {
95
- returnQueue.push(Promise.reject(error) as any);
96
- return fn as any;
97
- };
98
-
99
- fn.mockImplementation = (impl: (...args: any[]) => T) => {
100
- implementation = impl;
101
- return fn;
102
- };
103
-
104
- fn.mockImplementationOnce = (impl: (...args: any[]) => T) => {
105
- implementationQueue.push(impl);
106
- return fn;
107
- };
108
-
109
- fn.mockClear = () => {
110
- fn.calls = [];
111
- fn.results = [];
112
- };
113
-
114
- fn.mockReset = () => {
115
- fn.mockClear();
116
- returnValue = undefined;
117
- returnQueue = [];
118
- implementation = defaultImpl;
119
- implementationQueue = [];
120
- };
121
-
122
- fn.toHaveBeenCalled = () => fn.calls.length > 0;
123
- fn.toHaveBeenCalledTimes = (count: number) => fn.calls.length === count;
124
- fn.toHaveBeenCalledWith = (...args: any[]) =>
125
- fn.calls.some(call => JSON.stringify(call) === JSON.stringify(args));
126
- fn.toHaveBeenLastCalledWith = (...args: any[]) =>
127
- fn.calls.length > 0 && JSON.stringify(fn.calls[fn.calls.length - 1]) === JSON.stringify(args);
128
-
129
- return fn;
130
- }
131
-
132
- /**
133
- * Mock database for testing
134
- */
135
- export interface MockRecord {
136
- id: string | number;
137
- [key: string]: any;
138
- }
139
-
140
- export interface MockTableOptions {
141
- autoIncrement?: boolean;
142
- primaryKey?: string;
143
- }
144
-
145
- export class MockTable<T extends MockRecord = MockRecord> {
146
- private records: Map<string | number, T> = new Map();
147
- private autoIncrementId = 1;
148
- private options: MockTableOptions;
149
- private primaryKey: string;
150
-
151
- // Mock functions for assertion
152
- insert = createMockFn<Promise<T>>();
153
- update = createMockFn<Promise<T | undefined>>();
154
- delete = createMockFn<Promise<boolean>>();
155
- find = createMockFn<Promise<T | undefined>>();
156
- findMany = createMockFn<Promise<T[]>>();
157
-
158
- constructor(options: MockTableOptions = {}) {
159
- this.options = options;
160
- this.primaryKey = options.primaryKey ?? 'id';
161
-
162
- // Set up real implementations
163
- this.insert.mockImplementation(async (data: Partial<T>) => {
164
- const record = { ...data } as T;
165
- if (this.options.autoIncrement !== false && !record[this.primaryKey]) {
166
- (record as any)[this.primaryKey] = this.autoIncrementId++;
167
- }
168
- this.records.set(record[this.primaryKey], record);
169
- return record;
170
- });
171
-
172
- this.update.mockImplementation(async (id: string | number, data: Partial<T>) => {
173
- const existing = this.records.get(id);
174
- if (!existing) return undefined;
175
- const updated = { ...existing, ...data };
176
- this.records.set(id, updated);
177
- return updated;
178
- });
179
-
180
- this.delete.mockImplementation(async (id: string | number) => {
181
- return this.records.delete(id);
182
- });
183
-
184
- this.find.mockImplementation(async (id: string | number) => {
185
- return this.records.get(id);
186
- });
187
-
188
- this.findMany.mockImplementation(async (filter?: Partial<T>) => {
189
- const all = Array.from(this.records.values());
190
- if (!filter) return all;
191
- return all.filter(record => {
192
- for (const [key, value] of Object.entries(filter)) {
193
- if (record[key] !== value) return false;
194
- }
195
- return true;
196
- });
197
- });
198
- }
199
-
200
- /**
201
- * Get all records (for assertions)
202
- */
203
- getAll(): T[] {
204
- return Array.from(this.records.values());
205
- }
206
-
207
- /**
208
- * Seed the table with data
209
- */
210
- seed(records: T[]): void {
211
- for (const record of records) {
212
- this.records.set(record[this.primaryKey], record);
213
- if (typeof record[this.primaryKey] === 'number') {
214
- this.autoIncrementId = Math.max(this.autoIncrementId, record[this.primaryKey] as number + 1);
215
- }
216
- }
217
- }
218
-
219
- /**
220
- * Clear all records
221
- */
222
- clear(): void {
223
- this.records.clear();
224
- this.autoIncrementId = 1;
225
- }
226
-
227
- /**
228
- * Reset everything including mock calls
229
- */
230
- reset(): void {
231
- this.clear();
232
- this.insert.mockClear();
233
- this.update.mockClear();
234
- this.delete.mockClear();
235
- this.find.mockClear();
236
- this.findMany.mockClear();
237
- }
238
- }
239
-
240
- export class MockDatabase {
241
- private tables: Map<string, MockTable> = new Map();
242
-
243
- /**
244
- * Get or create a mock table
245
- */
246
- table<T extends MockRecord = MockRecord>(name: string, options?: MockTableOptions): MockTable<T> {
247
- if (!this.tables.has(name)) {
248
- this.tables.set(name, new MockTable<T>(options));
249
- }
250
- return this.tables.get(name) as MockTable<T>;
251
- }
252
-
253
- /**
254
- * Reset all tables
255
- */
256
- reset(): void {
257
- for (const table of this.tables.values()) {
258
- table.reset();
259
- }
260
- }
261
-
262
- /**
263
- * Clear all data but keep mock tracking
264
- */
265
- clear(): void {
266
- for (const table of this.tables.values()) {
267
- table.clear();
268
- }
269
- }
270
-
271
- /**
272
- * Transaction mock
273
- */
274
- transaction = createMockFn<Promise<any>>().mockImplementation(async (callback: (trx: MockDatabase) => Promise<any>) => {
275
- return callback(this);
276
- });
277
- }
278
-
279
- /**
280
- * Mock HTTP fetch with pattern matching
281
- */
282
- export interface MockRoute {
283
- method: string;
284
- pattern: RegExp | string;
285
- handler: (url: string, options?: RequestInit) => Promise<MockResponse> | MockResponse;
286
- }
287
-
288
- export interface MockResponse {
289
- status: number;
290
- statusText?: string;
291
- headers?: Record<string, string>;
292
- body?: any;
293
- }
294
-
295
- export class MockFetch {
296
- private routes: MockRoute[] = [];
297
- private calls: Array<{ url: string; options?: RequestInit }> = [];
298
- private originalFetch?: typeof fetch;
299
-
300
- /**
301
- * Register a mock route
302
- */
303
- mock(pattern: string | RegExp, method: string = 'GET'): MockRouteBuilder {
304
- return new MockRouteBuilder(this, pattern, method);
305
- }
306
-
307
- /**
308
- * Register GET mock
309
- */
310
- get(pattern: string | RegExp): MockRouteBuilder {
311
- return this.mock(pattern, 'GET');
312
- }
313
-
314
- /**
315
- * Register POST mock
316
- */
317
- post(pattern: string | RegExp): MockRouteBuilder {
318
- return this.mock(pattern, 'POST');
319
- }
320
-
321
- /**
322
- * Register PUT mock
323
- */
324
- put(pattern: string | RegExp): MockRouteBuilder {
325
- return this.mock(pattern, 'PUT');
326
- }
327
-
328
- /**
329
- * Register DELETE mock
330
- */
331
- delete(pattern: string | RegExp): MockRouteBuilder {
332
- return this.mock(pattern, 'DELETE');
333
- }
334
-
335
- /**
336
- * Add a route handler
337
- */
338
- addRoute(route: MockRoute): void {
339
- this.routes.push(route);
340
- }
341
-
342
- /**
343
- * Install mock fetch globally
344
- */
345
- install(): void {
346
- this.originalFetch = globalThis.fetch;
347
- globalThis.fetch = this.createFetch();
348
- }
349
-
350
- /**
351
- * Restore original fetch
352
- */
353
- restore(): void {
354
- if (this.originalFetch) {
355
- globalThis.fetch = this.originalFetch;
356
- this.originalFetch = undefined;
357
- }
358
- }
359
-
360
- /**
361
- * Get all calls made
362
- */
363
- getCalls(): Array<{ url: string; options?: RequestInit }> {
364
- return [...this.calls];
365
- }
366
-
367
- /**
368
- * Check if a URL was called
369
- */
370
- wasCalled(pattern: string | RegExp): boolean {
371
- return this.calls.some(call => {
372
- if (typeof pattern === 'string') {
373
- return call.url.includes(pattern);
374
- }
375
- return pattern.test(call.url);
376
- });
377
- }
378
-
379
- /**
380
- * Clear all routes and calls
381
- */
382
- reset(): void {
383
- this.routes = [];
384
- this.calls = [];
385
- }
386
-
387
- /**
388
- * Create the mock fetch function
389
- */
390
- private createFetch(): typeof fetch {
391
- return async (input: string | URL | Request, init?: RequestInit): Promise<Response> => {
392
- const url = typeof input === 'string' ? input : input.toString();
393
- const method = init?.method ?? 'GET';
394
-
395
- this.calls.push({ url, options: init });
396
-
397
- // Find matching route
398
- for (const route of this.routes) {
399
- if (route.method.toUpperCase() !== method.toUpperCase()) continue;
400
-
401
- const matches = typeof route.pattern === 'string'
402
- ? url.includes(route.pattern)
403
- : route.pattern.test(url);
404
-
405
- if (matches) {
406
- const mockResponse = await route.handler(url, init);
407
- return this.createResponse(mockResponse);
408
- }
409
- }
410
-
411
- // No match found - throw error or return 404
412
- throw new Error(`No mock found for ${method} ${url}`);
413
- };
414
- }
415
-
416
- private createResponse(mock: MockResponse): Response {
417
- const body = typeof mock.body === 'string' ? mock.body : JSON.stringify(mock.body);
418
- return new Response(body, {
419
- status: mock.status,
420
- statusText: mock.statusText ?? 'OK',
421
- headers: new Headers(mock.headers ?? { 'Content-Type': 'application/json' })
422
- });
423
- }
424
- }
425
-
426
- class MockRouteBuilder {
427
- private parent: MockFetch;
428
- private pattern: string | RegExp;
429
- private method: string;
430
-
431
- constructor(parent: MockFetch, pattern: string | RegExp, method: string) {
432
- this.parent = parent;
433
- this.pattern = pattern;
434
- this.method = method;
435
- }
436
-
437
- /**
438
- * Reply with static response
439
- */
440
- reply(status: number, body?: any, headers?: Record<string, string>): MockFetch {
441
- this.parent.addRoute({
442
- method: this.method,
443
- pattern: this.pattern,
444
- handler: () => ({ status, body, headers })
445
- });
446
- return this.parent;
447
- }
448
-
449
- /**
450
- * Reply with dynamic handler
451
- */
452
- replyWith(handler: (url: string, options?: RequestInit) => Promise<MockResponse> | MockResponse): MockFetch {
453
- this.parent.addRoute({
454
- method: this.method,
455
- pattern: this.pattern,
456
- handler
457
- });
458
- return this.parent;
459
- }
460
-
461
- /**
462
- * Simulate network error
463
- */
464
- networkError(message: string = 'Network error'): MockFetch {
465
- this.parent.addRoute({
466
- method: this.method,
467
- pattern: this.pattern,
468
- handler: () => { throw new Error(message); }
469
- });
470
- return this.parent;
471
- }
472
-
473
- /**
474
- * Simulate timeout
475
- */
476
- timeout(ms: number = 5000): MockFetch {
477
- this.parent.addRoute({
478
- method: this.method,
479
- pattern: this.pattern,
480
- handler: async () => {
481
- await new Promise(resolve => setTimeout(resolve, ms));
482
- throw new Error('Request timeout');
483
- }
484
- });
485
- return this.parent;
486
- }
487
- }
488
-
489
- /**
490
- * Mock timer utilities
491
- */
492
- export class MockTimers {
493
- private originalSetTimeout?: typeof setTimeout;
494
- private originalSetInterval?: typeof setInterval;
495
- private originalClearTimeout?: typeof clearTimeout;
496
- private originalClearInterval?: typeof clearInterval;
497
- private originalDateNow?: typeof Date.now;
498
- private currentTime: number = 0;
499
- private timers: Map<number, { callback: () => void; time: number; interval?: number }> = new Map();
500
- private nextId = 1;
501
-
502
- /**
503
- * Install mock timers
504
- */
505
- install(startTime: number = Date.now()): void {
506
- this.currentTime = startTime;
507
- this.originalSetTimeout = globalThis.setTimeout;
508
- this.originalSetInterval = globalThis.setInterval;
509
- this.originalClearTimeout = globalThis.clearTimeout;
510
- this.originalClearInterval = globalThis.clearInterval;
511
- this.originalDateNow = Date.now;
512
-
513
- (globalThis as any).setTimeout = (callback: () => void, delay: number = 0) => {
514
- const id = this.nextId++;
515
- this.timers.set(id, { callback, time: this.currentTime + delay });
516
- return id;
517
- };
518
-
519
- (globalThis as any).setInterval = (callback: () => void, delay: number) => {
520
- const id = this.nextId++;
521
- this.timers.set(id, { callback, time: this.currentTime + delay, interval: delay });
522
- return id;
523
- };
524
-
525
- (globalThis as any).clearTimeout = (id: number) => {
526
- this.timers.delete(id);
527
- };
528
-
529
- (globalThis as any).clearInterval = (id: number) => {
530
- this.timers.delete(id);
531
- };
532
-
533
- Date.now = () => this.currentTime;
534
- }
535
-
536
- /**
537
- * Advance time and run pending timers
538
- */
539
- async tick(ms: number): Promise<void> {
540
- const targetTime = this.currentTime + ms;
541
-
542
- while (this.currentTime < targetTime) {
543
- // Find next timer
544
- let nextTimer: { id: number; entry: { callback: () => void; time: number; interval?: number } } | undefined;
545
-
546
- for (const [id, entry] of this.timers.entries()) {
547
- if (entry.time <= targetTime) {
548
- if (!nextTimer || entry.time < nextTimer.entry.time) {
549
- nextTimer = { id, entry };
550
- }
551
- }
552
- }
553
-
554
- if (!nextTimer || nextTimer.entry.time > targetTime) {
555
- this.currentTime = targetTime;
556
- break;
557
- }
558
-
559
- this.currentTime = nextTimer.entry.time;
560
- const { id, entry } = nextTimer;
561
-
562
- if (entry.interval) {
563
- // Reschedule interval
564
- entry.time = this.currentTime + entry.interval;
565
- } else {
566
- this.timers.delete(id);
567
- }
568
-
569
- entry.callback();
570
- }
571
- }
572
-
573
- /**
574
- * Run all pending timers
575
- */
576
- async runAll(): Promise<void> {
577
- let iterations = 0;
578
- const maxIterations = 1000;
579
-
580
- while (this.timers.size > 0 && iterations < maxIterations) {
581
- const nextTime = Math.min(...Array.from(this.timers.values()).map(t => t.time));
582
- await this.tick(nextTime - this.currentTime + 1);
583
- iterations++;
584
- }
585
- }
586
-
587
- /**
588
- * Get current mocked time
589
- */
590
- now(): number {
591
- return this.currentTime;
592
- }
593
-
594
- /**
595
- * Set current time
596
- */
597
- setTime(time: number): void {
598
- this.currentTime = time;
599
- }
600
-
601
- /**
602
- * Restore original timers
603
- */
604
- restore(): void {
605
- if (this.originalSetTimeout) globalThis.setTimeout = this.originalSetTimeout;
606
- if (this.originalSetInterval) globalThis.setInterval = this.originalSetInterval;
607
- if (this.originalClearTimeout) globalThis.clearTimeout = this.originalClearTimeout;
608
- if (this.originalClearInterval) globalThis.clearInterval = this.originalClearInterval;
609
- if (this.originalDateNow) Date.now = this.originalDateNow;
610
- this.timers.clear();
611
- }
612
- }
613
-
614
- /**
615
- * Event spy for testing event emitters
616
- */
617
- export class EventSpy {
618
- private events: Map<string, any[][]> = new Map();
619
- private emitter: EventEmitter;
620
-
621
- constructor(emitter: EventEmitter) {
622
- this.emitter = emitter;
623
- }
624
-
625
- /**
626
- * Start spying on an event
627
- */
628
- on(event: string): this {
629
- this.events.set(event, []);
630
- this.emitter.on(event, (...args: any[]) => {
631
- this.events.get(event)?.push(args);
632
- });
633
- return this;
634
- }
635
-
636
- /**
637
- * Get calls for an event
638
- */
639
- getCalls(event: string): any[][] {
640
- return this.events.get(event) ?? [];
641
- }
642
-
643
- /**
644
- * Check if event was emitted
645
- */
646
- wasEmitted(event: string): boolean {
647
- return (this.events.get(event)?.length ?? 0) > 0;
648
- }
649
-
650
- /**
651
- * Get count of event emissions
652
- */
653
- count(event: string): number {
654
- return this.events.get(event)?.length ?? 0;
655
- }
656
-
657
- /**
658
- * Clear all tracked events
659
- */
660
- clear(): void {
661
- for (const calls of this.events.values()) {
662
- calls.length = 0;
663
- }
664
- }
665
- }
666
-
667
- // Export convenience singleton
668
- export const mockDb = new MockDatabase();
669
- export const mockFetch = new MockFetch();
670
- export const mockTimers = new MockTimers();
package/src/cli/bin.ts DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { CLI } from './cli';
4
-
5
- const cli = new CLI();
6
- cli.run(process.argv.slice(2)).catch((error) => {
7
- console.error('Fatal error:', error);
8
- process.exit(1);
9
- });