mcpmake 0.1.1 → 0.2.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/dist/commands/bundle.d.ts +1 -0
- package/dist/commands/bundle.d.ts.map +1 -0
- package/dist/commands/bundle.js +5 -4
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/ci.d.ts +1 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +3 -2
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +4 -3
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/diff.d.ts +1 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +5 -4
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/from/describe.d.ts +1 -0
- package/dist/commands/from/describe.d.ts.map +1 -0
- package/dist/commands/from/describe.js +11 -10
- package/dist/commands/from/describe.js.map +1 -0
- package/dist/commands/from/har.d.ts +1 -0
- package/dist/commands/from/har.d.ts.map +1 -0
- package/dist/commands/from/har.js +14 -13
- package/dist/commands/from/har.js.map +1 -0
- package/dist/commands/from/openapi.d.ts +1 -0
- package/dist/commands/from/openapi.d.ts.map +1 -0
- package/dist/commands/from/openapi.js +17 -16
- package/dist/commands/from/openapi.js.map +1 -0
- package/dist/commands/from/postman.d.ts +1 -0
- package/dist/commands/from/postman.d.ts.map +1 -0
- package/dist/commands/from/postman.js +13 -12
- package/dist/commands/from/postman.js.map +1 -0
- package/dist/commands/from/stainless.d.ts +110 -0
- package/dist/commands/from/stainless.d.ts.map +1 -0
- package/dist/commands/from/stainless.js +272 -0
- package/dist/commands/from/stainless.js.map +1 -0
- package/dist/commands/from/target-support.d.ts +1 -0
- package/dist/commands/from/target-support.d.ts.map +1 -0
- package/dist/commands/from/target-support.js +2 -1
- package/dist/commands/from/target-support.js.map +1 -0
- package/dist/commands/from/url.d.ts +1 -0
- package/dist/commands/from/url.d.ts.map +1 -0
- package/dist/commands/from/url.js +14 -13
- package/dist/commands/from/url.js.map +1 -0
- package/dist/commands/from/website.d.ts +1 -0
- package/dist/commands/from/website.d.ts.map +1 -0
- package/dist/commands/from/website.js +17 -16
- package/dist/commands/from/website.js.map +1 -0
- package/dist/commands/lint.d.ts +1 -0
- package/dist/commands/lint.d.ts.map +1 -0
- package/dist/commands/lint.js +6 -5
- package/dist/commands/lint.js.map +1 -0
- package/dist/commands/merge.d.ts +1 -0
- package/dist/commands/merge.d.ts.map +1 -0
- package/dist/commands/merge.js +3 -2
- package/dist/commands/merge.js.map +1 -0
- package/dist/commands/publish.d.ts +1 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +4 -3
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/rescan.d.ts +1 -0
- package/dist/commands/rescan.d.ts.map +1 -0
- package/dist/commands/rescan.js +12 -11
- package/dist/commands/rescan.js.map +1 -0
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +10 -9
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +1 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +7 -6
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -0
- package/dist/registry/official-registry.d.ts +1 -0
- package/dist/registry/official-registry.d.ts.map +1 -0
- package/dist/registry/official-registry.js +1 -0
- package/dist/registry/official-registry.js.map +1 -0
- package/package.json +20 -46
- package/README.md +0 -691
- package/dist/analyzer/auth-detector.d.ts +0 -12
- package/dist/analyzer/auth-detector.js +0 -142
- package/dist/analyzer/dom-parser.d.ts +0 -10
- package/dist/analyzer/dom-parser.js +0 -259
- package/dist/analyzer/goal-crawler.d.ts +0 -25
- package/dist/analyzer/goal-crawler.js +0 -177
- package/dist/analyzer/hybrid-detector.d.ts +0 -28
- package/dist/analyzer/hybrid-detector.js +0 -96
- package/dist/analyzer/index.d.ts +0 -12
- package/dist/analyzer/index.js +0 -8
- package/dist/analyzer/screenshot-capture.d.ts +0 -29
- package/dist/analyzer/screenshot-capture.js +0 -42
- package/dist/analyzer/selector-builder.d.ts +0 -19
- package/dist/analyzer/selector-builder.js +0 -199
- package/dist/analyzer/semantic-analyzer.d.ts +0 -13
- package/dist/analyzer/semantic-analyzer.js +0 -145
- package/dist/analyzer/site-crawler.d.ts +0 -38
- package/dist/analyzer/site-crawler.js +0 -235
- package/dist/cloud/billing/billing-engine.d.ts +0 -44
- package/dist/cloud/billing/billing-engine.js +0 -81
- package/dist/cloud/billing/credit-store.d.ts +0 -64
- package/dist/cloud/billing/credit-store.js +0 -168
- package/dist/cloud/billing/index.d.ts +0 -4
- package/dist/cloud/billing/index.js +0 -2
- package/dist/cloud/billing/usage-store.d.ts +0 -42
- package/dist/cloud/billing/usage-store.js +0 -85
- package/dist/cloud/billing/usage-tracker.d.ts +0 -38
- package/dist/cloud/billing/usage-tracker.js +0 -95
- package/dist/cloud/build-pipeline.d.ts +0 -39
- package/dist/cloud/build-pipeline.js +0 -310
- package/dist/cloud/build-queue.d.ts +0 -30
- package/dist/cloud/build-queue.js +0 -70
- package/dist/cloud/caddy-manager.d.ts +0 -18
- package/dist/cloud/caddy-manager.js +0 -97
- package/dist/cloud/container-backend.d.ts +0 -62
- package/dist/cloud/container-backend.js +0 -59
- package/dist/cloud/container-manager.d.ts +0 -64
- package/dist/cloud/container-manager.js +0 -301
- package/dist/cloud/crypto.d.ts +0 -27
- package/dist/cloud/crypto.js +0 -63
- package/dist/cloud/db/index.d.ts +0 -27
- package/dist/cloud/db/index.js +0 -53
- package/dist/cloud/db/migrations.d.ts +0 -12
- package/dist/cloud/db/migrations.js +0 -329
- package/dist/cloud/db/pg-store.d.ts +0 -45
- package/dist/cloud/db/pg-store.js +0 -336
- package/dist/cloud/failure-tracker.d.ts +0 -51
- package/dist/cloud/failure-tracker.js +0 -102
- package/dist/cloud/idle-monitor.d.ts +0 -30
- package/dist/cloud/idle-monitor.js +0 -70
- package/dist/cloud/mailer.d.ts +0 -21
- package/dist/cloud/mailer.js +0 -193
- package/dist/cloud/mcp-proxy.d.ts +0 -58
- package/dist/cloud/mcp-proxy.js +0 -203
- package/dist/cloud/metric-samples.d.ts +0 -43
- package/dist/cloud/metric-samples.js +0 -85
- package/dist/cloud/metrics.d.ts +0 -26
- package/dist/cloud/metrics.js +0 -59
- package/dist/cloud/multipart.d.ts +0 -26
- package/dist/cloud/multipart.js +0 -132
- package/dist/cloud/observability.d.ts +0 -27
- package/dist/cloud/observability.js +0 -98
- package/dist/cloud/rate-limiter.d.ts +0 -31
- package/dist/cloud/rate-limiter.js +0 -58
- package/dist/cloud/request-security.d.ts +0 -5
- package/dist/cloud/request-security.js +0 -74
- package/dist/cloud/resource-monitor.d.ts +0 -69
- package/dist/cloud/resource-monitor.js +0 -130
- package/dist/cloud/secret-store.d.ts +0 -38
- package/dist/cloud/secret-store.js +0 -103
- package/dist/cloud/security.d.ts +0 -26
- package/dist/cloud/security.js +0 -142
- package/dist/cloud/server.d.ts +0 -21
- package/dist/cloud/server.js +0 -1079
- package/dist/cloud/shared-state.d.ts +0 -72
- package/dist/cloud/shared-state.js +0 -159
- package/dist/cloud/ssrf.d.ts +0 -43
- package/dist/cloud/ssrf.js +0 -150
- package/dist/cloud/store.d.ts +0 -41
- package/dist/cloud/store.js +0 -75
- package/dist/cloud/stripe.d.ts +0 -78
- package/dist/cloud/stripe.js +0 -317
- package/dist/cloud/telemetry-store.d.ts +0 -53
- package/dist/cloud/telemetry-store.js +0 -108
- package/dist/cloud/web/auth.d.ts +0 -225
- package/dist/cloud/web/auth.js +0 -555
- package/dist/cloud/web/charts.d.ts +0 -70
- package/dist/cloud/web/charts.js +0 -178
- package/dist/cloud/web/csrf.d.ts +0 -14
- package/dist/cloud/web/csrf.js +0 -22
- package/dist/cloud/web/docs.d.ts +0 -40
- package/dist/cloud/web/docs.js +0 -174
- package/dist/cloud/web/router.d.ts +0 -25
- package/dist/cloud/web/router.js +0 -1921
- package/dist/cloud/web/static/alpine.min.js +0 -5
- package/dist/cloud/web/static/favicon.svg +0 -4
- package/dist/cloud/web/static/htmx-sse.js +0 -290
- package/dist/cloud/web/static/htmx.min.js +0 -1
- package/dist/cloud/web/static/style.css +0 -2683
- package/dist/cloud/web/static-server.d.ts +0 -13
- package/dist/cloud/web/static-server.js +0 -73
- package/dist/cloud/web/template-engine.d.ts +0 -27
- package/dist/cloud/web/template-engine.js +0 -146
- package/dist/cloud/web/templates/layouts/admin.hbs +0 -57
- package/dist/cloud/web/templates/layouts/auth.hbs +0 -138
- package/dist/cloud/web/templates/layouts/base.hbs +0 -16
- package/dist/cloud/web/templates/layouts/dashboard.hbs +0 -39
- package/dist/cloud/web/templates/layouts/landing.hbs +0 -82
- package/dist/cloud/web/templates/pages/admin/overview.hbs +0 -123
- package/dist/cloud/web/templates/pages/admin/servers.hbs +0 -129
- package/dist/cloud/web/templates/pages/admin/telemetry.hbs +0 -39
- package/dist/cloud/web/templates/pages/admin/user-edit.hbs +0 -91
- package/dist/cloud/web/templates/pages/admin/users.hbs +0 -179
- package/dist/cloud/web/templates/pages/auth/forgot-password.hbs +0 -25
- package/dist/cloud/web/templates/pages/auth/login.hbs +0 -33
- package/dist/cloud/web/templates/pages/auth/register.hbs +0 -32
- package/dist/cloud/web/templates/pages/auth/reset-password.hbs +0 -34
- package/dist/cloud/web/templates/pages/dashboard/billing.hbs +0 -140
- package/dist/cloud/web/templates/pages/dashboard/create.hbs +0 -173
- package/dist/cloud/web/templates/pages/dashboard/index.hbs +0 -8
- package/dist/cloud/web/templates/pages/dashboard/server-detail.hbs +0 -280
- package/dist/cloud/web/templates/pages/dashboard/server-logs.hbs +0 -35
- package/dist/cloud/web/templates/pages/dashboard/server-metrics.hbs +0 -63
- package/dist/cloud/web/templates/pages/dashboard/servers-partial.hbs +0 -21
- package/dist/cloud/web/templates/pages/dashboard/servers.hbs +0 -44
- package/dist/cloud/web/templates/pages/docs/show.hbs +0 -16
- package/dist/cloud/web/templates/pages/errors/404.hbs +0 -9
- package/dist/cloud/web/templates/pages/errors/500.hbs +0 -8
- package/dist/cloud/web/templates/pages/landing/index.hbs +0 -223
- package/dist/cloud/web/templates/pages/legal/privacy.hbs +0 -71
- package/dist/cloud/web/templates/pages/legal/terms.hbs +0 -73
- package/dist/cloud/web/templates/partials/admin-stats.hbs +0 -52
- package/dist/cloud/web/templates/partials/flash-message.hbs +0 -6
- package/dist/cloud/web/templates/partials/pricing-table.hbs +0 -103
- package/dist/cloud/web/templates/partials/server-card.hbs +0 -19
- package/dist/cloud/web/templates/partials/status-badge.hbs +0 -1
- package/dist/config/configurable-command.d.ts +0 -13
- package/dist/config/configurable-command.js +0 -70
- package/dist/config/mcpmake-config.d.ts +0 -68
- package/dist/config/mcpmake-config.js +0 -207
- package/dist/docs/cli.md +0 -400
- package/dist/docs/mcp-2026-07-28-migration.md +0 -78
- package/dist/docs/migrate-from-stainless.md +0 -94
- package/dist/docs/quickstart.md +0 -166
- package/dist/docs/show-hn.md +0 -26
- package/dist/docs/website-servers.md +0 -169
- package/dist/emitter/code-writer.d.ts +0 -8
- package/dist/emitter/code-writer.js +0 -25
- package/dist/emitter/index.d.ts +0 -32
- package/dist/emitter/index.js +0 -280
- package/dist/emitter/mcpb-bundler.d.ts +0 -31
- package/dist/emitter/mcpb-bundler.js +0 -172
- package/dist/emitter/project-scaffolder.d.ts +0 -4
- package/dist/emitter/project-scaffolder.js +0 -89
- package/dist/emitter/python-template-loader.d.ts +0 -4
- package/dist/emitter/python-template-loader.js +0 -30
- package/dist/emitter/python-templates/dockerfile.hbs +0 -14
- package/dist/emitter/python-templates/env.example.hbs +0 -6
- package/dist/emitter/python-templates/requirements.txt.hbs +0 -4
- package/dist/emitter/python-templates/server.py.hbs +0 -77
- package/dist/emitter/site-scaffolder.d.ts +0 -13
- package/dist/emitter/site-scaffolder.js +0 -70
- package/dist/emitter/site-template-loader.d.ts +0 -5
- package/dist/emitter/site-template-loader.js +0 -47
- package/dist/emitter/site-templates/browser-manager.ts.hbs +0 -233
- package/dist/emitter/site-templates/config.ts.hbs +0 -28
- package/dist/emitter/site-templates/dockerfile.hbs +0 -31
- package/dist/emitter/site-templates/env.example.hbs +0 -19
- package/dist/emitter/site-templates/package.json.hbs +0 -26
- package/dist/emitter/site-templates/server-main-http.ts.hbs +0 -108
- package/dist/emitter/site-templates/server-main.ts.hbs +0 -23
- package/dist/emitter/site-templates/tool-handler-action.ts.hbs +0 -86
- package/dist/emitter/site-templates/tool-handler-form.ts.hbs +0 -116
- package/dist/emitter/site-templates/tool-handler-lifecycle.ts.hbs +0 -146
- package/dist/emitter/site-templates/tool-index.ts.hbs +0 -11
- package/dist/emitter/template-loader.d.ts +0 -1
- package/dist/emitter/template-loader.js +0 -27
- package/dist/emitter/templates/auth-provider.ts.hbs +0 -57
- package/dist/emitter/templates/config.ts.hbs +0 -63
- package/dist/emitter/templates/discovery.ts.hbs +0 -301
- package/dist/emitter/templates/dockerfile.hbs +0 -34
- package/dist/emitter/templates/env.example.hbs +0 -28
- package/dist/emitter/templates/gitignore.hbs +0 -5
- package/dist/emitter/templates/http-executor.ts.hbs +0 -117
- package/dist/emitter/templates/oauth.ts.hbs +0 -188
- package/dist/emitter/templates/package.json.hbs +0 -25
- package/dist/emitter/templates/prompts.ts.hbs +0 -22
- package/dist/emitter/templates/readme.md.hbs +0 -123
- package/dist/emitter/templates/resources.ts.hbs +0 -63
- package/dist/emitter/templates/server-main-http.ts.hbs +0 -407
- package/dist/emitter/templates/server-main.ts.hbs +0 -40
- package/dist/emitter/templates/task-handlers.ts.hbs +0 -189
- package/dist/emitter/templates/task-manager.ts.hbs +0 -139
- package/dist/emitter/templates/task-sse.ts.hbs +0 -105
- package/dist/emitter/templates/tool-handler.ts.hbs +0 -124
- package/dist/emitter/templates/tool-index.ts.hbs +0 -11
- package/dist/emitter/templates/tool-test.ts.hbs +0 -57
- package/dist/emitter/templates/trace.ts.hbs +0 -79
- package/dist/emitter/templates/tsconfig.json.hbs +0 -16
- package/dist/emitter/templates/types.ts.hbs +0 -5
- package/dist/emitter/worker-template-loader.d.ts +0 -5
- package/dist/emitter/worker-template-loader.js +0 -33
- package/dist/emitter/worker-templates/config.ts.hbs +0 -54
- package/dist/emitter/worker-templates/dev-vars.example.hbs +0 -10
- package/dist/emitter/worker-templates/gitignore.hbs +0 -6
- package/dist/emitter/worker-templates/package.json.hbs +0 -24
- package/dist/emitter/worker-templates/readme.md.hbs +0 -53
- package/dist/emitter/worker-templates/server.test.ts.hbs +0 -20
- package/dist/emitter/worker-templates/tool-handler.ts.hbs +0 -85
- package/dist/emitter/worker-templates/tool-index.ts.hbs +0 -28
- package/dist/emitter/worker-templates/tsconfig.json.hbs +0 -17
- package/dist/emitter/worker-templates/worker.ts.hbs +0 -242
- package/dist/emitter/worker-templates/wrangler.toml.hbs +0 -19
- package/dist/generator/spec-generator.d.ts +0 -6
- package/dist/generator/spec-generator.js +0 -50
- package/dist/parser/har-filter.d.ts +0 -8
- package/dist/parser/har-filter.js +0 -71
- package/dist/parser/har-loader.d.ts +0 -2
- package/dist/parser/har-loader.js +0 -14
- package/dist/parser/har-normalizer.d.ts +0 -20
- package/dist/parser/har-normalizer.js +0 -78
- package/dist/parser/index.d.ts +0 -10
- package/dist/parser/index.js +0 -6
- package/dist/parser/openapi-loader.d.ts +0 -6
- package/dist/parser/openapi-loader.js +0 -308
- package/dist/parser/operation-extractor.d.ts +0 -13
- package/dist/parser/operation-extractor.js +0 -155
- package/dist/parser/overlay-loader.d.ts +0 -10
- package/dist/parser/overlay-loader.js +0 -184
- package/dist/parser/postman-loader.d.ts +0 -9
- package/dist/parser/postman-loader.js +0 -106
- package/dist/parser/schema-converter.d.ts +0 -12
- package/dist/parser/schema-converter.js +0 -117
- package/dist/plugins/adapter.d.ts +0 -40
- package/dist/plugins/adapter.js +0 -15
- package/dist/plugins/loader.d.ts +0 -25
- package/dist/plugins/loader.js +0 -58
- package/dist/pricing.d.ts +0 -55
- package/dist/pricing.js +0 -133
- package/dist/providers/index.d.ts +0 -15
- package/dist/providers/index.js +0 -56
- package/dist/recorder/browser-recorder.d.ts +0 -22
- package/dist/recorder/browser-recorder.js +0 -205
- package/dist/rescan/diff-engine.d.ts +0 -5
- package/dist/rescan/diff-engine.js +0 -312
- package/dist/rescan/index.d.ts +0 -3
- package/dist/rescan/index.js +0 -2
- package/dist/rescan/rescan-runner.d.ts +0 -42
- package/dist/rescan/rescan-runner.js +0 -69
- package/dist/rescan/rescan-scheduler.d.ts +0 -41
- package/dist/rescan/rescan-scheduler.js +0 -179
- package/dist/site-transformer/browser-tools.d.ts +0 -10
- package/dist/site-transformer/browser-tools.js +0 -59
- package/dist/site-transformer/index.d.ts +0 -2
- package/dist/site-transformer/index.js +0 -2
- package/dist/site-transformer/selector-healer.d.ts +0 -8
- package/dist/site-transformer/selector-healer.js +0 -106
- package/dist/site-transformer/tool-generator.d.ts +0 -13
- package/dist/site-transformer/tool-generator.js +0 -245
- package/dist/transformer/auth-detector.d.ts +0 -13
- package/dist/transformer/auth-detector.js +0 -90
- package/dist/transformer/catalog-builder.d.ts +0 -18
- package/dist/transformer/catalog-builder.js +0 -56
- package/dist/transformer/client-compat.d.ts +0 -6
- package/dist/transformer/client-compat.js +0 -44
- package/dist/transformer/har-clusterer.d.ts +0 -9
- package/dist/transformer/har-clusterer.js +0 -27
- package/dist/transformer/har-dedup.d.ts +0 -10
- package/dist/transformer/har-dedup.js +0 -81
- package/dist/transformer/har-schema-inferrer.d.ts +0 -15
- package/dist/transformer/har-schema-inferrer.js +0 -90
- package/dist/transformer/har-to-operations.d.ts +0 -13
- package/dist/transformer/har-to-operations.js +0 -192
- package/dist/transformer/index.d.ts +0 -8
- package/dist/transformer/index.js +0 -6
- package/dist/transformer/llm-namer.d.ts +0 -6
- package/dist/transformer/llm-namer.js +0 -59
- package/dist/transformer/naming.d.ts +0 -4
- package/dist/transformer/naming.js +0 -30
- package/dist/transformer/operation-filter.d.ts +0 -13
- package/dist/transformer/operation-filter.js +0 -52
- package/dist/transformer/resource-builder.d.ts +0 -12
- package/dist/transformer/resource-builder.js +0 -80
- package/dist/transformer/schema-merger.d.ts +0 -14
- package/dist/transformer/schema-merger.js +0 -65
- package/dist/transformer/tool-builder.d.ts +0 -3
- package/dist/transformer/tool-builder.js +0 -114
- package/dist/types/index.d.ts +0 -131
- package/dist/types/index.js +0 -1
- package/dist/types/site.d.ts +0 -284
- package/dist/types/site.js +0 -8
- package/dist/utils/fail.d.ts +0 -48
- package/dist/utils/fail.js +0 -204
- package/dist/utils/fs.d.ts +0 -5
- package/dist/utils/fs.js +0 -28
- package/dist/utils/interactive.d.ts +0 -6
- package/dist/utils/interactive.js +0 -30
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.js +0 -2
- package/dist/utils/sanitize.d.ts +0 -28
- package/dist/utils/sanitize.js +0 -44
- package/dist/utils/watcher.d.ts +0 -11
- package/dist/utils/watcher.js +0 -36
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import { logger } from '../utils/logger.js';
|
|
3
|
-
const SYSTEM_PROMPT = `You are an API architect. Given a description of an API or service, generate a valid OpenAPI 3.0 specification in JSON format.
|
|
4
|
-
|
|
5
|
-
Rules:
|
|
6
|
-
- Output ONLY valid JSON (no markdown fences, no explanation)
|
|
7
|
-
- Include realistic endpoints with proper HTTP methods
|
|
8
|
-
- Use descriptive operationIds in camelCase
|
|
9
|
-
- Include request/response schemas with realistic field types
|
|
10
|
-
- Add path parameters, query parameters, and request bodies where appropriate
|
|
11
|
-
- Include at least one security scheme if auth is likely needed
|
|
12
|
-
- Include a servers array with a base URL
|
|
13
|
-
- Keep it practical — 3-10 operations is typical`;
|
|
14
|
-
export async function generateSpecFromDescription(options) {
|
|
15
|
-
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
16
|
-
if (!apiKey) {
|
|
17
|
-
throw new Error('ANTHROPIC_API_KEY environment variable is required for describe mode.\n' +
|
|
18
|
-
'Set it with: export ANTHROPIC_API_KEY=your-key-here');
|
|
19
|
-
}
|
|
20
|
-
const client = new Anthropic({ apiKey });
|
|
21
|
-
const model = options.model ?? 'claude-sonnet-4-20250514';
|
|
22
|
-
let userPrompt = `Generate an OpenAPI 3.0 spec for: ${options.description}`;
|
|
23
|
-
if (options.baseUrl) {
|
|
24
|
-
userPrompt += `\n\nUse this base URL: ${options.baseUrl}`;
|
|
25
|
-
}
|
|
26
|
-
logger.info('Generating OpenAPI spec from description...');
|
|
27
|
-
const message = await client.messages.create({
|
|
28
|
-
model,
|
|
29
|
-
max_tokens: 4096,
|
|
30
|
-
system: SYSTEM_PROMPT,
|
|
31
|
-
messages: [{ role: 'user', content: userPrompt }],
|
|
32
|
-
});
|
|
33
|
-
const content = message.content[0];
|
|
34
|
-
if (content.type !== 'text') {
|
|
35
|
-
throw new Error('Unexpected response format from Claude');
|
|
36
|
-
}
|
|
37
|
-
// Extract JSON — strip markdown fences if present
|
|
38
|
-
let json = content.text.trim();
|
|
39
|
-
if (json.startsWith('```')) {
|
|
40
|
-
json = json.replace(/^```(?:json)?\n?/, '').replace(/\n?```$/, '');
|
|
41
|
-
}
|
|
42
|
-
// Validate it's parseable JSON
|
|
43
|
-
try {
|
|
44
|
-
JSON.parse(json);
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
throw new Error('Claude returned invalid JSON. Try again or refine your description.');
|
|
48
|
-
}
|
|
49
|
-
return json;
|
|
50
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Entry } from 'har-format';
|
|
2
|
-
export interface FilterOptions {
|
|
3
|
-
/** Only include entries from these domains. If empty, include all. */
|
|
4
|
-
allowedDomains?: string[];
|
|
5
|
-
/** Include requests that returned errors (4xx/5xx). Default: false */
|
|
6
|
-
includeErrors?: boolean;
|
|
7
|
-
}
|
|
8
|
-
export declare function filterHarEntries(entries: Entry[], options?: FilterOptions): Entry[];
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
const NOISE_EXTENSIONS = /\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|map|webp|avif)(\?|$)/i;
|
|
2
|
-
const ANALYTICS_DOMAINS = [
|
|
3
|
-
'google-analytics.com',
|
|
4
|
-
'googletagmanager.com',
|
|
5
|
-
'analytics.',
|
|
6
|
-
'mixpanel.com',
|
|
7
|
-
'segment.io',
|
|
8
|
-
'segment.com',
|
|
9
|
-
'hotjar.com',
|
|
10
|
-
'doubleclick.net',
|
|
11
|
-
'facebook.net',
|
|
12
|
-
'fbcdn.net',
|
|
13
|
-
'sentry.io',
|
|
14
|
-
'newrelic.com',
|
|
15
|
-
'datadoghq.com',
|
|
16
|
-
'clarity.ms',
|
|
17
|
-
];
|
|
18
|
-
const SKIP_MIME_TYPES = [
|
|
19
|
-
'text/html',
|
|
20
|
-
'text/css',
|
|
21
|
-
'application/javascript',
|
|
22
|
-
'text/javascript',
|
|
23
|
-
'image/',
|
|
24
|
-
'font/',
|
|
25
|
-
'audio/',
|
|
26
|
-
'video/',
|
|
27
|
-
];
|
|
28
|
-
export function filterHarEntries(entries, options = {}) {
|
|
29
|
-
return entries.filter((entry) => {
|
|
30
|
-
const url = entry.request.url;
|
|
31
|
-
let hostname;
|
|
32
|
-
try {
|
|
33
|
-
hostname = new URL(url).hostname;
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
// Skip non-HTTP methods
|
|
39
|
-
const method = entry.request.method.toUpperCase();
|
|
40
|
-
if (method === 'CONNECT' || method === 'OPTIONS')
|
|
41
|
-
return false;
|
|
42
|
-
// Skip static assets by extension
|
|
43
|
-
const pathname = new URL(url).pathname;
|
|
44
|
-
if (NOISE_EXTENSIONS.test(pathname))
|
|
45
|
-
return false;
|
|
46
|
-
// Skip analytics/tracking domains
|
|
47
|
-
if (ANALYTICS_DOMAINS.some((d) => hostname.includes(d)))
|
|
48
|
-
return false;
|
|
49
|
-
// Domain allowlist
|
|
50
|
-
if (options.allowedDomains?.length) {
|
|
51
|
-
if (!options.allowedDomains.some((d) => hostname.includes(d)))
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
// Skip error responses unless requested
|
|
55
|
-
if (!options.includeErrors && entry.response.status >= 400)
|
|
56
|
-
return false;
|
|
57
|
-
// Skip non-API content types in response
|
|
58
|
-
const responseMime = entry.response.content?.mimeType ?? '';
|
|
59
|
-
if (SKIP_MIME_TYPES.some((m) => responseMime.startsWith(m))) {
|
|
60
|
-
// Exception: text/html that's actually an API response (rare but possible)
|
|
61
|
-
// Keep if response body looks like JSON
|
|
62
|
-
if (responseMime.startsWith('text/html') && !entry.response.content?.text?.startsWith('{')) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
if (!responseMime.includes('json') && !responseMime.includes('xml')) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return true;
|
|
70
|
-
});
|
|
71
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { readFile, stat } from 'node:fs/promises';
|
|
2
|
-
const MAX_HAR_SIZE_BYTES = 50 * 1024 * 1024; // 50 MB
|
|
3
|
-
export async function loadHarFile(filePath) {
|
|
4
|
-
const fileInfo = await stat(filePath);
|
|
5
|
-
if (fileInfo.size > MAX_HAR_SIZE_BYTES) {
|
|
6
|
-
throw new Error(`HAR file is too large (${Math.round(fileInfo.size / 1024 / 1024)} MB). Maximum is 50 MB.`);
|
|
7
|
-
}
|
|
8
|
-
const raw = await readFile(filePath, 'utf-8');
|
|
9
|
-
const har = JSON.parse(raw);
|
|
10
|
-
if (!har.log?.entries || !Array.isArray(har.log.entries)) {
|
|
11
|
-
throw new Error('Invalid HAR file: missing log.entries array');
|
|
12
|
-
}
|
|
13
|
-
return har;
|
|
14
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { Entry } from 'har-format';
|
|
2
|
-
export interface NormalizedEntry {
|
|
3
|
-
entry: Entry;
|
|
4
|
-
normalizedPath: string;
|
|
5
|
-
baseUrl: string;
|
|
6
|
-
pathParams: PathParam[];
|
|
7
|
-
queryParams: QueryParam[];
|
|
8
|
-
}
|
|
9
|
-
export interface PathParam {
|
|
10
|
-
name: string;
|
|
11
|
-
position: number;
|
|
12
|
-
exampleValue: string;
|
|
13
|
-
inferredType: 'uuid' | 'integer' | 'string';
|
|
14
|
-
}
|
|
15
|
-
export interface QueryParam {
|
|
16
|
-
name: string;
|
|
17
|
-
exampleValue: string;
|
|
18
|
-
inferredType: 'integer' | 'boolean' | 'string';
|
|
19
|
-
}
|
|
20
|
-
export declare function normalizeEntry(entry: Entry): NormalizedEntry;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2
|
-
const NUMERIC_ID_PATTERN = /^\d+$/;
|
|
3
|
-
const MONGO_ID_PATTERN = /^[0-9a-f]{24}$/i;
|
|
4
|
-
const SHORT_ID_PATTERN = /^[a-zA-Z0-9]{8,22}$/;
|
|
5
|
-
export function normalizeEntry(entry) {
|
|
6
|
-
const url = new URL(entry.request.url);
|
|
7
|
-
const baseUrl = `${url.protocol}//${url.host}`;
|
|
8
|
-
const segments = url.pathname.split('/').filter(Boolean);
|
|
9
|
-
const pathParams = [];
|
|
10
|
-
let paramCounter = 0;
|
|
11
|
-
const normalizedSegments = segments.map((segment, i) => {
|
|
12
|
-
if (UUID_PATTERN.test(segment)) {
|
|
13
|
-
const name = deriveParamName(segments, i, paramCounter++);
|
|
14
|
-
pathParams.push({ name, position: i, exampleValue: segment, inferredType: 'uuid' });
|
|
15
|
-
return `{${name}}`;
|
|
16
|
-
}
|
|
17
|
-
if (NUMERIC_ID_PATTERN.test(segment) && segment.length < 15) {
|
|
18
|
-
const name = deriveParamName(segments, i, paramCounter++);
|
|
19
|
-
pathParams.push({ name, position: i, exampleValue: segment, inferredType: 'integer' });
|
|
20
|
-
return `{${name}}`;
|
|
21
|
-
}
|
|
22
|
-
if (MONGO_ID_PATTERN.test(segment)) {
|
|
23
|
-
const name = deriveParamName(segments, i, paramCounter++);
|
|
24
|
-
pathParams.push({ name, position: i, exampleValue: segment, inferredType: 'string' });
|
|
25
|
-
return `{${name}}`;
|
|
26
|
-
}
|
|
27
|
-
// Heuristic: if previous segment is a known collection name and this looks like an ID
|
|
28
|
-
if (i > 0 && isCollectionName(segments[i - 1]) && SHORT_ID_PATTERN.test(segment)) {
|
|
29
|
-
const prevSegment = segments[i - 1];
|
|
30
|
-
// Only treat as ID if short enough and not a known sub-resource
|
|
31
|
-
if (segment.length <= 22 && !isCollectionName(segment)) {
|
|
32
|
-
const name = singularize(prevSegment) + 'Id';
|
|
33
|
-
pathParams.push({ name, position: i, exampleValue: segment, inferredType: 'string' });
|
|
34
|
-
return `{${name}}`;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return segment;
|
|
38
|
-
});
|
|
39
|
-
const normalizedPath = '/' + normalizedSegments.join('/');
|
|
40
|
-
const queryParams = [];
|
|
41
|
-
for (const qs of entry.request.queryString) {
|
|
42
|
-
queryParams.push({
|
|
43
|
-
name: qs.name,
|
|
44
|
-
exampleValue: qs.value,
|
|
45
|
-
inferredType: inferQueryParamType(qs.value),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
return { entry, normalizedPath, baseUrl, pathParams, queryParams };
|
|
49
|
-
}
|
|
50
|
-
function deriveParamName(segments, currentIndex, counter) {
|
|
51
|
-
if (currentIndex > 0) {
|
|
52
|
-
const prev = segments[currentIndex - 1];
|
|
53
|
-
if (isCollectionName(prev)) {
|
|
54
|
-
return singularize(prev) + 'Id';
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return counter === 0 ? 'id' : `id${counter + 1}`;
|
|
58
|
-
}
|
|
59
|
-
function isCollectionName(segment) {
|
|
60
|
-
// Common REST patterns: plurals, known resource names
|
|
61
|
-
return (/^[a-z][a-z0-9_-]*s$/i.test(segment) || ['api', 'v1', 'v2', 'v3'].includes(segment) === false);
|
|
62
|
-
}
|
|
63
|
-
function singularize(word) {
|
|
64
|
-
if (word.endsWith('ies'))
|
|
65
|
-
return word.slice(0, -3) + 'y';
|
|
66
|
-
if (word.endsWith('ses') || word.endsWith('xes') || word.endsWith('zes'))
|
|
67
|
-
return word.slice(0, -2);
|
|
68
|
-
if (word.endsWith('s') && !word.endsWith('ss'))
|
|
69
|
-
return word.slice(0, -1);
|
|
70
|
-
return word;
|
|
71
|
-
}
|
|
72
|
-
function inferQueryParamType(value) {
|
|
73
|
-
if (NUMERIC_ID_PATTERN.test(value))
|
|
74
|
-
return 'integer';
|
|
75
|
-
if (value === 'true' || value === 'false')
|
|
76
|
-
return 'boolean';
|
|
77
|
-
return 'string';
|
|
78
|
-
}
|
package/dist/parser/index.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export { loadOpenApiSpec } from './openapi-loader.js';
|
|
2
|
-
export type { LoadResult } from './openapi-loader.js';
|
|
3
|
-
export { extractOperations } from './operation-extractor.js';
|
|
4
|
-
export type { ExtractionResult } from './operation-extractor.js';
|
|
5
|
-
export { jsonSchemaToZodCode, buildOperationInputSchema } from './schema-converter.js';
|
|
6
|
-
export { loadHarFile } from './har-loader.js';
|
|
7
|
-
export { filterHarEntries } from './har-filter.js';
|
|
8
|
-
export type { FilterOptions } from './har-filter.js';
|
|
9
|
-
export { normalizeEntry } from './har-normalizer.js';
|
|
10
|
-
export type { NormalizedEntry, PathParam, QueryParam } from './har-normalizer.js';
|
package/dist/parser/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { loadOpenApiSpec } from './openapi-loader.js';
|
|
2
|
-
export { extractOperations } from './operation-extractor.js';
|
|
3
|
-
export { jsonSchemaToZodCode, buildOperationInputSchema } from './schema-converter.js';
|
|
4
|
-
export { loadHarFile } from './har-loader.js';
|
|
5
|
-
export { filterHarEntries } from './har-filter.js';
|
|
6
|
-
export { normalizeEntry } from './har-normalizer.js';
|
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import SwaggerParser from '@apidevtools/swagger-parser';
|
|
2
|
-
import { logger } from '../utils/logger.js';
|
|
3
|
-
/**
|
|
4
|
-
* Detects if a parsed document is Swagger 2.0 and converts it to OpenAPI 3.0.
|
|
5
|
-
*/
|
|
6
|
-
function isSwagger2(doc) {
|
|
7
|
-
return typeof doc.swagger === 'string' && doc.swagger.startsWith('2.');
|
|
8
|
-
}
|
|
9
|
-
function convertSwagger2ToOpenApi3(doc) {
|
|
10
|
-
logger.warn('Converting Swagger 2.0 to OpenAPI 3.0');
|
|
11
|
-
const scheme = doc.schemes?.[0] ?? 'https';
|
|
12
|
-
const host = doc.host ?? 'localhost';
|
|
13
|
-
const basePath = doc.basePath ?? '/';
|
|
14
|
-
const serverUrl = `${scheme}://${host}${basePath === '/' ? '' : basePath}`;
|
|
15
|
-
const globalConsumes = doc.consumes ?? ['application/json'];
|
|
16
|
-
const globalProduces = doc.produces ?? ['application/json'];
|
|
17
|
-
const components = {};
|
|
18
|
-
// Map definitions -> components.schemas
|
|
19
|
-
if (doc.definitions) {
|
|
20
|
-
components.schemas = doc.definitions;
|
|
21
|
-
}
|
|
22
|
-
// Map parameters -> components.parameters
|
|
23
|
-
if (doc.parameters) {
|
|
24
|
-
components.parameters = convertParameterDefinitions(doc.parameters);
|
|
25
|
-
}
|
|
26
|
-
// Map securityDefinitions -> components.securitySchemes
|
|
27
|
-
if (doc.securityDefinitions) {
|
|
28
|
-
components.securitySchemes = convertSecurityDefinitions(doc.securityDefinitions);
|
|
29
|
-
}
|
|
30
|
-
// Convert paths
|
|
31
|
-
const convertedPaths = {};
|
|
32
|
-
if (doc.paths) {
|
|
33
|
-
for (const [path, pathItem] of Object.entries(doc.paths)) {
|
|
34
|
-
convertedPaths[path] = convertPathItem(pathItem, globalConsumes, globalProduces);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
const result = {
|
|
38
|
-
openapi: '3.0.0',
|
|
39
|
-
info: doc.info,
|
|
40
|
-
servers: [{ url: serverUrl }],
|
|
41
|
-
paths: convertedPaths,
|
|
42
|
-
};
|
|
43
|
-
if (Object.keys(components).length > 0) {
|
|
44
|
-
result.components = components;
|
|
45
|
-
}
|
|
46
|
-
if (doc.security) {
|
|
47
|
-
result.security = doc.security;
|
|
48
|
-
}
|
|
49
|
-
if (doc.tags) {
|
|
50
|
-
result.tags = doc.tags;
|
|
51
|
-
}
|
|
52
|
-
if (doc.externalDocs) {
|
|
53
|
-
result.externalDocs = doc.externalDocs;
|
|
54
|
-
}
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
function convertPathItem(pathItem, globalConsumes, globalProduces) {
|
|
58
|
-
const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];
|
|
59
|
-
const result = {};
|
|
60
|
-
// Preserve path-level parameters
|
|
61
|
-
if (pathItem.parameters) {
|
|
62
|
-
result.parameters = convertParameters(pathItem.parameters);
|
|
63
|
-
}
|
|
64
|
-
for (const method of methods) {
|
|
65
|
-
const operation = pathItem[method];
|
|
66
|
-
if (!operation)
|
|
67
|
-
continue;
|
|
68
|
-
result[method] = convertOperation(operation, globalConsumes, globalProduces);
|
|
69
|
-
}
|
|
70
|
-
return result;
|
|
71
|
-
}
|
|
72
|
-
function convertOperation(operation, globalConsumes, globalProduces) {
|
|
73
|
-
const consumes = operation.consumes ?? globalConsumes;
|
|
74
|
-
const produces = operation.produces ?? globalProduces;
|
|
75
|
-
const converted = {};
|
|
76
|
-
// Copy simple fields
|
|
77
|
-
for (const key of ['operationId', 'summary', 'description', 'tags', 'deprecated', 'security']) {
|
|
78
|
-
if (operation[key] !== undefined) {
|
|
79
|
-
converted[key] = operation[key];
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
// Copy x- extension fields
|
|
83
|
-
for (const key of Object.keys(operation)) {
|
|
84
|
-
if (key.startsWith('x-')) {
|
|
85
|
-
converted[key] = operation[key];
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// Separate body/formData params from regular params
|
|
89
|
-
const params = (operation.parameters ?? []);
|
|
90
|
-
const regularParams = [];
|
|
91
|
-
let bodyParam;
|
|
92
|
-
const formDataParams = [];
|
|
93
|
-
for (const p of params) {
|
|
94
|
-
if (p.in === 'body') {
|
|
95
|
-
bodyParam = p;
|
|
96
|
-
}
|
|
97
|
-
else if (p.in === 'formData') {
|
|
98
|
-
formDataParams.push(p);
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
regularParams.push(p);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (regularParams.length > 0) {
|
|
105
|
-
converted.parameters = convertParameters(regularParams);
|
|
106
|
-
}
|
|
107
|
-
// Build requestBody from body param or formData params
|
|
108
|
-
if (bodyParam) {
|
|
109
|
-
const contentType = consumes[0] ?? 'application/json';
|
|
110
|
-
converted.requestBody = {
|
|
111
|
-
description: bodyParam.description,
|
|
112
|
-
required: bodyParam.required ?? false,
|
|
113
|
-
content: {
|
|
114
|
-
[contentType]: {
|
|
115
|
-
schema: convertSchemaRef(bodyParam.schema),
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
else if (formDataParams.length > 0) {
|
|
121
|
-
const hasFile = formDataParams.some((p) => p.type === 'file');
|
|
122
|
-
const contentType = hasFile ? 'multipart/form-data' : 'application/x-www-form-urlencoded';
|
|
123
|
-
const properties = {};
|
|
124
|
-
const required = [];
|
|
125
|
-
for (const p of formDataParams) {
|
|
126
|
-
const name = p.name;
|
|
127
|
-
if (p.type === 'file') {
|
|
128
|
-
properties[name] = { type: 'string', format: 'binary' };
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
properties[name] = { type: p.type ?? 'string' };
|
|
132
|
-
if (p.description) {
|
|
133
|
-
properties[name].description = p.description;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (p.required) {
|
|
137
|
-
required.push(name);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
converted.requestBody = {
|
|
141
|
-
content: {
|
|
142
|
-
[contentType]: {
|
|
143
|
-
schema: {
|
|
144
|
-
type: 'object',
|
|
145
|
-
properties,
|
|
146
|
-
...(required.length > 0 ? { required } : {}),
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
// Convert responses
|
|
153
|
-
const responses = (operation.responses ?? {});
|
|
154
|
-
const convertedResponses = {};
|
|
155
|
-
for (const [status, response] of Object.entries(responses)) {
|
|
156
|
-
const convertedResponse = {
|
|
157
|
-
description: response.description ?? '',
|
|
158
|
-
};
|
|
159
|
-
if (response.schema) {
|
|
160
|
-
const contentType = produces[0] ?? 'application/json';
|
|
161
|
-
convertedResponse.content = {
|
|
162
|
-
[contentType]: {
|
|
163
|
-
schema: convertSchemaRef(response.schema),
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
if (response.headers) {
|
|
168
|
-
convertedResponse.headers = response.headers;
|
|
169
|
-
}
|
|
170
|
-
convertedResponses[status] = convertedResponse;
|
|
171
|
-
}
|
|
172
|
-
converted.responses = convertedResponses;
|
|
173
|
-
return converted;
|
|
174
|
-
}
|
|
175
|
-
function convertParameters(params) {
|
|
176
|
-
return params.map((p) => {
|
|
177
|
-
const converted = {
|
|
178
|
-
name: p.name,
|
|
179
|
-
in: p.in,
|
|
180
|
-
};
|
|
181
|
-
if (p.required !== undefined)
|
|
182
|
-
converted.required = p.required;
|
|
183
|
-
if (p.description !== undefined)
|
|
184
|
-
converted.description = p.description;
|
|
185
|
-
// Build schema from Swagger 2.0 parameter type fields
|
|
186
|
-
const schema = {};
|
|
187
|
-
if (p.type)
|
|
188
|
-
schema.type = p.type;
|
|
189
|
-
if (p.format)
|
|
190
|
-
schema.format = p.format;
|
|
191
|
-
if (p.enum)
|
|
192
|
-
schema.enum = p.enum;
|
|
193
|
-
if (p.default !== undefined)
|
|
194
|
-
schema.default = p.default;
|
|
195
|
-
if (p.items)
|
|
196
|
-
schema.items = p.items;
|
|
197
|
-
if (p.minimum !== undefined)
|
|
198
|
-
schema.minimum = p.minimum;
|
|
199
|
-
if (p.maximum !== undefined)
|
|
200
|
-
schema.maximum = p.maximum;
|
|
201
|
-
converted.schema = Object.keys(schema).length > 0 ? schema : { type: 'string' };
|
|
202
|
-
return converted;
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
function convertParameterDefinitions(params) {
|
|
206
|
-
const result = {};
|
|
207
|
-
for (const [name, param] of Object.entries(params)) {
|
|
208
|
-
const p = param;
|
|
209
|
-
if (p.in === 'body') {
|
|
210
|
-
// Body parameters in definitions are unusual; skip them for components.parameters
|
|
211
|
-
continue;
|
|
212
|
-
}
|
|
213
|
-
const converted = {
|
|
214
|
-
name: p.name ?? name,
|
|
215
|
-
in: p.in,
|
|
216
|
-
};
|
|
217
|
-
if (p.required !== undefined)
|
|
218
|
-
converted.required = p.required;
|
|
219
|
-
if (p.description !== undefined)
|
|
220
|
-
converted.description = p.description;
|
|
221
|
-
const schema = {};
|
|
222
|
-
if (p.type)
|
|
223
|
-
schema.type = p.type;
|
|
224
|
-
if (p.format)
|
|
225
|
-
schema.format = p.format;
|
|
226
|
-
if (p.enum)
|
|
227
|
-
schema.enum = p.enum;
|
|
228
|
-
converted.schema = Object.keys(schema).length > 0 ? schema : { type: 'string' };
|
|
229
|
-
result[name] = converted;
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
}
|
|
233
|
-
function convertSecurityDefinitions(defs) {
|
|
234
|
-
const result = {};
|
|
235
|
-
for (const [name, def] of Object.entries(defs)) {
|
|
236
|
-
const d = def;
|
|
237
|
-
switch (d.type) {
|
|
238
|
-
case 'basic':
|
|
239
|
-
result[name] = { type: 'http', scheme: 'basic' };
|
|
240
|
-
break;
|
|
241
|
-
case 'apiKey':
|
|
242
|
-
result[name] = { type: 'apiKey', name: d.name, in: d.in };
|
|
243
|
-
break;
|
|
244
|
-
case 'oauth2': {
|
|
245
|
-
const scheme = { type: 'oauth2', flows: {} };
|
|
246
|
-
const flows = scheme.flows;
|
|
247
|
-
const scopes = (d.scopes ?? {});
|
|
248
|
-
switch (d.flow) {
|
|
249
|
-
case 'implicit':
|
|
250
|
-
flows.implicit = { authorizationUrl: d.authorizationUrl, scopes };
|
|
251
|
-
break;
|
|
252
|
-
case 'password':
|
|
253
|
-
flows.password = { tokenUrl: d.tokenUrl, scopes };
|
|
254
|
-
break;
|
|
255
|
-
case 'application':
|
|
256
|
-
flows.clientCredentials = { tokenUrl: d.tokenUrl, scopes };
|
|
257
|
-
break;
|
|
258
|
-
case 'accessCode':
|
|
259
|
-
flows.authorizationCode = {
|
|
260
|
-
authorizationUrl: d.authorizationUrl,
|
|
261
|
-
tokenUrl: d.tokenUrl,
|
|
262
|
-
scopes,
|
|
263
|
-
};
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
result[name] = scheme;
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
default:
|
|
270
|
-
result[name] = d;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return result;
|
|
274
|
-
}
|
|
275
|
-
function convertSchemaRef(schema) {
|
|
276
|
-
if (!schema)
|
|
277
|
-
return {};
|
|
278
|
-
// Swagger 2.0 uses #/definitions/Foo, OpenAPI 3.0 uses #/components/schemas/Foo
|
|
279
|
-
// Since we move definitions -> components.schemas, update $ref paths
|
|
280
|
-
const result = {};
|
|
281
|
-
for (const [key, value] of Object.entries(schema)) {
|
|
282
|
-
if (key === '$ref' && typeof value === 'string') {
|
|
283
|
-
result.$ref = value.replace('#/definitions/', '#/components/schemas/');
|
|
284
|
-
}
|
|
285
|
-
else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
286
|
-
result[key] = convertSchemaRef(value);
|
|
287
|
-
}
|
|
288
|
-
else if (Array.isArray(value)) {
|
|
289
|
-
result[key] = value.map((item) => typeof item === 'object' && item !== null
|
|
290
|
-
? convertSchemaRef(item)
|
|
291
|
-
: item);
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
result[key] = value;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return result;
|
|
298
|
-
}
|
|
299
|
-
export async function loadOpenApiSpec(input) {
|
|
300
|
-
// First, parse without dereferencing to check for Swagger 2.0
|
|
301
|
-
const raw = (await SwaggerParser.parse(input));
|
|
302
|
-
let specToParse = input;
|
|
303
|
-
if (isSwagger2(raw)) {
|
|
304
|
-
specToParse = convertSwagger2ToOpenApi3(raw);
|
|
305
|
-
}
|
|
306
|
-
const api = (await SwaggerParser.dereference(specToParse));
|
|
307
|
-
return { api, specPath: input };
|
|
308
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { OpenAPIV3 } from 'openapi-types';
|
|
2
|
-
import type { OperationDescriptor } from '../types/index.js';
|
|
3
|
-
export interface ExtractionResult {
|
|
4
|
-
operations: OperationDescriptor[];
|
|
5
|
-
baseUrl: string;
|
|
6
|
-
securitySchemes: Record<string, OpenAPIV3.SecuritySchemeObject>;
|
|
7
|
-
info: {
|
|
8
|
-
title: string;
|
|
9
|
-
version: string;
|
|
10
|
-
description?: string;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export declare function extractOperations(api: OpenAPIV3.Document): ExtractionResult;
|