@engjts/nexus 0.1.8 → 0.1.10

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 (221) hide show
  1. package/dist/advanced/playground/playground.js.map +1 -1
  2. package/dist/advanced/static/generateDirectoryListing.d.ts +1 -1
  3. package/dist/advanced/static/generateDirectoryListing.d.ts.map +1 -1
  4. package/dist/advanced/static/generateDirectoryListing.js +12 -6
  5. package/dist/advanced/static/generateDirectoryListing.js.map +1 -1
  6. package/dist/advanced/static/index.d.ts +2 -0
  7. package/dist/advanced/static/index.d.ts.map +1 -1
  8. package/dist/advanced/static/index.js +4 -1
  9. package/dist/advanced/static/index.js.map +1 -1
  10. package/dist/advanced/static/serveStatic.d.ts.map +1 -1
  11. package/dist/advanced/static/serveStatic.js +7 -1
  12. package/dist/advanced/static/serveStatic.js.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -1
  16. package/dist/index.js.map +1 -1
  17. package/package.json +1 -1
  18. package/BENCHMARK_REPORT.md +0 -343
  19. package/documentation/01-getting-started.md +0 -240
  20. package/documentation/02-context.md +0 -335
  21. package/documentation/03-routing.md +0 -397
  22. package/documentation/04-middleware.md +0 -483
  23. package/documentation/05-validation.md +0 -514
  24. package/documentation/06-error-handling.md +0 -465
  25. package/documentation/07-performance.md +0 -364
  26. package/documentation/08-adapters.md +0 -470
  27. package/documentation/09-api-reference.md +0 -548
  28. package/documentation/10-examples.md +0 -582
  29. package/documentation/11-deployment.md +0 -477
  30. package/documentation/12-sentry.md +0 -620
  31. package/documentation/13-sentry-data-storage.md +0 -996
  32. package/documentation/14-sentry-data-reference.md +0 -457
  33. package/documentation/15-sentry-summary.md +0 -409
  34. package/documentation/16-alerts-system.md +0 -745
  35. package/documentation/17-alert-adapters.md +0 -696
  36. package/documentation/18-alerts-implementation-summary.md +0 -385
  37. package/documentation/19-class-based-routing.md +0 -840
  38. package/documentation/20-websocket-realtime.md +0 -813
  39. package/documentation/21-cache-system.md +0 -510
  40. package/documentation/22-job-queue.md +0 -772
  41. package/documentation/23-sentry-plugin.md +0 -551
  42. package/documentation/24-testing-utilities.md +0 -1287
  43. package/documentation/25-api-versioning.md +0 -533
  44. package/documentation/26-context-store.md +0 -607
  45. package/documentation/27-dependency-injection.md +0 -329
  46. package/documentation/28-lifecycle-hooks.md +0 -521
  47. package/documentation/29-package-structure.md +0 -196
  48. package/documentation/30-plugin-system.md +0 -414
  49. package/documentation/31-jwt-authentication.md +0 -597
  50. package/documentation/32-cli.md +0 -268
  51. package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
  52. package/documentation/ALERTS-INDEX.md +0 -330
  53. package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
  54. package/documentation/README.md +0 -178
  55. package/documentation/index.html +0 -34
  56. package/modern_framework_paper.md +0 -1870
  57. package/public/css/style.css +0 -87
  58. package/public/index.html +0 -34
  59. package/public/js/app.js +0 -27
  60. package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
  61. package/src/advanced/cache/MultiTierCache.ts +0 -194
  62. package/src/advanced/cache/RedisCacheStore.ts +0 -341
  63. package/src/advanced/cache/index.ts +0 -5
  64. package/src/advanced/cache/types.ts +0 -40
  65. package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
  66. package/src/advanced/graphql/index.ts +0 -22
  67. package/src/advanced/graphql/server.ts +0 -252
  68. package/src/advanced/graphql/types.ts +0 -42
  69. package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
  70. package/src/advanced/jobs/JobQueue.ts +0 -556
  71. package/src/advanced/jobs/RedisQueueStore.ts +0 -367
  72. package/src/advanced/jobs/index.ts +0 -5
  73. package/src/advanced/jobs/types.ts +0 -70
  74. package/src/advanced/observability/APMManager.ts +0 -163
  75. package/src/advanced/observability/AlertManager.ts +0 -109
  76. package/src/advanced/observability/MetricRegistry.ts +0 -151
  77. package/src/advanced/observability/ObservabilityCenter.ts +0 -304
  78. package/src/advanced/observability/StructuredLogger.ts +0 -154
  79. package/src/advanced/observability/TracingManager.ts +0 -117
  80. package/src/advanced/observability/adapters.ts +0 -304
  81. package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
  82. package/src/advanced/observability/index.ts +0 -11
  83. package/src/advanced/observability/types.ts +0 -174
  84. package/src/advanced/playground/extractPathParams.ts +0 -6
  85. package/src/advanced/playground/generateFieldExample.ts +0 -31
  86. package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1956
  87. package/src/advanced/playground/generateSummary.ts +0 -19
  88. package/src/advanced/playground/getTagFromPath.ts +0 -9
  89. package/src/advanced/playground/index.ts +0 -8
  90. package/src/advanced/playground/playground.ts +0 -250
  91. package/src/advanced/playground/types.ts +0 -49
  92. package/src/advanced/playground/zodToExample.ts +0 -16
  93. package/src/advanced/playground/zodToParams.ts +0 -15
  94. package/src/advanced/postman/buildAuth.ts +0 -31
  95. package/src/advanced/postman/buildBody.ts +0 -15
  96. package/src/advanced/postman/buildQueryParams.ts +0 -27
  97. package/src/advanced/postman/buildRequestItem.ts +0 -36
  98. package/src/advanced/postman/buildResponses.ts +0 -11
  99. package/src/advanced/postman/buildUrl.ts +0 -33
  100. package/src/advanced/postman/capitalize.ts +0 -4
  101. package/src/advanced/postman/generateCollection.ts +0 -59
  102. package/src/advanced/postman/generateEnvironment.ts +0 -34
  103. package/src/advanced/postman/generateExampleFromZod.ts +0 -21
  104. package/src/advanced/postman/generateFieldExample.ts +0 -45
  105. package/src/advanced/postman/generateName.ts +0 -20
  106. package/src/advanced/postman/generateUUID.ts +0 -11
  107. package/src/advanced/postman/getTagFromPath.ts +0 -10
  108. package/src/advanced/postman/index.ts +0 -28
  109. package/src/advanced/postman/postman.ts +0 -156
  110. package/src/advanced/postman/slugify.ts +0 -7
  111. package/src/advanced/postman/types.ts +0 -140
  112. package/src/advanced/realtime/index.ts +0 -18
  113. package/src/advanced/realtime/websocket.ts +0 -231
  114. package/src/advanced/sentry/index.ts +0 -1236
  115. package/src/advanced/sentry/types.ts +0 -355
  116. package/src/advanced/static/generateDirectoryListing.ts +0 -47
  117. package/src/advanced/static/generateETag.ts +0 -7
  118. package/src/advanced/static/getMimeType.ts +0 -9
  119. package/src/advanced/static/index.ts +0 -32
  120. package/src/advanced/static/isSafePath.ts +0 -13
  121. package/src/advanced/static/publicDir.ts +0 -21
  122. package/src/advanced/static/serveStatic.ts +0 -225
  123. package/src/advanced/static/spa.ts +0 -24
  124. package/src/advanced/static/types.ts +0 -159
  125. package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
  126. package/src/advanced/swagger/buildOperation.ts +0 -61
  127. package/src/advanced/swagger/buildParameters.ts +0 -61
  128. package/src/advanced/swagger/buildRequestBody.ts +0 -21
  129. package/src/advanced/swagger/buildResponses.ts +0 -54
  130. package/src/advanced/swagger/capitalize.ts +0 -5
  131. package/src/advanced/swagger/convertPath.ts +0 -9
  132. package/src/advanced/swagger/createSwagger.ts +0 -12
  133. package/src/advanced/swagger/generateOperationId.ts +0 -21
  134. package/src/advanced/swagger/generateSpec.ts +0 -105
  135. package/src/advanced/swagger/generateSummary.ts +0 -24
  136. package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
  137. package/src/advanced/swagger/generateThemeCss.ts +0 -53
  138. package/src/advanced/swagger/index.ts +0 -25
  139. package/src/advanced/swagger/swagger.ts +0 -237
  140. package/src/advanced/swagger/types.ts +0 -206
  141. package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
  142. package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
  143. package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
  144. package/src/advanced/testing/factory.ts +0 -509
  145. package/src/advanced/testing/harness.ts +0 -612
  146. package/src/advanced/testing/index.ts +0 -430
  147. package/src/advanced/testing/load-test.ts +0 -618
  148. package/src/advanced/testing/mock-server.ts +0 -498
  149. package/src/advanced/testing/mock.ts +0 -670
  150. package/src/cli/bin.ts +0 -9
  151. package/src/cli/cli.ts +0 -158
  152. package/src/cli/commands/add.ts +0 -178
  153. package/src/cli/commands/build.ts +0 -73
  154. package/src/cli/commands/create.ts +0 -166
  155. package/src/cli/commands/dev.ts +0 -85
  156. package/src/cli/commands/generate.ts +0 -99
  157. package/src/cli/commands/help.ts +0 -95
  158. package/src/cli/commands/init.ts +0 -91
  159. package/src/cli/commands/version.ts +0 -38
  160. package/src/cli/index.ts +0 -6
  161. package/src/cli/templates/generators.ts +0 -359
  162. package/src/cli/templates/index.ts +0 -680
  163. package/src/cli/utils/exec.ts +0 -52
  164. package/src/cli/utils/file-system.ts +0 -78
  165. package/src/cli/utils/logger.ts +0 -111
  166. package/src/core/adapter.ts +0 -88
  167. package/src/core/application.ts +0 -1453
  168. package/src/core/context-pool.ts +0 -79
  169. package/src/core/context.ts +0 -856
  170. package/src/core/index.ts +0 -94
  171. package/src/core/middleware.ts +0 -272
  172. package/src/core/performance/buffer-pool.ts +0 -108
  173. package/src/core/performance/middleware-optimizer.ts +0 -162
  174. package/src/core/plugin/PluginManager.ts +0 -435
  175. package/src/core/plugin/builder.ts +0 -358
  176. package/src/core/plugin/index.ts +0 -50
  177. package/src/core/plugin/types.ts +0 -214
  178. package/src/core/router/file-router.ts +0 -623
  179. package/src/core/router/index.ts +0 -260
  180. package/src/core/router/radix-tree.ts +0 -242
  181. package/src/core/serializer.ts +0 -397
  182. package/src/core/store/index.ts +0 -30
  183. package/src/core/store/registry.ts +0 -178
  184. package/src/core/store/request-store.ts +0 -240
  185. package/src/core/store/types.ts +0 -233
  186. package/src/core/types.ts +0 -616
  187. package/src/database/adapter.ts +0 -35
  188. package/src/database/adapters/index.ts +0 -1
  189. package/src/database/adapters/mysql.ts +0 -669
  190. package/src/database/database.ts +0 -70
  191. package/src/database/dialect.ts +0 -388
  192. package/src/database/index.ts +0 -12
  193. package/src/database/migrations.ts +0 -86
  194. package/src/database/optimizer.ts +0 -125
  195. package/src/database/query-builder.ts +0 -404
  196. package/src/database/realtime.ts +0 -53
  197. package/src/database/schema.ts +0 -71
  198. package/src/database/transactions.ts +0 -56
  199. package/src/database/types.ts +0 -87
  200. package/src/deployment/cluster.ts +0 -471
  201. package/src/deployment/config.ts +0 -454
  202. package/src/deployment/docker.ts +0 -599
  203. package/src/deployment/graceful-shutdown.ts +0 -373
  204. package/src/deployment/index.ts +0 -56
  205. package/src/index.ts +0 -281
  206. package/src/security/adapter.ts +0 -318
  207. package/src/security/auth/JWTPlugin.ts +0 -234
  208. package/src/security/auth/JWTProvider.ts +0 -316
  209. package/src/security/auth/adapter.ts +0 -12
  210. package/src/security/auth/jwt.ts +0 -234
  211. package/src/security/auth/middleware.ts +0 -188
  212. package/src/security/csrf.ts +0 -220
  213. package/src/security/headers.ts +0 -108
  214. package/src/security/index.ts +0 -60
  215. package/src/security/rate-limit/adapter.ts +0 -7
  216. package/src/security/rate-limit/memory.ts +0 -108
  217. package/src/security/rate-limit/middleware.ts +0 -181
  218. package/src/security/sanitization.ts +0 -75
  219. package/src/security/types.ts +0 -240
  220. package/src/security/utils.ts +0 -52
  221. 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
- });