docorbit 0.1.0 → 0.1.2
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/README.md +29 -15
- package/bin/docorbit.js +2 -2
- package/dist/apps/cli/src/commands/add.d.ts +7 -0
- package/dist/apps/cli/src/commands/add.js +35 -0
- package/dist/apps/cli/src/commands/api.d.ts +2 -0
- package/dist/apps/cli/src/commands/api.js +35 -0
- package/dist/apps/cli/src/commands/context.d.ts +10 -0
- package/dist/apps/cli/src/commands/context.js +36 -0
- package/dist/apps/cli/src/commands/dashboard.d.ts +8 -0
- package/dist/apps/cli/src/commands/dashboard.js +43 -0
- package/dist/apps/cli/src/commands/diff.d.ts +2 -0
- package/dist/apps/cli/src/commands/diff.js +29 -0
- package/dist/apps/cli/src/commands/evaluate.d.ts +11 -0
- package/dist/apps/cli/src/commands/evaluate.js +101 -0
- package/dist/apps/cli/src/commands/examples.d.ts +2 -0
- package/dist/apps/cli/src/commands/examples.js +36 -0
- package/dist/apps/cli/src/commands/export.d.ts +11 -0
- package/dist/apps/cli/src/commands/export.js +72 -0
- package/dist/apps/cli/src/commands/impact.d.ts +2 -0
- package/dist/apps/cli/src/commands/impact.js +30 -0
- package/dist/apps/cli/src/commands/init.d.ts +5 -0
- package/dist/apps/cli/src/commands/init.js +52 -0
- package/dist/apps/cli/src/commands/inspect.d.ts +5 -0
- package/dist/apps/cli/src/commands/inspect.js +24 -0
- package/dist/apps/cli/src/commands/mcp.d.ts +8 -0
- package/dist/apps/cli/src/commands/mcp.js +49 -0
- package/dist/apps/cli/src/commands/pitfalls.d.ts +2 -0
- package/dist/apps/cli/src/commands/pitfalls.js +35 -0
- package/dist/apps/cli/src/commands/recipes.d.ts +2 -0
- package/dist/apps/cli/src/commands/recipes.js +33 -0
- package/dist/apps/cli/src/commands/search.d.ts +11 -0
- package/dist/apps/cli/src/commands/search.js +36 -0
- package/dist/apps/cli/src/commands/update.d.ts +6 -0
- package/dist/apps/cli/src/commands/update.js +53 -0
- package/dist/apps/cli/src/commands/verify.d.ts +2 -0
- package/dist/apps/cli/src/commands/verify.js +44 -0
- package/dist/apps/cli/src/formatters/colors.d.ts +21 -0
- package/dist/apps/cli/src/formatters/colors.js +22 -0
- package/dist/apps/cli/src/formatters/inspection.d.ts +3 -0
- package/dist/apps/cli/src/formatters/inspection.js +88 -0
- package/dist/apps/cli/src/formatters/knowledge.d.ts +5 -0
- package/dist/apps/cli/src/formatters/knowledge.js +229 -0
- package/dist/apps/cli/src/formatters/retrieval.d.ts +3 -0
- package/dist/apps/cli/src/formatters/retrieval.js +61 -0
- package/{apps/cli/src/formatters/terminal.ts → dist/apps/cli/src/formatters/terminal.d.ts} +0 -1
- package/dist/apps/cli/src/formatters/terminal.js +5 -0
- package/dist/apps/cli/src/formatters/verification.d.ts +4 -0
- package/dist/apps/cli/src/formatters/verification.js +102 -0
- package/dist/apps/cli/src/index.d.ts +1 -0
- package/dist/apps/cli/src/index.js +376 -0
- package/dist/packages/core/src/dashboard/server.d.ts +33 -0
- package/dist/packages/core/src/dashboard/server.js +267 -0
- package/dist/packages/core/src/dashboard/ui.d.ts +5 -0
- package/{packages/core/src/dashboard/ui.ts → dist/packages/core/src/dashboard/ui.js} +2 -2
- package/dist/packages/core/src/implementation-service.d.ts +73 -0
- package/dist/packages/core/src/implementation-service.js +325 -0
- package/{packages/core/src/index.ts → dist/packages/core/src/index.d.ts} +0 -1
- package/dist/packages/core/src/index.js +6 -0
- package/dist/packages/core/src/inspector.d.ts +22 -0
- package/dist/packages/core/src/inspector.js +38 -0
- package/dist/packages/core/src/pipeline.d.ts +45 -0
- package/dist/packages/core/src/pipeline.js +246 -0
- package/dist/packages/crawler/src/config.d.ts +2 -0
- package/dist/packages/crawler/src/config.js +10 -0
- package/dist/packages/crawler/src/fetcher.d.ts +31 -0
- package/dist/packages/crawler/src/fetcher.js +139 -0
- package/dist/packages/crawler/src/index.js +2 -0
- package/dist/packages/discovery/src/index.d.ts +11 -0
- package/dist/packages/discovery/src/index.js +29 -0
- package/dist/packages/discovery/src/provider.d.ts +12 -0
- package/dist/packages/discovery/src/provider.js +30 -0
- package/dist/packages/discovery/src/providers/generic.d.ts +7 -0
- package/dist/packages/discovery/src/providers/generic.js +94 -0
- package/dist/packages/discovery/src/providers/github.d.ts +7 -0
- package/dist/packages/discovery/src/providers/github.js +52 -0
- package/dist/packages/discovery/src/providers/llms-txt.d.ts +7 -0
- package/dist/packages/discovery/src/providers/llms-txt.js +60 -0
- package/dist/packages/discovery/src/providers/markdown.d.ts +7 -0
- package/dist/packages/discovery/src/providers/markdown.js +38 -0
- package/dist/packages/discovery/src/providers/openapi.d.ts +7 -0
- package/dist/packages/discovery/src/providers/openapi.js +77 -0
- package/dist/packages/discovery/src/providers/sitemap.d.ts +7 -0
- package/dist/packages/discovery/src/providers/sitemap.js +53 -0
- package/dist/packages/discovery/src/providers/skill.d.ts +7 -0
- package/dist/packages/discovery/src/providers/skill.js +46 -0
- package/dist/packages/discovery/src/ranker.d.ts +6 -0
- package/dist/packages/discovery/src/ranker.js +107 -0
- package/dist/packages/evaluation/src/dataset.d.ts +2 -0
- package/dist/packages/evaluation/src/dataset.js +944 -0
- package/dist/packages/evaluation/src/index.js +8 -0
- package/dist/packages/evaluation/src/runner.d.ts +7 -0
- package/dist/packages/evaluation/src/runner.js +196 -0
- package/dist/packages/evaluation/src/strategies/context7-runner.d.ts +24 -0
- package/dist/packages/evaluation/src/strategies/context7-runner.js +229 -0
- package/dist/packages/evaluation/src/strategies/docorbit-runner.d.ts +5 -0
- package/dist/packages/evaluation/src/strategies/docorbit-runner.js +210 -0
- package/dist/packages/evaluation/src/strategies/firecrawl-runner.d.ts +24 -0
- package/dist/packages/evaluation/src/strategies/firecrawl-runner.js +151 -0
- package/dist/packages/evaluation/src/strategies/web-search-runner.d.ts +32 -0
- package/dist/packages/evaluation/src/strategies/web-search-runner.js +161 -0
- package/dist/packages/evaluation/src/types.d.ts +15 -0
- package/dist/packages/evaluation/src/types.js +1 -0
- package/dist/packages/evaluation/src/version-matcher.d.ts +11 -0
- package/dist/packages/evaluation/src/version-matcher.js +61 -0
- package/dist/packages/export/src/agents-md.d.ts +19 -0
- package/dist/packages/export/src/agents-md.js +170 -0
- package/dist/packages/export/src/claude-md.d.ts +17 -0
- package/dist/packages/export/src/claude-md.js +118 -0
- package/dist/packages/export/src/docs-map.d.ts +14 -0
- package/dist/packages/export/src/docs-map.js +118 -0
- package/dist/packages/export/src/index.js +6 -0
- package/dist/packages/export/src/llms-txt.d.ts +15 -0
- package/dist/packages/export/src/llms-txt.js +73 -0
- package/dist/packages/export/src/service.d.ts +23 -0
- package/dist/packages/export/src/service.js +210 -0
- package/dist/packages/export/src/skill-md.d.ts +14 -0
- package/dist/packages/export/src/skill-md.js +107 -0
- package/{packages/mcp/src/index.ts → dist/packages/mcp/src/index.d.ts} +2 -35
- package/dist/packages/mcp/src/index.js +6 -0
- package/dist/packages/mcp/src/resources/index.d.ts +12 -0
- package/dist/packages/mcp/src/resources/index.js +165 -0
- package/dist/packages/mcp/src/server.d.ts +30 -0
- package/dist/packages/mcp/src/server.js +243 -0
- package/dist/packages/mcp/src/tools/analyze-impact.d.ts +6 -0
- package/dist/packages/mcp/src/tools/analyze-impact.js +64 -0
- package/dist/packages/mcp/src/tools/check-api.d.ts +6 -0
- package/dist/packages/mcp/src/tools/check-api.js +74 -0
- package/dist/packages/mcp/src/tools/diff-docs.d.ts +6 -0
- package/dist/packages/mcp/src/tools/diff-docs.js +58 -0
- package/dist/packages/mcp/src/tools/export-context.d.ts +6 -0
- package/dist/packages/mcp/src/tools/export-context.js +61 -0
- package/dist/packages/mcp/src/tools/find-api.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-api.js +91 -0
- package/dist/packages/mcp/src/tools/find-example.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-example.js +92 -0
- package/dist/packages/mcp/src/tools/find-pitfall.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-pitfall.js +85 -0
- package/dist/packages/mcp/src/tools/find-recipe.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-recipe.js +89 -0
- package/dist/packages/mcp/src/tools/get-doc.d.ts +6 -0
- package/dist/packages/mcp/src/tools/get-doc.js +118 -0
- package/dist/packages/mcp/src/tools/get-docs-map.d.ts +6 -0
- package/dist/packages/mcp/src/tools/get-docs-map.js +54 -0
- package/dist/packages/mcp/src/tools/get-version.d.ts +6 -0
- package/dist/packages/mcp/src/tools/get-version.js +104 -0
- package/dist/packages/mcp/src/tools/implementation-context.d.ts +6 -0
- package/dist/packages/mcp/src/tools/implementation-context.js +102 -0
- package/dist/packages/mcp/src/tools/index.d.ts +19 -0
- package/dist/packages/mcp/src/tools/index.js +41 -0
- package/dist/packages/mcp/src/tools/ingest-doc.d.ts +6 -0
- package/dist/packages/mcp/src/tools/ingest-doc.js +264 -0
- package/dist/packages/mcp/src/tools/list-sources.d.ts +6 -0
- package/dist/packages/mcp/src/tools/list-sources.js +76 -0
- package/dist/packages/mcp/src/tools/search-docs.d.ts +6 -0
- package/dist/packages/mcp/src/tools/search-docs.js +113 -0
- package/dist/packages/mcp/src/tools/types.d.ts +22 -0
- package/dist/packages/mcp/src/tools/types.js +1 -0
- package/dist/packages/mcp/src/transports/http.d.ts +31 -0
- package/dist/packages/mcp/src/transports/http.js +215 -0
- package/dist/packages/mcp/src/transports/stdio.d.ts +22 -0
- package/dist/packages/mcp/src/transports/stdio.js +86 -0
- package/{packages/mcp/src/transports/types.ts → dist/packages/mcp/src/transports/types.d.ts} +2 -3
- package/dist/packages/mcp/src/transports/types.js +1 -0
- package/dist/packages/mcp/src/types.d.ts +89 -0
- package/dist/packages/mcp/src/types.js +7 -0
- package/dist/packages/normalizer/src/example-indexer.d.ts +5 -0
- package/dist/packages/normalizer/src/example-indexer.js +200 -0
- package/dist/packages/normalizer/src/html.d.ts +13 -0
- package/dist/packages/normalizer/src/html.js +221 -0
- package/{packages/normalizer/src/index.ts → dist/packages/normalizer/src/index.d.ts} +0 -1
- package/dist/packages/normalizer/src/index.js +7 -0
- package/dist/packages/normalizer/src/llms.d.ts +3 -0
- package/dist/packages/normalizer/src/llms.js +71 -0
- package/dist/packages/normalizer/src/openapi/endpoint-parser.d.ts +11 -0
- package/dist/packages/normalizer/src/openapi/endpoint-parser.js +357 -0
- package/dist/packages/normalizer/src/openapi/schema-resolver.d.ts +10 -0
- package/dist/packages/normalizer/src/openapi/schema-resolver.js +82 -0
- package/dist/packages/normalizer/src/openapi.js +2 -0
- package/dist/packages/normalizer/src/page.d.ts +13 -0
- package/dist/packages/normalizer/src/page.js +150 -0
- package/dist/packages/normalizer/src/pitfall-extractor.d.ts +6 -0
- package/dist/packages/normalizer/src/pitfall-extractor.js +153 -0
- package/dist/packages/normalizer/src/slicer.d.ts +30 -0
- package/dist/packages/normalizer/src/slicer.js +360 -0
- package/dist/packages/retrieval/src/engine.d.ts +17 -0
- package/dist/packages/retrieval/src/engine.js +93 -0
- package/{packages/retrieval/src/index.ts → dist/packages/retrieval/src/index.d.ts} +0 -1
- package/dist/packages/retrieval/src/index.js +6 -0
- package/dist/packages/retrieval/src/intent.d.ts +6 -0
- package/dist/packages/retrieval/src/intent.js +39 -0
- package/dist/packages/retrieval/src/packer.d.ts +2 -0
- package/dist/packages/retrieval/src/packer.js +108 -0
- package/dist/packages/retrieval/src/recipe-engine.d.ts +18 -0
- package/dist/packages/retrieval/src/recipe-engine.js +265 -0
- package/dist/packages/retrieval/src/scorer.d.ts +13 -0
- package/dist/packages/retrieval/src/scorer.js +110 -0
- package/dist/packages/retrieval/src/weights.d.ts +3 -0
- package/dist/packages/retrieval/src/weights.js +28 -0
- package/dist/packages/security/src/annotations.d.ts +10 -0
- package/dist/packages/security/src/annotations.js +100 -0
- package/dist/packages/security/src/index.js +2 -0
- package/dist/packages/security/src/ssrf.d.ts +17 -0
- package/dist/packages/security/src/ssrf.js +132 -0
- package/dist/packages/shared/src/errors.d.ts +22 -0
- package/dist/packages/shared/src/errors.js +44 -0
- package/dist/packages/shared/src/hashing.d.ts +3 -0
- package/dist/packages/shared/src/hashing.js +21 -0
- package/dist/packages/shared/src/index.js +3 -0
- package/dist/packages/shared/src/types.d.ts +715 -0
- package/dist/packages/shared/src/types.js +1 -0
- package/dist/packages/storage/src/db.d.ts +11 -0
- package/dist/packages/storage/src/db.js +128 -0
- package/dist/packages/storage/src/index.js +10 -0
- package/dist/packages/storage/src/interfaces.d.ts +83 -0
- package/dist/packages/storage/src/interfaces.js +1 -0
- package/dist/packages/storage/src/repositories/api-repository.d.ts +16 -0
- package/dist/packages/storage/src/repositories/api-repository.js +169 -0
- package/dist/packages/storage/src/repositories/chunk-repository.d.ts +32 -0
- package/dist/packages/storage/src/repositories/chunk-repository.js +250 -0
- package/dist/packages/storage/src/repositories/example-repository.d.ts +16 -0
- package/dist/packages/storage/src/repositories/example-repository.js +158 -0
- package/dist/packages/storage/src/repositories/page-repository.d.ts +16 -0
- package/dist/packages/storage/src/repositories/page-repository.js +161 -0
- package/dist/packages/storage/src/repositories/pitfall-repository.d.ts +15 -0
- package/dist/packages/storage/src/repositories/pitfall-repository.js +144 -0
- package/dist/packages/storage/src/repositories/source-repository.d.ts +33 -0
- package/dist/packages/storage/src/repositories/source-repository.js +153 -0
- package/dist/packages/storage/src/repository.d.ts +92 -0
- package/dist/packages/storage/src/repository.js +157 -0
- package/dist/packages/storage/src/schema.d.ts +2 -0
- package/{packages/storage/src/schema.ts → dist/packages/storage/src/schema.js} +0 -3
- package/dist/packages/storage/src/search-tokens.d.ts +6 -0
- package/dist/packages/storage/src/search-tokens.js +26 -0
- package/dist/packages/verification/src/diff-engine.d.ts +18 -0
- package/dist/packages/verification/src/diff-engine.js +218 -0
- package/dist/packages/verification/src/extractor.d.ts +29 -0
- package/dist/packages/verification/src/extractor.js +302 -0
- package/dist/packages/verification/src/impact-scanner.d.ts +9 -0
- package/dist/packages/verification/src/impact-scanner.js +181 -0
- package/dist/packages/verification/src/index.js +5 -0
- package/dist/packages/verification/src/services.d.ts +55 -0
- package/dist/packages/verification/src/services.js +189 -0
- package/dist/packages/verification/src/verifier.d.ts +15 -0
- package/dist/packages/verification/src/verifier.js +315 -0
- package/dist/packages/workspace/src/detector.d.ts +7 -0
- package/dist/packages/workspace/src/detector.js +117 -0
- package/dist/packages/workspace/src/ecosystems/cargo.d.ts +10 -0
- package/dist/packages/workspace/src/ecosystems/cargo.js +69 -0
- package/dist/packages/workspace/src/ecosystems/composer.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/composer.js +40 -0
- package/dist/packages/workspace/src/ecosystems/go.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/go.js +49 -0
- package/{packages/workspace/src/ecosystems/index.ts → dist/packages/workspace/src/ecosystems/index.d.ts} +2 -24
- package/dist/packages/workspace/src/ecosystems/index.js +21 -0
- package/dist/packages/workspace/src/ecosystems/maven.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/maven.js +28 -0
- package/dist/packages/workspace/src/ecosystems/npm.d.ts +10 -0
- package/dist/packages/workspace/src/ecosystems/npm.js +73 -0
- package/dist/packages/workspace/src/ecosystems/pub.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/pub.js +34 -0
- package/dist/packages/workspace/src/ecosystems/pypi.d.ts +9 -0
- package/dist/packages/workspace/src/ecosystems/pypi.js +94 -0
- package/dist/packages/workspace/src/ecosystems/rubygems.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/rubygems.js +25 -0
- package/dist/packages/workspace/src/ecosystems/types.d.ts +9 -0
- package/dist/packages/workspace/src/ecosystems/types.js +1 -0
- package/dist/packages/workspace/src/index.js +5 -0
- package/dist/packages/workspace/src/lockfile.d.ts +21 -0
- package/dist/packages/workspace/src/lockfile.js +153 -0
- package/dist/packages/workspace/src/resolver.d.ts +39 -0
- package/dist/packages/workspace/src/resolver.js +164 -0
- package/dist/packages/workspace/src/semver.d.ts +33 -0
- package/dist/packages/workspace/src/semver.js +235 -0
- package/package.json +13 -9
- package/apps/cli/bin/docorbit.js +0 -8
- package/apps/cli/src/commands/add.ts +0 -44
- package/apps/cli/src/commands/api.ts +0 -38
- package/apps/cli/src/commands/context.ts +0 -47
- package/apps/cli/src/commands/dashboard.ts +0 -55
- package/apps/cli/src/commands/diff.ts +0 -30
- package/apps/cli/src/commands/evaluate.ts +0 -133
- package/apps/cli/src/commands/examples.ts +0 -39
- package/apps/cli/src/commands/export.ts +0 -89
- package/apps/cli/src/commands/impact.ts +0 -31
- package/apps/cli/src/commands/init.ts +0 -69
- package/apps/cli/src/commands/inspect.ts +0 -30
- package/apps/cli/src/commands/mcp.ts +0 -72
- package/apps/cli/src/commands/pitfalls.ts +0 -38
- package/apps/cli/src/commands/recipes.ts +0 -35
- package/apps/cli/src/commands/search.ts +0 -48
- package/apps/cli/src/commands/update.ts +0 -73
- package/apps/cli/src/commands/verify.ts +0 -48
- package/apps/cli/src/formatters/colors.ts +0 -23
- package/apps/cli/src/formatters/inspection.ts +0 -102
- package/apps/cli/src/formatters/knowledge.ts +0 -272
- package/apps/cli/src/formatters/retrieval.ts +0 -74
- package/apps/cli/src/formatters/verification.ts +0 -126
- package/apps/cli/src/index.ts +0 -409
- package/packages/core/src/dashboard/server.ts +0 -314
- package/packages/core/src/implementation-service.ts +0 -451
- package/packages/core/src/inspector.ts +0 -71
- package/packages/core/src/pipeline.ts +0 -331
- package/packages/crawler/src/config.ts +0 -12
- package/packages/crawler/src/fetcher.ts +0 -185
- package/packages/discovery/src/index.ts +0 -31
- package/packages/discovery/src/provider.ts +0 -47
- package/packages/discovery/src/providers/generic.ts +0 -98
- package/packages/discovery/src/providers/github.ts +0 -61
- package/packages/discovery/src/providers/llms-txt.ts +0 -73
- package/packages/discovery/src/providers/markdown.ts +0 -48
- package/packages/discovery/src/providers/openapi.ts +0 -91
- package/packages/discovery/src/providers/sitemap.ts +0 -62
- package/packages/discovery/src/providers/skill.ts +0 -54
- package/packages/discovery/src/ranker.ts +0 -123
- package/packages/evaluation/src/dataset.ts +0 -963
- package/packages/evaluation/src/runner.ts +0 -241
- package/packages/evaluation/src/strategies/context7-runner.ts +0 -269
- package/packages/evaluation/src/strategies/docorbit-runner.ts +0 -228
- package/packages/evaluation/src/strategies/firecrawl-runner.ts +0 -172
- package/packages/evaluation/src/strategies/web-search-runner.ts +0 -194
- package/packages/evaluation/src/types.ts +0 -34
- package/packages/evaluation/src/version-matcher.ts +0 -73
- package/packages/export/src/agents-md.ts +0 -200
- package/packages/export/src/claude-md.ts +0 -141
- package/packages/export/src/docs-map.ts +0 -150
- package/packages/export/src/llms-txt.ts +0 -96
- package/packages/export/src/service.ts +0 -250
- package/packages/export/src/skill-md.ts +0 -128
- package/packages/mcp/src/resources/index.ts +0 -189
- package/packages/mcp/src/server.ts +0 -278
- package/packages/mcp/src/tools/analyze-impact.ts +0 -74
- package/packages/mcp/src/tools/check-api.ts +0 -86
- package/packages/mcp/src/tools/diff-docs.ts +0 -68
- package/packages/mcp/src/tools/export-context.ts +0 -73
- package/packages/mcp/src/tools/find-api.ts +0 -99
- package/packages/mcp/src/tools/find-example.ts +0 -100
- package/packages/mcp/src/tools/find-pitfall.ts +0 -94
- package/packages/mcp/src/tools/find-recipe.ts +0 -98
- package/packages/mcp/src/tools/get-doc.ts +0 -130
- package/packages/mcp/src/tools/get-docs-map.ts +0 -64
- package/packages/mcp/src/tools/get-version.ts +0 -118
- package/packages/mcp/src/tools/implementation-context.ts +0 -88
- package/packages/mcp/src/tools/index.ts +0 -59
- package/packages/mcp/src/tools/list-sources.ts +0 -85
- package/packages/mcp/src/tools/search-docs.ts +0 -123
- package/packages/mcp/src/tools/types.ts +0 -28
- package/packages/mcp/src/transports/http.ts +0 -256
- package/packages/mcp/src/transports/stdio.ts +0 -105
- package/packages/mcp/src/types.ts +0 -102
- package/packages/normalizer/src/example-indexer.ts +0 -240
- package/packages/normalizer/src/html.ts +0 -253
- package/packages/normalizer/src/llms.ts +0 -83
- package/packages/normalizer/src/openapi/endpoint-parser.ts +0 -406
- package/packages/normalizer/src/openapi/schema-resolver.ts +0 -111
- package/packages/normalizer/src/page.ts +0 -184
- package/packages/normalizer/src/pitfall-extractor.ts +0 -190
- package/packages/normalizer/src/slicer.ts +0 -455
- package/packages/retrieval/src/engine.ts +0 -120
- package/packages/retrieval/src/intent.ts +0 -43
- package/packages/retrieval/src/packer.ts +0 -145
- package/packages/retrieval/src/recipe-engine.ts +0 -313
- package/packages/retrieval/src/scorer.ts +0 -139
- package/packages/retrieval/src/weights.ts +0 -31
- package/packages/security/src/annotations.ts +0 -112
- package/packages/security/src/ssrf.ts +0 -153
- package/packages/shared/src/errors.ts +0 -53
- package/packages/shared/src/hashing.ts +0 -23
- package/packages/shared/src/types.ts +0 -881
- package/packages/storage/src/db.ts +0 -72
- package/packages/storage/src/interfaces.ts +0 -115
- package/packages/storage/src/repositories/api-repository.ts +0 -219
- package/packages/storage/src/repositories/chunk-repository.ts +0 -316
- package/packages/storage/src/repositories/example-repository.ts +0 -206
- package/packages/storage/src/repositories/page-repository.ts +0 -205
- package/packages/storage/src/repositories/pitfall-repository.ts +0 -188
- package/packages/storage/src/repositories/source-repository.ts +0 -205
- package/packages/storage/src/repository.ts +0 -256
- package/packages/storage/src/search-tokens.ts +0 -28
- package/packages/verification/src/diff-engine.ts +0 -258
- package/packages/verification/src/extractor.ts +0 -339
- package/packages/verification/src/impact-scanner.ts +0 -203
- package/packages/verification/src/services.ts +0 -238
- package/packages/verification/src/verifier.ts +0 -375
- package/packages/workspace/src/detector.ts +0 -143
- package/packages/workspace/src/ecosystems/cargo.ts +0 -84
- package/packages/workspace/src/ecosystems/composer.ts +0 -42
- package/packages/workspace/src/ecosystems/go.ts +0 -54
- package/packages/workspace/src/ecosystems/maven.ts +0 -34
- package/packages/workspace/src/ecosystems/npm.ts +0 -83
- package/packages/workspace/src/ecosystems/pub.ts +0 -40
- package/packages/workspace/src/ecosystems/pypi.ts +0 -100
- package/packages/workspace/src/ecosystems/rubygems.ts +0 -30
- package/packages/workspace/src/ecosystems/types.ts +0 -18
- package/packages/workspace/src/lockfile.ts +0 -194
- package/packages/workspace/src/resolver.ts +0 -234
- package/packages/workspace/src/semver.ts +0 -259
- /package/{packages/crawler/src/index.ts → dist/packages/crawler/src/index.d.ts} +0 -0
- /package/{packages/evaluation/src/index.ts → dist/packages/evaluation/src/index.d.ts} +0 -0
- /package/{packages/export/src/index.ts → dist/packages/export/src/index.d.ts} +0 -0
- /package/{packages/normalizer/src/openapi.ts → dist/packages/normalizer/src/openapi.d.ts} +0 -0
- /package/{packages/security/src/index.ts → dist/packages/security/src/index.d.ts} +0 -0
- /package/{packages/shared/src/index.ts → dist/packages/shared/src/index.d.ts} +0 -0
- /package/{packages/storage/src/index.ts → dist/packages/storage/src/index.d.ts} +0 -0
- /package/{packages/verification/src/index.ts → dist/packages/verification/src/index.d.ts} +0 -0
- /package/{packages/workspace/src/index.ts → dist/packages/workspace/src/index.d.ts} +0 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
export class DocDiffEngine {
|
|
2
|
+
repo;
|
|
3
|
+
constructor(repo) {
|
|
4
|
+
this.repo = repo;
|
|
5
|
+
}
|
|
6
|
+
diff(options) {
|
|
7
|
+
const fromEndpoints = this.getEndpoints(options.fromSnapshotId, options.fromVersion);
|
|
8
|
+
const toEndpoints = this.getEndpoints(options.toSnapshotId, options.toVersion);
|
|
9
|
+
const fromPitfalls = this.getPitfalls(options.fromSnapshotId, options.fromVersion);
|
|
10
|
+
const toPitfalls = this.getPitfalls(options.toSnapshotId, options.toVersion);
|
|
11
|
+
// 1. Compute Endpoint Diffs
|
|
12
|
+
const apiChanges = [];
|
|
13
|
+
const fromMap = new Map();
|
|
14
|
+
const toMap = new Map();
|
|
15
|
+
for (const ep of fromEndpoints) {
|
|
16
|
+
fromMap.set(`${ep.method.toUpperCase()} ${ep.path}`, ep);
|
|
17
|
+
}
|
|
18
|
+
for (const ep of toEndpoints) {
|
|
19
|
+
toMap.set(`${ep.method.toUpperCase()} ${ep.path}`, ep);
|
|
20
|
+
}
|
|
21
|
+
let addedCount = 0;
|
|
22
|
+
let removedCount = 0;
|
|
23
|
+
let modifiedCount = 0;
|
|
24
|
+
let deprecatedCount = 0;
|
|
25
|
+
// Check additions, deprecations, and modifications in 'to'
|
|
26
|
+
for (const [key, toEp] of toMap.entries()) {
|
|
27
|
+
const fromEp = fromMap.get(key);
|
|
28
|
+
if (!fromEp) {
|
|
29
|
+
// Newly added endpoint
|
|
30
|
+
apiChanges.push({
|
|
31
|
+
path: toEp.path,
|
|
32
|
+
method: toEp.method,
|
|
33
|
+
changeType: 'added',
|
|
34
|
+
endpoint: toEp,
|
|
35
|
+
});
|
|
36
|
+
addedCount++;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Existed previously: check deprecation status
|
|
40
|
+
if (toEp.deprecated && !fromEp.deprecated) {
|
|
41
|
+
apiChanges.push({
|
|
42
|
+
path: toEp.path,
|
|
43
|
+
method: toEp.method,
|
|
44
|
+
changeType: 'deprecated',
|
|
45
|
+
endpoint: toEp,
|
|
46
|
+
previousEndpoint: fromEp,
|
|
47
|
+
});
|
|
48
|
+
deprecatedCount++;
|
|
49
|
+
}
|
|
50
|
+
// Check semantic parameter and schema modifications
|
|
51
|
+
const changes = this.detectEndpointModifications(fromEp, toEp);
|
|
52
|
+
if (changes.length > 0) {
|
|
53
|
+
apiChanges.push({
|
|
54
|
+
path: toEp.path,
|
|
55
|
+
method: toEp.method,
|
|
56
|
+
changeType: 'modified',
|
|
57
|
+
changes,
|
|
58
|
+
endpoint: toEp,
|
|
59
|
+
previousEndpoint: fromEp,
|
|
60
|
+
});
|
|
61
|
+
modifiedCount++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Check removals from 'from'
|
|
66
|
+
for (const [key, fromEp] of fromMap.entries()) {
|
|
67
|
+
if (!toMap.has(key)) {
|
|
68
|
+
apiChanges.push({
|
|
69
|
+
path: fromEp.path,
|
|
70
|
+
method: fromEp.method,
|
|
71
|
+
changeType: 'removed',
|
|
72
|
+
endpoint: fromEp,
|
|
73
|
+
});
|
|
74
|
+
removedCount++;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// 2. Compute Pitfall Diffs
|
|
78
|
+
const pitfallChanges = [];
|
|
79
|
+
const fromPitfallTitles = new Set(fromPitfalls.map(p => `${p.kind}:${p.title}`));
|
|
80
|
+
const toPitfallTitles = new Set(toPitfalls.map(p => `${p.kind}:${p.title}`));
|
|
81
|
+
for (const toP of toPitfalls) {
|
|
82
|
+
if (!fromPitfallTitles.has(`${toP.kind}:${toP.title}`)) {
|
|
83
|
+
pitfallChanges.push({ changeType: 'added', pitfall: toP });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const fromP of fromPitfalls) {
|
|
87
|
+
if (!toPitfallTitles.has(`${fromP.kind}:${fromP.title}`)) {
|
|
88
|
+
pitfallChanges.push({ changeType: 'removed', pitfall: fromP });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// 3. Compute Content/Chunk Diffs (Semantic only, ignoring formatting-only whitespace)
|
|
92
|
+
const contentChanges = this.computeContentDiffs(options);
|
|
93
|
+
return {
|
|
94
|
+
fromVersion: options.fromVersion,
|
|
95
|
+
toVersion: options.toVersion,
|
|
96
|
+
fromSnapshotId: options.fromSnapshotId,
|
|
97
|
+
toSnapshotId: options.toSnapshotId,
|
|
98
|
+
sourceId: options.sourceId,
|
|
99
|
+
summary: {
|
|
100
|
+
endpointsAdded: addedCount,
|
|
101
|
+
endpointsRemoved: removedCount,
|
|
102
|
+
endpointsModified: modifiedCount,
|
|
103
|
+
endpointsDeprecated: deprecatedCount,
|
|
104
|
+
pitfallsAdded: pitfallChanges.filter(p => p.changeType === 'added').length,
|
|
105
|
+
pitfallsRemoved: pitfallChanges.filter(p => p.changeType === 'removed').length,
|
|
106
|
+
contentChanged: contentChanges.length,
|
|
107
|
+
},
|
|
108
|
+
apiChanges,
|
|
109
|
+
pitfallChanges,
|
|
110
|
+
contentChanges,
|
|
111
|
+
retrievedAt: new Date().toISOString(),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
getEndpoints(snapshotId, docVersion) {
|
|
115
|
+
if (snapshotId) {
|
|
116
|
+
return this.repo.getApiEndpointsBySnapshot(snapshotId);
|
|
117
|
+
}
|
|
118
|
+
return this.repo.searchApiEndpoints('', {
|
|
119
|
+
docVersion,
|
|
120
|
+
limit: 500,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
getPitfalls(snapshotId, docVersion) {
|
|
124
|
+
if (snapshotId) {
|
|
125
|
+
return this.repo.getPitfallsBySnapshot(snapshotId);
|
|
126
|
+
}
|
|
127
|
+
return this.repo.searchPitfalls('', {
|
|
128
|
+
docVersion,
|
|
129
|
+
limit: 200,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
detectEndpointModifications(fromEp, toEp) {
|
|
133
|
+
const changes = [];
|
|
134
|
+
// Compare parameters
|
|
135
|
+
const fromParams = new Map(fromEp.parameters.map(p => [p.name, p]));
|
|
136
|
+
const toParams = new Map(toEp.parameters.map(p => [p.name, p]));
|
|
137
|
+
for (const [name, toP] of toParams.entries()) {
|
|
138
|
+
const fromP = fromParams.get(name);
|
|
139
|
+
if (!fromP) {
|
|
140
|
+
changes.push(`Added parameter "${name}"${toP.required ? ' (required)' : ''}`);
|
|
141
|
+
}
|
|
142
|
+
else if (!fromP.required && toP.required) {
|
|
143
|
+
changes.push(`Parameter "${name}" is now required (was optional)`);
|
|
144
|
+
}
|
|
145
|
+
else if (fromP.type !== toP.type && toP.type) {
|
|
146
|
+
changes.push(`Parameter "${name}" type changed from ${fromP.type || 'any'} to ${toP.type}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
for (const name of fromParams.keys()) {
|
|
150
|
+
if (!toParams.has(name)) {
|
|
151
|
+
changes.push(`Removed parameter "${name}"`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Compare Request Body required fields
|
|
155
|
+
const fromReq = new Set(fromEp.requestSchema?.required || []);
|
|
156
|
+
const toReq = new Set(toEp.requestSchema?.required || []);
|
|
157
|
+
for (const field of toReq) {
|
|
158
|
+
if (!fromReq.has(field)) {
|
|
159
|
+
changes.push(`Request body field "${field}" is now required`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
for (const field of fromReq) {
|
|
163
|
+
if (!toReq.has(field)) {
|
|
164
|
+
changes.push(`Request body field "${field}" is no longer required`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return changes;
|
|
168
|
+
}
|
|
169
|
+
computeContentDiffs(options) {
|
|
170
|
+
const fromChunks = options.fromSnapshotId
|
|
171
|
+
? this.repo.getChunksBySnapshot(options.fromSnapshotId)
|
|
172
|
+
: options.fromVersion
|
|
173
|
+
? this.repo.getChunksByVersion(options.fromVersion)
|
|
174
|
+
: [];
|
|
175
|
+
const toChunks = options.toSnapshotId
|
|
176
|
+
? this.repo.getChunksBySnapshot(options.toSnapshotId)
|
|
177
|
+
: options.toVersion
|
|
178
|
+
? this.repo.getChunksByVersion(options.toVersion)
|
|
179
|
+
: [];
|
|
180
|
+
if (fromChunks.length === 0 && toChunks.length === 0)
|
|
181
|
+
return [];
|
|
182
|
+
const changes = [];
|
|
183
|
+
const fromMap = new Map(fromChunks.map(c => [c.title, c]));
|
|
184
|
+
const toMap = new Map(toChunks.map(c => [c.title, c]));
|
|
185
|
+
for (const [title, toC] of toMap.entries()) {
|
|
186
|
+
const fromC = fromMap.get(title);
|
|
187
|
+
if (!fromC) {
|
|
188
|
+
changes.push({
|
|
189
|
+
title,
|
|
190
|
+
changeType: 'added',
|
|
191
|
+
summary: `New documentation section: "${title}"`,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
else if (fromC.contentHash !== toC.contentHash) {
|
|
195
|
+
// Compare normalized text to ignore formatting-only whitespace
|
|
196
|
+
const normFrom = fromC.content.replace(/\s+/g, ' ').trim();
|
|
197
|
+
const normTo = toC.content.replace(/\s+/g, ' ').trim();
|
|
198
|
+
if (normFrom !== normTo) {
|
|
199
|
+
changes.push({
|
|
200
|
+
title,
|
|
201
|
+
changeType: 'modified',
|
|
202
|
+
summary: `Content updated for section "${title}"`,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
for (const title of fromMap.keys()) {
|
|
208
|
+
if (!toMap.has(title)) {
|
|
209
|
+
changes.push({
|
|
210
|
+
title,
|
|
211
|
+
changeType: 'removed',
|
|
212
|
+
summary: `Documentation section removed: "${title}"`,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return changes;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ExtractedApiCall } from '../../shared/src/index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes an API path for comparison against schema paths.
|
|
4
|
+
* E.g. extracts pathname from full URLs ("https://api.stripe.com/v1/webhook_endpoints" -> "/v1/webhook_endpoints")
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeApiPath(urlOrPath: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Checks if an extracted path matches an OpenAPI schema path template.
|
|
9
|
+
* E.g. candidate "/v1/webhook_endpoints/we_123" matches schema "/v1/webhook_endpoints/{id}"
|
|
10
|
+
*/
|
|
11
|
+
export declare function matchEndpointPath(candidatePath: string, schemaPath: string): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Deterministically extracts API calls, parameters, methods, and version syntax from code.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CodeApiExtractor {
|
|
16
|
+
/**
|
|
17
|
+
* Extracts API calls from code.
|
|
18
|
+
*/
|
|
19
|
+
extract(code: string, language?: string): ExtractedApiCall[];
|
|
20
|
+
private findLineNumber;
|
|
21
|
+
private extractNextJsParams;
|
|
22
|
+
private extractFetchCalls;
|
|
23
|
+
private extractAxiosCalls;
|
|
24
|
+
private extractPythonRequestsCalls;
|
|
25
|
+
private extractCurlCalls;
|
|
26
|
+
private extractSdkCalls;
|
|
27
|
+
private extractDynamicCalls;
|
|
28
|
+
private extractResponseFields;
|
|
29
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalizes an API path for comparison against schema paths.
|
|
3
|
+
* E.g. extracts pathname from full URLs ("https://api.stripe.com/v1/webhook_endpoints" -> "/v1/webhook_endpoints")
|
|
4
|
+
*/
|
|
5
|
+
export function normalizeApiPath(urlOrPath) {
|
|
6
|
+
try {
|
|
7
|
+
if (urlOrPath.startsWith('http://') || urlOrPath.startsWith('https://')) {
|
|
8
|
+
const parsed = new URL(urlOrPath);
|
|
9
|
+
return parsed.pathname;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// Fall back to regex
|
|
14
|
+
}
|
|
15
|
+
const match = urlOrPath.match(/^https?:\/\/[^/]+(\/.*)$/);
|
|
16
|
+
if (match)
|
|
17
|
+
return match[1].split('?')[0];
|
|
18
|
+
return urlOrPath.split('?')[0].trim();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Checks if an extracted path matches an OpenAPI schema path template.
|
|
22
|
+
* E.g. candidate "/v1/webhook_endpoints/we_123" matches schema "/v1/webhook_endpoints/{id}"
|
|
23
|
+
*/
|
|
24
|
+
export function matchEndpointPath(candidatePath, schemaPath) {
|
|
25
|
+
const normCandidate = normalizeApiPath(candidatePath).replace(/\/+$/, '');
|
|
26
|
+
const normSchema = normalizeApiPath(schemaPath).replace(/\/+$/, '');
|
|
27
|
+
if (normCandidate.toLowerCase() === normSchema.toLowerCase()) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
// Convert schema {param} or :param to regex wildcard
|
|
31
|
+
const regexPattern = normSchema
|
|
32
|
+
.replace(/{[^}]+}/g, '([^/]+)')
|
|
33
|
+
.replace(/:[a-zA-Z0-9_]+/g, '([^/]+)')
|
|
34
|
+
.replace(/\//g, '\\/');
|
|
35
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i');
|
|
36
|
+
return regex.test(normCandidate);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Extracts top-level key names from a JS/Python object or JSON snippet string.
|
|
40
|
+
*/
|
|
41
|
+
function extractObjectKeys(objSnippet) {
|
|
42
|
+
const keys = new Set();
|
|
43
|
+
// Try standard JSON parse first
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(objSnippet);
|
|
46
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
47
|
+
return Object.keys(parsed);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Fall back to lexical key extraction
|
|
52
|
+
}
|
|
53
|
+
// Match identifier keys: { foo: ..., "bar": ..., 'baz': ... }
|
|
54
|
+
const keyRegex = /(?:[{,]\s*)(?:["']?([a-zA-Z0-9_-]+)["']?)\s*:/g;
|
|
55
|
+
let match;
|
|
56
|
+
while ((match = keyRegex.exec(objSnippet)) !== null) {
|
|
57
|
+
if (match[1] && !['method', 'headers', 'body'].includes(match[1])) {
|
|
58
|
+
keys.add(match[1]);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return Array.from(keys);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Deterministically extracts API calls, parameters, methods, and version syntax from code.
|
|
65
|
+
*/
|
|
66
|
+
export class CodeApiExtractor {
|
|
67
|
+
/**
|
|
68
|
+
* Extracts API calls from code.
|
|
69
|
+
*/
|
|
70
|
+
extract(code, language) {
|
|
71
|
+
const results = [];
|
|
72
|
+
const lines = code.split('\n');
|
|
73
|
+
// 1. Check for Next.js Route Params patterns (sync vs async)
|
|
74
|
+
this.extractNextJsParams(code, lines, results);
|
|
75
|
+
// 2. Extract Fetch calls: fetch('url', { method: 'POST', body: ... })
|
|
76
|
+
this.extractFetchCalls(code, lines, results);
|
|
77
|
+
// 3. Extract Axios calls: axios.post('url', {...}) / axios.get('url')
|
|
78
|
+
this.extractAxiosCalls(code, lines, results);
|
|
79
|
+
// 4. Extract Python Requests calls: requests.post('url', json={...})
|
|
80
|
+
this.extractPythonRequestsCalls(code, lines, results);
|
|
81
|
+
// 5. Extract cURL commands: curl -X POST ...
|
|
82
|
+
this.extractCurlCalls(code, lines, results);
|
|
83
|
+
// 6. Extract common SDK calls: stripe.webhookEndpoints.create({...}), etc.
|
|
84
|
+
this.extractSdkCalls(code, lines, results);
|
|
85
|
+
// 7. Check for dynamic / unresolvable URLs: e.g. fetch(apiUrl) or axios.get(endpoint)
|
|
86
|
+
this.extractDynamicCalls(code, lines, results);
|
|
87
|
+
// If nothing was extracted at all, create an ambiguous marker
|
|
88
|
+
if (results.length === 0) {
|
|
89
|
+
results.push({
|
|
90
|
+
rawSnippet: code.slice(0, 150),
|
|
91
|
+
isDynamicOrAmbiguous: true,
|
|
92
|
+
reasonIfAmbiguous: language && !['javascript', 'typescript', 'python', 'curl', 'bash'].includes(language.toLowerCase())
|
|
93
|
+
? `Language "${language}" is not currently supported for deep AST schema verification.`
|
|
94
|
+
: 'No recognizable HTTP/API client calls, SDK invocations, or endpoint paths found in code.',
|
|
95
|
+
language,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return results;
|
|
99
|
+
}
|
|
100
|
+
findLineNumber(lines, snippetPattern) {
|
|
101
|
+
const clean = snippetPattern.trim().split('\n')[0].slice(0, 40);
|
|
102
|
+
for (let i = 0; i < lines.length; i++) {
|
|
103
|
+
if (lines[i].includes(clean))
|
|
104
|
+
return i + 1;
|
|
105
|
+
}
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
extractNextJsParams(code, lines, results) {
|
|
109
|
+
// Next.js 14 sync: params.slug, const { slug } = params
|
|
110
|
+
const syncParamRegex = /(?:const\s+{\s*([^}]+)\s*}\s*=\s*params\b|\bparams\.([a-zA-Z0-9_]+))/;
|
|
111
|
+
// Next.js 15+ async: await params, const { slug } = await params
|
|
112
|
+
const asyncParamRegex = /(?:await\s+params\b|const\s+{\s*([^}]+)\s*}\s*=\s*await\s+params\b)/;
|
|
113
|
+
const hasAsync = asyncParamRegex.test(code);
|
|
114
|
+
const hasSync = syncParamRegex.test(code) && !hasAsync;
|
|
115
|
+
if (hasAsync) {
|
|
116
|
+
const match = code.match(asyncParamRegex);
|
|
117
|
+
results.push({
|
|
118
|
+
symbol: 'nextjs_route_params_async',
|
|
119
|
+
endpointPath: 'nextjs/app_router/params',
|
|
120
|
+
method: 'get',
|
|
121
|
+
rawSnippet: match ? match[0] : 'await params',
|
|
122
|
+
line: match ? this.findLineNumber(lines, match[0]) : 1,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
else if (hasSync) {
|
|
126
|
+
const match = code.match(syncParamRegex);
|
|
127
|
+
results.push({
|
|
128
|
+
symbol: 'nextjs_route_params_sync',
|
|
129
|
+
endpointPath: 'nextjs/app_router/params',
|
|
130
|
+
method: 'get',
|
|
131
|
+
rawSnippet: match ? match[0] : 'params.slug',
|
|
132
|
+
line: match ? this.findLineNumber(lines, match[0]) : 1,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
extractFetchCalls(code, lines, results) {
|
|
137
|
+
// Matches: fetch(['"`]([^'"`]+)['"`](?:\s*,\s*({[\s\S]*?}))?\s*\)
|
|
138
|
+
const fetchRegex = /fetch\s*\(\s*['"`]([^'"`]+)['"`](?:\s*,\s*({[\s\S]*?}))?\s*\)/g;
|
|
139
|
+
let match;
|
|
140
|
+
while ((match = fetchRegex.exec(code)) !== null) {
|
|
141
|
+
const url = match[1];
|
|
142
|
+
const optionsSnippet = match[2] || '';
|
|
143
|
+
const endpointPath = normalizeApiPath(url);
|
|
144
|
+
let method = 'get';
|
|
145
|
+
const methodMatch = optionsSnippet.match(/method\s*:\s*['"]([a-zA-Z]+)['"]/i);
|
|
146
|
+
if (methodMatch) {
|
|
147
|
+
method = methodMatch[1].toLowerCase();
|
|
148
|
+
}
|
|
149
|
+
// Extract body fields if body: JSON.stringify({...}) or body: {...}
|
|
150
|
+
let bodyFields = [];
|
|
151
|
+
const bodyMatch = optionsSnippet.match(/body\s*:\s*(?:JSON\.stringify\s*\(\s*)?({[\s\S]*?})(?:\s*\))?/);
|
|
152
|
+
if (bodyMatch) {
|
|
153
|
+
bodyFields = extractObjectKeys(bodyMatch[1]);
|
|
154
|
+
}
|
|
155
|
+
// Extract response fields accessed: e.g. data.foo, res.json()
|
|
156
|
+
const responseFields = this.extractResponseFields(code, endpointPath);
|
|
157
|
+
results.push({
|
|
158
|
+
endpointPath,
|
|
159
|
+
method,
|
|
160
|
+
bodyFields,
|
|
161
|
+
responseFieldsAccessed: responseFields,
|
|
162
|
+
rawSnippet: match[0],
|
|
163
|
+
line: this.findLineNumber(lines, match[0]),
|
|
164
|
+
language: 'javascript',
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
extractAxiosCalls(code, lines, results) {
|
|
169
|
+
// Matches: axios.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`](?:\s*,\s*({[\s\S]*?}))?/g
|
|
170
|
+
const axiosRegex = /axios\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`](?:\s*,\s*({[\s\S]*?}))?/g;
|
|
171
|
+
let match;
|
|
172
|
+
while ((match = axiosRegex.exec(code)) !== null) {
|
|
173
|
+
const method = match[1].toLowerCase();
|
|
174
|
+
const url = match[2];
|
|
175
|
+
const payloadSnippet = match[3] || '';
|
|
176
|
+
const endpointPath = normalizeApiPath(url);
|
|
177
|
+
const bodyFields = payloadSnippet ? extractObjectKeys(payloadSnippet) : [];
|
|
178
|
+
const responseFields = this.extractResponseFields(code, endpointPath);
|
|
179
|
+
results.push({
|
|
180
|
+
endpointPath,
|
|
181
|
+
method,
|
|
182
|
+
bodyFields,
|
|
183
|
+
responseFieldsAccessed: responseFields,
|
|
184
|
+
rawSnippet: match[0],
|
|
185
|
+
line: this.findLineNumber(lines, match[0]),
|
|
186
|
+
language: 'javascript',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
extractPythonRequestsCalls(code, lines, results) {
|
|
191
|
+
// Matches: requests.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"](?:\s*,\s*(?:json|data)\s*=\s*({[\s\S]*?}))?
|
|
192
|
+
const requestsRegex = /requests\.(get|post|put|delete|patch)\s*\(\s*['"]([^'"]+)['"](?:\s*,\s*(?:json|data|params)\s*=\s*({[\s\S]*?}))?/g;
|
|
193
|
+
let match;
|
|
194
|
+
while ((match = requestsRegex.exec(code)) !== null) {
|
|
195
|
+
const method = match[1].toLowerCase();
|
|
196
|
+
const url = match[2];
|
|
197
|
+
const payloadSnippet = match[3] || '';
|
|
198
|
+
const endpointPath = normalizeApiPath(url);
|
|
199
|
+
const bodyFields = payloadSnippet ? extractObjectKeys(payloadSnippet) : [];
|
|
200
|
+
results.push({
|
|
201
|
+
endpointPath,
|
|
202
|
+
method,
|
|
203
|
+
bodyFields,
|
|
204
|
+
rawSnippet: match[0],
|
|
205
|
+
line: this.findLineNumber(lines, match[0]),
|
|
206
|
+
language: 'python',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
extractCurlCalls(code, lines, results) {
|
|
211
|
+
// Matches: curl ... https://... -X POST -d '{...}'
|
|
212
|
+
const curlRegex = /curl\s+([^\n]+)/g;
|
|
213
|
+
let match;
|
|
214
|
+
while ((match = curlRegex.exec(code)) !== null) {
|
|
215
|
+
const fullCmd = match[1];
|
|
216
|
+
const urlMatch = fullCmd.match(/https?:\/\/[^\s'"]+/);
|
|
217
|
+
if (!urlMatch)
|
|
218
|
+
continue;
|
|
219
|
+
const endpointPath = normalizeApiPath(urlMatch[0]);
|
|
220
|
+
let method = 'get';
|
|
221
|
+
const methodMatch = fullCmd.match(/-X\s+([A-Z]+)/i);
|
|
222
|
+
if (methodMatch) {
|
|
223
|
+
method = methodMatch[1].toLowerCase();
|
|
224
|
+
}
|
|
225
|
+
else if (fullCmd.includes('-d ') || fullCmd.includes('--data')) {
|
|
226
|
+
method = 'post';
|
|
227
|
+
}
|
|
228
|
+
let bodyFields = [];
|
|
229
|
+
const dataMatch = fullCmd.match(/(?:-d|--data(?:-raw)?)\s+['"]({[\s\S]*?})['"]/);
|
|
230
|
+
if (dataMatch) {
|
|
231
|
+
bodyFields = extractObjectKeys(dataMatch[1]);
|
|
232
|
+
}
|
|
233
|
+
results.push({
|
|
234
|
+
endpointPath,
|
|
235
|
+
method,
|
|
236
|
+
bodyFields,
|
|
237
|
+
rawSnippet: match[0],
|
|
238
|
+
line: this.findLineNumber(lines, match[0]),
|
|
239
|
+
language: 'curl',
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
extractSdkCalls(code, lines, results) {
|
|
244
|
+
// Stripe SDK: stripe.webhookEndpoints.create({...})
|
|
245
|
+
const stripeWebhookRegex = /stripe\.webhookEndpoints\.create\s*\(\s*({[\s\S]*?})\s*\)/g;
|
|
246
|
+
let match;
|
|
247
|
+
while ((match = stripeWebhookRegex.exec(code)) !== null) {
|
|
248
|
+
const bodyFields = extractObjectKeys(match[1]);
|
|
249
|
+
results.push({
|
|
250
|
+
endpointPath: '/v1/webhook_endpoints',
|
|
251
|
+
method: 'post',
|
|
252
|
+
symbol: 'stripe.webhookEndpoints.create',
|
|
253
|
+
bodyFields,
|
|
254
|
+
rawSnippet: match[0],
|
|
255
|
+
line: this.findLineNumber(lines, match[0]),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
// Stripe SDK: stripe.charges.create({...})
|
|
259
|
+
const stripeChargesRegex = /stripe\.charges\.create\s*\(\s*({[\s\S]*?})\s*\)/g;
|
|
260
|
+
while ((match = stripeChargesRegex.exec(code)) !== null) {
|
|
261
|
+
const bodyFields = extractObjectKeys(match[1]);
|
|
262
|
+
results.push({
|
|
263
|
+
endpointPath: '/v1/charges',
|
|
264
|
+
method: 'post',
|
|
265
|
+
symbol: 'stripe.charges.create',
|
|
266
|
+
bodyFields,
|
|
267
|
+
rawSnippet: match[0],
|
|
268
|
+
line: this.findLineNumber(lines, match[0]),
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
extractDynamicCalls(code, lines, results) {
|
|
273
|
+
// Matches fetch(dynamicVar) or axios.get(dynamicVar) where argument does not start with string quote
|
|
274
|
+
const dynamicFetch = /fetch\s*\(\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\s*(?:,|\))/g;
|
|
275
|
+
let match;
|
|
276
|
+
while ((match = dynamicFetch.exec(code)) !== null) {
|
|
277
|
+
const varName = match[1];
|
|
278
|
+
// Check if variable is defined as a string literal above
|
|
279
|
+
const defRegex = new RegExp(`(?:const|let|var)\\s+${varName}\\s*=\\s*['"\`]([^'"\`]+)['"\`]`);
|
|
280
|
+
if (!defRegex.test(code)) {
|
|
281
|
+
results.push({
|
|
282
|
+
rawSnippet: match[0],
|
|
283
|
+
isDynamicOrAmbiguous: true,
|
|
284
|
+
reasonIfAmbiguous: `Dynamic variable "${varName}" passed to fetch() cannot be statically resolved to an API path.`,
|
|
285
|
+
line: this.findLineNumber(lines, match[0]),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
extractResponseFields(code, _endpoint) {
|
|
291
|
+
const fields = new Set();
|
|
292
|
+
// Matches res.data.fieldName or data.fieldName or json.fieldName or event.fieldName
|
|
293
|
+
const fieldRegex = /(?:res(?:ponse)?(?:\.data)?|data|json|body|payload)\.([a-zA-Z0-9_]+)/g;
|
|
294
|
+
let m;
|
|
295
|
+
while ((m = fieldRegex.exec(code)) !== null) {
|
|
296
|
+
if (m[1] && !['json', 'status', 'headers', 'data', 'text'].includes(m[1])) {
|
|
297
|
+
fields.add(m[1]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return Array.from(fields);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DocDiffResult, ImpactAnalysisResult } from '../../shared/src/index.ts';
|
|
2
|
+
export declare class WorkspaceImpactScanner {
|
|
3
|
+
/**
|
|
4
|
+
* Scans a workspace project directory and identifies files affected by documentation diffs.
|
|
5
|
+
*/
|
|
6
|
+
scan(projectDir: string, diff: DocDiffResult): ImpactAnalysisResult;
|
|
7
|
+
private collectFiles;
|
|
8
|
+
private analyzeFile;
|
|
9
|
+
}
|