{"version":3,"sources":["../src/index.ts","../src/utils/index.ts","../src/helpers/gen-dbschema/postprocess.ts","../src/helpers/gen-dbschema/helper/header-format.ts","../src/helpers/gen-dbschema/helper/schema-conversion.ts","../src/helpers/gen-dbschema/helper/table-rename.ts","../src/helpers/gen-dbschema/helper/custom-types.ts","../src/helpers/gen-dbschema/helper/imports.ts","../src/helpers/gen-dbschema/helper/system-fields.ts","../src/helpers/gen-dbschema/helper/patch-helper.ts","../src/helpers/gen-dbschema/helper/timestamp-replacement.ts","../src/helpers/gen-dbschema/helper/appendTableAliases.ts","../src/helpers/gen-nest-resource/generator.ts","../src/helpers/gen-nest-resource/utils.ts","../src/helpers/gen-nest-resource/schema-parser.ts","../src/helpers/gen-nest-resource/index.ts","../src/helpers/proxy-error/index.ts","../src/middlewares/index.ts","../src/middlewares/openapi/router.ts","../src/middlewares/openapi/controller.ts","../src/middlewares/openapi/services.ts","../src/middlewares/openapi/utils.ts","../src/middlewares/openapi/spec-controller.ts","../src/middlewares/openapi/index.ts","../src/middlewares/dev-logs/router.ts","../src/middlewares/dev-logs/utils.ts","../src/middlewares/dev-logs/helper/path-matcher.ts","../src/middlewares/dev-logs/controller.ts","../src/middlewares/dev-logs/services/file-reader.ts","../src/middlewares/dev-logs/services/parsers.ts","../src/middlewares/dev-logs/services/trace.service.ts","../src/middlewares/dev-logs/services/server-log.service.ts","../src/middlewares/dev-logs/services/trigger.service.ts","../src/middlewares/dev-logs/services/capability.service.ts","../src/middlewares/dev-logs/health.controller.ts","../src/middlewares/dev-logs/sse/log-watcher.ts","../src/middlewares/dev-logs/sse/client-manager.ts","../src/middlewares/dev-logs/sse/sse.controller.ts","../src/middlewares/dev-logs/api-list-handler.ts","../src/middlewares/dev-logs/index.ts","../src/middlewares/collect-logs/router.ts","../src/middlewares/collect-logs/controller.ts","../src/middlewares/collect-logs/utils.ts","../src/middlewares/collect-logs/index.ts","../src/middlewares/compat.ts","../src/route-parser.ts"],"sourcesContent":["export * from './utils';\nexport * from './helpers';\nexport * from './middlewares';\nexport * from './route-parser';\n","/**\n * 标准化基础路径，确保以 '/' 开头且不包含 trailing slash\n * @param basePath 原始基础路径\n * @returns 标准化后的基础路径\n */\nexport function normalizeBasePath(basePath: string): string {\n  const normalizedBasePath = basePath.startsWith('/')\n    ? basePath\n    : `/${basePath}`;\n  const basePathWithoutTrailingSlash = normalizedBasePath.endsWith('/')\n    ? normalizedBasePath.slice(0, -1)\n    : normalizedBasePath;\n  return basePathWithoutTrailingSlash;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\n// Import all module functions\nimport {\n  // Constants\n  HEADER_COMMENT,\n  CUSTOM_TYPE_PATTERN,\n  // Header & Format\n  ensureHeaderComment,\n  stripLeadingNewlines,\n  collapseExtraBlankLines,\n  // Schema Conversion\n  removePgSchemaDeclarations,\n  convertSchemaTableInvocations,\n  // Table Rename\n  renamePgTableConstants,\n  updateTableReferenceIdentifiers,\n  escapeRegExp,\n  sanitizeIdentifier,\n  toAsciiName,\n  // Custom Types\n  replaceUnknownColumns,\n  replaceFollowingUnknown,\n  // Imports\n  tweakImports,\n  ensureTypesImport,\n  removeInlineTypeHelpers,\n  inlineCustomTypes,\n  inlineFromTemplate,\n  ensureImportIdentifier,\n  // System Fields\n  addSystemFieldComments,\n  removeConflictingSystemFields,\n  // Patch\n  patchDrizzleKitDefects,\n  // Timestamp Replacement\n  replaceTimestampWithCustomTypes,\n  replaceDefaultNowWithSql,\n  // Table Aliases\n  appendTableAliases,\n} from './helper';\n\ntype PostprocessStats = {\n  replacedUnknown: number;\n  unmatchedUnknown: string[];\n  patchedDefects: number;\n  replacedTimestamps: number;\n  replacedDefaultNow: number;\n};\n\n// Internal functions (exported for testing)\nexport const internal = {\n  CUSTOM_TYPE_PATTERN,\n  HEADER_COMMENT,\n  ensureHeaderComment,\n  stripLeadingNewlines,\n  collapseExtraBlankLines,\n  removePgSchemaDeclarations,\n  convertSchemaTableInvocations,\n  sanitizeIdentifier,\n  toAsciiName,\n  renamePgTableConstants,\n  updateTableReferenceIdentifiers,\n  escapeRegExp,\n  replaceUnknownColumns,\n  replaceFollowingUnknown,\n  addSystemFieldComments,\n  tweakImports,\n  ensureTypesImport,\n  removeInlineTypeHelpers,\n  inlineCustomTypes,\n  inlineFromTemplate,\n  ensureImportIdentifier,\n  removeConflictingSystemFields,\n  patchDrizzleKitDefects,\n  replaceTimestampWithCustomTypes,\n  replaceDefaultNowWithSql,\n  appendTableAliases,\n};\n\nexport function postprocessDrizzleSchema(targetPath: string): PostprocessStats | undefined {\n  const resolvedPath = path.resolve(targetPath);\n  if (!fs.existsSync(resolvedPath)) {\n    console.warn(`[postprocess-drizzle-schema] File not found: ${resolvedPath}`);\n    return undefined;\n  }\n\n  let text = fs.readFileSync(resolvedPath, 'utf8');\n\n  // Processing pipeline - maintain exact order\n  text = ensureHeaderComment(text);\n\n  // Patch drizzle-kit defects first\n  const patchResult = patchDrizzleKitDefects(text);\n  text = patchResult.text;\n\n  text = removePgSchemaDeclarations(text);\n  const tableConversion = convertSchemaTableInvocations(text);\n  text = tableConversion.text;\n  const renameResult = renamePgTableConstants(text);\n  text = renameResult.text;\n  text = updateTableReferenceIdentifiers(text, renameResult.renames);\n\n  const replacement = replaceUnknownColumns(text);\n  text = replacement.text;\n\n  // Replace timestamp with specific options to custom types\n  const timestampReplacement = replaceTimestampWithCustomTypes(text);\n  text = timestampReplacement.text;\n\n  // Replace .defaultNow() with .default(sql`CURRENT_TIMESTAMP`)\n  const defaultNowReplacement = replaceDefaultNowWithSql(text);\n  text = defaultNowReplacement.text;\n\n  // Remove conflicting system fields before adding comments\n  text = removeConflictingSystemFields(text);\n\n  text = addSystemFieldComments(text);\n\n  text = tweakImports(text);\n  // Inline custom types instead of importing from external file\n  text = inlineCustomTypes(text);\n\n  text = appendTableAliases(text);\n  // Note: removeInlineTypeHelpers is no longer needed since we intentionally inline types now\n  text = text.replace(/\\r?\\n/g, '\\n');\n  text = collapseExtraBlankLines(text);\n\n  fs.writeFileSync(resolvedPath, text, 'utf8');\n\n  if (patchResult.fixed > 0) {\n    console.info(`[postprocess-drizzle-schema] Patched ${patchResult.fixed} drizzle-kit defects (.default(') -> .default(''))`);\n  }\n  if (replacement.replaced > 0) {\n    console.info(`[postprocess-drizzle-schema] Replaced ${replacement.replaced} unknown columns`);\n  }\n  if (replacement.unmatched.length > 0) {\n    console.warn('[postprocess-drizzle-schema] Unmatched custom types:', replacement.unmatched.length);\n    replacement.unmatched.forEach((line) => console.warn(`  ${line}`));\n  }\n  if (tableConversion.converted > 0) {\n    console.info(`[postprocess-drizzle-schema] Converted ${tableConversion.converted} schema.table invocations to pgTable`);\n  }\n  if (timestampReplacement.replaced > 0) {\n    console.info(`[postprocess-drizzle-schema] Replaced ${timestampReplacement.replaced} timestamp fields with customTimestamptz`);\n  }\n  if (defaultNowReplacement.replaced > 0) {\n    console.info(`[postprocess-drizzle-schema] Replaced ${defaultNowReplacement.replaced} .defaultNow() with .default(sql\\`CURRENT_TIMESTAMP\\`)`);\n  }\n\n  return {\n    replacedUnknown: replacement.replaced,\n    unmatchedUnknown: replacement.unmatched,\n    patchedDefects: patchResult.fixed,\n    replacedTimestamps: timestampReplacement.replaced,\n    replacedDefaultNow: defaultNowReplacement.replaced,\n  };\n}\n","const HEADER_COMMENT = '/** auto generated, do not edit */';\n\nexport { HEADER_COMMENT };\n\nexport function ensureHeaderComment(source: string): string {\n  let text = source.startsWith('\\uFEFF') ? source.slice(1) : source;\n\n  while (text.startsWith(HEADER_COMMENT)) {\n    text = text.slice(HEADER_COMMENT.length);\n    text = stripLeadingNewlines(text);\n  }\n\n  const trimmed = stripLeadingNewlines(text);\n  if (trimmed.length === 0) {\n    return `${HEADER_COMMENT}\\n`;\n  }\n\n  return `${HEADER_COMMENT}\\n${trimmed}`;\n}\n\nexport function stripLeadingNewlines(value: string): string {\n  let current = value;\n  while (current.startsWith('\\r\\n') || current.startsWith('\\n')) {\n    current = current.startsWith('\\r\\n') ? current.slice(2) : current.slice(1);\n  }\n  return current;\n}\n\nexport function collapseExtraBlankLines(text: string): string {\n  return text.replace(/\\n{3,}/g, '\\n\\n');\n}\n","export function removePgSchemaDeclarations(source: string): string {\n  return source.replace(/export const \\w+ = pgSchema\\([\\s\\S]*?\\);\\n*/g, '');\n}\n\nexport function convertSchemaTableInvocations(source: string): { text: string; converted: number } {\n  let converted = 0;\n  let text = source.replace(/([A-Za-z0-9_]+)\\.table\\(/g, () => {\n    converted += 1;\n    return 'pgTable(';\n  });\n  text = text.replace(/([A-Za-z0-9_]+)\\.view\\(/g, () => {\n    converted += 1;\n    return 'pgView(';\n  });\n  text = text.replace(/([A-Za-z0-9_]+)\\.materializedView\\(/g, () => {\n    converted += 1;\n    return 'pgMaterializedView(';\n  });\n  text = text.replace(/([A-Za-z0-9_]+)\\.enum\\(/g, () => {\n    converted += 1;\n    return 'pgEnum(';\n  });\n  text = text.replace(/([A-Za-z0-9_]+)\\.sequence\\(/g, () => {\n    converted += 1;\n    return 'pgSequence(';\n  });\n  return { text, converted };\n}\n","import { pinyin } from 'pinyin-pro';\n\nexport type TableRename = {\n  from: string;\n  to: string;\n};\n\nexport function renamePgTableConstants(source: string): { text: string; renames: TableRename[] } {\n  const pgTableRegex = /export const\\s+([^\\s=]+)\\s*=\\s*(pgTable|pgView|pgMaterializedView)\\(\\s*[\"'`]([^\"'`]+)[\"'`]/gu;\n  const renames: TableRename[] = [];\n\n  const updated = source.replace(pgTableRegex, (match, currentName: string, factory: string, tableName: string) => {\n    const sanitized = sanitizeIdentifier(tableName);\n    if (sanitized === currentName) {\n      return match;\n    }\n    renames.push({ from: currentName, to: sanitized });\n    const equalsIndex = match.indexOf('=');\n    const suffix = equalsIndex >= 0 ? match.slice(equalsIndex) : ` = ${factory}(\"${tableName}\"`;\n    const normalizedSuffix = suffix.trimStart();\n    return `export const ${sanitized} ${normalizedSuffix}`;\n  });\n\n  return { text: updated, renames };\n}\n\nexport function updateTableReferenceIdentifiers(source: string, renames: TableRename[]): string {\n  if (renames.length === 0) {\n    return source;\n  }\n\n  return renames.reduce((acc, rename) => {\n    if (!rename.from || rename.from === rename.to) {\n      return acc;\n    }\n    const pattern = new RegExp(`\\\\b${escapeRegExp(rename.from)}(\\\\s*\\\\.)`, 'g');\n    return acc.replace(pattern, `${rename.to}$1`);\n  }, source);\n}\n\nexport function escapeRegExp(value: string): string {\n  return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\//g, '\\\\/');\n}\n\n/**\n * Convert a string to camelCase\n * Example: \"test_exam\" -> \"testExam\", \"user_profile_data\" -> \"userProfileData\"\n */\nfunction toCamelCase(str: string): string {\n  // Split by underscores, hyphens, or spaces\n  const words = str.split(/[_\\-\\s]+/).filter(Boolean);\n\n  if (words.length === 0) {\n    return '';\n  }\n\n  // First word lowercase, capitalize first letter of subsequent words\n  return words\n    .map((word, index) => {\n      if (index === 0) {\n        return word.toLowerCase();\n      }\n      return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n    })\n    .join('');\n}\n\nexport function sanitizeIdentifier(name: string): string {\n  const asciiName = toAsciiName(name);\n  // Replace non-alphanumeric characters with underscores\n  let sanitized = asciiName.replace(/[^A-Za-z0-9_]/g, '_');\n  // Collapse multiple underscores into one\n  sanitized = sanitized.replace(/_+/g, '_');\n  // Remove leading/trailing underscores\n  sanitized = sanitized.replace(/^_|_$/g, '');\n\n  // Convert to camelCase\n  sanitized = toCamelCase(sanitized);\n\n  if (!sanitized) {\n    sanitized = 'table';\n  }\n  if (!/^[A-Za-z_]/.test(sanitized)) {\n    sanitized = `_${sanitized}`;\n  }\n  return sanitized;\n}\n\nexport function toAsciiName(name: string): string {\n  if (!/[^\\x00-\\x7F]/.test(name)) {\n    return name;\n  }\n\n  try {\n    const transliterated = pinyin(name, { toneType: 'none', type: 'array' }).join('_');\n    return transliterated || name;\n  } catch (error) {\n    return name;\n  }\n}\n","// Match patterns like: 'user_profile', 'workspace_xxx.user_profile', 'user_profile[]', 'workspace_xxx.user_profile[]'，'file_attachment[]', 'workspace_xxx.file_attachment[]'\nconst CUSTOM_TYPE_PATTERN = /\\/\\/ TODO: failed to parse database type '(?:\\w+\\.)?(user_profile|file_attachment)(\\[\\])?'/;\n\nexport { CUSTOM_TYPE_PATTERN };\n\nexport type ReplacementOutcome = {\n  text: string;\n  replaced: number;\n  unmatched: string[];\n};\n\nexport function replaceUnknownColumns(source: string): ReplacementOutcome {\n  const lines = source.split('\\n');\n  const result: string[] = [];\n  let replaced = 0;\n  const unmatched: string[] = [];\n\n  for (let i = 0; i < lines.length; i += 1) {\n    const line = lines[i];\n\n    const match = line.match(CUSTOM_TYPE_PATTERN);\n    if (match) {\n      const typeName = match[1]; // 'user_profile' or 'file_attachment'\n      const factory = typeName === 'user_profile' ? 'userProfile' : 'fileAttachment';\n\n      const replacedLine = replaceFollowingUnknown(lines[i + 1], factory);\n      if (replacedLine) {\n        // Successfully replaced, add the replaced line and skip both the comment and original line\n        result.push(replacedLine);\n        replaced += 1;\n        i += 1; // Skip the next line (original unknown line)\n      } else {\n        // Failed to replace, keep the comment and continue\n        unmatched.push(line.trim());\n        result.push(line);\n      }\n      continue;\n    }\n\n    if (line.includes('unknown(')) {\n      unmatched.push(line.trim());\n    }\n\n    result.push(line);\n  }\n\n  return {\n    text: result.join('\\n'),\n    replaced,\n    unmatched,\n  };\n}\n\nexport function replaceFollowingUnknown(nextLine: string | undefined, factory: 'userProfile' | 'fileAttachment'): string | undefined {\n  if (!nextLine || !nextLine.includes('unknown(')) {\n    return undefined;\n  }\n  // Simply replace 'unknown' with the appropriate factory, preserving everything else (like .array())\n  return nextLine.replace('unknown(', `${factory}(`);\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { HEADER_COMMENT } from './header-format';\n\nexport function tweakImports(source: string): string {\n  const importRegex = /import \\{([^}]*)\\} from \"drizzle-orm\\/pg-core\";?/;\n  const match = source.match(importRegex);\n  if (!match) {\n    return source;\n  }\n\n  const identifiers = match[1]\n    .split(',')\n    .map((id) => id.trim())\n    .filter(Boolean)\n    .filter((id) => id !== 'pgSchema' && id !== 'customType');\n\n  // Remove timestamp if it's no longer used in the source\n  // (after timestamp -> customTimestamptz replacement)\n  const filteredIdentifiers = identifiers.filter((id) => {\n    if (id === 'timestamp') {\n      // Check if timestamp() is still used anywhere\n      const timestampUsageRegex = /timestamp\\s*\\(/;\n      return timestampUsageRegex.test(source);\n    }\n    return true;\n  });\n\n  if (source.includes('pgTable(') && !filteredIdentifiers.includes('pgTable')) {\n    filteredIdentifiers.push('pgTable');\n  }\n  if (source.includes('pgView(') && !filteredIdentifiers.includes('pgView')) {\n    filteredIdentifiers.push('pgView');\n  }\n  if (source.includes('pgMaterializedView(') && !filteredIdentifiers.includes('pgMaterializedView')) {\n    filteredIdentifiers.push('pgMaterializedView');\n  }\n  if (source.includes('pgEnum(') && !filteredIdentifiers.includes('pgEnum')) {\n    filteredIdentifiers.push('pgEnum');\n  }\n  if (source.includes('pgSequence(') && !filteredIdentifiers.includes('pgSequence')) {\n    filteredIdentifiers.push('pgSequence');\n  }\n\n  const unique = Array.from(new Set(filteredIdentifiers));\n  const replacement = `import { ${unique.join(', ')} } from \"drizzle-orm/pg-core\"`;\n  return source.replace(importRegex, replacement);\n}\n\nexport function ensureTypesImport(source: string): string {\n  if (source.includes('from \"./types\"')) {\n    return source;\n  }\n\n  const typesImport = 'import { userProfile, fileAttachment } from \"./types\"\\n';\n  const headerPrefix = `${HEADER_COMMENT}\\n`;\n  if (source.startsWith(headerPrefix)) {\n    const insertionPoint = headerPrefix.length;\n    return `${source.slice(0, insertionPoint)}${typesImport}${source.slice(insertionPoint)}`;\n  }\n\n  const importSectionMatch = source.match(/^(?:import [^\\n]+\\n)+/);\n  if (importSectionMatch) {\n    const insertionPoint = importSectionMatch[0].length;\n    return `${source.slice(0, insertionPoint)}${typesImport}${source.slice(insertionPoint)}`;\n  }\n\n  return `${typesImport}${source}`;\n}\n\nexport function removeInlineTypeHelpers(source: string): string {\n  return source\n    .replace(/type UserProfile = [\\s\\S]*?\\}\\);\\n*/g, '')\n    .replace(/type FileAttachment = [\\s\\S]*?\\}\\);\\n*/g, '');\n}\n\nexport function inlineCustomTypes(source: string): string {\n  // Remove any existing import from \"./types\"\n  let text = source.replace(/import \\{[^}]*\\} from [\"']\\.\\/types[\"'];?\\n*/g, '');\n\n  // Try multiple possible paths for the template file\n  const possiblePaths = [\n    // When bundled by tsup - __dirname points to dist/\n    path.resolve(__dirname, 'template', 'types.ts'),\n    // When running from source (development) - relative to helper/imports.ts\n    path.resolve(__dirname, '../template', 'types.ts'),\n    // Alternative paths\n    path.resolve(__dirname, '../../template', 'types.ts'),\n    path.resolve(__dirname, '../../../template', 'types.ts'),\n  ];\n\n  let templatePath: string | undefined;\n  for (const possiblePath of possiblePaths) {\n    if (fs.existsSync(possiblePath)) {\n      templatePath = possiblePath;\n      break;\n    }\n  }\n\n  if (!templatePath) {\n    console.warn('[postprocess-drizzle-schema] Template types file not found. Tried paths:', possiblePaths);\n    return text;\n  }\n\n  return inlineFromTemplate(text, templatePath);\n}\n\nexport function inlineFromTemplate(text: string, templatePath: string): string {\n  const templateContent = fs.readFileSync(templatePath, 'utf8');\n\n  // Extract the type definitions (everything except the imports)\n  const typeDefinitions = templateContent\n    .replace(/^import\\s+.*;\\r?\\n*/gm, '') // Remove all import statements\n    .trim();\n\n  // Check if we need to add imports for sql and customType\n  const needsSql = typeDefinitions.includes('sql`') && !text.includes(\"from 'drizzle-orm'\") && !text.includes('from \"drizzle-orm\"');\n  const needsCustomType = typeDefinitions.includes('customType<') && !text.includes('customType');\n\n  // Add necessary imports to drizzle-orm/pg-core import\n  if (needsCustomType) {\n    text = ensureImportIdentifier(text, 'drizzle-orm/pg-core', 'customType');\n  }\n\n  // Add sql import from drizzle-orm if needed\n  if (needsSql && !text.includes(\"from 'drizzle-orm'\") && !text.includes('from \"drizzle-orm\"')) {\n    const importMatch = text.match(/^import [\\s\\S]*?from [\"']drizzle-orm\\/pg-core[\"'];?\\n/m);\n    if (importMatch) {\n      const insertPoint = text.indexOf(importMatch[0]) + importMatch[0].length;\n      text = text.slice(0, insertPoint) + \"import { sql } from 'drizzle-orm';\\n\" + text.slice(insertPoint);\n    }\n  }\n\n  // Find insertion point: after the imports section\n  const headerPrefix = `${HEADER_COMMENT}\\n`;\n  let insertionPoint = 0;\n\n  if (text.startsWith(headerPrefix)) {\n    insertionPoint = headerPrefix.length;\n  }\n\n  const importSectionMatch = text.slice(insertionPoint).match(/^(?:import [^\\n]+\\n)+/);\n  if (importSectionMatch) {\n    insertionPoint += importSectionMatch[0].length;\n  }\n\n  // Insert type definitions\n  const typeBlock = `\\n${typeDefinitions}\\n\\n`;\n  return text.slice(0, insertionPoint) + typeBlock + text.slice(insertionPoint);\n}\n\nexport function ensureImportIdentifier(source: string, packageName: string, identifier: string): string {\n  const escapedPackage = packageName.replace(/\\//g, '\\\\/');\n  const importRegex = new RegExp(`import \\\\{([^}]*)\\\\} from [\"']${escapedPackage}[\"'];?`);\n  const match = source.match(importRegex);\n\n  if (!match) {\n    // No import from this package, can't add it\n    return source;\n  }\n\n  const identifiers = match[1]\n    .split(',')\n    .map((id) => id.trim())\n    .filter(Boolean);\n\n  if (identifiers.includes(identifier)) {\n    return source; // Already imported\n  }\n\n  identifiers.push(identifier);\n  const unique = Array.from(new Set(identifiers));\n  const replacement = `import { ${unique.join(', ')} } from \"${packageName}\"`;\n  return source.replace(importRegex, replacement);\n}\n","/**\n * Add comments for system fields in the Drizzle schema source code.\n * @param source The source code string to process\n * @returns The processed source code with system field comments added\n */\nexport function addSystemFieldComments(source: string): string {\n  const commentMap: Record<string, string> = {\n    '_created_at': 'Creation time',\n    '_created_by': 'Creator',\n    '_updated_at': 'Update time',\n    '_updated_by': 'Updater',\n  };\n\n  const lines = source.split('\\n');\n\n  for (let i = 0; i < lines.length; i += 1) {\n    const line = lines[i];\n    const entry = Object.entries(commentMap).find(([key]) => line.includes(`\"${key}\"`));\n    if (!entry) {\n      continue;\n    }\n\n    const [, description] = entry;\n    const previousLine = lines[i - 1]?.trim() ?? '';\n    if (previousLine.startsWith('//') && previousLine.includes('System field')) {\n      continue;\n    }\n\n    const indentMatch = line.match(/^\\s*/);\n    const indent = indentMatch ? indentMatch[0] : '';\n    const comment = `${indent}// System field: ${description} (auto-filled, do not modify)`;\n    lines.splice(i, 0, comment);\n    i += 1;\n  }\n\n  return lines.join('\\n');\n}\n\n/**\n * Remove conflicting system fields from the Drizzle schema source code.\n * @param source The source code string to process\n * @returns The processed source code with conflicting system fields removed\n */\nexport function removeConflictingSystemFields(source: string): string {\n  const systemFieldMap: Record<string, string> = {\n    '_created_at': 'created_at',\n    '_created_by': 'created_by',\n    '_updated_at': 'updated_at',\n    '_updated_by': 'updated_by',\n  };\n\n  const lines = source.split('\\n');\n  const result: Array<string | null> = [];\n\n  // Track table-level state\n  let inTable = false;\n  let tableStartLine = -1;\n  const tableBusinessFields = new Set<string>();\n  let bracketDepth = 0;\n\n  for (let i = 0; i < lines.length; i += 1) {\n    const line = lines[i];\n\n    // Check if we're starting a new table definition\n    if (!inTable && /=\\s*(pgTable|pgView|pgMaterializedView)\\s*\\(/.test(line)) {\n      inTable = true;\n      tableStartLine = result.length;\n      tableBusinessFields.clear();\n      bracketDepth = 0;\n    }\n\n    if (inTable) {\n      // Track bracket depth to find table end\n      for (const char of line) {\n        if (char === '{') bracketDepth++;\n        if (char === '}') bracketDepth--;\n      }\n\n      // Collect business fields in this table\n      for (const businessField of Object.values(systemFieldMap)) {\n        if (line.includes(`\"${businessField}\"`) || line.includes(`'${businessField}'`)) {\n          tableBusinessFields.add(businessField);\n        }\n      }\n\n      // Check if table definition ends\n      if (bracketDepth === 0 && line.includes(');')) {\n        inTable = false;\n\n        // Now process this table's lines to remove conflicting system fields\n        const tableEndLine = result.length;\n        for (let j = tableStartLine; j <= tableEndLine; j++) {\n          const tableLine = result[j] || '';\n          let shouldRemove = false;\n\n          for (const [systemField, businessField] of Object.entries(systemFieldMap)) {\n            if (tableBusinessFields.has(businessField)) {\n              if (tableLine.includes(`\"${systemField}\"`) || tableLine.includes(`'${systemField}'`)) {\n                shouldRemove = true;\n                // Also remove previous line if it's a system field comment\n                if (j > 0 && result[j - 1]?.includes('// System field:')) {\n                  result[j - 1] = null; // Mark for removal\n                }\n                break;\n              }\n            }\n          }\n\n          if (shouldRemove) {\n            result[j] = null; // Mark for removal\n          }\n        }\n      }\n    }\n\n    result.push(line);\n  }\n\n  // Filter out null entries (marked for removal)\n  return result.filter(line => line !== null).join('\\n');\n}\n","/**\n * Patch for drizzle-kit defects.\n *\n * Fix syntax error: .default(') -> .default('')\n * This is a drizzle-kit bug that generates invalid TypeScript code.\n */\n\n/**\n * Fix drizzle-kit syntax error where .default(') is generated.\n *\n * @param source - The schema source code\n * @returns Object with fixed text and count of fixes applied\n */\nexport function patchDrizzleKitDefects(source: string): { text: string; fixed: number } {\n  let fixed = 0;\n\n  // Fix syntax error: .default(') -> .default('')\n  const text = source.replace(/\\.default\\('\\)/g, () => {\n    fixed += 1;\n    return `.default('')`;\n  });\n\n  return { text, fixed };\n}\n","/**\n * Replace timestamp with specific options to custom types.\n *\n * Replaces timestamp(\"field\", { withTimezone: true, mode: 'string' })\n * with customTimestamptz(\"field\")\n */\n\n/**\n * Replace timestamp with timezone and string mode to customTimestamptz.\n *\n * @param source - The schema source code\n * @returns Object with replaced text and count of replacements\n */\nexport function replaceTimestampWithCustomTypes(source: string): { text: string; replaced: number } {\n  let replaced = 0;\n\n  // Match timestamp with any options: timestamp(\"field\", { ... })\n  const pattern = /timestamp\\((['\"])(.*?)\\1,\\s*(\\{[^}]*\\})\\)/g;\n\n  const text = source.replace(pattern, (match, quote, fieldName, options) => {\n    // Check if options contain both withTimezone: true and mode: 'string'\n    const hasWithTimezone = /withTimezone:\\s*true/.test(options);\n    const hasModeString = /mode:\\s*['\"]string['\"]/.test(options);\n\n    if (hasWithTimezone && hasModeString) {\n      replaced += 1;\n      return `customTimestamptz(${quote}${fieldName}${quote})`;\n    }\n\n    // Return original if conditions not met\n    return match;\n  });\n\n  return { text, replaced };\n}\n\n/**\n * Replace .defaultNow() with .default(sql`CURRENT_TIMESTAMP`)\n * for custom timestamp types that don't support defaultNow().\n *\n * @param source - The schema source code\n * @returns Object with replaced text and count of replacements\n */\nexport function replaceDefaultNowWithSql(source: string): { text: string; replaced: number } {\n  let replaced = 0;\n\n  // Match .defaultNow() and replace with .default(sql`CURRENT_TIMESTAMP`)\n  const pattern = /\\.defaultNow\\(\\)/g;\n\n  const text = source.replace(pattern, () => {\n    replaced += 1;\n    return '.default(sql`CURRENT_TIMESTAMP`)';\n  });\n\n  return { text, replaced };\n}\n","const TABLE_ALIAS_MARKER = '// table aliases';\n\nexport function appendTableAliases(source: string): string {\n  const markerIndex = source.indexOf(`\\n${TABLE_ALIAS_MARKER}`);\n  const base = markerIndex === -1 ? source : source.slice(0, markerIndex);\n\n  const exportRegex = /export const\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*pgTable\\s*\\(/g;\n  const tableExports = new Set<string>();\n\n  for (const match of base.matchAll(exportRegex)) {\n    const name = match[1];\n    tableExports.add(name);\n  }\n\n  if (tableExports.size === 0) {\n\n    return base;\n\n  }\n\n  const aliasLines = Array.from(tableExports)\n    .sort()\n    .map((name) => `export const ${name}Table = ${name};`)\n    .join('\\n');\n\n  const prefix = base.trimEnd();\n  return `${prefix}\\n\\n${TABLE_ALIAS_MARKER}\\n${aliasLines}\\n`;\n}\n","import { pluralize } from 'inflection';\nimport { FieldInfo, TableInfo } from './schema-parser';\nimport { mapDrizzleTypeToTS, toKebabCase, toPascalCase, toSnakeCase } from './utils';\n\nexport function generateDTO(table: TableInfo): string {\n  const className = toPascalCase(table.variableName);\n\n  let dto = `// 请修改该文件代码以满足需求\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport { IsDefined, IsNumber, IsOptional, IsString, MaxLength, IsInt, IsBoolean, IsUUID, IsDate, IsObject, IsArray } from 'class-validator';\nimport { Type } from 'class-transformer';\nimport { FileAttachment } from '../../../database/schema';\n\n`;\n  dto += `export class Create${className}Dto {\\n`;\n\n  for (const field of table.fields) {\n    // 跳过主键\n    if (\n      field.isPrimaryKey || field.name === 'id' ||\n      field.name.startsWith('_') ||\n      field.name.startsWith('created') ||\n      field.name.startsWith('updated')\n    ) {\n      continue;\n    }\n\n    // if (field.comment) {\n    //   dto += `  /** ${field.comment} */\\n`;\n    // }\n\n    const tsType = mapDrizzleTypeToTS(field);\n    const optional = field.nullable || field.hasDefault ? '?' : '';\n\n    // 添加验证装饰器注释\n    const decorators = generateValidationDecorators(field);\n    if (decorators) {\n      dto += decorators;\n    }\n\n    dto += `  ${field.name}${optional}: ${tsType};\\n\\n`;\n  }\n\n  dto += '}\\n\\n';\n\n  // Update DTO\n  dto += `export class Update${className}Dto {\\n`;\n\n  for (const field of table.fields) {\n    // 跳过系统字段和主键\n    if (\n      field.name.startsWith('_') ||\n      field.name.startsWith('created') ||\n      field.name.startsWith('updated') ||\n      field.isPrimaryKey || field.name === 'id'\n    ) {\n      continue;\n    }\n\n    // 先不插入注释\n    // if (field.comment) {\n    //   dto += `  /** ${field.comment} */\\n`;\n    // }\n\n    const tsType = mapDrizzleTypeToTS(field);\n\n    const decorators = generateValidationDecorators(field, {\n      isUpdate: true,\n    });\n    if (decorators) {\n      dto += decorators;\n    }\n\n    dto += `  ${field.name}?: ${tsType};\\n\\n`;\n  }\n\n  dto += '}\\n\\n';\n\n  // Response DTO\n  dto += `export class ${className}ResponseDto {\\n`;\n\n  for (const field of table.fields) {\n    // if (field.comment) {\n    //   dto += `  /** ${field.comment} */\\n`;\n    // }\n\n    const tsType = mapDrizzleTypeToTS(field);\n    const optional = field.nullable ? '?' : '';\n\n    const decorators = generateValidationDecorators(field, {\n      isResponse: true,\n    });\n    if (decorators) {\n      dto += decorators;\n    }\n\n    dto += `  ${field.name}${optional}: ${tsType};\\n\\n`;\n  }\n\n  dto += '}\\n';\n\n  return dto;\n}\n\n// 生成验证装饰器提示\nexport function generateValidationDecorators(field: FieldInfo, {\n  isUpdate = false,\n  isResponse = false,\n}: { isUpdate?: boolean, isResponse?: boolean } = {}): string {\n  let decorators = '  // 请按用户需求修改以下装饰器注释\\n';\n\n  if (field.nullable || (!isResponse && field.hasDefault) || isUpdate) {\n    decorators += `  @ApiPropertyOptional({ description: '${field.comment || field.name}' })\\n`;\n    if (isResponse) {\n      return decorators;\n    }\n    decorators += '  @IsOptional()\\n';\n  } else {\n    decorators += `  @ApiProperty({ description: '${field.comment || field.name}' })\\n`;\n    if (isResponse) {\n      return decorators;\n    }\n    decorators += '  @IsDefined()\\n';\n  }\n\n  // 根据字段类型和约束生成装饰器注释\n  switch (field.type) {\n    case 'varchar':\n    case 'char':\n    case 'text':\n      decorators += '  @IsString()\\n';\n      if (field.length) {\n        decorators += `  @MaxLength(${field.length})\\n`;\n      }\n      break;\n\n    case 'integer':\n    case 'smallint':\n    case 'serial':\n    case 'smallserial':\n      decorators += '  @IsInt()\\n';\n      break;\n\n    case 'decimal':\n    case 'numeric':\n    case 'real':\n    case 'doublePrecision':\n      decorators += '  @IsNumber()\\n';\n      break;\n\n    case 'boolean':\n      decorators += '  @IsBoolean()\\n';\n      break;\n\n    case 'uuid':\n      decorators += '  @IsUUID()\\n';\n      break;\n\n    case 'timestamp':\n    case 'timestamptz':\n    case 'date':\n    case 'customTimestamptz':\n      decorators += '  @IsDate()\\n';\n      break;\n\n    case 'json':\n    case 'jsonb':\n      decorators += '  @IsObject()\\n';\n      break;\n\n    // case 'inet':\n    // case 'cidr':\n    //   decorators += '  // @IsIP()\\n';\n    //   break;\n  }\n\n  if (field.isArray) {\n    decorators += '  @IsArray()\\n';\n  }\n\n  // if (field.isUnique) {\n  //   decorators += '  // @IsUnique() // Custom validator needed\\n';\n  // }\n\n  // if (field.enumValues) {\n  //   decorators += `  // @IsEnum([${field.enumValues.map((v) => `'${v}'`).join(', ')}])\\n`;\n  // }\n\n  return decorators;\n}\n\n// Controller 生成器\nexport function generateController(table: TableInfo): string {\n  const className = toPascalCase(table.variableName);\n  const routePath = toKebabCase(pluralize(table.variableName));\n  const filePath = toSnakeCase(table.variableName);\n\n  // 找到主键字段\n  const pkField = table.fields.find((f) => f.isPrimaryKey);\n  const pkType = pkField ? mapDrizzleTypeToTS(pkField) : 'string';\n  const pkName = pkField ? pkField.name : 'id';\n\n  const controller = `\n// 请修改该文件代码以满足需求\nimport { \n  Controller, \n  Get, \n  Post, \n  Put, \n  Delete, \n  Body, \n  Param, \n  Query,\n} from '@nestjs/common';\n import {\n  ApiTags,\n  ApiOperation,\n  ApiOkResponse,\n  ApiCreatedResponse,\n} from '@nestjs/swagger';\nimport { \n  Create${className}Dto, \n  Update${className}Dto,\n  ${className}ResponseDto\n} from './dtos/${filePath}.dto';\nimport { ${className}Service } from './${filePath}.service';\n\n@ApiTags('${toPascalCase(table.variableName)}')\n@Controller('api/${routePath}')\nexport class ${className}Controller {\n  constructor(private readonly ${table.variableName}Service: ${className}Service) {}\n\n  @Post()\n  @ApiOperation({\n    summary: '创建一条记录（模板内容，请修改我）',\n    description: '创建一条记录（模板内容，请修改我）',\n  })\n  @ApiCreatedResponse({\n    description: '成功创建一条记录',\n    type: ${className}ResponseDto,\n  })\n  async create(\n    @Body() createDto: Create${className}Dto\n  ): Promise<${className}ResponseDto> {\n    return this.${table.variableName}Service.create(createDto);\n  }\n\n  @ApiOperation({\n    summary: '根据主键查询一条记录（模板内容，请修改我）',\n    description: '根据主键查询一条记录（模板内容，请修改我）',\n  })\n  @ApiOkResponse({\n    description: '成功查询一条记录',\n    type: ${className}ResponseDto,\n  })\n  @Get(':${pkName}')\n  async findOne(\n    @Param('${pkName}') ${pkName}: ${pkType}\n  ): Promise<${className}ResponseDto> {\n    return this.${table.variableName}Service.findOne(${pkName});\n  }\n\n  @ApiOperation({\n    summary: '根据主键更新一条记录（模板内容，请修改我）',\n    description: '根据主键更新一条记录（模板内容，请修改我）',\n  })\n  @ApiOkResponse({\n    description: '成功更新一条记录',\n    type: ${className}ResponseDto,\n  })\n  @Put(':${pkName}')\n  async update(\n    @Param('${pkName}') ${pkName}: ${pkType},\n    @Body() updateDto: Update${className}Dto\n  ): Promise<${className}ResponseDto> {\n    return this.${table.variableName}Service.update(${pkName}, updateDto);\n  }\n\n  @ApiOperation({\n    summary: '根据主键删除一条记录（模板内容，请修改我）',\n    description: '根据主键删除一条记录（模板内容，请修改我）',\n  })\n  @ApiOkResponse({\n    description: '成功删除一条记录',\n  })\n  @Delete(':${pkName}')\n  async remove(\n    @Param('${pkName}') ${pkName}: ${pkType}\n  ): Promise<void> {\n    return this.${table.variableName}Service.remove(${pkName});\n  }\n}\n`;\n\n  return controller;\n}\n\n// Service 生成器\nexport function generateService(table: TableInfo): string {\n  const className = toPascalCase(table.variableName);\n  const filePath = toSnakeCase(table.variableName);\n\n  const pkField = table.fields.find((f) => f.isPrimaryKey);\n  const pkType = pkField ? mapDrizzleTypeToTS(pkField) : 'string';\n  const pkName = pkField ? pkField.name : 'id';\n\n  const service = `\n// 请修改该文件代码以满足需求\nimport { Injectable, Inject, Logger, NotFoundException } from '@nestjs/common';\nimport { eq } from 'drizzle-orm';\nimport { DRIZZLE_DATABASE, type PostgresJsDatabase } from '@lark-apaas/fullstack-nestjs-core';\nimport { ${table.variableName} } from '../../database/schema';\nimport { \n  Create${className}Dto, \n  Update${className}Dto,\n  ${className}ResponseDto \n} from './dtos/${filePath}.dto';\n\n@Injectable()\nexport class ${className}Service {\n  private readonly logger = new Logger(${className}Service.name);\n\n  constructor(@Inject(DRIZZLE_DATABASE) private readonly db: PostgresJsDatabase) {}\n\n  async create(createDto: Create${className}Dto): Promise<${className}ResponseDto> {\n    const [result] = await this.db\n      .insert(${table.variableName})\n      .values(createDto)\n      .returning();\n\n    this.logger.log(\\`Created ${className} with ${pkName} \\${result.${pkName}}\\`);\n    \n    return result;\n  }\n\n  async findAll(options?: { page?: number; limit?: number }): Promise<${className}ResponseDto[]> {\n    const { page = 1, limit = 10 } = options || {};\n    const offset = (page - 1) * limit;\n\n    return this.db\n      .select()\n      .from(${table.variableName})\n      .limit(limit)\n      .offset(offset);\n  }\n\n  async findOne(${pkName}: ${pkType}): Promise<${className}ResponseDto> {\n    const [result] = await this.db\n      .select()\n      .from(${table.variableName})\n      .where(eq(${table.variableName}.${pkName}, ${pkName}))\n      .limit(1);\n\n    if (!result) {\n      throw new NotFoundException(\\`${className} with ${pkName} \\${${pkName}} not found\\`);\n    }\n\n    return result;\n  }\n\n  async update(${pkName}: ${pkType}, updateDto: Update${className}Dto): Promise<${className}ResponseDto> {\n    const [result] = await this.db\n      .update(${table.variableName})\n      .set(updateDto)\n      .where(eq(${table.variableName}.${pkName}, ${pkName}))\n      .returning();\n\n    if (!result) {\n      throw new NotFoundException(\\`${className} with ${pkName} \\${${pkName}} not found\\`);\n    }\n\n    return result;\n  }\n\n  async remove(${pkName}: ${pkType}): Promise<void> {\n    const result = await this.db\n      .delete(${table.variableName})\n      .where(eq(${table.variableName}.${pkName}, ${pkName}))\n      .returning();\n\n    if (result.length === 0) {\n      throw new NotFoundException(\\`${className} with ${pkName} \\${${pkName}} not found\\`);\n    }\n\n    this.logger.log(\\`Deleted ${className} with ${pkName} \\${${pkName}}\\`);\n  }\n}\n`;\n\n  return service;\n}\n\nexport function generateModule(table: TableInfo): string {\n  const className = toPascalCase(table.variableName);\n  const filePath = toSnakeCase(table.variableName);\n\n  const module = `\nimport { Module } from '@nestjs/common';\nimport { ${className}Controller } from './${filePath}.controller';\nimport { ${className}Service } from './${filePath}.service';\n\n@Module({\n  controllers: [${className}Controller],\n  providers: [${className}Service],\n})\nexport class ${className}Module {}\n`;\n\n  return module;\n}\n","import { FieldInfo } from './schema-parser';\n\n// 完整的类型映射\nexport function mapDrizzleTypeToTS(field: FieldInfo): string {\n  const typeMap: Record<string, string> = {\n    // String types\n    char: 'string',\n    varchar: 'string',\n    text: 'string',\n\n    // Numeric types\n    smallint: 'number',\n    integer: 'number',\n    int: 'number',\n    bigint: 'string', // bigint 在 JS 中通常作为 string 处理\n    serial: 'number',\n    smallserial: 'number',\n    bigserial: 'string',\n\n    // Decimal types\n    decimal: 'string', // 精确数值通常用 string\n    numeric: 'string',\n    real: 'number',\n    doublePrecision: 'number',\n\n    // Boolean\n    boolean: 'boolean',\n\n    // Date/Time types\n    timestamp: 'Date',\n    timestamptz: 'Date',\n    date: 'Date',\n    time: 'string',\n    timetz: 'string',\n    interval: 'string',\n\n    // UUID\n    uuid: 'string',\n\n    // JSON types\n    json: 'any',\n    jsonb: 'any',\n\n    // Binary\n    bytea: 'Buffer',\n\n    // Network types\n    inet: 'string',\n    cidr: 'string',\n    macaddr: 'string',\n    macaddr8: 'string',\n\n    // Geometric types\n    point: '{ x: number; y: number }',\n    line: 'string',\n    lseg: 'string',\n    box: 'string',\n    path: 'string',\n    polygon: 'string',\n    circle: 'string',\n\n    // Array types (handled by isArray flag)\n    array: 'any[]',\n\n    // Custom types\n    customType: 'any',\n    customTimestamptz: 'Date',\n    userProfile: 'string',\n    fileAttachment: 'FileAttachment',\n\n    // Enum (handled separately)\n    pgEnum: 'string',\n  };\n\n  let baseType = typeMap[field.type] || 'any';\n\n  // 处理数组类型\n  if (field.isArray) {\n    baseType = baseType.endsWith('[]') ? baseType : `${baseType}[]`;\n  }\n\n  // 处理枚举\n  if (field.enumValues && field.enumValues.length > 0) {\n    baseType = field.enumValues.map((v) => `'${v}'`).join(' | ');\n  }\n\n  return baseType;\n}\n\n// 辅助函数\nexport function toPascalCase(str: string): string {\n  return str\n    .replace(/([a-z])([A-Z])/g, '$1 $2')\n    .split(/[-_\\s]/)\n    .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n    .join('');\n}\n\nexport function toKebabCase(str: string): string {\n  return str\n    .replace(/([a-z])([A-Z])/g, '$1-$2')\n    .toLowerCase()\n    .replace(/[_\\s]/g, '-');\n}\n\nexport function toSnakeCase(str: string): string {\n  return str\n    .replace(/([a-z])([A-Z])/g, '$1_$2')\n    .toLowerCase()\n    .replace(/[-\\s]/g, '_');\n}\n","import { Project, CallExpression, Node, ProjectOptions } from 'ts-morph';\n\ninterface FieldInfo {\n  name: string;\n  columnName: string;\n  type: string;\n  length?: number;\n  precision?: number;\n  scale?: number;\n  nullable: boolean;\n  hasDefault: boolean;\n  defaultValue?: string;\n  notNull: boolean;\n  mode?: 'string' | 'number' | 'bigint' | 'boolean' | 'date';\n  isPrimaryKey: boolean;\n  isUnique: boolean;\n  isArray: boolean;\n  comment?: string;\n  enumValues?: string[];\n  withTimezone?: boolean;\n  references?: {\n    table: string;\n    column: string;\n  };\n}\n\ninterface TableInfo {\n  tableName: string;\n  variableName: string;\n  fields: FieldInfo[];\n}\n\nclass DrizzleSchemaParser {\n  private project: Project;\n\n  constructor(projectOptions: ProjectOptions) {\n    this.project = new Project(projectOptions);\n  }\n\n  parseSchemaFile(filePath: string): TableInfo[] {\n    const sourceFile = this.project.addSourceFileAtPath(filePath);\n    const tables: TableInfo[] = [];\n\n    // 查找所有变量声明\n    const variableStatements = sourceFile.getVariableStatements();\n\n    for (const statement of variableStatements) {\n      const declarations = statement.getDeclarations();\n\n      for (const declaration of declarations) {\n        const initializer = declaration.getInitializer();\n\n        if (initializer && Node.isCallExpression(initializer)) {\n          const expression = initializer.getExpression();\n\n          // 检查是否是 pgTable 调用\n          if (expression.getText() === 'pgTable') {\n            const tableInfo = this.parsePgTable(\n              declaration.getName(),\n              initializer,\n            );\n            if (tableInfo) {\n              tables.push(tableInfo);\n            }\n          }\n        }\n      }\n    }\n\n    return tables;\n  }\n\n  private parsePgTable(\n    variableName: string,\n    callExpr: CallExpression,\n  ): TableInfo | null {\n    const args = callExpr.getArguments();\n\n    if (args.length < 2) {\n      return null;\n    }\n\n    // 表名\n    const tableName = args[0].getText().replace(/['\"]/g, '');\n\n    // 字段定义对象\n    const fieldsArg = args[1];\n\n    if (!Node.isObjectLiteralExpression(fieldsArg)) {\n      return null;\n    }\n\n    const fields: FieldInfo[] = [];\n\n    // 解析字段\n    const properties = fieldsArg.getProperties();\n\n    for (const prop of properties) {\n      if (Node.isPropertyAssignment(prop)) {\n        const fieldName = prop.getName();\n        const initializer = prop.getInitializer();\n\n        // 获取字段上方的注释\n        const leadingComments = prop.getLeadingCommentRanges();\n        let comment: string | undefined;\n\n        if (leadingComments.length > 0) {\n          comment = leadingComments\n            .map((c) => c.getText())\n            .join('\\n')\n            .replace(/\\/\\//g, '')\n            .trim();\n        }\n\n        if (initializer && Node.isCallExpression(initializer)) {\n          const fieldInfo = this.parseField(fieldName, initializer, comment);\n          fields.push(fieldInfo);\n        }\n      }\n    }\n\n    return {\n      tableName,\n      variableName,\n      fields,\n    };\n  }\n\n  private parseField(\n    fieldName: string,\n    callExpr: CallExpression,\n    comment?: string,\n  ): FieldInfo {\n    const fieldInfo: FieldInfo = {\n      name: fieldName,\n      columnName: fieldName,\n      type: '',\n      nullable: true,\n      hasDefault: false,\n      notNull: false,\n      isPrimaryKey: false,\n      isUnique: false,\n      isArray: false,\n      comment,\n    };\n\n    // 获取字段类型和基础参数\n    this.parseBaseType(callExpr, fieldInfo);\n\n    // 解析整个调用链\n    this.parseCallChain(callExpr, fieldInfo);\n\n    return fieldInfo;\n  }\n\n  private parseBaseType(callExpr: CallExpression, fieldInfo: FieldInfo): void {\n    // 找到最底层的类型调用\n    let current: Node = callExpr;\n    let baseCall: CallExpression | null = null;\n\n    while (Node.isCallExpression(current)) {\n      baseCall = current;\n      const expression = current.getExpression();\n\n      if (Node.isPropertyAccessExpression(expression)) {\n        current = expression.getExpression();\n      } else {\n        break;\n      }\n    }\n\n    if (!baseCall) {\n      return;\n    }\n\n    const expression = baseCall.getExpression();\n    let typeName = '';\n\n    if (Node.isPropertyAccessExpression(expression)) {\n      typeName = expression.getName();\n    } else {\n      typeName = expression.getText();\n    }\n\n    fieldInfo.type = typeName;\n\n    // 解析类型参数\n    const args = baseCall.getArguments();\n\n    if (args.length > 0) {\n      const firstArg = args[0];\n\n      // 字符串参数 - 列名\n      if (Node.isStringLiteral(firstArg)) {\n        fieldInfo.columnName = firstArg.getLiteralText();\n      }\n      // 对象参数 - 配置\n      else if (Node.isObjectLiteralExpression(firstArg)) {\n        this.parseTypeConfig(firstArg, fieldInfo);\n      }\n      // 数组参数 - enum 值\n      else if (Node.isArrayLiteralExpression(firstArg)) {\n        fieldInfo.enumValues = firstArg\n          .getElements()\n          .map((el) => el.getText().replace(/['\"]/g, ''));\n      }\n    }\n\n    // 第二个参数可能是配置对象\n    if (args.length > 1 && Node.isObjectLiteralExpression(args[1])) {\n      this.parseTypeConfig(args[1], fieldInfo);\n    }\n  }\n\n  private parseTypeConfig(objLiteral: Node, fieldInfo: FieldInfo): void {\n    if (!Node.isObjectLiteralExpression(objLiteral)) {\n      return;\n    }\n\n    const properties = objLiteral.getProperties();\n\n    for (const prop of properties) {\n      if (Node.isPropertyAssignment(prop)) {\n        const propName = prop.getName();\n        const value = prop.getInitializer()?.getText();\n\n        switch (propName) {\n          case 'length':\n            fieldInfo.length = value ? parseInt(value) : undefined;\n            break;\n          case 'precision':\n            fieldInfo.precision = value ? parseInt(value) : undefined;\n            break;\n          case 'scale':\n            fieldInfo.scale = value ? parseInt(value) : undefined;\n            break;\n          case 'default':\n            fieldInfo.hasDefault = true;\n            fieldInfo.defaultValue = value;\n            break;\n          // 时间精度（用于 timestamp, time 等）\n          case 'withTimezone':\n            fieldInfo.withTimezone = value === 'true';\n            break;\n          case 'mode':\n            // mode 可以是 'string' | 'number' | 'bigint' | 'boolean' | 'date'\n            // 用于指定 JS 中的数据类型\n            fieldInfo.mode = value?.replace(/['\"]/g, '') as\n              | 'string'\n              | 'number'\n              | 'bigint'\n              | 'boolean'\n              | 'date'\n              | undefined;\n            break;\n          default:\n            throw new Error(`Unsupported property: ${propName}`);\n        }\n      }\n    }\n  }\n\n  private parseCallChain(callExpr: CallExpression, fieldInfo: FieldInfo): void {\n    let current: Node = callExpr;\n\n    while (Node.isCallExpression(current)) {\n      const expression = current.getExpression();\n\n      if (Node.isPropertyAccessExpression(expression)) {\n        const methodName = expression.getName();\n        const args = current.getArguments();\n\n        switch (methodName) {\n          case 'notNull':\n            fieldInfo.notNull = true;\n            fieldInfo.nullable = false;\n            break;\n\n          case 'default':\n            fieldInfo.hasDefault = true;\n            if (args.length > 0) {\n              fieldInfo.defaultValue = args[0].getText();\n            }\n            break;\n\n          case 'defaultRandom':\n            fieldInfo.hasDefault = true;\n            fieldInfo.defaultValue = 'random';\n            break;\n\n          case 'primaryKey':\n            fieldInfo.isPrimaryKey = true;\n            fieldInfo.notNull = true;\n            fieldInfo.nullable = false;\n            break;\n\n          case 'unique':\n            fieldInfo.isUnique = true;\n            break;\n\n          case 'array':\n            fieldInfo.isArray = true;\n            break;\n\n          case 'references':\n            if (args.length > 0) {\n              const refArg = args[0].getText();\n              // 解析引用，如 () => users.id\n              const match = refArg.match(/=>\\s*(\\w+)\\.(\\w+)/);\n              if (match) {\n                fieldInfo.references = {\n                  table: match[1],\n                  column: match[2],\n                };\n              }\n            }\n            break;\n          default:\n            throw new Error(`Unsupported method: ${methodName}`);\n        }\n\n        current = expression.getExpression();\n      } else {\n        break;\n      }\n    }\n  }\n}\n\nexport { DrizzleSchemaParser, TableInfo, FieldInfo };\n\n","import { generateController, generateDTO, generateModule, generateService } from './generator';\nimport { DrizzleSchemaParser } from './schema-parser';\nimport { join } from 'path';\nimport { toSnakeCase } from './utils';\nimport { mkdir, rm, writeFile } from 'fs/promises';\nimport { existsSync } from 'fs';\n\nexport interface Options {\n  tsConfigFilePath: string;\n  schemaFilePath: string;\n  moduleOutputDir: string;\n}\n\nexport async function parseAndGenerateNestResourceTemplate(options: Options) {\n  const parser = new DrizzleSchemaParser({\n    tsConfigFilePath: options.tsConfigFilePath,\n  });\n  const tables = parser.parseSchemaFile(options.schemaFilePath);\n\n  if (tables.length === 0) {\n    console.warn('未解析到任何数据库表，无需生成 Nest.js 模块模板');\n    return;\n  }\n\n  // 按照变量名长度排序，降序\n  tables.sort((a, b) => b.variableName.length - a.variableName.length);\n\n  const table = tables[0];\n\n  // 生成代码，只生成一个模块的\n  console.info(`生成 Nest.js ${table.variableName} 模块`);\n  const filePath = toSnakeCase(table.variableName);\n  const moduleDir = join(options.moduleOutputDir, filePath);\n  if (existsSync(moduleDir)) {\n    console.info(`Nest.js 模块 ${filePath} 已存在，跳过生成代码`);\n    return;\n  }\n  const dto = generateDTO(table);\n  const controller = generateController(table);\n  const service = generateService(table);\n  const moduleFilePath = join(moduleDir, `${filePath}.module.ts`);\n  const module = generateModule(table);\n\n  try {\n    await mkdir(moduleDir, { recursive: true });\n    await mkdir(join(moduleDir, 'dtos'), { recursive: true });\n    await writeFile(join(moduleDir, 'dtos', `${filePath}.dto.ts`), dto);\n    await writeFile(join(moduleDir, `${filePath}.controller.ts`), controller);\n    await writeFile(join(moduleDir, `${filePath}.service.ts`), service);\n    await writeFile(moduleFilePath, module);\n  } catch (err) {\n    console.error(`生成 Nest.js ${filePath} 模块失败: ${(err as Error).message}`);\n    await rm(moduleDir, { recursive: true });\n  }\n}\n\n// const projectDir = '/Users/bytedance/Workspace/nestjs-react-fullstack-template';\n// const tsConfigFilePath = join(projectDir, './tsconfig.json');\n// const schemaFilePath = join(projectDir, './server/database/schema.ts');\n\n// const tmp = mkdtempSync(join(tmpdir(), 'tmp-'));\n// console.log('生成到 ', tmp);\n\n// parseAndGenerateNestResourceTemplate({\n//   tsConfigFilePath,\n//   schemaFilePath,\n//   moduleOutputDir: tmp,\n// }).finally(() => {\n//   console.log('NestJS 资源模板生成完成');\n// });\n","import * as http from 'node:http';\nimport * as https from 'node:https';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\n/**\n * Proxy Error Handler 选项\n */\nexport interface ProxyErrorOptions {\n  /** 等待服务重启的超时时间（毫秒），默认 5000ms */\n  retryTimeout?: number;\n  /** 轮询检查服务的间隔时间（毫秒），默认 500ms */\n  retryInterval?: number;\n  /** 目标服务器地址，用于检查服务是否恢复，格式：http://localhost:3000 */\n  target?: string;\n}\n\n/**\n * 判断是否是连接错误（服务未启动或重启中）\n */\nfunction isConnectionError(err: Error): boolean {\n  const code = (err as NodeJS.ErrnoException).code;\n  const connectionErrorCodes = ['ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'ENETUNREACH'];\n  return connectionErrorCodes.includes(code || '');\n}\n\n/**\n * 检查服务是否可用（通过 HTTP 请求）\n */\nfunction checkServiceAvailable(targetUrl: string, timeout = 2000): Promise<boolean> {\n  return new Promise((resolve) => {\n    try {\n      const url = new URL(targetUrl);\n      const isHttps = url.protocol === 'https:';\n      const httpModule = isHttps ? https : http;\n\n      const req = httpModule.request(\n        {\n          hostname: url.hostname,\n          port: url.port || (isHttps ? 443 : 80),\n          path: '/',\n          method: 'HEAD',\n          timeout,\n        },\n        (res) => {\n          // 任何非 502 响应都表示服务可用\n          resolve(res.statusCode !== 502);\n        }\n      );\n\n      req.on('timeout', () => {\n        req.destroy();\n        resolve(false);\n      });\n\n      req.on('error', () => {\n        resolve(false);\n      });\n\n      req.end();\n    } catch {\n      resolve(false);\n    }\n  });\n}\n\n/**\n * 等待服务恢复，带超时和轮询检查\n */\nasync function waitForServiceRecovery(\n  targetUrl: string,\n  timeout: number,\n  interval: number\n): Promise<boolean> {\n  const startTime = Date.now();\n\n  while (Date.now() - startTime < timeout) {\n    const isAvailable = await checkServiceAvailable(targetUrl, 2000);\n    if (isAvailable) {\n      return true;\n    }\n    await new Promise(resolve => setTimeout(resolve, interval));\n  }\n\n  return false;\n}\n\n/**\n * 发送 502 JSON 响应\n */\nfunction send502Json(res: ServerResponse): void {\n  if (res.headersSent) return;\n\n  res.writeHead(502, {\n    'Content-Type': 'application/json; charset=utf-8',\n    'Cache-Control': 'no-cache, no-store, must-revalidate',\n  });\n  res.end(JSON.stringify({\n    error: 'Bad Gateway',\n    message: 'Backend service is temporarily unavailable',\n  }));\n}\n\n/**\n * 发送 302 重定向响应\n */\nfunction sendRedirect(req: IncomingMessage, res: ServerResponse): void {\n  if (res.headersSent) return;\n\n  const originalUrl = req.url || '/';\n  console.log('[Proxy] Service recovered, redirecting to', originalUrl);\n\n  res.writeHead(302, {\n    'Location': originalUrl,\n    'Cache-Control': 'no-cache, no-store, must-revalidate',\n  });\n  res.end();\n}\n\n/**\n * HTTP Proxy 错误处理器\n *\n * 处理策略：\n * 1. 连接错误（服务重启中）→ 等待 5s，恢复则 302 重定向，否则 502\n * 2. 其他错误 → 直接 502\n *\n * @example\n * ```typescript\n * import { createProxyMiddleware } from 'http-proxy-middleware';\n * import { handleDevProxyError } from '@lark-apaas/devtool-kits';\n *\n * const proxy = createProxyMiddleware({\n *   target: 'http://localhost:3000',\n *   onError: (err, req, res) => {\n *     handleDevProxyError(err, req, res, {\n *       retryTimeout: 5000,\n *       retryInterval: 500,\n *     });\n *   }\n * });\n * ```\n */\nexport function handleDevProxyError(\n  err: Error,\n  req: IncomingMessage,\n  res: ServerResponse,\n  options?: ProxyErrorOptions\n): void {\n  const {\n    retryTimeout = 5000,\n    retryInterval = 500,\n    target = `http://localhost:${process.env.SERVER_PORT || 3000}`,\n  } = options || {};\n\n  console.error('[Proxy] Error:', err.message);\n\n  if (res.headersSent) {\n    console.error('[Proxy] Headers already sent, cannot handle error');\n    return;\n  }\n\n  // 非连接错误，直接返回 502\n  if (!isConnectionError(err)) {\n    console.log('[Proxy] Non-connection error, returning 502');\n    send502Json(res);\n    return;\n  }\n\n  // 连接错误，可能是服务热重载中，等待恢复\n  console.log('[Proxy] Connection error, waiting for service recovery...');\n\n  (async () => {\n    try {\n      const recovered = await waitForServiceRecovery(target, retryTimeout, retryInterval);\n\n      if (recovered) {\n        sendRedirect(req, res);\n      } else {\n        console.log('[Proxy] Service did not recover within timeout, returning 502');\n        send502Json(res);\n      }\n    } catch (error) {\n      console.error('[Proxy] Error during recovery wait:', error);\n      send502Json(res);\n    }\n  })();\n}\n","import path from 'node:path';\nimport type {\n  Middleware,\n  RouteMiddleware,\n  GlobalMiddleware,\n  MiddlewareContext,\n  ExpressApp,\n  ViteMiddleware,\n} from './types';\n\n/**\n * Enhance Request/Response objects with Express-compatible methods\n * This allows middleware written for Express to work with Vite/Connect\n */\nfunction enhanceForCompat(req: any, res: any): void {\n  // Enhance Response with Express-like methods\n  if (!res.status) {\n    res.status = function (code: number) {\n      res.statusCode = code;\n      return res;\n    };\n  }\n\n  if (!res.json) {\n    res.json = function (data: unknown) {\n      res.setHeader('Content-Type', 'application/json');\n      res.end(JSON.stringify(data));\n      return res;\n    };\n  }\n\n  if (!res.send) {\n    res.send = function (data: unknown) {\n      if (typeof data === 'object' && data !== null) {\n        res.setHeader('Content-Type', 'application/json');\n        res.end(JSON.stringify(data));\n      } else {\n        res.end(String(data));\n      }\n      return res;\n    };\n  }\n\n  // Enhance Request with parsed query\n  if (!req.query) {\n    const url = new URL(req.url || '', `http://${req.headers.host || 'localhost'}`);\n    req.query = Object.fromEntries(url.searchParams.entries());\n  }\n}\n\n/**\n * Detect if the server is a Connect/Vite middleware server (not Express)\n * Connect servers don't have Express-specific methods like 'set' or 'engine'\n */\nfunction isConnectServer(server: unknown): boolean {\n  return (\n    typeof server === 'function' &&\n    !('set' in (server as object)) &&\n    !('engine' in (server as object))\n  );\n}\n/**\n * Type guard to check if middleware is route-based\n */\nfunction isRouteMiddleware(middleware: Middleware): middleware is RouteMiddleware {\n  return 'createRouter' in middleware && middleware.createRouter !== undefined;\n}\n\n/**\n * Type guard to check if middleware is global\n */\nfunction isGlobalMiddleware(middleware: Middleware): middleware is GlobalMiddleware {\n  return 'createHandler' in middleware && middleware.createHandler !== undefined;\n}\n\n/**\n * Compute the full mount path by combining basePath and middleware mountPath\n */\nfunction computeMountPath(basePath: string, mountPath: string): string {\n  const routePath = path.posix.join(basePath, mountPath);\n  return routePath.startsWith('/') ? routePath : `/${routePath}`;\n}\n\n/**\n * Log middleware registration with routes info\n */\nfunction logMiddlewareRegistration(\n  middleware: RouteMiddleware,\n  fullMountPath: string,\n): void {\n  if (middleware.routes && middleware.routes.length > 0) {\n    console.log(`[Middleware] Registered: ${middleware.name} at ${fullMountPath}`);\n    middleware.routes.forEach((route) => {\n      const routePath = route.path === '/' ? fullMountPath : path.posix.join(fullMountPath, route.path);\n      console.log(`  ${route.method} ${routePath} - ${route.description}`);\n    });\n  } else {\n    console.log(`[Middleware] Registered: ${middleware.name} at ${fullMountPath}`);\n  }\n}\n\n// MUST stay synchronous. See note on `registerMiddlewares` below.\nfunction registerRouteMiddleware(\n  server: ExpressApp | ViteMiddleware,\n  middleware: RouteMiddleware,\n  context: MiddlewareContext,\n): void {\n  if (!middleware.mountPath) {\n    console.error(\n      `[Middleware] ${middleware.name}: Route middleware must have mountPath. Skipping.`\n    );\n    return;\n  }\n\n  const router = middleware.createRouter(context);\n  const fullMountPath = computeMountPath(context.basePath, middleware.mountPath);\n\n  server.use(fullMountPath, router);\n  logMiddlewareRegistration(middleware, fullMountPath);\n}\n\n// MUST stay synchronous. See note on `registerMiddlewares` below.\nfunction registerGlobalMiddleware(\n  server: ExpressApp | ViteMiddleware,\n  middleware: GlobalMiddleware,\n  context: MiddlewareContext,\n): void {\n  if (middleware.mountPath) {\n    console.warn(\n      `[Middleware] ${middleware.name}: Global middleware should not have mountPath. ` +\n      `Ignoring mountPath \"${middleware.mountPath}\".`\n    );\n  }\n\n  const handler = middleware.createHandler(context);\n  server.use(handler);\n  console.log(`[Middleware] Registered global: ${middleware.name}`);\n}\n\n/**\n * Register middlewares for Express-compatible servers or Vite.\n *\n * MUST stay synchronous (no async/await).\n *\n * Why: when called from webpack/rspack-dev-server's `setupMiddlewares` callback,\n * any `await` here yields a microtask, allowing dev-server to finish registering\n * its own built-ins (proxy, historyApiFallback, serveStatic, ...) BEFORE our\n * later iterations run. The first router lands before historyApiFallback while\n * subsequent routers land after — causing extensionless GETs (e.g. `/dev/openapi/spec`\n * with a wildcard Accept header) to be rewritten to `/index.html`. All registered work\n * (`server.use`, `createRouter`, `createHandler`) is sync, so async/await is also\n * unnecessary.\n *\n * @example\n * ```typescript\n * // In rspack/webpack setupMiddlewares\n * setupMiddlewares: (middlewares, devServer) => {\n *   if (devServer.app) {\n *     registerMiddlewares(devServer.app, [\n *       createDevLogsMiddleware({ logDir: './logs' }),\n *       createOpenapiMiddleware({ openapiFilePath: './openapi.json' })\n *     ], { basePath: '/api', isDev: true, rootDir: __dirname });\n *   }\n *   return middlewares;\n * }\n * ```\n */\nexport function registerMiddlewares(\n  server: ExpressApp | ViteMiddleware,\n  middlewares: Middleware[],\n  options?: Partial<MiddlewareContext>,\n): void {\n  // Build context with defaults\n  const context: MiddlewareContext = {\n    basePath: '/',\n    isDev: process.env.NODE_ENV !== 'production',\n    rootDir: process.cwd(),\n    ...options,\n  };\n\n  // If running in Connect/Vite environment, register compatibility middleware first\n  // This adds Express-like methods (res.status, res.json, req.query) to the request/response\n  if (isConnectServer(server)) {\n    server.use((req: any, res: any, next: any) => {\n      enhanceForCompat(req, res);\n      next();\n    });\n    console.log('[Middleware] Registered Express compatibility layer for Connect/Vite');\n  }\n\n  // 合并默认中间件和用户提供的中间件\n  const allMiddlewares = [...middlewares];\n\n  for (const middleware of allMiddlewares) {\n    // Check if middleware should be enabled\n    if (middleware.enabled && !middleware.enabled(context)) {\n      continue;\n    }\n\n    try {\n      // Check if both createRouter and createHandler are provided (type-unsafe case)\n      const hasCreateRouter = 'createRouter' in middleware && typeof (middleware as any).createRouter === 'function';\n      const hasCreateHandler = 'createHandler' in middleware && typeof (middleware as any).createHandler === 'function';\n\n      if (hasCreateRouter && hasCreateHandler) {\n        console.warn(\n          `[Middleware] ${middleware.name}: Both createRouter and createHandler provided. ` +\n          `Using createRouter and ignoring createHandler.`\n        );\n      }\n\n      if (isRouteMiddleware(middleware)) {\n        registerRouteMiddleware(server, middleware, context);\n      } else if (isGlobalMiddleware(middleware)) {\n        registerGlobalMiddleware(server, middleware, context);\n      } else {\n        // Type-unsafe middleware that has neither createRouter nor createHandler\n        console.error(\n          `[Middleware] ${(middleware as any).name || 'unknown'}: Must provide either createRouter or createHandler.`\n        );\n      }\n    } catch (error) {\n      console.error(`[Middleware] Failed to register ${middleware.name}:`, error);\n    }\n  }\n}\n\n// Re-export types and middleware creators\nexport type {\n  Middleware,\n  RouteMiddleware,\n  GlobalMiddleware,\n  MiddlewareContext,\n  RouteInfo,\n} from './types';\nexport { createOpenapiMiddleware, parseApiRoutes } from './openapi';\nexport { createDevLogsMiddleware } from './dev-logs';\nexport { createCollectLogsMiddleware } from './collect-logs';\n// Export compat utilities for controllers that want to explicitly use them\nexport { sendJson, sendError, sendSuccess, getQuery, getQueryParam } from './compat';\n","import express, { Router } from 'express';\nimport type { MiddlewareContext } from '../types';\nimport { createOpenapiHandler } from './controller';\nimport { createOpenapiSpecHandler } from './spec-controller';\n\n/**\n * Options for creating OpenAPI router\n */\nexport interface OpenapiRouterOptions {\n  /** Path to the openapi.json file */\n  openapiFilePath: string;\n  /** Path to the OpenAPI spec source file for /openapi/spec; when omitted, the route is not registered */\n  openapiSpecFilePath?: string;\n  /** Enable source code enhancement */\n  enableEnhancement: boolean;\n  /** Server directory for source code scanning */\n  serverDir?: string;\n}\n\n/**\n * Create OpenAPI router\n */\nexport function createOpenapiRouter(\n  options: OpenapiRouterOptions,\n  context: MiddlewareContext,\n): Router {\n  const { openapiFilePath, openapiSpecFilePath, enableEnhancement, serverDir } = options;\n  const router = express.Router();\n  const handler = createOpenapiHandler(openapiFilePath, enableEnhancement, serverDir);\n\n  // GET /openapi.json - Serve enhanced OpenAPI specification with x-source\n  router.get('/openapi.json', (req, res) => handler(req, res, context));\n\n  // GET /openapi/spec - Serve filtered OpenAPI spec for /openapi/* with refs resolved\n  if (openapiSpecFilePath) {\n    const specHandler = createOpenapiSpecHandler(openapiSpecFilePath);\n    router.get('/openapi/spec', (req, res) => specHandler(req, res, context));\n  }\n\n  return router;\n}\n","import fs from 'node:fs/promises';\nimport crypto from 'node:crypto';\n\nimport { enhanceOpenApiWithSourceInfo } from './services';\nimport { transformOpenapiPaths } from './utils';\n\nimport type { Request, Response } from 'express';\nimport type { OpenapiCache } from './types';\nimport type { MiddlewareContext } from '../types';\n\n/**\n * Create OpenAPI request handler with caching\n */\nexport function createOpenapiHandler(\n  openapiFilePath: string,\n  enableEnhancement: boolean,\n  serverDir?: string,\n) {\n  // In-memory cache\n  let cache: OpenapiCache | null = null;\n\n  return async (_req: Request, res: Response, context: MiddlewareContext) => {\n    try {\n      // Read OpenAPI file\n      const fileBuffer = await fs.readFile(openapiFilePath, 'utf-8');\n\n      // Calculate file hash for cache invalidation\n      const currentHash = crypto.createHash('md5').update(fileBuffer).digest('hex');\n\n      // Use cache if file content hasn't changed\n      if (cache && cache.fileHash === currentHash) {\n        return res.json(cache.data);\n      }\n\n      // Parse OpenAPI\n      let payload = JSON.parse(fileBuffer);\n\n      // Enhance with x-source if enabled\n      if (enableEnhancement && context.isDev) {\n        const { openapi: enhancedPayload, stats } = await enhanceOpenApiWithSourceInfo({\n          openapiData: payload,\n          writeFile: false, // Don't write to file, keep in memory\n          serverDir: serverDir || context.rootDir, // Use provided serverDir or fallback to context.rootDir\n        });\n        payload = enhancedPayload;\n\n        // Log performance\n        console.log(`[OpenAPI] Enhanced in ${stats.duration}ms (${stats.endpointsEnhanced} endpoints)`);\n      }\n\n      // Transform paths: remove basePath prefix from all API paths\n      const result = transformOpenapiPaths(payload, context.basePath);\n\n      // Update cache\n      cache = {\n        data: result,\n        fileHash: currentHash,\n      };\n\n      res.json(result);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : 'Unknown error';\n      res.status(500).json({\n        error: 'Failed to load OpenAPI spec',\n        message,\n      });\n    }\n  };\n}\n","import { promises as fs } from 'node:fs';\nimport * as fsSync from 'node:fs';\nimport path from 'node:path';\nimport ts from 'typescript';\nimport type { SourceInfo, EnhanceOptions, EnhanceResult } from './types';\nimport { findControllerFiles, buildSourceMap, enhanceOpenApiPaths } from './utils';\n\n/**\n * Enhances OpenAPI JSON with source file location metadata\n * Can be called programmatically or run as a script\n */\nexport async function enhanceOpenApiWithSourceInfo(options: EnhanceOptions = {}): Promise<EnhanceResult> {\n  const startTime = Date.now();\n\n  const openapiPath = options.openapiPath || path.resolve(__dirname, '../client/src/api/gen/openapi.json');\n  const serverDir = options.serverDir || path.resolve(__dirname, '../server');\n  const writeFile = options.writeFile !== false;\n\n  let openapi: any;\n  if (options.openapiData) {\n    // Use provided data (for in-memory enhancement)\n    openapi = JSON.parse(JSON.stringify(options.openapiData)); // Deep clone\n  } else {\n    // Read from file\n    const openapiContent = await fs.readFile(openapiPath, 'utf-8');\n    openapi = JSON.parse(openapiContent);\n  }\n\n  const controllerFiles = await findControllerFiles(serverDir);\n  const sourceMap = await buildSourceMap(controllerFiles, processControllerFile);\n  const enhanced = enhanceOpenApiPaths(openapi, sourceMap);\n\n  if (writeFile) {\n    await fs.writeFile(openapiPath, JSON.stringify(openapi, null, 2) + '\\n', 'utf-8');\n  }\n\n  const duration = Date.now() - startTime;\n\n  return {\n    openapi,\n    stats: {\n      duration,\n      controllersFound: controllerFiles.length,\n      endpointsExtracted: sourceMap.size,\n      endpointsEnhanced: enhanced,\n    },\n  };\n}\n\n/**\n * Process a single controller file\n */\nasync function processControllerFile(filePath: string): Promise<Map<string, SourceInfo>> {\n  const relativePath = path.relative(process.cwd(), filePath);\n\n  // Parse file\n  const content = await fs.readFile(filePath, 'utf-8');\n  const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n  return extractControllerMetadata(sourceFile, relativePath);\n}\n\n/**\n * Extract controller metadata from TypeScript source file\n */\nfunction extractControllerMetadata(sourceFile: ts.SourceFile, filePath: string): Map<string, SourceInfo> {\n  const metadata = new Map<string, SourceInfo>();\n  let controllerPath = '';\n  let className = '';\n\n  // Helper function to get decorators from both old and new TypeScript APIs\n  function getDecorators(node: ts.Node): readonly ts.Decorator[] {\n    // TypeScript 5.x: decorators are in modifiers array\n    if ('modifiers' in node && Array.isArray(node.modifiers)) {\n      return (node.modifiers as ts.ModifierLike[]).filter(\n        (mod): mod is ts.Decorator => mod.kind === ts.SyntaxKind.Decorator,\n      );\n    }\n    // TypeScript 4.x: decorators are in decorators array\n    if ('decorators' in node && Array.isArray(node.decorators)) {\n      return node.decorators as readonly ts.Decorator[];\n    }\n    return [];\n  }\n\n  function visit(node: ts.Node): void {\n    // Extract @Controller decorator and its path\n    if (ts.isClassDeclaration(node)) {\n      const decorators = getDecorators(node);\n\n      // Extract class name\n      if (node.name) {\n        className = node.name.getText(sourceFile);\n      }\n\n      for (const decorator of decorators) {\n        if (ts.isCallExpression(decorator.expression)) {\n          const expression = decorator.expression;\n          const decoratorName = expression.expression.getText(sourceFile);\n\n          if (decoratorName === 'Controller') {\n            if (expression.arguments.length > 0) {\n              const arg = expression.arguments[0];\n              if (ts.isStringLiteral(arg)) {\n                controllerPath = arg.text;\n              }\n            }\n          }\n        }\n      }\n    }\n\n    // Extract methods with HTTP decorators\n    if (ts.isMethodDeclaration(node) && node.name) {\n      const methodName = node.name.getText(sourceFile);\n      let httpMethod = '';\n      let routePath = '';\n      const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));\n\n      const decorators = getDecorators(node);\n\n      for (const decorator of decorators) {\n        if (ts.isCallExpression(decorator.expression)) {\n          const decoratorName = decorator.expression.expression.getText(sourceFile);\n          if (['Get', 'Post', 'Put', 'Delete', 'Patch', 'Options', 'Head', 'All'].includes(decoratorName)) {\n            httpMethod = decoratorName.toLowerCase();\n            if (decorator.expression.arguments.length > 0) {\n              const arg = decorator.expression.arguments[0];\n              if (ts.isStringLiteral(arg)) {\n                routePath = arg.text;\n              }\n            }\n          }\n        }\n      }\n\n      if (httpMethod && methodName && className) {\n        const operationId = `${className}_${methodName}`;\n        metadata.set(operationId, {\n          file: filePath,\n          line: line + 1,\n          method: httpMethod,\n          controllerPath,\n          routePath,\n        });\n      }\n    }\n\n    ts.forEachChild(node, visit);\n  }\n\n  visit(sourceFile);\n  return metadata;\n}\n\n// --- API Route Parsing (synchronous, for build-time injection) ---\n\nconst HTTP_DECORATOR_NAMES = ['Get', 'Post', 'Put', 'Delete', 'Patch', 'Options', 'Head', 'All'];\n\nfunction findControllerFilesSync(dir: string): string[] {\n  const files: string[] = [];\n  function scan(currentDir: string): void {\n    let entries: fsSync.Dirent[];\n    try {\n      entries = fsSync.readdirSync(currentDir, { withFileTypes: true });\n    } catch {\n      return;\n    }\n    for (const entry of entries) {\n      const fullPath = path.join(currentDir, entry.name);\n      if (entry.isDirectory()) {\n        scan(fullPath);\n      } else if (entry.isFile() && entry.name.endsWith('.controller.ts')) {\n        files.push(fullPath);\n      }\n    }\n  }\n  scan(dir);\n  return files;\n}\n\nfunction normalizeApiPath(controllerPath: string, routePath: string): string {\n  const combined = routePath ? `${controllerPath}/${routePath}` : controllerPath;\n  let normalized = combined.replace(/\\/+/g, '/');\n  if (!normalized.startsWith('/')) normalized = `/${normalized}`;\n  if (normalized.length > 1 && normalized.endsWith('/')) normalized = normalized.slice(0, -1);\n  return normalized;\n}\n\nfunction parseControllerRoutes(filePath: string): Array<{ method: string; path: string }> {\n  let content: string;\n  try {\n    content = fsSync.readFileSync(filePath, 'utf-8');\n  } catch {\n    return [];\n  }\n\n  const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n  const routes: Array<{ method: string; path: string }> = [];\n\n  function getDecoratorsCompat(node: ts.Node): readonly ts.Decorator[] {\n    if ('modifiers' in node && Array.isArray(node.modifiers)) {\n      return (node.modifiers as ts.ModifierLike[]).filter(\n        (mod): mod is ts.Decorator => mod.kind === ts.SyntaxKind.Decorator,\n      );\n    }\n    if ('decorators' in node && Array.isArray(node.decorators)) {\n      return node.decorators as readonly ts.Decorator[];\n    }\n    return [];\n  }\n\n  function getStringArg(expr: ts.CallExpression): string {\n    if (expr.arguments.length > 0 && ts.isStringLiteral(expr.arguments[0])) {\n      return expr.arguments[0].text;\n    }\n    return '';\n  }\n\n  function visit(node: ts.Node): void {\n    if (ts.isClassDeclaration(node)) {\n      let controllerPath = '';\n      for (const dec of getDecoratorsCompat(node)) {\n        if (ts.isCallExpression(dec.expression)) {\n          const name = dec.expression.expression.getText(sourceFile);\n          if (name === 'Controller') {\n            controllerPath = getStringArg(dec.expression);\n            break;\n          }\n        }\n      }\n\n      for (const member of node.members) {\n        if (!ts.isMethodDeclaration(member)) continue;\n        for (const dec of getDecoratorsCompat(member)) {\n          if (!ts.isCallExpression(dec.expression)) continue;\n          const decoratorName = dec.expression.expression.getText(sourceFile);\n          if (!HTTP_DECORATOR_NAMES.includes(decoratorName)) continue;\n\n          const routePath = getStringArg(dec.expression);\n          const fullPath = normalizeApiPath(controllerPath, routePath);\n          const method = decoratorName === 'All' ? '*' : decoratorName.toUpperCase();\n          routes.push({ method, path: fullPath });\n        }\n      }\n    }\n    ts.forEachChild(node, visit);\n  }\n\n  visit(sourceFile);\n  return routes;\n}\n\n/**\n * Scan serverDir for NestJS controller files and extract all parameterized API routes.\n * Synchronous — safe to call at preset config time (before bundling).\n */\nexport function parseApiRoutes(serverDir: string): Array<{ method: string; path: string }> {\n  const resolvedDir = path.resolve(serverDir);\n  const controllerFiles = findControllerFilesSync(resolvedDir);\n  const routes: Array<{ method: string; path: string }> = [];\n  for (const filePath of controllerFiles) {\n    routes.push(...parseControllerRoutes(filePath));\n  }\n  return routes;\n}\n","import path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport type { SourceInfo } from './types';\n\n/**\n * Find all controller files in a directory\n */\nexport async function findControllerFiles(dir: string): Promise<string[]> {\n  const files: string[] = [];\n\n  async function scan(currentDir: string): Promise<void> {\n    const entries = await fs.readdir(currentDir, { withFileTypes: true });\n\n    for (const entry of entries) {\n      const fullPath = path.join(currentDir, entry.name);\n\n      if (entry.isDirectory()) {\n        await scan(fullPath);\n      } else if (entry.isFile() && entry.name.endsWith('.controller.ts')) {\n        files.push(fullPath);\n      }\n    }\n  }\n\n  await scan(dir);\n  return files;\n}\n\n/**\n * Build source map from controller files\n */\nexport async function buildSourceMap(\n  controllerFiles: string[],\n  processFile: (filePath: string) => Promise<Map<string, SourceInfo>>,\n): Promise<Map<string, SourceInfo>> {\n  const sourceMap = new Map<string, SourceInfo>();\n\n  // Process files in parallel with a concurrency limit\n  const concurrency = 10;\n  const results: Map<string, SourceInfo>[] = [];\n\n  for (let i = 0; i < controllerFiles.length; i += concurrency) {\n    const batch = controllerFiles.slice(i, i + concurrency);\n    const batchResults = await Promise.all(batch.map((filePath) => processFile(filePath)));\n    results.push(...batchResults);\n  }\n\n  // Merge results\n  for (const metadata of results) {\n    for (const [operationId, info] of metadata.entries()) {\n      sourceMap.set(operationId, info);\n    }\n  }\n\n  return sourceMap;\n}\n\n/**\n * Try to match operationId with different formats\n * Supports:\n * - Direct match: ClassName_methodName\n * - Camel case: classNameMethodName\n * - Method only: methodName\n */\nfunction findSourceInfo(operationId: string, sourceMap: Map<string, SourceInfo>): SourceInfo | undefined {\n  // Try direct match first\n  const directMatch = sourceMap.get(operationId);\n  if (directMatch) {\n    return directMatch;\n  }\n\n  // Try matching with different formats\n  for (const [key, value] of sourceMap.entries()) {\n    // key format: ClassName_methodName\n    const [className, methodName] = key.split('_');\n    if (!className || !methodName) continue;\n\n    // Try camelCase format: classNameMethodName\n    const camelCaseId = className.charAt(0).toLowerCase() + className.slice(1) + methodName.charAt(0).toUpperCase() + methodName.slice(1);\n    if (operationId === camelCaseId) {\n      return value;\n    }\n\n    // Try method name only\n    if (operationId === methodName) {\n      return value;\n    }\n  }\n\n  return undefined;\n}\n\n/**\n * Enhance OpenAPI paths with source information\n */\nexport function enhanceOpenApiPaths(openapi: any, sourceMap: Map<string, SourceInfo>): number {\n  let enhancedCount = 0;\n\n  if (!openapi.paths) {\n    return enhancedCount;\n  }\n\n  for (const pathItem of Object.values(openapi.paths)) {\n    if (!pathItem || typeof pathItem !== 'object') continue;\n\n    for (const operation of Object.values(pathItem)) {\n      if (operation && typeof operation === 'object' && 'operationId' in operation) {\n        const sourceInfo = findSourceInfo(operation.operationId as string, sourceMap);\n        if (sourceInfo) {\n          operation['x-source'] = {\n            file: sourceInfo.file,\n            line: sourceInfo.line,\n          };\n          enhancedCount++;\n        }\n      }\n    }\n  }\n\n  return enhancedCount;\n}\n\n/**\n * Transform OpenAPI paths by removing basePath prefix\n */\nexport function transformOpenapiPaths(openapi: any, basePath: string): any {\n  if (basePath === '/' || !openapi.paths) {\n    return openapi;\n  }\n\n  const newPaths: any = {};\n  Object.keys(openapi.paths).forEach((key) => {\n    const staticApiKey = key.startsWith(basePath) ? key.slice(basePath.length) : key;\n    newPaths[staticApiKey] = openapi.paths[key];\n  });\n\n  return {\n    ...openapi,\n    paths: newPaths,\n    basePath,\n  };\n}\n","import fs from 'node:fs/promises';\nimport crypto from 'node:crypto';\n\nimport type { Request, Response } from 'express';\nimport type { OpenapiCache } from './types';\nimport type { MiddlewareContext } from '../types';\n\nconst MAX_REF_DEPTH = 5;\n\nconst EMPTY_OPENAPI_SPEC = {\n  openapi: '3.0.0',\n  info: { title: '开放 API', version: '0.0.0' },\n  paths: {},\n  components: { schemas: {} },\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnySpec = Record<string, any>;\n\nexport function createOpenapiSpecHandler(openapiSpecFilePath: string) {\n  let cache: OpenapiCache | null = null;\n\n  return async (_req: Request, res: Response, context: MiddlewareContext) => {\n    try {\n      let fileBuffer: string;\n      try {\n        fileBuffer = await fs.readFile(openapiSpecFilePath, 'utf-8');\n      } catch (err) {\n        if ((err as NodeJS.ErrnoException)?.code === 'ENOENT') {\n          return res.json(EMPTY_OPENAPI_SPEC);\n        }\n        throw err;\n      }\n      const currentHash = crypto.createHash('md5').update(fileBuffer).digest('hex');\n\n      if (cache && cache.fileHash === currentHash) {\n        return res.json(cache.data);\n      }\n\n      let parsed: AnySpec;\n      try {\n        parsed = JSON.parse(fileBuffer);\n      } catch (err) {\n        const message = err instanceof Error ? err.message : 'Invalid JSON';\n        return res.status(500).json({\n          error: 'Failed to load OpenAPI spec',\n          message: `${openapiSpecFilePath} invalid: ${message}`,\n        });\n      }\n\n      if (!parsed || typeof parsed !== 'object' || !parsed.paths || typeof parsed.paths !== 'object') {\n        return res.status(500).json({\n          error: 'Failed to load OpenAPI spec',\n          message: `${openapiSpecFilePath} missing \"paths\"`,\n        });\n      }\n\n      const result = buildFilteredSpec(parsed, context.basePath ?? '');\n\n      cache = {\n        data: result,\n        fileHash: currentHash,\n      };\n\n      res.json(result);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : 'Unknown error';\n      res.status(500).json({\n        error: 'Failed to load OpenAPI spec',\n        message,\n      });\n    }\n  };\n}\n\nfunction buildFilteredSpec(spec: AnySpec, globalPrefix: string) {\n  const schemas = (spec.components?.schemas ?? {}) as Record<string, unknown>;\n  const paths = (spec.paths ?? {}) as Record<string, AnySpec>;\n  const filteredPaths: Record<string, Record<string, unknown>> = {};\n\n  const cleanPrefix = globalPrefix.replace(/\\/+$/, '');\n\n  for (const [pathKey, methods] of Object.entries(paths)) {\n    const cleanPath = stripPrefix(pathKey, cleanPrefix);\n    if (!cleanPath.startsWith('/openapi')) continue;\n\n    filteredPaths[cleanPath] = {};\n\n    for (const [method, operation] of Object.entries(methods as Record<string, unknown>)) {\n      if (['parameters', 'summary', 'description', 'servers'].includes(method)) continue;\n      filteredPaths[cleanPath][method] = resolveRefsDeep(structuredClone(operation), schemas);\n    }\n  }\n\n  return {\n    openapi: spec.openapi ?? '3.0.0',\n    paths: filteredPaths,\n    components: {\n      schemas: resolveAllSchemaRefs(structuredClone(schemas)),\n    },\n  };\n}\n\nfunction stripPrefix(pathStr: string, prefix: string): string {\n  if (prefix && pathStr.startsWith(prefix)) {\n    return pathStr.slice(prefix.length);\n  }\n  return pathStr;\n}\n\nfunction resolveRefsDeep(\n  obj: unknown,\n  schemas: Record<string, unknown>,\n  depth = 0,\n): unknown {\n  if (depth > MAX_REF_DEPTH || obj === null || obj === undefined) return obj;\n  if (typeof obj !== 'object') return obj;\n\n  if (Array.isArray(obj)) {\n    return obj.map((item) => resolveRefsDeep(item, schemas, depth));\n  }\n\n  const record = obj as Record<string, unknown>;\n\n  if (typeof record['$ref'] === 'string') {\n    const resolved = resolveRef(record['$ref'] as string, schemas);\n    if (resolved !== undefined) {\n      return resolveRefsDeep(structuredClone(resolved), schemas, depth + 1);\n    }\n    return record;\n  }\n\n  const result: Record<string, unknown> = {};\n  for (const [key, value] of Object.entries(record)) {\n    result[key] = resolveRefsDeep(value, schemas, depth);\n  }\n  return result;\n}\n\nfunction resolveRef(ref: string, schemas: Record<string, unknown>): unknown {\n  const prefix = '#/components/schemas/';\n  if (ref.startsWith(prefix)) {\n    const name = ref.slice(prefix.length);\n    return schemas[name];\n  }\n  return undefined;\n}\n\nfunction resolveAllSchemaRefs(\n  schemas: Record<string, unknown>,\n): Record<string, unknown> {\n  const result: Record<string, unknown> = {};\n  for (const [name, schema] of Object.entries(schemas)) {\n    result[name] = resolveRefsDeep(schema, schemas);\n  }\n  return result;\n}\n","import type { RouteMiddleware, MiddlewareContext, RouteInfo } from '../types';\nimport type { OpenapiMiddlewareOptions } from './types';\nimport { createOpenapiRouter } from './router';\n\n/**\n * Routes provided by OpenAPI middleware\n */\nconst OPENAPI_ROUTES: RouteInfo[] = [\n  {\n    method: 'GET',\n    path: '/openapi.json',\n    description: 'Serve enhanced OpenAPI specification with source code references',\n  },\n  {\n    method: 'GET',\n    path: '/openapi/spec',\n    description: 'Serve OpenAPI specification for /openapi/*',\n  },\n];\n\n/**\n * Creates OpenAPI middleware that serves enhanced openapi.json\n * Supports both rspack/webpack and Vite dev servers\n */\nexport function createOpenapiMiddleware(options: OpenapiMiddlewareOptions): RouteMiddleware {\n  const { openapiFilePath, openapiSpecFilePath, enableEnhancement = true, serverDir } = options;\n\n  const routes = openapiSpecFilePath\n    ? OPENAPI_ROUTES\n    : OPENAPI_ROUTES.filter((route) => route.path !== '/openapi/spec');\n\n  return {\n    name: 'openapi',\n    mountPath: '/dev',\n    routes,\n\n    enabled: (context: MiddlewareContext) => context.isDev,\n\n    createRouter: (context: MiddlewareContext) => {\n      return createOpenapiRouter(\n        {\n          openapiFilePath,\n          openapiSpecFilePath,\n          enableEnhancement,\n          serverDir,\n        },\n        context,\n      );\n    },\n  };\n}\n\n// Re-export types and utilities\nexport type { OpenapiMiddlewareOptions, SourceInfo, EnhanceOptions, EnhanceResult } from './types';\nexport { enhanceOpenApiWithSourceInfo, parseApiRoutes } from './services';\n","import express, { Router } from 'express';\nimport type { RouterOptions } from './types';\nimport { resolveLogDir } from './utils';\nimport {\n  createGetTraceEntriesHandler,\n  createGetRecentTracesHandler,\n  createGetLogFileHandler,\n  createGetServerLogsHandler,\n  createGetTriggerListHandler,\n  createGetTriggerDetailHandler,\n  createGetCapabilityTraceListHandler,\n} from './controller';\nimport { createHealthCheckHandler } from './health.controller';\nimport { createSSEHandler } from './sse';\nimport { createApiListHandler } from './api-list-handler';\n/**\n * Create dev log router with all routes registered\n */\nexport function createDevLogRouter(options: RouterOptions = {}): Router {\n  const logDir = resolveLogDir(options.logDir);\n  const router = express.Router();\n\n  // GET /app/trace/:traceId - Get log entries by trace ID\n  router.get('/app/trace/:traceId', createGetTraceEntriesHandler(logDir));\n\n  // GET /trace/recent - Get recent trace calls with pagination\n  router.get('/trace/recent', createGetRecentTracesHandler(logDir));\n\n  // GET /files/:fileName - Get paginated log file content\n  router.get('/files/:fileName', createGetLogFileHandler(logDir));\n\n  // GET /server-logs - Get server logs in ServerLog format (compatible with frontend)\n  router.get('/server-logs', createGetServerLogsHandler(logDir));\n\n  // GET /server-logs/stream - SSE endpoint for real-time server logs\n  router.get('/server-logs/stream', createSSEHandler(logDir));\n  \n  // GET /trace/trigger/list - get all automation trigger list in trace.log\n  router.get('/trace/trigger/list', createGetTriggerListHandler(logDir));\n\n  // GET /trace/trigger/:instanceID - get automation trigger detail by instanceID in server.log\n  router.get('/trace/trigger/:instanceID', createGetTriggerDetailHandler(logDir));\n\n  // GET /trace/capability/list - get capability trace list by capability_id in server.log\n  router.get('/trace/capability/list', createGetCapabilityTraceListHandler(logDir));\n\n  router.get('/health', createHealthCheckHandler());\n\n  // GET /api-list - 获取所有 API 路由（从 api-routes 迁移过来）\n  router.get('/api-list', createApiListHandler());\n\n  return router;\n}\n","import { promises as fs } from 'node:fs';\nimport { isAbsolute, join, relative } from 'node:path';\nimport type { LogEntry } from './types';\nimport { matchesPathPattern } from './helper/path-matcher';\n\n/**\n * Resolve log directory path\n */\nexport function resolveLogDir(provided?: string): string {\n  if (!provided) {\n    return join(process.cwd(), 'logs');\n  }\n  return isAbsolute(provided) ? provided : join(process.cwd(), provided);\n}\n\n/**\n * Get relative path from current working directory\n */\nexport function getRelativePath(filePath: string): string {\n  return relative(process.cwd(), filePath);\n}\n\n/**\n * Check if file exists\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n  try {\n    await fs.access(filePath);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Parse a log line as JSON\n */\nexport function parseLogLine(line: string): LogEntry | undefined {\n  const trimmed = line.trim();\n  if (!trimmed) return undefined;\n\n  try {\n    return JSON.parse(trimmed) as LogEntry;\n  } catch {\n    return undefined;\n  }\n}\n\n/**\n * Extract number from message using regex pattern\n */\nexport function extractNumber(message: string, pattern: RegExp): number | undefined {\n  if (typeof message !== 'string') return undefined;\n\n  const match = message.match(pattern);\n  if (!match) return undefined;\n\n  const value = Number(match[1]);\n  return Number.isFinite(value) ? value : undefined;\n}\n\n/**\n * Parse limit parameter with default and max value\n */\nexport function parseLimit(value: string | undefined, defaultValue: number, maxValue: number): number {\n  if (typeof value !== 'string' || !value.trim()) {\n    return defaultValue;\n  }\n\n  const parsed = Number(value);\n  if (Number.isFinite(parsed) && parsed > 0) {\n    return Math.min(Math.floor(parsed), maxValue);\n  }\n\n  return defaultValue;\n}\n\n/**\n * Parse positive integer with fallback\n */\nexport function parsePositiveInt(value: string | undefined, fallback: number): number {\n  if (typeof value !== 'string' || !value.trim()) {\n    return fallback;\n  }\n\n  const parsed = Number(value);\n  return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;\n}\n\n/**\n * Resolve log file path with security checks\n */\nexport function resolveLogFilePath(baseDir: string, fileName: string): string {\n  const sanitized = fileName.replace(/\\\\/g, '/');\n  const segments = sanitized.split('/').filter(Boolean);\n\n  if (segments.some((segment) => segment === '..')) {\n    throw new Error('Invalid log file path');\n  }\n\n  const resolved = join(baseDir, segments.join('/'));\n  const rel = relative(baseDir, resolved);\n\n  if (rel.startsWith('..')) {\n    throw new Error('Access to the specified log file is denied');\n  }\n\n  return resolved;\n}\n\n/**\n * Check if actual request path matches expected OpenAPI/Swagger path pattern\n *\n * @param actualPath - The actual request path from logs (e.g., /api/users/123)\n * @param pattern - The OpenAPI path pattern to match against (e.g., /api/users/{id})\n * @returns true if the path matches the pattern\n *\n * @example\n * matchesPath('/api/users/123', '/api/users/{id}') // true\n * matchesPath('/api/users/123', '/api/users') // true (prefix match)\n * matchesPath('/api/posts/456', '/api/users/{id}') // false\n */\nexport function matchesPath(actualPath: string | undefined, pattern: string): boolean {\n  return matchesPathPattern(actualPath, pattern);\n}\n\n/**\n * Check if actual request method matches expected HTTP method\n *\n * @param actualMethod - The actual request method from logs (e.g., 'GET', 'POST')\n * @param expectedMethod - The expected HTTP method to match against (e.g., 'GET')\n * @returns true if the method matches (case-insensitive)\n *\n * @example\n * matchesMethod('GET', 'GET') // true\n * matchesMethod('get', 'GET') // true\n * matchesMethod('POST', 'GET') // false\n * matchesMethod(undefined, 'GET') // false\n */\nexport function matchesMethod(actualMethod: string | undefined, expectedMethod: string): boolean {\n  if (!actualMethod || !expectedMethod) {\n    return false;\n  }\n  return actualMethod.toUpperCase() === expectedMethod.toUpperCase();\n}\n\n\n/**\n * Serialize error for JSON response\n */\nexport function serializeError(error: unknown): { name?: string; message: string } {\n  return error instanceof Error\n    ? { name: error.name, message: error.message }\n    : { message: String(error) };\n}\n","/**\n * Path matcher utility for matching request paths against OpenAPI/Swagger/NestJS path patterns\n *\n * Note: Input paths should be clean request paths without query strings or hash fragments\n *\n * Supports:\n * - Exact matching: /api/users === /api/users (only)\n * - Path parameters: /api/users/{id} matches /api/users/123\n * - Nested parameters: /api/users/{userId}/posts/{postId}\n * - Wildcard (asterisk): /api/star/users matches /api/v1/users (use * for single segment)\n * - Recursive wildcard: /files/star-star matches /files/a/b/c (use two asterisks for multiple segments)\n *\n * Note: Prefix matching has been removed. Use slash-two-asterisks for matching sub-paths:\n * - /api/users - matches /api/users only\n * - /api/users/two-asterisks - matches /api/users, /api/users/123, /api/users/123/posts, etc.\n */\n\n/**\n * Convert path pattern to regex, supporting wildcards and path parameters\n *\n * Examples:\n *   /api/users/{id} -> /^\\/api\\/users\\/[^/]+$/\n *   /api/star/users -> /^\\/api\\/[^/]+\\/users$/\n *   /files/double-star -> /^\\/files\\/.+$/\n *   /api/v{version}/users -> /^\\/api\\/v[^/]+\\/users$/\n */\nfunction pathPatternToRegex(pattern: string): RegExp {\n  // Escape special regex characters except {}, *, /\n  let regexPattern = pattern.replace(/[.+?^$|()[\\]\\\\]/g, '\\\\$&');\n\n  // Handle recursive wildcard /** (must be at the end or followed by /)\n  // /files/** -> /files/.+ (matches one or more path segments)\n  // This follows NestJS routing convention where ** requires at least one segment\n  regexPattern = regexPattern.replace(/\\/\\*\\*$/, '/.+');\n  regexPattern = regexPattern.replace(/\\/\\*\\*\\//g, '/(?:.+/)?');\n\n  // Handle single wildcard * (matches exactly one path segment)\n  // /api/*/users -> /api/[^/]+/users\n  regexPattern = regexPattern.replace(/\\*/g, '[^/]+');\n\n  // Replace path parameters {param} with regex group that matches anything except /\n  regexPattern = regexPattern.replace(/\\{[^}]+\\}/g, '[^/]+');\n\n  // Anchor to start and end\n  return new RegExp(`^${regexPattern}$`);\n}\n\n/**\n * Check if an actual path matches an OpenAPI/Swagger/NestJS path pattern\n *\n * @param actualPath - The actual request path (e.g., /api/users/123)\n * @param pattern - The path pattern (e.g., /api/users/{id})\n * @returns true if the actual path matches the pattern\n *\n * @example\n * // Exact match\n * matchesPathPattern('/api/users', '/api/users') // true\n * matchesPathPattern('/api/users/123', '/api/users') // false\n *\n * // Path parameters\n * matchesPathPattern('/api/users/123', '/api/users/{id}') // true\n *\n * // Wildcards\n * matchesPathPattern('/api/v1/users', '/api/star/users') // true (use * not star)\n * matchesPathPattern('/api/v2/users', '/api/star/users') // true\n *\n * // Recursive wildcards (use two asterisks, not /**!)\n * matchesPathPattern('/files/a/b/c', '/files/starstar') // true (use ** not starstar)\n * matchesPathPattern('/files/x', '/files/starstar') // true\n */\nexport function matchesPathPattern(actualPath: string | undefined, pattern: string): boolean {\n  if (!actualPath || !pattern) {\n    return false;\n  }\n\n  // Normalize paths: remove trailing slashes and query strings\n  const normalizedActual = normalizePathForMatching(actualPath);\n  const normalizedPattern = normalizePathForMatching(pattern);\n\n  // Exact match (no parameters or wildcards)\n  if (normalizedActual === normalizedPattern) {\n    return true;\n  }\n\n  // Check if pattern contains special characters (parameters, wildcards)\n  if (hasSpecialPatterns(normalizedPattern)) {\n    const regex = pathPatternToRegex(normalizedPattern);\n    return regex.test(normalizedActual);\n  }\n\n  // No match - exact paths that are different\n  return false;\n}\n\n/**\n * Extract path parameters from actual path using pattern\n *\n * Note: This only extracts named parameters {param}, not wildcards\n *\n * @param actualPath - The actual request path\n * @param pattern - The path pattern with parameters\n * @returns Object with parameter names and values, or null if no match\n *\n * @example\n * extractPathParams('/api/users/123', '/api/users/{id}')\n * // { id: '123' }\n *\n * extractPathParams('/api/users/123/posts/456', '/api/users/{userId}/posts/{postId}')\n * // { userId: '123', postId: '456' }\n *\n * // Wildcards are not captured (use asterisk)\n * extractPathParams('/api/v1/users/123', '/api/asterisk/users/{id}')\n * // { id: '123' }\n */\nexport function extractPathParams(\n  actualPath: string,\n  pattern: string,\n): Record<string, string> | null {\n  const normalizedActual = normalizePathForMatching(actualPath);\n  const normalizedPattern = normalizePathForMatching(pattern);\n\n  // Extract parameter names from pattern (only {param} style)\n  const paramNames: string[] = [];\n  const paramRegex = /\\{([^}]+)\\}/g;\n  let match: RegExpExecArray | null;\n\n  while ((match = paramRegex.exec(normalizedPattern)) !== null) {\n    paramNames.push(match[1]);\n  }\n\n  if (paramNames.length === 0) {\n    // No named parameters in pattern\n    return normalizedActual === normalizedPattern ? {} : null;\n  }\n\n  // Build regex with capturing groups for named parameters\n  let regexPattern = normalizedPattern.replace(/[.+?^$|()[\\]\\\\]/g, '\\\\$&');\n\n  // Replace wildcards with non-capturing groups\n  regexPattern = regexPattern.replace(/\\/\\*\\*$/, '/.+');\n  regexPattern = regexPattern.replace(/\\/\\*\\*\\//g, '/(?:.+/)?');\n  regexPattern = regexPattern.replace(/\\*/g, '[^/]+');\n\n  // Replace named parameters with capturing groups\n  regexPattern = regexPattern.replace(/\\{[^}]+\\}/g, '([^/]+)');\n\n  const regex = new RegExp(`^${regexPattern}$`);\n\n  const result = regex.exec(normalizedActual);\n  if (!result) {\n    return null;\n  }\n\n  // Map parameter names to captured values\n  const params: Record<string, string> = {};\n  paramNames.forEach((name, index) => {\n    params[name] = result[index + 1]; // index + 1 because result[0] is the full match\n  });\n\n  return params;\n}\n\n/**\n * Check if a pattern contains special matching characters\n *\n * @param pattern - The path pattern to check\n * @returns true if the pattern contains parameters, wildcards, etc.\n *\n * @example\n * hasSpecialPatterns('/api/users/{id}') // true\n * hasSpecialPatterns('/api/asterisk/users') // true (with actual asterisk character)\n * hasSpecialPatterns('/files/double-asterisk') // true (with actual double asterisk)\n * hasSpecialPatterns('/api/users') // false\n */\nexport function hasSpecialPatterns(pattern: string): boolean {\n  return /[{*]/.test(pattern);\n}\n\n/**\n * Check if a pattern contains path parameters (not wildcards)\n *\n * @param pattern - The path pattern to check\n * @returns true if the pattern contains {param} style parameters\n *\n * @example\n * hasPathParameters('/api/users/{id}') // true\n * hasPathParameters('/api/asterisk/users') // false (with actual asterisk character)\n * hasPathParameters('/api/users') // false\n */\nexport function hasPathParameters(pattern: string): boolean {\n  return /\\{[^}]+\\}/.test(pattern);\n}\n\n/**\n * Check if a pattern contains wildcards\n *\n * @param pattern - The path pattern to check\n * @returns true if the pattern contains asterisk or double asterisk\n *\n * @example\n * hasWildcards('/api/asterisk/users') // true (with actual asterisk character)\n * hasWildcards('/files/double-asterisk') // true (with actual double asterisk)\n * hasWildcards('/api/users/{id}') // false\n */\nexport function hasWildcards(pattern: string): boolean {\n  return pattern.includes('*');\n}\n\n/**\n * Normalize a path for matching by:\n * - Removing trailing slashes\n * - Removing duplicate slashes\n *\n * @param path - The path to normalize\n * @returns Normalized path\n *\n * @example\n * normalizePathForMatching('/api/users/') // '/api/users'\n * normalizePathForMatching('/api//users') // '/api/users'\n */\nexport function normalizePathForMatching(path: string): string {\n  return path\n    .replace(/\\/+/g, '/') // Replace multiple slashes with single slash\n    .replace(/\\/+$/, ''); // Remove trailing slash\n}\n\n/**\n * Normalize a path (deprecated, use normalizePathForMatching)\n * @deprecated Use normalizePathForMatching instead\n */\nexport function normalizePath(path: string): string {\n  return normalizePathForMatching(path);\n}\n","import { join } from 'node:path';\nimport type { Request, Response } from 'express';\n\nimport { readLogEntriesByTrace, readRecentTraceCalls, readLogFilePage, readServerLogs, readTriggerList, readTriggerDetail, readCapabilityTraceList } from './services';\nimport {\n  getRelativePath,\n  parseLimit,\n  parsePositiveInt,\n  resolveLogFilePath,\n  serializeError,\n} from './utils';\n\n/**\n * Handle not found error\n */\nfunction handleNotFound(res: Response, filePath: string, message = 'Log file not found'): void {\n  res.status(404).json({ message: `${message}: ${getRelativePath(filePath)}` });\n}\n\n/**\n * Handle generic error\n */\nfunction handleError(res: Response, error: unknown, message = 'Failed to read log file'): void {\n  res.status(500).json({ message, error: serializeError(error) });\n}\n\n/**\n * Create handler for getting log entries by trace ID\n */\nexport function createGetTraceEntriesHandler(logDir: string) {\n  const appLogPath = join(logDir, 'server.log');\n\n  return async (req: Request, res: Response) => {\n    const traceId = (req.params.traceId || '').trim();\n    if (!traceId) {\n      return res.status(400).json({ message: 'traceId is required' });\n    }\n\n    const limit = parseLimit(req.query.limit as string | undefined, 200, 1000);\n\n    try {\n      const entries = await readLogEntriesByTrace(appLogPath, traceId, limit);\n      if (!entries) {\n        return handleNotFound(res, appLogPath);\n      }\n      res.json({\n        file: getRelativePath(appLogPath),\n        traceId,\n        count: entries.length,\n        entries,\n      });\n    } catch (error) {\n      handleError(res, error);\n    }\n  };\n}\n\n/**\n * Create handler for getting recent trace calls\n */\nexport function createGetRecentTracesHandler(logDir: string) {\n  const traceLogPath = join(logDir, 'trace.log');\n\n  return async (req: Request, res: Response) => {\n    const page = parsePositiveInt(req.query.page as string | undefined, 1);\n    const pageSize = parseLimit(req.query.pageSize as string | undefined, 10, 100);\n    const pathFilter = typeof req.query.path === 'string' ? req.query.path.trim() : undefined;\n    const methodFilter = typeof req.query.method === 'string' ? req.query.method.trim().toUpperCase() : undefined;\n\n    try {\n      const result = await readRecentTraceCalls(traceLogPath, page, pageSize, pathFilter, methodFilter);\n      if (!result) {\n        return handleNotFound(res, traceLogPath);\n      }\n      res.json({\n        file: getRelativePath(traceLogPath),\n        ...result,\n        path: pathFilter || null,\n        method: methodFilter || null,\n        count: result.calls.length,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to read trace log');\n    }\n  };\n}\n\n/**\n * Create handler for getting log file by name\n */\nexport function createGetLogFileHandler(logDir: string) {\n  return async (req: Request, res: Response) => {\n    const fileName = (req.params.fileName || '').trim();\n    if (!fileName) {\n      return res.status(400).json({ message: 'fileName is required' });\n    }\n\n    const page = parsePositiveInt(req.query.page as string | undefined, 1);\n    const pageSize = parseLimit(req.query.pageSize as string | undefined, 200, 2000);\n\n    try {\n      const filePath = resolveLogFilePath(logDir, fileName);\n      const result = await readLogFilePage(filePath, page, pageSize);\n      if (!result) {\n        return handleNotFound(res, filePath);\n      }\n\n      res.json({\n        file: getRelativePath(filePath),\n        ...result,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to read specified log file');\n    }\n  };\n}\n\n/**\n * Create handler for getting server logs\n *\n * Reads from 4 log sources:\n * - server.log (Pino JSON)\n * - trace.log (Pino JSON)\n * - server.std.log (plain text)\n * - client.std.log (plain text)\n *\n * Query parameters:\n * - limit: number of logs to return (default: 100, max: 1000)\n * - offset: offset for pagination (default: 0)\n * - levels: comma-separated log levels (e.g., \"error,warn\")\n * - sources: comma-separated sources (e.g., \"server,trace\")\n */\nexport function createGetServerLogsHandler(logDir: string) {\n  return async (req: Request, res: Response) => {\n    const limit = parseLimit(req.query.limit as string | undefined, 100, 1000);\n    const offset = parsePositiveInt(req.query.offset as string | undefined, 0);\n\n    // Parse levels filter\n    const levels = req.query.levels\n      ? String(req.query.levels).split(',').map(l => l.trim()).filter(Boolean)\n      : undefined;\n\n    // Parse sources filter\n    const sources = req.query.sources\n      ? String(req.query.sources).split(',').map(s => s.trim()).filter(Boolean)\n      : undefined;\n\n    try {\n      const result = await readServerLogs(logDir, {\n        limit,\n        offset,\n        levels,\n        sources,\n      });\n\n      if (!result) {\n        return res.status(404).json({\n          message: 'No server log files found',\n          hint: 'Expected files: server.log, trace.log, server.std.log, client.std.log',\n        });\n      }\n\n      res.json(result);\n    } catch (error) {\n      handleError(res, error, 'Failed to read server logs');\n    }\n  }\n}\n/**\n * Create handler for getting all automation trigger list in trace.log\n * filter by request_body.trigger & limit & path=/__innerapi__/automation/invoke\n */\nexport function createGetTriggerListHandler(logDir: string) {\n  const traceLogPath = join(logDir, 'trace.log');\n\n  return async (req: Request, res: Response) => {\n    const trigger = typeof req.query.trigger === 'string' ? req.query.trigger.trim() : undefined;\n    if (!trigger) {\n      return res.status(400).json({ message: 'trigger is required' });\n    }\n\n    const triggerID = typeof req.query.triggerID === 'string' ? req.query.triggerID.trim() : undefined;\n    const path = typeof req.query.path === 'string' ? req.query.path.trim() : '/__innerapi__/automation/invoke';\n    const limit = parseLimit(req.query.limit as string | undefined, 10, 200);\n\n    try {\n      const result = await readTriggerList(traceLogPath, trigger, path, limit, triggerID);\n      if (!result) {\n        return handleNotFound(res, traceLogPath);\n      }\n      res.json({\n        file: getRelativePath(traceLogPath),\n        path,\n        ...result,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to read trace log');\n    }\n  };\n}\n\nexport function createGetTriggerDetailHandler(logDir: string) {\n  const traceLogPath = join(logDir, 'server.log');\n\n  return async (req: Request, res: Response) => {\n    const instanceID = (req.params.instanceID || '').trim();\n    if (!instanceID) {\n      return res.status(400).json({ message: 'instanceID is required' });\n    }\n\n    const path = typeof req.query.path === 'string' ? req.query.path.trim() : '/__innerapi__/automation/invoke';\n\n    try {\n      const result = await readTriggerDetail(traceLogPath, path, instanceID);\n      if (!result) {\n        return handleNotFound(res, traceLogPath);\n      }\n      res.json({\n        file: getRelativePath(traceLogPath),\n        ...result,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to read trace log');\n    }\n  };\n}\n\n/**\n * Create handler for getting capability trace list\n * Filter by capability_id in server.log\n *\n * Query parameters:\n * - capability_id: required, the capability ID to filter\n * - limit: number of traces to return (default: 10, max: 200)\n */\nexport function createGetCapabilityTraceListHandler(logDir: string) {\n  const serverLogPath = join(logDir, 'server.log');\n\n  return async (req: Request, res: Response) => {\n    const capabilityId = typeof req.query.capability_id === 'string' ? req.query.capability_id.trim() : undefined;\n    if (!capabilityId) {\n      return res.status(400).json({ message: 'capability_id is required' });\n    }\n\n    const limit = parseLimit(req.query.limit as string | undefined, 10, 200);\n\n    try {\n      const result = await readCapabilityTraceList(serverLogPath, capabilityId, limit);\n      if (!result) {\n        return handleNotFound(res, serverLogPath);\n      }\n      res.json({\n        file: getRelativePath(serverLogPath),\n        ...result,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to read server log');\n    }\n  };\n}","import { promises as fs } from 'node:fs';\nimport type { TraceBuilder, RecentTraceCallsResponse } from '../types';\n\n/**\n * Read file in reverse order (from end to beginning)\n */\nexport async function readFileReverse(\n  filePath: string,\n  chunkSize: number,\n  processLine: (line: string) => void,\n): Promise<void> {\n  const handle = await fs.open(filePath, 'r');\n\n  try {\n    const stats = await handle.stat();\n    let position = stats.size;\n    let remainder = '';\n\n    while (position > 0) {\n      const length = Math.min(chunkSize, position);\n      position -= length;\n\n      const buffer = Buffer.alloc(length);\n      await handle.read(buffer, 0, length, position);\n\n      let chunk = buffer.toString('utf8');\n      if (remainder) {\n        chunk += remainder;\n        remainder = '';\n      }\n\n      const lines = chunk.split('\\n');\n      remainder = lines.shift() ?? '';\n\n      for (let i = lines.length - 1; i >= 0; i -= 1) {\n        if (lines[i]) {\n          processLine(lines[i]);\n        }\n      }\n    }\n\n    if (remainder) {\n      processLine(remainder);\n    }\n  } finally {\n    await handle.close();\n  }\n}\n\n/**\n * Build paginated response from trace builders\n */\nexport function buildPaginatedResponse(\n  items: TraceBuilder[],\n  page: number,\n  pageSize: number,\n): RecentTraceCallsResponse {\n  const totalItems = items.length;\n  const totalPages = totalItems === 0 ? 0 : Math.ceil(totalItems / pageSize);\n  const startIndex = (page - 1) * pageSize;\n  const endIndex = Math.min(startIndex + pageSize, totalItems);\n\n  const pagedItems = items.slice(startIndex, endIndex).map((builder) => ({\n    traceId: builder.traceId,\n    method: builder.method,\n    path: builder.path,\n    startTime: builder.startTime,\n    endTime: builder.endTime,\n    statusCode: builder.statusCode,\n    durationMs: builder.durationMs,\n    entries: builder.entries.slice().reverse(),\n  }));\n\n  return {\n    page,\n    pageSize,\n    totalCalls: totalItems,\n    totalPages,\n    calls: pagedItems,\n  };\n}\n","import type { ServerLog } from '../types';\n\n/**\n * Generate a simple UUID v4\n */\nexport function generateUUID(): string {\n  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n    const r = (Math.random() * 16) | 0;\n    const v = c === 'x' ? r : (r & 0x3) | 0x8;\n    return v.toString(16);\n  });\n}\n\n/**\n * Map Pino log level to ServerLogLevel\n */\nexport function mapPinoLevelToServerLogLevel(\n  pinoLevel: number | string\n): 'fatal' | 'error' | 'warn' | 'log' | 'debug' | 'verbose' {\n  if (typeof pinoLevel === 'string') {\n    const lower = pinoLevel.toLowerCase();\n    if (lower === 'fatal') return 'fatal';\n    if (lower === 'error') return 'error';\n    if (lower === 'warn' || lower === 'warning') return 'warn';\n    if (lower === 'info' || lower === 'log') return 'log';\n    if (lower === 'debug') return 'debug';\n    if (lower === 'trace' || lower === 'verbose') return 'verbose';\n    return 'log';\n  }\n\n  // Pino numeric levels\n  if (pinoLevel >= 60) return 'fatal';\n  if (pinoLevel >= 50) return 'error';\n  if (pinoLevel >= 40) return 'warn';\n  if (pinoLevel >= 30) return 'log';\n  if (pinoLevel >= 20) return 'debug';\n  return 'verbose';\n}\n\n/**\n * Extract log level from text content\n */\nexport function extractLogLevel(text: string): 'fatal' | 'error' | 'warn' | 'log' | 'debug' | 'verbose' {\n  const lower = text.toLowerCase();\n\n  if (lower.includes('fatal') || lower.includes('critical')) return 'fatal';\n  if (lower.includes('error') || lower.includes('<e>') || lower.includes('✖')) return 'error';\n  if (lower.includes('warn') || lower.includes('warning') || lower.includes('<w>') || lower.includes('⚠')) return 'warn';\n  if (lower.includes('debug') || lower.includes('<d>')) return 'debug';\n  if (lower.includes('verbose') || lower.includes('trace')) return 'verbose';\n\n  return 'log';\n}\n\n/**\n * Parse Pino JSON log to ServerLog format\n */\nexport function parsePinoLog(line: string, source: 'server' | 'trace'): ServerLog | null {\n  try {\n    const pinoLog = JSON.parse(line);\n    const id = generateUUID();\n\n    return {\n      id,\n      level: mapPinoLevelToServerLogLevel(pinoLog.level),\n      timestamp: new Date(pinoLog.time).getTime(),\n      message: pinoLog.message || pinoLog.msg || '',\n      context: pinoLog.context || null,\n      traceId: pinoLog.trace_id || null,\n      userId: pinoLog.user_id || null,\n      appId: pinoLog.app_id || null,\n      tenantId: pinoLog.tenant_id || null,\n      stack: pinoLog.stack || null,\n      meta: {\n        pid: pinoLog.pid,\n        hostname: pinoLog.hostname,\n        path: pinoLog.path,\n        method: pinoLog.method,\n        statusCode: pinoLog.status_code,\n        durationMs: pinoLog.duration_ms,\n        ip: pinoLog.ip,\n        pageRoute: pinoLog.page_route,\n        requestBody: pinoLog.request_body,\n        responseBody: pinoLog.response_body,\n        queryParams: pinoLog.query_params,\n      },\n      tags: [source],\n    };\n  } catch (error) {\n    return null;\n  }\n}\n\n/**\n * Parse plain text log to ServerLog format\n * Format: [2025-11-20 21:48:42] [server] content\n */\nexport function parseStdLog(line: string, source: 'server-std' | 'client-std'): ServerLog | null {\n  const id = generateUUID();\n  const match = line.match(/^\\[(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\] \\[(server|client)\\] (.*)$/);\n\n  if (!match) {\n    return {\n      id,\n      level: 'log',\n      timestamp: Date.now(),\n      message: line,\n      context: null,\n      traceId: null,\n      userId: null,\n      appId: null,\n      tenantId: null,\n      stack: null,\n      meta: null,\n      tags: [source],\n    };\n  }\n\n  const [, timeStr, , content] = match;\n\n  let timestamp: number;\n  try {\n    const isoStr = timeStr.replace(' ', 'T');\n    timestamp = new Date(isoStr).getTime();\n    if (isNaN(timestamp)) {\n      timestamp = Date.now();\n    }\n  } catch (error) {\n    timestamp = Date.now();\n  }\n\n  const level = extractLogLevel(content);\n\n  return {\n    id,\n    level,\n    timestamp,\n    message: content,\n    context: null,\n    traceId: null,\n    userId: null,\n    appId: null,\n    tenantId: null,\n    stack: null,\n    meta: null,\n    tags: [source],\n  };\n}\n","import { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport type {\n  LogEntry,\n  TraceBuilder,\n  RecentTraceCallsResponse,\n  LogFilePageResponse,\n} from '../types';\nimport { fileExists, parseLogLine, extractNumber, matchesPath, matchesMethod } from '../utils';\nimport { readFileReverse, buildPaginatedResponse } from './file-reader';\n\n/**\n * Read log entries by trace ID\n */\nexport async function readLogEntriesByTrace(\n  filePath: string,\n  traceId: string,\n  limit: number,\n): Promise<LogEntry[] | undefined> {\n  const exists = await fileExists(filePath);\n  if (!exists) {\n    return undefined;\n  }\n\n  const matches: LogEntry[] = [];\n  const stream = createReadStream(filePath, { encoding: 'utf8' });\n  const rl = createInterface({ input: stream, crlfDelay: Infinity });\n\n  for await (const line of rl) {\n    const entry = parseLogLine(line);\n    if (!entry) continue;\n    if (entry.trace_id !== traceId) continue;\n\n    matches.push(entry);\n    if (limit > 0 && matches.length > limit) {\n      matches.shift();\n    }\n  }\n\n  rl.close();\n  stream.close();\n\n  return matches;\n}\n\n/**\n * Read recent trace calls with pagination\n */\nexport async function readRecentTraceCalls(\n  filePath: string,\n  page: number,\n  pageSize: number,\n  pathFilter?: string,\n  methodFilter?: string,\n): Promise<RecentTraceCallsResponse | undefined> {\n  if (!(await fileExists(filePath))) {\n    return undefined;\n  }\n\n  const config = {\n    maxEntriesPerTrace: 10,\n    chunkSize: 64 * 1024,\n  };\n\n  const builders = new Map<string, TraceBuilder>();\n  const completedCalls: TraceBuilder[] = [];\n\n  const createTraceBuilder = (traceId: string): TraceBuilder => ({\n    traceId,\n    entries: [],\n    method: undefined,\n    path: undefined,\n    startTime: undefined,\n    endTime: undefined,\n    statusCode: undefined,\n    durationMs: undefined,\n    hasCompleted: false,\n  });\n\n  const updateBuilderMetadata = (builder: TraceBuilder, entry: LogEntry): void => {\n    if (entry.method && !builder.method) builder.method = String(entry.method);\n    if (entry.path && !builder.path) builder.path = String(entry.path);\n\n    builder.entries.push(entry);\n    if (builder.entries.length > config.maxEntriesPerTrace) {\n      builder.entries.shift();\n    }\n  };\n\n  const handleRequestCompleted = (builder: TraceBuilder, entry: LogEntry, message: string): void => {\n    builder.hasCompleted = true;\n    builder.endTime = entry.time;\n    // 结构化日志将 status_code / duration_ms 作为顶层字段，优先读字段；\n    // 仅当日志以文本形式拼接（例如 app.log 的 HTTP request failed 消息）时才回退正则。\n    builder.statusCode =\n      typeof entry.status_code === 'number' ? entry.status_code : extractNumber(message, /status_code:\\s*(\\d+)/);\n    builder.durationMs =\n      typeof entry.duration_ms === 'number' ? entry.duration_ms : extractNumber(message, /duration_ms:\\s*(\\d+)/);\n    if (!builder.path && entry.path) {\n      builder.path = String(entry.path);\n    }\n\n    const pathMatches = !pathFilter || matchesPath(builder.path, pathFilter);\n    const methodMatches = !methodFilter || matchesMethod(builder.method, methodFilter);\n    const shouldInclude = pathMatches && methodMatches;\n\n    if (shouldInclude) {\n      completedCalls.push(builder);\n    }\n  };\n\n  const processLogEntry = (entry: LogEntry): void => {\n    const { trace_id: traceId, message = '' } = entry;\n    if (!traceId) return;\n\n    let builder = builders.get(traceId);\n    if (!builder) {\n      builder = createTraceBuilder(traceId);\n      builders.set(traceId, builder);\n    }\n\n    updateBuilderMetadata(builder, entry);\n\n    if (!builder.hasCompleted && (message.includes('HTTP request completed') || message.includes('HTTP request failed'))) {\n      handleRequestCompleted(builder, entry, message);\n    }\n\n    if (message.includes('HTTP request started') && !builder.startTime) {\n      builder.startTime = entry.time;\n    }\n  };\n\n  const processLine = (line: string): void => {\n    const entry = parseLogLine(line);\n    if (entry?.trace_id) {\n      processLogEntry(entry);\n    }\n  };\n\n  await readFileReverse(filePath, config.chunkSize, processLine);\n\n  return buildPaginatedResponse(completedCalls, page, pageSize);\n}\n\n/**\n * Read log file page with pagination\n */\nexport async function readLogFilePage(\n  filePath: string,\n  page: number,\n  pageSize: number,\n): Promise<LogFilePageResponse | undefined> {\n  if (!(await fileExists(filePath))) {\n    return undefined;\n  }\n\n  const capacity = page * pageSize;\n  const buffer: string[] = [];\n  let totalLines = 0;\n\n  const stream = createReadStream(filePath, { encoding: 'utf8' });\n  const rl = createInterface({ input: stream, crlfDelay: Infinity });\n\n  try {\n    for await (const line of rl) {\n      buffer.push(line);\n      if (buffer.length > capacity) {\n        buffer.shift();\n      }\n      totalLines += 1;\n    }\n  } finally {\n    rl.close();\n    stream.close();\n  }\n\n  const totalPages = totalLines === 0 ? 0 : Math.ceil(totalLines / pageSize);\n\n  if (buffer.length === 0) {\n    return { page, pageSize, totalLines, totalPages, lines: [] };\n  }\n\n  const startIndex = Math.max(totalLines - page * pageSize, 0);\n  const endIndex = Math.max(totalLines - (page - 1) * pageSize, 0);\n  const bufferStartIndex = totalLines - buffer.length;\n\n  const lines: string[] = [];\n  for (let i = buffer.length - 1; i >= 0; i -= 1) {\n    const lineIndex = bufferStartIndex + i;\n    if (lineIndex >= startIndex && lineIndex < endIndex) {\n      lines.push(buffer[i]);\n    }\n  }\n\n  return {\n    page,\n    pageSize,\n    totalLines,\n    totalPages,\n    lines: lines.reverse(),\n  };\n}\n","import { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport { join } from 'node:path';\nimport type { ServerLog, ServerLogResponse } from '../types';\nimport { fileExists } from '../utils';\nimport { parsePinoLog, parseStdLog } from './parsers';\n\n/**\n * Read ServerLog logs from multiple sources\n *\n * Reads from 4 log files:\n * - server.log (Pino JSON)\n * - trace.log (Pino JSON)\n * - server.std.log (plain text)\n * - client.std.log (plain text)\n */\nexport async function readServerLogs(\n  logDir: string,\n  options: {\n    limit?: number;\n    offset?: number;\n    levels?: string[];\n    sources?: string[];\n  } = {}\n): Promise<ServerLogResponse | undefined> {\n  const limit = options.limit || 100;\n  const offset = options.offset || 0;\n  const sources = options.sources || ['server', 'trace', 'server-std', 'client-std'];\n\n  const allLogs: ServerLog[] = [];\n  const errors: string[] = [];\n\n  for (const source of sources) {\n    try {\n      const logs = await readLogsBySource(logDir, source);\n      allLogs.push(...logs);\n    } catch (error) {\n      const errorMsg = `Failed to read ${source}: ${error instanceof Error ? error.message : String(error)}`;\n      errors.push(errorMsg);\n      console.warn(`[readServerLogs] ${errorMsg}`);\n    }\n  }\n\n  if (allLogs.length === 0) {\n    if (errors.length > 0) {\n      console.warn(`[readServerLogs] No logs found. Errors: ${errors.join(', ')}`);\n    }\n    return undefined;\n  }\n\n  let filteredLogs = allLogs;\n  if (options.levels && options.levels.length > 0) {\n    filteredLogs = allLogs.filter(log => options.levels!.includes(log.level));\n  }\n\n  // Sort by timestamp descending (newest first)\n  filteredLogs.sort((a, b) => b.timestamp - a.timestamp);\n\n  const total = filteredLogs.length;\n  const paginatedLogs = filteredLogs.slice(offset, offset + limit);\n\n  return {\n    logs: paginatedLogs,\n    total,\n    hasMore: offset + limit < total,\n  };\n}\n\n/**\n * Read logs from a specific source\n */\nasync function readLogsBySource(\n  logDir: string,\n  source: string\n): Promise<ServerLog[]> {\n  let filePath: string;\n  let parser: (line: string) => ServerLog | null;\n\n  if (source === 'server') {\n    filePath = join(logDir, 'server.log');\n    parser = (line) => parsePinoLog(line, 'server');\n  } else if (source === 'trace') {\n    filePath = join(logDir, 'trace.log');\n    parser = (line) => parsePinoLog(line, 'trace');\n  } else if (source === 'server-std') {\n    filePath = join(logDir, 'server.std.log');\n    parser = (line) => parseStdLog(line, 'server-std');\n  } else if (source === 'client-std') {\n    filePath = join(logDir, 'client.std.log');\n    parser = (line) => parseStdLog(line, 'client-std');\n  } else {\n    console.warn(`[readLogsBySource] Unknown source: ${source}`);\n    return [];\n  }\n\n  if (!(await fileExists(filePath))) {\n    console.warn(`[readLogsBySource] File not found: ${filePath}`);\n    return [];\n  }\n\n  const logs: ServerLog[] = [];\n  let stream: ReturnType<typeof createReadStream> | null = null;\n  let rl: ReturnType<typeof createInterface> | null = null;\n\n  try {\n    stream = createReadStream(filePath, { encoding: 'utf8' });\n    rl = createInterface({ input: stream, crlfDelay: Infinity });\n\n    for await (const line of rl) {\n      if (!line.trim()) continue;\n\n      try {\n        const log = parser(line);\n        if (log) {\n          logs.push(log);\n        }\n      } catch (parseError) {\n        // Ignore individual line parse errors\n      }\n    }\n  } catch (error) {\n    console.error(`[readLogsBySource] Error reading ${filePath}:`, error);\n    throw error;\n  } finally {\n    if (rl) {\n      rl.close();\n    }\n    if (stream) {\n      stream.close();\n    }\n  }\n\n  return logs;\n}\n","import { createReadStream } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport type { LogEntry, TraceBuilder, RecentTraceCallsResponse } from '../types';\nimport { fileExists, parseLogLine, extractNumber } from '../utils';\nimport { readFileReverse } from './file-reader';\n\n/**\n * Read all automation trigger list in trace.log\n * filter by request_body.trigger & limit & path=/__innerapi__/automation/invoke\n */\nexport async function readTriggerList(\n  filePath: string,\n  trigger: string,\n  path: string,\n  limit?: number,\n  triggerID?: string,\n): Promise<RecentTraceCallsResponse | undefined> {\n  if (!(await fileExists(filePath))) {\n    return undefined;\n  }\n\n  const config = {\n    maxEntriesPerTrace: 10,\n    chunkSize: 64 * 1024,\n  };\n\n  const builders = new Map<string, TraceBuilder>();\n  const completedCalls: TraceBuilder[] = [];\n\n  const createTraceBuilder = (traceId: string): TraceBuilder => ({\n    traceId,\n    entries: [],\n    method: undefined,\n    path: undefined,\n    startTime: undefined,\n    endTime: undefined,\n    statusCode: undefined,\n    durationMs: undefined,\n    hasCompleted: false,\n  });\n\n  const shouldIncludeInCompletedCalls = (builder: TraceBuilder): boolean => {\n    const alreadyAdded = completedCalls.some(call => call.traceId === builder.traceId);\n    if (alreadyAdded) {\n      return false;\n    }\n\n    const isAutomationTrigger = builder.path?.endsWith(path);\n    if (!isAutomationTrigger) {\n      return false;\n    }\n\n    if (trigger && builder.entries.length > 0) {\n      const requestEntry = builder.entries.find(e => e.request_body?.trigger);\n      if (requestEntry?.request_body?.trigger) {\n        return String(requestEntry.request_body.trigger) === trigger\n          && (triggerID ? requestEntry?.request_body?.triggerID === triggerID : true);\n      }\n      return false;\n    }\n\n    return true;\n  };\n\n  const updateBuilderMetadata = (builder: TraceBuilder, entry: LogEntry): void => {\n    if (entry.method && !builder.method) builder.method = String(entry.method);\n    if (entry.path && !builder.path) builder.path = String(entry.path);\n\n    builder.entries.push(entry);\n    if (builder.entries.length > config.maxEntriesPerTrace) {\n      builder.entries.shift();\n    }\n\n    if (shouldIncludeInCompletedCalls(builder)) {\n      completedCalls.push(builder);\n      if (limit && completedCalls.length > limit) {\n        completedCalls.pop();\n      }\n    }\n  };\n\n  const handleRequestCompleted = (builder: TraceBuilder, entry: LogEntry, message: string): void => {\n    builder.hasCompleted = true;\n    builder.endTime = entry.time;\n    builder.statusCode = extractNumber(message, /status_code:\\s*(\\d+)/);\n    builder.durationMs = extractNumber(message, /duration_ms:\\s*(\\d+)/);\n    if (!builder.path && entry.path) {\n      builder.path = String(entry.path);\n    }\n\n    if (shouldIncludeInCompletedCalls(builder)) {\n      completedCalls.push(builder);\n      if (limit && completedCalls.length > limit) {\n        completedCalls.pop();\n      }\n    }\n  };\n\n  const processLogEntry = (entry: LogEntry): void => {\n    const { trace_id: traceId, message = '' } = entry;\n    if (!traceId) return;\n\n    let builder = builders.get(traceId);\n    if (!builder) {\n      builder = createTraceBuilder(traceId);\n      builders.set(traceId, builder);\n    }\n\n    updateBuilderMetadata(builder, entry);\n\n    if (!builder.hasCompleted && (message.includes('HTTP request completed') || message.includes('HTTP request failed'))) {\n      handleRequestCompleted(builder, entry, message);\n    }\n\n    if (message.includes('HTTP request started') && !builder.startTime) {\n      builder.startTime = entry.time;\n    }\n  };\n\n  const processLine = (line: string): void => {\n    const entry = parseLogLine(line);\n    if (entry?.trace_id) {\n      processLogEntry(entry);\n    }\n  };\n\n  await readFileReverse(filePath, config.chunkSize, processLine);\n\n  return {\n    page: 1,\n    pageSize: completedCalls.length,\n    totalCalls: completedCalls.length,\n    totalPages: 1,\n    calls: completedCalls.map((builder) => ({\n      traceId: builder.traceId,\n      method: builder.method,\n      path: builder.path,\n      startTime: builder.startTime,\n      endTime: builder.endTime,\n      statusCode: builder.statusCode,\n      durationMs: builder.durationMs,\n      entries: builder.entries.slice().reverse(),\n    })),\n  };\n}\n\n/**\n * Read trigger detail entries by instance ID\n */\nexport async function readTriggerDetail(\n  filePath: string,\n  path: string,\n  instanceID: string,\n): Promise<{ instanceID: string; entries: LogEntry[] } | undefined> {\n  const exists = await fileExists(filePath);\n  if (!exists) {\n    return undefined;\n  }\n\n  const matches: LogEntry[] = [];\n  const stream = createReadStream(filePath, { encoding: 'utf8' });\n  const rl = createInterface({ input: stream, crlfDelay: Infinity });\n\n  for await (const line of rl) {\n    const entry = parseLogLine(line);\n    if (!entry) continue;\n\n    const isAutomationTrigger = entry.path?.endsWith(path);\n    const hasInstanceID = entry.instance_id === instanceID && entry.trigger;\n    if (!isAutomationTrigger || !hasInstanceID) continue;\n\n    matches.push(entry);\n  }\n\n  rl.close();\n  stream.close();\n\n  return {\n    instanceID,\n    entries: matches,\n  };\n}\n","import type { LogEntry } from '../types';\nimport { fileExists, parseLogLine } from '../utils';\nimport { readFileReverse } from './file-reader';\n\n/**\n * Capability trace builder for aggregating capability execution logs\n */\ninterface CapabilityTraceBuilder {\n  traceId: string;\n  capabilityId: string;\n  pluginKey?: string;\n  action?: string;\n  startTime?: string;\n  endTime?: string;\n  durationMs?: number;\n  status?: 'success' | 'failed';\n  input?: string;\n  output?: string;\n  error?: { message: string };\n  hasCompleted: boolean;\n  hasStartEntry: boolean;\n}\n\n/**\n * Capability trace item\n */\nexport interface CapabilityTraceItem {\n  traceId: string;\n  capabilityId: string;\n  pluginKey?: string;\n  action?: string;\n  startTime?: string;\n  endTime?: string;\n  durationMs?: number;\n  status: 'success' | 'failed';\n  input?: string;\n  output?: string;\n  error?: { message: string };\n}\n\n/**\n * Response for capability trace list\n */\nexport interface CapabilityTraceListResponse {\n  capabilityId: string;\n  totalTraces: number;\n  traces: CapabilityTraceItem[];\n}\n\n/**\n * Read capability trace list from server.log\n * Filter by capability_id field in log entries\n * Returns only input and output entries for each trace\n */\nexport async function readCapabilityTraceList(\n  filePath: string,\n  capabilityId: string,\n  limit?: number,\n): Promise<CapabilityTraceListResponse | undefined> {\n  if (!(await fileExists(filePath))) {\n    return undefined;\n  }\n\n  const config = {\n    chunkSize: 64 * 1024,\n  };\n\n  const builders = new Map<string, CapabilityTraceBuilder>();\n  const completedTraces: CapabilityTraceBuilder[] = [];\n\n  const createCapabilityTraceBuilder = (traceId: string, capId: string): CapabilityTraceBuilder => ({\n    traceId,\n    capabilityId: capId,\n    hasCompleted: false,\n    hasStartEntry: false,\n  });\n\n  const shouldIncludeInCompletedTraces = (builder: CapabilityTraceBuilder): boolean => {\n    const alreadyAdded = completedTraces.some(trace => trace.traceId === builder.traceId);\n    if (alreadyAdded) {\n      return false;\n    }\n    return builder.capabilityId === capabilityId;\n  };\n\n  const updateBuilderMetadata = (builder: CapabilityTraceBuilder, entry: LogEntry): void => {\n    if (entry.plugin_key && !builder.pluginKey) {\n      builder.pluginKey = String(entry.plugin_key);\n    }\n    if (entry.action && !builder.action) {\n      builder.action = String(entry.action);\n    }\n\n    const message = entry.message || '';\n\n    // Check if this is the start of capability execution (入参日志)\n    // 从独立字段读取 input\n    if (message.includes('Executing capability') && !builder.hasStartEntry) {\n      builder.hasStartEntry = true;\n      builder.startTime = entry.time;\n      if (entry.input) {\n        builder.input = String(entry.input);\n      }\n    }\n\n    // Check if this is successful completion (结果日志)\n    // 从独立字段读取 output, duration_ms\n    if (message.includes('executed successfully')) {\n      builder.hasCompleted = true;\n      builder.endTime = entry.time;\n      builder.status = 'success';\n      if (entry.output) {\n        builder.output = String(entry.output);\n      }\n      if (entry.duration_ms) {\n        builder.durationMs = Number(entry.duration_ms);\n      }\n\n      if (shouldIncludeInCompletedTraces(builder)) {\n        completedTraces.push(builder);\n      }\n    }\n\n    // Check if this is failed execution (失败日志)\n    // 从独立字段读取 error, duration_ms\n    if (message.includes('execution failed')) {\n      builder.hasCompleted = true;\n      builder.endTime = entry.time;\n      builder.status = 'failed';\n      if (entry.error) {\n        builder.error = { message: String(entry.error) };\n      }\n      if (entry.duration_ms) {\n        builder.durationMs = Number(entry.duration_ms);\n      }\n\n      if (shouldIncludeInCompletedTraces(builder)) {\n        completedTraces.push(builder);\n      }\n    }\n  };\n\n  const processLogEntry = (entry: LogEntry): void => {\n    const { trace_id: traceId, capability_id: capId } = entry;\n\n    if (!traceId || !capId || capId !== capabilityId) return;\n\n    let builder = builders.get(traceId);\n    if (!builder) {\n      builder = createCapabilityTraceBuilder(traceId, capId);\n      builders.set(traceId, builder);\n    }\n\n    updateBuilderMetadata(builder, entry);\n  };\n\n  const processLine = (line: string): void => {\n    const entry = parseLogLine(line);\n    if (entry?.capability_id) {\n      processLogEntry(entry);\n    }\n  };\n\n  await readFileReverse(filePath, config.chunkSize, processLine);\n\n  // Sort by endTime descending (newest first)\n  completedTraces.sort((a, b) => {\n    const timeA = a.endTime ? new Date(a.endTime).getTime() : 0;\n    const timeB = b.endTime ? new Date(b.endTime).getTime() : 0;\n    return timeB - timeA;\n  });\n\n  // Apply limit after sorting\n  const limitedTraces = limit ? completedTraces.slice(0, limit) : completedTraces;\n\n  return {\n    capabilityId,\n    totalTraces: limitedTraces.length,\n    traces: limitedTraces.map((builder): CapabilityTraceItem => ({\n      traceId: builder.traceId,\n      capabilityId: builder.capabilityId,\n      pluginKey: builder.pluginKey,\n      action: builder.action,\n      startTime: builder.startTime,\n      endTime: builder.endTime,\n      durationMs: builder.durationMs,\n      status: builder.status || 'failed',\n      input: builder.input,\n      output: builder.output,\n      error: builder.error,\n    })),\n  };\n}\n","import http from 'node:http';\nimport type { Request, Response } from 'express';\n\ninterface HealthCheckRouterOptions {\n  /** 目标服务端口，默认 3000 */\n  targetPort?: number;\n  /** 目标服务主机，默认 localhost */\n  targetHost?: string;\n  /** 健康检查超时时间（毫秒），默认 2000ms */\n  timeout?: number;\n}\n\n/**\n * 检查目标服务是否可用\n */\nfunction checkServiceHealth(\n  host: string,\n  port: number,\n  timeout: number\n): Promise<{ available: boolean; responseTime?: number; error?: string }> {\n  return new Promise((resolve) => {\n    const startTime = Date.now();\n\n    const req = http.request(\n      {\n        hostname: host,\n        port,\n        path: '/',\n        method: 'HEAD',\n        timeout,\n      },\n      (_res) => {\n        const responseTime = Date.now() - startTime;\n        // 任何响应都表示服务可用（包括错误状态码）\n        resolve({\n          available: true,\n          responseTime,\n        });\n      }\n    );\n\n    req.on('timeout', () => {\n      req.destroy();\n      resolve({\n        available: false,\n        error: 'Request timeout',\n      });\n    });\n\n    req.on('error', (err) => {\n      resolve({\n        available: false,\n        error: err.message,\n      });\n    });\n\n    req.end();\n  });\n}\n\n/**\n * 创建健康检查路由\n */\nexport function createHealthCheckHandler(options: HealthCheckRouterOptions = {}) {\n  const {\n    targetPort = Number(process.env.SERVER_PORT) || 3000,\n    targetHost = 'localhost',\n    timeout = 2000,\n  } = options;\n  return  async (_req: Request, res: Response) => {\n    try {\n      const result = await checkServiceHealth(targetHost, targetPort, timeout);\n\n      if (result.available) {\n        res.status(200).json({\n          status: 'healthy',\n          service: `${targetHost}:${targetPort}`,\n          responseTime: result.responseTime,\n          timestamp: new Date().toISOString(),\n        });\n      } else {\n        res.status(503).json({\n          status: 'unhealthy',\n          service: `${targetHost}:${targetPort}`,\n          error: result.error,\n          timestamp: new Date().toISOString(),\n        });\n      }\n    } catch (error) {\n      res.status(500).json({\n        status: 'error',\n        service: `${targetHost}:${targetPort}`,\n        error: error instanceof Error ? error.message : 'Unknown error',\n        timestamp: new Date().toISOString(),\n      });\n    }\n  };\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { ServerLog } from '../types';\n\n/**\n * Log level mapping from Pino numeric levels\n */\nfunction mapPinoLevelToServerLogLevel(\n  pinoLevel: number | string\n): 'fatal' | 'error' | 'warn' | 'log' | 'debug' | 'verbose' {\n  if (typeof pinoLevel === 'string') {\n    const lower = pinoLevel.toLowerCase();\n    if (lower === 'fatal') return 'fatal';\n    if (lower === 'error') return 'error';\n    if (lower === 'warn' || lower === 'warning') return 'warn';\n    if (lower === 'info' || lower === 'log') return 'log';\n    if (lower === 'debug') return 'debug';\n    if (lower === 'trace' || lower === 'verbose') return 'verbose';\n    return 'log';\n  }\n\n  if (pinoLevel >= 60) return 'fatal';\n  if (pinoLevel >= 50) return 'error';\n  if (pinoLevel >= 40) return 'warn';\n  if (pinoLevel >= 30) return 'log';\n  if (pinoLevel >= 20) return 'debug';\n  return 'verbose';\n}\n\n/**\n * Extract log level from text content\n */\nfunction extractLogLevel(text: string): 'fatal' | 'error' | 'warn' | 'log' | 'debug' | 'verbose' {\n  const lower = text.toLowerCase();\n\n  if (lower.includes('fatal') || lower.includes('critical')) return 'fatal';\n  if (lower.includes('error') || lower.includes('<e>') || lower.includes('✖')) return 'error';\n  if (lower.includes('warn') || lower.includes('warning') || lower.includes('<w>') || lower.includes('⚠')) return 'warn';\n  if (lower.includes('debug') || lower.includes('<d>')) return 'debug';\n  if (lower.includes('verbose') || lower.includes('trace')) return 'verbose';\n\n  return 'log';\n}\n\n/**\n * Generate a simple UUID v4\n */\nfunction generateUUID(): string {\n  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n    const r = (Math.random() * 16) | 0;\n    const v = c === 'x' ? r : (r & 0x3) | 0x8;\n    return v.toString(16);\n  });\n}\n\n/**\n * Parse Pino JSON log to ServerLog format\n */\nfunction parsePinoLog(line: string, source: 'server' | 'trace'): ServerLog | null {\n  try {\n    const pinoLog = JSON.parse(line);\n    const id = generateUUID();\n\n    return {\n      id,\n      level: mapPinoLevelToServerLogLevel(pinoLog.level),\n      timestamp: new Date(pinoLog.time).getTime(),\n      message: pinoLog.message || pinoLog.msg || '',\n      context: pinoLog.context || null,\n      traceId: pinoLog.trace_id || null,\n      userId: pinoLog.user_id || null,\n      appId: pinoLog.app_id || null,\n      tenantId: pinoLog.tenant_id || null,\n      stack: pinoLog.stack || null,\n      meta: {\n        pid: pinoLog.pid,\n        hostname: pinoLog.hostname,\n        path: pinoLog.path,\n        method: pinoLog.method,\n        statusCode: pinoLog.status_code,\n        durationMs: pinoLog.duration_ms,\n        ip: pinoLog.ip,\n        pageRoute: pinoLog.page_route,\n        requestBody: pinoLog.request_body,\n        responseBody: pinoLog.response_body,\n        queryParams: pinoLog.query_params,\n      },\n      tags: [source],\n    };\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Parse plain text log to ServerLog format\n */\nfunction parseStdLog(line: string, source: 'server-std' | 'client-std'): ServerLog | null {\n  const id = generateUUID();\n  const match = line.match(/^\\[(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\] \\[(server|client)\\] (.*)$/);\n\n  if (!match) {\n    return {\n      id,\n      level: extractLogLevel(line),\n      timestamp: Date.now(),\n      message: line,\n      context: null,\n      traceId: null,\n      userId: null,\n      appId: null,\n      tenantId: null,\n      stack: null,\n      meta: null,\n      tags: [source],\n    };\n  }\n\n  const [, timeStr, , content] = match;\n  let timestamp: number;\n\n  try {\n    const isoStr = timeStr.replace(' ', 'T');\n    timestamp = new Date(isoStr).getTime();\n    if (isNaN(timestamp)) {\n      timestamp = Date.now();\n    }\n  } catch {\n    timestamp = Date.now();\n  }\n\n  return {\n    id,\n    level: extractLogLevel(content),\n    timestamp,\n    message: content,\n    context: null,\n    traceId: null,\n    userId: null,\n    appId: null,\n    tenantId: null,\n    stack: null,\n    meta: null,\n    tags: [source],\n  };\n}\n\nexport type LogSubscriber = (log: ServerLog) => void;\n\ninterface LogFileConfig {\n  fileName: string;\n  source: string;\n  parser: (line: string, source: string) => ServerLog | null;\n}\n\n/**\n * LogWatcher - watches log files and emits new log entries via SSE\n */\nexport class LogWatcher {\n  private logDir: string = '';\n  private watchers: Map<string, fs.FSWatcher> = new Map();\n  private filePositions: Map<string, number> = new Map();\n  private subscribers: Set<LogSubscriber> = new Set();\n  private isRunning: boolean = false;\n  private debug: boolean = false;\n\n  private readonly logFiles: LogFileConfig[] = [\n    { fileName: 'server.log', source: 'server', parser: parsePinoLog as (line: string, source: string) => ServerLog | null },\n    { fileName: 'trace.log', source: 'trace', parser: parsePinoLog as (line: string, source: string) => ServerLog | null },\n    { fileName: 'server.std.log', source: 'server-std', parser: parseStdLog as (line: string, source: string) => ServerLog | null },\n    { fileName: 'client.std.log', source: 'client-std', parser: parseStdLog as (line: string, source: string) => ServerLog | null },\n  ];\n\n  constructor(options: { debug?: boolean } = {}) {\n    this.debug = options.debug ?? false;\n  }\n\n  private log(...args: unknown[]): void {\n    if (this.debug) {\n      console.log('[LogWatcher]', ...args);\n    }\n  }\n\n  /**\n   * Start watching log files\n   */\n  start(logDir: string): void {\n    if (this.isRunning) {\n      this.log('Already running, ignoring start call');\n      return;\n    }\n\n    this.logDir = logDir;\n    this.isRunning = true;\n    this.log(`Starting to watch log files in: ${logDir}`);\n\n    for (const config of this.logFiles) {\n      this.watchFile(config);\n    }\n  }\n\n  /**\n   * Stop watching all files\n   */\n  stop(): void {\n    if (!this.isRunning) {\n      return;\n    }\n\n    this.log('Stopping file watchers');\n    this.isRunning = false;\n\n    Array.from(this.watchers.entries()).forEach(([fileName, watcher]) => {\n      watcher.close();\n      this.log(`Closed watcher for: ${fileName}`);\n    });\n\n    this.watchers.clear();\n    this.filePositions.clear();\n  }\n\n  /**\n   * Subscribe to new log events\n   */\n  onLog(callback: LogSubscriber): () => void {\n    this.subscribers.add(callback);\n    this.log(`Subscriber added, total: ${this.subscribers.size}`);\n\n    return () => {\n      this.subscribers.delete(callback);\n      this.log(`Subscriber removed, total: ${this.subscribers.size}`);\n    };\n  }\n\n  /**\n   * Get subscriber count\n   */\n  getSubscriberCount(): number {\n    return this.subscribers.size;\n  }\n\n  /**\n   * Watch a single log file\n   */\n  private watchFile(config: LogFileConfig): void {\n    const filePath = path.join(this.logDir, config.fileName);\n\n    // Check if file exists\n    if (!fs.existsSync(filePath)) {\n      this.log(`File not found, skipping: ${config.fileName}`);\n      return;\n    }\n\n    // Initialize file position to end of file (only watch new content)\n    try {\n      const stats = fs.statSync(filePath);\n      this.filePositions.set(config.fileName, stats.size);\n      this.log(`Initialized position for ${config.fileName}: ${stats.size} bytes`);\n    } catch (error) {\n      this.log(`Failed to get initial position for ${config.fileName}:`, error);\n      this.filePositions.set(config.fileName, 0);\n    }\n\n    // Start watching\n    try {\n      const watcher = fs.watch(filePath, (eventType) => {\n        if (eventType === 'change') {\n          this.handleFileChange(config);\n        }\n      });\n\n      watcher.on('error', (error) => {\n        this.log(`Watcher error for ${config.fileName}:`, error);\n        // Try to restart watcher\n        this.restartWatcher(config);\n      });\n\n      this.watchers.set(config.fileName, watcher);\n      this.log(`Started watching: ${config.fileName}`);\n    } catch (error) {\n      this.log(`Failed to start watcher for ${config.fileName}:`, error);\n    }\n  }\n\n  /**\n   * Restart a file watcher after error\n   */\n  private restartWatcher(config: LogFileConfig): void {\n    const existingWatcher = this.watchers.get(config.fileName);\n    if (existingWatcher) {\n      existingWatcher.close();\n      this.watchers.delete(config.fileName);\n    }\n\n    // Wait a bit before restarting\n    setTimeout(() => {\n      if (this.isRunning) {\n        this.log(`Restarting watcher for: ${config.fileName}`);\n        this.watchFile(config);\n      }\n    }, 1000);\n  }\n\n  /**\n   * Handle file change event - read new content\n   */\n  private handleFileChange(config: LogFileConfig): void {\n    const filePath = path.join(this.logDir, config.fileName);\n    const lastPosition = this.filePositions.get(config.fileName) || 0;\n\n    try {\n      const stats = fs.statSync(filePath);\n      const currentSize = stats.size;\n\n      // File was truncated/rotated - reset position\n      if (currentSize < lastPosition) {\n        this.log(`File ${config.fileName} was truncated, resetting position`);\n        this.filePositions.set(config.fileName, 0);\n        this.handleFileChange(config); // Re-read from beginning\n        return;\n      }\n\n      // No new content\n      if (currentSize === lastPosition) {\n        return;\n      }\n\n      // Read new content\n      const readSize = currentSize - lastPosition;\n      const buffer = Buffer.alloc(readSize);\n      const fd = fs.openSync(filePath, 'r');\n\n      try {\n        fs.readSync(fd, buffer, 0, readSize, lastPosition);\n      } finally {\n        fs.closeSync(fd);\n      }\n\n      // Update position\n      this.filePositions.set(config.fileName, currentSize);\n\n      // Parse lines\n      const content = buffer.toString('utf8');\n      const lines = content.split('\\n');\n\n      for (const line of lines) {\n        if (!line.trim()) continue;\n\n        try {\n          const log = config.parser(line, config.source);\n          if (log) {\n            this.notifySubscribers(log);\n          }\n        } catch {\n          // Ignore parse errors for individual lines\n        }\n      }\n    } catch (error) {\n      this.log(`Error reading file ${config.fileName}:`, error);\n    }\n  }\n\n  /**\n   * Notify all subscribers of new log\n   */\n  private notifySubscribers(log: ServerLog): void {\n    Array.from(this.subscribers).forEach(subscriber => {\n      try {\n        subscriber(log);\n      } catch (error) {\n        this.log('Subscriber error:', error);\n      }\n    });\n  }\n}\n","import type { Response } from 'express';\n\ninterface SSEClient {\n  id: string;\n  res: Response;\n  connectedAt: number;\n}\n\n/**\n * ClientManager - manages SSE client connections\n */\nexport class ClientManager {\n  private clients: Map<string, SSEClient> = new Map();\n  private debug: boolean = false;\n\n  constructor(options: { debug?: boolean } = {}) {\n    this.debug = options.debug ?? false;\n  }\n\n  private log(...args: unknown[]): void {\n    if (this.debug) {\n      console.log('[ClientManager]', ...args);\n    }\n  }\n\n  /**\n   * Generate a unique client ID\n   */\n  generateClientId(): string {\n    return `client_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n  }\n\n  /**\n   * Add a new client connection\n   */\n  addClient(id: string, res: Response): void {\n    this.clients.set(id, {\n      id,\n      res,\n      connectedAt: Date.now(),\n    });\n    this.log(`Client connected: ${id}, total clients: ${this.clients.size}`);\n  }\n\n  /**\n   * Remove a client connection\n   */\n  removeClient(id: string): void {\n    if (this.clients.has(id)) {\n      this.clients.delete(id);\n      this.log(`Client disconnected: ${id}, total clients: ${this.clients.size}`);\n    }\n  }\n\n  /**\n   * Get current client count\n   */\n  getClientCount(): number {\n    return this.clients.size;\n  }\n\n  /**\n   * Check if a client exists\n   */\n  hasClient(id: string): boolean {\n    return this.clients.has(id);\n  }\n\n  /**\n   * Send SSE event to a specific client\n   */\n  sendToClient(clientId: string, event: string, data: unknown): boolean {\n    const client = this.clients.get(clientId);\n    if (!client) {\n      return false;\n    }\n\n    try {\n      const message = this.formatSSEMessage(event, data);\n      client.res.write(message);\n      return true;\n    } catch (error) {\n      this.log(`Failed to send to client ${clientId}:`, error);\n      // Remove client if send fails\n      this.removeClient(clientId);\n      return false;\n    }\n  }\n\n  /**\n   * Broadcast SSE event to all clients\n   */\n  broadcast(event: string, data: unknown): void {\n    const message = this.formatSSEMessage(event, data);\n    const failedClients: string[] = [];\n\n    Array.from(this.clients.entries()).forEach(([id, client]) => {\n      try {\n        client.res.write(message);\n      } catch (error) {\n        this.log(`Broadcast failed for client ${id}:`, error);\n        failedClients.push(id);\n      }\n    });\n\n    // Remove failed clients\n    failedClients.forEach(id => {\n      this.removeClient(id);\n    });\n  }\n\n  /**\n   * Format SSE message\n   * SSE format: event: <event>\\ndata: <json>\\n\\n\n   */\n  private formatSSEMessage(event: string, data: unknown): string {\n    const jsonData = JSON.stringify(data);\n    return `event: ${event}\\ndata: ${jsonData}\\n\\n`;\n  }\n\n  /**\n   * Get all client IDs\n   */\n  getClientIds(): string[] {\n    return Array.from(this.clients.keys());\n  }\n\n  /**\n   * Get client info\n   */\n  getClientInfo(id: string): { id: string; connectedAt: number } | null {\n    const client = this.clients.get(id);\n    if (!client) {\n      return null;\n    }\n    return {\n      id: client.id,\n      connectedAt: client.connectedAt,\n    };\n  }\n\n  /**\n   * Close all client connections\n   */\n  closeAll(): void {\n    this.log(`Closing all ${this.clients.size} clients`);\n    Array.from(this.clients.entries()).forEach(([id, client]) => {\n      try {\n        client.res.end();\n      } catch (error) {\n        this.log(`Error closing client ${id}:`, error);\n      }\n    });\n    this.clients.clear();\n  }\n}\n","import type { Request, Response, RequestHandler } from 'express';\nimport { LogWatcher } from './log-watcher';\nimport { ClientManager } from './client-manager';\n\ninterface SSEHandlerOptions {\n  debug?: boolean;\n  heartbeatInterval?: number; // ms, default 30000\n}\n\n/**\n * Create SSE handler for server logs streaming\n *\n * Endpoint: GET /dev/logs/server-logs/stream\n *\n * SSE Events:\n * - connected: { clientId: string } - sent when client connects\n * - log: ServerLog - sent when new log entry is written\n * - heartbeat: { timestamp: number } - sent periodically to keep connection alive\n */\nexport function createSSEHandler(logDir: string, options: SSEHandlerOptions = {}): RequestHandler {\n  const { debug = false, heartbeatInterval = 30000 } = options;\n\n  // Shared instances across all connections\n  const logWatcher = new LogWatcher({ debug });\n  const clientManager = new ClientManager({ debug });\n\n  const log = (...args: unknown[]): void => {\n    if (debug) {\n      console.log('[SSEHandler]', ...args);\n    }\n  };\n\n  return (req: Request, res: Response): void => {\n    // Set SSE headers\n    res.setHeader('Content-Type', 'text/event-stream');\n    res.setHeader('Cache-Control', 'no-cache');\n    res.setHeader('Connection', 'keep-alive');\n    res.setHeader('X-Accel-Buffering', 'no'); // Disable nginx buffering\n\n    // Disable response timeout\n    res.setTimeout(0);\n\n    // Generate client ID and register\n    const clientId = clientManager.generateClientId();\n    clientManager.addClient(clientId, res);\n\n    log(`New SSE connection: ${clientId}`);\n\n    // Start log watcher if this is the first client\n    if (clientManager.getClientCount() === 1) {\n      log('First client connected, starting log watcher');\n      logWatcher.start(logDir);\n    }\n\n    // Subscribe to new logs\n    const unsubscribe = logWatcher.onLog((logEntry) => {\n      clientManager.sendToClient(clientId, 'log', logEntry);\n    });\n\n    // Send connected event\n    clientManager.sendToClient(clientId, 'connected', {\n      clientId,\n      timestamp: Date.now(),\n    });\n\n    // Set up heartbeat\n    const heartbeat = setInterval(() => {\n      const success = clientManager.sendToClient(clientId, 'heartbeat', {\n        timestamp: Date.now(),\n      });\n\n      if (!success) {\n        // Client disconnected, clean up\n        clearInterval(heartbeat);\n      }\n    }, heartbeatInterval);\n\n    // Handle client disconnect\n    const cleanup = (): void => {\n      log(`Client disconnected: ${clientId}`);\n\n      clearInterval(heartbeat);\n      unsubscribe();\n      clientManager.removeClient(clientId);\n\n      // Stop log watcher if no more clients\n      if (clientManager.getClientCount() === 0) {\n        log('No more clients, stopping log watcher');\n        logWatcher.stop();\n      }\n    };\n\n    req.on('close', cleanup);\n    req.on('error', (error) => {\n      log(`Client error ${clientId}:`, error);\n      cleanup();\n    });\n  };\n}\n\n/**\n * Create a handler that returns current SSE status\n * Useful for debugging/monitoring\n */\nexport function createSSEStatusHandler(\n  clientManager: ClientManager,\n  logWatcher: LogWatcher\n): RequestHandler {\n  return (_req: Request, res: Response): void => {\n    res.json({\n      clients: clientManager.getClientCount(),\n      clientIds: clientManager.getClientIds(),\n      subscribers: logWatcher.getSubscriberCount(),\n    });\n  };\n}\n","import { Request, Response, RequestHandler } from 'express';\n\nconst SERVER_PORT = process.env.SERVER_PORT || '3000';\n\n/**\n * API 路由信息\n */\ninterface ApiRouteInfo {\n  id: string;\n  path: string;\n  method: string;\n  module: string;\n}\n\n/**\n * API 路由分组\n */\ninterface ApiRouteGroup {\n  id: string;\n  name: string;\n  apis: ApiRouteInfo[];\n}\n\n/**\n * 后端 debug 接口返回的路由信息\n */\ninterface DebugRouteInfo {\n  order: string;\n  path: string;\n  method: string;\n  regexp?: string;\n}\n\n/**\n * 后端 debug 接口返回的完整响应\n */\ninterface DebugResponse {\n  '路由配置': {\n    total: number;\n    routes: DebugRouteInfo[];\n  };\n  '进程存活时间（秒）': number;\n  '进程启动时间（秒）': string;\n  '运行时版本': Record<string, string>;\n}\n\n/**\n * 从路径中提取模块名\n */\nfunction extractModuleFromPath(path: string): string {\n  const segments = path.split('/').filter(Boolean);\n\n  // 跳过 'api' 前缀\n  let startIndex = 0;\n  if (segments[0] === 'api') {\n    startIndex = 1;\n  }\n\n  // 跳过版本号 (v1, v2, etc.)\n  if (segments[startIndex]?.match(/^v\\d+$/)) {\n    startIndex++;\n  }\n\n  const moduleName = segments[startIndex];\n  if (!moduleName || moduleName.startsWith(':')) {\n    return 'default';\n  }\n\n  return moduleName;\n}\n\n/**\n * 生成路由唯一标识\n */\nfunction generateRouteId(method: string, path: string): string {\n  const cleanPath = path.replace(/[/:]/g, '_').replace(/^_+|_+$/g, '');\n  return `${method.toLowerCase()}_${cleanPath}`;\n}\n\n/**\n * 首字母大写\n */\nfunction capitalize(str: string): string {\n  return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * 按模块分组路由\n */\nfunction groupRoutesByModule(routes: ApiRouteInfo[]): ApiRouteGroup[] {\n  const groupMap = new Map<string, ApiRouteInfo[]>();\n\n  routes.forEach((route) => {\n    const existing = groupMap.get(route.module) || [];\n    existing.push(route);\n    groupMap.set(route.module, existing);\n  });\n\n  const groups: ApiRouteGroup[] = [];\n\n  groupMap.forEach((apis, moduleName) => {\n    groups.push({\n      id: moduleName,\n      name: capitalize(moduleName),\n      apis: apis.sort((a, b) => a.path.localeCompare(b.path)),\n    });\n  });\n\n  return groups.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * 从后端 debug 接口获取路由列表\n */\nasync function fetchRoutesFromBackend(basePath: string): Promise<ApiRouteInfo[]> {\n  // basePath 例如 /af/p/app_xxx，需要拼接完整路径\n  const normalizedBasePath = basePath.replace(/\\/+$/, '');\n  const url = `http://localhost:${SERVER_PORT}${normalizedBasePath}/api/__framework__/debug`;\n\n  const response = await fetch(url, {\n    method: 'GET',\n    headers: {\n      'Accept': 'application/json',\n    },\n  });\n\n  if (!response.ok) {\n    throw new Error(`Failed to fetch routes: ${response.status}`);\n  }\n\n  const data = (await response.json()) as DebugResponse;\n\n  // 从 debug 接口响应中提取路由信息\n  const routeConfig = data['路由配置'];\n  if (!routeConfig || !routeConfig.routes || !Array.isArray(routeConfig.routes)) {\n    console.warn('[api-list] Invalid routes data:', routeConfig);\n    return [];\n  }\n\n  const debugRoutes = routeConfig.routes;\n\n  return debugRoutes\n    .filter((route: DebugRouteInfo) => {\n      // 只保留包含 /api/ 的路由，排除内部路由和 capability 路由\n      return route.path.includes('/api/') &&\n        !route.path.includes('__framework__') &&\n        !route.path.includes('__innerapi__') &&\n        !route.path.includes('__platform__') &&\n        !route.path.includes('/api/capability') &&\n        !route.path.includes('/api/authnpaas') &&\n        !route.path.includes('/api/sdk_innerapi');\n    })\n    .map((route: DebugRouteInfo) => {\n      // 从完整路径中提取 /api/... 部分\n      const apiPathMatch = route.path.match(/\\/api\\/.*/);\n      const apiPath = apiPathMatch ? apiPathMatch[0] : route.path;\n\n      const method = route.method || 'ALL';\n\n      return {\n        id: generateRouteId(method, apiPath),\n        path: apiPath,\n        method,\n        module: extractModuleFromPath(apiPath),\n      };\n    });\n}\n\n/**\n * Create handler for /api-list route\n */\nexport function createApiListHandler(): RequestHandler {\n  return async (_req: Request, res: Response) => {\n    try {\n      // 从环境变量或请求中获取 basePath\n      // req.baseUrl 是当前 router 的挂载路径，如 /af/p/app_xxx/dev/logs\n      // 我们需要提取 /af/p/app_xxx 部分\n      const basePath = process.env.CLIENT_BASE_PATH || '';\n      const routes = await fetchRoutesFromBackend(basePath);\n      const groups = groupRoutesByModule(routes);\n\n      res.json({\n        groups,\n        total: routes.length,\n      });\n    } catch (error) {\n      console.error('[api-list] Failed to fetch routes:', error);\n      res.status(500).json({\n        error: 'Failed to fetch routes',\n        message: error instanceof Error ? error.message : 'Unknown error',\n      });\n    }\n  };\n}\n","import type { RouteMiddleware, MiddlewareContext, RouteInfo } from '../types';\nimport { createDevLogRouter } from './router';\n\ninterface DevLogsMiddlewareOptions {\n  /** Directory containing log files */\n  logDir?: string;\n}\n\n/**\n * Routes provided by dev logs middleware\n */\nconst DEV_LOGS_ROUTES: RouteInfo[] = [\n  {\n    method: 'GET',\n    path: '/app/trace/:traceId',\n    description: 'Get log entries by trace ID',\n  },\n  {\n    method: 'GET',\n    path: '/trace/recent',\n    description: 'Get recent trace calls with pagination and optional path/method filters',\n  },\n  {\n    method: 'GET',\n    path: '/files/:fileName',\n    description: 'Get paginated log file content by file name',\n  },\n  {\n    method: 'GET',\n    path: '/server-logs',\n    description: 'Get server logs in ServerLog format (compatible with frontend)',\n  },\n  {\n    method: 'GET',\n    path: '/trace/trigger/list',\n    description: 'Get trigger list (automation trigger) in trace.log',\n  },\n  {\n    method: 'GET',\n    path: '/trace/trigger/:instanceID',\n    description: 'Get trigger detail (automation trigger) in trace.log by instanceID',\n  },\n  {\n    method: 'GET',\n    path: '/api-list',\n    description: 'Get all API routes grouped by module',\n  },\n];\n\n/**\n * Creates dev logs middleware for viewing application logs\n * Supports both rspack/webpack and Vite dev servers\n */\nexport function createDevLogsMiddleware(options: DevLogsMiddlewareOptions = {}): RouteMiddleware {\n  const { logDir } = options;\n\n  return {\n    name: 'dev-logs',\n    mountPath: '/dev/logs',\n    routes: DEV_LOGS_ROUTES,\n\n    enabled: (context: MiddlewareContext) => context.isDev,\n\n    createRouter: (context: MiddlewareContext) => {\n      return createDevLogRouter({ logDir: logDir || context.logDir });\n    },\n  };\n}\n","import express, { Router } from 'express';\nimport {\n  collectLogsHandler,\n  collectLogsBatchHandler,\n} from './controller';\nimport { resolveLogDir } from './utils';\n\ninterface RouterOptions {\n  logDir?: string;\n  fileName?: string;\n}\n\n// Default body size limit: 20mb, can be overridden via BODY_SIZE_LIMIT env variable (e.g., '50mb')\nconst DEFAULT_BODY_SIZE_LIMIT = '20mb';\n\nfunction getBodySizeLimit(): string {\n  return process.env.BODY_SIZE_LIMIT || DEFAULT_BODY_SIZE_LIMIT;\n}\n\n/**\n * Create dev log router with all routes registered\n */\nexport function createDevLogRouter(options: RouterOptions = {}): Router {\n  const logDir = resolveLogDir(options.logDir);\n  const router = express.Router();\n  const bodyLimit = getBodySizeLimit();\n\n  // POST /collect - Collect logs from client\n  // Use express.json() middleware only for this route\n  router.post('/collect', express.json({ limit: bodyLimit }), collectLogsHandler(logDir, options.fileName || 'client.log'));\n  router.post('/collect-batch', express.json({ limit: bodyLimit }), collectLogsBatchHandler(logDir, options.fileName || 'client.log'));\n\n  return router;\n}\n","import { Request, Response } from 'express';\nimport { join } from 'path';\nimport fs from 'fs';\n\nimport { serializeError, ensureDir } from './utils';\n\ninterface CollectLogRequest {\n  level: string;\n  message: string;\n  time: string; // ISO String\n  source?: string; // Log Source string\n  user_id: string; // User ID\n  tenant_id: string; // Tenant ID\n  app_id: string; // App ID\n}\n\nexport function collectLogsHandler(logDir: string, fileName: string) {\n  const filePath = join(logDir, fileName);\n  // Ensure log directory exists\n  ensureDir(logDir);\n\n  return async (req: Request, res: Response) => {\n    try {\n      const logContent = req.body as CollectLogRequest;\n      if(!logContent.message){\n        return res.status(400).json({ message: 'message is required' });\n      }\n      const logLine = JSON.stringify({\n        ...logContent,\n        server_time: new Date().toISOString(),\n      }) + '\\n';\n      await fs.promises.appendFile(filePath, logLine);\n      res.json({\n        success: true,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to collect logs');\n    }\n  };\n}\nexport function collectLogsBatchHandler(logDir: string, fileName: string) {\n  const filePath = join(logDir, fileName);\n  // Ensure log directory exists\n  ensureDir(logDir);\n\n  return async (req: Request, res: Response) => {\n    try {\n      const logContents = req.body as Array<CollectLogRequest>;\n      if(!Array.isArray(logContents)){\n        return res.status(400).json({ message: 'logContents must be an array' });\n      }\n      const logLines = [];\n      for (const logContent of logContents) {\n        logLines.push(JSON.stringify({\n          ...logContent,\n          server_time: new Date().toISOString(),\n        }) + '\\n');\n      }\n      await fs.promises.appendFile(filePath, logLines.join(''));\n      res.json({\n        success: true,\n      });\n    } catch (error) {\n      handleError(res, error, 'Failed to collect logs');\n    }\n  };\n}\n\nfunction handleError(res: Response, error: unknown, message = 'Failed to collect logs'): void {\n  res.status(500).json({ message, error: serializeError(error) });\n}","import { isAbsolute, join } from 'node:path';\nimport fs from 'node:fs';\n\n/**\n * Resolve log directory path\n */\nexport function resolveLogDir(provided?: string): string {\n  if (!provided) {\n    return join(process.cwd(), 'logs');\n  }\n  return isAbsolute(provided) ? provided : join(process.cwd(), provided);\n}\n\n/**\n * Ensure directory exists, create if not\n */\nexport function ensureDir(dir: string): void {\n  if (!fs.existsSync(dir)) {\n    fs.mkdirSync(dir, { recursive: true });\n  }\n}\n\n/**\n * Serialize error for JSON response\n */\nexport function serializeError(error: unknown): { name?: string; message: string } {\n  return error instanceof Error\n    ? { name: error.name, message: error.message }\n    : { message: String(error) };\n}\n","import type { RouteMiddleware, MiddlewareContext, RouteInfo } from '../types';\nimport { createDevLogRouter } from './router';\n\ninterface DevLogsMiddlewareOptions {\n  logDir?: string; // log directory\n  fileName?: string; // client.log by default\n}\n\n/**\n * Routes provided by dev logs middleware\n */\nconst DEV_LOGS_ROUTES: RouteInfo[] = [\n  {\n    method: 'POST',\n    path: '/collect',\n    description: 'Collect logs from client.',\n  }\n];\n\n/**\n * Creates dev logs middleware for viewing application logs\n * Supports both rspack/webpack and Vite dev servers\n */\nexport function createCollectLogsMiddleware(options: DevLogsMiddlewareOptions = {}): RouteMiddleware {\n  const { logDir } = options;\n\n  return {\n    name: 'collect-logs',\n    mountPath: '/dev/logs',\n    routes: DEV_LOGS_ROUTES,\n    enabled: (context: MiddlewareContext) => context.isDev,\n    createRouter: (context: MiddlewareContext) => {\n      return createDevLogRouter({\n        logDir: logDir || context.logDir,\n        fileName: options.fileName || 'client.log',\n      });\n    },\n  };\n}\n","/**\n * Express/Connect 兼容层\n * 让 middleware 同时支持 Express 和 Vite/Connect\n */\nimport type { ServerResponse, IncomingMessage } from 'http';\n\ntype AnyResponse = ServerResponse & {\n  status?: (code: number) => AnyResponse;\n  json?: (data: unknown) => void;\n  send?: (data: unknown) => void;\n};\n\ntype AnyRequest = IncomingMessage & {\n  query?: Record<string, string>;\n  params?: Record<string, string>;\n};\n\n/**\n * 发送 JSON 响应，兼容 Express 和 Connect\n */\nexport function sendJson(res: AnyResponse, data: unknown, statusCode = 200): void {\n  const statusFn = res.status;\n  const jsonFn = res.json;\n  if (typeof statusFn === 'function' && typeof jsonFn === 'function') {\n    // Express style\n    statusFn.call(res, statusCode);\n    jsonFn.call(res, data);\n  } else {\n    // Connect/Node style\n    res.statusCode = statusCode;\n    res.setHeader('Content-Type', 'application/json');\n    res.end(JSON.stringify(data));\n  }\n}\n\n/**\n * 发送错误响应\n */\nexport function sendError(\n  res: AnyResponse,\n  message: string,\n  error?: unknown,\n  statusCode = 500\n): void {\n  const errorData = {\n    message,\n    ...(error ? { error: serializeError(error) } : {}),\n  };\n  sendJson(res, errorData, statusCode);\n}\n\n/**\n * 发送成功响应\n */\nexport function sendSuccess(res: AnyResponse, data?: Record<string, unknown>): void {\n  sendJson(res, { success: true, ...data }, 200);\n}\n\n/**\n * 获取 query 参数，兼容 Express 和 Connect\n */\nexport function getQuery(req: AnyRequest): Record<string, string> {\n  if (req.query) {\n    return req.query as Record<string, string>;\n  }\n  // Connect/Node style - parse from URL\n  const url = new URL(req.url || '', `http://${req.headers.host}`);\n  return Object.fromEntries(url.searchParams.entries());\n}\n\n/**\n * 获取单个 query 参数\n */\nexport function getQueryParam(req: AnyRequest, key: string): string | undefined {\n  const query = getQuery(req);\n  return query[key];\n}\n\n/**\n * 序列化错误对象\n */\nfunction serializeError(error: unknown): Record<string, unknown> {\n  if (error instanceof Error) {\n    return {\n      name: error.name,\n      message: error.message,\n      stack: error.stack,\n    };\n  }\n  return { message: String(error) };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport { parse } from '@babel/parser';\nimport _traverse from '@babel/traverse';\nimport * as t from '@babel/types';\n\n// Handle CJS default export interop in ESM context\nconst traverse = typeof _traverse === 'function' ? _traverse : (_traverse as any).default;\n\nexport interface PageRouteInfo {\n  path?: string;\n  index?: boolean;\n  [key: string]: unknown;\n}\n\nexport interface ParseRoutesOptions {\n  /** If true, prefix all routes with basePath. Default: true */\n  applyBasePath?: boolean;\n}\n\nexport function routeParserLog(\n  level: 'log' | 'warn' | 'error' | 'info',\n  message: string,\n  ...args: unknown[]\n): void {\n  const prefix = '[route-parser]';\n  const logMessage = `${prefix} ${message}`;\n  switch (level) {\n    case 'warn':\n      console.warn(logMessage, ...args);\n      break;\n    case 'error':\n      console.error(logMessage, ...args);\n      break;\n    case 'info':\n      console.info(logMessage, ...args);\n      break;\n    default:\n      console.log(logMessage, ...args);\n  }\n}\n\nexport function calculateFileHash(filePath: string): string | null {\n  try {\n    const content = fs.readFileSync(filePath, 'utf-8');\n    return crypto.createHash('md5').update(content).digest('hex');\n  } catch (error) {\n    routeParserLog('warn', 'Failed to calculate file hash:', (error as Error).message);\n    return null;\n  }\n}\n\nexport function isRouteComponent(openingElement: t.JSXOpeningElement): boolean {\n  return (\n    t.isJSXIdentifier(openingElement.name) &&\n    openingElement.name.name === 'Route'\n  );\n}\n\nexport function evaluateTemplateLiteral(templateLiteral: t.TemplateLiteral): string {\n  const quasis = templateLiteral.quasis;\n  const expressions = templateLiteral.expressions;\n\n  if (quasis.length === 1 && expressions.length === 0) {\n    return quasis[0].value.raw;\n  }\n\n  return quasis.map((q) => q.value.raw).join('');\n}\n\nexport function extractPageRouteInfo(openingElement: t.JSXOpeningElement): PageRouteInfo {\n  const routeInfo: PageRouteInfo = {};\n\n  openingElement.attributes.forEach((attr) => {\n    if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {\n      const name = attr.name.name;\n      let value: unknown;\n\n      if (attr.value) {\n        if (t.isStringLiteral(attr.value)) {\n          value = attr.value.value;\n        } else if (t.isJSXExpressionContainer(attr.value)) {\n          const expression = attr.value.expression;\n          if (t.isStringLiteral(expression)) {\n            value = expression.value;\n          } else if (t.isTemplateLiteral(expression)) {\n            value = evaluateTemplateLiteral(expression);\n          } else {\n            value = true;\n          }\n        }\n      } else {\n        value = true;\n      }\n\n      routeInfo[name] = value;\n    }\n  });\n\n  return routeInfo;\n}\n\nexport function buildFullPath(\n  routeStack: PageRouteInfo[],\n  currentRoute: PageRouteInfo\n): string | null {\n  let fullPath = '';\n\n  for (let i = 0; i < routeStack.length; i++) {\n    if (routeStack[i].path) {\n      let parentPath = routeStack[i].path!;\n      if (!parentPath.startsWith('/')) parentPath = `/${parentPath}`;\n      if (parentPath.endsWith('/') && parentPath !== '/') {\n        parentPath = parentPath.slice(0, -1);\n      }\n\n      fullPath += parentPath === '/' ? '' : parentPath;\n    }\n  }\n\n  if (currentRoute.index) {\n    return fullPath || '/';\n  } else if (currentRoute.path) {\n    const routePath = currentRoute.path;\n\n    if (routePath === '*') {\n      return null;\n    }\n\n    if (!routePath.startsWith('/')) {\n      fullPath = `${fullPath}/${routePath}`;\n    } else {\n      fullPath = routePath;\n    }\n\n    if (fullPath === '') fullPath = '/';\n    if (!fullPath.startsWith('/')) fullPath = `/${fullPath}`;\n\n    return fullPath;\n  }\n\n  return null;\n}\n\n/**\n * Parse routes from the app file at build time.\n * @param appPath - Path to app.tsx (relative to cwd or absolute)\n * @param basePath - Normalized base path prefix (e.g., '/my_plugin', or '' for no prefix)\n * @param options - Parse options\n * @returns Array of route definitions\n */\nexport function parseRoutesFromFile(\n  appPath: string,\n  basePath: string,\n  options: ParseRoutesOptions = {}\n): Array<{ path: string }> {\n  const { applyBasePath = true } = options;\n  const defaultPath = applyBasePath && basePath ? `${basePath}/` : '/';\n\n  try {\n    const appFilePath = path.resolve(process.cwd(), appPath);\n\n    if (!fs.existsSync(appFilePath)) {\n      throw new Error(`App file does not exist: ${appFilePath}`);\n    }\n\n    const sourceCode = fs.readFileSync(appFilePath, 'utf-8');\n\n    const ast = parse(sourceCode, {\n      sourceType: 'module',\n      plugins: [\n        'jsx',\n        'typescript',\n        'decorators-legacy',\n        'classProperties',\n        'objectRestSpread',\n        'functionBind',\n        'exportDefaultFrom',\n        'exportNamespaceFrom',\n        'dynamicImport',\n        'nullishCoalescingOperator',\n        'optionalChaining',\n      ],\n    });\n\n    const routeSet = new Set<string>();\n    const routeStack: PageRouteInfo[] = [];\n\n    traverse(ast, {\n      JSXElement: {\n        enter(nodePath: any) {\n          const { openingElement } = nodePath.node;\n          if (isRouteComponent(openingElement)) {\n            routeStack.push(extractPageRouteInfo(openingElement));\n          }\n        },\n        exit(nodePath: any) {\n          const { openingElement } = nodePath.node;\n          if (isRouteComponent(openingElement)) {\n            const currentRoute = routeStack.pop();\n            if (currentRoute && currentRoute.path === '*') return;\n            if (currentRoute && (currentRoute.path || currentRoute.index)) {\n              const fullPath = buildFullPath(routeStack, currentRoute);\n              if (fullPath) routeSet.add(fullPath);\n            }\n          }\n        },\n      },\n    });\n\n    const routes = Array.from(routeSet).map((routePath) => ({\n      path: applyBasePath && basePath ? `${basePath}${routePath}` : routePath,\n    }));\n    return routes.length > 0 ? routes : [{ path: defaultPath }];\n  } catch (error) {\n    routeParserLog('warn', 'Route parsing failed, using default routes:', (error as Error).message);\n    return [{ path: defaultPath }];\n  }\n}\n"],"mappings":"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","names":["normalizeBasePath","basePath","normalizedBasePath","startsWith","basePathWithoutTrailingSlash","endsWith","slice","import_node_fs","import_node_path","HEADER_COMMENT","ensureHeaderComment","source","text","startsWith","slice","HEADER_COMMENT","length","stripLeadingNewlines","trimmed","value","current","collapseExtraBlankLines","replace","removePgSchemaDeclarations","source","replace","convertSchemaTableInvocations","converted","text","renamePgTableConstants","source","pgTableRegex","renames","updated","replace","match","currentName","factory","tableName","sanitized","sanitizeIdentifier","push","from","to","equalsIndex","indexOf","suffix","slice","normalizedSuffix","trimStart","text","updateTableReferenceIdentifiers","length","reduce","acc","rename","pattern","RegExp","escapeRegExp","value","toCamelCase","str","words","split","filter","Boolean","map","word","index","toLowerCase","charAt","toUpperCase","join","name","asciiName","toAsciiName","test","transliterated","pinyin","toneType","type","error","CUSTOM_TYPE_PATTERN","replaceUnknownColumns","source","lines","split","result","replaced","unmatched","i","length","line","match","CUSTOM_TYPE_PATTERN","typeName","factory","replacedLine","replaceFollowingUnknown","push","trim","includes","text","join","nextLine","undefined","replace","tweakImports","source","importRegex","match","identifiers","split","map","id","trim","filter","Boolean","filteredIdentifiers","timestampUsageRegex","test","includes","push","unique","Array","from","Set","replacement","join","replace","inlineCustomTypes","source","text","replace","possiblePaths","path","resolve","__dirname","templatePath","possiblePath","fs","existsSync","console","warn","inlineFromTemplate","templateContent","readFileSync","typeDefinitions","trim","needsSql","includes","needsCustomType","ensureImportIdentifier","importMatch","match","insertPoint","indexOf","length","slice","headerPrefix","HEADER_COMMENT","insertionPoint","startsWith","importSectionMatch","typeBlock","packageName","identifier","escapedPackage","importRegex","RegExp","identifiers","split","map","id","filter","Boolean","push","unique","Array","from","Set","replacement","join","addSystemFieldComments","source","commentMap","lines","split","i","length","line","entry","Object","entries","find","key","includes","description","previousLine","trim","startsWith","indentMatch","match","indent","comment","splice","join","removeConflictingSystemFields","systemFieldMap","result","inTable","tableStartLine","tableBusinessFields","Set","bracketDepth","test","clear","char","businessField","values","add","tableEndLine","j","tableLine","shouldRemove","systemField","has","push","filter","patchDrizzleKitDefects","source","fixed","text","replace","replaceTimestampWithCustomTypes","source","replaced","pattern","text","replace","match","quote","fieldName","options","hasWithTimezone","test","hasModeString","replaceDefaultNowWithSql","TABLE_ALIAS_MARKER","appendTableAliases","source","markerIndex","indexOf","base","slice","exportRegex","tableExports","Set","match","matchAll","name","add","size","aliasLines","Array","from","sort","map","join","prefix","trimEnd","postprocessDrizzleSchema","targetPath","resolvedPath","path","resolve","fs","existsSync","console","warn","undefined","text","readFileSync","ensureHeaderComment","patchResult","patchDrizzleKitDefects","removePgSchemaDeclarations","tableConversion","convertSchemaTableInvocations","renameResult","renamePgTableConstants","updateTableReferenceIdentifiers","renames","replacement","replaceUnknownColumns","timestampReplacement","replaceTimestampWithCustomTypes","defaultNowReplacement","replaceDefaultNowWithSql","removeConflictingSystemFields","addSystemFieldComments","tweakImports","inlineCustomTypes","appendTableAliases","replace","collapseExtraBlankLines","writeFileSync","fixed","info","replaced","unmatched","length","forEach","line","converted","replacedUnknown","unmatchedUnknown","patchedDefects","replacedTimestamps","replacedDefaultNow","mapDrizzleTypeToTS","field","typeMap","char","varchar","text","smallint","integer","int","bigint","serial","smallserial","bigserial","decimal","numeric","real","doublePrecision","boolean","timestamp","timestamptz","date","time","timetz","interval","uuid","json","jsonb","bytea","inet","cidr","macaddr","macaddr8","point","line","lseg","box","path","polygon","circle","array","customType","customTimestamptz","userProfile","fileAttachment","pgEnum","baseType","type","isArray","endsWith","enumValues","length","map","v","join","toPascalCase","str","replace","split","word","charAt","toUpperCase","slice","toKebabCase","toLowerCase","toSnakeCase","generateDTO","table","className","toPascalCase","variableName","dto","field","fields","isPrimaryKey","name","startsWith","tsType","mapDrizzleTypeToTS","optional","nullable","hasDefault","decorators","generateValidationDecorators","isUpdate","isResponse","comment","type","length","isArray","generateController","routePath","toKebabCase","pluralize","filePath","toSnakeCase","pkField","find","f","pkType","pkName","controller","generateService","service","generateModule","module","DrizzleSchemaParser","project","projectOptions","Project","parseSchemaFile","filePath","sourceFile","addSourceFileAtPath","tables","variableStatements","getVariableStatements","statement","declarations","getDeclarations","declaration","initializer","getInitializer","Node","isCallExpression","expression","getExpression","getText","tableInfo","parsePgTable","getName","push","variableName","callExpr","args","getArguments","length","tableName","replace","fieldsArg","isObjectLiteralExpression","fields","properties","getProperties","prop","isPropertyAssignment","fieldName","leadingComments","getLeadingCommentRanges","comment","map","c","join","trim","fieldInfo","parseField","name","columnName","type","nullable","hasDefault","notNull","isPrimaryKey","isUnique","isArray","parseBaseType","parseCallChain","current","baseCall","isPropertyAccessExpression","typeName","firstArg","isStringLiteral","getLiteralText","parseTypeConfig","isArrayLiteralExpression","enumValues","getElements","el","objLiteral","propName","value","parseInt","undefined","precision","scale","defaultValue","withTimezone","mode","Error","methodName","refArg","match","references","table","column","parseAndGenerateNestResourceTemplate","options","parser","DrizzleSchemaParser","tsConfigFilePath","tables","parseSchemaFile","schemaFilePath","length","console","warn","sort","a","b","variableName","table","info","filePath","toSnakeCase","moduleDir","join","moduleOutputDir","existsSync","dto","generateDTO","controller","generateController","service","generateService","moduleFilePath","module","generateModule","mkdir","recursive","writeFile","err","error","message","rm","isConnectionError","err","code","connectionErrorCodes","includes","checkServiceAvailable","targetUrl","timeout","Promise","resolve","url","URL","isHttps","protocol","httpModule","https","http","req","request","hostname","port","path","method","res","statusCode","on","destroy","end","waitForServiceRecovery","interval","startTime","Date","now","isAvailable","setTimeout","send502Json","headersSent","writeHead","JSON","stringify","error","message","sendRedirect","originalUrl","console","log","handleDevProxyError","options","retryTimeout","retryInterval","target","process","env","SERVER_PORT","recovered","import_node_path","import_promises","import_node_fs","import_node_path","import_node_path","import_node_fs","findControllerFiles","dir","files","scan","currentDir","entries","fs","readdir","withFileTypes","entry","fullPath","path","join","name","isDirectory","isFile","endsWith","push","buildSourceMap","controllerFiles","processFile","sourceMap","Map","concurrency","results","i","length","batch","slice","batchResults","Promise","all","map","filePath","metadata","operationId","info","set","findSourceInfo","directMatch","get","key","value","className","methodName","split","camelCaseId","charAt","toLowerCase","toUpperCase","undefined","enhanceOpenApiPaths","openapi","enhancedCount","paths","pathItem","Object","values","operation","sourceInfo","file","line","transformOpenapiPaths","basePath","newPaths","keys","forEach","staticApiKey","startsWith","enhanceOpenApiWithSourceInfo","options","startTime","Date","now","openapiPath","path","resolve","__dirname","serverDir","writeFile","openapi","openapiData","JSON","parse","stringify","openapiContent","fs","readFile","controllerFiles","findControllerFiles","sourceMap","buildSourceMap","processControllerFile","enhanced","enhanceOpenApiPaths","duration","stats","controllersFound","length","endpointsExtracted","size","endpointsEnhanced","filePath","relativePath","relative","process","cwd","content","sourceFile","ts","createSourceFile","ScriptTarget","Latest","extractControllerMetadata","metadata","Map","controllerPath","className","getDecorators","node","Array","isArray","modifiers","filter","mod","kind","SyntaxKind","Decorator","decorators","visit","isClassDeclaration","name","getText","decorator","isCallExpression","expression","decoratorName","arguments","arg","isStringLiteral","text","isMethodDeclaration","methodName","httpMethod","routePath","line","getLineAndCharacterOfPosition","getStart","includes","toLowerCase","operationId","set","file","method","forEachChild","HTTP_DECORATOR_NAMES","findControllerFilesSync","dir","files","scan","currentDir","entries","readdirSync","withFileTypes","entry","fullPath","join","isDirectory","isFile","endsWith","push","normalizeApiPath","combined","normalized","replace","startsWith","slice","parseControllerRoutes","readFileSync","routes","getDecoratorsCompat","getStringArg","expr","dec","member","members","toUpperCase","parseApiRoutes","resolvedDir","createOpenapiHandler","openapiFilePath","enableEnhancement","serverDir","cache","_req","res","context","fileBuffer","fs","readFile","currentHash","crypto","createHash","update","digest","fileHash","json","data","payload","JSON","parse","isDev","openapi","enhancedPayload","stats","enhanceOpenApiWithSourceInfo","openapiData","writeFile","rootDir","console","log","duration","endpointsEnhanced","result","transformOpenapiPaths","basePath","error","message","Error","status","import_promises","import_node_crypto","MAX_REF_DEPTH","EMPTY_OPENAPI_SPEC","openapi","info","title","version","paths","components","schemas","createOpenapiSpecHandler","openapiSpecFilePath","cache","_req","res","context","fileBuffer","fs","readFile","err","code","json","currentHash","crypto","createHash","update","digest","fileHash","data","parsed","JSON","parse","message","Error","status","error","result","buildFilteredSpec","basePath","spec","globalPrefix","filteredPaths","cleanPrefix","replace","pathKey","methods","Object","entries","cleanPath","stripPrefix","startsWith","method","operation","includes","resolveRefsDeep","structuredClone","resolveAllSchemaRefs","pathStr","prefix","slice","length","obj","depth","undefined","Array","isArray","map","item","record","resolved","resolveRef","key","value","ref","name","schema","createOpenapiRouter","options","context","openapiFilePath","openapiSpecFilePath","enableEnhancement","serverDir","router","express","Router","handler","createOpenapiHandler","get","req","res","specHandler","createOpenapiSpecHandler","OPENAPI_ROUTES","method","path","description","createOpenapiMiddleware","options","openapiFilePath","openapiSpecFilePath","enableEnhancement","serverDir","routes","filter","route","name","mountPath","enabled","context","isDev","createRouter","createOpenapiRouter","import_express","import_node_fs","import_node_path","pathPatternToRegex","pattern","regexPattern","replace","RegExp","matchesPathPattern","actualPath","normalizedActual","normalizePathForMatching","normalizedPattern","hasSpecialPatterns","regex","test","hasSpecialPatterns","pattern","test","normalizePathForMatching","path","replace","resolveLogDir","provided","join","process","cwd","isAbsolute","getRelativePath","filePath","relative","fileExists","fs","access","parseLogLine","line","trimmed","trim","undefined","JSON","parse","extractNumber","message","pattern","match","value","Number","isFinite","parseLimit","defaultValue","maxValue","parsed","Math","min","floor","parsePositiveInt","fallback","resolveLogFilePath","baseDir","fileName","sanitized","replace","segments","split","filter","Boolean","some","segment","Error","resolved","rel","startsWith","matchesPath","actualPath","matchesPathPattern","matchesMethod","actualMethod","expectedMethod","toUpperCase","serializeError","error","name","String","import_node_path","import_node_fs","readFileReverse","filePath","chunkSize","processLine","handle","fs","open","stats","stat","position","size","remainder","length","Math","min","buffer","Buffer","alloc","read","chunk","toString","lines","split","shift","i","close","buildPaginatedResponse","items","page","pageSize","totalItems","totalPages","ceil","startIndex","endIndex","pagedItems","slice","map","builder","traceId","method","path","startTime","endTime","statusCode","durationMs","entries","reverse","totalCalls","calls","generateUUID","replace","c","r","Math","random","v","toString","mapPinoLevelToServerLogLevel","pinoLevel","lower","toLowerCase","extractLogLevel","text","includes","parsePinoLog","line","source","pinoLog","JSON","parse","id","level","timestamp","Date","time","getTime","message","msg","context","traceId","trace_id","userId","user_id","appId","app_id","tenantId","tenant_id","stack","meta","pid","hostname","path","method","statusCode","status_code","durationMs","duration_ms","ip","pageRoute","page_route","requestBody","request_body","responseBody","response_body","queryParams","query_params","tags","error","parseStdLog","match","now","timeStr","content","isoStr","isNaN","import_node_fs","readLogEntriesByTrace","filePath","traceId","limit","exists","fileExists","undefined","matches","stream","createReadStream","encoding","rl","createInterface","input","crlfDelay","Infinity","line","entry","parseLogLine","trace_id","push","length","shift","close","readRecentTraceCalls","page","pageSize","pathFilter","methodFilter","config","maxEntriesPerTrace","chunkSize","builders","Map","completedCalls","createTraceBuilder","entries","method","path","startTime","endTime","statusCode","durationMs","hasCompleted","updateBuilderMetadata","builder","String","handleRequestCompleted","message","time","status_code","extractNumber","duration_ms","pathMatches","matchesPath","methodMatches","matchesMethod","shouldInclude","processLogEntry","get","set","includes","processLine","readFileReverse","buildPaginatedResponse","readLogFilePage","capacity","buffer","totalLines","totalPages","Math","ceil","lines","startIndex","max","endIndex","bufferStartIndex","i","lineIndex","reverse","import_node_fs","import_node_readline","import_node_path","readServerLogs","logDir","options","limit","offset","sources","allLogs","errors","source","logs","readLogsBySource","push","error","errorMsg","Error","message","String","console","warn","length","join","undefined","filteredLogs","levels","filter","log","includes","level","sort","a","b","timestamp","total","paginatedLogs","slice","hasMore","filePath","parser","line","parsePinoLog","parseStdLog","fileExists","stream","rl","createReadStream","encoding","createInterface","input","crlfDelay","Infinity","trim","parseError","close","import_node_fs","import_node_readline","readTriggerList","filePath","trigger","path","limit","triggerID","fileExists","undefined","config","maxEntriesPerTrace","chunkSize","builders","Map","completedCalls","createTraceBuilder","traceId","entries","method","startTime","endTime","statusCode","durationMs","hasCompleted","shouldIncludeInCompletedCalls","builder","alreadyAdded","some","call","isAutomationTrigger","endsWith","length","requestEntry","find","e","request_body","String","updateBuilderMetadata","entry","push","shift","pop","handleRequestCompleted","message","time","extractNumber","processLogEntry","trace_id","get","set","includes","processLine","line","parseLogLine","readFileReverse","page","pageSize","totalCalls","totalPages","calls","map","slice","reverse","readTriggerDetail","instanceID","exists","matches","stream","createReadStream","encoding","rl","createInterface","input","crlfDelay","Infinity","hasInstanceID","instance_id","close","readCapabilityTraceList","filePath","capabilityId","limit","fileExists","undefined","config","chunkSize","builders","Map","completedTraces","createCapabilityTraceBuilder","traceId","capId","hasCompleted","hasStartEntry","shouldIncludeInCompletedTraces","builder","alreadyAdded","some","trace","updateBuilderMetadata","entry","plugin_key","pluginKey","String","action","message","includes","startTime","time","input","endTime","status","output","duration_ms","durationMs","Number","push","error","processLogEntry","trace_id","capability_id","get","set","processLine","line","parseLogLine","readFileReverse","sort","a","b","timeA","Date","getTime","timeB","limitedTraces","slice","totalTraces","length","traces","map","handleNotFound","res","filePath","message","status","json","getRelativePath","handleError","error","serializeError","createGetTraceEntriesHandler","logDir","appLogPath","join","req","traceId","params","trim","limit","parseLimit","query","entries","readLogEntriesByTrace","file","count","length","createGetRecentTracesHandler","traceLogPath","page","parsePositiveInt","pageSize","pathFilter","path","undefined","methodFilter","method","toUpperCase","result","readRecentTraceCalls","calls","createGetLogFileHandler","fileName","resolveLogFilePath","readLogFilePage","createGetServerLogsHandler","offset","levels","String","split","map","l","filter","Boolean","sources","s","readServerLogs","hint","createGetTriggerListHandler","trigger","triggerID","readTriggerList","createGetTriggerDetailHandler","instanceID","readTriggerDetail","createGetCapabilityTraceListHandler","serverLogPath","capabilityId","capability_id","readCapabilityTraceList","checkServiceHealth","host","port","timeout","Promise","resolve","startTime","Date","now","req","http","request","hostname","path","method","_res","responseTime","available","on","destroy","error","err","message","end","createHealthCheckHandler","options","targetPort","Number","process","env","SERVER_PORT","targetHost","_req","res","result","status","json","service","timestamp","toISOString","Error","fs","path","mapPinoLevelToServerLogLevel","pinoLevel","lower","toLowerCase","extractLogLevel","text","includes","generateUUID","replace","c","r","Math","random","v","toString","parsePinoLog","line","source","pinoLog","JSON","parse","id","level","timestamp","Date","time","getTime","message","msg","context","traceId","trace_id","userId","user_id","appId","app_id","tenantId","tenant_id","stack","meta","pid","hostname","path","method","statusCode","status_code","durationMs","duration_ms","ip","pageRoute","page_route","requestBody","request_body","responseBody","response_body","queryParams","query_params","tags","parseStdLog","match","now","timeStr","content","isoStr","isNaN","LogWatcher","logDir","watchers","Map","filePositions","subscribers","Set","isRunning","debug","logFiles","fileName","parser","options","log","args","console","start","config","watchFile","stop","Array","from","entries","forEach","watcher","close","clear","onLog","callback","add","size","delete","getSubscriberCount","filePath","join","existsSync","stats","statSync","set","error","watch","eventType","handleFileChange","on","restartWatcher","existingWatcher","get","setTimeout","lastPosition","currentSize","readSize","buffer","Buffer","alloc","fd","openSync","fs","readSync","closeSync","lines","split","trim","notifySubscribers","subscriber","ClientManager","clients","Map","debug","options","log","args","console","generateClientId","Date","now","Math","random","toString","substring","addClient","id","res","set","connectedAt","size","removeClient","has","delete","getClientCount","hasClient","sendToClient","clientId","event","data","client","get","message","formatSSEMessage","write","error","broadcast","failedClients","Array","from","entries","forEach","push","jsonData","JSON","stringify","getClientIds","keys","getClientInfo","closeAll","end","clear","createSSEHandler","logDir","options","debug","heartbeatInterval","logWatcher","LogWatcher","clientManager","ClientManager","log","args","console","req","res","setHeader","setTimeout","clientId","generateClientId","addClient","getClientCount","start","unsubscribe","onLog","logEntry","sendToClient","timestamp","Date","now","heartbeat","setInterval","success","clearInterval","cleanup","removeClient","stop","on","error","SERVER_PORT","process","env","extractModuleFromPath","path","segments","split","filter","Boolean","startIndex","match","moduleName","startsWith","generateRouteId","method","cleanPath","replace","toLowerCase","capitalize","str","charAt","toUpperCase","slice","groupRoutesByModule","routes","groupMap","Map","forEach","route","existing","get","module","push","set","groups","apis","id","name","sort","a","b","localeCompare","fetchRoutesFromBackend","basePath","normalizedBasePath","url","response","fetch","headers","ok","Error","status","data","json","routeConfig","Array","isArray","console","warn","debugRoutes","includes","map","apiPathMatch","apiPath","createApiListHandler","_req","res","CLIENT_BASE_PATH","total","length","error","message","createDevLogRouter","options","logDir","resolveLogDir","router","express","Router","get","createGetTraceEntriesHandler","createGetRecentTracesHandler","createGetLogFileHandler","createGetServerLogsHandler","createSSEHandler","createGetTriggerListHandler","createGetTriggerDetailHandler","createGetCapabilityTraceListHandler","createHealthCheckHandler","createApiListHandler","DEV_LOGS_ROUTES","method","path","description","createDevLogsMiddleware","options","logDir","name","mountPath","routes","enabled","context","isDev","createRouter","createDevLogRouter","import_express","import_path","import_fs","import_node_path","import_node_fs","resolveLogDir","provided","join","process","cwd","isAbsolute","ensureDir","dir","fs","existsSync","mkdirSync","recursive","serializeError","error","Error","name","message","String","collectLogsHandler","logDir","fileName","filePath","join","ensureDir","req","res","logContent","body","message","status","json","logLine","JSON","stringify","server_time","Date","toISOString","fs","promises","appendFile","success","error","handleError","collectLogsBatchHandler","logContents","Array","isArray","logLines","push","serializeError","DEFAULT_BODY_SIZE_LIMIT","getBodySizeLimit","process","env","BODY_SIZE_LIMIT","createDevLogRouter","options","logDir","resolveLogDir","router","express","Router","bodyLimit","post","json","limit","collectLogsHandler","fileName","collectLogsBatchHandler","DEV_LOGS_ROUTES","method","path","description","createCollectLogsMiddleware","options","logDir","name","mountPath","routes","enabled","context","isDev","createRouter","createDevLogRouter","fileName","sendJson","res","data","statusCode","statusFn","status","jsonFn","json","call","setHeader","end","JSON","stringify","sendError","message","error","errorData","serializeError","sendSuccess","success","getQuery","req","query","url","URL","headers","host","Object","fromEntries","searchParams","entries","getQueryParam","key","Error","name","stack","String","enhanceForCompat","req","res","status","code","statusCode","json","data","setHeader","end","JSON","stringify","send","String","query","url","URL","headers","host","Object","fromEntries","searchParams","entries","isConnectServer","server","isRouteMiddleware","middleware","createRouter","undefined","isGlobalMiddleware","createHandler","computeMountPath","basePath","mountPath","routePath","path","posix","join","startsWith","logMiddlewareRegistration","fullMountPath","routes","length","console","log","name","forEach","route","method","description","registerRouteMiddleware","context","error","router","use","registerGlobalMiddleware","warn","handler","registerMiddlewares","middlewares","options","isDev","process","env","NODE_ENV","rootDir","cwd","next","allMiddlewares","enabled","hasCreateRouter","hasCreateHandler","fs","path","crypto","traverse","_traverse","default","routeParserLog","level","message","args","prefix","logMessage","console","warn","error","info","log","calculateFileHash","filePath","content","readFileSync","createHash","update","digest","isRouteComponent","openingElement","isJSXIdentifier","name","evaluateTemplateLiteral","templateLiteral","quasis","expressions","length","value","raw","map","q","join","extractPageRouteInfo","routeInfo","attributes","forEach","attr","isJSXAttribute","isStringLiteral","isJSXExpressionContainer","expression","isTemplateLiteral","buildFullPath","routeStack","currentRoute","fullPath","i","path","parentPath","startsWith","endsWith","slice","index","routePath","parseRoutesFromFile","appPath","basePath","options","applyBasePath","defaultPath","appFilePath","resolve","process","cwd","existsSync","Error","sourceCode","ast","parse","sourceType","plugins","routeSet","Set","JSXElement","enter","nodePath","node","push","exit","pop","add","routes","Array","from"]}