next-api-mock 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  import { validateConfig } from '../src/configValidator'
2
- import { MockConfig, MockFunction } from '../src/types'
2
+ import { MockConfig, MockFunction, MockResponse } from '../src/types'
3
3
  import { NextApiRequest } from 'next'
4
4
  import { NextRequest } from 'next/server'
5
5
 
@@ -10,7 +10,7 @@ describe('Config Validator', () => {
10
10
  status: 200,
11
11
  data: { message: 'Test successful' },
12
12
  },
13
- '/api/function': ((req: NextApiRequest | NextRequest) => ({
13
+ '/api/function': (async (req: NextApiRequest | NextRequest) => ({
14
14
  status: 200,
15
15
  data: { method: req.method },
16
16
  })) as MockFunction,
@@ -58,7 +58,7 @@ describe('Config Validator', () => {
58
58
 
59
59
  it('should pass for valid function configurations', () => {
60
60
  const validConfig: MockConfig = {
61
- '/api/function': ((req: NextApiRequest | NextRequest) => ({
61
+ '/api/function': (async (req: NextApiRequest | NextRequest): Promise<MockResponse> => ({
62
62
  status: 200,
63
63
  data: { method: req.method },
64
64
  })) as MockFunction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-api-mock",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A production-ready, scalable tool for mocking API and GraphQL responses in Next.js applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/core.ts ADDED
@@ -0,0 +1,380 @@
1
+ import { EventEmitter } from 'events'
2
+ import * as winston from 'winston'
3
+ import config from 'config'
4
+ import { parse } from 'url'
5
+ import { match } from 'path-to-regexp'
6
+ import { isAppRouter, isNextJs12, isNextJs13, isNextJs14, isNextJs15, getNextVersion } from './utils/versionCheck'
7
+ import {
8
+ MockResponse,
9
+ MockConfig,
10
+ RequestLogger,
11
+ MockInterceptor,
12
+ MockOptions,
13
+ MiddlewareFunction,
14
+ MockFunction,
15
+ AnyRequest,
16
+ AnyResponse,
17
+ isNextApiRequest as typeGuardIsNextApiRequest,
18
+ isNextRequest
19
+ } from './types'
20
+ import { validateConfig } from './configValidator'
21
+ import { applyMiddleware } from './middleware'
22
+ import { cacheResponse, getCachedResponse, clearCache } from './cache'
23
+ import { configureServerMocks, resetServerMocks, mockServerAction, createServerComponentMock } from './serverMock'
24
+ import { initializePlugins, registerPlugin } from './plugins'
25
+ import { setSecureHeaders as localSetSecureHeaders } from './security'
26
+ import { collectMetrics, reportMetrics } from './monitoring'
27
+ import { createRequestValidator } from './validation'
28
+ import { createRateLimiter } from './rateLimit'
29
+ import { createMockDatabase } from './mockDatabase'
30
+ import { createGraphQLMockHandler } from './graphqlMock'
31
+
32
+ import type { NextApiRequest, NextApiResponse } from 'next'
33
+ import { NextRequest, NextResponse } from 'next/server'
34
+
35
+ const logger = winston.createLogger({
36
+ level: config.get<string>('logLevel') || 'info',
37
+ format: winston.format.json(),
38
+ defaultMeta: { service: 'mock-library' },
39
+ transports: [
40
+ new winston.transports.Console(),
41
+ new winston.transports.File({ filename: 'error.log', level: 'error' }),
42
+ new winston.transports.File({ filename: 'combined.log' }),
43
+ ],
44
+ })
45
+
46
+ const defaultConfig: MockConfig = {}
47
+ const defaultOptions: MockOptions = {
48
+ enableLogging: false,
49
+ cacheTimeout: 5 * 60 * 1000, // 5 minutes
50
+ defaultDelay: 0,
51
+ errorRate: 0,
52
+ }
53
+
54
+ let mockConfig: MockConfig = { ...defaultConfig }
55
+ let mockOptions: MockOptions = { ...defaultOptions }
56
+ let globalDelay = 0
57
+ let requestLogger: RequestLogger | null = null
58
+ let mockInterceptor: MockInterceptor | null = null
59
+ const eventEmitter = new EventEmitter()
60
+ const middlewarePipeline: MiddlewareFunction[] = []
61
+
62
+ export async function configureMocksAsync(configPromise: Promise<MockConfig>, options?: Partial<MockOptions>): Promise<void> {
63
+ try {
64
+ const loadedConfig = await configPromise
65
+ configureMocks(loadedConfig, options)
66
+ } catch (error) {
67
+ logger.error('Error loading configuration:', error)
68
+ throw new Error('Failed to load mock configuration')
69
+ }
70
+ }
71
+
72
+ export function configureMocks(loadedConfig: MockConfig, options?: Partial<MockOptions>): void {
73
+ try {
74
+ validateConfig(loadedConfig)
75
+ mockConfig = { ...defaultConfig, ...loadedConfig }
76
+ mockOptions = { ...defaultOptions, ...options }
77
+ if (mockOptions.enableLogging) {
78
+ setRequestLogger(defaultLogger)
79
+ }
80
+ if (mockOptions.defaultDelay) {
81
+ setGlobalDelay(mockOptions.defaultDelay)
82
+ }
83
+ initializePlugins(mockConfig)
84
+ } catch (error) {
85
+ logger.error('Error configuring mocks:', error)
86
+ throw new Error('Failed to configure mocks')
87
+ }
88
+ }
89
+
90
+ export function resetMocks(): void {
91
+ mockConfig = { ...defaultConfig }
92
+ mockOptions = { ...defaultOptions }
93
+ globalDelay = 0
94
+ requestLogger = null
95
+ mockInterceptor = null
96
+ clearCache()
97
+ resetServerMocks()
98
+ }
99
+
100
+ export function setGlobalDelay(delay: number): void {
101
+ globalDelay = delay
102
+ }
103
+
104
+ export function setRequestLogger(logger: RequestLogger): void {
105
+ requestLogger = logger
106
+ }
107
+
108
+ export function setMockInterceptor(interceptor: MockInterceptor): void {
109
+ mockInterceptor = interceptor
110
+ }
111
+
112
+ export function onMockResponse(listener: (path: string, response: MockResponse<unknown>) => void): () => void {
113
+ eventEmitter.on('mockResponse', listener)
114
+ return () => eventEmitter.off('mockResponse', listener)
115
+ }
116
+
117
+ export function addMiddleware(middleware: MiddlewareFunction): void {
118
+ middlewarePipeline.push(middleware)
119
+ }
120
+
121
+ function defaultLogger(req: AnyRequest, res: AnyResponse): void {
122
+ let status: number
123
+ if (isNextApiResponse(res)) {
124
+ status = res.statusCode
125
+ } else if ('status' in res) {
126
+ status = res.status
127
+ } else {
128
+ status = 200 // Default status if not found
129
+ }
130
+ logger.info(`${req.method} ${req.url} - Status: ${status}`)
131
+ }
132
+
133
+ function shouldSimulateError(): boolean {
134
+ return Math.random() < mockOptions.errorRate
135
+ }
136
+
137
+ const limiter = createRateLimiter({
138
+ windowMs: 15 * 60 * 1000, // 15 minutes
139
+ max: 100 // limit each IP to 100 requests per windowMs
140
+ })
141
+
142
+ export function createMockHandler(path: string) {
143
+ if (isAppRouter) {
144
+ return createAppRouterHandler(path)
145
+ } else {
146
+ return createPagesApiHandler(path)
147
+ }
148
+ }
149
+
150
+ function createAppRouterHandler(path: string) {
151
+ return async (req: NextRequest, context: { params: any }): Promise<NextResponse> => {
152
+ try {
153
+ if (isNextRequest(req)) {
154
+ // Handle NextRequest (App Router)
155
+ const headers = new Headers(req.headers)
156
+ headers.set('X-Secure-Header', 'true')
157
+ const secureReq = new NextRequest(req.url, {
158
+ headers,
159
+ method: req.method,
160
+ body: req.body,
161
+ cache: req.cache,
162
+ credentials: req.credentials,
163
+ integrity: req.integrity,
164
+ keepalive: req.keepalive,
165
+ mode: req.mode,
166
+ redirect: req.redirect,
167
+ referrer: req.referrer,
168
+ referrerPolicy: req.referrerPolicy,
169
+ signal: req.signal,
170
+ })
171
+
172
+ // Process the request with the new headers
173
+ return handleRequest(secureReq, path)
174
+ } else {
175
+ throw new Error('Unexpected request type in App Router handler')
176
+ }
177
+ } catch (error) {
178
+ logger.error('Error in App Router handler:', error)
179
+ return NextResponse.json({ error: 'Internal server error', details: (error as Error).message }, { status: 500 })
180
+ }
181
+ }
182
+ }
183
+
184
+ function createPagesApiHandler(path: string) {
185
+ return limiter(async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
186
+ try {
187
+ if (typeGuardIsNextApiRequest(req)) {
188
+ localSetSecureHeaders(res)
189
+ await handleApiRequest(req, res, path)
190
+ } else {
191
+ throw new Error('Unexpected request type in Pages API handler')
192
+ }
193
+ } catch (error) {
194
+ logger.error('Error in Pages API handler:', error)
195
+ res.status(500).json({ error: 'Internal server error', details: (error as Error).message })
196
+ }
197
+ })
198
+ }
199
+
200
+ async function handleRequest(req: NextRequest, path: string): Promise<NextResponse> {
201
+ if (shouldSimulateError()) {
202
+ throw new Error('Simulated server error')
203
+ }
204
+
205
+ for (const middleware of middlewarePipeline) {
206
+ await middleware(req as unknown as AnyRequest, NextResponse.next() as unknown as AnyResponse)
207
+ }
208
+
209
+ const cacheKey = `${req.method}:${path}:${JSON.stringify(Object.fromEntries(req.nextUrl.searchParams))}:${await req.text()}`
210
+ const cachedResponse = getCachedResponse(cacheKey)
211
+
212
+ if (cachedResponse) {
213
+ return NextResponse.json(cachedResponse.data, { status: cachedResponse.status || 200 })
214
+ }
215
+
216
+ const { pathname } = new URL(req.url)
217
+ const matchFn = match(path, { decode: decodeURIComponent })
218
+
219
+ if (pathname === null) {
220
+ return NextResponse.json({ error: 'Invalid URL' }, { status: 400 })
221
+ }
222
+
223
+ const matched = matchFn(pathname)
224
+
225
+ if (!matched) {
226
+ return NextResponse.json({ error: 'Not found' }, { status: 404 })
227
+ }
228
+
229
+ let mockResponse: MockResponse<unknown>
230
+ const mockConfigItem = mockConfig[path]
231
+
232
+ if (typeof mockConfigItem === 'function') {
233
+ mockResponse = await (mockConfigItem as MockFunction)(req as unknown as AnyRequest)
234
+ } else {
235
+ mockResponse = mockConfigItem as MockResponse<unknown>
236
+ }
237
+
238
+ if (!mockResponse) {
239
+ return NextResponse.json({ error: 'Not found' }, { status: 404 })
240
+ }
241
+
242
+ mockResponse = await applyMiddleware(req as unknown as AnyRequest, mockResponse, mockInterceptor)
243
+
244
+ if (requestLogger) {
245
+ requestLogger(req as unknown as AnyRequest, NextResponse.json({}, { status: mockResponse.status || 200 }) as unknown as AnyResponse)
246
+ }
247
+
248
+ const delay = mockResponse.delay || globalDelay
249
+ if (delay) {
250
+ await new Promise(resolve => setTimeout(resolve, delay))
251
+ }
252
+
253
+ eventEmitter.emit('mockResponse', path, mockResponse)
254
+ collectMetrics(req as unknown as AnyRequest, NextResponse.json({}, { status: mockResponse.status || 200 }) as unknown as AnyResponse, mockResponse)
255
+
256
+ cacheResponse(cacheKey, mockResponse, mockOptions.cacheTimeout)
257
+
258
+ return NextResponse.json(mockResponse.data, {
259
+ status: mockResponse.status || 200,
260
+ headers: mockResponse.headers,
261
+ })
262
+ }
263
+
264
+ async function handleApiRequest(req: NextApiRequest, res: NextApiResponse, path: string): Promise<void> {
265
+ if (shouldSimulateError()) {
266
+ throw new Error('Simulated server error')
267
+ }
268
+
269
+ for (const middleware of middlewarePipeline) {
270
+ await middleware(req, res)
271
+ }
272
+
273
+ const cacheKey = `${req.method}:${path}:${JSON.stringify(req.query)}:${JSON.stringify(req.body)}`
274
+ const cachedResponse = getCachedResponse(cacheKey)
275
+
276
+ if (cachedResponse) {
277
+ res.status(cachedResponse.status || 200).json(cachedResponse.data)
278
+ return
279
+ }
280
+
281
+ const { pathname } = parse(req.url || '', true)
282
+ const matchFn = match(path, { decode: decodeURIComponent })
283
+
284
+ if (pathname === null) {
285
+ res.status(400).json({ error: 'Invalid URL' })
286
+ return
287
+ }
288
+
289
+ const matched = matchFn(pathname)
290
+
291
+ if (!matched) {
292
+ res.status(404).json({ error: 'Not found' })
293
+ return
294
+ }
295
+
296
+ let mockResponse: MockResponse<unknown>
297
+ const mockConfigItem = mockConfig[path]
298
+
299
+ if (typeof mockConfigItem === 'function') {
300
+ mockResponse = await (mockConfigItem as MockFunction)(req)
301
+ } else {
302
+ mockResponse = mockConfigItem as MockResponse<unknown>
303
+ }
304
+
305
+ if (!mockResponse) {
306
+ res.status(404).json({ error: 'Not found' })
307
+ return
308
+ }
309
+
310
+ mockResponse = await applyMiddleware(req, mockResponse, mockInterceptor)
311
+
312
+ if (requestLogger) {
313
+ requestLogger(req, res)
314
+ }
315
+
316
+ const delay = mockResponse.delay || globalDelay
317
+ if (delay) {
318
+ await new Promise(resolve => setTimeout(resolve, delay))
319
+ }
320
+
321
+ if (mockResponse.headers) {
322
+ Object.entries(mockResponse.headers).forEach(([key, value]) => {
323
+ res.setHeader(key, value as string)
324
+ })
325
+ }
326
+
327
+ eventEmitter.emit('mockResponse', path, mockResponse)
328
+ collectMetrics(req, res, mockResponse)
329
+
330
+ cacheResponse(cacheKey, mockResponse, mockOptions.cacheTimeout)
331
+
332
+ res.status(mockResponse.status || 200).json(mockResponse.data)
333
+ }
334
+
335
+ function isNextApiRequest(req: AnyRequest): req is NextApiRequest {
336
+ return typeGuardIsNextApiRequest(req)
337
+ }
338
+
339
+ function isNextApiResponse(res: AnyResponse): res is NextApiResponse {
340
+ return 'status' in res && typeof res.status === 'function'
341
+ }
342
+
343
+ function setSecureHeaders(reqOrRes: NextRequest | NextApiResponse): NextRequest | void {
344
+ if (reqOrRes instanceof NextRequest) {
345
+ // For NextRequest, we can't set headers directly, but we can create a new request with added headers
346
+ const headers = new Headers(reqOrRes.headers)
347
+ headers.set('X-Secure-Header', 'true')
348
+ return new NextRequest(reqOrRes.url, {
349
+ headers,
350
+ method: reqOrRes.method,
351
+ body: reqOrRes.body,
352
+ cache: reqOrRes.cache,
353
+ credentials: reqOrRes.credentials,
354
+ integrity: reqOrRes.integrity,
355
+ keepalive: reqOrRes.keepalive,
356
+ mode: reqOrRes.mode,
357
+ redirect: reqOrRes.redirect,
358
+ referrer: reqOrRes.referrer,
359
+ referrerPolicy: reqOrRes.referrerPolicy,
360
+ signal: reqOrRes.signal,
361
+ })
362
+ } else {
363
+ // Handle NextApiResponse (Pages Router)
364
+ localSetSecureHeaders(reqOrRes)
365
+ }
366
+ }
367
+
368
+ export {
369
+ createMockDatabase,
370
+ createGraphQLMockHandler,
371
+ configureServerMocks,
372
+ resetServerMocks,
373
+ mockServerAction,
374
+ createServerComponentMock,
375
+ registerPlugin,
376
+ reportMetrics,
377
+ createRequestValidator,
378
+ setSecureHeaders
379
+ }
380
+
package/src/index.ts CHANGED
@@ -1,210 +1,47 @@
1
- import { NextApiRequest, NextApiResponse } from 'next'
2
- import { parse } from 'url'
3
- import { match } from 'path-to-regexp'
4
- import { EventEmitter } from 'events'
5
- import * as winston from 'winston'
6
- import config from 'config'
7
- import { MockResponse, MockConfig, RequestLogger, MockInterceptor, MockOptions, MiddlewareFunction, MockFunction } from './types'
8
- import { createMockDatabase } from './mockDatabase'
9
- import { createGraphQLMockHandler } from './graphqlMock'
10
- import { validateConfig } from './configValidator'
11
- import { applyMiddleware } from './middleware'
12
- import { cacheResponse, getCachedResponse, clearCache } from './cache'
13
- import { configureServerMocks, resetServerMocks, mockServerAction, createServerComponentMock } from './serverMock'
14
- import { initializePlugins, registerPlugin } from './plugins'
15
- import { setSecureHeaders } from './security'
16
- import { collectMetrics, reportMetrics } from './monitoring'
17
- import { createRequestValidator } from './validation'
18
- import { createRateLimiter } from './rateLimit'
1
+ // Core functionality
2
+ export { configureMocks, configureMocksAsync, resetMocks, setGlobalDelay, setRequestLogger, setMockInterceptor, onMockResponse, addMiddleware, createMockHandler } from './core'
19
3
 
20
- const logger = winston.createLogger({
21
- level: config.get<string>('logLevel') || 'info',
22
- format: winston.format.json(),
23
- defaultMeta: { service: 'mock-library' },
24
- transports: [
25
- new winston.transports.Console(),
26
- new winston.transports.File({ filename: 'error.log', level: 'error' }),
27
- new winston.transports.File({ filename: 'combined.log' }),
28
- ],
29
- })
4
+ // Server-side mocking
5
+ export { configureServerMocks, resetServerMocks, mockServerAction, createServerComponentMock } from './serverMock'
30
6
 
31
- const defaultConfig: MockConfig = {}
32
- const defaultOptions: MockOptions = {
33
- enableLogging: false,
34
- cacheTimeout: 5 * 60 * 1000, // 5 minutes
35
- defaultDelay: 0,
36
- errorRate: 0,
37
- }
7
+ // Database and GraphQL mocking
8
+ export { createMockDatabase } from './mockDatabase'
9
+ export { createGraphQLMockHandler } from './graphqlMock'
38
10
 
39
- let mockConfig: MockConfig = { ...defaultConfig }
40
- let mockOptions: MockOptions = { ...defaultOptions }
41
- let globalDelay = 0
42
- let requestLogger: RequestLogger | null = null
43
- let mockInterceptor: MockInterceptor | null = null
44
- const eventEmitter = new EventEmitter()
45
- const middlewarePipeline: MiddlewareFunction[] = []
11
+ // Plugins and metrics
12
+ export { registerPlugin } from './plugins'
13
+ export { reportMetrics } from './monitoring'
46
14
 
47
- export async function configureMocksAsync(configPromise: Promise<MockConfig>, options?: Partial<MockOptions>): Promise<void> {
48
- try {
49
- const loadedConfig = await configPromise
50
- configureMocks(loadedConfig, options)
51
- } catch (error) {
52
- logger.error('Error loading configuration:', error)
53
- throw new Error('Failed to load mock configuration')
54
- }
55
- }
15
+ // Validation and security
16
+ export { createRequestValidator } from './validation'
17
+ export { setSecureHeaders } from './security'
56
18
 
57
- export function configureMocks(loadedConfig: MockConfig, options?: Partial<MockOptions>): void {
58
- try {
59
- validateConfig(loadedConfig)
60
- mockConfig = { ...defaultConfig, ...loadedConfig }
61
- mockOptions = { ...defaultOptions, ...options }
62
- if (mockOptions.enableLogging) {
63
- setRequestLogger(defaultLogger)
64
- }
65
- if (mockOptions.defaultDelay) {
66
- setGlobalDelay(mockOptions.defaultDelay)
67
- }
68
- initializePlugins(mockConfig)
69
- } catch (error) {
70
- logger.error('Error configuring mocks:', error)
71
- throw new Error('Failed to configure mocks')
72
- }
73
- }
19
+ // Types
20
+ export type {
21
+ MockResponse,
22
+ MockConfig,
23
+ RequestLogger,
24
+ MockInterceptor,
25
+ MockOptions,
26
+ MiddlewareFunction,
27
+ MockFunction,
28
+ AnyRequest,
29
+ AnyResponse
30
+ } from './types'
74
31
 
75
- export function resetMocks(): void {
76
- mockConfig = { ...defaultConfig }
77
- mockOptions = { ...defaultOptions }
78
- globalDelay = 0
79
- requestLogger = null
80
- mockInterceptor = null
81
- clearCache()
82
- resetServerMocks()
83
- }
32
+ // Version check utilities
33
+ export { isAppRouter, isNextJs12, isNextJs13, isNextJs14, isNextJs15, getNextVersion } from './utils/versionCheck'
84
34
 
85
- export function setGlobalDelay(delay: number): void {
86
- globalDelay = delay
87
- }
35
+ // Config validation
36
+ export { validateConfig } from './configValidator'
88
37
 
89
- export function setRequestLogger(logger: RequestLogger): void {
90
- requestLogger = logger
91
- }
38
+ // Middleware
39
+ export { applyMiddleware } from './middleware'
92
40
 
93
- export function setMockInterceptor(interceptor: MockInterceptor): void {
94
- mockInterceptor = interceptor
95
- }
41
+ // Caching
42
+ export { cacheResponse, getCachedResponse, clearCache } from './cache'
96
43
 
97
- export function onMockResponse(listener: (path: string, response: MockResponse<unknown>) => void): () => void {
98
- eventEmitter.on('mockResponse', listener)
99
- return () => eventEmitter.off('mockResponse', listener)
100
- }
44
+ // Rate limiting
45
+ export { createRateLimiter } from './rateLimit'
101
46
 
102
- export function addMiddleware(middleware: MiddlewareFunction): void {
103
- middlewarePipeline.push(middleware)
104
- }
105
-
106
- function defaultLogger(req: NextApiRequest, res: NextApiResponse): void {
107
- logger.info(`${req.method} ${req.url} - Status: ${res.statusCode}`)
108
- }
109
-
110
- function shouldSimulateError(): boolean {
111
- return Math.random() < mockOptions.errorRate
112
- }
113
-
114
- const limiter = createRateLimiter({
115
- windowMs: 15 * 60 * 1000, // 15 minutes
116
- max: 100 // limit each IP to 100 requests per windowMs
117
- })
118
-
119
- export function createMockHandler(path: string) {
120
- return limiter(async (req: NextApiRequest, res: NextApiResponse): Promise<void> => {
121
- try {
122
- setSecureHeaders(res)
123
-
124
- if (shouldSimulateError()) {
125
- throw new Error('Simulated server error')
126
- }
127
-
128
- for (const middleware of middlewarePipeline) {
129
- await middleware(req, res)
130
- }
131
-
132
- const cacheKey = `${req.method}:${path}:${JSON.stringify(req.query)}:${JSON.stringify(req.body)}`
133
- const cachedResponse = getCachedResponse(cacheKey)
134
-
135
- if (cachedResponse) {
136
- res.status(cachedResponse.status || 200).json(cachedResponse.data)
137
- return
138
- }
139
-
140
- const { pathname } = parse(req.url || '', true)
141
- const matchFn = match(path, { decode: decodeURIComponent })
142
-
143
- if (pathname === null) {
144
- res.status(400).json({ error: 'Invalid URL' })
145
- return
146
- }
147
-
148
- const matched = matchFn(pathname)
149
-
150
- if (!matched) {
151
- res.status(404).json({ error: 'Not found' })
152
- return
153
- }
154
-
155
- let mockResponse: MockResponse<unknown>
156
- const mockConfigItem = mockConfig[path]
157
-
158
- if (typeof mockConfigItem === 'function') {
159
- mockResponse = await (mockConfigItem as MockFunction)(req)
160
- } else {
161
- mockResponse = mockConfigItem as MockResponse<unknown>
162
- }
163
-
164
- if (!mockResponse) {
165
- res.status(404).json({ error: 'Not found' })
166
- return
167
- }
168
-
169
- mockResponse = await applyMiddleware(req, mockResponse, mockInterceptor)
170
-
171
- if (requestLogger) {
172
- requestLogger(req, res)
173
- }
174
-
175
- const delay = mockResponse.delay || globalDelay
176
- if (delay) {
177
- await new Promise(resolve => setTimeout(resolve, delay))
178
- }
179
-
180
- if (mockResponse.headers) {
181
- Object.entries(mockResponse.headers).forEach(([key, value]) => {
182
- res.setHeader(key, value as string)
183
- })
184
- }
185
-
186
- eventEmitter.emit('mockResponse', path, mockResponse)
187
- collectMetrics(req, res, mockResponse)
188
-
189
- cacheResponse(cacheKey, mockResponse, mockOptions.cacheTimeout)
190
-
191
- res.status(mockResponse.status || 200).json(mockResponse.data)
192
- } catch (error) {
193
- logger.error('Error in mock handler:', error)
194
- res.status(500).json({ error: 'Internal server error', details: (error as Error).message })
195
- }
196
- })
197
- }
198
-
199
- export {
200
- createMockDatabase,
201
- createGraphQLMockHandler,
202
- configureServerMocks,
203
- resetServerMocks,
204
- mockServerAction,
205
- createServerComponentMock,
206
- registerPlugin,
207
- reportMetrics,
208
- createRequestValidator
209
- }
210
47