mnehmos.trace.mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1662 -0
- package/dist/adapters/bootstrap.d.ts +29 -0
- package/dist/adapters/bootstrap.d.ts.map +1 -0
- package/dist/adapters/bootstrap.js +46 -0
- package/dist/adapters/bootstrap.js.map +1 -0
- package/dist/adapters/errors.d.ts +94 -0
- package/dist/adapters/errors.d.ts.map +1 -0
- package/dist/adapters/errors.js +107 -0
- package/dist/adapters/errors.js.map +1 -0
- package/dist/adapters/graphql/index.d.ts +9 -0
- package/dist/adapters/graphql/index.d.ts.map +1 -0
- package/dist/adapters/graphql/index.js +9 -0
- package/dist/adapters/graphql/index.js.map +1 -0
- package/dist/adapters/graphql/sdl-parser.d.ts +74 -0
- package/dist/adapters/graphql/sdl-parser.d.ts.map +1 -0
- package/dist/adapters/graphql/sdl-parser.js +559 -0
- package/dist/adapters/graphql/sdl-parser.js.map +1 -0
- package/dist/adapters/grpc/adapter.d.ts +76 -0
- package/dist/adapters/grpc/adapter.d.ts.map +1 -0
- package/dist/adapters/grpc/adapter.js +362 -0
- package/dist/adapters/grpc/adapter.js.map +1 -0
- package/dist/adapters/grpc/index.d.ts +10 -0
- package/dist/adapters/grpc/index.d.ts.map +1 -0
- package/dist/adapters/grpc/index.js +12 -0
- package/dist/adapters/grpc/index.js.map +1 -0
- package/dist/adapters/grpc/proto-parser.d.ts +76 -0
- package/dist/adapters/grpc/proto-parser.d.ts.map +1 -0
- package/dist/adapters/grpc/proto-parser.js +523 -0
- package/dist/adapters/grpc/proto-parser.js.map +1 -0
- package/dist/adapters/grpc/type-converter.d.ts +43 -0
- package/dist/adapters/grpc/type-converter.d.ts.map +1 -0
- package/dist/adapters/grpc/type-converter.js +270 -0
- package/dist/adapters/grpc/type-converter.js.map +1 -0
- package/dist/adapters/grpc/types.d.ts +85 -0
- package/dist/adapters/grpc/types.d.ts.map +1 -0
- package/dist/adapters/grpc/types.js +7 -0
- package/dist/adapters/grpc/types.js.map +1 -0
- package/dist/adapters/index.d.ts +39 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +50 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/mcp.d.ts +23 -0
- package/dist/adapters/mcp.d.ts.map +1 -0
- package/dist/adapters/mcp.js +293 -0
- package/dist/adapters/mcp.js.map +1 -0
- package/dist/adapters/openapi/adapter.d.ts +213 -0
- package/dist/adapters/openapi/adapter.d.ts.map +1 -0
- package/dist/adapters/openapi/adapter.js +557 -0
- package/dist/adapters/openapi/adapter.js.map +1 -0
- package/dist/adapters/openapi/convert.d.ts +120 -0
- package/dist/adapters/openapi/convert.d.ts.map +1 -0
- package/dist/adapters/openapi/convert.js +363 -0
- package/dist/adapters/openapi/convert.js.map +1 -0
- package/dist/adapters/openapi/index.d.ts +39 -0
- package/dist/adapters/openapi/index.d.ts.map +1 -0
- package/dist/adapters/openapi/index.js +48 -0
- package/dist/adapters/openapi/index.js.map +1 -0
- package/dist/adapters/openapi/parser.d.ts +95 -0
- package/dist/adapters/openapi/parser.d.ts.map +1 -0
- package/dist/adapters/openapi/parser.js +171 -0
- package/dist/adapters/openapi/parser.js.map +1 -0
- package/dist/adapters/registry.d.ts +116 -0
- package/dist/adapters/registry.d.ts.map +1 -0
- package/dist/adapters/registry.js +246 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/trpc/adapter.d.ts +159 -0
- package/dist/adapters/trpc/adapter.d.ts.map +1 -0
- package/dist/adapters/trpc/adapter.js +223 -0
- package/dist/adapters/trpc/adapter.js.map +1 -0
- package/dist/adapters/trpc/extractor.d.ts +218 -0
- package/dist/adapters/trpc/extractor.d.ts.map +1 -0
- package/dist/adapters/trpc/extractor.js +708 -0
- package/dist/adapters/trpc/extractor.js.map +1 -0
- package/dist/adapters/trpc/index.d.ts +31 -0
- package/dist/adapters/trpc/index.d.ts.map +1 -0
- package/dist/adapters/trpc/index.js +40 -0
- package/dist/adapters/trpc/index.js.map +1 -0
- package/dist/adapters/trpc/parser.d.ts +119 -0
- package/dist/adapters/trpc/parser.d.ts.map +1 -0
- package/dist/adapters/trpc/parser.js +128 -0
- package/dist/adapters/trpc/parser.js.map +1 -0
- package/dist/compare/index.d.ts +33 -0
- package/dist/compare/index.d.ts.map +1 -0
- package/dist/compare/index.js +261 -0
- package/dist/compare/index.js.map +1 -0
- package/dist/core/types.d.ts +188 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -0
- package/dist/extract/index.d.ts +26 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +44 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +674 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/base.d.ts +57 -0
- package/dist/languages/base.d.ts.map +1 -0
- package/dist/languages/base.js +6 -0
- package/dist/languages/base.js.map +1 -0
- package/dist/languages/bootstrap.d.ts +10 -0
- package/dist/languages/bootstrap.d.ts.map +1 -0
- package/dist/languages/bootstrap.js +25 -0
- package/dist/languages/bootstrap.js.map +1 -0
- package/dist/languages/go/handlers/chi.d.ts +24 -0
- package/dist/languages/go/handlers/chi.d.ts.map +1 -0
- package/dist/languages/go/handlers/chi.js +205 -0
- package/dist/languages/go/handlers/chi.js.map +1 -0
- package/dist/languages/go/handlers/gin.d.ts +24 -0
- package/dist/languages/go/handlers/gin.d.ts.map +1 -0
- package/dist/languages/go/handlers/gin.js +156 -0
- package/dist/languages/go/handlers/gin.js.map +1 -0
- package/dist/languages/go/handlers/stdlib.d.ts +19 -0
- package/dist/languages/go/handlers/stdlib.d.ts.map +1 -0
- package/dist/languages/go/handlers/stdlib.js +112 -0
- package/dist/languages/go/handlers/stdlib.js.map +1 -0
- package/dist/languages/go/index.d.ts +18 -0
- package/dist/languages/go/index.d.ts.map +1 -0
- package/dist/languages/go/index.js +20 -0
- package/dist/languages/go/index.js.map +1 -0
- package/dist/languages/go/parser.d.ts +33 -0
- package/dist/languages/go/parser.d.ts.map +1 -0
- package/dist/languages/go/parser.js +95 -0
- package/dist/languages/go/parser.js.map +1 -0
- package/dist/languages/go/struct-extractor.d.ts +59 -0
- package/dist/languages/go/struct-extractor.d.ts.map +1 -0
- package/dist/languages/go/struct-extractor.js +483 -0
- package/dist/languages/go/struct-extractor.js.map +1 -0
- package/dist/languages/go/tag-parser.d.ts +62 -0
- package/dist/languages/go/tag-parser.d.ts.map +1 -0
- package/dist/languages/go/tag-parser.js +108 -0
- package/dist/languages/go/tag-parser.js.map +1 -0
- package/dist/languages/go/type-converter.d.ts +32 -0
- package/dist/languages/go/type-converter.d.ts.map +1 -0
- package/dist/languages/go/type-converter.js +226 -0
- package/dist/languages/go/type-converter.js.map +1 -0
- package/dist/languages/go/types.d.ts +153 -0
- package/dist/languages/go/types.d.ts.map +1 -0
- package/dist/languages/go/types.js +6 -0
- package/dist/languages/go/types.js.map +1 -0
- package/dist/languages/import-resolver.d.ts +645 -0
- package/dist/languages/import-resolver.d.ts.map +1 -0
- package/dist/languages/import-resolver.js +1278 -0
- package/dist/languages/import-resolver.js.map +1 -0
- package/dist/languages/index.d.ts +34 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +93 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/json-schema.d.ts +40 -0
- package/dist/languages/json-schema.d.ts.map +1 -0
- package/dist/languages/json-schema.js +188 -0
- package/dist/languages/json-schema.js.map +1 -0
- package/dist/languages/python-ast/index.d.ts +8 -0
- package/dist/languages/python-ast/index.d.ts.map +1 -0
- package/dist/languages/python-ast/index.js +7 -0
- package/dist/languages/python-ast/index.js.map +1 -0
- package/dist/languages/python-ast/parser.d.ts +174 -0
- package/dist/languages/python-ast/parser.d.ts.map +1 -0
- package/dist/languages/python-ast/parser.js +1205 -0
- package/dist/languages/python-ast/parser.js.map +1 -0
- package/dist/languages/python-ast/type-resolver.d.ts +75 -0
- package/dist/languages/python-ast/type-resolver.d.ts.map +1 -0
- package/dist/languages/python-ast/type-resolver.js +421 -0
- package/dist/languages/python-ast/type-resolver.js.map +1 -0
- package/dist/languages/python-ast/types.d.ts +216 -0
- package/dist/languages/python-ast/types.d.ts.map +1 -0
- package/dist/languages/python-ast/types.js +6 -0
- package/dist/languages/python-ast/types.js.map +1 -0
- package/dist/languages/python.d.ts +55 -0
- package/dist/languages/python.d.ts.map +1 -0
- package/dist/languages/python.js +311 -0
- package/dist/languages/python.js.map +1 -0
- package/dist/languages/typescript.d.ts +272 -0
- package/dist/languages/typescript.d.ts.map +1 -0
- package/dist/languages/typescript.js +1381 -0
- package/dist/languages/typescript.js.map +1 -0
- package/dist/patterns/base.d.ts +146 -0
- package/dist/patterns/base.d.ts.map +1 -0
- package/dist/patterns/base.js +89 -0
- package/dist/patterns/base.js.map +1 -0
- package/dist/patterns/errors.d.ts +172 -0
- package/dist/patterns/errors.d.ts.map +1 -0
- package/dist/patterns/errors.js +185 -0
- package/dist/patterns/errors.js.map +1 -0
- package/dist/patterns/extractors.d.ts +170 -0
- package/dist/patterns/extractors.d.ts.map +1 -0
- package/dist/patterns/extractors.js +305 -0
- package/dist/patterns/extractors.js.map +1 -0
- package/dist/patterns/graphql/apollo-client.d.ts +80 -0
- package/dist/patterns/graphql/apollo-client.d.ts.map +1 -0
- package/dist/patterns/graphql/apollo-client.js +800 -0
- package/dist/patterns/graphql/apollo-client.js.map +1 -0
- package/dist/patterns/graphql/apollo-server.d.ts +55 -0
- package/dist/patterns/graphql/apollo-server.d.ts.map +1 -0
- package/dist/patterns/graphql/apollo-server.js +523 -0
- package/dist/patterns/graphql/apollo-server.js.map +1 -0
- package/dist/patterns/graphql/index.d.ts +11 -0
- package/dist/patterns/graphql/index.d.ts.map +1 -0
- package/dist/patterns/graphql/index.js +12 -0
- package/dist/patterns/graphql/index.js.map +1 -0
- package/dist/patterns/graphql/types.d.ts +213 -0
- package/dist/patterns/graphql/types.d.ts.map +1 -0
- package/dist/patterns/graphql/types.js +16 -0
- package/dist/patterns/graphql/types.js.map +1 -0
- package/dist/patterns/http-clients/axios.d.ts +148 -0
- package/dist/patterns/http-clients/axios.d.ts.map +1 -0
- package/dist/patterns/http-clients/axios.js +652 -0
- package/dist/patterns/http-clients/axios.js.map +1 -0
- package/dist/patterns/http-clients/fetch.d.ts +88 -0
- package/dist/patterns/http-clients/fetch.d.ts.map +1 -0
- package/dist/patterns/http-clients/fetch.js +364 -0
- package/dist/patterns/http-clients/fetch.js.map +1 -0
- package/dist/patterns/http-clients/index.d.ts +36 -0
- package/dist/patterns/http-clients/index.d.ts.map +1 -0
- package/dist/patterns/http-clients/index.js +50 -0
- package/dist/patterns/http-clients/index.js.map +1 -0
- package/dist/patterns/http-clients/property-access.d.ts +46 -0
- package/dist/patterns/http-clients/property-access.d.ts.map +1 -0
- package/dist/patterns/http-clients/property-access.js +818 -0
- package/dist/patterns/http-clients/property-access.js.map +1 -0
- package/dist/patterns/http-clients/type-inference.d.ts +48 -0
- package/dist/patterns/http-clients/type-inference.d.ts.map +1 -0
- package/dist/patterns/http-clients/type-inference.js +293 -0
- package/dist/patterns/http-clients/type-inference.js.map +1 -0
- package/dist/patterns/http-clients/types.d.ts +168 -0
- package/dist/patterns/http-clients/types.d.ts.map +1 -0
- package/dist/patterns/http-clients/types.js +10 -0
- package/dist/patterns/http-clients/types.js.map +1 -0
- package/dist/patterns/http-clients/url-extractor.d.ts +53 -0
- package/dist/patterns/http-clients/url-extractor.d.ts.map +1 -0
- package/dist/patterns/http-clients/url-extractor.js +338 -0
- package/dist/patterns/http-clients/url-extractor.js.map +1 -0
- package/dist/patterns/index.d.ts +44 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +49 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/python/aiohttp.d.ts +21 -0
- package/dist/patterns/python/aiohttp.d.ts.map +1 -0
- package/dist/patterns/python/aiohttp.js +188 -0
- package/dist/patterns/python/aiohttp.js.map +1 -0
- package/dist/patterns/python/httpx.d.ts +20 -0
- package/dist/patterns/python/httpx.d.ts.map +1 -0
- package/dist/patterns/python/httpx.js +183 -0
- package/dist/patterns/python/httpx.js.map +1 -0
- package/dist/patterns/python/index.d.ts +32 -0
- package/dist/patterns/python/index.d.ts.map +1 -0
- package/dist/patterns/python/index.js +63 -0
- package/dist/patterns/python/index.js.map +1 -0
- package/dist/patterns/python/property-access.d.ts +27 -0
- package/dist/patterns/python/property-access.d.ts.map +1 -0
- package/dist/patterns/python/property-access.js +132 -0
- package/dist/patterns/python/property-access.js.map +1 -0
- package/dist/patterns/python/requests.d.ts +19 -0
- package/dist/patterns/python/requests.d.ts.map +1 -0
- package/dist/patterns/python/requests.js +239 -0
- package/dist/patterns/python/requests.js.map +1 -0
- package/dist/patterns/python/types.d.ts +95 -0
- package/dist/patterns/python/types.d.ts.map +1 -0
- package/dist/patterns/python/types.js +43 -0
- package/dist/patterns/python/types.js.map +1 -0
- package/dist/patterns/registry.d.ts +181 -0
- package/dist/patterns/registry.d.ts.map +1 -0
- package/dist/patterns/registry.js +304 -0
- package/dist/patterns/registry.js.map +1 -0
- package/dist/patterns/rest/express.d.ts +78 -0
- package/dist/patterns/rest/express.d.ts.map +1 -0
- package/dist/patterns/rest/express.js +289 -0
- package/dist/patterns/rest/express.js.map +1 -0
- package/dist/patterns/rest/fastify.d.ts +93 -0
- package/dist/patterns/rest/fastify.d.ts.map +1 -0
- package/dist/patterns/rest/fastify.js +420 -0
- package/dist/patterns/rest/fastify.js.map +1 -0
- package/dist/patterns/rest/index.d.ts +31 -0
- package/dist/patterns/rest/index.d.ts.map +1 -0
- package/dist/patterns/rest/index.js +45 -0
- package/dist/patterns/rest/index.js.map +1 -0
- package/dist/patterns/rest/middleware.d.ts +25 -0
- package/dist/patterns/rest/middleware.d.ts.map +1 -0
- package/dist/patterns/rest/middleware.js +219 -0
- package/dist/patterns/rest/middleware.js.map +1 -0
- package/dist/patterns/rest/path-parser.d.ts +50 -0
- package/dist/patterns/rest/path-parser.d.ts.map +1 -0
- package/dist/patterns/rest/path-parser.js +137 -0
- package/dist/patterns/rest/path-parser.js.map +1 -0
- package/dist/patterns/rest/response-inference.d.ts +44 -0
- package/dist/patterns/rest/response-inference.d.ts.map +1 -0
- package/dist/patterns/rest/response-inference.js +218 -0
- package/dist/patterns/rest/response-inference.js.map +1 -0
- package/dist/patterns/rest/types.d.ts +102 -0
- package/dist/patterns/rest/types.d.ts.map +1 -0
- package/dist/patterns/rest/types.js +10 -0
- package/dist/patterns/rest/types.js.map +1 -0
- package/dist/patterns/types.d.ts +105 -0
- package/dist/patterns/types.d.ts.map +1 -0
- package/dist/patterns/types.js +11 -0
- package/dist/patterns/types.js.map +1 -0
- package/dist/report/index.d.ts +11 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +55 -0
- package/dist/report/index.js.map +1 -0
- package/dist/tools/contract-comments.d.ts +48 -0
- package/dist/tools/contract-comments.d.ts.map +1 -0
- package/dist/tools/contract-comments.js +130 -0
- package/dist/tools/contract-comments.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/scaffold.d.ts +38 -0
- package/dist/tools/scaffold.d.ts.map +1 -0
- package/dist/tools/scaffold.js +373 -0
- package/dist/tools/scaffold.js.map +1 -0
- package/dist/trace/index.d.ts +28 -0
- package/dist/trace/index.d.ts.map +1 -0
- package/dist/trace/index.js +45 -0
- package/dist/trace/index.js.map +1 -0
- package/dist/types.d.ts +135 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -0
- package/dist/watch/cache.d.ts +41 -0
- package/dist/watch/cache.d.ts.map +1 -0
- package/dist/watch/cache.js +230 -0
- package/dist/watch/cache.js.map +1 -0
- package/dist/watch/index.d.ts +9 -0
- package/dist/watch/index.d.ts.map +1 -0
- package/dist/watch/index.js +7 -0
- package/dist/watch/index.js.map +1 -0
- package/dist/watch/project.d.ts +128 -0
- package/dist/watch/project.d.ts.map +1 -0
- package/dist/watch/project.js +152 -0
- package/dist/watch/project.js.map +1 -0
- package/dist/watch/watcher.d.ts +76 -0
- package/dist/watch/watcher.d.ts.map +1 -0
- package/dist/watch/watcher.js +235 -0
- package/dist/watch/watcher.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL Extraction Utilities
|
|
3
|
+
*
|
|
4
|
+
* Extract URL information from AST nodes for HTTP client calls.
|
|
5
|
+
* Handles static strings, template literals, variable references,
|
|
6
|
+
* and string concatenation.
|
|
7
|
+
*
|
|
8
|
+
* @module patterns/http-clients/url-extractor
|
|
9
|
+
* @see .context/ADR-P2-3-HTTP-CLIENT-TRACING.md
|
|
10
|
+
*/
|
|
11
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
12
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
13
|
+
* 🔗 Public API
|
|
14
|
+
* ═══════════════════════════════════════════════════════════════════════════ */
|
|
15
|
+
/**
|
|
16
|
+
* Extract URL information from an AST node.
|
|
17
|
+
*
|
|
18
|
+
* Handles:
|
|
19
|
+
* - String literals: `'/api/users'`
|
|
20
|
+
* - Template literals: `` `/api/users/${id}` ``
|
|
21
|
+
* - Variable references: `API_URL`
|
|
22
|
+
* - Concatenation: `baseUrl + '/users'`
|
|
23
|
+
*
|
|
24
|
+
* @param node - The AST node to extract URL from
|
|
25
|
+
* @returns URLExtractionResult or undefined if not extractable
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const urlNode = callExpr.getArguments()[0];
|
|
30
|
+
* const result = extractURL(urlNode);
|
|
31
|
+
* // { raw: '/api/users', static: '/api/users', isDynamic: false }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function extractURL(node) {
|
|
35
|
+
if (!node)
|
|
36
|
+
return undefined;
|
|
37
|
+
// Handle string literals
|
|
38
|
+
if (Node.isStringLiteral(node)) {
|
|
39
|
+
const value = node.getLiteralValue();
|
|
40
|
+
return parseStaticURL(value);
|
|
41
|
+
}
|
|
42
|
+
// Handle no-substitution template literals (static templates)
|
|
43
|
+
if (Node.isNoSubstitutionTemplateLiteral(node)) {
|
|
44
|
+
const value = node.getLiteralValue();
|
|
45
|
+
return parseStaticURL(value);
|
|
46
|
+
}
|
|
47
|
+
// Handle template expressions with substitutions
|
|
48
|
+
if (Node.isTemplateExpression(node)) {
|
|
49
|
+
return parseTemplateExpression(node);
|
|
50
|
+
}
|
|
51
|
+
// Handle identifier references (variable names)
|
|
52
|
+
if (Node.isIdentifier(node)) {
|
|
53
|
+
return resolveIdentifier(node);
|
|
54
|
+
}
|
|
55
|
+
// Handle binary expressions (concatenation)
|
|
56
|
+
if (Node.isBinaryExpression(node)) {
|
|
57
|
+
return parseBinaryExpression(node);
|
|
58
|
+
}
|
|
59
|
+
// Handle call expressions like URL.toString()
|
|
60
|
+
if (Node.isCallExpression(node)) {
|
|
61
|
+
const expr = node.getExpression();
|
|
62
|
+
if (Node.isPropertyAccessExpression(expr)) {
|
|
63
|
+
const methodName = expr.getName();
|
|
64
|
+
if (methodName === 'toString') {
|
|
65
|
+
// URL object's toString() - mark as dynamic
|
|
66
|
+
return {
|
|
67
|
+
raw: 'URL.toString()',
|
|
68
|
+
isDynamic: true,
|
|
69
|
+
pathParams: [],
|
|
70
|
+
queryParams: [],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Compose a baseURL with a path.
|
|
79
|
+
*
|
|
80
|
+
* Handles:
|
|
81
|
+
* - Trailing slashes in baseURL
|
|
82
|
+
* - Missing leading slashes in path
|
|
83
|
+
* - Full URL baseURLs
|
|
84
|
+
*
|
|
85
|
+
* @param baseURL - Base URL (e.g., '/api' or 'https://api.example.com')
|
|
86
|
+
* @param path - Path to append (e.g., '/users' or 'users')
|
|
87
|
+
* @returns Composed URL
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* composeURL('/api', '/users') // '/api/users'
|
|
92
|
+
* composeURL('/api/', 'users') // '/api/users'
|
|
93
|
+
* composeURL('https://api.com', '/users') // 'https://api.com/users'
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export function composeURL(baseURL, path) {
|
|
97
|
+
// Normalize base URL - remove trailing slash
|
|
98
|
+
const normalizedBase = baseURL.replace(/\/+$/, '');
|
|
99
|
+
// Normalize path - ensure leading slash
|
|
100
|
+
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
101
|
+
return normalizedBase + normalizedPath;
|
|
102
|
+
}
|
|
103
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
104
|
+
* 🔧 Static URL Parsing
|
|
105
|
+
* ═══════════════════════════════════════════════════════════════════════════ */
|
|
106
|
+
/**
|
|
107
|
+
* Parse a static URL string and extract path/query params.
|
|
108
|
+
*
|
|
109
|
+
* @internal
|
|
110
|
+
*/
|
|
111
|
+
function parseStaticURL(url) {
|
|
112
|
+
const pathParams = [];
|
|
113
|
+
const queryParams = [];
|
|
114
|
+
// Check for Express-style path params like :userId
|
|
115
|
+
const expressParamRegex = /:(\w+)/g;
|
|
116
|
+
let match;
|
|
117
|
+
while ((match = expressParamRegex.exec(url)) !== null) {
|
|
118
|
+
pathParams.push(match[1]);
|
|
119
|
+
}
|
|
120
|
+
// Extract query parameters
|
|
121
|
+
const queryIndex = url.indexOf('?');
|
|
122
|
+
if (queryIndex !== -1) {
|
|
123
|
+
const queryString = url.slice(queryIndex + 1);
|
|
124
|
+
const params = queryString.split('&');
|
|
125
|
+
for (const param of params) {
|
|
126
|
+
const [key] = param.split('=');
|
|
127
|
+
if (key) {
|
|
128
|
+
// Remove any template placeholders in query param names
|
|
129
|
+
const cleanKey = key.replace(/\$\{[^}]+\}/, '').trim();
|
|
130
|
+
if (cleanKey) {
|
|
131
|
+
queryParams.push(cleanKey);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const hasExpressParams = pathParams.length > 0;
|
|
137
|
+
return {
|
|
138
|
+
raw: url,
|
|
139
|
+
static: hasExpressParams ? undefined : url,
|
|
140
|
+
isDynamic: hasExpressParams,
|
|
141
|
+
pattern: hasExpressParams ? url : undefined,
|
|
142
|
+
pathParams: pathParams.length > 0 ? pathParams : undefined,
|
|
143
|
+
queryParams: queryParams.length > 0 ? queryParams : undefined,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
147
|
+
* 📝 Template Expression Parsing
|
|
148
|
+
* ═══════════════════════════════════════════════════════════════════════════ */
|
|
149
|
+
/**
|
|
150
|
+
* Get the literal text from a template head/middle/tail node.
|
|
151
|
+
*
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
function getTemplatePartText(node) {
|
|
155
|
+
// Use getText() and strip the template delimiters
|
|
156
|
+
const text = node.getText();
|
|
157
|
+
// TemplateHead: `text${ -> extract "text"
|
|
158
|
+
// TemplateMiddle: }text${ -> extract "text"
|
|
159
|
+
// TemplateTail: }text` -> extract "text"
|
|
160
|
+
// Remove leading ` or }
|
|
161
|
+
let result = text;
|
|
162
|
+
if (result.startsWith('`')) {
|
|
163
|
+
result = result.slice(1);
|
|
164
|
+
}
|
|
165
|
+
else if (result.startsWith('}')) {
|
|
166
|
+
result = result.slice(1);
|
|
167
|
+
}
|
|
168
|
+
// Remove trailing ${ or `
|
|
169
|
+
if (result.endsWith('${')) {
|
|
170
|
+
result = result.slice(0, -2);
|
|
171
|
+
}
|
|
172
|
+
else if (result.endsWith('`')) {
|
|
173
|
+
result = result.slice(0, -1);
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Parse a template expression with substitutions.
|
|
179
|
+
*
|
|
180
|
+
* @internal
|
|
181
|
+
*/
|
|
182
|
+
function parseTemplateExpression(node) {
|
|
183
|
+
if (!Node.isTemplateExpression(node))
|
|
184
|
+
return { raw: '', isDynamic: true };
|
|
185
|
+
const head = node.getHead();
|
|
186
|
+
const spans = node.getTemplateSpans();
|
|
187
|
+
let pattern = getTemplatePartText(head);
|
|
188
|
+
const pathParams = [];
|
|
189
|
+
const queryParams = [];
|
|
190
|
+
for (const span of spans) {
|
|
191
|
+
const expr = span.getExpression();
|
|
192
|
+
let paramName = 'param';
|
|
193
|
+
// Try to extract parameter name from expression
|
|
194
|
+
if (Node.isIdentifier(expr)) {
|
|
195
|
+
paramName = expr.getText();
|
|
196
|
+
}
|
|
197
|
+
else if (Node.isPropertyAccessExpression(expr)) {
|
|
198
|
+
// Get the property name: user.id -> id
|
|
199
|
+
paramName = expr.getName();
|
|
200
|
+
}
|
|
201
|
+
else if (Node.isElementAccessExpression(expr)) {
|
|
202
|
+
// Get array index identifier if possible
|
|
203
|
+
const argExpr = expr.getArgumentExpression();
|
|
204
|
+
if (argExpr && Node.isNumericLiteral(argExpr)) {
|
|
205
|
+
paramName = `item${argExpr.getText()}`;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Check if we're in query params section
|
|
209
|
+
const literal = span.getLiteral();
|
|
210
|
+
const literalText = getTemplatePartText(literal);
|
|
211
|
+
const isInQuerySection = pattern.includes('?') || literalText.includes('?');
|
|
212
|
+
if (isInQuerySection && !pattern.includes('?')) {
|
|
213
|
+
// We're adding a query param
|
|
214
|
+
const beforeQuestion = literalText.indexOf('?');
|
|
215
|
+
if (beforeQuestion !== -1) {
|
|
216
|
+
pattern += `:${paramName}` + literalText.slice(0, beforeQuestion + 1);
|
|
217
|
+
pathParams.push(paramName);
|
|
218
|
+
// Continue parsing query params
|
|
219
|
+
const afterQuestion = literalText.slice(beforeQuestion + 1);
|
|
220
|
+
if (afterQuestion.includes('=')) {
|
|
221
|
+
const queryKey = afterQuestion.split('=')[0];
|
|
222
|
+
if (queryKey)
|
|
223
|
+
queryParams.push(queryKey);
|
|
224
|
+
}
|
|
225
|
+
pattern += afterQuestion;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
pattern += `:${paramName}` + literalText;
|
|
229
|
+
queryParams.push(paramName);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
pattern += `:${paramName}` + literalText;
|
|
234
|
+
pathParams.push(paramName);
|
|
235
|
+
}
|
|
236
|
+
// Extract any query params from literal text
|
|
237
|
+
const queryMatch = literalText.match(/[?&](\w+)=/g);
|
|
238
|
+
if (queryMatch) {
|
|
239
|
+
for (const q of queryMatch) {
|
|
240
|
+
const key = q.replace(/[?&=]/g, '');
|
|
241
|
+
if (key && !queryParams.includes(key)) {
|
|
242
|
+
queryParams.push(key);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Build the raw template string representation
|
|
248
|
+
const rawParts = [getTemplatePartText(head)];
|
|
249
|
+
for (const span of spans) {
|
|
250
|
+
rawParts.push('${', span.getExpression().getText(), '}');
|
|
251
|
+
rawParts.push(getTemplatePartText(span.getLiteral()));
|
|
252
|
+
}
|
|
253
|
+
const raw = rawParts.join('');
|
|
254
|
+
return {
|
|
255
|
+
raw,
|
|
256
|
+
isDynamic: true,
|
|
257
|
+
pattern,
|
|
258
|
+
pathParams: pathParams.length > 0 ? pathParams : undefined,
|
|
259
|
+
queryParams: queryParams.length > 0 ? queryParams : undefined,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
263
|
+
* 🔍 Identifier Resolution
|
|
264
|
+
* ═══════════════════════════════════════════════════════════════════════════ */
|
|
265
|
+
/**
|
|
266
|
+
* Resolve an identifier to its value.
|
|
267
|
+
*
|
|
268
|
+
* @internal
|
|
269
|
+
*/
|
|
270
|
+
function resolveIdentifier(node) {
|
|
271
|
+
if (!Node.isIdentifier(node))
|
|
272
|
+
return undefined;
|
|
273
|
+
const name = node.getText();
|
|
274
|
+
const symbol = node.getSymbol();
|
|
275
|
+
if (!symbol) {
|
|
276
|
+
return {
|
|
277
|
+
raw: name,
|
|
278
|
+
isDynamic: true,
|
|
279
|
+
pathParams: [],
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
// Try to find the variable declaration
|
|
283
|
+
const declarations = symbol.getDeclarations();
|
|
284
|
+
for (const decl of declarations) {
|
|
285
|
+
if (Node.isVariableDeclaration(decl)) {
|
|
286
|
+
const initializer = decl.getInitializer();
|
|
287
|
+
if (initializer) {
|
|
288
|
+
const result = extractURL(initializer);
|
|
289
|
+
if (result)
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
raw: name,
|
|
296
|
+
isDynamic: true,
|
|
297
|
+
pathParams: [],
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
301
|
+
* ➕ Binary Expression Parsing
|
|
302
|
+
* ═══════════════════════════════════════════════════════════════════════════ */
|
|
303
|
+
/**
|
|
304
|
+
* Parse binary expression (concatenation).
|
|
305
|
+
*
|
|
306
|
+
* @internal
|
|
307
|
+
*/
|
|
308
|
+
function parseBinaryExpression(node) {
|
|
309
|
+
if (!Node.isBinaryExpression(node))
|
|
310
|
+
return undefined;
|
|
311
|
+
const operator = node.getOperatorToken().getKind();
|
|
312
|
+
if (operator !== SyntaxKind.PlusToken)
|
|
313
|
+
return undefined;
|
|
314
|
+
const left = extractURL(node.getLeft());
|
|
315
|
+
const right = extractURL(node.getRight());
|
|
316
|
+
if (!left && !right) {
|
|
317
|
+
return {
|
|
318
|
+
raw: node.getText(),
|
|
319
|
+
isDynamic: true,
|
|
320
|
+
pathParams: [],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
const leftRaw = left?.raw || node.getLeft().getText();
|
|
324
|
+
const rightRaw = right?.raw || node.getRight().getText();
|
|
325
|
+
return {
|
|
326
|
+
raw: leftRaw + rightRaw,
|
|
327
|
+
isDynamic: true,
|
|
328
|
+
pathParams: [
|
|
329
|
+
...(left?.pathParams || []),
|
|
330
|
+
...(right?.pathParams || []),
|
|
331
|
+
],
|
|
332
|
+
queryParams: [
|
|
333
|
+
...(left?.queryParams || []),
|
|
334
|
+
...(right?.queryParams || []),
|
|
335
|
+
],
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=url-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url-extractor.js","sourceRoot":"","sources":["../../../src/patterns/http-clients/url-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Matcher Module
|
|
3
|
+
*
|
|
4
|
+
* Public API for the pattern matcher abstraction that enables pluggable
|
|
5
|
+
* framework-agnostic API detection.
|
|
6
|
+
*
|
|
7
|
+
* ## Overview
|
|
8
|
+
*
|
|
9
|
+
* The pattern matcher system provides:
|
|
10
|
+
* - **Type Definitions**: Core types for pattern matching ({@link PatternType}, {@link PatternDef})
|
|
11
|
+
* - **Error Handling**: Typed errors with machine-readable codes ({@link PatternErrorCodes})
|
|
12
|
+
* - **Base Classes**: Abstract base for custom matchers ({@link BasePatternMatcher})
|
|
13
|
+
* - **Registry**: Singleton registry for pattern matchers ({@link registerPattern}, {@link scanForPatterns})
|
|
14
|
+
* - **Extractors**: Schema extraction utilities ({@link extractSchemaNode})
|
|
15
|
+
*
|
|
16
|
+
* ## Quick Start
|
|
17
|
+
*
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import {
|
|
20
|
+
* registerPattern,
|
|
21
|
+
* scanForPatterns,
|
|
22
|
+
* BasePatternMatcher
|
|
23
|
+
* } from './patterns';
|
|
24
|
+
*
|
|
25
|
+
* // Register a custom matcher
|
|
26
|
+
* class MyMatcher extends BasePatternMatcher { ... }
|
|
27
|
+
* registerPattern(new MyMatcher());
|
|
28
|
+
*
|
|
29
|
+
* // Scan for patterns
|
|
30
|
+
* const matches = scanForPatterns(sourceFile);
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @module patterns
|
|
34
|
+
* @see .context/ADR-P2-1-PATTERN-MATCHER.md
|
|
35
|
+
*/
|
|
36
|
+
export type { PatternType, SchemaLocation, PatternDef, MatchCaptures, MatchResult, } from './types.js';
|
|
37
|
+
export { PatternErrorCodes, PatternRegistryError, PatternNotFoundError, PatternValidationError, PatternMatchError, PatternExtractionError, } from './errors.js';
|
|
38
|
+
export type { PatternErrorCode } from './errors.js';
|
|
39
|
+
export type { PatternMatcher } from './base.js';
|
|
40
|
+
export { BasePatternMatcher } from './base.js';
|
|
41
|
+
export { registerPattern, getPattern, getPatternsByFramework, getPatternsByType, hasPattern, listPatterns, listFrameworks, scanForPatterns, } from './registry.js';
|
|
42
|
+
export type { ScanOptions } from './registry.js';
|
|
43
|
+
export { extractSchemaNode, extractFromArg, extractFromNamedArg, extractFromReturn, extractFromTypeParam, extractFromBody, extractFromChainMethod, extractFromDecoratorArg, } from './extractors.js';
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,aAAa,EACb,WAAW,GACZ,MAAM,YAAY,CAAC;AAMpB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAM/C,OAAO,EACL,eAAe,EACf,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAMjD,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pattern Matcher Module
|
|
3
|
+
*
|
|
4
|
+
* Public API for the pattern matcher abstraction that enables pluggable
|
|
5
|
+
* framework-agnostic API detection.
|
|
6
|
+
*
|
|
7
|
+
* ## Overview
|
|
8
|
+
*
|
|
9
|
+
* The pattern matcher system provides:
|
|
10
|
+
* - **Type Definitions**: Core types for pattern matching ({@link PatternType}, {@link PatternDef})
|
|
11
|
+
* - **Error Handling**: Typed errors with machine-readable codes ({@link PatternErrorCodes})
|
|
12
|
+
* - **Base Classes**: Abstract base for custom matchers ({@link BasePatternMatcher})
|
|
13
|
+
* - **Registry**: Singleton registry for pattern matchers ({@link registerPattern}, {@link scanForPatterns})
|
|
14
|
+
* - **Extractors**: Schema extraction utilities ({@link extractSchemaNode})
|
|
15
|
+
*
|
|
16
|
+
* ## Quick Start
|
|
17
|
+
*
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import {
|
|
20
|
+
* registerPattern,
|
|
21
|
+
* scanForPatterns,
|
|
22
|
+
* BasePatternMatcher
|
|
23
|
+
* } from './patterns';
|
|
24
|
+
*
|
|
25
|
+
* // Register a custom matcher
|
|
26
|
+
* class MyMatcher extends BasePatternMatcher { ... }
|
|
27
|
+
* registerPattern(new MyMatcher());
|
|
28
|
+
*
|
|
29
|
+
* // Scan for patterns
|
|
30
|
+
* const matches = scanForPatterns(sourceFile);
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @module patterns
|
|
34
|
+
* @see .context/ADR-P2-1-PATTERN-MATCHER.md
|
|
35
|
+
*/
|
|
36
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
37
|
+
// ⚠️ Error Types and Codes
|
|
38
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
39
|
+
export { PatternErrorCodes, PatternRegistryError, PatternNotFoundError, PatternValidationError, PatternMatchError, PatternExtractionError, } from './errors.js';
|
|
40
|
+
export { BasePatternMatcher } from './base.js';
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
// 📝 Registry Functions
|
|
43
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
44
|
+
export { registerPattern, getPattern, getPatternsByFramework, getPatternsByType, hasPattern, listPatterns, listFrameworks, scanForPatterns, } from './registry.js';
|
|
45
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
46
|
+
// 🔍 Schema Extractors
|
|
47
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
48
|
+
export { extractSchemaNode, extractFromArg, extractFromNamedArg, extractFromReturn, extractFromTypeParam, extractFromBody, extractFromChainMethod, extractFromDecoratorArg, } from './extractors.js';
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAcH,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AASrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF,OAAO,EACL,eAAe,EACf,UAAU,EACV,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAIvB,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python aiohttp library HTTP client detection
|
|
3
|
+
*
|
|
4
|
+
* Detects calls to the aiohttp library:
|
|
5
|
+
* - aiohttp.ClientSession().get(), etc.
|
|
6
|
+
* - session.get(), session.post() within context managers
|
|
7
|
+
*
|
|
8
|
+
* aiohttp is always async and uses context managers heavily
|
|
9
|
+
*
|
|
10
|
+
* @see .context/TASK_MAP_P3.md - Task P3-4
|
|
11
|
+
*/
|
|
12
|
+
import type { PythonHttpCall } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Detect HTTP calls from the aiohttp library in Python source code
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectAiohttpCalls(content: string): PythonHttpCall[];
|
|
17
|
+
/**
|
|
18
|
+
* Get the response properties that aiohttp library supports
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAiohttpResponseProperties(): string[];
|
|
21
|
+
//# sourceMappingURL=aiohttp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aiohttp.d.ts","sourceRoot":"","sources":["../../../src/patterns/python/aiohttp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,YAAY,CAAC;AAUpB;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAsFpE;AAiHD;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,EAAE,CAEvD"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python aiohttp library HTTP client detection
|
|
3
|
+
*
|
|
4
|
+
* Detects calls to the aiohttp library:
|
|
5
|
+
* - aiohttp.ClientSession().get(), etc.
|
|
6
|
+
* - session.get(), session.post() within context managers
|
|
7
|
+
*
|
|
8
|
+
* aiohttp is always async and uses context managers heavily
|
|
9
|
+
*
|
|
10
|
+
* @see .context/TASK_MAP_P3.md - Task P3-4
|
|
11
|
+
*/
|
|
12
|
+
import { HTTP_CLIENT_PATTERNS, normalizeHttpMethod } from './types.js';
|
|
13
|
+
const AIOHTTP_PATTERN = HTTP_CLIENT_PATTERNS.aiohttp;
|
|
14
|
+
/**
|
|
15
|
+
* Track known session variable names
|
|
16
|
+
*/
|
|
17
|
+
const sessionVars = new Set();
|
|
18
|
+
/**
|
|
19
|
+
* Detect HTTP calls from the aiohttp library in Python source code
|
|
20
|
+
*/
|
|
21
|
+
export function detectAiohttpCalls(content) {
|
|
22
|
+
const calls = [];
|
|
23
|
+
const lines = content.split('\n');
|
|
24
|
+
// First pass: detect imports
|
|
25
|
+
const hasAiohttpImport = /^\s*import\s+aiohttp\b/m.test(content) ||
|
|
26
|
+
/^\s*from\s+aiohttp\s+import\s+/.test(content);
|
|
27
|
+
if (!hasAiohttpImport) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
// Second pass: find session variables
|
|
31
|
+
sessionVars.clear();
|
|
32
|
+
// Match: async with aiohttp.ClientSession() as session:
|
|
33
|
+
const asyncWithSessionRegex = /async\s+with\s+(?:aiohttp\.)?ClientSession\s*\([^)]*\)\s+as\s+(\w+)/g;
|
|
34
|
+
let match;
|
|
35
|
+
while ((match = asyncWithSessionRegex.exec(content)) !== null) {
|
|
36
|
+
sessionVars.add(match[1]);
|
|
37
|
+
}
|
|
38
|
+
// Match: session = aiohttp.ClientSession()
|
|
39
|
+
const sessionCreateRegex = /\b(\w+)\s*=\s*(?:aiohttp\.)?ClientSession\s*\(/g;
|
|
40
|
+
while ((match = sessionCreateRegex.exec(content)) !== null) {
|
|
41
|
+
sessionVars.add(match[1]);
|
|
42
|
+
}
|
|
43
|
+
// Also match common variable names that might be sessions
|
|
44
|
+
// (client, session, http_session, api_session)
|
|
45
|
+
const commonSessionNames = ['session', 'client', 'http_session', 'api_session'];
|
|
46
|
+
for (const name of commonSessionNames) {
|
|
47
|
+
const regex = new RegExp(`\\b${name}\\s*=\\s*(?:aiohttp\\.)?ClientSession\\s*\\(`, 'g');
|
|
48
|
+
if (regex.test(content)) {
|
|
49
|
+
sessionVars.add(name);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Third pass: detect HTTP calls line by line
|
|
53
|
+
for (let i = 0; i < lines.length; i++) {
|
|
54
|
+
const line = lines[i];
|
|
55
|
+
const lineNum = i + 1;
|
|
56
|
+
// Detect session.method() calls in context managers
|
|
57
|
+
// Pattern: async with session.get(...) as response:
|
|
58
|
+
const asyncWithMethodRegex = /async\s+with\s+(\w+)\.(get|post|put|patch|delete|head|options|request)\s*\(/gi;
|
|
59
|
+
while ((match = asyncWithMethodRegex.exec(line)) !== null) {
|
|
60
|
+
const sessionVar = match[1];
|
|
61
|
+
const method = normalizeHttpMethod(match[2]);
|
|
62
|
+
// Check if it's a known session or likely a session
|
|
63
|
+
if (method && (sessionVars.has(sessionVar) || isLikelySession(sessionVar, content))) {
|
|
64
|
+
const call = createHttpCall(method, 'aiohttp', line, lineNum, match.index);
|
|
65
|
+
call.isSession = true;
|
|
66
|
+
call.isAsync = true;
|
|
67
|
+
// Extract response variable from "as response"
|
|
68
|
+
const asMatch = line.match(/as\s+(\w+)\s*:/);
|
|
69
|
+
if (asMatch) {
|
|
70
|
+
call.responseVariable = asMatch[1];
|
|
71
|
+
}
|
|
72
|
+
calls.push(call);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Detect await session.method() calls (not in context manager)
|
|
76
|
+
// Pattern: await session.get(...)
|
|
77
|
+
for (const sessionVar of sessionVars) {
|
|
78
|
+
const awaitCallRegex = new RegExp(`await\\s+${escapeRegex(sessionVar)}\\.(get|post|put|patch|delete|head|options|request)\\s*\\(`, 'gi');
|
|
79
|
+
while ((match = awaitCallRegex.exec(line)) !== null) {
|
|
80
|
+
const method = normalizeHttpMethod(match[1]);
|
|
81
|
+
if (method) {
|
|
82
|
+
const call = createHttpCall(method, 'aiohttp', line, lineNum, match.index);
|
|
83
|
+
call.isSession = true;
|
|
84
|
+
call.isAsync = true;
|
|
85
|
+
calls.push(call);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return calls;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if a variable name is likely a session based on context
|
|
94
|
+
*/
|
|
95
|
+
function isLikelySession(varName, content) {
|
|
96
|
+
// Common patterns that indicate aiohttp session
|
|
97
|
+
const sessionIndicators = [
|
|
98
|
+
`${varName} = aiohttp.ClientSession`,
|
|
99
|
+
`${varName} = ClientSession`,
|
|
100
|
+
`aiohttp.ClientSession() as ${varName}`,
|
|
101
|
+
`ClientSession() as ${varName}`
|
|
102
|
+
];
|
|
103
|
+
for (const indicator of sessionIndicators) {
|
|
104
|
+
if (content.includes(indicator)) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Variable names that suggest sessions
|
|
109
|
+
const sessionNamePatterns = /^(session|client|http_client|api_client|http_session|api_session)$/i;
|
|
110
|
+
return sessionNamePatterns.test(varName);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Create a PythonHttpCall from a detected call
|
|
114
|
+
*/
|
|
115
|
+
function createHttpCall(method, library, line, lineNum, column) {
|
|
116
|
+
const call = {
|
|
117
|
+
method,
|
|
118
|
+
library,
|
|
119
|
+
line: lineNum,
|
|
120
|
+
column,
|
|
121
|
+
isAsync: true // aiohttp is always async
|
|
122
|
+
};
|
|
123
|
+
// Extract URL
|
|
124
|
+
const urlInfo = extractUrl(line);
|
|
125
|
+
if (urlInfo) {
|
|
126
|
+
call.url = urlInfo.url;
|
|
127
|
+
call.isDynamicUrl = urlInfo.isDynamic;
|
|
128
|
+
call.pathParams = urlInfo.pathParams;
|
|
129
|
+
}
|
|
130
|
+
// Detect query params
|
|
131
|
+
if (/\bparams\s*=/.test(line)) {
|
|
132
|
+
call.hasQueryParams = true;
|
|
133
|
+
}
|
|
134
|
+
// URL with query string
|
|
135
|
+
if (call.url?.includes('?')) {
|
|
136
|
+
call.hasQueryParams = true;
|
|
137
|
+
}
|
|
138
|
+
// Detect headers
|
|
139
|
+
if (/\bheaders\s*=/.test(line)) {
|
|
140
|
+
call.hasHeaders = true;
|
|
141
|
+
}
|
|
142
|
+
// Detect body
|
|
143
|
+
if (/\bjson\s*=/.test(line) || /\bdata\s*=/.test(line)) {
|
|
144
|
+
call.hasBody = true;
|
|
145
|
+
}
|
|
146
|
+
return call;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Extract URL from a call line
|
|
150
|
+
*/
|
|
151
|
+
function extractUrl(line) {
|
|
152
|
+
// Match f-strings first
|
|
153
|
+
const fstringMatch = line.match(/f["']([^"']+)["']/);
|
|
154
|
+
if (fstringMatch) {
|
|
155
|
+
const url = fstringMatch[1];
|
|
156
|
+
const pathParams = [];
|
|
157
|
+
let paramMatch;
|
|
158
|
+
const paramRegex = /\{(\w+)\}/g;
|
|
159
|
+
while ((paramMatch = paramRegex.exec(url)) !== null) {
|
|
160
|
+
pathParams.push(paramMatch[1]);
|
|
161
|
+
}
|
|
162
|
+
return { url, isDynamic: true, pathParams };
|
|
163
|
+
}
|
|
164
|
+
// Match regular strings - look for method call with string arg
|
|
165
|
+
const stringMatch = line.match(/\.(get|post|put|patch|delete|head|options|request)\s*\(\s*["']([^"']+)["']/i);
|
|
166
|
+
if (stringMatch) {
|
|
167
|
+
return { url: stringMatch[2], isDynamic: false, pathParams: [] };
|
|
168
|
+
}
|
|
169
|
+
// Generic string match after opening paren
|
|
170
|
+
const genericMatch = line.match(/\(\s*["']([^"']+)["']/);
|
|
171
|
+
if (genericMatch) {
|
|
172
|
+
return { url: genericMatch[1], isDynamic: false, pathParams: [] };
|
|
173
|
+
}
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Escape special regex characters in a string
|
|
178
|
+
*/
|
|
179
|
+
function escapeRegex(str) {
|
|
180
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get the response properties that aiohttp library supports
|
|
184
|
+
*/
|
|
185
|
+
export function getAiohttpResponseProperties() {
|
|
186
|
+
return AIOHTTP_PATTERN.responseAccess;
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=aiohttp.js.map
|