github-to-mcp-monorepo 1.0.0
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/.env.example +8 -0
- package/.github/CODEOWNERS +6 -0
- package/.husky/pre-commit +1 -0
- package/.nvmrc +1 -0
- package/.prettierignore +5 -0
- package/.prettierrc +7 -0
- package/.vscode/settings.json +4 -0
- package/ARCHITECTURE.md +1429 -0
- package/CHANGELOG.md +167 -0
- package/CONTRIBUTING.md +327 -0
- package/LICENSE +201 -0
- package/README.md +1028 -0
- package/SECURITY.md +248 -0
- package/VISUAL_GUIDE.md +437 -0
- package/apps/vscode/IMPLEMENTATION.md +480 -0
- package/apps/vscode/README.md +248 -0
- package/apps/vscode/package.json +381 -0
- package/apps/vscode/resources/icon.png +0 -0
- package/apps/vscode/resources/icon.svg +5 -0
- package/apps/vscode/src/commands/browseRegistry.ts +211 -0
- package/apps/vscode/src/commands/configureClaudeDesktop.ts +332 -0
- package/apps/vscode/src/commands/convert.ts +82 -0
- package/apps/vscode/src/commands/convertCurrentRepo.ts +109 -0
- package/apps/vscode/src/commands/convertFromUrl.ts +138 -0
- package/apps/vscode/src/commands/index.ts +121 -0
- package/apps/vscode/src/commands/validate.ts +197 -0
- package/apps/vscode/src/extension.ts +464 -0
- package/apps/vscode/src/global.d.ts +36 -0
- package/apps/vscode/src/test/extension.test.ts +73 -0
- package/apps/vscode/src/utils/file-generator.ts +529 -0
- package/apps/vscode/src/utils/github-api.ts +335 -0
- package/apps/vscode/src/utils/index.ts +29 -0
- package/apps/vscode/src/utils/mcp-config.ts +334 -0
- package/apps/vscode/src/utils/storage.ts +87 -0
- package/apps/vscode/src/views/McpServersTreeView.ts +160 -0
- package/apps/vscode/src/views/OutputChannelView.ts +195 -0
- package/apps/vscode/src/views/StatusBarItem.ts +251 -0
- package/apps/vscode/src/views/ToolsExplorerView.ts +314 -0
- package/apps/vscode/src/views/historyProvider.ts +75 -0
- package/apps/vscode/src/views/index.ts +12 -0
- package/apps/vscode/src/views/resultsPanel.ts +330 -0
- package/apps/vscode/src/webviews/ConversionPanel.ts +350 -0
- package/apps/vscode/src/webviews/ToolDetailsPanel.ts +448 -0
- package/apps/vscode/src/webviews/index.ts +9 -0
- package/apps/vscode/src/webviews/webview-ui/styles.ts +492 -0
- package/apps/vscode/tsconfig.json +20 -0
- package/apps/web/PLAYGROUND_GUIDE.md +499 -0
- package/apps/web/README.md +505 -0
- package/apps/web/app/api/convert/route.ts +100 -0
- package/apps/web/app/api/convert/stream/route.ts +198 -0
- package/apps/web/app/api/deploy/route.ts +157 -0
- package/apps/web/app/api/edge/route.ts +308 -0
- package/apps/web/app/api/export-docker/route.ts +284 -0
- package/apps/web/app/api/generate-openapi/route.ts +119 -0
- package/apps/web/app/api/mcp/[serverId]/route.ts +263 -0
- package/apps/web/app/api/playground/connect/route.ts +143 -0
- package/apps/web/app/api/playground/disconnect/route.ts +78 -0
- package/apps/web/app/api/playground/execute/route.ts +135 -0
- package/apps/web/app/api/playground/sessions/route.ts +103 -0
- package/apps/web/app/api/playground/tools/route.ts +117 -0
- package/apps/web/app/api/playground/v2/connect/route.ts +96 -0
- package/apps/web/app/api/playground/v2/disconnect/route.ts +88 -0
- package/apps/web/app/api/playground/v2/health/route.ts +80 -0
- package/apps/web/app/api/playground/v2/prompts/route.ts +160 -0
- package/apps/web/app/api/playground/v2/resources/route.ts +159 -0
- package/apps/web/app/api/playground/v2/sessions/route.ts +184 -0
- package/apps/web/app/api/playground/v2/tools/route.ts +167 -0
- package/apps/web/app/api/stream/route.ts +232 -0
- package/apps/web/app/batch/BatchConvertClient.tsx +190 -0
- package/apps/web/app/batch/page.tsx +37 -0
- package/apps/web/app/convert/page.tsx +269 -0
- package/apps/web/app/dashboard/page.tsx +380 -0
- package/apps/web/app/globals.css +622 -0
- package/apps/web/app/layout.tsx +120 -0
- package/apps/web/app/manifest.ts +31 -0
- package/apps/web/app/opengraph-image.tsx +112 -0
- package/apps/web/app/page.old.tsx +924 -0
- package/apps/web/app/page.tsx +77 -0
- package/apps/web/app/playground/page.tsx +306 -0
- package/apps/web/app/playground/v2/error.tsx +163 -0
- package/apps/web/app/playground/v2/layout.tsx +58 -0
- package/apps/web/app/playground/v2/loading.tsx +152 -0
- package/apps/web/app/playground/v2/page.tsx +644 -0
- package/apps/web/app/playground/v2/providers.tsx +214 -0
- package/apps/web/app/playground/v2/use-shortcuts.ts +209 -0
- package/apps/web/app/playground/v2/use-url-state.ts +296 -0
- package/apps/web/app/providers.tsx +22 -0
- package/apps/web/app/sitemap.ts +32 -0
- package/apps/web/app/twitter-image.tsx +112 -0
- package/apps/web/components/BranchSelector.tsx +401 -0
- package/apps/web/components/ClaudeConfigExport.tsx +226 -0
- package/apps/web/components/Features.tsx +84 -0
- package/apps/web/components/Footer.tsx +119 -0
- package/apps/web/components/GenerationProgress.tsx +248 -0
- package/apps/web/components/GithubUrlInput.tsx +483 -0
- package/apps/web/components/Header.tsx +175 -0
- package/apps/web/components/Hero.tsx +117 -0
- package/apps/web/components/HowItWorks.tsx +119 -0
- package/apps/web/components/InstallBanner.tsx +158 -0
- package/apps/web/components/Logo.tsx +116 -0
- package/apps/web/components/ParticleBackground.tsx +105 -0
- package/apps/web/components/Playground.tsx +472 -0
- package/apps/web/components/PlaygroundToolTester.tsx +410 -0
- package/apps/web/components/ProductCards.tsx +179 -0
- package/apps/web/components/SplitView.tsx +194 -0
- package/apps/web/components/ToolFilter.tsx +260 -0
- package/apps/web/components/ToolList.tsx +325 -0
- package/apps/web/components/batch/BatchConvert.tsx +785 -0
- package/apps/web/components/batch/index.ts +7 -0
- package/apps/web/components/convert/ConfigTabs.tsx +230 -0
- package/apps/web/components/convert/ConversionResult.tsx +482 -0
- package/apps/web/components/convert/InlinePlayground.tsx +259 -0
- package/apps/web/components/convert/LoadingSteps.tsx +311 -0
- package/apps/web/components/convert/OneClickInstall.tsx +224 -0
- package/apps/web/components/convert/ToolCard.tsx +189 -0
- package/apps/web/components/convert/TryInPlayground.tsx +242 -0
- package/apps/web/components/convert/index.ts +12 -0
- package/apps/web/components/deploy/DeployButton.tsx +369 -0
- package/apps/web/components/deploy/index.ts +7 -0
- package/apps/web/components/docker/DockerExport.tsx +690 -0
- package/apps/web/components/docker/index.ts +7 -0
- package/apps/web/components/install/OneClickInstall.tsx +676 -0
- package/apps/web/components/install/index.ts +7 -0
- package/apps/web/components/playground/CapabilityTabs.tsx +150 -0
- package/apps/web/components/playground/ConnectionStatusV2.tsx +322 -0
- package/apps/web/components/playground/EmptyStates.tsx +305 -0
- package/apps/web/components/playground/ExecutionLog.tsx +260 -0
- package/apps/web/components/playground/ExecutionLogV2.tsx +378 -0
- package/apps/web/components/playground/JsonViewer.tsx +388 -0
- package/apps/web/components/playground/PlaygroundLayout.tsx +244 -0
- package/apps/web/components/playground/PromptsPanel.tsx +385 -0
- package/apps/web/components/playground/ResourcesPanel.tsx +378 -0
- package/apps/web/components/playground/SchemaForm.tsx +477 -0
- package/apps/web/components/playground/ServerStatus.tsx +151 -0
- package/apps/web/components/playground/ShareButton.tsx +239 -0
- package/apps/web/components/playground/ToolsPanel.tsx +309 -0
- package/apps/web/components/playground/TransportConfigurator.tsx +563 -0
- package/apps/web/components/playground/index.ts +74 -0
- package/apps/web/components/playground/types.ts +202 -0
- package/apps/web/components/streaming/StreamingProgress.tsx +441 -0
- package/apps/web/components/streaming/index.ts +7 -0
- package/apps/web/components/ui/badge.tsx +42 -0
- package/apps/web/components/ui/button.tsx +88 -0
- package/apps/web/components/ui/card.tsx +75 -0
- package/apps/web/components/ui/code-block.tsx +122 -0
- package/apps/web/components/ui/index.ts +12 -0
- package/apps/web/components/ui/input.tsx +55 -0
- package/apps/web/components/ui/tabs.tsx +61 -0
- package/apps/web/hooks/index.ts +85 -0
- package/apps/web/hooks/types.ts +1173 -0
- package/apps/web/hooks/use-conversion.ts +133 -0
- package/apps/web/hooks/use-execution-history.ts +376 -0
- package/apps/web/hooks/use-generation-progress.ts +147 -0
- package/apps/web/hooks/use-local-storage.ts +88 -0
- package/apps/web/hooks/use-mcp-client.ts +623 -0
- package/apps/web/hooks/use-mcp-connection.ts +500 -0
- package/apps/web/hooks/use-mcp-execution.ts +282 -0
- package/apps/web/hooks/use-mcp-prompts.ts +441 -0
- package/apps/web/hooks/use-mcp-resources.ts +430 -0
- package/apps/web/hooks/use-mcp-tools.ts +540 -0
- package/apps/web/hooks/use-playground-store.ts +299 -0
- package/apps/web/hooks/use-playground.ts +184 -0
- package/apps/web/hooks/use-streaming-conversion.ts +227 -0
- package/apps/web/hooks/useBatchConversion.ts +271 -0
- package/apps/web/hooks/useDockerConfig.ts +161 -0
- package/apps/web/hooks/usePlatformDetection.ts +80 -0
- package/apps/web/hooks/useStreaming.ts +199 -0
- package/apps/web/lib/api/errors.ts +386 -0
- package/apps/web/lib/api/index.ts +137 -0
- package/apps/web/lib/api/logger.ts +187 -0
- package/apps/web/lib/api/middleware.ts +364 -0
- package/apps/web/lib/api/openapi.ts +977 -0
- package/apps/web/lib/api/session-manager.ts +594 -0
- package/apps/web/lib/api/types.ts +433 -0
- package/apps/web/lib/api/validation.ts +523 -0
- package/apps/web/lib/constants.ts +114 -0
- package/apps/web/lib/mcp/client.ts +1137 -0
- package/apps/web/lib/mcp/events.ts +651 -0
- package/apps/web/lib/mcp/index.ts +347 -0
- package/apps/web/lib/mcp/logger.ts +428 -0
- package/apps/web/lib/mcp/metrics.ts +703 -0
- package/apps/web/lib/mcp/retry.ts +616 -0
- package/apps/web/lib/mcp/session-manager.ts +779 -0
- package/apps/web/lib/mcp/transports.ts +988 -0
- package/apps/web/lib/mcp/types.ts +594 -0
- package/apps/web/lib/mcp-client-enhanced.ts +871 -0
- package/apps/web/lib/mcp-client.ts +778 -0
- package/apps/web/lib/mcp-errors.ts +489 -0
- package/apps/web/lib/mcp-sandbox.ts +593 -0
- package/apps/web/lib/mcp-testing.ts +428 -0
- package/apps/web/lib/mcp-types.ts +448 -0
- package/apps/web/lib/playground-store.tsx +1147 -0
- package/apps/web/lib/utils.ts +439 -0
- package/apps/web/next-env.d.ts +5 -0
- package/apps/web/next.config.js +23 -0
- package/apps/web/package.json +55 -0
- package/apps/web/postcss.config.js +6 -0
- package/apps/web/public/.well-known/ai-plugin.json +17 -0
- package/apps/web/public/logo.svg +6 -0
- package/apps/web/public/robots.txt +22 -0
- package/apps/web/public/schema.json +27 -0
- package/apps/web/tailwind.config.js +26 -0
- package/apps/web/tailwind.config.ts +123 -0
- package/apps/web/tsconfig.json +20 -0
- package/apps/web/types/deploy.ts +139 -0
- package/apps/web/types/index.ts +247 -0
- package/apps/web/vercel.json +39 -0
- package/eslint.config.mjs +23 -0
- package/llms.txt +102 -0
- package/mkdocs/docs/api/core.md +318 -0
- package/mkdocs/docs/api/index.md +128 -0
- package/mkdocs/docs/api/mcp-server.md +301 -0
- package/mkdocs/docs/api/openapi-parser.md +254 -0
- package/mkdocs/docs/assets/logo.svg +7 -0
- package/mkdocs/docs/changelog.md +118 -0
- package/mkdocs/docs/cli/generate.md +148 -0
- package/mkdocs/docs/cli/index.md +52 -0
- package/mkdocs/docs/cli/inspect.md +164 -0
- package/mkdocs/docs/cli/serve.md +136 -0
- package/mkdocs/docs/concepts/classification.md +254 -0
- package/mkdocs/docs/concepts/how-it-works.md +299 -0
- package/mkdocs/docs/concepts/index.md +77 -0
- package/mkdocs/docs/concepts/mcp-protocol.md +362 -0
- package/mkdocs/docs/concepts/tool-types.md +382 -0
- package/mkdocs/docs/contributing/architecture.md +262 -0
- package/mkdocs/docs/contributing/development.md +245 -0
- package/mkdocs/docs/contributing/index.md +73 -0
- package/mkdocs/docs/contributing/testing.md +320 -0
- package/mkdocs/docs/getting-started/configuration.md +235 -0
- package/mkdocs/docs/getting-started/index.md +54 -0
- package/mkdocs/docs/getting-started/installation.md +145 -0
- package/mkdocs/docs/getting-started/quickstart.md +160 -0
- package/mkdocs/docs/guides/batch.md +375 -0
- package/mkdocs/docs/guides/claude-desktop.md +227 -0
- package/mkdocs/docs/guides/cursor.md +188 -0
- package/mkdocs/docs/guides/custom-tools.md +367 -0
- package/mkdocs/docs/guides/index.md +78 -0
- package/mkdocs/docs/guides/private-repos.md +221 -0
- package/mkdocs/docs/guides/vscode.md +247 -0
- package/mkdocs/docs/index.md +175 -0
- package/mkdocs/docs/reference/config.md +223 -0
- package/mkdocs/docs/reference/env.md +192 -0
- package/mkdocs/docs/reference/index.md +102 -0
- package/mkdocs/docs/reference/tools.md +309 -0
- package/mkdocs/docs/stylesheets/extra.css +231 -0
- package/mkdocs/mkdocs.yml +204 -0
- package/mkdocs/overrides/.gitkeep +1 -0
- package/mkdocs/overrides/main.html +7 -0
- package/mkdocs/python-deps.txt +7 -0
- package/mkdocs/vercel.json +11 -0
- package/package.json +63 -0
- package/packages/core/package.json +61 -0
- package/packages/core/src/__tests__/bitbucket-client.test.ts +366 -0
- package/packages/core/src/__tests__/cli.test.ts +235 -0
- package/packages/core/src/__tests__/code-extractor.test.ts +378 -0
- package/packages/core/src/__tests__/docker-generator.test.ts +255 -0
- package/packages/core/src/__tests__/github-client.test.ts +390 -0
- package/packages/core/src/__tests__/gitlab-client.test.ts +319 -0
- package/packages/core/src/__tests__/go-extractor.test.ts +351 -0
- package/packages/core/src/__tests__/graphql-extractor.test.ts +330 -0
- package/packages/core/src/__tests__/java-extractor.test.ts +497 -0
- package/packages/core/src/__tests__/plugins.test.ts +467 -0
- package/packages/core/src/__tests__/readme-extractor.test.ts +258 -0
- package/packages/core/src/__tests__/redis-cache.test.ts +307 -0
- package/packages/core/src/__tests__/rust-extractor.test.ts +252 -0
- package/packages/core/src/__tests__/streaming.test.ts +251 -0
- package/packages/core/src/additional-extractors.ts +333 -0
- package/packages/core/src/cache/cache-interface.ts +179 -0
- package/packages/core/src/cache/index.ts +210 -0
- package/packages/core/src/cache/redis-cache.ts +291 -0
- package/packages/core/src/cache/upstash-cache.ts +379 -0
- package/packages/core/src/cache.ts +251 -0
- package/packages/core/src/cli.ts +822 -0
- package/packages/core/src/code-extractor.ts +696 -0
- package/packages/core/src/docker-generator.ts +470 -0
- package/packages/core/src/edge-compatible.ts +491 -0
- package/packages/core/src/extractors/go-extractor.ts +791 -0
- package/packages/core/src/extractors/index.ts +9 -0
- package/packages/core/src/extractors/java-extractor.ts +937 -0
- package/packages/core/src/extractors/rust-extractor.ts +744 -0
- package/packages/core/src/github-client.ts +319 -0
- package/packages/core/src/go-generator.ts +356 -0
- package/packages/core/src/graphql-extractor.ts +358 -0
- package/packages/core/src/index.ts +797 -0
- package/packages/core/src/langchain-exporter.ts +617 -0
- package/packages/core/src/language-parsers.ts +1114 -0
- package/packages/core/src/mcp-introspector.ts +279 -0
- package/packages/core/src/monorepo-detector.ts +378 -0
- package/packages/core/src/plugins/index.ts +370 -0
- package/packages/core/src/plugins/registry.ts +404 -0
- package/packages/core/src/plugins/types.ts +215 -0
- package/packages/core/src/providers/base-provider.ts +246 -0
- package/packages/core/src/providers/bitbucket-client.ts +464 -0
- package/packages/core/src/providers/gitlab-client.ts +388 -0
- package/packages/core/src/providers/index.ts +176 -0
- package/packages/core/src/python-generator.ts +260 -0
- package/packages/core/src/queue/index.ts +100 -0
- package/packages/core/src/queue/memory-queue.ts +445 -0
- package/packages/core/src/queue/redis-queue.ts +578 -0
- package/packages/core/src/queue/types.ts +251 -0
- package/packages/core/src/readme-extractor.ts +409 -0
- package/packages/core/src/schema-generator.ts +638 -0
- package/packages/core/src/streaming.ts +999 -0
- package/packages/core/src/types.ts +289 -0
- package/packages/core/tsconfig.json +9 -0
- package/packages/core/tsup.config.ts +25 -0
- package/packages/mcp-server/README.md +297 -0
- package/packages/mcp-server/package.json +55 -0
- package/packages/mcp-server/src/__tests__/mcp-server.test.ts +177 -0
- package/packages/mcp-server/src/__tests__/tools.test.ts +217 -0
- package/packages/mcp-server/src/index.ts +1206 -0
- package/packages/mcp-server/src/prompts/index.ts +601 -0
- package/packages/mcp-server/src/tools/export-docker.ts +362 -0
- package/packages/mcp-server/src/tools/generate-openapi.ts +162 -0
- package/packages/mcp-server/src/tools/monitor-mcp-server.ts +448 -0
- package/packages/mcp-server/src/tools/stream-convert.ts +398 -0
- package/packages/mcp-server/src/tools/test-mcp-tool.ts +531 -0
- package/packages/mcp-server/tsconfig.json +12 -0
- package/packages/mcp-server/tsup.config.ts +14 -0
- package/packages/openapi-parser/package-lock.json +3028 -0
- package/packages/openapi-parser/package.json +41 -0
- package/packages/openapi-parser/src/analyzer.ts +700 -0
- package/packages/openapi-parser/src/asyncapi-parser.ts +475 -0
- package/packages/openapi-parser/src/cli.ts +302 -0
- package/packages/openapi-parser/src/generator.ts +570 -0
- package/packages/openapi-parser/src/generators/express-analyzer.ts +649 -0
- package/packages/openapi-parser/src/generators/fastapi-analyzer.ts +960 -0
- package/packages/openapi-parser/src/generators/index.ts +200 -0
- package/packages/openapi-parser/src/generators/nextjs-analyzer.ts +768 -0
- package/packages/openapi-parser/src/generators/openapi-builder.ts +527 -0
- package/packages/openapi-parser/src/generators/types.ts +298 -0
- package/packages/openapi-parser/src/graphql-parser.ts +462 -0
- package/packages/openapi-parser/src/grpc-parser.ts +649 -0
- package/packages/openapi-parser/src/har-parser.ts +723 -0
- package/packages/openapi-parser/src/index.ts +635 -0
- package/packages/openapi-parser/src/insomnia-parser.ts +614 -0
- package/packages/openapi-parser/src/parser.ts +231 -0
- package/packages/openapi-parser/src/postman-parser.ts +611 -0
- package/packages/openapi-parser/src/ref-resolver.ts +313 -0
- package/packages/openapi-parser/src/transformer.ts +459 -0
- package/packages/openapi-parser/tests/generators/express.test.ts +209 -0
- package/packages/openapi-parser/tests/generators/fastapi.test.ts +236 -0
- package/packages/openapi-parser/tests/generators/nextjs.test.ts +273 -0
- package/packages/openapi-parser/tests/parsers.test.ts +847 -0
- package/packages/openapi-parser/tsconfig.json +9 -0
- package/packages/openapi-parser/tsup.config.ts +11 -0
- package/packages/registry/package.json +59 -0
- package/packages/registry/src/cli.ts +456 -0
- package/packages/registry/src/index.ts +44 -0
- package/packages/registry/src/popular/github.json +47 -0
- package/packages/registry/src/popular/index.ts +55 -0
- package/packages/registry/src/popular/linear.json +42 -0
- package/packages/registry/src/popular/notion.json +42 -0
- package/packages/registry/src/popular/openai.json +40 -0
- package/packages/registry/src/popular/resend.json +38 -0
- package/packages/registry/src/popular/slack.json +42 -0
- package/packages/registry/src/popular/stripe.json +163 -0
- package/packages/registry/src/popular/supabase.json +42 -0
- package/packages/registry/src/popular/twilio.json +40 -0
- package/packages/registry/src/popular/vercel.json +40 -0
- package/packages/registry/src/registry.ts +492 -0
- package/packages/registry/src/storage.ts +334 -0
- package/packages/registry/src/types.ts +275 -0
- package/packages/registry/src/updater.ts +208 -0
- package/packages/registry/tsconfig.json +10 -0
- package/packages/registry/tsup.config.ts +11 -0
- package/pnpm-workspace.yaml +3 -0
- package/scripts/build-docs.sh +16 -0
- package/server.json +9 -0
- package/templates/Dockerfile.python.template +60 -0
- package/templates/Dockerfile.typescript.template +60 -0
- package/templates/docker-compose.template.yml +68 -0
- package/tests/fixtures/express-app/index.js +34 -0
- package/tests/fixtures/express-app/routes/posts.js +43 -0
- package/tests/fixtures/express-app/routes/users.js +58 -0
- package/tests/fixtures/fastapi-app/main.py +125 -0
- package/tests/fixtures/fastapi-app/routes/admin.py +42 -0
- package/tests/fixtures/graphql/simple-schema.graphql +65 -0
- package/tests/fixtures/mocks/github-api-responses.json +63 -0
- package/tests/fixtures/nextjs-app/app/api/posts/route.ts +55 -0
- package/tests/fixtures/nextjs-app/app/api/users/[id]/route.ts +63 -0
- package/tests/fixtures/nextjs-app/app/api/users/route.ts +44 -0
- package/tests/fixtures/nextjs-app/pages/api/health.ts +28 -0
- package/tests/fixtures/openapi/petstore.yaml +179 -0
- package/tests/integration/langchain-export.test.ts +405 -0
- package/tests/integration/openapi-conversion.test.ts +221 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +32 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Module exports and initialization
|
|
3
|
+
* Multi-format API specification parser with unified interface
|
|
4
|
+
* Supports: OpenAPI, AsyncAPI, GraphQL, gRPC/Protobuf, Postman, Insomnia, HAR
|
|
5
|
+
* @copyright Copyright (c) 2024-2026 nirholas
|
|
6
|
+
* @license MIT
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { OpenAPIV3 } from 'openapi-types';
|
|
10
|
+
import { OpenApiParser } from './parser.js';
|
|
11
|
+
import { OpenApiAnalyzer, type EndpointInfo } from './analyzer.js';
|
|
12
|
+
import { OpenApiTransformer, type TransformOptions, type McpToolDefinition } from './transformer.js';
|
|
13
|
+
import { CodeGenerator, type GeneratorOptions } from './generator.js';
|
|
14
|
+
import { parseAsyncAPI, type AsyncAPIParseResult, type AsyncAPIToolDefinition } from './asyncapi-parser.js';
|
|
15
|
+
import { parseGraphQL, type GraphQLParseResult, type GraphQLToolDefinition } from './graphql-parser.js';
|
|
16
|
+
import { GrpcParser, type GrpcParseResult, type GrpcToolDefinition, type ProtobufService, type ProtobufMessage, type ProtobufEnum, type ProtobufRpcMethod } from './grpc-parser.js';
|
|
17
|
+
import { parsePostman, type PostmanParseResult, type PostmanToolDefinition } from './postman-parser.js';
|
|
18
|
+
import { parseInsomnia, type InsomniaParseResult, type InsomniaToolDefinition } from './insomnia-parser.js';
|
|
19
|
+
import { parseHAR, type HarParseResult, type HarToolDefinition } from './har-parser.js';
|
|
20
|
+
import { RefResolver, resolveRefs, type RefResolverOptions, type ResolvedSpec } from './ref-resolver.js';
|
|
21
|
+
import { promises as fs } from 'fs';
|
|
22
|
+
import path from 'path';
|
|
23
|
+
import yaml from 'js-yaml';
|
|
24
|
+
|
|
25
|
+
// Export generators module
|
|
26
|
+
export * from './generators/index.js';
|
|
27
|
+
export {
|
|
28
|
+
ExpressAnalyzer,
|
|
29
|
+
FastAPIAnalyzer,
|
|
30
|
+
NextJSAnalyzer,
|
|
31
|
+
OpenApiBuilder,
|
|
32
|
+
generateOpenApiFromCode,
|
|
33
|
+
generateOpenApiFromCodeWithDetails,
|
|
34
|
+
analyzeFiles,
|
|
35
|
+
detectFramework,
|
|
36
|
+
analyzeWithFramework,
|
|
37
|
+
} from './generators/index.js';
|
|
38
|
+
|
|
39
|
+
// Export gRPC parser
|
|
40
|
+
export { GrpcParser, type GrpcParseResult, type GrpcToolDefinition, type ProtobufService, type ProtobufMessage, type ProtobufEnum, type ProtobufRpcMethod };
|
|
41
|
+
|
|
42
|
+
export interface ConverterConfig {
|
|
43
|
+
/** OpenAPI spec source (file path or URL) */
|
|
44
|
+
spec: string;
|
|
45
|
+
|
|
46
|
+
/** Output directory */
|
|
47
|
+
outputDir: string;
|
|
48
|
+
|
|
49
|
+
/** Base URL for API (overrides spec) */
|
|
50
|
+
baseUrl?: string;
|
|
51
|
+
|
|
52
|
+
/** Filter options */
|
|
53
|
+
filters?: {
|
|
54
|
+
tags?: string[];
|
|
55
|
+
paths?: string[];
|
|
56
|
+
methods?: string[];
|
|
57
|
+
include?: string[];
|
|
58
|
+
exclude?: string[];
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** Transformation options */
|
|
62
|
+
transform?: TransformOptions;
|
|
63
|
+
|
|
64
|
+
/** Generation options */
|
|
65
|
+
generation?: Partial<GeneratorOptions>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface ConversionStats {
|
|
69
|
+
spec: {
|
|
70
|
+
title: string;
|
|
71
|
+
version: string;
|
|
72
|
+
endpoints: number;
|
|
73
|
+
};
|
|
74
|
+
conversion: {
|
|
75
|
+
toolsGenerated: number;
|
|
76
|
+
filesCreated: number;
|
|
77
|
+
duration: number;
|
|
78
|
+
};
|
|
79
|
+
breakdown: {
|
|
80
|
+
byMethod: Record<string, number>;
|
|
81
|
+
byTag: Record<string, number>;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Main converter class - orchestrates the conversion pipeline
|
|
87
|
+
*/
|
|
88
|
+
export class OpenApiToMcp {
|
|
89
|
+
private parser: OpenApiParser;
|
|
90
|
+
private analyzer: OpenApiAnalyzer | null = null;
|
|
91
|
+
private transformer: OpenApiTransformer | null = null;
|
|
92
|
+
private generator: CodeGenerator | null = null;
|
|
93
|
+
|
|
94
|
+
private tools: McpToolDefinition[] = [];
|
|
95
|
+
private stats: ConversionStats | null = null;
|
|
96
|
+
|
|
97
|
+
constructor(private config: ConverterConfig) {
|
|
98
|
+
this.parser = new OpenApiParser();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Run the complete conversion pipeline
|
|
103
|
+
*/
|
|
104
|
+
async convert(): Promise<ConversionStats> {
|
|
105
|
+
const startTime = Date.now();
|
|
106
|
+
|
|
107
|
+
console.log('🔍 Parsing OpenAPI specification...');
|
|
108
|
+
const spec = await this.parser.parse(this.config.spec);
|
|
109
|
+
const specInfo = this.parser.getInfo();
|
|
110
|
+
|
|
111
|
+
console.log(`✅ Parsed: ${specInfo.title} v${specInfo.version}`);
|
|
112
|
+
|
|
113
|
+
console.log('📊 Analyzing endpoints...');
|
|
114
|
+
// Cast to OpenAPIV3.Document - OpenAPI 3.1 is mostly compatible for our analysis
|
|
115
|
+
const v3Spec = spec as OpenAPIV3.Document;
|
|
116
|
+
this.analyzer = new OpenApiAnalyzer(v3Spec);
|
|
117
|
+
let endpoints = this.analyzer.extractEndpoints(this.config.filters);
|
|
118
|
+
|
|
119
|
+
// Apply include/exclude filters
|
|
120
|
+
if (this.config.filters?.include) {
|
|
121
|
+
endpoints = endpoints.filter(e =>
|
|
122
|
+
this.config.filters!.include!.includes(e.operationId || '')
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
if (this.config.filters?.exclude) {
|
|
126
|
+
endpoints = endpoints.filter(e =>
|
|
127
|
+
!this.config.filters!.exclude!.includes(e.operationId || '')
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
console.log(`✅ Found ${endpoints.length} endpoints`);
|
|
132
|
+
|
|
133
|
+
console.log('🔄 Transforming to MCP tools...');
|
|
134
|
+
this.transformer = new OpenApiTransformer(v3Spec, this.config.transform);
|
|
135
|
+
|
|
136
|
+
// Detect pagination for endpoints
|
|
137
|
+
const paginationMap = new Map();
|
|
138
|
+
for (const endpoint of endpoints) {
|
|
139
|
+
const pagination = this.analyzer.detectPagination(endpoint);
|
|
140
|
+
if (pagination) {
|
|
141
|
+
const key = `${endpoint.method}:${endpoint.path}`;
|
|
142
|
+
paginationMap.set(key, pagination);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.tools = this.transformer.transformEndpoints(endpoints, paginationMap);
|
|
147
|
+
console.log(`✅ Generated ${this.tools.length} MCP tools`);
|
|
148
|
+
|
|
149
|
+
console.log('💻 Generating code...');
|
|
150
|
+
const baseUrl = this.config.baseUrl || this.parser.getBaseUrl();
|
|
151
|
+
const generatorOptions: GeneratorOptions = {
|
|
152
|
+
format: 'typescript',
|
|
153
|
+
serverName: specInfo.title,
|
|
154
|
+
serverVersion: specInfo.version,
|
|
155
|
+
baseUrl,
|
|
156
|
+
...this.config.generation,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
this.generator = new CodeGenerator(generatorOptions);
|
|
160
|
+
|
|
161
|
+
// Group tools by tag
|
|
162
|
+
const toolGroups = new Map<string, McpToolDefinition[]>();
|
|
163
|
+
for (const tool of this.tools) {
|
|
164
|
+
const group = tool.metadata.tags?.[0] || 'default';
|
|
165
|
+
if (!toolGroups.has(group)) {
|
|
166
|
+
toolGroups.set(group, []);
|
|
167
|
+
}
|
|
168
|
+
toolGroups.get(group)!.push(tool);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const files = this.generator.generateServer(this.tools, toolGroups);
|
|
172
|
+
|
|
173
|
+
console.log('📝 Writing files...');
|
|
174
|
+
await this.writeFiles(files);
|
|
175
|
+
console.log(`✅ Created ${files.size} files`);
|
|
176
|
+
|
|
177
|
+
const duration = Date.now() - startTime;
|
|
178
|
+
|
|
179
|
+
this.stats = {
|
|
180
|
+
spec: {
|
|
181
|
+
title: specInfo.title,
|
|
182
|
+
version: specInfo.version,
|
|
183
|
+
endpoints: endpoints.length,
|
|
184
|
+
},
|
|
185
|
+
conversion: {
|
|
186
|
+
toolsGenerated: this.tools.length,
|
|
187
|
+
filesCreated: files.size,
|
|
188
|
+
duration,
|
|
189
|
+
},
|
|
190
|
+
breakdown: this.analyzer.getEndpointStats(endpoints) as any,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
console.log('\n✨ Conversion complete!');
|
|
194
|
+
console.log(`⏱️ Duration: ${(duration / 1000).toFixed(2)}s`);
|
|
195
|
+
console.log(`📁 Output: ${this.config.outputDir}`);
|
|
196
|
+
|
|
197
|
+
return this.stats;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Write generated files to disk
|
|
202
|
+
*/
|
|
203
|
+
private async writeFiles(files: Map<string, string>): Promise<void> {
|
|
204
|
+
// Create output directory
|
|
205
|
+
await fs.mkdir(this.config.outputDir, { recursive: true });
|
|
206
|
+
|
|
207
|
+
// Write each file
|
|
208
|
+
for (const [relativePath, content] of files.entries()) {
|
|
209
|
+
const fullPath = path.join(this.config.outputDir, relativePath);
|
|
210
|
+
const dir = path.dirname(fullPath);
|
|
211
|
+
|
|
212
|
+
// Ensure directory exists
|
|
213
|
+
await fs.mkdir(dir, { recursive: true });
|
|
214
|
+
|
|
215
|
+
// Write file
|
|
216
|
+
await fs.writeFile(fullPath, content, 'utf-8');
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Get generated tools
|
|
222
|
+
*/
|
|
223
|
+
getTools(): McpToolDefinition[] {
|
|
224
|
+
return this.tools;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Get conversion statistics
|
|
229
|
+
*/
|
|
230
|
+
getStats(): ConversionStats | null {
|
|
231
|
+
return this.stats;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Preview conversion (don't write files)
|
|
236
|
+
*/
|
|
237
|
+
async preview(): Promise<{
|
|
238
|
+
tools: McpToolDefinition[];
|
|
239
|
+
stats: any;
|
|
240
|
+
}> {
|
|
241
|
+
const spec = await this.parser.parse(this.config.spec);
|
|
242
|
+
// Cast to OpenAPIV3.Document - OpenAPI 3.1 is mostly compatible
|
|
243
|
+
const v3Spec = spec as OpenAPIV3.Document;
|
|
244
|
+
this.analyzer = new OpenApiAnalyzer(v3Spec);
|
|
245
|
+
|
|
246
|
+
let endpoints = this.analyzer.extractEndpoints(this.config.filters);
|
|
247
|
+
|
|
248
|
+
if (this.config.filters?.include) {
|
|
249
|
+
endpoints = endpoints.filter(e =>
|
|
250
|
+
this.config.filters!.include!.includes(e.operationId || '')
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
if (this.config.filters?.exclude) {
|
|
254
|
+
endpoints = endpoints.filter(e =>
|
|
255
|
+
!this.config.filters!.exclude!.includes(e.operationId || '')
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
this.transformer = new OpenApiTransformer(v3Spec, this.config.transform);
|
|
260
|
+
const tools = this.transformer.transformEndpoints(endpoints);
|
|
261
|
+
const stats = this.analyzer.getEndpointStats(endpoints);
|
|
262
|
+
|
|
263
|
+
return { tools, stats };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Convenience function to convert OpenAPI spec to MCP tools
|
|
269
|
+
*/
|
|
270
|
+
export async function convertOpenApiToMcp(spec: any): Promise<{
|
|
271
|
+
tools: McpToolDefinition[];
|
|
272
|
+
stats: any;
|
|
273
|
+
}> {
|
|
274
|
+
const parser = new OpenApiParser();
|
|
275
|
+
const parsedSpec = parser.parseObject(spec);
|
|
276
|
+
const v3Spec = parsedSpec as OpenAPIV3.Document;
|
|
277
|
+
|
|
278
|
+
const analyzer = new OpenApiAnalyzer(v3Spec);
|
|
279
|
+
const endpoints = analyzer.extractEndpoints();
|
|
280
|
+
|
|
281
|
+
const transformer = new OpenApiTransformer(v3Spec);
|
|
282
|
+
const tools = transformer.transformEndpoints(endpoints);
|
|
283
|
+
const stats = analyzer.getEndpointStats(endpoints);
|
|
284
|
+
|
|
285
|
+
return { tools, stats };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Export all types (excluding duplicates)
|
|
289
|
+
export * from './parser.js';
|
|
290
|
+
export * from './analyzer.js';
|
|
291
|
+
export * from './transformer.js';
|
|
292
|
+
// Note: GeneratorOptions is exported from generators/types.js, not generator.js to avoid conflicts
|
|
293
|
+
export { CodeGenerator } from './generator.js';
|
|
294
|
+
export * from './asyncapi-parser.js';
|
|
295
|
+
export * from './graphql-parser.js';
|
|
296
|
+
export * from './postman-parser.js';
|
|
297
|
+
export * from './insomnia-parser.js';
|
|
298
|
+
export * from './har-parser.js';
|
|
299
|
+
export * from './ref-resolver.js';
|
|
300
|
+
|
|
301
|
+
// ============================================================================
|
|
302
|
+
// Unified Parser Interface
|
|
303
|
+
// ============================================================================
|
|
304
|
+
|
|
305
|
+
/** Supported API specification formats */
|
|
306
|
+
export type SpecFormat = 'openapi' | 'asyncapi' | 'graphql' | 'postman' | 'insomnia' | 'har';
|
|
307
|
+
|
|
308
|
+
/** Unified tool definition */
|
|
309
|
+
export interface UnifiedToolDefinition {
|
|
310
|
+
name: string;
|
|
311
|
+
description: string;
|
|
312
|
+
inputSchema: {
|
|
313
|
+
type: 'object';
|
|
314
|
+
properties: Record<string, any>;
|
|
315
|
+
required?: string[];
|
|
316
|
+
};
|
|
317
|
+
metadata: {
|
|
318
|
+
format: SpecFormat;
|
|
319
|
+
endpoint?: {
|
|
320
|
+
path: string;
|
|
321
|
+
method: string;
|
|
322
|
+
};
|
|
323
|
+
channel?: string;
|
|
324
|
+
operationType?: 'query' | 'mutation' | 'subscription';
|
|
325
|
+
auth?: {
|
|
326
|
+
type: string;
|
|
327
|
+
envVar?: string;
|
|
328
|
+
};
|
|
329
|
+
tags?: string[];
|
|
330
|
+
deprecated?: boolean;
|
|
331
|
+
confidence?: 'high' | 'medium' | 'low';
|
|
332
|
+
};
|
|
333
|
+
examples?: Array<{ input?: any; output?: any }>;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Unified parse options */
|
|
337
|
+
export interface ParseOptions {
|
|
338
|
+
/** Specify format or auto-detect if not specified */
|
|
339
|
+
format?: SpecFormat;
|
|
340
|
+
/** How to group operations */
|
|
341
|
+
groupBy?: 'tags' | 'paths' | 'none';
|
|
342
|
+
/** Include examples in output */
|
|
343
|
+
includeExamples?: boolean;
|
|
344
|
+
/** Resolve external $ref references */
|
|
345
|
+
resolveRefs?: boolean;
|
|
346
|
+
/** Include deprecated operations */
|
|
347
|
+
includeDeprecated?: boolean;
|
|
348
|
+
/** Custom operation filter */
|
|
349
|
+
operationFilter?: (op: any) => boolean;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** Unified parse result */
|
|
353
|
+
export interface UnifiedParseResult {
|
|
354
|
+
format: SpecFormat;
|
|
355
|
+
info: {
|
|
356
|
+
title?: string;
|
|
357
|
+
version?: string;
|
|
358
|
+
description?: string;
|
|
359
|
+
};
|
|
360
|
+
tools: UnifiedToolDefinition[];
|
|
361
|
+
auth?: {
|
|
362
|
+
type: string;
|
|
363
|
+
schemes?: Array<{ name: string; type: string }>;
|
|
364
|
+
};
|
|
365
|
+
errors?: Array<{ message: string; location?: string }>;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Detect the format of an API specification
|
|
370
|
+
*/
|
|
371
|
+
export function detectFormat(input: string | object): SpecFormat {
|
|
372
|
+
let obj: any;
|
|
373
|
+
|
|
374
|
+
if (typeof input === 'string') {
|
|
375
|
+
const trimmed = input.trim();
|
|
376
|
+
|
|
377
|
+
// Check for GraphQL SDL patterns first (before YAML parsing which can succeed on SDL)
|
|
378
|
+
if (trimmed.includes('type Query') ||
|
|
379
|
+
trimmed.includes('type Mutation') ||
|
|
380
|
+
trimmed.includes('type Subscription') ||
|
|
381
|
+
trimmed.includes('schema {') ||
|
|
382
|
+
/^\s*type\s+\w+\s*\{/.test(trimmed)) {
|
|
383
|
+
return 'graphql';
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Try JSON first
|
|
387
|
+
if (trimmed.startsWith('{')) {
|
|
388
|
+
try {
|
|
389
|
+
obj = JSON.parse(trimmed);
|
|
390
|
+
} catch {
|
|
391
|
+
// Try YAML
|
|
392
|
+
try {
|
|
393
|
+
obj = yaml.load(trimmed);
|
|
394
|
+
} catch {
|
|
395
|
+
throw new Error('Unable to parse input as JSON, YAML, or GraphQL SDL');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
// Likely YAML
|
|
400
|
+
try {
|
|
401
|
+
obj = yaml.load(trimmed);
|
|
402
|
+
} catch {
|
|
403
|
+
throw new Error('Unable to parse input as JSON, YAML, or GraphQL SDL');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
} else {
|
|
407
|
+
obj = input;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (!obj || typeof obj !== 'object') {
|
|
411
|
+
throw new Error('Invalid input: expected an object');
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// OpenAPI detection
|
|
415
|
+
if ('openapi' in obj || 'swagger' in obj) {
|
|
416
|
+
return 'openapi';
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// AsyncAPI detection
|
|
420
|
+
if ('asyncapi' in obj) {
|
|
421
|
+
return 'asyncapi';
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Postman Collection detection
|
|
425
|
+
// Check for Postman collection schema URL (should be at the start of the schema property)
|
|
426
|
+
if ('info' in obj && typeof obj.info?.schema === 'string') {
|
|
427
|
+
const schema = obj.info.schema;
|
|
428
|
+
// Postman collection schemas follow the pattern: https://schema.getpostman.com/...
|
|
429
|
+
if (schema.startsWith('https://schema.getpostman.com/') ||
|
|
430
|
+
schema.startsWith('http://schema.getpostman.com/')) {
|
|
431
|
+
return 'postman';
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
// Fallback detection for Postman collections without schema field
|
|
435
|
+
if ('info' in obj && 'item' in obj && Array.isArray(obj.item)) {
|
|
436
|
+
return 'postman';
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Insomnia export detection
|
|
440
|
+
if (obj._type === 'export' && '__export_format' in obj) {
|
|
441
|
+
return 'insomnia';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// HAR file detection
|
|
445
|
+
if ('log' in obj && obj.log?.version && Array.isArray(obj.log?.entries)) {
|
|
446
|
+
return 'har';
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// GraphQL introspection result detection
|
|
450
|
+
if ('__schema' in obj || (obj.data && '__schema' in obj.data)) {
|
|
451
|
+
return 'graphql';
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
throw new Error('Unable to detect specification format');
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Convert format-specific tools to unified format
|
|
459
|
+
*/
|
|
460
|
+
function toUnifiedTools(
|
|
461
|
+
tools: any[],
|
|
462
|
+
format: SpecFormat
|
|
463
|
+
): UnifiedToolDefinition[] {
|
|
464
|
+
return tools.map(tool => ({
|
|
465
|
+
name: tool.name,
|
|
466
|
+
description: tool.description,
|
|
467
|
+
inputSchema: tool.inputSchema,
|
|
468
|
+
metadata: {
|
|
469
|
+
format,
|
|
470
|
+
endpoint: tool.metadata?.endpoint,
|
|
471
|
+
channel: tool.metadata?.channel,
|
|
472
|
+
operationType: tool.metadata?.operationType,
|
|
473
|
+
auth: tool.metadata?.auth,
|
|
474
|
+
tags: tool.metadata?.tags,
|
|
475
|
+
deprecated: tool.metadata?.deprecated,
|
|
476
|
+
confidence: tool.metadata?.confidence,
|
|
477
|
+
},
|
|
478
|
+
examples: tool.examples,
|
|
479
|
+
}));
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Unified parser entry point - parses any supported specification format
|
|
484
|
+
*/
|
|
485
|
+
export async function parseSpec(
|
|
486
|
+
input: string | object,
|
|
487
|
+
options: ParseOptions = {}
|
|
488
|
+
): Promise<UnifiedParseResult> {
|
|
489
|
+
const format = options.format || detectFormat(input);
|
|
490
|
+
|
|
491
|
+
switch (format) {
|
|
492
|
+
case 'openapi': {
|
|
493
|
+
const parser = new OpenApiParser();
|
|
494
|
+
let spec: any;
|
|
495
|
+
|
|
496
|
+
if (typeof input === 'string') {
|
|
497
|
+
// Check if it's a file path or content
|
|
498
|
+
if (input.trim().startsWith('{') || input.trim().startsWith('openapi:') || input.trim().startsWith('swagger:')) {
|
|
499
|
+
// It's content, parse it
|
|
500
|
+
try {
|
|
501
|
+
spec = JSON.parse(input);
|
|
502
|
+
} catch {
|
|
503
|
+
spec = yaml.load(input);
|
|
504
|
+
}
|
|
505
|
+
parser.parseObject(spec);
|
|
506
|
+
} else {
|
|
507
|
+
// It's a file path
|
|
508
|
+
spec = await parser.parse(input);
|
|
509
|
+
}
|
|
510
|
+
} else {
|
|
511
|
+
spec = parser.parseObject(input as any);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Optionally resolve refs
|
|
515
|
+
if (options.resolveRefs) {
|
|
516
|
+
const resolved = await resolveRefs(spec);
|
|
517
|
+
spec = resolved.spec;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const v3Spec = spec as OpenAPIV3.Document;
|
|
521
|
+
const analyzer = new OpenApiAnalyzer(v3Spec);
|
|
522
|
+
let endpoints = analyzer.extractEndpoints();
|
|
523
|
+
|
|
524
|
+
// Apply filters
|
|
525
|
+
if (!options.includeDeprecated) {
|
|
526
|
+
endpoints = endpoints.filter(e => !e.deprecated);
|
|
527
|
+
}
|
|
528
|
+
if (options.operationFilter) {
|
|
529
|
+
endpoints = endpoints.filter(options.operationFilter);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
const transformer = new OpenApiTransformer(v3Spec);
|
|
533
|
+
const tools = transformer.transformEndpoints(endpoints);
|
|
534
|
+
|
|
535
|
+
// Extract auth info
|
|
536
|
+
const authInfo = analyzer.getAuthenticationInfo();
|
|
537
|
+
|
|
538
|
+
return {
|
|
539
|
+
format: 'openapi',
|
|
540
|
+
info: {
|
|
541
|
+
title: spec.info?.title,
|
|
542
|
+
version: spec.info?.version,
|
|
543
|
+
description: spec.info?.description,
|
|
544
|
+
},
|
|
545
|
+
tools: toUnifiedTools(tools, 'openapi'),
|
|
546
|
+
auth: authInfo.length > 0 ? {
|
|
547
|
+
type: authInfo[0].type,
|
|
548
|
+
schemes: authInfo.map(a => ({ name: a.name || 'default', type: a.type })),
|
|
549
|
+
} : undefined,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
case 'asyncapi': {
|
|
554
|
+
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
555
|
+
const result = parseAsyncAPI(inputStr);
|
|
556
|
+
|
|
557
|
+
return {
|
|
558
|
+
format: 'asyncapi',
|
|
559
|
+
info: {
|
|
560
|
+
title: result.info.title,
|
|
561
|
+
version: result.info.version,
|
|
562
|
+
description: result.info.description,
|
|
563
|
+
},
|
|
564
|
+
tools: toUnifiedTools(result.tools, 'asyncapi'),
|
|
565
|
+
auth: Object.keys(result.securitySchemes).length > 0 ? {
|
|
566
|
+
type: 'multiple',
|
|
567
|
+
schemes: Object.entries(result.securitySchemes).map(([name, scheme]) => ({
|
|
568
|
+
name,
|
|
569
|
+
type: (scheme as any).type,
|
|
570
|
+
})),
|
|
571
|
+
} : undefined,
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
case 'graphql': {
|
|
576
|
+
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
577
|
+
const result = parseGraphQL(inputStr);
|
|
578
|
+
|
|
579
|
+
return {
|
|
580
|
+
format: 'graphql',
|
|
581
|
+
info: {
|
|
582
|
+
title: 'GraphQL API',
|
|
583
|
+
description: `${result.types.queries.length} queries, ${result.types.mutations.length} mutations, ${result.types.subscriptions.length} subscriptions`,
|
|
584
|
+
},
|
|
585
|
+
tools: toUnifiedTools(result.tools, 'graphql'),
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
case 'postman': {
|
|
590
|
+
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
591
|
+
const result = parsePostman(inputStr);
|
|
592
|
+
|
|
593
|
+
return {
|
|
594
|
+
format: 'postman',
|
|
595
|
+
info: {
|
|
596
|
+
title: result.info.name,
|
|
597
|
+
description: result.info.description,
|
|
598
|
+
},
|
|
599
|
+
tools: toUnifiedTools(result.tools, 'postman'),
|
|
600
|
+
auth: result.auth ? { type: result.auth.type } : undefined,
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
case 'insomnia': {
|
|
605
|
+
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
606
|
+
const result = parseInsomnia(inputStr);
|
|
607
|
+
|
|
608
|
+
return {
|
|
609
|
+
format: 'insomnia',
|
|
610
|
+
info: {
|
|
611
|
+
title: result.workspaces[0]?.name || 'Insomnia Collection',
|
|
612
|
+
description: result.workspaces[0]?.description,
|
|
613
|
+
},
|
|
614
|
+
tools: toUnifiedTools(result.tools, 'insomnia'),
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
case 'har': {
|
|
619
|
+
const inputStr = typeof input === 'string' ? input : JSON.stringify(input);
|
|
620
|
+
const result = parseHAR(inputStr);
|
|
621
|
+
|
|
622
|
+
return {
|
|
623
|
+
format: 'har',
|
|
624
|
+
info: {
|
|
625
|
+
title: 'API from HAR',
|
|
626
|
+
description: `Inferred from ${result.info.entryCount} captured requests (${result.info.endpointCount} unique endpoints)`,
|
|
627
|
+
},
|
|
628
|
+
tools: toUnifiedTools(result.tools, 'har'),
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
default:
|
|
633
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
634
|
+
}
|
|
635
|
+
}
|