{"version":3,"sources":["../src/index.ts","../src/tools/getTextTool.ts","../src/tools/getTextTool.schema.ts"],"sourcesContent":["// src/index.ts for @sylphlab/mcp-pdf-core\n\n// Export the tool implementation, Zod schema, core function, and inferred types\nexport { getTextTool, extractPdfText } from './tools/getTextTool.js';\nexport { getTextToolInputSchema } from './tools/getTextTool.schema.js'; // Export schema from schema file\nexport type { GetTextToolInput, GetTextToolOutput } from './tools/getTextTool.js';\n","import { readFile } from 'node:fs/promises';\nimport { defineTool } from '@sylphlab/mcp-core'; // Import the helper\nimport {\n  type BaseMcpToolOutput,\n  type McpTool, // McpTool might not be needed directly\n  type McpToolExecuteOptions,\n  McpToolInput, // McpToolInput might not be needed directly\n  validateAndResolvePath,\n} from '@sylphlab/mcp-core';\nimport * as mupdfjs from 'mupdf/mupdfjs';\nimport type { z } from 'zod';\nimport { type GetTextItemSchema, getTextToolInputSchema } from './getTextTool.schema.js'; // Import schema (added .js)\n\n// --- Core Logic Function ---\n\n/**\n * Extracts text content from a PDF buffer using MuPDF.\n * @param pdfBuffer Buffer containing the PDF data.\n * @returns A promise resolving to the extracted text content.\n * @throws If PDF parsing or text extraction fails.\n */\nexport async function extractPdfText(pdfBuffer: Buffer): Promise<string> {\n  const doc = mupdfjs.PDFDocument.openDocument(pdfBuffer, 'application/pdf');\n  const numPages = doc.countPages();\n  const pageTexts: string[] = [];\n\n  for (let i = 0; i < numPages; i++) {\n    const page = doc.loadPage(i);\n    pageTexts.push(page.getText());\n    // Note: You can also use page.getText('text') for more control over text extraction\n  }\n\n  return pageTexts.join('\\n').trim();\n}\n\n// --- TypeScript Types ---\nexport type GetTextInputItem = z.infer<typeof GetTextItemSchema>;\nexport type GetTextToolInput = z.infer<typeof getTextToolInputSchema>;\n\n// Interface for a single PDF text extraction result item\nexport interface GetTextResultItem {\n  id?: string;\n  success: boolean;\n  result?: string; // Extracted text\n  error?: string;\n  suggestion?: string;\n}\n\n// Output interface for the tool (includes multiple results)\nexport interface GetTextToolOutput extends BaseMcpToolOutput {\n  results: GetTextResultItem[];\n  error?: string; // Optional overall error if the tool itself fails unexpectedly\n}\n\n// --- Helper Function ---\n\n// Helper function to process a single PDF text extraction item\nasync function processSinglePdfGetText(\n  item: GetTextInputItem,\n  options: McpToolExecuteOptions, // Use options object\n): Promise<GetTextResultItem> {\n  const { id, filePath: inputFilePath } = item;\n  const resultItem: GetTextResultItem = { id, success: false };\n  const { workspaceRoot, allowOutsideWorkspace } = options; // Extract from options\n\n  // --- Path Validation ---\n  const validationResult = validateAndResolvePath(\n    inputFilePath,\n    workspaceRoot,\n    allowOutsideWorkspace,\n  ); // Use extracted values\n  if (typeof validationResult !== 'string') {\n    resultItem.error = validationResult.error;\n    resultItem.suggestion = validationResult.suggestion;\n    return resultItem; // Return early with validation error\n  }\n  const resolvedPath = validationResult;\n  // --- End Path Validation ---\n\n  try {\n    const buffer = await readFile(resolvedPath);\n    const extractedText = await extractPdfText(buffer); // Call the core function\n    resultItem.success = true;\n    resultItem.result = extractedText;\n    resultItem.suggestion = 'Successfully extracted text from PDF.';\n  } catch (e: unknown) {\n    // console.log(e); // Removed console.log\n    // Check if e is an object with a code property before accessing it\n    if (e && typeof e === 'object' && 'code' in e) {\n      if (e.code === 'ENOENT') {\n        resultItem.error = `File not found: ${inputFilePath}`;\n        resultItem.suggestion = 'Ensure the file path is correct and the file exists.';\n      } else if (e.code === 'EACCES') {\n        resultItem.error = `Permission denied: Cannot read file ${inputFilePath}`;\n        resultItem.suggestion = 'Check file read permissions.';\n      } else {\n        // Handle other errors with a code property if necessary, or fall through\n        const message = e instanceof Error ? e.message : String(e);\n        resultItem.error = `Failed to get text from PDF '${inputFilePath}': ${message}`;\n        resultItem.suggestion =\n          'Ensure the file is a valid PDF and not corrupted. Check file permissions.';\n      }\n    } else {\n      // Catch errors from readFile or extractPdfText (likely Error instances)\n      const message = e instanceof Error ? e.message : String(e);\n      resultItem.error = `Failed to get text from PDF '${inputFilePath}': ${message}`;\n      resultItem.suggestion =\n        'Ensure the file is a valid PDF and not corrupted. Check file permissions.';\n    }\n    // Ensure success is false if an error occurred\n    resultItem.success = false;\n  }\n  return resultItem;\n}\n\n// --- Tool Definition using defineTool ---\nexport const getTextTool = defineTool({\n  name: 'getText',\n  description: 'Extracts text content from one or more PDF files.',\n  inputSchema: getTextToolInputSchema, // Schema expects { items: [...] }\n\n  execute: async ( // Core logic passed to defineTool\n    input: GetTextToolInput,\n    options: McpToolExecuteOptions, // Options are received here\n  ): Promise<GetTextToolOutput> => { // Still returns the specific output type\n\n    // Input validation is handled by registerTools/SDK\n    const { items } = input;\n\n    const results: GetTextResultItem[] = [];\n    let overallSuccess = true; // Assume success until a failure occurs\n\n    // Removed the outermost try/catch block; defineTool handles unexpected errors\n\n    // Process requests sequentially\n    for (const item of items) {\n      // processSinglePdfGetText handles its own errors for individual file processing\n      const result = await processSinglePdfGetText(item, options);\n      results.push(result);\n      if (!result.success) {\n        overallSuccess = false; // Mark overall as failed if any item fails\n      }\n    }\n\n    // Serialize the detailed results into the content field\n    const contentText = JSON.stringify(\n      {\n        summary: `Processed ${items.length} PDF text extraction requests. Overall success: ${overallSuccess}`,\n        results: results,\n      },\n      null,\n      2,\n    );\n\n    // Return the specific output structure\n    return {\n      success: overallSuccess,\n      results: results,\n      content: [{ type: 'text', text: contentText }],\n    };\n  },\n});\n\n// Ensure necessary types are still exported\n// export type { GetTextToolInput, GetTextToolOutput, GetTextResultItem, GetTextInputItem }; // Removed duplicate export\n","import { z } from 'zod';\n\n// Schema for a single PDF text extraction item\nexport const GetTextItemSchema = z.object({\n  id: z.string().optional(),\n  filePath: z.string().min(1, 'filePath cannot be empty.'),\n  // Add options like page range later if needed\n});\n\n// Main input schema: an array of PDF items\nexport const getTextToolInputSchema = z.object({\n  items: z.array(GetTextItemSchema).min(1, 'At least one PDF item is required.'),\n  // allowOutsideWorkspace is handled by McpToolExecuteOptions\n});\n"],"mappings":"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","names":["import_mcp_core"]}