@cyanheads/mcp-ts-core 0.1.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +583 -0
- package/LICENSE +201 -0
- package/README.md +287 -0
- package/biome.json +103 -0
- package/dist/app.d.ts +82 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +222 -0
- package/dist/app.js.map +1 -0
- package/dist/cli/init.d.ts +8 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +161 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/config/index.d.ts +349 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +464 -0
- package/dist/config/index.js.map +1 -0
- package/dist/context.d.ts +119 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +144 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/prompts/prompt-registration.d.ts +33 -0
- package/dist/mcp-server/prompts/prompt-registration.d.ts.map +1 -0
- package/dist/mcp-server/prompts/prompt-registration.js +91 -0
- package/dist/mcp-server/prompts/prompt-registration.js.map +1 -0
- package/dist/mcp-server/prompts/utils/newPromptDefinition.d.ts +49 -0
- package/dist/mcp-server/prompts/utils/newPromptDefinition.d.ts.map +1 -0
- package/dist/mcp-server/prompts/utils/newPromptDefinition.js +39 -0
- package/dist/mcp-server/prompts/utils/newPromptDefinition.js.map +1 -0
- package/dist/mcp-server/prompts/utils/promptDefinition.d.ts +37 -0
- package/dist/mcp-server/prompts/utils/promptDefinition.d.ts.map +1 -0
- package/dist/mcp-server/prompts/utils/promptDefinition.js +2 -0
- package/dist/mcp-server/prompts/utils/promptDefinition.js.map +1 -0
- package/dist/mcp-server/resources/resource-registration.d.ts +27 -0
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -0
- package/dist/mcp-server/resources/resource-registration.js +85 -0
- package/dist/mcp-server/resources/resource-registration.js.map +1 -0
- package/dist/mcp-server/resources/utils/newResourceDefinition.d.ts +84 -0
- package/dist/mcp-server/resources/utils/newResourceDefinition.d.ts.map +1 -0
- package/dist/mcp-server/resources/utils/newResourceDefinition.js +40 -0
- package/dist/mcp-server/resources/utils/newResourceDefinition.js.map +1 -0
- package/dist/mcp-server/resources/utils/newResourceHandlerFactory.d.ts +32 -0
- package/dist/mcp-server/resources/utils/newResourceHandlerFactory.d.ts.map +1 -0
- package/dist/mcp-server/resources/utils/newResourceHandlerFactory.js +103 -0
- package/dist/mcp-server/resources/utils/newResourceHandlerFactory.js.map +1 -0
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +94 -0
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -0
- package/dist/mcp-server/resources/utils/resourceDefinition.js +2 -0
- package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -0
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts +14 -0
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -0
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +111 -0
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -0
- package/dist/mcp-server/roots/roots-registration.d.ts +22 -0
- package/dist/mcp-server/roots/roots-registration.d.ts.map +1 -0
- package/dist/mcp-server/roots/roots-registration.js +25 -0
- package/dist/mcp-server/roots/roots-registration.js.map +1 -0
- package/dist/mcp-server/server.d.ts +34 -0
- package/dist/mcp-server/server.d.ts.map +1 -0
- package/dist/mcp-server/server.js +62 -0
- package/dist/mcp-server/server.js.map +1 -0
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts +42 -0
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.d.ts.map +1 -0
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js +70 -0
- package/dist/mcp-server/tasks/core/sessionAwareTaskStore.js.map +1 -0
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts +109 -0
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.d.ts.map +1 -0
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.js +209 -0
- package/dist/mcp-server/tasks/core/storageBackedTaskStore.js.map +1 -0
- package/dist/mcp-server/tasks/core/taskManager.d.ts +103 -0
- package/dist/mcp-server/tasks/core/taskManager.d.ts.map +1 -0
- package/dist/mcp-server/tasks/core/taskManager.js +144 -0
- package/dist/mcp-server/tasks/core/taskManager.js.map +1 -0
- package/dist/mcp-server/tasks/core/taskTypes.d.ts +11 -0
- package/dist/mcp-server/tasks/core/taskTypes.d.ts.map +1 -0
- package/dist/mcp-server/tasks/core/taskTypes.js +13 -0
- package/dist/mcp-server/tasks/core/taskTypes.js.map +1 -0
- package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts +108 -0
- package/dist/mcp-server/tasks/utils/taskToolDefinition.d.ts.map +1 -0
- package/dist/mcp-server/tasks/utils/taskToolDefinition.js +14 -0
- package/dist/mcp-server/tasks/utils/taskToolDefinition.js.map +1 -0
- package/dist/mcp-server/tools/tool-registration.d.ts +49 -0
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -0
- package/dist/mcp-server/tools/tool-registration.js +269 -0
- package/dist/mcp-server/tools/tool-registration.js.map +1 -0
- package/dist/mcp-server/tools/utils/newToolDefinition.d.ts +73 -0
- package/dist/mcp-server/tools/utils/newToolDefinition.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/newToolDefinition.js +45 -0
- package/dist/mcp-server/tools/utils/newToolDefinition.js.map +1 -0
- package/dist/mcp-server/tools/utils/newToolHandlerFactory.d.ts +33 -0
- package/dist/mcp-server/tools/utils/newToolHandlerFactory.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/newToolHandlerFactory.js +107 -0
- package/dist/mcp-server/tools/utils/newToolHandlerFactory.js.map +1 -0
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +118 -0
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/toolDefinition.js +2 -0
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -0
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts +34 -0
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +68 -0
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -0
- package/dist/mcp-server/transports/ITransport.d.ts +15 -0
- package/dist/mcp-server/transports/ITransport.d.ts.map +1 -0
- package/dist/mcp-server/transports/ITransport.js +2 -0
- package/dist/mcp-server/transports/ITransport.js.map +1 -0
- package/dist/mcp-server/transports/auth/authFactory.d.ts +11 -0
- package/dist/mcp-server/transports/auth/authFactory.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/authFactory.js +43 -0
- package/dist/mcp-server/transports/auth/authFactory.js.map +1 -0
- package/dist/mcp-server/transports/auth/authMiddleware.d.ts +24 -0
- package/dist/mcp-server/transports/auth/authMiddleware.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/authMiddleware.js +69 -0
- package/dist/mcp-server/transports/auth/authMiddleware.js.map +1 -0
- package/dist/mcp-server/transports/auth/lib/authContext.d.ts +34 -0
- package/dist/mcp-server/transports/auth/lib/authContext.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/lib/authContext.js +25 -0
- package/dist/mcp-server/transports/auth/lib/authContext.js.map +1 -0
- package/dist/mcp-server/transports/auth/lib/authTypes.d.ts +19 -0
- package/dist/mcp-server/transports/auth/lib/authTypes.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/lib/authTypes.js +2 -0
- package/dist/mcp-server/transports/auth/lib/authTypes.js.map +1 -0
- package/dist/mcp-server/transports/auth/lib/authUtils.d.ts +18 -0
- package/dist/mcp-server/transports/auth/lib/authUtils.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/lib/authUtils.js +64 -0
- package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -0
- package/dist/mcp-server/transports/auth/lib/checkScopes.d.ts +25 -0
- package/dist/mcp-server/transports/auth/lib/checkScopes.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/lib/checkScopes.js +34 -0
- package/dist/mcp-server/transports/auth/lib/checkScopes.js.map +1 -0
- package/dist/mcp-server/transports/auth/lib/claimParser.d.ts +34 -0
- package/dist/mcp-server/transports/auth/lib/claimParser.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/lib/claimParser.js +58 -0
- package/dist/mcp-server/transports/auth/lib/claimParser.js.map +1 -0
- package/dist/mcp-server/transports/auth/lib/withAuth.d.ts +25 -0
- package/dist/mcp-server/transports/auth/lib/withAuth.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/lib/withAuth.js +30 -0
- package/dist/mcp-server/transports/auth/lib/withAuth.js.map +1 -0
- package/dist/mcp-server/transports/auth/strategies/authStrategy.d.ts +18 -0
- package/dist/mcp-server/transports/auth/strategies/authStrategy.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/strategies/authStrategy.js +2 -0
- package/dist/mcp-server/transports/auth/strategies/authStrategy.js.map +1 -0
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts +14 -0
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +86 -0
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -0
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts +14 -0
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -0
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +113 -0
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -0
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts +25 -0
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/httpErrorHandler.js +112 -0
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -0
- package/dist/mcp-server/transports/http/httpTransport.d.ts +47 -0
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/httpTransport.js +396 -0
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -0
- package/dist/mcp-server/transports/http/httpTypes.d.ts +17 -0
- package/dist/mcp-server/transports/http/httpTypes.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/httpTypes.js +2 -0
- package/dist/mcp-server/transports/http/httpTypes.js.map +1 -0
- package/dist/mcp-server/transports/http/protectedResourceMetadata.d.ts +21 -0
- package/dist/mcp-server/transports/http/protectedResourceMetadata.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/protectedResourceMetadata.js +44 -0
- package/dist/mcp-server/transports/http/protectedResourceMetadata.js.map +1 -0
- package/dist/mcp-server/transports/http/sessionIdUtils.d.ts +33 -0
- package/dist/mcp-server/transports/http/sessionIdUtils.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/sessionIdUtils.js +54 -0
- package/dist/mcp-server/transports/http/sessionIdUtils.js.map +1 -0
- package/dist/mcp-server/transports/http/sessionStore.d.ts +87 -0
- package/dist/mcp-server/transports/http/sessionStore.d.ts.map +1 -0
- package/dist/mcp-server/transports/http/sessionStore.js +209 -0
- package/dist/mcp-server/transports/http/sessionStore.js.map +1 -0
- package/dist/mcp-server/transports/manager.d.ts +22 -0
- package/dist/mcp-server/transports/manager.d.ts.map +1 -0
- package/dist/mcp-server/transports/manager.js +62 -0
- package/dist/mcp-server/transports/manager.js.map +1 -0
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts +44 -0
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -0
- package/dist/mcp-server/transports/stdio/stdioTransport.js +63 -0
- package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -0
- package/dist/services/graph/core/GraphService.d.ts +205 -0
- package/dist/services/graph/core/GraphService.d.ts.map +1 -0
- package/dist/services/graph/core/GraphService.js +231 -0
- package/dist/services/graph/core/GraphService.js.map +1 -0
- package/dist/services/graph/core/IGraphProvider.d.ts +295 -0
- package/dist/services/graph/core/IGraphProvider.d.ts.map +1 -0
- package/dist/services/graph/core/IGraphProvider.js +8 -0
- package/dist/services/graph/core/IGraphProvider.js.map +1 -0
- package/dist/services/graph/types.d.ts +107 -0
- package/dist/services/graph/types.d.ts.map +1 -0
- package/dist/services/graph/types.js +8 -0
- package/dist/services/graph/types.js.map +1 -0
- package/dist/services/llm/core/ILlmProvider.d.ts +86 -0
- package/dist/services/llm/core/ILlmProvider.d.ts.map +1 -0
- package/dist/services/llm/core/ILlmProvider.js +2 -0
- package/dist/services/llm/core/ILlmProvider.js.map +1 -0
- package/dist/services/llm/providers/openrouter.provider.d.ts +187 -0
- package/dist/services/llm/providers/openrouter.provider.d.ts.map +1 -0
- package/dist/services/llm/providers/openrouter.provider.js +302 -0
- package/dist/services/llm/providers/openrouter.provider.js.map +1 -0
- package/dist/services/llm/types.d.ts +16 -0
- package/dist/services/llm/types.d.ts.map +1 -0
- package/dist/services/llm/types.js +9 -0
- package/dist/services/llm/types.js.map +1 -0
- package/dist/services/speech/core/ISpeechProvider.d.ts +92 -0
- package/dist/services/speech/core/ISpeechProvider.d.ts.map +1 -0
- package/dist/services/speech/core/ISpeechProvider.js +34 -0
- package/dist/services/speech/core/ISpeechProvider.js.map +1 -0
- package/dist/services/speech/core/SpeechService.d.ts +87 -0
- package/dist/services/speech/core/SpeechService.d.ts.map +1 -0
- package/dist/services/speech/core/SpeechService.js +135 -0
- package/dist/services/speech/core/SpeechService.js.map +1 -0
- package/dist/services/speech/providers/elevenlabs.provider.d.ts +77 -0
- package/dist/services/speech/providers/elevenlabs.provider.d.ts.map +1 -0
- package/dist/services/speech/providers/elevenlabs.provider.js +199 -0
- package/dist/services/speech/providers/elevenlabs.provider.js.map +1 -0
- package/dist/services/speech/providers/whisper.provider.d.ts +94 -0
- package/dist/services/speech/providers/whisper.provider.d.ts.map +1 -0
- package/dist/services/speech/providers/whisper.provider.js +240 -0
- package/dist/services/speech/providers/whisper.provider.js.map +1 -0
- package/dist/services/speech/types.d.ts +173 -0
- package/dist/services/speech/types.d.ts.map +1 -0
- package/dist/services/speech/types.js +8 -0
- package/dist/services/speech/types.js.map +1 -0
- package/dist/storage/core/IStorageProvider.d.ts +159 -0
- package/dist/storage/core/IStorageProvider.d.ts.map +1 -0
- package/dist/storage/core/IStorageProvider.js +2 -0
- package/dist/storage/core/IStorageProvider.js.map +1 -0
- package/dist/storage/core/StorageService.d.ts +22 -0
- package/dist/storage/core/StorageService.d.ts.map +1 -0
- package/dist/storage/core/StorageService.js +151 -0
- package/dist/storage/core/StorageService.js.map +1 -0
- package/dist/storage/core/storageFactory.d.ts +66 -0
- package/dist/storage/core/storageFactory.d.ts.map +1 -0
- package/dist/storage/core/storageFactory.js +122 -0
- package/dist/storage/core/storageFactory.js.map +1 -0
- package/dist/storage/core/storageValidation.d.ts +77 -0
- package/dist/storage/core/storageValidation.d.ts.map +1 -0
- package/dist/storage/core/storageValidation.js +303 -0
- package/dist/storage/core/storageValidation.js.map +1 -0
- package/dist/storage/providers/cloudflare/d1Provider.d.ts +94 -0
- package/dist/storage/providers/cloudflare/d1Provider.d.ts.map +1 -0
- package/dist/storage/providers/cloudflare/d1Provider.js +347 -0
- package/dist/storage/providers/cloudflare/d1Provider.js.map +1 -0
- package/dist/storage/providers/cloudflare/kvProvider.d.ts +21 -0
- package/dist/storage/providers/cloudflare/kvProvider.d.ts.map +1 -0
- package/dist/storage/providers/cloudflare/kvProvider.js +183 -0
- package/dist/storage/providers/cloudflare/kvProvider.js.map +1 -0
- package/dist/storage/providers/cloudflare/r2Provider.d.ts +28 -0
- package/dist/storage/providers/cloudflare/r2Provider.d.ts.map +1 -0
- package/dist/storage/providers/cloudflare/r2Provider.js +222 -0
- package/dist/storage/providers/cloudflare/r2Provider.js.map +1 -0
- package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts +20 -0
- package/dist/storage/providers/fileSystem/fileSystemProvider.d.ts.map +1 -0
- package/dist/storage/providers/fileSystem/fileSystemProvider.js +282 -0
- package/dist/storage/providers/fileSystem/fileSystemProvider.js.map +1 -0
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts +21 -0
- package/dist/storage/providers/inMemory/inMemoryProvider.d.ts.map +1 -0
- package/dist/storage/providers/inMemory/inMemoryProvider.js +139 -0
- package/dist/storage/providers/inMemory/inMemoryProvider.js.map +1 -0
- package/dist/storage/providers/supabase/supabase.types.d.ts +49 -0
- package/dist/storage/providers/supabase/supabase.types.d.ts.map +1 -0
- package/dist/storage/providers/supabase/supabase.types.js +8 -0
- package/dist/storage/providers/supabase/supabase.types.js.map +1 -0
- package/dist/storage/providers/supabase/supabaseProvider.d.ts +24 -0
- package/dist/storage/providers/supabase/supabaseProvider.d.ts.map +1 -0
- package/dist/storage/providers/supabase/supabaseProvider.js +209 -0
- package/dist/storage/providers/supabase/supabaseProvider.js.map +1 -0
- package/dist/testing/index.d.ts +53 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +132 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-global/errors.d.ts +83 -0
- package/dist/types-global/errors.d.ts.map +1 -0
- package/dist/types-global/errors.js +113 -0
- package/dist/types-global/errors.js.map +1 -0
- package/dist/utils/formatting/diffFormatter.d.ts +227 -0
- package/dist/utils/formatting/diffFormatter.d.ts.map +1 -0
- package/dist/utils/formatting/diffFormatter.js +369 -0
- package/dist/utils/formatting/diffFormatter.js.map +1 -0
- package/dist/utils/formatting/index.d.ts +9 -0
- package/dist/utils/formatting/index.d.ts.map +1 -0
- package/dist/utils/formatting/index.js +9 -0
- package/dist/utils/formatting/index.js.map +1 -0
- package/dist/utils/formatting/markdownBuilder.d.ts +543 -0
- package/dist/utils/formatting/markdownBuilder.d.ts.map +1 -0
- package/dist/utils/formatting/markdownBuilder.js +674 -0
- package/dist/utils/formatting/markdownBuilder.js.map +1 -0
- package/dist/utils/formatting/tableFormatter.d.ts +261 -0
- package/dist/utils/formatting/tableFormatter.d.ts.map +1 -0
- package/dist/utils/formatting/tableFormatter.js +456 -0
- package/dist/utils/formatting/tableFormatter.js.map +1 -0
- package/dist/utils/formatting/treeFormatter.d.ts +344 -0
- package/dist/utils/formatting/treeFormatter.d.ts.map +1 -0
- package/dist/utils/formatting/treeFormatter.js +400 -0
- package/dist/utils/formatting/treeFormatter.js.map +1 -0
- package/dist/utils/internal/encoding.d.ts +42 -0
- package/dist/utils/internal/encoding.d.ts.map +1 -0
- package/dist/utils/internal/encoding.js +87 -0
- package/dist/utils/internal/encoding.js.map +1 -0
- package/dist/utils/internal/error-handler/errorHandler.d.ts +140 -0
- package/dist/utils/internal/error-handler/errorHandler.d.ts.map +1 -0
- package/dist/utils/internal/error-handler/errorHandler.js +318 -0
- package/dist/utils/internal/error-handler/errorHandler.js.map +1 -0
- package/dist/utils/internal/error-handler/helpers.d.ts +98 -0
- package/dist/utils/internal/error-handler/helpers.d.ts.map +1 -0
- package/dist/utils/internal/error-handler/helpers.js +214 -0
- package/dist/utils/internal/error-handler/helpers.js.map +1 -0
- package/dist/utils/internal/error-handler/mappings.d.ts +85 -0
- package/dist/utils/internal/error-handler/mappings.d.ts.map +1 -0
- package/dist/utils/internal/error-handler/mappings.js +234 -0
- package/dist/utils/internal/error-handler/mappings.js.map +1 -0
- package/dist/utils/internal/error-handler/types.d.ts +160 -0
- package/dist/utils/internal/error-handler/types.d.ts.map +1 -0
- package/dist/utils/internal/error-handler/types.js +6 -0
- package/dist/utils/internal/error-handler/types.js.map +1 -0
- package/dist/utils/internal/health.d.ts +60 -0
- package/dist/utils/internal/health.d.ts.map +1 -0
- package/dist/utils/internal/health.js +46 -0
- package/dist/utils/internal/health.js.map +1 -0
- package/dist/utils/internal/logger.d.ts +300 -0
- package/dist/utils/internal/logger.d.ts.map +1 -0
- package/dist/utils/internal/logger.js +573 -0
- package/dist/utils/internal/logger.js.map +1 -0
- package/dist/utils/internal/performance.d.ts +78 -0
- package/dist/utils/internal/performance.d.ts.map +1 -0
- package/dist/utils/internal/performance.js +227 -0
- package/dist/utils/internal/performance.js.map +1 -0
- package/dist/utils/internal/requestContext.d.ts +200 -0
- package/dist/utils/internal/requestContext.d.ts.map +1 -0
- package/dist/utils/internal/requestContext.js +163 -0
- package/dist/utils/internal/requestContext.js.map +1 -0
- package/dist/utils/internal/runtime.d.ts +49 -0
- package/dist/utils/internal/runtime.d.ts.map +1 -0
- package/dist/utils/internal/runtime.js +90 -0
- package/dist/utils/internal/runtime.js.map +1 -0
- package/dist/utils/internal/startupBanner.d.ts +23 -0
- package/dist/utils/internal/startupBanner.d.ts.map +1 -0
- package/dist/utils/internal/startupBanner.js +34 -0
- package/dist/utils/internal/startupBanner.js.map +1 -0
- package/dist/utils/metrics/tokenCounter.d.ts +97 -0
- package/dist/utils/metrics/tokenCounter.d.ts.map +1 -0
- package/dist/utils/metrics/tokenCounter.js +162 -0
- package/dist/utils/metrics/tokenCounter.js.map +1 -0
- package/dist/utils/network/fetchWithTimeout.d.ts +91 -0
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -0
- package/dist/utils/network/fetchWithTimeout.js +305 -0
- package/dist/utils/network/fetchWithTimeout.js.map +1 -0
- package/dist/utils/pagination/pagination.d.ts +157 -0
- package/dist/utils/pagination/pagination.d.ts.map +1 -0
- package/dist/utils/pagination/pagination.js +191 -0
- package/dist/utils/pagination/pagination.js.map +1 -0
- package/dist/utils/parsing/csvParser.d.ts +84 -0
- package/dist/utils/parsing/csvParser.d.ts.map +1 -0
- package/dist/utils/parsing/csvParser.js +132 -0
- package/dist/utils/parsing/csvParser.js.map +1 -0
- package/dist/utils/parsing/dateParser.d.ts +103 -0
- package/dist/utils/parsing/dateParser.d.ts.map +1 -0
- package/dist/utils/parsing/dateParser.js +142 -0
- package/dist/utils/parsing/dateParser.js.map +1 -0
- package/dist/utils/parsing/frontmatterParser.d.ts +91 -0
- package/dist/utils/parsing/frontmatterParser.d.ts.map +1 -0
- package/dist/utils/parsing/frontmatterParser.js +163 -0
- package/dist/utils/parsing/frontmatterParser.js.map +1 -0
- package/dist/utils/parsing/index.d.ts +15 -0
- package/dist/utils/parsing/index.d.ts.map +1 -0
- package/dist/utils/parsing/index.js +15 -0
- package/dist/utils/parsing/index.js.map +1 -0
- package/dist/utils/parsing/jsonParser.d.ts +115 -0
- package/dist/utils/parsing/jsonParser.d.ts.map +1 -0
- package/dist/utils/parsing/jsonParser.js +177 -0
- package/dist/utils/parsing/jsonParser.js.map +1 -0
- package/dist/utils/parsing/pdfParser.d.ts +563 -0
- package/dist/utils/parsing/pdfParser.d.ts.map +1 -0
- package/dist/utils/parsing/pdfParser.js +775 -0
- package/dist/utils/parsing/pdfParser.js.map +1 -0
- package/dist/utils/parsing/thinkBlock.d.ts +31 -0
- package/dist/utils/parsing/thinkBlock.d.ts.map +1 -0
- package/dist/utils/parsing/thinkBlock.js +31 -0
- package/dist/utils/parsing/thinkBlock.js.map +1 -0
- package/dist/utils/parsing/xmlParser.d.ts +69 -0
- package/dist/utils/parsing/xmlParser.d.ts.map +1 -0
- package/dist/utils/parsing/xmlParser.js +140 -0
- package/dist/utils/parsing/xmlParser.js.map +1 -0
- package/dist/utils/parsing/yamlParser.d.ts +64 -0
- package/dist/utils/parsing/yamlParser.d.ts.map +1 -0
- package/dist/utils/parsing/yamlParser.js +129 -0
- package/dist/utils/parsing/yamlParser.js.map +1 -0
- package/dist/utils/scheduling/scheduler.d.ts +174 -0
- package/dist/utils/scheduling/scheduler.d.ts.map +1 -0
- package/dist/utils/scheduling/scheduler.js +248 -0
- package/dist/utils/scheduling/scheduler.js.map +1 -0
- package/dist/utils/security/idGenerator.d.ts +189 -0
- package/dist/utils/security/idGenerator.d.ts.map +1 -0
- package/dist/utils/security/idGenerator.js +301 -0
- package/dist/utils/security/idGenerator.js.map +1 -0
- package/dist/utils/security/index.d.ts +8 -0
- package/dist/utils/security/index.d.ts.map +1 -0
- package/dist/utils/security/index.js +8 -0
- package/dist/utils/security/index.js.map +1 -0
- package/dist/utils/security/rateLimiter.d.ts +171 -0
- package/dist/utils/security/rateLimiter.d.ts.map +1 -0
- package/dist/utils/security/rateLimiter.js +294 -0
- package/dist/utils/security/rateLimiter.js.map +1 -0
- package/dist/utils/security/sanitization.d.ts +430 -0
- package/dist/utils/security/sanitization.d.ts.map +1 -0
- package/dist/utils/security/sanitization.js +759 -0
- package/dist/utils/security/sanitization.js.map +1 -0
- package/dist/utils/telemetry/index.d.ts +12 -0
- package/dist/utils/telemetry/index.d.ts.map +1 -0
- package/dist/utils/telemetry/index.js +12 -0
- package/dist/utils/telemetry/index.js.map +1 -0
- package/dist/utils/telemetry/instrumentation.d.ts +62 -0
- package/dist/utils/telemetry/instrumentation.d.ts.map +1 -0
- package/dist/utils/telemetry/instrumentation.js +223 -0
- package/dist/utils/telemetry/instrumentation.js.map +1 -0
- package/dist/utils/telemetry/metrics.d.ts +170 -0
- package/dist/utils/telemetry/metrics.d.ts.map +1 -0
- package/dist/utils/telemetry/metrics.js +205 -0
- package/dist/utils/telemetry/metrics.js.map +1 -0
- package/dist/utils/telemetry/semconv.d.ts +147 -0
- package/dist/utils/telemetry/semconv.d.ts.map +1 -0
- package/dist/utils/telemetry/semconv.js +159 -0
- package/dist/utils/telemetry/semconv.js.map +1 -0
- package/dist/utils/telemetry/trace.d.ts +141 -0
- package/dist/utils/telemetry/trace.d.ts.map +1 -0
- package/dist/utils/telemetry/trace.js +193 -0
- package/dist/utils/telemetry/trace.js.map +1 -0
- package/dist/utils/types/guards.d.ts +209 -0
- package/dist/utils/types/guards.d.ts.map +1 -0
- package/dist/utils/types/guards.js +229 -0
- package/dist/utils/types/guards.js.map +1 -0
- package/dist/utils/types/index.d.ts +6 -0
- package/dist/utils/types/index.d.ts.map +1 -0
- package/dist/utils/types/index.js +6 -0
- package/dist/utils/types/index.js.map +1 -0
- package/dist/worker.d.ts +59 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +216 -0
- package/dist/worker.js.map +1 -0
- package/package.json +377 -0
- package/skills/README.md +38 -0
- package/skills/add-export/SKILL.md +49 -0
- package/skills/add-prompt/SKILL.md +97 -0
- package/skills/add-provider/SKILL.md +53 -0
- package/skills/add-resource/SKILL.md +107 -0
- package/skills/add-service/SKILL.md +113 -0
- package/skills/add-tool/SKILL.md +110 -0
- package/skills/api-auth/SKILL.md +173 -0
- package/skills/api-config/SKILL.md +68 -0
- package/skills/api-context/SKILL.md +321 -0
- package/skills/api-errors/SKILL.md +146 -0
- package/skills/api-services/SKILL.md +24 -0
- package/skills/api-services/references/graph.md +124 -0
- package/skills/api-services/references/llm.md +46 -0
- package/skills/api-services/references/speech.md +72 -0
- package/skills/api-testing/SKILL.md +263 -0
- package/skills/api-utils/SKILL.md +106 -0
- package/skills/api-utils/references/formatting.md +237 -0
- package/skills/api-utils/references/parsing.md +263 -0
- package/skills/api-utils/references/security.md +226 -0
- package/skills/api-workers/SKILL.md +165 -0
- package/skills/devcheck/SKILL.md +31 -0
- package/skills/maintenance/SKILL.md +52 -0
- package/skills/migrate-mcp-ts-template/SKILL.md +131 -0
- package/skills/release/SKILL.md +67 -0
- package/skills/setup/SKILL.md +89 -0
- package/skills/walkthrough-init/SKILL.md +50 -0
- package/templates/.env.example +17 -0
- package/templates/AGENTS.md +113 -0
- package/templates/CLAUDE.md +113 -0
- package/templates/_tsconfig.json +33 -0
- package/templates/biome.template.json +43 -0
- package/templates/package.json +26 -0
- package/templates/src/index.ts +16 -0
- package/templates/src/mcp-server/prompts/definitions/echo.prompt.ts +19 -0
- package/templates/src/mcp-server/resources/definitions/echo.resource.ts +30 -0
- package/templates/src/mcp-server/tools/definitions/echo.tool.ts +24 -0
- package/templates/vitest.config.ts +12 -0
- package/tsconfig.base.json +44 -0
- package/vitest.config.base.ts +38 -0
|
@@ -0,0 +1,775 @@
|
|
|
1
|
+
import { JsonRpcErrorCode, McpError } from '../../types-global/errors.js';
|
|
2
|
+
import { logger } from '../../utils/internal/logger.js';
|
|
3
|
+
import { requestContextService } from '../../utils/internal/requestContext.js';
|
|
4
|
+
let _pdfLib;
|
|
5
|
+
async function getPdfLib() {
|
|
6
|
+
_pdfLib ??= await import('pdf-lib').catch(() => {
|
|
7
|
+
throw new McpError(JsonRpcErrorCode.ConfigurationError, 'Install "pdf-lib" to use PDF operations: bun add pdf-lib');
|
|
8
|
+
});
|
|
9
|
+
return _pdfLib;
|
|
10
|
+
}
|
|
11
|
+
let _unpdf;
|
|
12
|
+
async function getUnpdf() {
|
|
13
|
+
_unpdf ??= await import('unpdf').catch(() => {
|
|
14
|
+
throw new McpError(JsonRpcErrorCode.ConfigurationError, 'Install "unpdf" to use PDF text extraction: bun add unpdf');
|
|
15
|
+
});
|
|
16
|
+
return _unpdf;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Utility class for creating, modifying, and parsing PDF documents.
|
|
20
|
+
*
|
|
21
|
+
* Wraps the `pdf-lib` library for document creation/editing and `unpdf` for text
|
|
22
|
+
* extraction (Cloudflare Workers compatible). Most methods are async due to lazy
|
|
23
|
+
* loading of these peer dependencies. Install both with:
|
|
24
|
+
* `bun add pdf-lib unpdf`
|
|
25
|
+
*/
|
|
26
|
+
export class PdfParser {
|
|
27
|
+
/**
|
|
28
|
+
* Creates a new blank PDF document.
|
|
29
|
+
*
|
|
30
|
+
* Async due to lazy loading of the `pdf-lib` peer dependency (`bun add pdf-lib`).
|
|
31
|
+
*
|
|
32
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
33
|
+
* @returns A new empty `PDFDocument` instance.
|
|
34
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
35
|
+
* @throws {McpError} With `InternalError` if document creation fails.
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const doc = await pdfParser.createDocument();
|
|
39
|
+
* const page = pdfParser.addPage(doc);
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
async createDocument(context) {
|
|
43
|
+
const logContext = context ||
|
|
44
|
+
requestContextService.createRequestContext({
|
|
45
|
+
operation: 'PdfParser.createDocument',
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
const pdfLib = await getPdfLib();
|
|
49
|
+
logger.debug('Creating new PDF document.', logContext);
|
|
50
|
+
const doc = await pdfLib.PDFDocument.create();
|
|
51
|
+
return doc;
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
55
|
+
logger.error('Failed to create PDF document.', {
|
|
56
|
+
...logContext,
|
|
57
|
+
errorDetails: error.message,
|
|
58
|
+
});
|
|
59
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to create PDF document: ${error.message}`, {
|
|
60
|
+
...context,
|
|
61
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Loads an existing PDF document from raw bytes.
|
|
67
|
+
*
|
|
68
|
+
* Async due to lazy loading of the `pdf-lib` peer dependency (`bun add pdf-lib`).
|
|
69
|
+
*
|
|
70
|
+
* @param pdfBytes - The PDF file contents as `Uint8Array` or `ArrayBuffer`.
|
|
71
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
72
|
+
* @returns The loaded `PDFDocument` instance.
|
|
73
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
74
|
+
* @throws {McpError} With `ValidationError` if the bytes are not a valid PDF.
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* import { readFile } from 'node:fs/promises';
|
|
78
|
+
* const pdfBytes = await readFile('input.pdf');
|
|
79
|
+
* const doc = await pdfParser.loadDocument(pdfBytes);
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
async loadDocument(pdfBytes, context) {
|
|
83
|
+
const logContext = context ||
|
|
84
|
+
requestContextService.createRequestContext({
|
|
85
|
+
operation: 'PdfParser.loadDocument',
|
|
86
|
+
});
|
|
87
|
+
try {
|
|
88
|
+
const pdfLib = await getPdfLib();
|
|
89
|
+
logger.debug('Loading PDF document from bytes.', {
|
|
90
|
+
...logContext,
|
|
91
|
+
byteLength: pdfBytes instanceof Uint8Array ? pdfBytes.length : pdfBytes.byteLength,
|
|
92
|
+
});
|
|
93
|
+
const doc = await pdfLib.PDFDocument.load(pdfBytes);
|
|
94
|
+
return doc;
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
98
|
+
logger.error('Failed to load PDF document.', {
|
|
99
|
+
...logContext,
|
|
100
|
+
errorDetails: error.message,
|
|
101
|
+
});
|
|
102
|
+
throw new McpError(JsonRpcErrorCode.ValidationError, `Failed to load PDF document: ${error.message}`, {
|
|
103
|
+
...context,
|
|
104
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Adds a new blank page to a PDF document.
|
|
110
|
+
*
|
|
111
|
+
* Synchronous — does not load any peer dependencies.
|
|
112
|
+
*
|
|
113
|
+
* @param doc - The `PDFDocument` to add the page to.
|
|
114
|
+
* @param options - Optional page dimensions. Defaults to US Letter (612 × 792 points).
|
|
115
|
+
* @returns The newly added `PDFPage`.
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* const page = pdfParser.addPage(doc, { width: 600, height: 400 });
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
addPage(doc, options) {
|
|
122
|
+
const width = options?.width ?? 612; // US Letter width
|
|
123
|
+
const height = options?.height ?? 792; // US Letter height
|
|
124
|
+
return doc.addPage([width, height]);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Embeds a standard PDF font into a document.
|
|
128
|
+
*
|
|
129
|
+
* `fontName` must be a key of `pdf-lib`'s `StandardFonts` enum (e.g. `'Helvetica'`,
|
|
130
|
+
* `'TimesRoman'`, `'Courier'`). Async due to lazy loading of `pdf-lib`
|
|
131
|
+
* (`bun add pdf-lib`).
|
|
132
|
+
*
|
|
133
|
+
* @param doc - The `PDFDocument` to embed the font into.
|
|
134
|
+
* @param fontName - A `StandardFonts` key. Defaults to `'Helvetica'`.
|
|
135
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
136
|
+
* @returns The embedded `PDFFont` ready to pass to `drawText`.
|
|
137
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
138
|
+
* @throws {McpError} With `InternalError` if the font name is invalid or embedding fails.
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const font = await pdfParser.embedFont(doc, 'TimesRoman');
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
async embedFont(doc, fontName = 'Helvetica', context) {
|
|
145
|
+
const logContext = context ||
|
|
146
|
+
requestContextService.createRequestContext({
|
|
147
|
+
operation: 'PdfParser.embedFont',
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
const { StandardFonts } = await getPdfLib();
|
|
151
|
+
logger.debug('Embedding standard font.', {
|
|
152
|
+
...logContext,
|
|
153
|
+
fontName,
|
|
154
|
+
});
|
|
155
|
+
const font = await doc.embedFont(StandardFonts[fontName]);
|
|
156
|
+
return font;
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
160
|
+
logger.error('Failed to embed font.', {
|
|
161
|
+
...logContext,
|
|
162
|
+
fontName,
|
|
163
|
+
errorDetails: error.message,
|
|
164
|
+
});
|
|
165
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to embed font '${fontName}': ${error.message}`, {
|
|
166
|
+
...context,
|
|
167
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Embeds a PNG or JPEG image into a PDF document for later rendering.
|
|
173
|
+
*
|
|
174
|
+
* Does not draw the image — call `drawImage` after embedding. Async due to lazy
|
|
175
|
+
* loading of `pdf-lib` (`bun add pdf-lib`).
|
|
176
|
+
*
|
|
177
|
+
* @param doc - The `PDFDocument` to embed the image into.
|
|
178
|
+
* @param options - Image bytes and format (`'png'` or `'jpg'`).
|
|
179
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
180
|
+
* @returns The embedded `PDFImage`, usable as the `image` option in `drawImage`.
|
|
181
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
182
|
+
* @throws {McpError} With `InternalError` if the image data is invalid or embedding fails.
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* import { readFile } from 'node:fs/promises';
|
|
186
|
+
* const imageBytes = await readFile('logo.png');
|
|
187
|
+
* const image = await pdfParser.embedImage(doc, { imageBytes, format: 'png' });
|
|
188
|
+
* pdfParser.drawImage(page, { image, x: 50, y: 700, width: 100, height: 50 });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
async embedImage(doc, options, context) {
|
|
192
|
+
const logContext = context ||
|
|
193
|
+
requestContextService.createRequestContext({
|
|
194
|
+
operation: 'PdfParser.embedImage',
|
|
195
|
+
});
|
|
196
|
+
try {
|
|
197
|
+
logger.debug('Embedding image into PDF.', {
|
|
198
|
+
...logContext,
|
|
199
|
+
format: options.format,
|
|
200
|
+
});
|
|
201
|
+
const image = options.format === 'png'
|
|
202
|
+
? await doc.embedPng(options.imageBytes)
|
|
203
|
+
: await doc.embedJpg(options.imageBytes);
|
|
204
|
+
return image;
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
208
|
+
logger.error('Failed to embed image.', {
|
|
209
|
+
...logContext,
|
|
210
|
+
format: options.format,
|
|
211
|
+
errorDetails: error.message,
|
|
212
|
+
});
|
|
213
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to embed ${options.format} image: ${error.message}`, {
|
|
214
|
+
...context,
|
|
215
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Draws text on a PDF page with optional font, size, color, rotation, and word-wrap.
|
|
221
|
+
*
|
|
222
|
+
* When `maxWidth` is set, the text is split into words and wrapped across multiple
|
|
223
|
+
* lines; each line is rendered at decreasing Y positions by `size * lineHeight`.
|
|
224
|
+
* Async due to lazy loading of `pdf-lib` (`bun add pdf-lib`).
|
|
225
|
+
*
|
|
226
|
+
* @param page - The `PDFPage` to draw text on.
|
|
227
|
+
* @param options - Text content, baseline position (`x`, `y`), and styling.
|
|
228
|
+
* @returns A promise that resolves when drawing is complete.
|
|
229
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const font = await pdfParser.embedFont(doc, 'Helvetica');
|
|
233
|
+
* await pdfParser.drawText(page, {
|
|
234
|
+
* text: 'Hello, World!',
|
|
235
|
+
* x: 50,
|
|
236
|
+
* y: 700,
|
|
237
|
+
* size: 30,
|
|
238
|
+
* font,
|
|
239
|
+
* color: rgb(0, 0.53, 0.71),
|
|
240
|
+
* });
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
async drawText(page, options) {
|
|
244
|
+
const pdfLib = await getPdfLib();
|
|
245
|
+
const { text, x, y, size = 12, font, rotate = 0, maxWidth, lineHeight = 1.2 } = options;
|
|
246
|
+
const color = options.color ?? pdfLib.rgb(0, 0, 0);
|
|
247
|
+
if (!maxWidth) {
|
|
248
|
+
// Simple single-line text
|
|
249
|
+
page.drawText(text, {
|
|
250
|
+
x,
|
|
251
|
+
y,
|
|
252
|
+
size,
|
|
253
|
+
color,
|
|
254
|
+
...(font && { font }),
|
|
255
|
+
...(rotate && { rotate: pdfLib.degrees(rotate) }),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// Text wrapping
|
|
260
|
+
const words = text.split(' ');
|
|
261
|
+
const lines = [];
|
|
262
|
+
let currentLine = '';
|
|
263
|
+
const effectiveFont = font || page.doc.getForm().getDefaultFont();
|
|
264
|
+
for (const word of words) {
|
|
265
|
+
const testLine = currentLine ? `${currentLine} ${word}` : word;
|
|
266
|
+
const testWidth = effectiveFont.widthOfTextAtSize(testLine, size);
|
|
267
|
+
if (testWidth <= maxWidth) {
|
|
268
|
+
currentLine = testLine;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
if (currentLine) {
|
|
272
|
+
lines.push(currentLine);
|
|
273
|
+
}
|
|
274
|
+
currentLine = word;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (currentLine) {
|
|
278
|
+
lines.push(currentLine);
|
|
279
|
+
}
|
|
280
|
+
// Draw each line
|
|
281
|
+
let currentY = y;
|
|
282
|
+
for (const line of lines) {
|
|
283
|
+
page.drawText(line, {
|
|
284
|
+
x,
|
|
285
|
+
y: currentY,
|
|
286
|
+
size,
|
|
287
|
+
color,
|
|
288
|
+
...(font && { font }),
|
|
289
|
+
...(rotate && { rotate: pdfLib.degrees(rotate) }),
|
|
290
|
+
});
|
|
291
|
+
currentY -= size * lineHeight;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Draws a previously embedded image onto a PDF page.
|
|
297
|
+
*
|
|
298
|
+
* The image must first be embedded via `embedImage`. Width and height default to the
|
|
299
|
+
* image's intrinsic dimensions. Async due to lazy loading of `pdf-lib`
|
|
300
|
+
* (`bun add pdf-lib`).
|
|
301
|
+
*
|
|
302
|
+
* @param page - The `PDFPage` to draw the image on.
|
|
303
|
+
* @param options - The embedded image, position (`x`, `y`), dimensions, opacity, and rotation.
|
|
304
|
+
* @returns A promise that resolves when drawing is complete.
|
|
305
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* const image = await pdfParser.embedImage(doc, { imageBytes, format: 'png' });
|
|
309
|
+
* await pdfParser.drawImage(page, {
|
|
310
|
+
* image,
|
|
311
|
+
* x: 100,
|
|
312
|
+
* y: 500,
|
|
313
|
+
* width: 200,
|
|
314
|
+
* height: 150,
|
|
315
|
+
* });
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
async drawImage(page, options) {
|
|
319
|
+
const pdfLib = await getPdfLib();
|
|
320
|
+
const { image, x, y, width = image.width, height = image.height, rotate = 0, opacity = 1, } = options;
|
|
321
|
+
page.drawImage(image, {
|
|
322
|
+
x,
|
|
323
|
+
y,
|
|
324
|
+
width,
|
|
325
|
+
height,
|
|
326
|
+
opacity,
|
|
327
|
+
...(rotate && { rotate: pdfLib.degrees(rotate) }),
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Merges multiple PDF documents into a single new document.
|
|
332
|
+
*
|
|
333
|
+
* Pages are appended in the order the source buffers appear in the array. Undefined
|
|
334
|
+
* or falsy entries in the array are silently skipped. Async due to lazy loading of
|
|
335
|
+
* `pdf-lib` (`bun add pdf-lib`).
|
|
336
|
+
*
|
|
337
|
+
* @param pdfBytesArray - Source PDF files as `Uint8Array` or `ArrayBuffer` elements.
|
|
338
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
339
|
+
* @returns A new `PDFDocument` containing all pages from the input documents.
|
|
340
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
341
|
+
* @throws {McpError} With `InternalError` if any source PDF is invalid or merging fails.
|
|
342
|
+
* @example
|
|
343
|
+
* ```typescript
|
|
344
|
+
* import { readFile } from 'node:fs/promises';
|
|
345
|
+
* const pdf1 = await readFile('doc1.pdf');
|
|
346
|
+
* const pdf2 = await readFile('doc2.pdf');
|
|
347
|
+
* const merged = await pdfParser.mergePdfs([pdf1, pdf2]);
|
|
348
|
+
* const bytes = await pdfParser.saveDocument(merged);
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
async mergePdfs(pdfBytesArray, context) {
|
|
352
|
+
const logContext = context ||
|
|
353
|
+
requestContextService.createRequestContext({
|
|
354
|
+
operation: 'PdfParser.mergePdfs',
|
|
355
|
+
});
|
|
356
|
+
try {
|
|
357
|
+
const pdfLib = await getPdfLib();
|
|
358
|
+
logger.debug('Merging PDF documents.', {
|
|
359
|
+
...logContext,
|
|
360
|
+
documentCount: pdfBytesArray.length,
|
|
361
|
+
});
|
|
362
|
+
const mergedPdf = await pdfLib.PDFDocument.create();
|
|
363
|
+
for (let i = 0; i < pdfBytesArray.length; i++) {
|
|
364
|
+
const pdfBytes = pdfBytesArray[i];
|
|
365
|
+
if (!pdfBytes)
|
|
366
|
+
continue;
|
|
367
|
+
const pdfDoc = await pdfLib.PDFDocument.load(pdfBytes);
|
|
368
|
+
const copiedPages = await mergedPdf.copyPages(pdfDoc, pdfDoc.getPageIndices());
|
|
369
|
+
for (const page of copiedPages)
|
|
370
|
+
mergedPdf.addPage(page);
|
|
371
|
+
}
|
|
372
|
+
logger.debug('Successfully merged PDF documents.', {
|
|
373
|
+
...logContext,
|
|
374
|
+
mergedPageCount: mergedPdf.getPageCount(),
|
|
375
|
+
});
|
|
376
|
+
return mergedPdf;
|
|
377
|
+
}
|
|
378
|
+
catch (e) {
|
|
379
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
380
|
+
logger.error('Failed to merge PDF documents.', {
|
|
381
|
+
...logContext,
|
|
382
|
+
errorDetails: error.message,
|
|
383
|
+
});
|
|
384
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to merge PDFs: ${error.message}`, {
|
|
385
|
+
...context,
|
|
386
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Splits a PDF document into multiple new documents based on page ranges.
|
|
392
|
+
*
|
|
393
|
+
* Each `PageRange` produces one output `PDFDocument` containing the pages from
|
|
394
|
+
* `start` to `end` (both 0-based, inclusive). Ranges may overlap. Async due to
|
|
395
|
+
* lazy loading of `pdf-lib` (`bun add pdf-lib`).
|
|
396
|
+
*
|
|
397
|
+
* @param pdfBytes - The source PDF as `Uint8Array` or `ArrayBuffer`.
|
|
398
|
+
* @param ranges - Page ranges to extract; each produces one output document.
|
|
399
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
400
|
+
* @returns An array of new `PDFDocument` instances, one per range, in order.
|
|
401
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` is not installed.
|
|
402
|
+
* @throws {McpError} With `InternalError` if the source PDF is invalid or a page index is out of bounds.
|
|
403
|
+
* @example
|
|
404
|
+
* ```typescript
|
|
405
|
+
* import { readFile } from 'node:fs/promises';
|
|
406
|
+
* const pdfBytes = await readFile('document.pdf');
|
|
407
|
+
* const [part1, part2] = await pdfParser.splitPdf(pdfBytes, [
|
|
408
|
+
* { start: 0, end: 4 },
|
|
409
|
+
* { start: 5, end: 9 },
|
|
410
|
+
* ]);
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
async splitPdf(pdfBytes, ranges, context) {
|
|
414
|
+
const logContext = context ||
|
|
415
|
+
requestContextService.createRequestContext({
|
|
416
|
+
operation: 'PdfParser.splitPdf',
|
|
417
|
+
});
|
|
418
|
+
try {
|
|
419
|
+
const pdfLib = await getPdfLib();
|
|
420
|
+
logger.debug('Splitting PDF document.', {
|
|
421
|
+
...logContext,
|
|
422
|
+
rangeCount: ranges.length,
|
|
423
|
+
});
|
|
424
|
+
const sourcePdf = await pdfLib.PDFDocument.load(pdfBytes);
|
|
425
|
+
const results = [];
|
|
426
|
+
for (const range of ranges) {
|
|
427
|
+
const newPdf = await pdfLib.PDFDocument.create();
|
|
428
|
+
const pageIndices = [];
|
|
429
|
+
for (let i = range.start; i <= range.end; i++) {
|
|
430
|
+
pageIndices.push(i);
|
|
431
|
+
}
|
|
432
|
+
const copiedPages = await newPdf.copyPages(sourcePdf, pageIndices);
|
|
433
|
+
for (const page of copiedPages)
|
|
434
|
+
newPdf.addPage(page);
|
|
435
|
+
results.push(newPdf);
|
|
436
|
+
}
|
|
437
|
+
logger.debug('Successfully split PDF document.', {
|
|
438
|
+
...logContext,
|
|
439
|
+
resultCount: results.length,
|
|
440
|
+
});
|
|
441
|
+
return results;
|
|
442
|
+
}
|
|
443
|
+
catch (e) {
|
|
444
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
445
|
+
logger.error('Failed to split PDF document.', {
|
|
446
|
+
...logContext,
|
|
447
|
+
errorDetails: error.message,
|
|
448
|
+
});
|
|
449
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to split PDF: ${error.message}`, {
|
|
450
|
+
...context,
|
|
451
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Fills form fields in a PDF document.
|
|
457
|
+
*
|
|
458
|
+
* String and number values are set via `setText`; boolean values check/uncheck
|
|
459
|
+
* checkbox fields. Individual field errors are logged as warnings and skipped
|
|
460
|
+
* rather than aborting the whole operation. If `flatten` is true, the form is
|
|
461
|
+
* flattened after filling, making it non-editable. Synchronous.
|
|
462
|
+
*
|
|
463
|
+
* @param doc - The `PDFDocument` containing the AcroForm.
|
|
464
|
+
* @param options - Map of field names to values, plus optional `flatten` flag.
|
|
465
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
466
|
+
* @throws {McpError} With `InternalError` if the overall form operation fails.
|
|
467
|
+
* @example
|
|
468
|
+
* ```typescript
|
|
469
|
+
* pdfParser.fillForm(doc, {
|
|
470
|
+
* fields: {
|
|
471
|
+
* Name: 'John Doe',
|
|
472
|
+
* Age: 30,
|
|
473
|
+
* Subscribe: true,
|
|
474
|
+
* },
|
|
475
|
+
* flatten: true,
|
|
476
|
+
* });
|
|
477
|
+
* ```
|
|
478
|
+
*/
|
|
479
|
+
fillForm(doc, options, context) {
|
|
480
|
+
const logContext = context ||
|
|
481
|
+
requestContextService.createRequestContext({
|
|
482
|
+
operation: 'PdfParser.fillForm',
|
|
483
|
+
});
|
|
484
|
+
try {
|
|
485
|
+
logger.debug('Filling PDF form fields.', {
|
|
486
|
+
...logContext,
|
|
487
|
+
fieldCount: Object.keys(options.fields).length,
|
|
488
|
+
flatten: options.flatten ?? false,
|
|
489
|
+
});
|
|
490
|
+
const form = doc.getForm();
|
|
491
|
+
for (const [fieldName, value] of Object.entries(options.fields)) {
|
|
492
|
+
try {
|
|
493
|
+
const field = form.getField(fieldName);
|
|
494
|
+
if (typeof value === 'string') {
|
|
495
|
+
if ('setText' in field) {
|
|
496
|
+
field.setText(value);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
else if (typeof value === 'boolean') {
|
|
500
|
+
if ('check' in field || 'uncheck' in field) {
|
|
501
|
+
const checkboxField = field;
|
|
502
|
+
if (value) {
|
|
503
|
+
checkboxField.check?.();
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
checkboxField.uncheck?.();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
else if (typeof value === 'number') {
|
|
511
|
+
if ('setText' in field) {
|
|
512
|
+
field.setText(String(value));
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
catch (fieldError) {
|
|
517
|
+
logger.warning('Failed to fill form field.', {
|
|
518
|
+
...logContext,
|
|
519
|
+
fieldName,
|
|
520
|
+
fieldError: fieldError instanceof Error ? fieldError.message : String(fieldError),
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
if (options.flatten) {
|
|
525
|
+
form.flatten();
|
|
526
|
+
}
|
|
527
|
+
logger.debug('Successfully filled PDF form.', logContext);
|
|
528
|
+
}
|
|
529
|
+
catch (e) {
|
|
530
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
531
|
+
logger.error('Failed to fill PDF form.', {
|
|
532
|
+
...logContext,
|
|
533
|
+
errorDetails: error.message,
|
|
534
|
+
});
|
|
535
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to fill PDF form: ${error.message}`, {
|
|
536
|
+
...context,
|
|
537
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Extracts metadata from a PDF document.
|
|
543
|
+
*
|
|
544
|
+
* Reads title, author, subject, keywords, creator, producer, creation date, and
|
|
545
|
+
* modification date from the document's info dictionary. Optional fields are
|
|
546
|
+
* omitted from the result if not set. Synchronous — no peer dependency loading.
|
|
547
|
+
*
|
|
548
|
+
* @param doc - The `PDFDocument` to extract metadata from.
|
|
549
|
+
* @returns A `PdfMetadata` object; optional fields are absent if not set in the document.
|
|
550
|
+
* @example
|
|
551
|
+
* ```typescript
|
|
552
|
+
* const metadata = pdfParser.extractMetadata(doc);
|
|
553
|
+
* console.log(`${metadata.title} by ${metadata.author} (${metadata.pageCount} pages)`);
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
extractMetadata(doc) {
|
|
557
|
+
const title = doc.getTitle();
|
|
558
|
+
const author = doc.getAuthor();
|
|
559
|
+
const subject = doc.getSubject();
|
|
560
|
+
const keywords = doc.getKeywords();
|
|
561
|
+
const creator = doc.getCreator();
|
|
562
|
+
const producer = doc.getProducer();
|
|
563
|
+
const creationDate = doc.getCreationDate();
|
|
564
|
+
const modificationDate = doc.getModificationDate();
|
|
565
|
+
const metadata = {
|
|
566
|
+
pageCount: doc.getPageCount(),
|
|
567
|
+
};
|
|
568
|
+
if (title !== undefined)
|
|
569
|
+
metadata.title = title;
|
|
570
|
+
if (author !== undefined)
|
|
571
|
+
metadata.author = author;
|
|
572
|
+
if (subject !== undefined)
|
|
573
|
+
metadata.subject = subject;
|
|
574
|
+
if (keywords !== undefined)
|
|
575
|
+
metadata.keywords = keywords;
|
|
576
|
+
if (creator !== undefined)
|
|
577
|
+
metadata.creator = creator;
|
|
578
|
+
if (producer !== undefined)
|
|
579
|
+
metadata.producer = producer;
|
|
580
|
+
if (creationDate !== undefined)
|
|
581
|
+
metadata.creationDate = creationDate.toISOString();
|
|
582
|
+
if (modificationDate !== undefined)
|
|
583
|
+
metadata.modificationDate = modificationDate.toISOString();
|
|
584
|
+
return metadata;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Sets metadata fields on a PDF document.
|
|
588
|
+
*
|
|
589
|
+
* Only fields present in `metadata` are written; omitted fields are left unchanged.
|
|
590
|
+
* Note: `keywords` is passed as a single-element array to `pdf-lib`'s `setKeywords`.
|
|
591
|
+
* Synchronous — no peer dependency loading.
|
|
592
|
+
*
|
|
593
|
+
* @param doc - The `PDFDocument` to update.
|
|
594
|
+
* @param metadata - Metadata values to set. Omitted fields are left unchanged.
|
|
595
|
+
* @example
|
|
596
|
+
* ```typescript
|
|
597
|
+
* pdfParser.setMetadata(doc, {
|
|
598
|
+
* title: 'My Document',
|
|
599
|
+
* author: 'John Doe',
|
|
600
|
+
* subject: 'Important Document',
|
|
601
|
+
* });
|
|
602
|
+
* ```
|
|
603
|
+
*/
|
|
604
|
+
setMetadata(doc, metadata) {
|
|
605
|
+
if (metadata.title)
|
|
606
|
+
doc.setTitle(metadata.title);
|
|
607
|
+
if (metadata.author)
|
|
608
|
+
doc.setAuthor(metadata.author);
|
|
609
|
+
if (metadata.subject)
|
|
610
|
+
doc.setSubject(metadata.subject);
|
|
611
|
+
if (metadata.keywords)
|
|
612
|
+
doc.setKeywords([metadata.keywords]);
|
|
613
|
+
if (metadata.creator)
|
|
614
|
+
doc.setCreator(metadata.creator);
|
|
615
|
+
if (metadata.producer)
|
|
616
|
+
doc.setProducer(metadata.producer);
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Extracts text content from all pages of a PDF document using `unpdf`.
|
|
620
|
+
*
|
|
621
|
+
* Serializes the `PDFDocument` to bytes, then delegates to `unpdf`'s `extractText`,
|
|
622
|
+
* which is compatible with Cloudflare Workers and other serverless environments.
|
|
623
|
+
* Async due to lazy loading of both `pdf-lib` and `unpdf`
|
|
624
|
+
* (`bun add pdf-lib unpdf`).
|
|
625
|
+
*
|
|
626
|
+
* @param doc - The `PDFDocument` to extract text from.
|
|
627
|
+
* @param options - Optional extraction options. Set `mergePages: true` to get a
|
|
628
|
+
* single concatenated string instead of one string per page.
|
|
629
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
630
|
+
* @returns An `ExtractTextResult` with `totalPages` and `text` — a `string[]` (one
|
|
631
|
+
* per page) by default, or a single `string` when `mergePages` is `true`.
|
|
632
|
+
* @throws {McpError} With `ConfigurationError` if `pdf-lib` or `unpdf` is not installed.
|
|
633
|
+
* @throws {McpError} With `InternalError` if text extraction fails.
|
|
634
|
+
* @example
|
|
635
|
+
* ```typescript
|
|
636
|
+
* // Per-page array (default)
|
|
637
|
+
* const result = await pdfParser.extractText(doc);
|
|
638
|
+
* console.log(result.text[0]); // Text from first page
|
|
639
|
+
*
|
|
640
|
+
* // All pages concatenated into one string
|
|
641
|
+
* const merged = await pdfParser.extractText(doc, { mergePages: true });
|
|
642
|
+
* console.log(merged.text); // Full document text
|
|
643
|
+
* ```
|
|
644
|
+
*/
|
|
645
|
+
async extractText(doc, options, context) {
|
|
646
|
+
const logContext = context ||
|
|
647
|
+
requestContextService.createRequestContext({
|
|
648
|
+
operation: 'PdfParser.extractText',
|
|
649
|
+
});
|
|
650
|
+
try {
|
|
651
|
+
const pageCount = doc.getPageCount();
|
|
652
|
+
const mergePages = options?.mergePages ?? false;
|
|
653
|
+
logger.debug('Extracting text from PDF using unpdf.', {
|
|
654
|
+
...logContext,
|
|
655
|
+
pageCount,
|
|
656
|
+
mergePages,
|
|
657
|
+
});
|
|
658
|
+
// Convert PDFDocument to bytes
|
|
659
|
+
const pdfBytes = await doc.save();
|
|
660
|
+
const { getDocumentProxy, extractText: unpdfExtractText } = await getUnpdf();
|
|
661
|
+
// Create document proxy for unpdf
|
|
662
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
663
|
+
const pdfProxy = await getDocumentProxy(pdfBytes);
|
|
664
|
+
// Extract text using unpdf with explicit type handling
|
|
665
|
+
let result;
|
|
666
|
+
if (mergePages) {
|
|
667
|
+
// Call with mergePages: true for merged text
|
|
668
|
+
const merged = await unpdfExtractText(pdfProxy, { mergePages: true });
|
|
669
|
+
result = merged;
|
|
670
|
+
}
|
|
671
|
+
else {
|
|
672
|
+
// Call with mergePages: false for per-page text
|
|
673
|
+
const perPage = await unpdfExtractText(pdfProxy, {
|
|
674
|
+
mergePages: false,
|
|
675
|
+
});
|
|
676
|
+
result = perPage;
|
|
677
|
+
}
|
|
678
|
+
logger.debug('Successfully extracted text from PDF.', {
|
|
679
|
+
...logContext,
|
|
680
|
+
totalPages: result.totalPages,
|
|
681
|
+
textLength: Array.isArray(result.text)
|
|
682
|
+
? result.text.reduce((sum, t) => sum + t.length, 0)
|
|
683
|
+
: result.text.length,
|
|
684
|
+
});
|
|
685
|
+
return {
|
|
686
|
+
totalPages: result.totalPages,
|
|
687
|
+
text: result.text,
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
catch (e) {
|
|
691
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
692
|
+
logger.error('Failed to extract text from PDF.', {
|
|
693
|
+
...logContext,
|
|
694
|
+
errorDetails: error.message,
|
|
695
|
+
});
|
|
696
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to extract text: ${error.message}`, {
|
|
697
|
+
...context,
|
|
698
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Serializes a PDF document to a `Uint8Array` for writing to disk or transmission.
|
|
704
|
+
*
|
|
705
|
+
* Async due to `pdf-lib`'s async `save()` implementation (cross-origin / Worker
|
|
706
|
+
* compatible). Does not reload peer dependencies if already cached.
|
|
707
|
+
*
|
|
708
|
+
* @param doc - The `PDFDocument` to serialize.
|
|
709
|
+
* @param context - Optional `RequestContext` for correlated logging and error metadata.
|
|
710
|
+
* @returns The complete PDF file as a `Uint8Array`.
|
|
711
|
+
* @throws {McpError} With `InternalError` if serialization fails.
|
|
712
|
+
* @example
|
|
713
|
+
* ```typescript
|
|
714
|
+
* import { writeFile } from 'node:fs/promises';
|
|
715
|
+
* const pdfBytes = await pdfParser.saveDocument(doc);
|
|
716
|
+
* await writeFile('output.pdf', pdfBytes);
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
async saveDocument(doc, context) {
|
|
720
|
+
const logContext = context ||
|
|
721
|
+
requestContextService.createRequestContext({
|
|
722
|
+
operation: 'PdfParser.saveDocument',
|
|
723
|
+
});
|
|
724
|
+
try {
|
|
725
|
+
logger.debug('Serializing PDF document to bytes.', logContext);
|
|
726
|
+
const bytes = await doc.save();
|
|
727
|
+
logger.debug('Successfully serialized PDF document.', {
|
|
728
|
+
...logContext,
|
|
729
|
+
byteLength: bytes.length,
|
|
730
|
+
});
|
|
731
|
+
return bytes;
|
|
732
|
+
}
|
|
733
|
+
catch (e) {
|
|
734
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
735
|
+
logger.error('Failed to serialize PDF document.', {
|
|
736
|
+
...logContext,
|
|
737
|
+
errorDetails: error.message,
|
|
738
|
+
});
|
|
739
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Failed to save PDF document: ${error.message}`, {
|
|
740
|
+
...context,
|
|
741
|
+
rawError: error instanceof Error ? error.stack : String(error),
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Singleton instance of `PdfParser`.
|
|
748
|
+
*
|
|
749
|
+
* Provides PDF creation, editing, merging, splitting, form filling, metadata
|
|
750
|
+
* extraction, and text extraction. Requires `pdf-lib` for document operations
|
|
751
|
+
* and `unpdf` for text extraction — install both with: `bun add pdf-lib unpdf`
|
|
752
|
+
*
|
|
753
|
+
* @example
|
|
754
|
+
* ```typescript
|
|
755
|
+
* import { pdfParser } from '../../utils/parsing/pdfParser.js';
|
|
756
|
+
* import { writeFile } from 'node:fs/promises';
|
|
757
|
+
*
|
|
758
|
+
* const doc = await pdfParser.createDocument();
|
|
759
|
+
* const page = pdfParser.addPage(doc);
|
|
760
|
+
* const font = await pdfParser.embedFont(doc, 'Helvetica');
|
|
761
|
+
*
|
|
762
|
+
* await pdfParser.drawText(page, {
|
|
763
|
+
* text: 'Hello, World!',
|
|
764
|
+
* x: 50,
|
|
765
|
+
* y: 750,
|
|
766
|
+
* size: 30,
|
|
767
|
+
* font,
|
|
768
|
+
* });
|
|
769
|
+
*
|
|
770
|
+
* const pdfBytes = await pdfParser.saveDocument(doc);
|
|
771
|
+
* await writeFile('output.pdf', pdfBytes);
|
|
772
|
+
* ```
|
|
773
|
+
*/
|
|
774
|
+
export const pdfParser = new PdfParser();
|
|
775
|
+
//# sourceMappingURL=pdfParser.js.map
|