vite-plugin-automock 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -3
- package/dist/index.mjs.map +1 -1
- package/dist/inspector-template.html +76 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -833,10 +833,8 @@ function proxyAndCapture(req, res, options) {
|
|
|
833
833
|
let bodyStr = "";
|
|
834
834
|
req.on("data", (chunk) => bodyStr += chunk.toString());
|
|
835
835
|
req.on("end", () => sendProxyRequest(bodyStr));
|
|
836
|
-
} else if (req.readableEnded) {
|
|
837
|
-
sendProxyRequest();
|
|
838
836
|
} else {
|
|
839
|
-
|
|
837
|
+
sendProxyRequest();
|
|
840
838
|
}
|
|
841
839
|
}
|
|
842
840
|
function printServerUrls(server, urls) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/mockFileUtils.ts","../src/utils.ts","../src/inspector.ts","../src/mockBundler.ts","../src/client/interceptor.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\n\nimport { automock as createAutomockPlugin } from './middleware'\nimport { bundleMockFiles, writeMockBundle } from './mockBundler'\nimport { buildMockIndex } from './mockFileUtils'\nimport type { Plugin } from 'vite'\nimport type { AutomockPluginOptions } from './types'\nimport type { MockBundle } from './mockBundler'\n\nexport type { AutomockPluginOptions, InspectorOptions } from './types'\nexport { saveMockData, buildMockIndex, parseMockModule, writeMockFile } from './mockFileUtils'\nexport type { MockBundle, MockBundleData } from './mockBundler'\nexport { bundleMockFiles, writeMockBundle } from './mockBundler'\n\n// Client interceptor exports\nexport {\n createMockInterceptor,\n initMockInterceptor,\n initMockInterceptorForPureHttp,\n setMockEnabled,\n isMockEnabled,\n loadMockData,\n registerHttpInstance\n} from './client'\nexport type { MockInterceptorOptions, MockBundleData as ClientMockBundleData } from './client/interceptor'\n\nexport interface AutomockWithBundleOptions extends AutomockPluginOptions {\n bundleMockData?: boolean\n bundleOutputPath?: string\n}\n\nexport function automock(options: AutomockWithBundleOptions = {}): Plugin {\n const {\n bundleMockData = true,\n bundleOutputPath = 'public/mock-data.json',\n ...pluginOptions\n } = options\n\n const basePlugin = createAutomockPlugin(pluginOptions)\n\n let cachedBundle: MockBundle | null = null\n\n const ensureBundleExists = () => {\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n if (!fs.existsSync(outputPath) && cachedBundle) {\n console.log('[automock] Re-writing mock bundle...')\n writeMockBundle(cachedBundle, outputPath)\n }\n }\n\n return {\n ...basePlugin,\n name: 'vite-plugin-automock-with-bundle',\n config() {\n // Inject compile-time constant for client interceptor\n const enabled = pluginOptions.productionMock !== false\n return {\n define: {\n __AUTOMOCK_ENABLED__: JSON.stringify(enabled),\n },\n }\n },\n buildEnd: async () => {\n if (bundleMockData && pluginOptions.productionMock !== false) {\n try {\n const mockDir = pluginOptions.mockDir || path.join(process.cwd(), 'mock')\n\n if (!fs.existsSync(mockDir)) {\n console.log('[automock] Mock directory not found, skipping bundle generation')\n console.log('[automock] Using existing mock-data.json if present')\n return\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n if (mockFileMap.size === 0) {\n console.log('[automock] No mock files found, skipping bundle generation')\n return\n }\n\n cachedBundle = await bundleMockFiles({ mockDir })\n\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n writeMockBundle(cachedBundle, outputPath)\n console.log(`[automock] Mock bundle written to: ${outputPath}`)\n } catch (error) {\n console.error('[automock] Failed to bundle mock data:', error)\n }\n }\n },\n writeBundle: ensureBundleExists,\n closeBundle: ensureBundleExists,\n }\n}\n\n","import chokidar from \"chokidar\";\nimport debounce from \"lodash.debounce\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport http from \"http\";\nimport https from \"https\";\nimport type { AddressInfo } from \"net\";\n\nimport { buildMockIndex, saveMockData } from \"./mockFileUtils\";\nimport { createInspectorHandler, normalizeInspectorConfig } from \"./inspector\";\nimport {\n resolveAbsolutePath,\n getServerAddress,\n sendError,\n} from \"./utils\";\n\nimport type { Plugin } from \"vite\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { FSWatcher } from \"chokidar\";\nimport type { AutomockPluginOptions } from \"./types\";\n\nfunction serveMockResponse(\n res: ServerResponse,\n mockFilePath: string,\n mockResult: { data?: unknown; delay?: number; status?: number },\n): void {\n const { data, delay = 0, status = 200 } = mockResult;\n\n setTimeout(() => {\n const isBinaryMock = data && typeof data === \"object\" && (data as Record<string, unknown>).__binaryFile;\n\n if (isBinaryMock) {\n const binaryData = data as Record<string, unknown>;\n const binaryFilePath = mockFilePath.replace(\n /\\.js$/,\n \".\" + binaryData.__binaryFile,\n );\n\n if (!fs.existsSync(binaryFilePath)) {\n console.error(\n `[automock] Binary mock file not found: ${binaryFilePath}`,\n );\n sendError(res, \"Binary mock file not found\", 404);\n return;\n }\n\n try {\n const fileData = fs.readFileSync(binaryFilePath);\n const contentType =\n (binaryData.__contentType as string) || \"application/octet-stream\";\n res.setHeader(\"Content-Type\", contentType);\n res.setHeader(\"Content-Length\", fileData.length);\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.setHeader(\"X-Mock-Binary-File\", \"true\");\n res.statusCode = status;\n res.end(fileData);\n } catch (error) {\n console.error(\"[automock] Failed to read binary mock file:\", error);\n sendError(res, \"Failed to read binary mock file\");\n }\n } else {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n }\n }, delay);\n}\n\nfunction proxyAndCapture(\n req: IncomingMessage,\n res: ServerResponse,\n options: {\n proxyBaseUrl: string;\n pathRewrite: (p: string) => string;\n shouldSave: boolean;\n method: string;\n pathname: string;\n mockDir: string;\n onMockSaved: () => void;\n },\n): void {\n const { proxyBaseUrl, pathRewrite, shouldSave, method, pathname, mockDir, onMockSaved } = options;\n const targetUrl = proxyBaseUrl + pathRewrite(req.url || \"\");\n const client = targetUrl.startsWith(\"https\") ? https : http;\n\n function sendProxyRequest(body?: string) {\n const targetUrlObj = new URL(proxyBaseUrl);\n const proxyOptions = {\n method: req.method,\n headers: {\n ...req.headers,\n host: targetUrlObj.host,\n },\n rejectUnauthorized: false,\n };\n\n const proxyReq = client.request(targetUrl, proxyOptions, (proxyRes) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isJson = contentType.includes(\"application/json\");\n\n // Non-JSON response (file download, stream, etc.) → pipe directly\n if (!isJson) {\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // JSON response → buffer, save mock, then respond\n const chunks: Buffer[] = [];\n\n proxyRes.on(\"data\", (chunk) => chunks.push(chunk));\n proxyRes.on(\"end\", async () => {\n try {\n const responseData = Buffer.concat(chunks);\n\n if (shouldSave) {\n try {\n console.log(\n `[automock] Capturing mock: ${req.url!} -> ${pathname}`,\n );\n const savedFilePath = await saveMockData(\n req.url!,\n method,\n responseData,\n mockDir,\n proxyRes.statusCode,\n contentType,\n );\n if (savedFilePath) {\n console.log(`[automock] Mock saved: ${pathname}`);\n onMockSaved();\n } else {\n console.log(\n `[automock] Mock file already exists, skipped: ${pathname}`,\n );\n }\n } catch (saveError) {\n console.error(\"[automock] Failed to save mock:\", saveError);\n }\n }\n\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(responseData);\n } catch (error) {\n console.error(\"[automock] Failed to process response:\", error);\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(Buffer.concat(chunks));\n }\n });\n });\n\n proxyReq.on(\"error\", (err) => {\n console.error(\"[automock] Proxy request failed:\", err);\n sendError(res, err.message);\n });\n\n if (\n body &&\n (req.method === \"POST\" || req.method === \"PUT\" || req.method === \"PATCH\")\n ) {\n proxyReq.write(body);\n }\n\n proxyReq.end();\n }\n\n if (\n req.method === \"POST\" ||\n req.method === \"PUT\" ||\n req.method === \"PATCH\"\n ) {\n let bodyStr = \"\";\n req.on(\"data\", (chunk) => (bodyStr += chunk.toString()));\n req.on(\"end\", () => sendProxyRequest(bodyStr));\n } else if (req.readableEnded) {\n sendProxyRequest();\n } else {\n req.on(\"end\", () => sendProxyRequest());\n }\n}\n\nfunction printServerUrls(\n server: { httpServer?: { address(): AddressInfo | string | null; once(event: string, cb: () => void): void } | null; config: { server: { https?: unknown } } },\n urls: Array<{ path: string; label: string; color: string; delay: number }>,\n): void {\n server.httpServer?.once(\"listening\", () => {\n const address = server.httpServer?.address();\n if (!address || typeof address !== \"object\") return;\n\n const { protocol, host, port } = getServerAddress(\n address,\n !!server.config.server.https,\n );\n\n for (const { path: urlPath, label, color, delay } of urls) {\n setTimeout(() => {\n const fullUrl = `${protocol}://${host}:${port}${urlPath}`;\n console.log(` ➜ ${color}${label}\\x1b[0m: \\x1b[1m${fullUrl}\\x1b[0m`);\n }, delay);\n }\n });\n}\n\nexport function automock(options: AutomockPluginOptions): Plugin {\n const {\n mockDir: configMockDir = path.join(process.cwd(), \"mock\"),\n apiPrefix = \"/api\",\n pathRewrite = (p) => p,\n proxyBaseUrl,\n inspector = false,\n } = options;\n\n const mockDir = resolveAbsolutePath(configMockDir);\n\n if (!fs.existsSync(mockDir)) {\n try {\n fs.ensureDirSync(mockDir);\n console.log(`[automock] Mock directory created: ${mockDir}`);\n } catch (error) {\n console.error(`[automock] Failed to create mock directory: ${mockDir}`, error);\n }\n }\n\n let watcher: FSWatcher | undefined;\n\n return {\n name: \"vite-plugin-automock\",\n config(userConfig) {\n if (proxyBaseUrl && userConfig.server?.proxy) {\n const proxyConfig = userConfig.server.proxy;\n const hasConflictingPrefix =\n typeof proxyConfig === \"object\" && apiPrefix in proxyConfig;\n\n if (hasConflictingPrefix) {\n console.warn(\n `\\n⚠️ [automock] WARNING: You have both Vite's server.proxy[\"${apiPrefix}\"] and automock's proxyBaseUrl configured.`,\n );\n console.warn(\n ` This may cause request conflicts. Remove the \"${apiPrefix}\" entry from vite.config.ts server.proxy to avoid issues.`,\n );\n console.warn(\n ` Automock will handle all ${apiPrefix} requests when proxyBaseUrl is set.\\n`,\n );\n }\n }\n },\n async configureServer(server) {\n let mockFileMap = await buildMockIndex(mockDir);\n console.log(`[automock] Loaded ${mockFileMap.size} mock files`);\n\n const rebuildMockFileMap = debounce(async () => {\n mockFileMap = await buildMockIndex(mockDir);\n }, 200);\n\n watcher = chokidar.watch(mockDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 30,\n });\n watcher.on(\"add\", () => rebuildMockFileMap());\n watcher.on(\"unlink\", () => rebuildMockFileMap());\n\n server.httpServer?.on(\"close\", () => watcher?.close());\n\n const inspectorHandler = createInspectorHandler({\n inspector,\n apiPrefix,\n mockDir,\n getMockFileMap: () => mockFileMap,\n });\n\n const urlsToPrint: Array<{ path: string; label: string; color: string; delay: number }> = [\n { path: apiPrefix, label: \"Mock API\", color: \"\\x1b[32m\", delay: 100 },\n ];\n\n if (inspector) {\n const inspectorConfig = normalizeInspectorConfig(inspector);\n urlsToPrint.push({\n path: inspectorConfig.route,\n label: \"Mock Inspector\",\n color: \"\\x1b[95m\",\n delay: 150,\n });\n }\n\n printServerUrls(server, urlsToPrint);\n\n async function tryLoadMock(key: string): Promise<{ absolutePath: string; mockResult: Record<string, unknown> } | null> {\n const mockFilePath = mockFileMap.get(key);\n if (!mockFilePath) return null;\n\n const absolutePath = resolveAbsolutePath(mockFilePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n const mockResult =\n typeof mockModule.data === \"function\"\n ? mockModule.data()\n : mockModule;\n\n const { enable = true } = mockResult || {};\n return enable ? { absolutePath, mockResult } : null;\n }\n\n server.middlewares.use(\n async (\n req: IncomingMessage,\n res: ServerResponse,\n next: (err?: Error | unknown) => void,\n ): Promise<void> => {\n if (inspectorHandler && req.url) {\n const handled = await inspectorHandler(req, res);\n if (handled) return;\n }\n\n if (!req.url?.startsWith(apiPrefix)) {\n return next();\n }\n\n // Skip non-standard requests (SSE, WebSocket, file streams)\n const accept = req.headers.accept || \"\";\n const upgrade = req.headers.upgrade || \"\";\n if (accept.includes(\"text/event-stream\") || upgrade.toLowerCase() === \"websocket\") {\n return next();\n }\n\n const method = (req.method || \"GET\").toLowerCase();\n const pathname = new URL(req.url, \"http://localhost\").pathname;\n const key = `${pathname}/${method}.js`.toLowerCase();\n\n // 1. Try mock\n try {\n const mock = await tryLoadMock(key);\n if (mock) {\n serveMockResponse(res, mock.absolutePath, mock.mockResult);\n return;\n }\n } catch (error) {\n console.error(\"[automock] Failed to load mock file:\", error);\n }\n\n // 2. Try proxy\n if (!proxyBaseUrl) return next();\n\n try {\n proxyAndCapture(req, res, {\n proxyBaseUrl,\n pathRewrite,\n shouldSave: !mockFileMap.has(key),\n method,\n pathname,\n mockDir,\n onMockSaved: async () => {\n mockFileMap = await buildMockIndex(mockDir);\n },\n });\n } catch (error) {\n console.error(\"[automock] Proxy request error:\", error);\n sendError(res, \"Internal server error\");\n }\n },\n );\n },\n closeBundle() {\n watcher?.close();\n },\n transform() {\n return null;\n },\n };\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport prettier from \"prettier\";\n\nimport { resolveAbsolutePath, toPosixPath } from \"./utils\";\n\nexport interface MockFileConfig {\n enable: boolean;\n data: unknown;\n delay: number;\n status: number;\n [key: string]: unknown;\n}\n\nexport interface MockFileInfo {\n config: MockFileConfig;\n serializable: boolean;\n hasDynamicData: boolean;\n headerComment?: string;\n description?: string;\n dataText: string;\n isBinary?: boolean;\n}\n\nexport const DEFAULT_CONFIG: MockFileConfig = {\n enable: true,\n data: null,\n delay: 0,\n status: 200,\n};\n\nconst isBufferTextLike = (buffer: Buffer): boolean => {\n try {\n const sample = buffer.slice(0, 100);\n const nullBytes = [...sample].filter((b) => b === 0).length;\n const controlChars = [...sample].filter(\n (b) => b < 32 && b !== 9 && b !== 10 && b !== 13,\n ).length;\n return nullBytes === 0 && controlChars < 5;\n } catch {\n return false;\n }\n};\n\nconst isBinaryResponse = (\n contentType: string | undefined,\n data: Buffer,\n): boolean => {\n if (!contentType) return false;\n\n const binaryTypes = [\n \"application/octet-stream\",\n \"application/pdf\",\n \"application/zip\",\n \"application/x-zip-compressed\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"image/\",\n \"video/\",\n \"audio/\",\n ];\n\n return (\n binaryTypes.some((type) => contentType.toLowerCase().includes(type)) ||\n !isBufferTextLike(data)\n );\n};\n\nconst getFileExtension = (\n contentType: string | undefined,\n url: string,\n): string => {\n const mimeMap: Record<string, string> = {\n \"application/json\": \"json\",\n \"application/pdf\": \"pdf\",\n \"application/zip\": \"zip\",\n \"application/vnd.ms-excel\": \"xls\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/msword\": \"doc\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"docx\",\n \"application/vnd.ms-powerpoint\": \"ppt\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\":\n \"pptx\",\n \"image/jpeg\": \"jpg\",\n \"image/png\": \"png\",\n \"image/gif\": \"gif\",\n \"text/plain\": \"txt\",\n \"text/html\": \"html\",\n \"text/css\": \"css\",\n \"application/javascript\": \"js\",\n \"text/xml\": \"xml\",\n };\n\n if (contentType && mimeMap[contentType.toLowerCase()]) {\n return mimeMap[contentType.toLowerCase()];\n }\n\n try {\n const urlObj = new URL(url, \"http://localhost\");\n const fileName = urlObj.searchParams.get(\"file_name\");\n if (fileName) {\n const extensionMatch = fileName.match(/\\.([a-zA-Z0-9]+)$/);\n if (extensionMatch) {\n return extensionMatch[1];\n }\n }\n } catch {\n // Ignore URL parse errors\n }\n\n return \"bin\";\n};\n\nasync function formatWithPrettier(content: string): Promise<string> {\n try {\n return await prettier.format(content, { parser: \"babel\" });\n } catch {\n return content;\n }\n}\n\nfunction buildMockFileHeader(\n pathname: string,\n method: string,\n search: string,\n extra?: string,\n): string {\n return `/**\n * Mock data for ${pathname} (${method.toUpperCase()})${search || \"\"}\n * @description ${pathname}${search || \"\"}${extra ? ` - ${extra}` : \"\"}\n * Generated at ${new Date().toISOString()}\n */`;\n}\n\nasync function saveBinaryMock(\n filePath: string,\n binaryData: Buffer,\n pathname: string,\n method: string,\n search: string,\n contentType: string | undefined,\n url: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n const extension = getFileExtension(contentType, url);\n const binaryFilePath = filePath.replace(/\\.js$/, \".\" + extension);\n\n if (fs.existsSync(binaryFilePath)) return null;\n\n fs.writeFileSync(binaryFilePath, binaryData);\n\n const header = buildMockFileHeader(pathname, method, search, `Binary file (${extension})`);\n const configContent = `${header}\nexport default {\n enable: false,\n data: {\n __binaryFile: '${extension}',\n __originalPath: '${pathname}',\n __originalQuery: '${search}',\n __originalUrl: '${pathname}${search || \"\"}',\n __contentType: '${contentType}',\n __fileSize: ${binaryData.length}\n },\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(configContent);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nasync function saveJsonMock(\n filePath: string,\n dataStr: string,\n pathname: string,\n method: string,\n search: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n if (fs.existsSync(filePath)) return null;\n\n let jsonData;\n if (!dataStr || dataStr.trim() === \"\") {\n jsonData = {\n error: true,\n message: `Empty response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: null,\n };\n } else {\n try {\n jsonData = JSON.parse(dataStr);\n if (statusCode && statusCode >= 400) {\n const errorMeta = { __mockStatusCode: statusCode, __isErrorResponse: true };\n jsonData =\n typeof jsonData === \"object\" && jsonData !== null\n ? { ...jsonData, ...errorMeta }\n : { originalData: jsonData, ...errorMeta };\n }\n } catch {\n jsonData = {\n error: true,\n message: `Non-JSON response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: dataStr,\n __mockStatusCode: statusCode,\n __isErrorResponse: true,\n };\n }\n }\n\n const header = buildMockFileHeader(pathname, method, search);\n const content = `${header}\nexport default {\n enable: false,\n data: ${JSON.stringify(jsonData)},\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(content);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nexport async function saveMockData(\n url: string,\n method: string,\n data: Buffer | string,\n rootDir: string,\n statusCode?: number,\n contentType?: string,\n): Promise<string | null> {\n try {\n const absoluteRootDir = resolveAbsolutePath(rootDir);\n const urlObj = new URL(url, \"http://localhost\");\n const pathname = urlObj.pathname;\n const search = urlObj.search;\n\n const filePath = path.join(\n absoluteRootDir,\n pathname.replace(/^\\//, \"\"),\n method.toLowerCase() + \".js\",\n );\n\n await fs.ensureDir(path.dirname(filePath));\n\n const isBuffer = Buffer.isBuffer(data);\n const binaryData = isBuffer ? data : Buffer.from(data || \"\");\n const isBinary = isBinaryResponse(contentType, binaryData);\n\n if (isBinary) {\n return saveBinaryMock(\n filePath, binaryData, pathname, method, search,\n contentType, url, statusCode,\n );\n }\n\n const dataStr = isBuffer ? data.toString(\"utf8\") : data || \"\";\n return saveJsonMock(filePath, dataStr, pathname, method, search, statusCode);\n } catch (error) {\n console.error(`Failed to save mock data for ${url}:`, error);\n console.error(\n `URL details: url=${url}, method=${method}, statusCode=${statusCode}, contentType=${contentType}`,\n );\n throw error;\n }\n}\n\nconst recursiveReadAllFiles = async (dir: string): Promise<string[]> => {\n if (!(await fs.pathExists(dir))) return [];\n\n const files: string[] = [];\n try {\n const list = await fs.readdir(dir);\n for (const file of list) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n files.push(...(await recursiveReadAllFiles(filePath)));\n } else {\n files.push(filePath);\n }\n }\n } catch (error) {\n console.error(`Error reading directory ${dir}:`, error);\n }\n return files;\n};\n\nexport async function buildMockIndex(mockDir: string): Promise<Map<string, string>> {\n const mockFileMap = new Map<string, string>();\n\n if (!(await fs.pathExists(mockDir))) {\n await fs.ensureDir(mockDir);\n return mockFileMap;\n }\n\n const files = await recursiveReadAllFiles(mockDir);\n\n files.forEach((filePath) => {\n if (!filePath.endsWith(\".js\")) return;\n\n try {\n const relativePath = path.relative(mockDir, filePath);\n const method = path.basename(filePath, \".js\");\n const dirPath = path.dirname(relativePath);\n const urlPath = \"/\" + toPosixPath(dirPath);\n const absolutePath = resolveAbsolutePath(filePath);\n const key = `${urlPath}/${method}.js`.toLowerCase();\n\n mockFileMap.set(key, absolutePath);\n } catch (error) {\n console.error(`[automock] Failed to process file ${filePath}:`, error);\n }\n });\n\n return mockFileMap;\n}\n\nexport async function parseMockModule(filePath: string): Promise<MockFileInfo> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n if (!fs.existsSync(absolutePath)) {\n throw new Error(`Mock file does not exist: ${absolutePath}`);\n }\n\n const content = fs.readFileSync(absolutePath, \"utf-8\");\n const headerCommentMatch = content.match(/^(\\/\\*\\*[\\s\\S]*?\\*\\/)/);\n const headerComment = headerCommentMatch ? headerCommentMatch[1] : undefined;\n\n let description: string | undefined;\n if (headerComment) {\n const descMatch = headerComment.match(/@description\\s+(.+?)(?:\\n|\\*\\/)/s);\n if (descMatch) {\n description = descMatch[1].trim();\n }\n }\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n\n const exportedConfig =\n typeof mockModule === \"function\" ? mockModule() : mockModule;\n const hasDynamicData = typeof exportedConfig?.data === \"function\";\n const config: MockFileConfig = {\n ...DEFAULT_CONFIG,\n ...(exportedConfig ?? {}),\n };\n\n const serializable = !hasDynamicData;\n const dataObj =\n typeof config.data === \"object\" && config.data !== null\n ? (config.data as Record<string, unknown>)\n : null;\n const isBinary = dataObj !== null && \"__binaryFile\" in dataObj;\n\n return {\n config,\n serializable,\n hasDynamicData,\n headerComment,\n description,\n dataText: isBinary\n ? `/* Binary file: ${dataObj?.__binaryFile} */`\n : serializable\n ? JSON.stringify(config.data ?? null, null, 2)\n : \"/* data is generated dynamically and cannot be edited here */\",\n isBinary,\n };\n}\n\nexport async function writeMockFile(\n filePath: string,\n mockInfo: Pick<MockFileInfo, \"config\" | \"headerComment\" | \"description\">,\n): Promise<void> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n let header = mockInfo.headerComment || \"\";\n\n if (mockInfo.description !== undefined) {\n if (header) {\n if (/@description/.test(header)) {\n header = header.replace(\n /@description\\s+.+?(?=\\n|\\*\\/)/s,\n `@description ${mockInfo.description}`,\n );\n } else {\n header = header.replace(\n /\\*\\//,\n ` * @description ${mockInfo.description}\\n */`,\n );\n }\n }\n }\n\n const content = header ? `${header}\\n` : \"\";\n const finalContent = `${content}export default ${JSON.stringify(mockInfo.config, null, 2)}\\n`;\n\n try {\n const formatted = await formatWithPrettier(finalContent);\n fs.writeFileSync(absolutePath, formatted, \"utf-8\");\n } catch {\n console.error(\"Error formatting code with prettier, writing raw content\");\n fs.writeFileSync(absolutePath, finalContent, \"utf-8\");\n }\n}\n","import path from \"path\";\n\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AddressInfo } from \"net\";\n\nexport function resolveAbsolutePath(p: string): string {\n return path.isAbsolute(p) ? p : path.resolve(process.cwd(), p);\n}\n\nexport function toPosixPath(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nexport interface ServerAddress {\n protocol: string;\n host: string;\n port: number;\n}\n\nexport function getServerAddress(\n address: AddressInfo,\n isHttps: boolean,\n): ServerAddress {\n return {\n protocol: isHttps ? \"https\" : \"http\",\n host:\n address.address === \"::\" || address.address === \"0.0.0.0\"\n ? \"localhost\"\n : address.address,\n port: address.port,\n };\n}\n\nexport function sendJson(\n res: ServerResponse,\n data: unknown,\n status = 200,\n): void {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n}\n\nexport function sendError(\n res: ServerResponse,\n message: string,\n status = 500,\n): void {\n sendJson(res, { error: message }, status);\n}\n\nconst MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let totalSize = 0;\n req.on(\"data\", (chunk: Buffer) => {\n totalSize += chunk.length;\n if (totalSize > MAX_BODY_SIZE) {\n reject(new Error(\"Request body too large\"));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport { fileURLToPath } from \"url\";\n\n// ESM/CJS compatible __dirname\nconst _dirName = typeof __dirname !== \"undefined\"\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url));\nimport { parseMockModule, writeMockFile, saveMockData, buildMockIndex, type MockFileConfig } from \"./mockFileUtils\";\nimport { toPosixPath, sendJson, readBody } from \"./utils\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AutomockPluginOptions, InspectorOptions } from \"./types\";\n\ninterface InspectorContext {\n req: IncomingMessage;\n res: ServerResponse;\n mockDir: string;\n inspectorRoute: string;\n apiPrefix: string;\n inspectorConfig: Required<InspectorOptions>;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorHandlerOptions {\n inspector: AutomockPluginOptions[\"inspector\"];\n apiPrefix: string;\n mockDir: string;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorApiContext extends InspectorContext {\n pathname: string;\n}\n\ninterface InspectorPayload {\n key: string;\n config?: Partial<MockFileConfig>;\n description?: string;\n}\n\ninterface MockItem {\n key: string;\n file: string;\n method: string;\n path: string;\n config: MockFileConfig;\n editable: boolean;\n description?: string;\n dataText: string;\n}\n\nfunction buildMockItem(\n key: string,\n filePath: string,\n mockDir: string,\n info: Awaited<ReturnType<typeof parseMockModule>>,\n): MockItem {\n return {\n key,\n file: path.relative(mockDir, filePath),\n method: key.split(\"/\").pop()?.replace(/\\.js$/, \"\") ?? \"get\",\n path: key.replace(/\\/[^/]+\\.js$/, \"\"),\n config: info.config,\n editable: info.serializable,\n description: info.description,\n dataText: info.dataText,\n };\n}\n\nexport const DEFAULT_ROUTE = \"/__mock/\";\n\nfunction ensureTrailingSlash(route: string): string {\n return route.endsWith(\"/\") ? route : `${route}/`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport function normalizeInspectorConfig(\n input: AutomockPluginOptions[\"inspector\"],\n): Required<InspectorOptions> {\n if (input === false || input === undefined) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n if (input === true) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n return {\n route: ensureTrailingSlash(input.route ?? DEFAULT_ROUTE),\n enableToggle: input.enableToggle ?? true,\n };\n}\n\nexport type InspectorRequestHandler = (\n req: IncomingMessage,\n res: ServerResponse,\n) => Promise<boolean>;\n\nexport function createInspectorHandler(\n options: InspectorHandlerOptions,\n): InspectorRequestHandler | null {\n if (!options.inspector) {\n return null;\n }\n\n const inspectorConfig = normalizeInspectorConfig(options.inspector);\n const inspectorRoute = ensureTrailingSlash(inspectorConfig.route);\n\n return async (req, res) => {\n if (!req.url) {\n return false;\n }\n const url = new URL(req.url, \"http://localhost\");\n if (!url.pathname.startsWith(inspectorRoute)) {\n return false;\n }\n\n await handleInspectorRequest({\n req,\n res,\n mockDir: options.mockDir,\n inspectorRoute,\n apiPrefix: options.apiPrefix,\n inspectorConfig,\n getMockFileMap: options.getMockFileMap,\n });\n\n return true;\n };\n}\n\nasync function handleInspectorRequest(\n context: InspectorContext,\n): Promise<void> {\n const { req, res, inspectorRoute } = context;\n const url = new URL(req.url || inspectorRoute, \"http://localhost\");\n const normalizedRoute = ensureTrailingSlash(inspectorRoute);\n\n if (\n url.pathname === normalizedRoute.slice(0, -1) ||\n url.pathname === normalizedRoute\n ) {\n await serveInspectorHtml(context);\n return;\n }\n\n const relativePath = url.pathname.startsWith(normalizedRoute)\n ? url.pathname.slice(normalizedRoute.length)\n : null;\n\n if (relativePath && relativePath.startsWith(\"api/\")) {\n await handleInspectorApi({ ...context, pathname: relativePath.slice(4) });\n return;\n }\n\n res.statusCode = 404;\n res.end(\"Not Found\");\n}\n\nasync function serveInspectorHtml({\n res,\n inspectorRoute,\n apiPrefix,\n inspectorConfig,\n}: InspectorContext): Promise<void> {\n const routeJson = JSON.stringify(ensureTrailingSlash(inspectorRoute));\n const allowToggleJson = JSON.stringify(inspectorConfig.enableToggle);\n const apiPrefixEscaped = escapeHtml(apiPrefix);\n\n const templatePath = path.join(_dirName, \"inspector-template.html\");\n const template = fs.readFileSync(templatePath, \"utf-8\");\n const html = template\n .replace(\"__API_PREFIX__\", apiPrefixEscaped)\n .replace(\"__ROUTE_JSON__\", routeJson)\n .replace(\"__ALLOW_TOGGLE_JSON__\", allowToggleJson);\n\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(html);\n}\n\nasync function handleList(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { res, mockDir } = ctx;\n const list = await Promise.all(\n Array.from(mockFileMap.entries()).map(async ([key, filePath]) => {\n const info = await parseMockModule(filePath);\n return buildMockItem(key, filePath, mockDir, info);\n }),\n );\n sendJson(res, { mocks: list });\n return true;\n}\n\nasync function handleDetail(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n const info = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, info) });\n return true;\n}\n\nasync function handleUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, inspectorConfig } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: InspectorPayload;\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { key, config, description } = payload || {};\n if (!key) {\n sendJson(res, { error: \"Invalid payload: missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n\n let nextConfig = info.config;\n if (config && typeof config === \"object\") {\n if (!inspectorConfig.enableToggle && config.enable !== undefined) {\n delete config.enable;\n }\n nextConfig = { ...info.config, ...config };\n }\n\n const nextDescription =\n description !== undefined ? description : info.description;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: nextDescription,\n });\n\n const updatedInfo = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, updatedInfo) });\n return true;\n}\n\nasync function handleCreate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, apiPrefix } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { method: string; path: string; description?: string; data?: unknown };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { method, path: apiPath, data } = payload || {};\n if (!method || !apiPath) {\n sendJson(res, { error: \"Invalid payload: missing method or path\" }, 400);\n return true;\n }\n\n const fullUrl = apiPrefix + apiPath;\n\n try {\n let dataToSave: Buffer | string;\n if (typeof data === \"object\" && data !== null) {\n dataToSave = JSON.stringify(data, null, 2);\n } else {\n dataToSave = typeof data === \"string\" ? data : \"\";\n }\n\n await saveMockData(fullUrl, method.toLowerCase(), dataToSave, mockDir, 200);\n\n const newMockFileMap = await buildMockIndex(mockDir);\n for (const [key, value] of newMockFileMap.entries()) {\n mockFileMap.set(key, value);\n }\n\n const normalizedPath = toPosixPath(apiPath);\n const key = (normalizedPath.startsWith(\"/\") ? \"\" : \"/\") +\n normalizedPath.toLowerCase() + \"/\" + method.toLowerCase() + \".js\";\n const filePath = mockFileMap.get(key);\n\n if (!filePath) {\n sendJson(res, { error: \"Mock file created but not found in map\" }, 500);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n sendJson(res, {\n success: true,\n mock: buildMockItem(key, filePath, mockDir, info),\n });\n return true;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to create mock: \" + errorMessage }, 500);\n return true;\n }\n}\n\nasync function handleDelete(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n try {\n const stats = await fs.stat(filePath);\n if (stats.isDirectory()) {\n await fs.remove(filePath);\n for (const [mapKey, mapPath] of mockFileMap.entries()) {\n if (mapPath.startsWith(filePath + path.sep) || mapPath === filePath) {\n mockFileMap.delete(mapKey);\n }\n }\n } else {\n await fs.unlink(filePath);\n mockFileMap.delete(key);\n }\n sendJson(res, { success: true });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to delete: \" + errorMessage }, 500);\n }\n return true;\n}\n\ntype ApiHandler = (ctx: InspectorApiContext, mockFileMap: Map<string, string>) => Promise<boolean>;\n\nasync function handleBatchUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { updates?: Array<{ key: string; config?: Record<string, unknown> }> };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const updates = payload?.updates;\n if (!Array.isArray(updates) || updates.length === 0) {\n sendJson(res, { error: \"Invalid payload: updates must be a non-empty array\" }, 400);\n return true;\n }\n\n let updated = 0;\n const errors: string[] = [];\n\n for (const item of updates) {\n const { key, config } = item;\n if (!key) continue;\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n errors.push(`Mock not found: ${key}`);\n continue;\n }\n\n try {\n const info = await parseMockModule(filePath);\n const nextConfig = config ? { ...info.config, ...config } : info.config;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: info.description,\n });\n updated++;\n } catch (err) {\n errors.push(`Failed to update ${key}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n sendJson(res, { success: true, updated, errors: errors.length > 0 ? errors : undefined });\n return true;\n}\n\nconst API_ROUTES: Record<string, ApiHandler> = {\n list: handleList,\n detail: handleDetail,\n update: handleUpdate,\n \"batch-update\": handleBatchUpdate,\n create: handleCreate,\n delete: handleDelete,\n};\n\nasync function handleInspectorApi(ctx: InspectorApiContext): Promise<void> {\n try {\n const mockFileMap = ctx.getMockFileMap();\n const handler = API_ROUTES[ctx.pathname];\n if (handler) {\n await handler(ctx, mockFileMap);\n return;\n }\n sendJson(ctx.res, { error: \"Unknown inspector endpoint\" }, 404);\n } catch (error) {\n console.error(\"[automock] Inspector request failed:\", error);\n sendJson(ctx.res, { error: \"Inspector failed\" }, 500);\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\n\nimport { buildMockIndex, parseMockModule } from './mockFileUtils'\n\nexport interface MockBundleData {\n enable: boolean\n data: unknown\n delay: number\n status: number\n isBinary?: boolean\n}\n\nexport interface MockBundle {\n [key: string]: MockBundleData\n}\n\nexport interface BundleOptions {\n mockDir: string\n includeDisabled?: boolean\n log?: boolean\n}\n\nconst DEFAULT_BUNDLE_OPTIONS: Partial<BundleOptions> = {\n includeDisabled: true,\n log: true\n}\n\nasync function bundleMockFiles(options: BundleOptions): Promise<MockBundle> {\n const opts = { ...DEFAULT_BUNDLE_OPTIONS, ...options }\n const { mockDir, log } = opts\n\n if (!fs.existsSync(mockDir)) {\n if (log) {\n console.log(`[mock-bundler] Mock directory does not exist: ${mockDir}`)\n }\n return {}\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n const bundle: MockBundle = {}\n let bundledCount = 0\n let skippedCount = 0\n\n for (const [key, filePath] of mockFileMap) {\n try {\n const mockInfo = await parseMockModule(filePath)\n\n if (!mockInfo.serializable) {\n skippedCount++\n if (log) {\n console.log(`[mock-bundler] Skipping non-serializable mock: ${key}`)\n }\n continue\n }\n\n bundle[key] = {\n enable: mockInfo.config.enable,\n data: mockInfo.config.data,\n delay: mockInfo.config.delay,\n status: mockInfo.config.status,\n isBinary: mockInfo.isBinary\n }\n\n bundledCount++\n } catch (error) {\n if (log) {\n console.error(`[mock-bundler] Failed to bundle mock ${key}:`, error)\n }\n }\n }\n\n if (log) {\n console.log(`[mock-bundler] Bundled ${bundledCount} mocks, skipped ${skippedCount} non-serializable mocks`)\n }\n\n return bundle\n}\n\nfunction writeMockBundle(bundle: MockBundle, outputPath: string): void {\n const outputDir = path.dirname(outputPath)\n\n if (!fs.existsSync(outputDir)) {\n fs.ensureDirSync(outputDir)\n }\n\n fs.writeFileSync(\n outputPath,\n JSON.stringify(bundle, null, 2),\n 'utf-8'\n )\n}\n\nexport { bundleMockFiles, writeMockBundle }\n","import type {\n AxiosInstance,\n AxiosResponse,\n InternalAxiosRequestConfig,\n} from \"axios\";\n\ndeclare const __AUTOMOCK_ENABLED__: boolean;\n\nexport type MockBundleData = {\n enable: boolean;\n data: unknown;\n delay?: number;\n status?: number;\n isBinary?: boolean;\n};\n\nexport type MockInterceptorOptions = {\n mockData: Record<string, MockBundleData>;\n enabled?: boolean | (() => boolean);\n onMockHit?: (url: string, method: string, mock: MockBundleData) => void;\n onBypass?: (url: string, method: string, reason: string) => void;\n};\n\ntype MockEnabledState = boolean | undefined;\n\ndeclare global {\n interface Window {\n __MOCK_ENABLED__?: MockEnabledState;\n }\n}\n\nclass MockInterceptor {\n private options: MockInterceptorOptions;\n\n constructor(options: MockInterceptorOptions) {\n this.options = options;\n }\n\n /**\n * Check if mock is enabled\n */\n isEnabled(): boolean {\n // Check runtime flag first\n if (window.__MOCK_ENABLED__ !== undefined) {\n return window.__MOCK_ENABLED__;\n }\n // Check environment variable\n if (typeof this.options.enabled === \"function\") {\n return this.options.enabled();\n }\n return this.options.enabled ?? false;\n }\n\n /**\n * Find matching mock data for the request\n * Supports both formats:\n * - \"GET /api/v1/asset/xxx\" (HTTP method + URL)\n * - \"/api/v1/asset/xxx/get.js\" (File path format from automock plugin)\n */\n private findMock(url: string, method: string): MockBundleData | null {\n const methodUpper = method.toUpperCase();\n const methodLower = method.toLowerCase();\n\n // Try HTTP method + URL format first (for compatibility)\n const httpMethodKey = `${methodUpper} ${url}`;\n if (this.options.mockData[httpMethodKey]) {\n return this.options.mockData[httpMethodKey];\n }\n\n // Try file path format from automock plugin: /api/v1/asset/xxx/get.js\n const filePathKey = `${url}/${methodLower}.js`;\n if (this.options.mockData[filePathKey]) {\n return this.options.mockData[filePathKey];\n }\n\n return null;\n }\n\n /**\n * Determine if request should be mocked\n */\n shouldMock(url: string, method: string): boolean {\n if (!this.isEnabled()) {\n return false;\n }\n\n const mock = this.findMock(url, method);\n return mock !== null && mock.enable;\n }\n\n /**\n * Get mock data for request\n */\n getMock(url: string, method: string): MockBundleData | null {\n if (!this.shouldMock(url, method)) {\n return null;\n }\n return this.findMock(url, method);\n }\n\n /**\n * Setup axios interceptor\n */\n setupAxios(axiosInstance: AxiosInstance): void {\n axiosInstance.interceptors.request.use(\n async (config: InternalAxiosRequestConfig) => {\n const url = config.url || \"\";\n const method = config.method?.toUpperCase() || \"GET\";\n\n const mock = this.getMock(url, method);\n\n if (mock) {\n // Trigger mock hit callback\n this.options.onMockHit?.(url, method, mock);\n\n // Set adapter to return mock data\n (config as InternalAxiosRequestConfig & { adapter: () => Promise<AxiosResponse> }).adapter = async () => {\n const { data, delay = 0, status = 200 } = mock;\n\n // Simulate delay\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n return {\n data,\n status,\n statusText: \"OK\",\n headers: {},\n config,\n };\n };\n } else {\n // Trigger bypass callback\n const reason = !this.isEnabled()\n ? \"Mock disabled globally\"\n : \"No matching mock found or mock disabled\";\n this.options.onBypass?.(url, method, reason);\n }\n\n return config;\n },\n (error: unknown) => Promise.reject(error),\n );\n }\n}\n\n/**\n * Create mock interceptor instance\n */\nexport function createMockInterceptor(\n options: MockInterceptorOptions,\n): MockInterceptor {\n return new MockInterceptor(options);\n}\n\n/**\n * Load mock data from bundled JSON file\n */\nexport async function loadMockData(): Promise<Record<string, MockBundleData>> {\n try {\n // In production, mock-data.json is generated by automock plugin\n // Use absolute path to load it from dist directory\n const response = await fetch(\"/mock-data.json\");\n if (!response.ok) {\n console.warn(\n \"[MockInterceptor] Failed to load mock-data.json:\",\n response.statusText,\n );\n return {};\n }\n const data = (await response.json()) as Record<string, MockBundleData>;\n return data;\n } catch (error) {\n console.warn(\"[MockInterceptor] Failed to load mock-data.json:\", error);\n return {};\n }\n}\n\nasync function createInterceptorFromBundle(): Promise<MockInterceptor> {\n const mockData = await loadMockData();\n const isEnabled = typeof __AUTOMOCK_ENABLED__ !== \"undefined\" && __AUTOMOCK_ENABLED__;\n\n return new MockInterceptor({\n mockData,\n enabled: isEnabled,\n onMockHit: (url: string, method: string) => {\n console.log(`[MOCK HIT] ${method} ${url}`);\n },\n onBypass: (url: string, method: string, reason: string) => {\n console.log(`[MOCK BYPASS] ${method} ${url} - ${reason}`);\n },\n });\n}\n\nexport async function initMockInterceptor(\n axiosInstance?: AxiosInstance,\n): Promise<void> {\n if (!axiosInstance) {\n throw new Error(\n \"[MockInterceptor] axiosInstance is required. Please provide an axios instance.\",\n );\n }\n\n const interceptor = await createInterceptorFromBundle();\n interceptor.setupAxios(axiosInstance);\n}\n\nexport function setMockEnabled(enabled: boolean): void {\n window.__MOCK_ENABLED__ = enabled;\n}\n\nexport function isMockEnabled(): boolean {\n return !!window.__MOCK_ENABLED__;\n}\n\ntype HttpInstance = {\n constructor: { axiosInstance: AxiosInstance };\n};\n\nlet httpInstanceRef: HttpInstance | undefined;\n\nexport function registerHttpInstance(http: HttpInstance): void {\n httpInstanceRef = http;\n}\n\nexport async function initMockInterceptorForPureHttp(): Promise<void> {\n if (!httpInstanceRef) {\n throw new Error(\n \"[MockInterceptor] http instance not registered. Call registerHttpInstance(http) first.\",\n );\n }\n\n const interceptor = await createInterceptorFromBundle();\n interceptor.setupAxios(httpInstanceRef.constructor.axiosInstance);\n}\n"],"mappings":"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","names":["automock","import_path","import_fs_extra","import_path","import_fs_extra","import_path","path","prettier","fs","path","import_path","import_fs_extra","path","fs","key","fs","https","http","path","debounce","chokidar","import_path","import_fs_extra","fs","path","http","automock","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/mockFileUtils.ts","../src/utils.ts","../src/inspector.ts","../src/mockBundler.ts","../src/client/interceptor.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\n\nimport { automock as createAutomockPlugin } from './middleware'\nimport { bundleMockFiles, writeMockBundle } from './mockBundler'\nimport { buildMockIndex } from './mockFileUtils'\nimport type { Plugin } from 'vite'\nimport type { AutomockPluginOptions } from './types'\nimport type { MockBundle } from './mockBundler'\n\nexport type { AutomockPluginOptions, InspectorOptions } from './types'\nexport { saveMockData, buildMockIndex, parseMockModule, writeMockFile } from './mockFileUtils'\nexport type { MockBundle, MockBundleData } from './mockBundler'\nexport { bundleMockFiles, writeMockBundle } from './mockBundler'\n\n// Client interceptor exports\nexport {\n createMockInterceptor,\n initMockInterceptor,\n initMockInterceptorForPureHttp,\n setMockEnabled,\n isMockEnabled,\n loadMockData,\n registerHttpInstance\n} from './client'\nexport type { MockInterceptorOptions, MockBundleData as ClientMockBundleData } from './client/interceptor'\n\nexport interface AutomockWithBundleOptions extends AutomockPluginOptions {\n bundleMockData?: boolean\n bundleOutputPath?: string\n}\n\nexport function automock(options: AutomockWithBundleOptions = {}): Plugin {\n const {\n bundleMockData = true,\n bundleOutputPath = 'public/mock-data.json',\n ...pluginOptions\n } = options\n\n const basePlugin = createAutomockPlugin(pluginOptions)\n\n let cachedBundle: MockBundle | null = null\n\n const ensureBundleExists = () => {\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n if (!fs.existsSync(outputPath) && cachedBundle) {\n console.log('[automock] Re-writing mock bundle...')\n writeMockBundle(cachedBundle, outputPath)\n }\n }\n\n return {\n ...basePlugin,\n name: 'vite-plugin-automock-with-bundle',\n config() {\n // Inject compile-time constant for client interceptor\n const enabled = pluginOptions.productionMock !== false\n return {\n define: {\n __AUTOMOCK_ENABLED__: JSON.stringify(enabled),\n },\n }\n },\n buildEnd: async () => {\n if (bundleMockData && pluginOptions.productionMock !== false) {\n try {\n const mockDir = pluginOptions.mockDir || path.join(process.cwd(), 'mock')\n\n if (!fs.existsSync(mockDir)) {\n console.log('[automock] Mock directory not found, skipping bundle generation')\n console.log('[automock] Using existing mock-data.json if present')\n return\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n if (mockFileMap.size === 0) {\n console.log('[automock] No mock files found, skipping bundle generation')\n return\n }\n\n cachedBundle = await bundleMockFiles({ mockDir })\n\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n writeMockBundle(cachedBundle, outputPath)\n console.log(`[automock] Mock bundle written to: ${outputPath}`)\n } catch (error) {\n console.error('[automock] Failed to bundle mock data:', error)\n }\n }\n },\n writeBundle: ensureBundleExists,\n closeBundle: ensureBundleExists,\n }\n}\n\n","import chokidar from \"chokidar\";\nimport debounce from \"lodash.debounce\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport http from \"http\";\nimport https from \"https\";\nimport type { AddressInfo } from \"net\";\n\nimport { buildMockIndex, saveMockData } from \"./mockFileUtils\";\nimport { createInspectorHandler, normalizeInspectorConfig } from \"./inspector\";\nimport {\n resolveAbsolutePath,\n getServerAddress,\n sendError,\n} from \"./utils\";\n\nimport type { Plugin } from \"vite\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { FSWatcher } from \"chokidar\";\nimport type { AutomockPluginOptions } from \"./types\";\n\nfunction serveMockResponse(\n res: ServerResponse,\n mockFilePath: string,\n mockResult: { data?: unknown; delay?: number; status?: number },\n): void {\n const { data, delay = 0, status = 200 } = mockResult;\n\n setTimeout(() => {\n const isBinaryMock = data && typeof data === \"object\" && (data as Record<string, unknown>).__binaryFile;\n\n if (isBinaryMock) {\n const binaryData = data as Record<string, unknown>;\n const binaryFilePath = mockFilePath.replace(\n /\\.js$/,\n \".\" + binaryData.__binaryFile,\n );\n\n if (!fs.existsSync(binaryFilePath)) {\n console.error(\n `[automock] Binary mock file not found: ${binaryFilePath}`,\n );\n sendError(res, \"Binary mock file not found\", 404);\n return;\n }\n\n try {\n const fileData = fs.readFileSync(binaryFilePath);\n const contentType =\n (binaryData.__contentType as string) || \"application/octet-stream\";\n res.setHeader(\"Content-Type\", contentType);\n res.setHeader(\"Content-Length\", fileData.length);\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.setHeader(\"X-Mock-Binary-File\", \"true\");\n res.statusCode = status;\n res.end(fileData);\n } catch (error) {\n console.error(\"[automock] Failed to read binary mock file:\", error);\n sendError(res, \"Failed to read binary mock file\");\n }\n } else {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n }\n }, delay);\n}\n\nfunction proxyAndCapture(\n req: IncomingMessage,\n res: ServerResponse,\n options: {\n proxyBaseUrl: string;\n pathRewrite: (p: string) => string;\n shouldSave: boolean;\n method: string;\n pathname: string;\n mockDir: string;\n onMockSaved: () => void;\n },\n): void {\n const { proxyBaseUrl, pathRewrite, shouldSave, method, pathname, mockDir, onMockSaved } = options;\n const targetUrl = proxyBaseUrl + pathRewrite(req.url || \"\");\n const client = targetUrl.startsWith(\"https\") ? https : http;\n\n function sendProxyRequest(body?: string) {\n const targetUrlObj = new URL(proxyBaseUrl);\n const proxyOptions = {\n method: req.method,\n headers: {\n ...req.headers,\n host: targetUrlObj.host,\n },\n rejectUnauthorized: false,\n };\n\n const proxyReq = client.request(targetUrl, proxyOptions, (proxyRes) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isJson = contentType.includes(\"application/json\");\n\n // Non-JSON response (file download, stream, etc.) → pipe directly\n if (!isJson) {\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // JSON response → buffer, save mock, then respond\n const chunks: Buffer[] = [];\n\n proxyRes.on(\"data\", (chunk) => chunks.push(chunk));\n proxyRes.on(\"end\", async () => {\n try {\n const responseData = Buffer.concat(chunks);\n\n if (shouldSave) {\n try {\n console.log(\n `[automock] Capturing mock: ${req.url!} -> ${pathname}`,\n );\n const savedFilePath = await saveMockData(\n req.url!,\n method,\n responseData,\n mockDir,\n proxyRes.statusCode,\n contentType,\n );\n if (savedFilePath) {\n console.log(`[automock] Mock saved: ${pathname}`);\n onMockSaved();\n } else {\n console.log(\n `[automock] Mock file already exists, skipped: ${pathname}`,\n );\n }\n } catch (saveError) {\n console.error(\"[automock] Failed to save mock:\", saveError);\n }\n }\n\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(responseData);\n } catch (error) {\n console.error(\"[automock] Failed to process response:\", error);\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(Buffer.concat(chunks));\n }\n });\n });\n\n proxyReq.on(\"error\", (err) => {\n console.error(\"[automock] Proxy request failed:\", err);\n sendError(res, err.message);\n });\n\n if (\n body &&\n (req.method === \"POST\" || req.method === \"PUT\" || req.method === \"PATCH\")\n ) {\n proxyReq.write(body);\n }\n\n proxyReq.end();\n }\n\n if (\n req.method === \"POST\" ||\n req.method === \"PUT\" ||\n req.method === \"PATCH\"\n ) {\n let bodyStr = \"\";\n req.on(\"data\", (chunk) => (bodyStr += chunk.toString()));\n req.on(\"end\", () => sendProxyRequest(bodyStr));\n } else {\n sendProxyRequest();\n }\n}\n\nfunction printServerUrls(\n server: { httpServer?: { address(): AddressInfo | string | null; once(event: string, cb: () => void): void } | null; config: { server: { https?: unknown } } },\n urls: Array<{ path: string; label: string; color: string; delay: number }>,\n): void {\n server.httpServer?.once(\"listening\", () => {\n const address = server.httpServer?.address();\n if (!address || typeof address !== \"object\") return;\n\n const { protocol, host, port } = getServerAddress(\n address,\n !!server.config.server.https,\n );\n\n for (const { path: urlPath, label, color, delay } of urls) {\n setTimeout(() => {\n const fullUrl = `${protocol}://${host}:${port}${urlPath}`;\n console.log(` ➜ ${color}${label}\\x1b[0m: \\x1b[1m${fullUrl}\\x1b[0m`);\n }, delay);\n }\n });\n}\n\nexport function automock(options: AutomockPluginOptions): Plugin {\n const {\n mockDir: configMockDir = path.join(process.cwd(), \"mock\"),\n apiPrefix = \"/api\",\n pathRewrite = (p) => p,\n proxyBaseUrl,\n inspector = false,\n } = options;\n\n const mockDir = resolveAbsolutePath(configMockDir);\n\n if (!fs.existsSync(mockDir)) {\n try {\n fs.ensureDirSync(mockDir);\n console.log(`[automock] Mock directory created: ${mockDir}`);\n } catch (error) {\n console.error(`[automock] Failed to create mock directory: ${mockDir}`, error);\n }\n }\n\n let watcher: FSWatcher | undefined;\n\n return {\n name: \"vite-plugin-automock\",\n config(userConfig) {\n if (proxyBaseUrl && userConfig.server?.proxy) {\n const proxyConfig = userConfig.server.proxy;\n const hasConflictingPrefix =\n typeof proxyConfig === \"object\" && apiPrefix in proxyConfig;\n\n if (hasConflictingPrefix) {\n console.warn(\n `\\n⚠️ [automock] WARNING: You have both Vite's server.proxy[\"${apiPrefix}\"] and automock's proxyBaseUrl configured.`,\n );\n console.warn(\n ` This may cause request conflicts. Remove the \"${apiPrefix}\" entry from vite.config.ts server.proxy to avoid issues.`,\n );\n console.warn(\n ` Automock will handle all ${apiPrefix} requests when proxyBaseUrl is set.\\n`,\n );\n }\n }\n },\n async configureServer(server) {\n let mockFileMap = await buildMockIndex(mockDir);\n console.log(`[automock] Loaded ${mockFileMap.size} mock files`);\n\n const rebuildMockFileMap = debounce(async () => {\n mockFileMap = await buildMockIndex(mockDir);\n }, 200);\n\n watcher = chokidar.watch(mockDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 30,\n });\n watcher.on(\"add\", () => rebuildMockFileMap());\n watcher.on(\"unlink\", () => rebuildMockFileMap());\n\n server.httpServer?.on(\"close\", () => watcher?.close());\n\n const inspectorHandler = createInspectorHandler({\n inspector,\n apiPrefix,\n mockDir,\n getMockFileMap: () => mockFileMap,\n });\n\n const urlsToPrint: Array<{ path: string; label: string; color: string; delay: number }> = [\n { path: apiPrefix, label: \"Mock API\", color: \"\\x1b[32m\", delay: 100 },\n ];\n\n if (inspector) {\n const inspectorConfig = normalizeInspectorConfig(inspector);\n urlsToPrint.push({\n path: inspectorConfig.route,\n label: \"Mock Inspector\",\n color: \"\\x1b[95m\",\n delay: 150,\n });\n }\n\n printServerUrls(server, urlsToPrint);\n\n async function tryLoadMock(key: string): Promise<{ absolutePath: string; mockResult: Record<string, unknown> } | null> {\n const mockFilePath = mockFileMap.get(key);\n if (!mockFilePath) return null;\n\n const absolutePath = resolveAbsolutePath(mockFilePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n const mockResult =\n typeof mockModule.data === \"function\"\n ? mockModule.data()\n : mockModule;\n\n const { enable = true } = mockResult || {};\n return enable ? { absolutePath, mockResult } : null;\n }\n\n server.middlewares.use(\n async (\n req: IncomingMessage,\n res: ServerResponse,\n next: (err?: Error | unknown) => void,\n ): Promise<void> => {\n if (inspectorHandler && req.url) {\n const handled = await inspectorHandler(req, res);\n if (handled) return;\n }\n\n if (!req.url?.startsWith(apiPrefix)) {\n return next();\n }\n\n // Skip non-standard requests (SSE, WebSocket, file streams)\n const accept = req.headers.accept || \"\";\n const upgrade = req.headers.upgrade || \"\";\n if (accept.includes(\"text/event-stream\") || upgrade.toLowerCase() === \"websocket\") {\n return next();\n }\n\n const method = (req.method || \"GET\").toLowerCase();\n const pathname = new URL(req.url, \"http://localhost\").pathname;\n const key = `${pathname}/${method}.js`.toLowerCase();\n\n // 1. Try mock\n try {\n const mock = await tryLoadMock(key);\n if (mock) {\n serveMockResponse(res, mock.absolutePath, mock.mockResult);\n return;\n }\n } catch (error) {\n console.error(\"[automock] Failed to load mock file:\", error);\n }\n\n // 2. Try proxy\n if (!proxyBaseUrl) return next();\n\n try {\n proxyAndCapture(req, res, {\n proxyBaseUrl,\n pathRewrite,\n shouldSave: !mockFileMap.has(key),\n method,\n pathname,\n mockDir,\n onMockSaved: async () => {\n mockFileMap = await buildMockIndex(mockDir);\n },\n });\n } catch (error) {\n console.error(\"[automock] Proxy request error:\", error);\n sendError(res, \"Internal server error\");\n }\n },\n );\n },\n closeBundle() {\n watcher?.close();\n },\n transform() {\n return null;\n },\n };\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport prettier from \"prettier\";\n\nimport { resolveAbsolutePath, toPosixPath } from \"./utils\";\n\nexport interface MockFileConfig {\n enable: boolean;\n data: unknown;\n delay: number;\n status: number;\n [key: string]: unknown;\n}\n\nexport interface MockFileInfo {\n config: MockFileConfig;\n serializable: boolean;\n hasDynamicData: boolean;\n headerComment?: string;\n description?: string;\n dataText: string;\n isBinary?: boolean;\n}\n\nexport const DEFAULT_CONFIG: MockFileConfig = {\n enable: true,\n data: null,\n delay: 0,\n status: 200,\n};\n\nconst isBufferTextLike = (buffer: Buffer): boolean => {\n try {\n const sample = buffer.slice(0, 100);\n const nullBytes = [...sample].filter((b) => b === 0).length;\n const controlChars = [...sample].filter(\n (b) => b < 32 && b !== 9 && b !== 10 && b !== 13,\n ).length;\n return nullBytes === 0 && controlChars < 5;\n } catch {\n return false;\n }\n};\n\nconst isBinaryResponse = (\n contentType: string | undefined,\n data: Buffer,\n): boolean => {\n if (!contentType) return false;\n\n const binaryTypes = [\n \"application/octet-stream\",\n \"application/pdf\",\n \"application/zip\",\n \"application/x-zip-compressed\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"image/\",\n \"video/\",\n \"audio/\",\n ];\n\n return (\n binaryTypes.some((type) => contentType.toLowerCase().includes(type)) ||\n !isBufferTextLike(data)\n );\n};\n\nconst getFileExtension = (\n contentType: string | undefined,\n url: string,\n): string => {\n const mimeMap: Record<string, string> = {\n \"application/json\": \"json\",\n \"application/pdf\": \"pdf\",\n \"application/zip\": \"zip\",\n \"application/vnd.ms-excel\": \"xls\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/msword\": \"doc\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"docx\",\n \"application/vnd.ms-powerpoint\": \"ppt\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\":\n \"pptx\",\n \"image/jpeg\": \"jpg\",\n \"image/png\": \"png\",\n \"image/gif\": \"gif\",\n \"text/plain\": \"txt\",\n \"text/html\": \"html\",\n \"text/css\": \"css\",\n \"application/javascript\": \"js\",\n \"text/xml\": \"xml\",\n };\n\n if (contentType && mimeMap[contentType.toLowerCase()]) {\n return mimeMap[contentType.toLowerCase()];\n }\n\n try {\n const urlObj = new URL(url, \"http://localhost\");\n const fileName = urlObj.searchParams.get(\"file_name\");\n if (fileName) {\n const extensionMatch = fileName.match(/\\.([a-zA-Z0-9]+)$/);\n if (extensionMatch) {\n return extensionMatch[1];\n }\n }\n } catch {\n // Ignore URL parse errors\n }\n\n return \"bin\";\n};\n\nasync function formatWithPrettier(content: string): Promise<string> {\n try {\n return await prettier.format(content, { parser: \"babel\" });\n } catch {\n return content;\n }\n}\n\nfunction buildMockFileHeader(\n pathname: string,\n method: string,\n search: string,\n extra?: string,\n): string {\n return `/**\n * Mock data for ${pathname} (${method.toUpperCase()})${search || \"\"}\n * @description ${pathname}${search || \"\"}${extra ? ` - ${extra}` : \"\"}\n * Generated at ${new Date().toISOString()}\n */`;\n}\n\nasync function saveBinaryMock(\n filePath: string,\n binaryData: Buffer,\n pathname: string,\n method: string,\n search: string,\n contentType: string | undefined,\n url: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n const extension = getFileExtension(contentType, url);\n const binaryFilePath = filePath.replace(/\\.js$/, \".\" + extension);\n\n if (fs.existsSync(binaryFilePath)) return null;\n\n fs.writeFileSync(binaryFilePath, binaryData);\n\n const header = buildMockFileHeader(pathname, method, search, `Binary file (${extension})`);\n const configContent = `${header}\nexport default {\n enable: false,\n data: {\n __binaryFile: '${extension}',\n __originalPath: '${pathname}',\n __originalQuery: '${search}',\n __originalUrl: '${pathname}${search || \"\"}',\n __contentType: '${contentType}',\n __fileSize: ${binaryData.length}\n },\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(configContent);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nasync function saveJsonMock(\n filePath: string,\n dataStr: string,\n pathname: string,\n method: string,\n search: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n if (fs.existsSync(filePath)) return null;\n\n let jsonData;\n if (!dataStr || dataStr.trim() === \"\") {\n jsonData = {\n error: true,\n message: `Empty response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: null,\n };\n } else {\n try {\n jsonData = JSON.parse(dataStr);\n if (statusCode && statusCode >= 400) {\n const errorMeta = { __mockStatusCode: statusCode, __isErrorResponse: true };\n jsonData =\n typeof jsonData === \"object\" && jsonData !== null\n ? { ...jsonData, ...errorMeta }\n : { originalData: jsonData, ...errorMeta };\n }\n } catch {\n jsonData = {\n error: true,\n message: `Non-JSON response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: dataStr,\n __mockStatusCode: statusCode,\n __isErrorResponse: true,\n };\n }\n }\n\n const header = buildMockFileHeader(pathname, method, search);\n const content = `${header}\nexport default {\n enable: false,\n data: ${JSON.stringify(jsonData)},\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(content);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nexport async function saveMockData(\n url: string,\n method: string,\n data: Buffer | string,\n rootDir: string,\n statusCode?: number,\n contentType?: string,\n): Promise<string | null> {\n try {\n const absoluteRootDir = resolveAbsolutePath(rootDir);\n const urlObj = new URL(url, \"http://localhost\");\n const pathname = urlObj.pathname;\n const search = urlObj.search;\n\n const filePath = path.join(\n absoluteRootDir,\n pathname.replace(/^\\//, \"\"),\n method.toLowerCase() + \".js\",\n );\n\n await fs.ensureDir(path.dirname(filePath));\n\n const isBuffer = Buffer.isBuffer(data);\n const binaryData = isBuffer ? data : Buffer.from(data || \"\");\n const isBinary = isBinaryResponse(contentType, binaryData);\n\n if (isBinary) {\n return saveBinaryMock(\n filePath, binaryData, pathname, method, search,\n contentType, url, statusCode,\n );\n }\n\n const dataStr = isBuffer ? data.toString(\"utf8\") : data || \"\";\n return saveJsonMock(filePath, dataStr, pathname, method, search, statusCode);\n } catch (error) {\n console.error(`Failed to save mock data for ${url}:`, error);\n console.error(\n `URL details: url=${url}, method=${method}, statusCode=${statusCode}, contentType=${contentType}`,\n );\n throw error;\n }\n}\n\nconst recursiveReadAllFiles = async (dir: string): Promise<string[]> => {\n if (!(await fs.pathExists(dir))) return [];\n\n const files: string[] = [];\n try {\n const list = await fs.readdir(dir);\n for (const file of list) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n files.push(...(await recursiveReadAllFiles(filePath)));\n } else {\n files.push(filePath);\n }\n }\n } catch (error) {\n console.error(`Error reading directory ${dir}:`, error);\n }\n return files;\n};\n\nexport async function buildMockIndex(mockDir: string): Promise<Map<string, string>> {\n const mockFileMap = new Map<string, string>();\n\n if (!(await fs.pathExists(mockDir))) {\n await fs.ensureDir(mockDir);\n return mockFileMap;\n }\n\n const files = await recursiveReadAllFiles(mockDir);\n\n files.forEach((filePath) => {\n if (!filePath.endsWith(\".js\")) return;\n\n try {\n const relativePath = path.relative(mockDir, filePath);\n const method = path.basename(filePath, \".js\");\n const dirPath = path.dirname(relativePath);\n const urlPath = \"/\" + toPosixPath(dirPath);\n const absolutePath = resolveAbsolutePath(filePath);\n const key = `${urlPath}/${method}.js`.toLowerCase();\n\n mockFileMap.set(key, absolutePath);\n } catch (error) {\n console.error(`[automock] Failed to process file ${filePath}:`, error);\n }\n });\n\n return mockFileMap;\n}\n\nexport async function parseMockModule(filePath: string): Promise<MockFileInfo> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n if (!fs.existsSync(absolutePath)) {\n throw new Error(`Mock file does not exist: ${absolutePath}`);\n }\n\n const content = fs.readFileSync(absolutePath, \"utf-8\");\n const headerCommentMatch = content.match(/^(\\/\\*\\*[\\s\\S]*?\\*\\/)/);\n const headerComment = headerCommentMatch ? headerCommentMatch[1] : undefined;\n\n let description: string | undefined;\n if (headerComment) {\n const descMatch = headerComment.match(/@description\\s+(.+?)(?:\\n|\\*\\/)/s);\n if (descMatch) {\n description = descMatch[1].trim();\n }\n }\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n\n const exportedConfig =\n typeof mockModule === \"function\" ? mockModule() : mockModule;\n const hasDynamicData = typeof exportedConfig?.data === \"function\";\n const config: MockFileConfig = {\n ...DEFAULT_CONFIG,\n ...(exportedConfig ?? {}),\n };\n\n const serializable = !hasDynamicData;\n const dataObj =\n typeof config.data === \"object\" && config.data !== null\n ? (config.data as Record<string, unknown>)\n : null;\n const isBinary = dataObj !== null && \"__binaryFile\" in dataObj;\n\n return {\n config,\n serializable,\n hasDynamicData,\n headerComment,\n description,\n dataText: isBinary\n ? `/* Binary file: ${dataObj?.__binaryFile} */`\n : serializable\n ? JSON.stringify(config.data ?? null, null, 2)\n : \"/* data is generated dynamically and cannot be edited here */\",\n isBinary,\n };\n}\n\nexport async function writeMockFile(\n filePath: string,\n mockInfo: Pick<MockFileInfo, \"config\" | \"headerComment\" | \"description\">,\n): Promise<void> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n let header = mockInfo.headerComment || \"\";\n\n if (mockInfo.description !== undefined) {\n if (header) {\n if (/@description/.test(header)) {\n header = header.replace(\n /@description\\s+.+?(?=\\n|\\*\\/)/s,\n `@description ${mockInfo.description}`,\n );\n } else {\n header = header.replace(\n /\\*\\//,\n ` * @description ${mockInfo.description}\\n */`,\n );\n }\n }\n }\n\n const content = header ? `${header}\\n` : \"\";\n const finalContent = `${content}export default ${JSON.stringify(mockInfo.config, null, 2)}\\n`;\n\n try {\n const formatted = await formatWithPrettier(finalContent);\n fs.writeFileSync(absolutePath, formatted, \"utf-8\");\n } catch {\n console.error(\"Error formatting code with prettier, writing raw content\");\n fs.writeFileSync(absolutePath, finalContent, \"utf-8\");\n }\n}\n","import path from \"path\";\n\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AddressInfo } from \"net\";\n\nexport function resolveAbsolutePath(p: string): string {\n return path.isAbsolute(p) ? p : path.resolve(process.cwd(), p);\n}\n\nexport function toPosixPath(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nexport interface ServerAddress {\n protocol: string;\n host: string;\n port: number;\n}\n\nexport function getServerAddress(\n address: AddressInfo,\n isHttps: boolean,\n): ServerAddress {\n return {\n protocol: isHttps ? \"https\" : \"http\",\n host:\n address.address === \"::\" || address.address === \"0.0.0.0\"\n ? \"localhost\"\n : address.address,\n port: address.port,\n };\n}\n\nexport function sendJson(\n res: ServerResponse,\n data: unknown,\n status = 200,\n): void {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n}\n\nexport function sendError(\n res: ServerResponse,\n message: string,\n status = 500,\n): void {\n sendJson(res, { error: message }, status);\n}\n\nconst MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let totalSize = 0;\n req.on(\"data\", (chunk: Buffer) => {\n totalSize += chunk.length;\n if (totalSize > MAX_BODY_SIZE) {\n reject(new Error(\"Request body too large\"));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport { fileURLToPath } from \"url\";\n\n// ESM/CJS compatible __dirname\nconst _dirName = typeof __dirname !== \"undefined\"\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url));\nimport { parseMockModule, writeMockFile, saveMockData, buildMockIndex, type MockFileConfig } from \"./mockFileUtils\";\nimport { toPosixPath, sendJson, readBody } from \"./utils\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AutomockPluginOptions, InspectorOptions } from \"./types\";\n\ninterface InspectorContext {\n req: IncomingMessage;\n res: ServerResponse;\n mockDir: string;\n inspectorRoute: string;\n apiPrefix: string;\n inspectorConfig: Required<InspectorOptions>;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorHandlerOptions {\n inspector: AutomockPluginOptions[\"inspector\"];\n apiPrefix: string;\n mockDir: string;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorApiContext extends InspectorContext {\n pathname: string;\n}\n\ninterface InspectorPayload {\n key: string;\n config?: Partial<MockFileConfig>;\n description?: string;\n}\n\ninterface MockItem {\n key: string;\n file: string;\n method: string;\n path: string;\n config: MockFileConfig;\n editable: boolean;\n description?: string;\n dataText: string;\n}\n\nfunction buildMockItem(\n key: string,\n filePath: string,\n mockDir: string,\n info: Awaited<ReturnType<typeof parseMockModule>>,\n): MockItem {\n return {\n key,\n file: path.relative(mockDir, filePath),\n method: key.split(\"/\").pop()?.replace(/\\.js$/, \"\") ?? \"get\",\n path: key.replace(/\\/[^/]+\\.js$/, \"\"),\n config: info.config,\n editable: info.serializable,\n description: info.description,\n dataText: info.dataText,\n };\n}\n\nexport const DEFAULT_ROUTE = \"/__mock/\";\n\nfunction ensureTrailingSlash(route: string): string {\n return route.endsWith(\"/\") ? route : `${route}/`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport function normalizeInspectorConfig(\n input: AutomockPluginOptions[\"inspector\"],\n): Required<InspectorOptions> {\n if (input === false || input === undefined) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n if (input === true) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n return {\n route: ensureTrailingSlash(input.route ?? DEFAULT_ROUTE),\n enableToggle: input.enableToggle ?? true,\n };\n}\n\nexport type InspectorRequestHandler = (\n req: IncomingMessage,\n res: ServerResponse,\n) => Promise<boolean>;\n\nexport function createInspectorHandler(\n options: InspectorHandlerOptions,\n): InspectorRequestHandler | null {\n if (!options.inspector) {\n return null;\n }\n\n const inspectorConfig = normalizeInspectorConfig(options.inspector);\n const inspectorRoute = ensureTrailingSlash(inspectorConfig.route);\n\n return async (req, res) => {\n if (!req.url) {\n return false;\n }\n const url = new URL(req.url, \"http://localhost\");\n if (!url.pathname.startsWith(inspectorRoute)) {\n return false;\n }\n\n await handleInspectorRequest({\n req,\n res,\n mockDir: options.mockDir,\n inspectorRoute,\n apiPrefix: options.apiPrefix,\n inspectorConfig,\n getMockFileMap: options.getMockFileMap,\n });\n\n return true;\n };\n}\n\nasync function handleInspectorRequest(\n context: InspectorContext,\n): Promise<void> {\n const { req, res, inspectorRoute } = context;\n const url = new URL(req.url || inspectorRoute, \"http://localhost\");\n const normalizedRoute = ensureTrailingSlash(inspectorRoute);\n\n if (\n url.pathname === normalizedRoute.slice(0, -1) ||\n url.pathname === normalizedRoute\n ) {\n await serveInspectorHtml(context);\n return;\n }\n\n const relativePath = url.pathname.startsWith(normalizedRoute)\n ? url.pathname.slice(normalizedRoute.length)\n : null;\n\n if (relativePath && relativePath.startsWith(\"api/\")) {\n await handleInspectorApi({ ...context, pathname: relativePath.slice(4) });\n return;\n }\n\n res.statusCode = 404;\n res.end(\"Not Found\");\n}\n\nasync function serveInspectorHtml({\n res,\n inspectorRoute,\n apiPrefix,\n inspectorConfig,\n}: InspectorContext): Promise<void> {\n const routeJson = JSON.stringify(ensureTrailingSlash(inspectorRoute));\n const allowToggleJson = JSON.stringify(inspectorConfig.enableToggle);\n const apiPrefixEscaped = escapeHtml(apiPrefix);\n\n const templatePath = path.join(_dirName, \"inspector-template.html\");\n const template = fs.readFileSync(templatePath, \"utf-8\");\n const html = template\n .replace(\"__API_PREFIX__\", apiPrefixEscaped)\n .replace(\"__ROUTE_JSON__\", routeJson)\n .replace(\"__ALLOW_TOGGLE_JSON__\", allowToggleJson);\n\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(html);\n}\n\nasync function handleList(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { res, mockDir } = ctx;\n const list = await Promise.all(\n Array.from(mockFileMap.entries()).map(async ([key, filePath]) => {\n const info = await parseMockModule(filePath);\n return buildMockItem(key, filePath, mockDir, info);\n }),\n );\n sendJson(res, { mocks: list });\n return true;\n}\n\nasync function handleDetail(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n const info = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, info) });\n return true;\n}\n\nasync function handleUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, inspectorConfig } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: InspectorPayload;\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { key, config, description } = payload || {};\n if (!key) {\n sendJson(res, { error: \"Invalid payload: missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n\n let nextConfig = info.config;\n if (config && typeof config === \"object\") {\n if (!inspectorConfig.enableToggle && config.enable !== undefined) {\n delete config.enable;\n }\n nextConfig = { ...info.config, ...config };\n }\n\n const nextDescription =\n description !== undefined ? description : info.description;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: nextDescription,\n });\n\n const updatedInfo = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, updatedInfo) });\n return true;\n}\n\nasync function handleCreate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, apiPrefix } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { method: string; path: string; description?: string; data?: unknown };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { method, path: apiPath, data } = payload || {};\n if (!method || !apiPath) {\n sendJson(res, { error: \"Invalid payload: missing method or path\" }, 400);\n return true;\n }\n\n const fullUrl = apiPrefix + apiPath;\n\n try {\n let dataToSave: Buffer | string;\n if (typeof data === \"object\" && data !== null) {\n dataToSave = JSON.stringify(data, null, 2);\n } else {\n dataToSave = typeof data === \"string\" ? data : \"\";\n }\n\n await saveMockData(fullUrl, method.toLowerCase(), dataToSave, mockDir, 200);\n\n const newMockFileMap = await buildMockIndex(mockDir);\n for (const [key, value] of newMockFileMap.entries()) {\n mockFileMap.set(key, value);\n }\n\n const normalizedPath = toPosixPath(apiPath);\n const key = (normalizedPath.startsWith(\"/\") ? \"\" : \"/\") +\n normalizedPath.toLowerCase() + \"/\" + method.toLowerCase() + \".js\";\n const filePath = mockFileMap.get(key);\n\n if (!filePath) {\n sendJson(res, { error: \"Mock file created but not found in map\" }, 500);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n sendJson(res, {\n success: true,\n mock: buildMockItem(key, filePath, mockDir, info),\n });\n return true;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to create mock: \" + errorMessage }, 500);\n return true;\n }\n}\n\nasync function handleDelete(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n try {\n const stats = await fs.stat(filePath);\n if (stats.isDirectory()) {\n await fs.remove(filePath);\n for (const [mapKey, mapPath] of mockFileMap.entries()) {\n if (mapPath.startsWith(filePath + path.sep) || mapPath === filePath) {\n mockFileMap.delete(mapKey);\n }\n }\n } else {\n await fs.unlink(filePath);\n mockFileMap.delete(key);\n }\n sendJson(res, { success: true });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to delete: \" + errorMessage }, 500);\n }\n return true;\n}\n\ntype ApiHandler = (ctx: InspectorApiContext, mockFileMap: Map<string, string>) => Promise<boolean>;\n\nasync function handleBatchUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { updates?: Array<{ key: string; config?: Record<string, unknown> }> };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const updates = payload?.updates;\n if (!Array.isArray(updates) || updates.length === 0) {\n sendJson(res, { error: \"Invalid payload: updates must be a non-empty array\" }, 400);\n return true;\n }\n\n let updated = 0;\n const errors: string[] = [];\n\n for (const item of updates) {\n const { key, config } = item;\n if (!key) continue;\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n errors.push(`Mock not found: ${key}`);\n continue;\n }\n\n try {\n const info = await parseMockModule(filePath);\n const nextConfig = config ? { ...info.config, ...config } : info.config;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: info.description,\n });\n updated++;\n } catch (err) {\n errors.push(`Failed to update ${key}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n sendJson(res, { success: true, updated, errors: errors.length > 0 ? errors : undefined });\n return true;\n}\n\nconst API_ROUTES: Record<string, ApiHandler> = {\n list: handleList,\n detail: handleDetail,\n update: handleUpdate,\n \"batch-update\": handleBatchUpdate,\n create: handleCreate,\n delete: handleDelete,\n};\n\nasync function handleInspectorApi(ctx: InspectorApiContext): Promise<void> {\n try {\n const mockFileMap = ctx.getMockFileMap();\n const handler = API_ROUTES[ctx.pathname];\n if (handler) {\n await handler(ctx, mockFileMap);\n return;\n }\n sendJson(ctx.res, { error: \"Unknown inspector endpoint\" }, 404);\n } catch (error) {\n console.error(\"[automock] Inspector request failed:\", error);\n sendJson(ctx.res, { error: \"Inspector failed\" }, 500);\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\n\nimport { buildMockIndex, parseMockModule } from './mockFileUtils'\n\nexport interface MockBundleData {\n enable: boolean\n data: unknown\n delay: number\n status: number\n isBinary?: boolean\n}\n\nexport interface MockBundle {\n [key: string]: MockBundleData\n}\n\nexport interface BundleOptions {\n mockDir: string\n includeDisabled?: boolean\n log?: boolean\n}\n\nconst DEFAULT_BUNDLE_OPTIONS: Partial<BundleOptions> = {\n includeDisabled: true,\n log: true\n}\n\nasync function bundleMockFiles(options: BundleOptions): Promise<MockBundle> {\n const opts = { ...DEFAULT_BUNDLE_OPTIONS, ...options }\n const { mockDir, log } = opts\n\n if (!fs.existsSync(mockDir)) {\n if (log) {\n console.log(`[mock-bundler] Mock directory does not exist: ${mockDir}`)\n }\n return {}\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n const bundle: MockBundle = {}\n let bundledCount = 0\n let skippedCount = 0\n\n for (const [key, filePath] of mockFileMap) {\n try {\n const mockInfo = await parseMockModule(filePath)\n\n if (!mockInfo.serializable) {\n skippedCount++\n if (log) {\n console.log(`[mock-bundler] Skipping non-serializable mock: ${key}`)\n }\n continue\n }\n\n bundle[key] = {\n enable: mockInfo.config.enable,\n data: mockInfo.config.data,\n delay: mockInfo.config.delay,\n status: mockInfo.config.status,\n isBinary: mockInfo.isBinary\n }\n\n bundledCount++\n } catch (error) {\n if (log) {\n console.error(`[mock-bundler] Failed to bundle mock ${key}:`, error)\n }\n }\n }\n\n if (log) {\n console.log(`[mock-bundler] Bundled ${bundledCount} mocks, skipped ${skippedCount} non-serializable mocks`)\n }\n\n return bundle\n}\n\nfunction writeMockBundle(bundle: MockBundle, outputPath: string): void {\n const outputDir = path.dirname(outputPath)\n\n if (!fs.existsSync(outputDir)) {\n fs.ensureDirSync(outputDir)\n }\n\n fs.writeFileSync(\n outputPath,\n JSON.stringify(bundle, null, 2),\n 'utf-8'\n )\n}\n\nexport { bundleMockFiles, writeMockBundle }\n","import type {\n AxiosInstance,\n AxiosResponse,\n InternalAxiosRequestConfig,\n} from \"axios\";\n\ndeclare const __AUTOMOCK_ENABLED__: boolean;\n\nexport type MockBundleData = {\n enable: boolean;\n data: unknown;\n delay?: number;\n status?: number;\n isBinary?: boolean;\n};\n\nexport type MockInterceptorOptions = {\n mockData: Record<string, MockBundleData>;\n enabled?: boolean | (() => boolean);\n onMockHit?: (url: string, method: string, mock: MockBundleData) => void;\n onBypass?: (url: string, method: string, reason: string) => void;\n};\n\ntype MockEnabledState = boolean | undefined;\n\ndeclare global {\n interface Window {\n __MOCK_ENABLED__?: MockEnabledState;\n }\n}\n\nclass MockInterceptor {\n private options: MockInterceptorOptions;\n\n constructor(options: MockInterceptorOptions) {\n this.options = options;\n }\n\n /**\n * Check if mock is enabled\n */\n isEnabled(): boolean {\n // Check runtime flag first\n if (window.__MOCK_ENABLED__ !== undefined) {\n return window.__MOCK_ENABLED__;\n }\n // Check environment variable\n if (typeof this.options.enabled === \"function\") {\n return this.options.enabled();\n }\n return this.options.enabled ?? false;\n }\n\n /**\n * Find matching mock data for the request\n * Supports both formats:\n * - \"GET /api/v1/asset/xxx\" (HTTP method + URL)\n * - \"/api/v1/asset/xxx/get.js\" (File path format from automock plugin)\n */\n private findMock(url: string, method: string): MockBundleData | null {\n const methodUpper = method.toUpperCase();\n const methodLower = method.toLowerCase();\n\n // Try HTTP method + URL format first (for compatibility)\n const httpMethodKey = `${methodUpper} ${url}`;\n if (this.options.mockData[httpMethodKey]) {\n return this.options.mockData[httpMethodKey];\n }\n\n // Try file path format from automock plugin: /api/v1/asset/xxx/get.js\n const filePathKey = `${url}/${methodLower}.js`;\n if (this.options.mockData[filePathKey]) {\n return this.options.mockData[filePathKey];\n }\n\n return null;\n }\n\n /**\n * Determine if request should be mocked\n */\n shouldMock(url: string, method: string): boolean {\n if (!this.isEnabled()) {\n return false;\n }\n\n const mock = this.findMock(url, method);\n return mock !== null && mock.enable;\n }\n\n /**\n * Get mock data for request\n */\n getMock(url: string, method: string): MockBundleData | null {\n if (!this.shouldMock(url, method)) {\n return null;\n }\n return this.findMock(url, method);\n }\n\n /**\n * Setup axios interceptor\n */\n setupAxios(axiosInstance: AxiosInstance): void {\n axiosInstance.interceptors.request.use(\n async (config: InternalAxiosRequestConfig) => {\n const url = config.url || \"\";\n const method = config.method?.toUpperCase() || \"GET\";\n\n const mock = this.getMock(url, method);\n\n if (mock) {\n // Trigger mock hit callback\n this.options.onMockHit?.(url, method, mock);\n\n // Set adapter to return mock data\n (config as InternalAxiosRequestConfig & { adapter: () => Promise<AxiosResponse> }).adapter = async () => {\n const { data, delay = 0, status = 200 } = mock;\n\n // Simulate delay\n if (delay > 0) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n\n return {\n data,\n status,\n statusText: \"OK\",\n headers: {},\n config,\n };\n };\n } else {\n // Trigger bypass callback\n const reason = !this.isEnabled()\n ? \"Mock disabled globally\"\n : \"No matching mock found or mock disabled\";\n this.options.onBypass?.(url, method, reason);\n }\n\n return config;\n },\n (error: unknown) => Promise.reject(error),\n );\n }\n}\n\n/**\n * Create mock interceptor instance\n */\nexport function createMockInterceptor(\n options: MockInterceptorOptions,\n): MockInterceptor {\n return new MockInterceptor(options);\n}\n\n/**\n * Load mock data from bundled JSON file\n */\nexport async function loadMockData(): Promise<Record<string, MockBundleData>> {\n try {\n // In production, mock-data.json is generated by automock plugin\n // Use absolute path to load it from dist directory\n const response = await fetch(\"/mock-data.json\");\n if (!response.ok) {\n console.warn(\n \"[MockInterceptor] Failed to load mock-data.json:\",\n response.statusText,\n );\n return {};\n }\n const data = (await response.json()) as Record<string, MockBundleData>;\n return data;\n } catch (error) {\n console.warn(\"[MockInterceptor] Failed to load mock-data.json:\", error);\n return {};\n }\n}\n\nasync function createInterceptorFromBundle(): Promise<MockInterceptor> {\n const mockData = await loadMockData();\n const isEnabled = typeof __AUTOMOCK_ENABLED__ !== \"undefined\" && __AUTOMOCK_ENABLED__;\n\n return new MockInterceptor({\n mockData,\n enabled: isEnabled,\n onMockHit: (url: string, method: string) => {\n console.log(`[MOCK HIT] ${method} ${url}`);\n },\n onBypass: (url: string, method: string, reason: string) => {\n console.log(`[MOCK BYPASS] ${method} ${url} - ${reason}`);\n },\n });\n}\n\nexport async function initMockInterceptor(\n axiosInstance?: AxiosInstance,\n): Promise<void> {\n if (!axiosInstance) {\n throw new Error(\n \"[MockInterceptor] axiosInstance is required. Please provide an axios instance.\",\n );\n }\n\n const interceptor = await createInterceptorFromBundle();\n interceptor.setupAxios(axiosInstance);\n}\n\nexport function setMockEnabled(enabled: boolean): void {\n window.__MOCK_ENABLED__ = enabled;\n}\n\nexport function isMockEnabled(): boolean {\n return !!window.__MOCK_ENABLED__;\n}\n\ntype HttpInstance = {\n constructor: { axiosInstance: AxiosInstance };\n};\n\nlet httpInstanceRef: HttpInstance | undefined;\n\nexport function registerHttpInstance(http: HttpInstance): void {\n httpInstanceRef = http;\n}\n\nexport async function initMockInterceptorForPureHttp(): Promise<void> {\n if (!httpInstanceRef) {\n throw new Error(\n \"[MockInterceptor] http instance not registered. Call registerHttpInstance(http) first.\",\n );\n }\n\n const interceptor = await createInterceptorFromBundle();\n interceptor.setupAxios(httpInstanceRef.constructor.axiosInstance);\n}\n"],"mappings":"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","names":["automock","import_path","import_fs_extra","import_path","import_fs_extra","import_path","path","prettier","fs","path","import_path","import_fs_extra","path","fs","key","fs","https","http","path","debounce","chokidar","import_path","import_fs_extra","fs","path","http","automock","path","fs"]}
|
package/dist/index.mjs
CHANGED
|
@@ -795,10 +795,8 @@ function proxyAndCapture(req, res, options) {
|
|
|
795
795
|
let bodyStr = "";
|
|
796
796
|
req.on("data", (chunk) => bodyStr += chunk.toString());
|
|
797
797
|
req.on("end", () => sendProxyRequest(bodyStr));
|
|
798
|
-
} else if (req.readableEnded) {
|
|
799
|
-
sendProxyRequest();
|
|
800
798
|
} else {
|
|
801
|
-
|
|
799
|
+
sendProxyRequest();
|
|
802
800
|
}
|
|
803
801
|
}
|
|
804
802
|
function printServerUrls(server, urls) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/mockFileUtils.ts","../src/utils.ts","../src/inspector.ts","../src/mockBundler.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\n\nimport { automock as createAutomockPlugin } from './middleware'\nimport { bundleMockFiles, writeMockBundle } from './mockBundler'\nimport { buildMockIndex } from './mockFileUtils'\nimport type { Plugin } from 'vite'\nimport type { AutomockPluginOptions } from './types'\nimport type { MockBundle } from './mockBundler'\n\nexport type { AutomockPluginOptions, InspectorOptions } from './types'\nexport { saveMockData, buildMockIndex, parseMockModule, writeMockFile } from './mockFileUtils'\nexport type { MockBundle, MockBundleData } from './mockBundler'\nexport { bundleMockFiles, writeMockBundle } from './mockBundler'\n\n// Client interceptor exports\nexport {\n createMockInterceptor,\n initMockInterceptor,\n initMockInterceptorForPureHttp,\n setMockEnabled,\n isMockEnabled,\n loadMockData,\n registerHttpInstance\n} from './client'\nexport type { MockInterceptorOptions, MockBundleData as ClientMockBundleData } from './client/interceptor'\n\nexport interface AutomockWithBundleOptions extends AutomockPluginOptions {\n bundleMockData?: boolean\n bundleOutputPath?: string\n}\n\nexport function automock(options: AutomockWithBundleOptions = {}): Plugin {\n const {\n bundleMockData = true,\n bundleOutputPath = 'public/mock-data.json',\n ...pluginOptions\n } = options\n\n const basePlugin = createAutomockPlugin(pluginOptions)\n\n let cachedBundle: MockBundle | null = null\n\n const ensureBundleExists = () => {\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n if (!fs.existsSync(outputPath) && cachedBundle) {\n console.log('[automock] Re-writing mock bundle...')\n writeMockBundle(cachedBundle, outputPath)\n }\n }\n\n return {\n ...basePlugin,\n name: 'vite-plugin-automock-with-bundle',\n config() {\n // Inject compile-time constant for client interceptor\n const enabled = pluginOptions.productionMock !== false\n return {\n define: {\n __AUTOMOCK_ENABLED__: JSON.stringify(enabled),\n },\n }\n },\n buildEnd: async () => {\n if (bundleMockData && pluginOptions.productionMock !== false) {\n try {\n const mockDir = pluginOptions.mockDir || path.join(process.cwd(), 'mock')\n\n if (!fs.existsSync(mockDir)) {\n console.log('[automock] Mock directory not found, skipping bundle generation')\n console.log('[automock] Using existing mock-data.json if present')\n return\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n if (mockFileMap.size === 0) {\n console.log('[automock] No mock files found, skipping bundle generation')\n return\n }\n\n cachedBundle = await bundleMockFiles({ mockDir })\n\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n writeMockBundle(cachedBundle, outputPath)\n console.log(`[automock] Mock bundle written to: ${outputPath}`)\n } catch (error) {\n console.error('[automock] Failed to bundle mock data:', error)\n }\n }\n },\n writeBundle: ensureBundleExists,\n closeBundle: ensureBundleExists,\n }\n}\n\n","import chokidar from \"chokidar\";\nimport debounce from \"lodash.debounce\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport http from \"http\";\nimport https from \"https\";\nimport type { AddressInfo } from \"net\";\n\nimport { buildMockIndex, saveMockData } from \"./mockFileUtils\";\nimport { createInspectorHandler, normalizeInspectorConfig } from \"./inspector\";\nimport {\n resolveAbsolutePath,\n getServerAddress,\n sendError,\n} from \"./utils\";\n\nimport type { Plugin } from \"vite\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { FSWatcher } from \"chokidar\";\nimport type { AutomockPluginOptions } from \"./types\";\n\nfunction serveMockResponse(\n res: ServerResponse,\n mockFilePath: string,\n mockResult: { data?: unknown; delay?: number; status?: number },\n): void {\n const { data, delay = 0, status = 200 } = mockResult;\n\n setTimeout(() => {\n const isBinaryMock = data && typeof data === \"object\" && (data as Record<string, unknown>).__binaryFile;\n\n if (isBinaryMock) {\n const binaryData = data as Record<string, unknown>;\n const binaryFilePath = mockFilePath.replace(\n /\\.js$/,\n \".\" + binaryData.__binaryFile,\n );\n\n if (!fs.existsSync(binaryFilePath)) {\n console.error(\n `[automock] Binary mock file not found: ${binaryFilePath}`,\n );\n sendError(res, \"Binary mock file not found\", 404);\n return;\n }\n\n try {\n const fileData = fs.readFileSync(binaryFilePath);\n const contentType =\n (binaryData.__contentType as string) || \"application/octet-stream\";\n res.setHeader(\"Content-Type\", contentType);\n res.setHeader(\"Content-Length\", fileData.length);\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.setHeader(\"X-Mock-Binary-File\", \"true\");\n res.statusCode = status;\n res.end(fileData);\n } catch (error) {\n console.error(\"[automock] Failed to read binary mock file:\", error);\n sendError(res, \"Failed to read binary mock file\");\n }\n } else {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n }\n }, delay);\n}\n\nfunction proxyAndCapture(\n req: IncomingMessage,\n res: ServerResponse,\n options: {\n proxyBaseUrl: string;\n pathRewrite: (p: string) => string;\n shouldSave: boolean;\n method: string;\n pathname: string;\n mockDir: string;\n onMockSaved: () => void;\n },\n): void {\n const { proxyBaseUrl, pathRewrite, shouldSave, method, pathname, mockDir, onMockSaved } = options;\n const targetUrl = proxyBaseUrl + pathRewrite(req.url || \"\");\n const client = targetUrl.startsWith(\"https\") ? https : http;\n\n function sendProxyRequest(body?: string) {\n const targetUrlObj = new URL(proxyBaseUrl);\n const proxyOptions = {\n method: req.method,\n headers: {\n ...req.headers,\n host: targetUrlObj.host,\n },\n rejectUnauthorized: false,\n };\n\n const proxyReq = client.request(targetUrl, proxyOptions, (proxyRes) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isJson = contentType.includes(\"application/json\");\n\n // Non-JSON response (file download, stream, etc.) → pipe directly\n if (!isJson) {\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // JSON response → buffer, save mock, then respond\n const chunks: Buffer[] = [];\n\n proxyRes.on(\"data\", (chunk) => chunks.push(chunk));\n proxyRes.on(\"end\", async () => {\n try {\n const responseData = Buffer.concat(chunks);\n\n if (shouldSave) {\n try {\n console.log(\n `[automock] Capturing mock: ${req.url!} -> ${pathname}`,\n );\n const savedFilePath = await saveMockData(\n req.url!,\n method,\n responseData,\n mockDir,\n proxyRes.statusCode,\n contentType,\n );\n if (savedFilePath) {\n console.log(`[automock] Mock saved: ${pathname}`);\n onMockSaved();\n } else {\n console.log(\n `[automock] Mock file already exists, skipped: ${pathname}`,\n );\n }\n } catch (saveError) {\n console.error(\"[automock] Failed to save mock:\", saveError);\n }\n }\n\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(responseData);\n } catch (error) {\n console.error(\"[automock] Failed to process response:\", error);\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(Buffer.concat(chunks));\n }\n });\n });\n\n proxyReq.on(\"error\", (err) => {\n console.error(\"[automock] Proxy request failed:\", err);\n sendError(res, err.message);\n });\n\n if (\n body &&\n (req.method === \"POST\" || req.method === \"PUT\" || req.method === \"PATCH\")\n ) {\n proxyReq.write(body);\n }\n\n proxyReq.end();\n }\n\n if (\n req.method === \"POST\" ||\n req.method === \"PUT\" ||\n req.method === \"PATCH\"\n ) {\n let bodyStr = \"\";\n req.on(\"data\", (chunk) => (bodyStr += chunk.toString()));\n req.on(\"end\", () => sendProxyRequest(bodyStr));\n } else if (req.readableEnded) {\n sendProxyRequest();\n } else {\n req.on(\"end\", () => sendProxyRequest());\n }\n}\n\nfunction printServerUrls(\n server: { httpServer?: { address(): AddressInfo | string | null; once(event: string, cb: () => void): void } | null; config: { server: { https?: unknown } } },\n urls: Array<{ path: string; label: string; color: string; delay: number }>,\n): void {\n server.httpServer?.once(\"listening\", () => {\n const address = server.httpServer?.address();\n if (!address || typeof address !== \"object\") return;\n\n const { protocol, host, port } = getServerAddress(\n address,\n !!server.config.server.https,\n );\n\n for (const { path: urlPath, label, color, delay } of urls) {\n setTimeout(() => {\n const fullUrl = `${protocol}://${host}:${port}${urlPath}`;\n console.log(` ➜ ${color}${label}\\x1b[0m: \\x1b[1m${fullUrl}\\x1b[0m`);\n }, delay);\n }\n });\n}\n\nexport function automock(options: AutomockPluginOptions): Plugin {\n const {\n mockDir: configMockDir = path.join(process.cwd(), \"mock\"),\n apiPrefix = \"/api\",\n pathRewrite = (p) => p,\n proxyBaseUrl,\n inspector = false,\n } = options;\n\n const mockDir = resolveAbsolutePath(configMockDir);\n\n if (!fs.existsSync(mockDir)) {\n try {\n fs.ensureDirSync(mockDir);\n console.log(`[automock] Mock directory created: ${mockDir}`);\n } catch (error) {\n console.error(`[automock] Failed to create mock directory: ${mockDir}`, error);\n }\n }\n\n let watcher: FSWatcher | undefined;\n\n return {\n name: \"vite-plugin-automock\",\n config(userConfig) {\n if (proxyBaseUrl && userConfig.server?.proxy) {\n const proxyConfig = userConfig.server.proxy;\n const hasConflictingPrefix =\n typeof proxyConfig === \"object\" && apiPrefix in proxyConfig;\n\n if (hasConflictingPrefix) {\n console.warn(\n `\\n⚠️ [automock] WARNING: You have both Vite's server.proxy[\"${apiPrefix}\"] and automock's proxyBaseUrl configured.`,\n );\n console.warn(\n ` This may cause request conflicts. Remove the \"${apiPrefix}\" entry from vite.config.ts server.proxy to avoid issues.`,\n );\n console.warn(\n ` Automock will handle all ${apiPrefix} requests when proxyBaseUrl is set.\\n`,\n );\n }\n }\n },\n async configureServer(server) {\n let mockFileMap = await buildMockIndex(mockDir);\n console.log(`[automock] Loaded ${mockFileMap.size} mock files`);\n\n const rebuildMockFileMap = debounce(async () => {\n mockFileMap = await buildMockIndex(mockDir);\n }, 200);\n\n watcher = chokidar.watch(mockDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 30,\n });\n watcher.on(\"add\", () => rebuildMockFileMap());\n watcher.on(\"unlink\", () => rebuildMockFileMap());\n\n server.httpServer?.on(\"close\", () => watcher?.close());\n\n const inspectorHandler = createInspectorHandler({\n inspector,\n apiPrefix,\n mockDir,\n getMockFileMap: () => mockFileMap,\n });\n\n const urlsToPrint: Array<{ path: string; label: string; color: string; delay: number }> = [\n { path: apiPrefix, label: \"Mock API\", color: \"\\x1b[32m\", delay: 100 },\n ];\n\n if (inspector) {\n const inspectorConfig = normalizeInspectorConfig(inspector);\n urlsToPrint.push({\n path: inspectorConfig.route,\n label: \"Mock Inspector\",\n color: \"\\x1b[95m\",\n delay: 150,\n });\n }\n\n printServerUrls(server, urlsToPrint);\n\n async function tryLoadMock(key: string): Promise<{ absolutePath: string; mockResult: Record<string, unknown> } | null> {\n const mockFilePath = mockFileMap.get(key);\n if (!mockFilePath) return null;\n\n const absolutePath = resolveAbsolutePath(mockFilePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n const mockResult =\n typeof mockModule.data === \"function\"\n ? mockModule.data()\n : mockModule;\n\n const { enable = true } = mockResult || {};\n return enable ? { absolutePath, mockResult } : null;\n }\n\n server.middlewares.use(\n async (\n req: IncomingMessage,\n res: ServerResponse,\n next: (err?: Error | unknown) => void,\n ): Promise<void> => {\n if (inspectorHandler && req.url) {\n const handled = await inspectorHandler(req, res);\n if (handled) return;\n }\n\n if (!req.url?.startsWith(apiPrefix)) {\n return next();\n }\n\n // Skip non-standard requests (SSE, WebSocket, file streams)\n const accept = req.headers.accept || \"\";\n const upgrade = req.headers.upgrade || \"\";\n if (accept.includes(\"text/event-stream\") || upgrade.toLowerCase() === \"websocket\") {\n return next();\n }\n\n const method = (req.method || \"GET\").toLowerCase();\n const pathname = new URL(req.url, \"http://localhost\").pathname;\n const key = `${pathname}/${method}.js`.toLowerCase();\n\n // 1. Try mock\n try {\n const mock = await tryLoadMock(key);\n if (mock) {\n serveMockResponse(res, mock.absolutePath, mock.mockResult);\n return;\n }\n } catch (error) {\n console.error(\"[automock] Failed to load mock file:\", error);\n }\n\n // 2. Try proxy\n if (!proxyBaseUrl) return next();\n\n try {\n proxyAndCapture(req, res, {\n proxyBaseUrl,\n pathRewrite,\n shouldSave: !mockFileMap.has(key),\n method,\n pathname,\n mockDir,\n onMockSaved: async () => {\n mockFileMap = await buildMockIndex(mockDir);\n },\n });\n } catch (error) {\n console.error(\"[automock] Proxy request error:\", error);\n sendError(res, \"Internal server error\");\n }\n },\n );\n },\n closeBundle() {\n watcher?.close();\n },\n transform() {\n return null;\n },\n };\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport prettier from \"prettier\";\n\nimport { resolveAbsolutePath, toPosixPath } from \"./utils\";\n\nexport interface MockFileConfig {\n enable: boolean;\n data: unknown;\n delay: number;\n status: number;\n [key: string]: unknown;\n}\n\nexport interface MockFileInfo {\n config: MockFileConfig;\n serializable: boolean;\n hasDynamicData: boolean;\n headerComment?: string;\n description?: string;\n dataText: string;\n isBinary?: boolean;\n}\n\nexport const DEFAULT_CONFIG: MockFileConfig = {\n enable: true,\n data: null,\n delay: 0,\n status: 200,\n};\n\nconst isBufferTextLike = (buffer: Buffer): boolean => {\n try {\n const sample = buffer.slice(0, 100);\n const nullBytes = [...sample].filter((b) => b === 0).length;\n const controlChars = [...sample].filter(\n (b) => b < 32 && b !== 9 && b !== 10 && b !== 13,\n ).length;\n return nullBytes === 0 && controlChars < 5;\n } catch {\n return false;\n }\n};\n\nconst isBinaryResponse = (\n contentType: string | undefined,\n data: Buffer,\n): boolean => {\n if (!contentType) return false;\n\n const binaryTypes = [\n \"application/octet-stream\",\n \"application/pdf\",\n \"application/zip\",\n \"application/x-zip-compressed\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"image/\",\n \"video/\",\n \"audio/\",\n ];\n\n return (\n binaryTypes.some((type) => contentType.toLowerCase().includes(type)) ||\n !isBufferTextLike(data)\n );\n};\n\nconst getFileExtension = (\n contentType: string | undefined,\n url: string,\n): string => {\n const mimeMap: Record<string, string> = {\n \"application/json\": \"json\",\n \"application/pdf\": \"pdf\",\n \"application/zip\": \"zip\",\n \"application/vnd.ms-excel\": \"xls\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/msword\": \"doc\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"docx\",\n \"application/vnd.ms-powerpoint\": \"ppt\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\":\n \"pptx\",\n \"image/jpeg\": \"jpg\",\n \"image/png\": \"png\",\n \"image/gif\": \"gif\",\n \"text/plain\": \"txt\",\n \"text/html\": \"html\",\n \"text/css\": \"css\",\n \"application/javascript\": \"js\",\n \"text/xml\": \"xml\",\n };\n\n if (contentType && mimeMap[contentType.toLowerCase()]) {\n return mimeMap[contentType.toLowerCase()];\n }\n\n try {\n const urlObj = new URL(url, \"http://localhost\");\n const fileName = urlObj.searchParams.get(\"file_name\");\n if (fileName) {\n const extensionMatch = fileName.match(/\\.([a-zA-Z0-9]+)$/);\n if (extensionMatch) {\n return extensionMatch[1];\n }\n }\n } catch {\n // Ignore URL parse errors\n }\n\n return \"bin\";\n};\n\nasync function formatWithPrettier(content: string): Promise<string> {\n try {\n return await prettier.format(content, { parser: \"babel\" });\n } catch {\n return content;\n }\n}\n\nfunction buildMockFileHeader(\n pathname: string,\n method: string,\n search: string,\n extra?: string,\n): string {\n return `/**\n * Mock data for ${pathname} (${method.toUpperCase()})${search || \"\"}\n * @description ${pathname}${search || \"\"}${extra ? ` - ${extra}` : \"\"}\n * Generated at ${new Date().toISOString()}\n */`;\n}\n\nasync function saveBinaryMock(\n filePath: string,\n binaryData: Buffer,\n pathname: string,\n method: string,\n search: string,\n contentType: string | undefined,\n url: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n const extension = getFileExtension(contentType, url);\n const binaryFilePath = filePath.replace(/\\.js$/, \".\" + extension);\n\n if (fs.existsSync(binaryFilePath)) return null;\n\n fs.writeFileSync(binaryFilePath, binaryData);\n\n const header = buildMockFileHeader(pathname, method, search, `Binary file (${extension})`);\n const configContent = `${header}\nexport default {\n enable: false,\n data: {\n __binaryFile: '${extension}',\n __originalPath: '${pathname}',\n __originalQuery: '${search}',\n __originalUrl: '${pathname}${search || \"\"}',\n __contentType: '${contentType}',\n __fileSize: ${binaryData.length}\n },\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(configContent);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nasync function saveJsonMock(\n filePath: string,\n dataStr: string,\n pathname: string,\n method: string,\n search: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n if (fs.existsSync(filePath)) return null;\n\n let jsonData;\n if (!dataStr || dataStr.trim() === \"\") {\n jsonData = {\n error: true,\n message: `Empty response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: null,\n };\n } else {\n try {\n jsonData = JSON.parse(dataStr);\n if (statusCode && statusCode >= 400) {\n const errorMeta = { __mockStatusCode: statusCode, __isErrorResponse: true };\n jsonData =\n typeof jsonData === \"object\" && jsonData !== null\n ? { ...jsonData, ...errorMeta }\n : { originalData: jsonData, ...errorMeta };\n }\n } catch {\n jsonData = {\n error: true,\n message: `Non-JSON response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: dataStr,\n __mockStatusCode: statusCode,\n __isErrorResponse: true,\n };\n }\n }\n\n const header = buildMockFileHeader(pathname, method, search);\n const content = `${header}\nexport default {\n enable: false,\n data: ${JSON.stringify(jsonData)},\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(content);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nexport async function saveMockData(\n url: string,\n method: string,\n data: Buffer | string,\n rootDir: string,\n statusCode?: number,\n contentType?: string,\n): Promise<string | null> {\n try {\n const absoluteRootDir = resolveAbsolutePath(rootDir);\n const urlObj = new URL(url, \"http://localhost\");\n const pathname = urlObj.pathname;\n const search = urlObj.search;\n\n const filePath = path.join(\n absoluteRootDir,\n pathname.replace(/^\\//, \"\"),\n method.toLowerCase() + \".js\",\n );\n\n await fs.ensureDir(path.dirname(filePath));\n\n const isBuffer = Buffer.isBuffer(data);\n const binaryData = isBuffer ? data : Buffer.from(data || \"\");\n const isBinary = isBinaryResponse(contentType, binaryData);\n\n if (isBinary) {\n return saveBinaryMock(\n filePath, binaryData, pathname, method, search,\n contentType, url, statusCode,\n );\n }\n\n const dataStr = isBuffer ? data.toString(\"utf8\") : data || \"\";\n return saveJsonMock(filePath, dataStr, pathname, method, search, statusCode);\n } catch (error) {\n console.error(`Failed to save mock data for ${url}:`, error);\n console.error(\n `URL details: url=${url}, method=${method}, statusCode=${statusCode}, contentType=${contentType}`,\n );\n throw error;\n }\n}\n\nconst recursiveReadAllFiles = async (dir: string): Promise<string[]> => {\n if (!(await fs.pathExists(dir))) return [];\n\n const files: string[] = [];\n try {\n const list = await fs.readdir(dir);\n for (const file of list) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n files.push(...(await recursiveReadAllFiles(filePath)));\n } else {\n files.push(filePath);\n }\n }\n } catch (error) {\n console.error(`Error reading directory ${dir}:`, error);\n }\n return files;\n};\n\nexport async function buildMockIndex(mockDir: string): Promise<Map<string, string>> {\n const mockFileMap = new Map<string, string>();\n\n if (!(await fs.pathExists(mockDir))) {\n await fs.ensureDir(mockDir);\n return mockFileMap;\n }\n\n const files = await recursiveReadAllFiles(mockDir);\n\n files.forEach((filePath) => {\n if (!filePath.endsWith(\".js\")) return;\n\n try {\n const relativePath = path.relative(mockDir, filePath);\n const method = path.basename(filePath, \".js\");\n const dirPath = path.dirname(relativePath);\n const urlPath = \"/\" + toPosixPath(dirPath);\n const absolutePath = resolveAbsolutePath(filePath);\n const key = `${urlPath}/${method}.js`.toLowerCase();\n\n mockFileMap.set(key, absolutePath);\n } catch (error) {\n console.error(`[automock] Failed to process file ${filePath}:`, error);\n }\n });\n\n return mockFileMap;\n}\n\nexport async function parseMockModule(filePath: string): Promise<MockFileInfo> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n if (!fs.existsSync(absolutePath)) {\n throw new Error(`Mock file does not exist: ${absolutePath}`);\n }\n\n const content = fs.readFileSync(absolutePath, \"utf-8\");\n const headerCommentMatch = content.match(/^(\\/\\*\\*[\\s\\S]*?\\*\\/)/);\n const headerComment = headerCommentMatch ? headerCommentMatch[1] : undefined;\n\n let description: string | undefined;\n if (headerComment) {\n const descMatch = headerComment.match(/@description\\s+(.+?)(?:\\n|\\*\\/)/s);\n if (descMatch) {\n description = descMatch[1].trim();\n }\n }\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n\n const exportedConfig =\n typeof mockModule === \"function\" ? mockModule() : mockModule;\n const hasDynamicData = typeof exportedConfig?.data === \"function\";\n const config: MockFileConfig = {\n ...DEFAULT_CONFIG,\n ...(exportedConfig ?? {}),\n };\n\n const serializable = !hasDynamicData;\n const dataObj =\n typeof config.data === \"object\" && config.data !== null\n ? (config.data as Record<string, unknown>)\n : null;\n const isBinary = dataObj !== null && \"__binaryFile\" in dataObj;\n\n return {\n config,\n serializable,\n hasDynamicData,\n headerComment,\n description,\n dataText: isBinary\n ? `/* Binary file: ${dataObj?.__binaryFile} */`\n : serializable\n ? JSON.stringify(config.data ?? null, null, 2)\n : \"/* data is generated dynamically and cannot be edited here */\",\n isBinary,\n };\n}\n\nexport async function writeMockFile(\n filePath: string,\n mockInfo: Pick<MockFileInfo, \"config\" | \"headerComment\" | \"description\">,\n): Promise<void> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n let header = mockInfo.headerComment || \"\";\n\n if (mockInfo.description !== undefined) {\n if (header) {\n if (/@description/.test(header)) {\n header = header.replace(\n /@description\\s+.+?(?=\\n|\\*\\/)/s,\n `@description ${mockInfo.description}`,\n );\n } else {\n header = header.replace(\n /\\*\\//,\n ` * @description ${mockInfo.description}\\n */`,\n );\n }\n }\n }\n\n const content = header ? `${header}\\n` : \"\";\n const finalContent = `${content}export default ${JSON.stringify(mockInfo.config, null, 2)}\\n`;\n\n try {\n const formatted = await formatWithPrettier(finalContent);\n fs.writeFileSync(absolutePath, formatted, \"utf-8\");\n } catch {\n console.error(\"Error formatting code with prettier, writing raw content\");\n fs.writeFileSync(absolutePath, finalContent, \"utf-8\");\n }\n}\n","import path from \"path\";\n\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AddressInfo } from \"net\";\n\nexport function resolveAbsolutePath(p: string): string {\n return path.isAbsolute(p) ? p : path.resolve(process.cwd(), p);\n}\n\nexport function toPosixPath(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nexport interface ServerAddress {\n protocol: string;\n host: string;\n port: number;\n}\n\nexport function getServerAddress(\n address: AddressInfo,\n isHttps: boolean,\n): ServerAddress {\n return {\n protocol: isHttps ? \"https\" : \"http\",\n host:\n address.address === \"::\" || address.address === \"0.0.0.0\"\n ? \"localhost\"\n : address.address,\n port: address.port,\n };\n}\n\nexport function sendJson(\n res: ServerResponse,\n data: unknown,\n status = 200,\n): void {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n}\n\nexport function sendError(\n res: ServerResponse,\n message: string,\n status = 500,\n): void {\n sendJson(res, { error: message }, status);\n}\n\nconst MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let totalSize = 0;\n req.on(\"data\", (chunk: Buffer) => {\n totalSize += chunk.length;\n if (totalSize > MAX_BODY_SIZE) {\n reject(new Error(\"Request body too large\"));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport { fileURLToPath } from \"url\";\n\n// ESM/CJS compatible __dirname\nconst _dirName = typeof __dirname !== \"undefined\"\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url));\nimport { parseMockModule, writeMockFile, saveMockData, buildMockIndex, type MockFileConfig } from \"./mockFileUtils\";\nimport { toPosixPath, sendJson, readBody } from \"./utils\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AutomockPluginOptions, InspectorOptions } from \"./types\";\n\ninterface InspectorContext {\n req: IncomingMessage;\n res: ServerResponse;\n mockDir: string;\n inspectorRoute: string;\n apiPrefix: string;\n inspectorConfig: Required<InspectorOptions>;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorHandlerOptions {\n inspector: AutomockPluginOptions[\"inspector\"];\n apiPrefix: string;\n mockDir: string;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorApiContext extends InspectorContext {\n pathname: string;\n}\n\ninterface InspectorPayload {\n key: string;\n config?: Partial<MockFileConfig>;\n description?: string;\n}\n\ninterface MockItem {\n key: string;\n file: string;\n method: string;\n path: string;\n config: MockFileConfig;\n editable: boolean;\n description?: string;\n dataText: string;\n}\n\nfunction buildMockItem(\n key: string,\n filePath: string,\n mockDir: string,\n info: Awaited<ReturnType<typeof parseMockModule>>,\n): MockItem {\n return {\n key,\n file: path.relative(mockDir, filePath),\n method: key.split(\"/\").pop()?.replace(/\\.js$/, \"\") ?? \"get\",\n path: key.replace(/\\/[^/]+\\.js$/, \"\"),\n config: info.config,\n editable: info.serializable,\n description: info.description,\n dataText: info.dataText,\n };\n}\n\nexport const DEFAULT_ROUTE = \"/__mock/\";\n\nfunction ensureTrailingSlash(route: string): string {\n return route.endsWith(\"/\") ? route : `${route}/`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport function normalizeInspectorConfig(\n input: AutomockPluginOptions[\"inspector\"],\n): Required<InspectorOptions> {\n if (input === false || input === undefined) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n if (input === true) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n return {\n route: ensureTrailingSlash(input.route ?? DEFAULT_ROUTE),\n enableToggle: input.enableToggle ?? true,\n };\n}\n\nexport type InspectorRequestHandler = (\n req: IncomingMessage,\n res: ServerResponse,\n) => Promise<boolean>;\n\nexport function createInspectorHandler(\n options: InspectorHandlerOptions,\n): InspectorRequestHandler | null {\n if (!options.inspector) {\n return null;\n }\n\n const inspectorConfig = normalizeInspectorConfig(options.inspector);\n const inspectorRoute = ensureTrailingSlash(inspectorConfig.route);\n\n return async (req, res) => {\n if (!req.url) {\n return false;\n }\n const url = new URL(req.url, \"http://localhost\");\n if (!url.pathname.startsWith(inspectorRoute)) {\n return false;\n }\n\n await handleInspectorRequest({\n req,\n res,\n mockDir: options.mockDir,\n inspectorRoute,\n apiPrefix: options.apiPrefix,\n inspectorConfig,\n getMockFileMap: options.getMockFileMap,\n });\n\n return true;\n };\n}\n\nasync function handleInspectorRequest(\n context: InspectorContext,\n): Promise<void> {\n const { req, res, inspectorRoute } = context;\n const url = new URL(req.url || inspectorRoute, \"http://localhost\");\n const normalizedRoute = ensureTrailingSlash(inspectorRoute);\n\n if (\n url.pathname === normalizedRoute.slice(0, -1) ||\n url.pathname === normalizedRoute\n ) {\n await serveInspectorHtml(context);\n return;\n }\n\n const relativePath = url.pathname.startsWith(normalizedRoute)\n ? url.pathname.slice(normalizedRoute.length)\n : null;\n\n if (relativePath && relativePath.startsWith(\"api/\")) {\n await handleInspectorApi({ ...context, pathname: relativePath.slice(4) });\n return;\n }\n\n res.statusCode = 404;\n res.end(\"Not Found\");\n}\n\nasync function serveInspectorHtml({\n res,\n inspectorRoute,\n apiPrefix,\n inspectorConfig,\n}: InspectorContext): Promise<void> {\n const routeJson = JSON.stringify(ensureTrailingSlash(inspectorRoute));\n const allowToggleJson = JSON.stringify(inspectorConfig.enableToggle);\n const apiPrefixEscaped = escapeHtml(apiPrefix);\n\n const templatePath = path.join(_dirName, \"inspector-template.html\");\n const template = fs.readFileSync(templatePath, \"utf-8\");\n const html = template\n .replace(\"__API_PREFIX__\", apiPrefixEscaped)\n .replace(\"__ROUTE_JSON__\", routeJson)\n .replace(\"__ALLOW_TOGGLE_JSON__\", allowToggleJson);\n\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(html);\n}\n\nasync function handleList(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { res, mockDir } = ctx;\n const list = await Promise.all(\n Array.from(mockFileMap.entries()).map(async ([key, filePath]) => {\n const info = await parseMockModule(filePath);\n return buildMockItem(key, filePath, mockDir, info);\n }),\n );\n sendJson(res, { mocks: list });\n return true;\n}\n\nasync function handleDetail(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n const info = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, info) });\n return true;\n}\n\nasync function handleUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, inspectorConfig } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: InspectorPayload;\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { key, config, description } = payload || {};\n if (!key) {\n sendJson(res, { error: \"Invalid payload: missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n\n let nextConfig = info.config;\n if (config && typeof config === \"object\") {\n if (!inspectorConfig.enableToggle && config.enable !== undefined) {\n delete config.enable;\n }\n nextConfig = { ...info.config, ...config };\n }\n\n const nextDescription =\n description !== undefined ? description : info.description;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: nextDescription,\n });\n\n const updatedInfo = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, updatedInfo) });\n return true;\n}\n\nasync function handleCreate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, apiPrefix } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { method: string; path: string; description?: string; data?: unknown };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { method, path: apiPath, data } = payload || {};\n if (!method || !apiPath) {\n sendJson(res, { error: \"Invalid payload: missing method or path\" }, 400);\n return true;\n }\n\n const fullUrl = apiPrefix + apiPath;\n\n try {\n let dataToSave: Buffer | string;\n if (typeof data === \"object\" && data !== null) {\n dataToSave = JSON.stringify(data, null, 2);\n } else {\n dataToSave = typeof data === \"string\" ? data : \"\";\n }\n\n await saveMockData(fullUrl, method.toLowerCase(), dataToSave, mockDir, 200);\n\n const newMockFileMap = await buildMockIndex(mockDir);\n for (const [key, value] of newMockFileMap.entries()) {\n mockFileMap.set(key, value);\n }\n\n const normalizedPath = toPosixPath(apiPath);\n const key = (normalizedPath.startsWith(\"/\") ? \"\" : \"/\") +\n normalizedPath.toLowerCase() + \"/\" + method.toLowerCase() + \".js\";\n const filePath = mockFileMap.get(key);\n\n if (!filePath) {\n sendJson(res, { error: \"Mock file created but not found in map\" }, 500);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n sendJson(res, {\n success: true,\n mock: buildMockItem(key, filePath, mockDir, info),\n });\n return true;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to create mock: \" + errorMessage }, 500);\n return true;\n }\n}\n\nasync function handleDelete(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n try {\n const stats = await fs.stat(filePath);\n if (stats.isDirectory()) {\n await fs.remove(filePath);\n for (const [mapKey, mapPath] of mockFileMap.entries()) {\n if (mapPath.startsWith(filePath + path.sep) || mapPath === filePath) {\n mockFileMap.delete(mapKey);\n }\n }\n } else {\n await fs.unlink(filePath);\n mockFileMap.delete(key);\n }\n sendJson(res, { success: true });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to delete: \" + errorMessage }, 500);\n }\n return true;\n}\n\ntype ApiHandler = (ctx: InspectorApiContext, mockFileMap: Map<string, string>) => Promise<boolean>;\n\nasync function handleBatchUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { updates?: Array<{ key: string; config?: Record<string, unknown> }> };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const updates = payload?.updates;\n if (!Array.isArray(updates) || updates.length === 0) {\n sendJson(res, { error: \"Invalid payload: updates must be a non-empty array\" }, 400);\n return true;\n }\n\n let updated = 0;\n const errors: string[] = [];\n\n for (const item of updates) {\n const { key, config } = item;\n if (!key) continue;\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n errors.push(`Mock not found: ${key}`);\n continue;\n }\n\n try {\n const info = await parseMockModule(filePath);\n const nextConfig = config ? { ...info.config, ...config } : info.config;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: info.description,\n });\n updated++;\n } catch (err) {\n errors.push(`Failed to update ${key}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n sendJson(res, { success: true, updated, errors: errors.length > 0 ? errors : undefined });\n return true;\n}\n\nconst API_ROUTES: Record<string, ApiHandler> = {\n list: handleList,\n detail: handleDetail,\n update: handleUpdate,\n \"batch-update\": handleBatchUpdate,\n create: handleCreate,\n delete: handleDelete,\n};\n\nasync function handleInspectorApi(ctx: InspectorApiContext): Promise<void> {\n try {\n const mockFileMap = ctx.getMockFileMap();\n const handler = API_ROUTES[ctx.pathname];\n if (handler) {\n await handler(ctx, mockFileMap);\n return;\n }\n sendJson(ctx.res, { error: \"Unknown inspector endpoint\" }, 404);\n } catch (error) {\n console.error(\"[automock] Inspector request failed:\", error);\n sendJson(ctx.res, { error: \"Inspector failed\" }, 500);\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\n\nimport { buildMockIndex, parseMockModule } from './mockFileUtils'\n\nexport interface MockBundleData {\n enable: boolean\n data: unknown\n delay: number\n status: number\n isBinary?: boolean\n}\n\nexport interface MockBundle {\n [key: string]: MockBundleData\n}\n\nexport interface BundleOptions {\n mockDir: string\n includeDisabled?: boolean\n log?: boolean\n}\n\nconst DEFAULT_BUNDLE_OPTIONS: Partial<BundleOptions> = {\n includeDisabled: true,\n log: true\n}\n\nasync function bundleMockFiles(options: BundleOptions): Promise<MockBundle> {\n const opts = { ...DEFAULT_BUNDLE_OPTIONS, ...options }\n const { mockDir, log } = opts\n\n if (!fs.existsSync(mockDir)) {\n if (log) {\n console.log(`[mock-bundler] Mock directory does not exist: ${mockDir}`)\n }\n return {}\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n const bundle: MockBundle = {}\n let bundledCount = 0\n let skippedCount = 0\n\n for (const [key, filePath] of mockFileMap) {\n try {\n const mockInfo = await parseMockModule(filePath)\n\n if (!mockInfo.serializable) {\n skippedCount++\n if (log) {\n console.log(`[mock-bundler] Skipping non-serializable mock: ${key}`)\n }\n continue\n }\n\n bundle[key] = {\n enable: mockInfo.config.enable,\n data: mockInfo.config.data,\n delay: mockInfo.config.delay,\n status: mockInfo.config.status,\n isBinary: mockInfo.isBinary\n }\n\n bundledCount++\n } catch (error) {\n if (log) {\n console.error(`[mock-bundler] Failed to bundle mock ${key}:`, error)\n }\n }\n }\n\n if (log) {\n console.log(`[mock-bundler] Bundled ${bundledCount} mocks, skipped ${skippedCount} non-serializable mocks`)\n }\n\n return bundle\n}\n\nfunction writeMockBundle(bundle: MockBundle, outputPath: string): void {\n const outputDir = path.dirname(outputPath)\n\n if (!fs.existsSync(outputDir)) {\n fs.ensureDirSync(outputDir)\n }\n\n fs.writeFileSync(\n outputPath,\n JSON.stringify(bundle, null, 2),\n 'utf-8'\n )\n}\n\nexport { bundleMockFiles, writeMockBundle }\n"],"mappings":"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","names":["path","fs","path","fs","path","path","path","fs","path","fs","key","fs","path","path","fs","fs","path","automock","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/mockFileUtils.ts","../src/utils.ts","../src/inspector.ts","../src/mockBundler.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\n\nimport { automock as createAutomockPlugin } from './middleware'\nimport { bundleMockFiles, writeMockBundle } from './mockBundler'\nimport { buildMockIndex } from './mockFileUtils'\nimport type { Plugin } from 'vite'\nimport type { AutomockPluginOptions } from './types'\nimport type { MockBundle } from './mockBundler'\n\nexport type { AutomockPluginOptions, InspectorOptions } from './types'\nexport { saveMockData, buildMockIndex, parseMockModule, writeMockFile } from './mockFileUtils'\nexport type { MockBundle, MockBundleData } from './mockBundler'\nexport { bundleMockFiles, writeMockBundle } from './mockBundler'\n\n// Client interceptor exports\nexport {\n createMockInterceptor,\n initMockInterceptor,\n initMockInterceptorForPureHttp,\n setMockEnabled,\n isMockEnabled,\n loadMockData,\n registerHttpInstance\n} from './client'\nexport type { MockInterceptorOptions, MockBundleData as ClientMockBundleData } from './client/interceptor'\n\nexport interface AutomockWithBundleOptions extends AutomockPluginOptions {\n bundleMockData?: boolean\n bundleOutputPath?: string\n}\n\nexport function automock(options: AutomockWithBundleOptions = {}): Plugin {\n const {\n bundleMockData = true,\n bundleOutputPath = 'public/mock-data.json',\n ...pluginOptions\n } = options\n\n const basePlugin = createAutomockPlugin(pluginOptions)\n\n let cachedBundle: MockBundle | null = null\n\n const ensureBundleExists = () => {\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n if (!fs.existsSync(outputPath) && cachedBundle) {\n console.log('[automock] Re-writing mock bundle...')\n writeMockBundle(cachedBundle, outputPath)\n }\n }\n\n return {\n ...basePlugin,\n name: 'vite-plugin-automock-with-bundle',\n config() {\n // Inject compile-time constant for client interceptor\n const enabled = pluginOptions.productionMock !== false\n return {\n define: {\n __AUTOMOCK_ENABLED__: JSON.stringify(enabled),\n },\n }\n },\n buildEnd: async () => {\n if (bundleMockData && pluginOptions.productionMock !== false) {\n try {\n const mockDir = pluginOptions.mockDir || path.join(process.cwd(), 'mock')\n\n if (!fs.existsSync(mockDir)) {\n console.log('[automock] Mock directory not found, skipping bundle generation')\n console.log('[automock] Using existing mock-data.json if present')\n return\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n if (mockFileMap.size === 0) {\n console.log('[automock] No mock files found, skipping bundle generation')\n return\n }\n\n cachedBundle = await bundleMockFiles({ mockDir })\n\n const outputPath = path.join(process.cwd(), bundleOutputPath)\n writeMockBundle(cachedBundle, outputPath)\n console.log(`[automock] Mock bundle written to: ${outputPath}`)\n } catch (error) {\n console.error('[automock] Failed to bundle mock data:', error)\n }\n }\n },\n writeBundle: ensureBundleExists,\n closeBundle: ensureBundleExists,\n }\n}\n\n","import chokidar from \"chokidar\";\nimport debounce from \"lodash.debounce\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport http from \"http\";\nimport https from \"https\";\nimport type { AddressInfo } from \"net\";\n\nimport { buildMockIndex, saveMockData } from \"./mockFileUtils\";\nimport { createInspectorHandler, normalizeInspectorConfig } from \"./inspector\";\nimport {\n resolveAbsolutePath,\n getServerAddress,\n sendError,\n} from \"./utils\";\n\nimport type { Plugin } from \"vite\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { FSWatcher } from \"chokidar\";\nimport type { AutomockPluginOptions } from \"./types\";\n\nfunction serveMockResponse(\n res: ServerResponse,\n mockFilePath: string,\n mockResult: { data?: unknown; delay?: number; status?: number },\n): void {\n const { data, delay = 0, status = 200 } = mockResult;\n\n setTimeout(() => {\n const isBinaryMock = data && typeof data === \"object\" && (data as Record<string, unknown>).__binaryFile;\n\n if (isBinaryMock) {\n const binaryData = data as Record<string, unknown>;\n const binaryFilePath = mockFilePath.replace(\n /\\.js$/,\n \".\" + binaryData.__binaryFile,\n );\n\n if (!fs.existsSync(binaryFilePath)) {\n console.error(\n `[automock] Binary mock file not found: ${binaryFilePath}`,\n );\n sendError(res, \"Binary mock file not found\", 404);\n return;\n }\n\n try {\n const fileData = fs.readFileSync(binaryFilePath);\n const contentType =\n (binaryData.__contentType as string) || \"application/octet-stream\";\n res.setHeader(\"Content-Type\", contentType);\n res.setHeader(\"Content-Length\", fileData.length);\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.setHeader(\"X-Mock-Binary-File\", \"true\");\n res.statusCode = status;\n res.end(fileData);\n } catch (error) {\n console.error(\"[automock] Failed to read binary mock file:\", error);\n sendError(res, \"Failed to read binary mock file\");\n }\n } else {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.setHeader(\"X-Mock-Response\", \"true\");\n res.setHeader(\"X-Mock-Source\", \"vite-plugin-automock\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n }\n }, delay);\n}\n\nfunction proxyAndCapture(\n req: IncomingMessage,\n res: ServerResponse,\n options: {\n proxyBaseUrl: string;\n pathRewrite: (p: string) => string;\n shouldSave: boolean;\n method: string;\n pathname: string;\n mockDir: string;\n onMockSaved: () => void;\n },\n): void {\n const { proxyBaseUrl, pathRewrite, shouldSave, method, pathname, mockDir, onMockSaved } = options;\n const targetUrl = proxyBaseUrl + pathRewrite(req.url || \"\");\n const client = targetUrl.startsWith(\"https\") ? https : http;\n\n function sendProxyRequest(body?: string) {\n const targetUrlObj = new URL(proxyBaseUrl);\n const proxyOptions = {\n method: req.method,\n headers: {\n ...req.headers,\n host: targetUrlObj.host,\n },\n rejectUnauthorized: false,\n };\n\n const proxyReq = client.request(targetUrl, proxyOptions, (proxyRes) => {\n const contentType = proxyRes.headers[\"content-type\"] || \"\";\n const isJson = contentType.includes(\"application/json\");\n\n // Non-JSON response (file download, stream, etc.) → pipe directly\n if (!isJson) {\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n proxyRes.pipe(res);\n return;\n }\n\n // JSON response → buffer, save mock, then respond\n const chunks: Buffer[] = [];\n\n proxyRes.on(\"data\", (chunk) => chunks.push(chunk));\n proxyRes.on(\"end\", async () => {\n try {\n const responseData = Buffer.concat(chunks);\n\n if (shouldSave) {\n try {\n console.log(\n `[automock] Capturing mock: ${req.url!} -> ${pathname}`,\n );\n const savedFilePath = await saveMockData(\n req.url!,\n method,\n responseData,\n mockDir,\n proxyRes.statusCode,\n contentType,\n );\n if (savedFilePath) {\n console.log(`[automock] Mock saved: ${pathname}`);\n onMockSaved();\n } else {\n console.log(\n `[automock] Mock file already exists, skipped: ${pathname}`,\n );\n }\n } catch (saveError) {\n console.error(\"[automock] Failed to save mock:\", saveError);\n }\n }\n\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(responseData);\n } catch (error) {\n console.error(\"[automock] Failed to process response:\", error);\n res.writeHead(proxyRes.statusCode || 200, proxyRes.headers);\n res.end(Buffer.concat(chunks));\n }\n });\n });\n\n proxyReq.on(\"error\", (err) => {\n console.error(\"[automock] Proxy request failed:\", err);\n sendError(res, err.message);\n });\n\n if (\n body &&\n (req.method === \"POST\" || req.method === \"PUT\" || req.method === \"PATCH\")\n ) {\n proxyReq.write(body);\n }\n\n proxyReq.end();\n }\n\n if (\n req.method === \"POST\" ||\n req.method === \"PUT\" ||\n req.method === \"PATCH\"\n ) {\n let bodyStr = \"\";\n req.on(\"data\", (chunk) => (bodyStr += chunk.toString()));\n req.on(\"end\", () => sendProxyRequest(bodyStr));\n } else {\n sendProxyRequest();\n }\n}\n\nfunction printServerUrls(\n server: { httpServer?: { address(): AddressInfo | string | null; once(event: string, cb: () => void): void } | null; config: { server: { https?: unknown } } },\n urls: Array<{ path: string; label: string; color: string; delay: number }>,\n): void {\n server.httpServer?.once(\"listening\", () => {\n const address = server.httpServer?.address();\n if (!address || typeof address !== \"object\") return;\n\n const { protocol, host, port } = getServerAddress(\n address,\n !!server.config.server.https,\n );\n\n for (const { path: urlPath, label, color, delay } of urls) {\n setTimeout(() => {\n const fullUrl = `${protocol}://${host}:${port}${urlPath}`;\n console.log(` ➜ ${color}${label}\\x1b[0m: \\x1b[1m${fullUrl}\\x1b[0m`);\n }, delay);\n }\n });\n}\n\nexport function automock(options: AutomockPluginOptions): Plugin {\n const {\n mockDir: configMockDir = path.join(process.cwd(), \"mock\"),\n apiPrefix = \"/api\",\n pathRewrite = (p) => p,\n proxyBaseUrl,\n inspector = false,\n } = options;\n\n const mockDir = resolveAbsolutePath(configMockDir);\n\n if (!fs.existsSync(mockDir)) {\n try {\n fs.ensureDirSync(mockDir);\n console.log(`[automock] Mock directory created: ${mockDir}`);\n } catch (error) {\n console.error(`[automock] Failed to create mock directory: ${mockDir}`, error);\n }\n }\n\n let watcher: FSWatcher | undefined;\n\n return {\n name: \"vite-plugin-automock\",\n config(userConfig) {\n if (proxyBaseUrl && userConfig.server?.proxy) {\n const proxyConfig = userConfig.server.proxy;\n const hasConflictingPrefix =\n typeof proxyConfig === \"object\" && apiPrefix in proxyConfig;\n\n if (hasConflictingPrefix) {\n console.warn(\n `\\n⚠️ [automock] WARNING: You have both Vite's server.proxy[\"${apiPrefix}\"] and automock's proxyBaseUrl configured.`,\n );\n console.warn(\n ` This may cause request conflicts. Remove the \"${apiPrefix}\" entry from vite.config.ts server.proxy to avoid issues.`,\n );\n console.warn(\n ` Automock will handle all ${apiPrefix} requests when proxyBaseUrl is set.\\n`,\n );\n }\n }\n },\n async configureServer(server) {\n let mockFileMap = await buildMockIndex(mockDir);\n console.log(`[automock] Loaded ${mockFileMap.size} mock files`);\n\n const rebuildMockFileMap = debounce(async () => {\n mockFileMap = await buildMockIndex(mockDir);\n }, 200);\n\n watcher = chokidar.watch(mockDir, {\n ignoreInitial: true,\n persistent: true,\n depth: 30,\n });\n watcher.on(\"add\", () => rebuildMockFileMap());\n watcher.on(\"unlink\", () => rebuildMockFileMap());\n\n server.httpServer?.on(\"close\", () => watcher?.close());\n\n const inspectorHandler = createInspectorHandler({\n inspector,\n apiPrefix,\n mockDir,\n getMockFileMap: () => mockFileMap,\n });\n\n const urlsToPrint: Array<{ path: string; label: string; color: string; delay: number }> = [\n { path: apiPrefix, label: \"Mock API\", color: \"\\x1b[32m\", delay: 100 },\n ];\n\n if (inspector) {\n const inspectorConfig = normalizeInspectorConfig(inspector);\n urlsToPrint.push({\n path: inspectorConfig.route,\n label: \"Mock Inspector\",\n color: \"\\x1b[95m\",\n delay: 150,\n });\n }\n\n printServerUrls(server, urlsToPrint);\n\n async function tryLoadMock(key: string): Promise<{ absolutePath: string; mockResult: Record<string, unknown> } | null> {\n const mockFilePath = mockFileMap.get(key);\n if (!mockFilePath) return null;\n\n const absolutePath = resolveAbsolutePath(mockFilePath);\n if (!fs.existsSync(absolutePath)) return null;\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n const mockResult =\n typeof mockModule.data === \"function\"\n ? mockModule.data()\n : mockModule;\n\n const { enable = true } = mockResult || {};\n return enable ? { absolutePath, mockResult } : null;\n }\n\n server.middlewares.use(\n async (\n req: IncomingMessage,\n res: ServerResponse,\n next: (err?: Error | unknown) => void,\n ): Promise<void> => {\n if (inspectorHandler && req.url) {\n const handled = await inspectorHandler(req, res);\n if (handled) return;\n }\n\n if (!req.url?.startsWith(apiPrefix)) {\n return next();\n }\n\n // Skip non-standard requests (SSE, WebSocket, file streams)\n const accept = req.headers.accept || \"\";\n const upgrade = req.headers.upgrade || \"\";\n if (accept.includes(\"text/event-stream\") || upgrade.toLowerCase() === \"websocket\") {\n return next();\n }\n\n const method = (req.method || \"GET\").toLowerCase();\n const pathname = new URL(req.url, \"http://localhost\").pathname;\n const key = `${pathname}/${method}.js`.toLowerCase();\n\n // 1. Try mock\n try {\n const mock = await tryLoadMock(key);\n if (mock) {\n serveMockResponse(res, mock.absolutePath, mock.mockResult);\n return;\n }\n } catch (error) {\n console.error(\"[automock] Failed to load mock file:\", error);\n }\n\n // 2. Try proxy\n if (!proxyBaseUrl) return next();\n\n try {\n proxyAndCapture(req, res, {\n proxyBaseUrl,\n pathRewrite,\n shouldSave: !mockFileMap.has(key),\n method,\n pathname,\n mockDir,\n onMockSaved: async () => {\n mockFileMap = await buildMockIndex(mockDir);\n },\n });\n } catch (error) {\n console.error(\"[automock] Proxy request error:\", error);\n sendError(res, \"Internal server error\");\n }\n },\n );\n },\n closeBundle() {\n watcher?.close();\n },\n transform() {\n return null;\n },\n };\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport prettier from \"prettier\";\n\nimport { resolveAbsolutePath, toPosixPath } from \"./utils\";\n\nexport interface MockFileConfig {\n enable: boolean;\n data: unknown;\n delay: number;\n status: number;\n [key: string]: unknown;\n}\n\nexport interface MockFileInfo {\n config: MockFileConfig;\n serializable: boolean;\n hasDynamicData: boolean;\n headerComment?: string;\n description?: string;\n dataText: string;\n isBinary?: boolean;\n}\n\nexport const DEFAULT_CONFIG: MockFileConfig = {\n enable: true,\n data: null,\n delay: 0,\n status: 200,\n};\n\nconst isBufferTextLike = (buffer: Buffer): boolean => {\n try {\n const sample = buffer.slice(0, 100);\n const nullBytes = [...sample].filter((b) => b === 0).length;\n const controlChars = [...sample].filter(\n (b) => b < 32 && b !== 9 && b !== 10 && b !== 13,\n ).length;\n return nullBytes === 0 && controlChars < 5;\n } catch {\n return false;\n }\n};\n\nconst isBinaryResponse = (\n contentType: string | undefined,\n data: Buffer,\n): boolean => {\n if (!contentType) return false;\n\n const binaryTypes = [\n \"application/octet-stream\",\n \"application/pdf\",\n \"application/zip\",\n \"application/x-zip-compressed\",\n \"application/vnd.ms-excel\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n \"application/msword\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.ms-powerpoint\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n \"image/\",\n \"video/\",\n \"audio/\",\n ];\n\n return (\n binaryTypes.some((type) => contentType.toLowerCase().includes(type)) ||\n !isBufferTextLike(data)\n );\n};\n\nconst getFileExtension = (\n contentType: string | undefined,\n url: string,\n): string => {\n const mimeMap: Record<string, string> = {\n \"application/json\": \"json\",\n \"application/pdf\": \"pdf\",\n \"application/zip\": \"zip\",\n \"application/vnd.ms-excel\": \"xls\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/msword\": \"doc\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\n \"docx\",\n \"application/vnd.ms-powerpoint\": \"ppt\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\":\n \"pptx\",\n \"image/jpeg\": \"jpg\",\n \"image/png\": \"png\",\n \"image/gif\": \"gif\",\n \"text/plain\": \"txt\",\n \"text/html\": \"html\",\n \"text/css\": \"css\",\n \"application/javascript\": \"js\",\n \"text/xml\": \"xml\",\n };\n\n if (contentType && mimeMap[contentType.toLowerCase()]) {\n return mimeMap[contentType.toLowerCase()];\n }\n\n try {\n const urlObj = new URL(url, \"http://localhost\");\n const fileName = urlObj.searchParams.get(\"file_name\");\n if (fileName) {\n const extensionMatch = fileName.match(/\\.([a-zA-Z0-9]+)$/);\n if (extensionMatch) {\n return extensionMatch[1];\n }\n }\n } catch {\n // Ignore URL parse errors\n }\n\n return \"bin\";\n};\n\nasync function formatWithPrettier(content: string): Promise<string> {\n try {\n return await prettier.format(content, { parser: \"babel\" });\n } catch {\n return content;\n }\n}\n\nfunction buildMockFileHeader(\n pathname: string,\n method: string,\n search: string,\n extra?: string,\n): string {\n return `/**\n * Mock data for ${pathname} (${method.toUpperCase()})${search || \"\"}\n * @description ${pathname}${search || \"\"}${extra ? ` - ${extra}` : \"\"}\n * Generated at ${new Date().toISOString()}\n */`;\n}\n\nasync function saveBinaryMock(\n filePath: string,\n binaryData: Buffer,\n pathname: string,\n method: string,\n search: string,\n contentType: string | undefined,\n url: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n const extension = getFileExtension(contentType, url);\n const binaryFilePath = filePath.replace(/\\.js$/, \".\" + extension);\n\n if (fs.existsSync(binaryFilePath)) return null;\n\n fs.writeFileSync(binaryFilePath, binaryData);\n\n const header = buildMockFileHeader(pathname, method, search, `Binary file (${extension})`);\n const configContent = `${header}\nexport default {\n enable: false,\n data: {\n __binaryFile: '${extension}',\n __originalPath: '${pathname}',\n __originalQuery: '${search}',\n __originalUrl: '${pathname}${search || \"\"}',\n __contentType: '${contentType}',\n __fileSize: ${binaryData.length}\n },\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(configContent);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nasync function saveJsonMock(\n filePath: string,\n dataStr: string,\n pathname: string,\n method: string,\n search: string,\n statusCode: number | undefined,\n): Promise<string | null> {\n if (fs.existsSync(filePath)) return null;\n\n let jsonData;\n if (!dataStr || dataStr.trim() === \"\") {\n jsonData = {\n error: true,\n message: `Empty response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: null,\n };\n } else {\n try {\n jsonData = JSON.parse(dataStr);\n if (statusCode && statusCode >= 400) {\n const errorMeta = { __mockStatusCode: statusCode, __isErrorResponse: true };\n jsonData =\n typeof jsonData === \"object\" && jsonData !== null\n ? { ...jsonData, ...errorMeta }\n : { originalData: jsonData, ...errorMeta };\n }\n } catch {\n jsonData = {\n error: true,\n message: `Non-JSON response (${statusCode || \"unknown status\"})`,\n status: statusCode || 404,\n data: dataStr,\n __mockStatusCode: statusCode,\n __isErrorResponse: true,\n };\n }\n }\n\n const header = buildMockFileHeader(pathname, method, search);\n const content = `${header}\nexport default {\n enable: false,\n data: ${JSON.stringify(jsonData)},\n delay: 0,\n status: ${statusCode || 200}\n}`;\n\n const formatted = await formatWithPrettier(content);\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n return filePath;\n}\n\nexport async function saveMockData(\n url: string,\n method: string,\n data: Buffer | string,\n rootDir: string,\n statusCode?: number,\n contentType?: string,\n): Promise<string | null> {\n try {\n const absoluteRootDir = resolveAbsolutePath(rootDir);\n const urlObj = new URL(url, \"http://localhost\");\n const pathname = urlObj.pathname;\n const search = urlObj.search;\n\n const filePath = path.join(\n absoluteRootDir,\n pathname.replace(/^\\//, \"\"),\n method.toLowerCase() + \".js\",\n );\n\n await fs.ensureDir(path.dirname(filePath));\n\n const isBuffer = Buffer.isBuffer(data);\n const binaryData = isBuffer ? data : Buffer.from(data || \"\");\n const isBinary = isBinaryResponse(contentType, binaryData);\n\n if (isBinary) {\n return saveBinaryMock(\n filePath, binaryData, pathname, method, search,\n contentType, url, statusCode,\n );\n }\n\n const dataStr = isBuffer ? data.toString(\"utf8\") : data || \"\";\n return saveJsonMock(filePath, dataStr, pathname, method, search, statusCode);\n } catch (error) {\n console.error(`Failed to save mock data for ${url}:`, error);\n console.error(\n `URL details: url=${url}, method=${method}, statusCode=${statusCode}, contentType=${contentType}`,\n );\n throw error;\n }\n}\n\nconst recursiveReadAllFiles = async (dir: string): Promise<string[]> => {\n if (!(await fs.pathExists(dir))) return [];\n\n const files: string[] = [];\n try {\n const list = await fs.readdir(dir);\n for (const file of list) {\n const filePath = path.join(dir, file);\n const stat = await fs.stat(filePath);\n if (stat.isDirectory()) {\n files.push(...(await recursiveReadAllFiles(filePath)));\n } else {\n files.push(filePath);\n }\n }\n } catch (error) {\n console.error(`Error reading directory ${dir}:`, error);\n }\n return files;\n};\n\nexport async function buildMockIndex(mockDir: string): Promise<Map<string, string>> {\n const mockFileMap = new Map<string, string>();\n\n if (!(await fs.pathExists(mockDir))) {\n await fs.ensureDir(mockDir);\n return mockFileMap;\n }\n\n const files = await recursiveReadAllFiles(mockDir);\n\n files.forEach((filePath) => {\n if (!filePath.endsWith(\".js\")) return;\n\n try {\n const relativePath = path.relative(mockDir, filePath);\n const method = path.basename(filePath, \".js\");\n const dirPath = path.dirname(relativePath);\n const urlPath = \"/\" + toPosixPath(dirPath);\n const absolutePath = resolveAbsolutePath(filePath);\n const key = `${urlPath}/${method}.js`.toLowerCase();\n\n mockFileMap.set(key, absolutePath);\n } catch (error) {\n console.error(`[automock] Failed to process file ${filePath}:`, error);\n }\n });\n\n return mockFileMap;\n}\n\nexport async function parseMockModule(filePath: string): Promise<MockFileInfo> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n if (!fs.existsSync(absolutePath)) {\n throw new Error(`Mock file does not exist: ${absolutePath}`);\n }\n\n const content = fs.readFileSync(absolutePath, \"utf-8\");\n const headerCommentMatch = content.match(/^(\\/\\*\\*[\\s\\S]*?\\*\\/)/);\n const headerComment = headerCommentMatch ? headerCommentMatch[1] : undefined;\n\n let description: string | undefined;\n if (headerComment) {\n const descMatch = headerComment.match(/@description\\s+(.+?)(?:\\n|\\*\\/)/s);\n if (descMatch) {\n description = descMatch[1].trim();\n }\n }\n\n const { default: mockModule } = await import(\n `${absolutePath}?t=${Date.now()}`\n );\n\n const exportedConfig =\n typeof mockModule === \"function\" ? mockModule() : mockModule;\n const hasDynamicData = typeof exportedConfig?.data === \"function\";\n const config: MockFileConfig = {\n ...DEFAULT_CONFIG,\n ...(exportedConfig ?? {}),\n };\n\n const serializable = !hasDynamicData;\n const dataObj =\n typeof config.data === \"object\" && config.data !== null\n ? (config.data as Record<string, unknown>)\n : null;\n const isBinary = dataObj !== null && \"__binaryFile\" in dataObj;\n\n return {\n config,\n serializable,\n hasDynamicData,\n headerComment,\n description,\n dataText: isBinary\n ? `/* Binary file: ${dataObj?.__binaryFile} */`\n : serializable\n ? JSON.stringify(config.data ?? null, null, 2)\n : \"/* data is generated dynamically and cannot be edited here */\",\n isBinary,\n };\n}\n\nexport async function writeMockFile(\n filePath: string,\n mockInfo: Pick<MockFileInfo, \"config\" | \"headerComment\" | \"description\">,\n): Promise<void> {\n const absolutePath = resolveAbsolutePath(filePath);\n\n let header = mockInfo.headerComment || \"\";\n\n if (mockInfo.description !== undefined) {\n if (header) {\n if (/@description/.test(header)) {\n header = header.replace(\n /@description\\s+.+?(?=\\n|\\*\\/)/s,\n `@description ${mockInfo.description}`,\n );\n } else {\n header = header.replace(\n /\\*\\//,\n ` * @description ${mockInfo.description}\\n */`,\n );\n }\n }\n }\n\n const content = header ? `${header}\\n` : \"\";\n const finalContent = `${content}export default ${JSON.stringify(mockInfo.config, null, 2)}\\n`;\n\n try {\n const formatted = await formatWithPrettier(finalContent);\n fs.writeFileSync(absolutePath, formatted, \"utf-8\");\n } catch {\n console.error(\"Error formatting code with prettier, writing raw content\");\n fs.writeFileSync(absolutePath, finalContent, \"utf-8\");\n }\n}\n","import path from \"path\";\n\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AddressInfo } from \"net\";\n\nexport function resolveAbsolutePath(p: string): string {\n return path.isAbsolute(p) ? p : path.resolve(process.cwd(), p);\n}\n\nexport function toPosixPath(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nexport interface ServerAddress {\n protocol: string;\n host: string;\n port: number;\n}\n\nexport function getServerAddress(\n address: AddressInfo,\n isHttps: boolean,\n): ServerAddress {\n return {\n protocol: isHttps ? \"https\" : \"http\",\n host:\n address.address === \"::\" || address.address === \"0.0.0.0\"\n ? \"localhost\"\n : address.address,\n port: address.port,\n };\n}\n\nexport function sendJson(\n res: ServerResponse,\n data: unknown,\n status = 200,\n): void {\n res.setHeader(\"Content-Type\", \"application/json; charset=utf-8\");\n res.statusCode = status;\n res.end(typeof data === \"string\" ? data : JSON.stringify(data));\n}\n\nexport function sendError(\n res: ServerResponse,\n message: string,\n status = 500,\n): void {\n sendJson(res, { error: message }, status);\n}\n\nconst MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let totalSize = 0;\n req.on(\"data\", (chunk: Buffer) => {\n totalSize += chunk.length;\n if (totalSize > MAX_BODY_SIZE) {\n reject(new Error(\"Request body too large\"));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n req.on(\"error\", reject);\n });\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport { fileURLToPath } from \"url\";\n\n// ESM/CJS compatible __dirname\nconst _dirName = typeof __dirname !== \"undefined\"\n ? __dirname\n : path.dirname(fileURLToPath(import.meta.url));\nimport { parseMockModule, writeMockFile, saveMockData, buildMockIndex, type MockFileConfig } from \"./mockFileUtils\";\nimport { toPosixPath, sendJson, readBody } from \"./utils\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport type { AutomockPluginOptions, InspectorOptions } from \"./types\";\n\ninterface InspectorContext {\n req: IncomingMessage;\n res: ServerResponse;\n mockDir: string;\n inspectorRoute: string;\n apiPrefix: string;\n inspectorConfig: Required<InspectorOptions>;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorHandlerOptions {\n inspector: AutomockPluginOptions[\"inspector\"];\n apiPrefix: string;\n mockDir: string;\n getMockFileMap: () => Map<string, string>;\n}\n\ninterface InspectorApiContext extends InspectorContext {\n pathname: string;\n}\n\ninterface InspectorPayload {\n key: string;\n config?: Partial<MockFileConfig>;\n description?: string;\n}\n\ninterface MockItem {\n key: string;\n file: string;\n method: string;\n path: string;\n config: MockFileConfig;\n editable: boolean;\n description?: string;\n dataText: string;\n}\n\nfunction buildMockItem(\n key: string,\n filePath: string,\n mockDir: string,\n info: Awaited<ReturnType<typeof parseMockModule>>,\n): MockItem {\n return {\n key,\n file: path.relative(mockDir, filePath),\n method: key.split(\"/\").pop()?.replace(/\\.js$/, \"\") ?? \"get\",\n path: key.replace(/\\/[^/]+\\.js$/, \"\"),\n config: info.config,\n editable: info.serializable,\n description: info.description,\n dataText: info.dataText,\n };\n}\n\nexport const DEFAULT_ROUTE = \"/__mock/\";\n\nfunction ensureTrailingSlash(route: string): string {\n return route.endsWith(\"/\") ? route : `${route}/`;\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nexport function normalizeInspectorConfig(\n input: AutomockPluginOptions[\"inspector\"],\n): Required<InspectorOptions> {\n if (input === false || input === undefined) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n if (input === true) {\n return { route: DEFAULT_ROUTE, enableToggle: true };\n }\n return {\n route: ensureTrailingSlash(input.route ?? DEFAULT_ROUTE),\n enableToggle: input.enableToggle ?? true,\n };\n}\n\nexport type InspectorRequestHandler = (\n req: IncomingMessage,\n res: ServerResponse,\n) => Promise<boolean>;\n\nexport function createInspectorHandler(\n options: InspectorHandlerOptions,\n): InspectorRequestHandler | null {\n if (!options.inspector) {\n return null;\n }\n\n const inspectorConfig = normalizeInspectorConfig(options.inspector);\n const inspectorRoute = ensureTrailingSlash(inspectorConfig.route);\n\n return async (req, res) => {\n if (!req.url) {\n return false;\n }\n const url = new URL(req.url, \"http://localhost\");\n if (!url.pathname.startsWith(inspectorRoute)) {\n return false;\n }\n\n await handleInspectorRequest({\n req,\n res,\n mockDir: options.mockDir,\n inspectorRoute,\n apiPrefix: options.apiPrefix,\n inspectorConfig,\n getMockFileMap: options.getMockFileMap,\n });\n\n return true;\n };\n}\n\nasync function handleInspectorRequest(\n context: InspectorContext,\n): Promise<void> {\n const { req, res, inspectorRoute } = context;\n const url = new URL(req.url || inspectorRoute, \"http://localhost\");\n const normalizedRoute = ensureTrailingSlash(inspectorRoute);\n\n if (\n url.pathname === normalizedRoute.slice(0, -1) ||\n url.pathname === normalizedRoute\n ) {\n await serveInspectorHtml(context);\n return;\n }\n\n const relativePath = url.pathname.startsWith(normalizedRoute)\n ? url.pathname.slice(normalizedRoute.length)\n : null;\n\n if (relativePath && relativePath.startsWith(\"api/\")) {\n await handleInspectorApi({ ...context, pathname: relativePath.slice(4) });\n return;\n }\n\n res.statusCode = 404;\n res.end(\"Not Found\");\n}\n\nasync function serveInspectorHtml({\n res,\n inspectorRoute,\n apiPrefix,\n inspectorConfig,\n}: InspectorContext): Promise<void> {\n const routeJson = JSON.stringify(ensureTrailingSlash(inspectorRoute));\n const allowToggleJson = JSON.stringify(inspectorConfig.enableToggle);\n const apiPrefixEscaped = escapeHtml(apiPrefix);\n\n const templatePath = path.join(_dirName, \"inspector-template.html\");\n const template = fs.readFileSync(templatePath, \"utf-8\");\n const html = template\n .replace(\"__API_PREFIX__\", apiPrefixEscaped)\n .replace(\"__ROUTE_JSON__\", routeJson)\n .replace(\"__ALLOW_TOGGLE_JSON__\", allowToggleJson);\n\n res.setHeader(\"Content-Type\", \"text/html; charset=utf-8\");\n res.end(html);\n}\n\nasync function handleList(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { res, mockDir } = ctx;\n const list = await Promise.all(\n Array.from(mockFileMap.entries()).map(async ([key, filePath]) => {\n const info = await parseMockModule(filePath);\n return buildMockItem(key, filePath, mockDir, info);\n }),\n );\n sendJson(res, { mocks: list });\n return true;\n}\n\nasync function handleDetail(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n const info = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, info) });\n return true;\n}\n\nasync function handleUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, inspectorConfig } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: InspectorPayload;\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { key, config, description } = payload || {};\n if (!key) {\n sendJson(res, { error: \"Invalid payload: missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n\n let nextConfig = info.config;\n if (config && typeof config === \"object\") {\n if (!inspectorConfig.enableToggle && config.enable !== undefined) {\n delete config.enable;\n }\n nextConfig = { ...info.config, ...config };\n }\n\n const nextDescription =\n description !== undefined ? description : info.description;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: nextDescription,\n });\n\n const updatedInfo = await parseMockModule(filePath);\n sendJson(res, { mock: buildMockItem(key, filePath, mockDir, updatedInfo) });\n return true;\n}\n\nasync function handleCreate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res, mockDir, apiPrefix } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { method: string; path: string; description?: string; data?: unknown };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const { method, path: apiPath, data } = payload || {};\n if (!method || !apiPath) {\n sendJson(res, { error: \"Invalid payload: missing method or path\" }, 400);\n return true;\n }\n\n const fullUrl = apiPrefix + apiPath;\n\n try {\n let dataToSave: Buffer | string;\n if (typeof data === \"object\" && data !== null) {\n dataToSave = JSON.stringify(data, null, 2);\n } else {\n dataToSave = typeof data === \"string\" ? data : \"\";\n }\n\n await saveMockData(fullUrl, method.toLowerCase(), dataToSave, mockDir, 200);\n\n const newMockFileMap = await buildMockIndex(mockDir);\n for (const [key, value] of newMockFileMap.entries()) {\n mockFileMap.set(key, value);\n }\n\n const normalizedPath = toPosixPath(apiPath);\n const key = (normalizedPath.startsWith(\"/\") ? \"\" : \"/\") +\n normalizedPath.toLowerCase() + \"/\" + method.toLowerCase() + \".js\";\n const filePath = mockFileMap.get(key);\n\n if (!filePath) {\n sendJson(res, { error: \"Mock file created but not found in map\" }, 500);\n return true;\n }\n\n const info = await parseMockModule(filePath);\n sendJson(res, {\n success: true,\n mock: buildMockItem(key, filePath, mockDir, info),\n });\n return true;\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to create mock: \" + errorMessage }, 500);\n return true;\n }\n}\n\nasync function handleDelete(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n const url = new URL(req.url || \"\", \"http://localhost\");\n const key = url.searchParams.get(\"key\");\n if (!key) {\n sendJson(res, { error: \"Missing key\" }, 400);\n return true;\n }\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n sendJson(res, { error: \"Mock not found\" }, 404);\n return true;\n }\n\n try {\n const stats = await fs.stat(filePath);\n if (stats.isDirectory()) {\n await fs.remove(filePath);\n for (const [mapKey, mapPath] of mockFileMap.entries()) {\n if (mapPath.startsWith(filePath + path.sep) || mapPath === filePath) {\n mockFileMap.delete(mapKey);\n }\n }\n } else {\n await fs.unlink(filePath);\n mockFileMap.delete(key);\n }\n sendJson(res, { success: true });\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n sendJson(res, { error: \"Failed to delete: \" + errorMessage }, 500);\n }\n return true;\n}\n\ntype ApiHandler = (ctx: InspectorApiContext, mockFileMap: Map<string, string>) => Promise<boolean>;\n\nasync function handleBatchUpdate(\n ctx: InspectorApiContext,\n mockFileMap: Map<string, string>,\n): Promise<boolean> {\n const { req, res } = ctx;\n if (req.method !== \"POST\") {\n sendJson(res, { error: \"Method not allowed\" }, 405);\n return true;\n }\n const body = await readBody(req);\n let payload: { updates?: Array<{ key: string; config?: Record<string, unknown> }> };\n try {\n payload = JSON.parse(body);\n } catch {\n sendJson(res, { error: \"Invalid JSON body\" }, 400);\n return true;\n }\n\n const updates = payload?.updates;\n if (!Array.isArray(updates) || updates.length === 0) {\n sendJson(res, { error: \"Invalid payload: updates must be a non-empty array\" }, 400);\n return true;\n }\n\n let updated = 0;\n const errors: string[] = [];\n\n for (const item of updates) {\n const { key, config } = item;\n if (!key) continue;\n\n const filePath = mockFileMap.get(key);\n if (!filePath) {\n errors.push(`Mock not found: ${key}`);\n continue;\n }\n\n try {\n const info = await parseMockModule(filePath);\n const nextConfig = config ? { ...info.config, ...config } : info.config;\n\n await writeMockFile(filePath, {\n headerComment: info.headerComment,\n config: nextConfig,\n description: info.description,\n });\n updated++;\n } catch (err) {\n errors.push(`Failed to update ${key}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n sendJson(res, { success: true, updated, errors: errors.length > 0 ? errors : undefined });\n return true;\n}\n\nconst API_ROUTES: Record<string, ApiHandler> = {\n list: handleList,\n detail: handleDetail,\n update: handleUpdate,\n \"batch-update\": handleBatchUpdate,\n create: handleCreate,\n delete: handleDelete,\n};\n\nasync function handleInspectorApi(ctx: InspectorApiContext): Promise<void> {\n try {\n const mockFileMap = ctx.getMockFileMap();\n const handler = API_ROUTES[ctx.pathname];\n if (handler) {\n await handler(ctx, mockFileMap);\n return;\n }\n sendJson(ctx.res, { error: \"Unknown inspector endpoint\" }, 404);\n } catch (error) {\n console.error(\"[automock] Inspector request failed:\", error);\n sendJson(ctx.res, { error: \"Inspector failed\" }, 500);\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\n\nimport { buildMockIndex, parseMockModule } from './mockFileUtils'\n\nexport interface MockBundleData {\n enable: boolean\n data: unknown\n delay: number\n status: number\n isBinary?: boolean\n}\n\nexport interface MockBundle {\n [key: string]: MockBundleData\n}\n\nexport interface BundleOptions {\n mockDir: string\n includeDisabled?: boolean\n log?: boolean\n}\n\nconst DEFAULT_BUNDLE_OPTIONS: Partial<BundleOptions> = {\n includeDisabled: true,\n log: true\n}\n\nasync function bundleMockFiles(options: BundleOptions): Promise<MockBundle> {\n const opts = { ...DEFAULT_BUNDLE_OPTIONS, ...options }\n const { mockDir, log } = opts\n\n if (!fs.existsSync(mockDir)) {\n if (log) {\n console.log(`[mock-bundler] Mock directory does not exist: ${mockDir}`)\n }\n return {}\n }\n\n const mockFileMap = await buildMockIndex(mockDir)\n const bundle: MockBundle = {}\n let bundledCount = 0\n let skippedCount = 0\n\n for (const [key, filePath] of mockFileMap) {\n try {\n const mockInfo = await parseMockModule(filePath)\n\n if (!mockInfo.serializable) {\n skippedCount++\n if (log) {\n console.log(`[mock-bundler] Skipping non-serializable mock: ${key}`)\n }\n continue\n }\n\n bundle[key] = {\n enable: mockInfo.config.enable,\n data: mockInfo.config.data,\n delay: mockInfo.config.delay,\n status: mockInfo.config.status,\n isBinary: mockInfo.isBinary\n }\n\n bundledCount++\n } catch (error) {\n if (log) {\n console.error(`[mock-bundler] Failed to bundle mock ${key}:`, error)\n }\n }\n }\n\n if (log) {\n console.log(`[mock-bundler] Bundled ${bundledCount} mocks, skipped ${skippedCount} non-serializable mocks`)\n }\n\n return bundle\n}\n\nfunction writeMockBundle(bundle: MockBundle, outputPath: string): void {\n const outputDir = path.dirname(outputPath)\n\n if (!fs.existsSync(outputDir)) {\n fs.ensureDirSync(outputDir)\n }\n\n fs.writeFileSync(\n outputPath,\n JSON.stringify(bundle, null, 2),\n 'utf-8'\n )\n}\n\nexport { bundleMockFiles, writeMockBundle }\n"],"mappings":"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","names":["path","fs","path","fs","path","path","path","fs","path","fs","key","fs","path","path","fs","fs","path","automock","path","fs"]}
|
|
@@ -1257,6 +1257,75 @@
|
|
|
1257
1257
|
attachTreeEventListeners();
|
|
1258
1258
|
}
|
|
1259
1259
|
|
|
1260
|
+
// Collect all mock keys affected by a checkbox toggle (from DOM)
|
|
1261
|
+
function collectAffectedKeys(nodeEl) {
|
|
1262
|
+
const deleteBtn = nodeEl.querySelector('.tree-node-delete');
|
|
1263
|
+
// File node: has data-mock-key
|
|
1264
|
+
if (deleteBtn && deleteBtn.dataset.mockKey) {
|
|
1265
|
+
return [deleteBtn.dataset.mockKey];
|
|
1266
|
+
}
|
|
1267
|
+
// Folder node: has data-mock-keys (JSON array)
|
|
1268
|
+
if (deleteBtn && deleteBtn.dataset.mockKeys) {
|
|
1269
|
+
try { return JSON.parse(deleteBtn.dataset.mockKeys); } catch { return []; }
|
|
1270
|
+
}
|
|
1271
|
+
// Fallback: collect from all child file nodes
|
|
1272
|
+
const keys = [];
|
|
1273
|
+
nodeEl.querySelectorAll('.tree-node-delete[data-is-folder="false"]').forEach(btn => {
|
|
1274
|
+
if (btn.dataset.mockKey) keys.push(btn.dataset.mockKey);
|
|
1275
|
+
});
|
|
1276
|
+
return keys;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
// Incremental DOM update for checkbox state changes
|
|
1280
|
+
function updateCheckboxStatesInDOM(nodeEl, checked) {
|
|
1281
|
+
// Update all descendant checkboxes
|
|
1282
|
+
nodeEl.querySelectorAll('.tree-node-checkbox').forEach(cb => {
|
|
1283
|
+
cb.checked = checked;
|
|
1284
|
+
cb.indeterminate = false;
|
|
1285
|
+
cb.removeAttribute('data-indeterminate');
|
|
1286
|
+
});
|
|
1287
|
+
// Update the clicked checkbox itself (it may not be a descendant selector match)
|
|
1288
|
+
const selfCb = nodeEl.querySelector(':scope > .tree-node-content > .tree-node-checkbox');
|
|
1289
|
+
if (selfCb) {
|
|
1290
|
+
selfCb.checked = checked;
|
|
1291
|
+
selfCb.indeterminate = false;
|
|
1292
|
+
selfCb.removeAttribute('data-indeterminate');
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// Update parent chain (indeterminate state)
|
|
1296
|
+
let current = nodeEl.parentElement;
|
|
1297
|
+
while (current) {
|
|
1298
|
+
const parentNode = current.closest('.tree-node');
|
|
1299
|
+
if (!parentNode) break;
|
|
1300
|
+
|
|
1301
|
+
const childContainer = parentNode.querySelector(':scope > .tree-children');
|
|
1302
|
+
if (!childContainer) break;
|
|
1303
|
+
|
|
1304
|
+
const childCheckboxes = childContainer.querySelectorAll(':scope > .tree-node > .tree-node-content > .tree-node-checkbox');
|
|
1305
|
+
if (childCheckboxes.length === 0) break;
|
|
1306
|
+
|
|
1307
|
+
let allChecked = true;
|
|
1308
|
+
let someChecked = false;
|
|
1309
|
+
childCheckboxes.forEach(cb => {
|
|
1310
|
+
if (cb.checked || cb.indeterminate) someChecked = true;
|
|
1311
|
+
if (!cb.checked || cb.indeterminate) allChecked = false;
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
const parentCb = parentNode.querySelector(':scope > .tree-node-content > .tree-node-checkbox');
|
|
1315
|
+
if (parentCb) {
|
|
1316
|
+
parentCb.checked = allChecked;
|
|
1317
|
+
parentCb.indeterminate = !allChecked && someChecked;
|
|
1318
|
+
if (parentCb.indeterminate) {
|
|
1319
|
+
parentCb.setAttribute('data-indeterminate', 'true');
|
|
1320
|
+
} else {
|
|
1321
|
+
parentCb.removeAttribute('data-indeterminate');
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
current = parentNode.parentElement;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1260
1329
|
// Attach event listeners for tree interactions
|
|
1261
1330
|
function attachTreeEventListeners() {
|
|
1262
1331
|
const list = document.getElementById('mock-list');
|
|
@@ -1282,27 +1351,16 @@
|
|
|
1282
1351
|
if (!nodeEl) return;
|
|
1283
1352
|
|
|
1284
1353
|
const nodeId = nodeEl.dataset.nodeId;
|
|
1285
|
-
const nodeType = nodeEl.dataset.nodeType;
|
|
1286
1354
|
const checked = checkbox.checked;
|
|
1287
1355
|
|
|
1288
|
-
//
|
|
1289
|
-
const
|
|
1356
|
+
// Collect affected keys from DOM
|
|
1357
|
+
const affectedKeys = collectAffectedKeys(nodeEl);
|
|
1290
1358
|
|
|
1291
|
-
//
|
|
1292
|
-
|
|
1293
|
-
if (node) {
|
|
1294
|
-
// Update children
|
|
1295
|
-
updateTreeNodeState(node, checked, true);
|
|
1296
|
-
// Update parents
|
|
1297
|
-
updateParentNodeState(node, tree);
|
|
1359
|
+
// Send batch API request
|
|
1360
|
+
await batchToggleMockEnable(affectedKeys, checked);
|
|
1298
1361
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
await batchToggleMockEnable(affectedKeys, checked);
|
|
1302
|
-
|
|
1303
|
-
// Re-render tree with preserved expanded state
|
|
1304
|
-
renderMockList(currentMocks, true);
|
|
1305
|
-
}
|
|
1362
|
+
// Incremental DOM update (no full re-render)
|
|
1363
|
+
updateCheckboxStatesInDOM(nodeEl, checked);
|
|
1306
1364
|
});
|
|
1307
1365
|
});
|
|
1308
1366
|
|
|
@@ -1485,7 +1543,7 @@
|
|
|
1485
1543
|
' <h3>Response Data</h3>',
|
|
1486
1544
|
' ' + renderDataSection(mock),
|
|
1487
1545
|
'</div>'
|
|
1488
|
-
].join('
|
|
1546
|
+
].join('');
|
|
1489
1547
|
|
|
1490
1548
|
const descriptionInput = document.getElementById('description-input');
|
|
1491
1549
|
if (descriptionInput) {
|