gitnexus 1.5.3 → 1.6.1
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 +10 -0
- package/dist/_shared/graph/types.d.ts +1 -1
- package/dist/_shared/graph/types.d.ts.map +1 -1
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/language-detection.d.ts.map +1 -1
- package/dist/_shared/language-detection.js +2 -0
- package/dist/_shared/language-detection.js.map +1 -1
- package/dist/_shared/languages.d.ts +1 -0
- package/dist/_shared/languages.d.ts.map +1 -1
- package/dist/_shared/languages.js +1 -0
- package/dist/_shared/languages.js.map +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts +1 -1
- package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
- package/dist/_shared/lbug/schema-constants.js +3 -1
- package/dist/_shared/lbug/schema-constants.js.map +1 -1
- package/dist/_shared/mro-strategy.d.ts +19 -0
- package/dist/_shared/mro-strategy.d.ts.map +1 -0
- package/dist/_shared/mro-strategy.js +2 -0
- package/dist/_shared/mro-strategy.js.map +1 -0
- package/dist/cli/ai-context.d.ts +1 -0
- package/dist/cli/ai-context.js +28 -4
- package/dist/cli/analyze.d.ts +2 -0
- package/dist/cli/analyze.js +30 -4
- package/dist/cli/group.d.ts +2 -0
- package/dist/cli/group.js +233 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/serve.js +4 -1
- package/dist/cli/setup.js +34 -3
- package/dist/config/ignore-service.js +8 -3
- package/dist/core/augmentation/engine.js +1 -1
- package/dist/core/git-staleness.d.ts +13 -0
- package/dist/core/git-staleness.js +29 -0
- package/dist/core/group/bridge-db.d.ts +82 -0
- package/dist/core/group/bridge-db.js +460 -0
- package/dist/core/group/bridge-schema.d.ts +27 -0
- package/dist/core/group/bridge-schema.js +55 -0
- package/dist/core/group/config-parser.d.ts +3 -0
- package/dist/core/group/config-parser.js +83 -0
- package/dist/core/group/contract-extractor.d.ts +7 -0
- package/dist/core/group/contract-extractor.js +1 -0
- package/dist/core/group/extractors/fs-utils.d.ts +10 -0
- package/dist/core/group/extractors/fs-utils.js +24 -0
- package/dist/core/group/extractors/grpc-extractor.d.ts +25 -0
- package/dist/core/group/extractors/grpc-extractor.js +386 -0
- package/dist/core/group/extractors/grpc-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/go.js +97 -0
- package/dist/core/group/extractors/grpc-patterns/index.d.ts +19 -0
- package/dist/core/group/extractors/grpc-patterns/index.js +46 -0
- package/dist/core/group/extractors/grpc-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/java.js +173 -0
- package/dist/core/group/extractors/grpc-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/grpc-patterns/node.js +290 -0
- package/dist/core/group/extractors/grpc-patterns/proto.d.ts +9 -0
- package/dist/core/group/extractors/grpc-patterns/proto.js +134 -0
- package/dist/core/group/extractors/grpc-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/grpc-patterns/python.js +67 -0
- package/dist/core/group/extractors/grpc-patterns/types.d.ts +50 -0
- package/dist/core/group/extractors/grpc-patterns/types.js +1 -0
- package/dist/core/group/extractors/http-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/go.js +215 -0
- package/dist/core/group/extractors/http-patterns/index.d.ts +17 -0
- package/dist/core/group/extractors/http-patterns/index.js +44 -0
- package/dist/core/group/extractors/http-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/java.js +253 -0
- package/dist/core/group/extractors/http-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/http-patterns/node.js +354 -0
- package/dist/core/group/extractors/http-patterns/php.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/php.js +70 -0
- package/dist/core/group/extractors/http-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/http-patterns/python.js +133 -0
- package/dist/core/group/extractors/http-patterns/types.d.ts +61 -0
- package/dist/core/group/extractors/http-patterns/types.js +1 -0
- package/dist/core/group/extractors/http-route-extractor.d.ts +21 -0
- package/dist/core/group/extractors/http-route-extractor.js +391 -0
- package/dist/core/group/extractors/manifest-extractor.d.ts +54 -0
- package/dist/core/group/extractors/manifest-extractor.js +235 -0
- package/dist/core/group/extractors/topic-extractor.d.ts +8 -0
- package/dist/core/group/extractors/topic-extractor.js +97 -0
- package/dist/core/group/extractors/topic-patterns/go.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/go.js +120 -0
- package/dist/core/group/extractors/topic-patterns/index.d.ts +14 -0
- package/dist/core/group/extractors/topic-patterns/index.js +38 -0
- package/dist/core/group/extractors/topic-patterns/java.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/java.js +80 -0
- package/dist/core/group/extractors/topic-patterns/node.d.ts +4 -0
- package/dist/core/group/extractors/topic-patterns/node.js +155 -0
- package/dist/core/group/extractors/topic-patterns/python.d.ts +2 -0
- package/dist/core/group/extractors/topic-patterns/python.js +116 -0
- package/dist/core/group/extractors/topic-patterns/types.d.ts +25 -0
- package/dist/core/group/extractors/topic-patterns/types.js +10 -0
- package/dist/core/group/extractors/tree-sitter-scanner.d.ts +113 -0
- package/dist/core/group/extractors/tree-sitter-scanner.js +94 -0
- package/dist/core/group/matching.d.ts +13 -0
- package/dist/core/group/matching.js +198 -0
- package/dist/core/group/normalization.d.ts +3 -0
- package/dist/core/group/normalization.js +115 -0
- package/dist/core/group/service-boundary-detector.d.ts +8 -0
- package/dist/core/group/service-boundary-detector.js +155 -0
- package/dist/core/group/service.d.ts +46 -0
- package/dist/core/group/service.js +160 -0
- package/dist/core/group/storage.d.ts +9 -0
- package/dist/core/group/storage.js +91 -0
- package/dist/core/group/sync.d.ts +21 -0
- package/dist/core/group/sync.js +148 -0
- package/dist/core/group/types.d.ts +130 -0
- package/dist/core/group/types.js +1 -0
- package/dist/core/ingestion/binding-accumulator.d.ts +212 -0
- package/dist/core/ingestion/binding-accumulator.js +336 -0
- package/dist/core/ingestion/call-processor.d.ts +155 -24
- package/dist/core/ingestion/call-processor.js +1129 -247
- package/dist/core/ingestion/class-extractors/generic.d.ts +2 -0
- package/dist/core/ingestion/class-extractors/generic.js +135 -0
- package/dist/core/ingestion/class-types.d.ts +34 -0
- package/dist/core/ingestion/class-types.js +1 -0
- package/dist/core/ingestion/cobol-processor.d.ts +1 -1
- package/dist/core/ingestion/entry-point-scoring.d.ts +1 -0
- package/dist/core/ingestion/entry-point-scoring.js +1 -0
- package/dist/core/ingestion/field-types.d.ts +2 -2
- package/dist/core/ingestion/filesystem-walker.js +8 -0
- package/dist/core/ingestion/framework-detection.d.ts +1 -0
- package/dist/core/ingestion/framework-detection.js +1 -0
- package/dist/core/ingestion/heritage-processor.d.ts +8 -15
- package/dist/core/ingestion/heritage-processor.js +15 -28
- package/dist/core/ingestion/import-processor.d.ts +1 -11
- package/dist/core/ingestion/import-processor.js +1 -13
- package/dist/core/ingestion/import-resolvers/utils.js +1 -0
- package/dist/core/ingestion/import-resolvers/vue.d.ts +8 -0
- package/dist/core/ingestion/import-resolvers/vue.js +9 -0
- package/dist/core/ingestion/language-config.js +1 -1
- package/dist/core/ingestion/language-provider.d.ts +14 -3
- package/dist/core/ingestion/languages/c-cpp.js +168 -1
- package/dist/core/ingestion/languages/csharp.js +20 -0
- package/dist/core/ingestion/languages/dart.js +26 -4
- package/dist/core/ingestion/languages/go.js +22 -0
- package/dist/core/ingestion/languages/index.d.ts +1 -0
- package/dist/core/ingestion/languages/index.js +2 -0
- package/dist/core/ingestion/languages/java.js +17 -0
- package/dist/core/ingestion/languages/kotlin.js +24 -1
- package/dist/core/ingestion/languages/php.js +23 -11
- package/dist/core/ingestion/languages/python.js +9 -0
- package/dist/core/ingestion/languages/ruby.js +43 -0
- package/dist/core/ingestion/languages/rust.js +38 -0
- package/dist/core/ingestion/languages/swift.js +31 -0
- package/dist/core/ingestion/languages/typescript.d.ts +1 -0
- package/dist/core/ingestion/languages/typescript.js +52 -3
- package/dist/core/ingestion/languages/vue.d.ts +13 -0
- package/dist/core/ingestion/languages/vue.js +81 -0
- package/dist/core/ingestion/markdown-processor.d.ts +1 -1
- package/dist/core/ingestion/method-extractors/configs/c-cpp.d.ts +3 -0
- package/dist/core/ingestion/method-extractors/configs/c-cpp.js +387 -0
- package/dist/core/ingestion/method-extractors/configs/csharp.js +5 -1
- package/dist/core/ingestion/method-extractors/configs/dart.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/dart.js +376 -0
- package/dist/core/ingestion/method-extractors/configs/go.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/go.js +176 -0
- package/dist/core/ingestion/method-extractors/configs/jvm.js +14 -4
- package/dist/core/ingestion/method-extractors/configs/php.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/php.js +304 -0
- package/dist/core/ingestion/method-extractors/configs/python.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/python.js +309 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/ruby.js +286 -0
- package/dist/core/ingestion/method-extractors/configs/rust.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/rust.js +195 -0
- package/dist/core/ingestion/method-extractors/configs/swift.d.ts +2 -0
- package/dist/core/ingestion/method-extractors/configs/swift.js +277 -0
- package/dist/core/ingestion/method-extractors/configs/typescript-javascript.js +85 -8
- package/dist/core/ingestion/method-extractors/generic.d.ts +6 -0
- package/dist/core/ingestion/method-extractors/generic.js +84 -17
- package/dist/core/ingestion/method-types.d.ts +29 -0
- package/dist/core/ingestion/model/field-registry.d.ts +18 -0
- package/dist/core/ingestion/model/field-registry.js +22 -0
- package/dist/core/ingestion/model/heritage-map.d.ts +70 -0
- package/dist/core/ingestion/model/heritage-map.js +159 -0
- package/dist/core/ingestion/model/index.d.ts +20 -0
- package/dist/core/ingestion/model/index.js +41 -0
- package/dist/core/ingestion/model/method-registry.d.ts +62 -0
- package/dist/core/ingestion/model/method-registry.js +130 -0
- package/dist/core/ingestion/model/registration-table.d.ts +139 -0
- package/dist/core/ingestion/model/registration-table.js +224 -0
- package/dist/core/ingestion/model/resolution-context.d.ts +93 -0
- package/dist/core/ingestion/model/resolution-context.js +337 -0
- package/dist/core/ingestion/model/resolve.d.ts +56 -0
- package/dist/core/ingestion/model/resolve.js +297 -0
- package/dist/core/ingestion/model/semantic-model.d.ts +86 -0
- package/dist/core/ingestion/model/semantic-model.js +120 -0
- package/dist/core/ingestion/model/symbol-table.d.ts +222 -0
- package/dist/core/ingestion/model/symbol-table.js +206 -0
- package/dist/core/ingestion/model/type-registry.d.ts +39 -0
- package/dist/core/ingestion/model/type-registry.js +62 -0
- package/dist/core/ingestion/mro-processor.d.ts +5 -4
- package/dist/core/ingestion/mro-processor.js +311 -107
- package/dist/core/ingestion/parsing-processor.d.ts +5 -4
- package/dist/core/ingestion/parsing-processor.js +224 -87
- package/dist/core/ingestion/pipeline-phases/cobol.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/cobol.js +45 -0
- package/dist/core/ingestion/pipeline-phases/communities.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/communities.js +62 -0
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +156 -0
- package/dist/core/ingestion/pipeline-phases/cross-file.d.ts +37 -0
- package/dist/core/ingestion/pipeline-phases/cross-file.js +63 -0
- package/dist/core/ingestion/pipeline-phases/index.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/index.js +22 -0
- package/dist/core/ingestion/pipeline-phases/markdown.d.ts +17 -0
- package/dist/core/ingestion/pipeline-phases/markdown.js +33 -0
- package/dist/core/ingestion/pipeline-phases/mro.d.ts +18 -0
- package/dist/core/ingestion/pipeline-phases/mro.js +36 -0
- package/dist/core/ingestion/pipeline-phases/orm-extraction.d.ts +22 -0
- package/dist/core/ingestion/pipeline-phases/orm-extraction.js +92 -0
- package/dist/core/ingestion/pipeline-phases/orm.d.ts +15 -0
- package/dist/core/ingestion/pipeline-phases/orm.js +74 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +47 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +437 -0
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +49 -0
- package/dist/core/ingestion/pipeline-phases/parse.js +33 -0
- package/dist/core/ingestion/pipeline-phases/processes.d.ts +16 -0
- package/dist/core/ingestion/pipeline-phases/processes.js +143 -0
- package/dist/core/ingestion/pipeline-phases/routes.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/routes.js +243 -0
- package/dist/core/ingestion/pipeline-phases/runner.d.ts +22 -0
- package/dist/core/ingestion/pipeline-phases/runner.js +203 -0
- package/dist/core/ingestion/pipeline-phases/scan.d.ts +21 -0
- package/dist/core/ingestion/pipeline-phases/scan.js +46 -0
- package/dist/core/ingestion/pipeline-phases/structure.d.ts +27 -0
- package/dist/core/ingestion/pipeline-phases/structure.js +35 -0
- package/dist/core/ingestion/pipeline-phases/tools.d.ts +20 -0
- package/dist/core/ingestion/pipeline-phases/tools.js +79 -0
- package/dist/core/ingestion/pipeline-phases/types.d.ts +79 -0
- package/dist/core/ingestion/pipeline-phases/types.js +37 -0
- package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.d.ts +35 -0
- package/dist/core/ingestion/pipeline-phases/wildcard-synthesis.js +174 -0
- package/dist/core/ingestion/pipeline.d.ts +18 -10
- package/dist/core/ingestion/pipeline.js +66 -1410
- package/dist/core/ingestion/process-processor.js +1 -1
- package/dist/core/ingestion/tree-sitter-queries.d.ts +5 -5
- package/dist/core/ingestion/tree-sitter-queries.js +90 -0
- package/dist/core/ingestion/type-env.d.ts +15 -2
- package/dist/core/ingestion/type-env.js +163 -102
- package/dist/core/ingestion/type-extractors/csharp.js +17 -0
- package/dist/core/ingestion/type-extractors/jvm.js +11 -0
- package/dist/core/ingestion/type-extractors/php.js +0 -55
- package/dist/core/ingestion/type-extractors/ruby.js +0 -32
- package/dist/core/ingestion/type-extractors/swift.js +13 -0
- package/dist/core/ingestion/type-extractors/types.d.ts +8 -8
- package/dist/core/ingestion/type-extractors/typescript.js +66 -69
- package/dist/core/ingestion/utils/ast-helpers.d.ts +32 -44
- package/dist/core/ingestion/utils/ast-helpers.js +157 -573
- package/dist/core/ingestion/utils/env.d.ts +10 -0
- package/dist/core/ingestion/utils/env.js +10 -0
- package/dist/core/ingestion/utils/graph-sort.d.ts +58 -0
- package/dist/core/ingestion/utils/graph-sort.js +100 -0
- package/dist/core/ingestion/utils/method-props.d.ts +32 -0
- package/dist/core/ingestion/utils/method-props.js +147 -0
- package/dist/core/ingestion/vue-sfc-extractor.d.ts +44 -0
- package/dist/core/ingestion/vue-sfc-extractor.js +94 -0
- package/dist/core/ingestion/workers/parse-worker.d.ts +31 -19
- package/dist/core/ingestion/workers/parse-worker.js +469 -200
- package/dist/core/lbug/lbug-adapter.d.ts +6 -0
- package/dist/core/lbug/lbug-adapter.js +134 -27
- package/dist/core/lbug/pool-adapter.d.ts +76 -0
- package/dist/core/lbug/pool-adapter.js +522 -0
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +1 -1
- package/dist/core/search/bm25-index.js +1 -1
- package/dist/core/tree-sitter/parser-loader.js +1 -0
- package/dist/core/wiki/graph-queries.js +1 -1
- package/dist/mcp/core/embedder.js +6 -5
- package/dist/mcp/core/lbug-adapter.d.ts +3 -63
- package/dist/mcp/core/lbug-adapter.js +3 -484
- package/dist/mcp/local/local-backend.d.ts +31 -2
- package/dist/mcp/local/local-backend.js +255 -46
- package/dist/mcp/resources.js +5 -4
- package/dist/mcp/staleness.d.ts +3 -13
- package/dist/mcp/staleness.js +2 -31
- package/dist/mcp/tools.js +80 -4
- package/dist/server/analyze-job.d.ts +2 -0
- package/dist/server/analyze-job.js +4 -0
- package/dist/server/api.d.ts +20 -1
- package/dist/server/api.js +306 -71
- package/dist/server/git-clone.d.ts +2 -1
- package/dist/server/git-clone.js +98 -5
- package/dist/storage/git.d.ts +13 -0
- package/dist/storage/git.js +25 -0
- package/dist/storage/repo-manager.js +1 -1
- package/package.json +9 -3
- package/scripts/patch-tree-sitter-swift.cjs +78 -0
- package/vendor/tree-sitter-proto/binding.gyp +30 -0
- package/vendor/tree-sitter-proto/bindings/node/binding.cc +20 -0
- package/vendor/tree-sitter-proto/bindings/node/index.d.ts +28 -0
- package/vendor/tree-sitter-proto/bindings/node/index.js +7 -0
- package/vendor/tree-sitter-proto/package.json +18 -0
- package/vendor/tree-sitter-proto/src/node-types.json +1145 -0
- package/vendor/tree-sitter-proto/src/parser.c +10149 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/alloc.h +54 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/array.h +291 -0
- package/vendor/tree-sitter-proto/src/tree_sitter/parser.h +266 -0
- package/dist/core/ingestion/named-binding-processor.d.ts +0 -18
- package/dist/core/ingestion/named-binding-processor.js +0 -42
- package/dist/core/ingestion/resolution-context.d.ts +0 -58
- package/dist/core/ingestion/resolution-context.js +0 -135
- package/dist/core/ingestion/symbol-table.d.ts +0 -79
- package/dist/core/ingestion/symbol-table.js +0 -115
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import JavaScript from 'tree-sitter-javascript';
|
|
2
|
+
import TypeScript from 'tree-sitter-typescript';
|
|
3
|
+
import { compilePatterns, } from '../tree-sitter-scanner.js';
|
|
4
|
+
/**
|
|
5
|
+
* Node.js / TypeScript topic extraction patterns.
|
|
6
|
+
*
|
|
7
|
+
* Detects kafkajs, amqplib (RabbitMQ), and nats.js producer/consumer APIs:
|
|
8
|
+
* - `producer.send({ topic: 'xxx', ... })` (kafkajs)
|
|
9
|
+
* - `consumer.subscribe({ topic: 'xxx', ... })` (kafkajs)
|
|
10
|
+
* - `channel.consume("queue", ...)` / `channel.publish(...)` / `channel.sendToQueue(...)`
|
|
11
|
+
* - `nc.subscribe("topic")` / `js.subscribe("topic")`
|
|
12
|
+
* - `nc.publish("topic", ...)` / `js.publish("topic", ...)`
|
|
13
|
+
*
|
|
14
|
+
* The JavaScript and TypeScript tree-sitter grammars share node type
|
|
15
|
+
* names for every construct we query here, so the pattern sources are
|
|
16
|
+
* defined once and compiled against each grammar variant. We export three
|
|
17
|
+
* providers because Parser.Query objects are NOT portable across grammar
|
|
18
|
+
* instances — `.js` files use the JavaScript grammar, `.ts` uses
|
|
19
|
+
* TypeScript.typescript, and `.tsx` uses TypeScript.tsx.
|
|
20
|
+
*
|
|
21
|
+
* Every query MUST bind `@value` to the topic literal node.
|
|
22
|
+
*/
|
|
23
|
+
const NODE_TOPIC_PATTERNS = [
|
|
24
|
+
{
|
|
25
|
+
meta: {
|
|
26
|
+
role: 'provider',
|
|
27
|
+
broker: 'kafka',
|
|
28
|
+
confidence: 0.8,
|
|
29
|
+
symbolName: 'producer.send',
|
|
30
|
+
},
|
|
31
|
+
query: `
|
|
32
|
+
(call_expression
|
|
33
|
+
function: (member_expression
|
|
34
|
+
object: (identifier) @obj (#eq? @obj "producer")
|
|
35
|
+
property: (property_identifier) @prop (#eq? @prop "send"))
|
|
36
|
+
arguments: (arguments
|
|
37
|
+
(object
|
|
38
|
+
(pair
|
|
39
|
+
key: (property_identifier) @key (#eq? @key "topic")
|
|
40
|
+
value: [(string) (template_string)] @value))))
|
|
41
|
+
`,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
meta: {
|
|
45
|
+
role: 'consumer',
|
|
46
|
+
broker: 'kafka',
|
|
47
|
+
confidence: 0.8,
|
|
48
|
+
symbolName: 'consumer.subscribe',
|
|
49
|
+
},
|
|
50
|
+
query: `
|
|
51
|
+
(call_expression
|
|
52
|
+
function: (member_expression
|
|
53
|
+
object: (identifier) @obj (#eq? @obj "consumer")
|
|
54
|
+
property: (property_identifier) @prop (#eq? @prop "subscribe"))
|
|
55
|
+
arguments: (arguments
|
|
56
|
+
(object
|
|
57
|
+
(pair
|
|
58
|
+
key: (property_identifier) @key (#eq? @key "topic")
|
|
59
|
+
value: [(string) (template_string)] @value))))
|
|
60
|
+
`,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
meta: {
|
|
64
|
+
role: 'consumer',
|
|
65
|
+
broker: 'rabbitmq',
|
|
66
|
+
confidence: 0.8,
|
|
67
|
+
symbolName: 'channel.consume',
|
|
68
|
+
},
|
|
69
|
+
query: `
|
|
70
|
+
(call_expression
|
|
71
|
+
function: (member_expression
|
|
72
|
+
object: (identifier) @obj (#eq? @obj "channel")
|
|
73
|
+
property: (property_identifier) @prop (#eq? @prop "consume"))
|
|
74
|
+
arguments: (arguments . [(string) (template_string)] @value))
|
|
75
|
+
`,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
meta: {
|
|
79
|
+
role: 'provider',
|
|
80
|
+
broker: 'rabbitmq',
|
|
81
|
+
confidence: 0.8,
|
|
82
|
+
symbolName: 'channel.publish',
|
|
83
|
+
},
|
|
84
|
+
query: `
|
|
85
|
+
(call_expression
|
|
86
|
+
function: (member_expression
|
|
87
|
+
object: (identifier) @obj (#eq? @obj "channel")
|
|
88
|
+
property: (property_identifier) @prop (#eq? @prop "publish"))
|
|
89
|
+
arguments: (arguments . [(string) (template_string)] @value))
|
|
90
|
+
`,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
meta: {
|
|
94
|
+
role: 'provider',
|
|
95
|
+
broker: 'rabbitmq',
|
|
96
|
+
confidence: 0.8,
|
|
97
|
+
symbolName: 'channel.sendToQueue',
|
|
98
|
+
},
|
|
99
|
+
query: `
|
|
100
|
+
(call_expression
|
|
101
|
+
function: (member_expression
|
|
102
|
+
object: (identifier) @obj (#eq? @obj "channel")
|
|
103
|
+
property: (property_identifier) @prop (#eq? @prop "sendToQueue"))
|
|
104
|
+
arguments: (arguments . [(string) (template_string)] @value))
|
|
105
|
+
`,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
meta: {
|
|
109
|
+
role: 'consumer',
|
|
110
|
+
broker: 'nats',
|
|
111
|
+
confidence: 0.8,
|
|
112
|
+
symbolName: 'nc.subscribe',
|
|
113
|
+
},
|
|
114
|
+
query: `
|
|
115
|
+
(call_expression
|
|
116
|
+
function: (member_expression
|
|
117
|
+
object: (identifier) @obj (#match? @obj "^(nc|js)$")
|
|
118
|
+
property: (property_identifier) @prop (#match? @prop "^[Ss]ubscribe$"))
|
|
119
|
+
arguments: (arguments . [(string) (template_string)] @value))
|
|
120
|
+
`,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
meta: {
|
|
124
|
+
role: 'provider',
|
|
125
|
+
broker: 'nats',
|
|
126
|
+
confidence: 0.8,
|
|
127
|
+
symbolName: 'nc.publish',
|
|
128
|
+
},
|
|
129
|
+
query: `
|
|
130
|
+
(call_expression
|
|
131
|
+
function: (member_expression
|
|
132
|
+
object: (identifier) @obj (#match? @obj "^(nc|js)$")
|
|
133
|
+
property: (property_identifier) @prop (#match? @prop "^[Pp]ublish$"))
|
|
134
|
+
arguments: (arguments . [(string) (template_string)] @value))
|
|
135
|
+
`,
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
const JAVASCRIPT_TOPIC_SPEC = {
|
|
139
|
+
name: 'javascript-topic',
|
|
140
|
+
language: JavaScript,
|
|
141
|
+
patterns: NODE_TOPIC_PATTERNS,
|
|
142
|
+
};
|
|
143
|
+
const TYPESCRIPT_TOPIC_SPEC = {
|
|
144
|
+
name: 'typescript-topic',
|
|
145
|
+
language: TypeScript.typescript,
|
|
146
|
+
patterns: NODE_TOPIC_PATTERNS,
|
|
147
|
+
};
|
|
148
|
+
const TSX_TOPIC_SPEC = {
|
|
149
|
+
name: 'tsx-topic',
|
|
150
|
+
language: TypeScript.tsx,
|
|
151
|
+
patterns: NODE_TOPIC_PATTERNS,
|
|
152
|
+
};
|
|
153
|
+
export const JAVASCRIPT_TOPIC_PROVIDER = compilePatterns(JAVASCRIPT_TOPIC_SPEC);
|
|
154
|
+
export const TYPESCRIPT_TOPIC_PROVIDER = compilePatterns(TYPESCRIPT_TOPIC_SPEC);
|
|
155
|
+
export const TSX_TOPIC_PROVIDER = compilePatterns(TSX_TOPIC_SPEC);
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import Python from 'tree-sitter-python';
|
|
2
|
+
import { compilePatterns } from '../tree-sitter-scanner.js';
|
|
3
|
+
/**
|
|
4
|
+
* Python topic extraction patterns.
|
|
5
|
+
*
|
|
6
|
+
* Detects kafka-python, pika (RabbitMQ), and nats-py producer/consumer APIs:
|
|
7
|
+
* - `KafkaConsumer('topic', ...)`
|
|
8
|
+
* - `producer.send('topic', ...)` / `producer.produce('topic', ...)`
|
|
9
|
+
* - `channel.basic_consume(queue='xxx', ...)`
|
|
10
|
+
* - `channel.basic_publish(exchange='xxx', ...)`
|
|
11
|
+
* - `await nc.subscribe('topic')`
|
|
12
|
+
* - `await nc.publish('topic', ...)`
|
|
13
|
+
*
|
|
14
|
+
* Every query MUST bind `@value` to the topic literal node.
|
|
15
|
+
*/
|
|
16
|
+
const PYTHON_TOPIC_SPEC = {
|
|
17
|
+
name: 'python-topic',
|
|
18
|
+
language: Python,
|
|
19
|
+
patterns: [
|
|
20
|
+
{
|
|
21
|
+
meta: {
|
|
22
|
+
role: 'consumer',
|
|
23
|
+
broker: 'kafka',
|
|
24
|
+
confidence: 0.7,
|
|
25
|
+
symbolName: 'KafkaConsumer',
|
|
26
|
+
},
|
|
27
|
+
query: `
|
|
28
|
+
(call
|
|
29
|
+
function: (identifier) @func (#eq? @func "KafkaConsumer")
|
|
30
|
+
arguments: (argument_list . (string) @value))
|
|
31
|
+
`,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
meta: {
|
|
35
|
+
role: 'provider',
|
|
36
|
+
broker: 'kafka',
|
|
37
|
+
confidence: 0.7,
|
|
38
|
+
symbolName: 'producer.send',
|
|
39
|
+
},
|
|
40
|
+
query: `
|
|
41
|
+
(call
|
|
42
|
+
function: (attribute
|
|
43
|
+
object: (identifier) @obj (#eq? @obj "producer")
|
|
44
|
+
attribute: (identifier) @method (#match? @method "^(send|produce)$"))
|
|
45
|
+
arguments: (argument_list . (string) @value))
|
|
46
|
+
`,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
meta: {
|
|
50
|
+
role: 'consumer',
|
|
51
|
+
broker: 'rabbitmq',
|
|
52
|
+
confidence: 0.7,
|
|
53
|
+
symbolName: 'basic_consume',
|
|
54
|
+
},
|
|
55
|
+
query: `
|
|
56
|
+
(call
|
|
57
|
+
function: (attribute
|
|
58
|
+
object: (identifier) @obj (#eq? @obj "channel")
|
|
59
|
+
attribute: (identifier) @method (#eq? @method "basic_consume"))
|
|
60
|
+
arguments: (argument_list
|
|
61
|
+
(keyword_argument
|
|
62
|
+
name: (identifier) @kw (#eq? @kw "queue")
|
|
63
|
+
value: (string) @value)))
|
|
64
|
+
`,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
meta: {
|
|
68
|
+
role: 'provider',
|
|
69
|
+
broker: 'rabbitmq',
|
|
70
|
+
confidence: 0.7,
|
|
71
|
+
symbolName: 'basic_publish',
|
|
72
|
+
},
|
|
73
|
+
query: `
|
|
74
|
+
(call
|
|
75
|
+
function: (attribute
|
|
76
|
+
object: (identifier) @obj (#eq? @obj "channel")
|
|
77
|
+
attribute: (identifier) @method (#eq? @method "basic_publish"))
|
|
78
|
+
arguments: (argument_list
|
|
79
|
+
(keyword_argument
|
|
80
|
+
name: (identifier) @kw (#eq? @kw "exchange")
|
|
81
|
+
value: (string) @value)))
|
|
82
|
+
`,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
meta: {
|
|
86
|
+
role: 'consumer',
|
|
87
|
+
broker: 'nats',
|
|
88
|
+
confidence: 0.75,
|
|
89
|
+
symbolName: 'nc.subscribe',
|
|
90
|
+
},
|
|
91
|
+
query: `
|
|
92
|
+
(call
|
|
93
|
+
function: (attribute
|
|
94
|
+
object: (identifier) @obj (#eq? @obj "nc")
|
|
95
|
+
attribute: (identifier) @method (#eq? @method "subscribe"))
|
|
96
|
+
arguments: (argument_list . (string) @value))
|
|
97
|
+
`,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
meta: {
|
|
101
|
+
role: 'provider',
|
|
102
|
+
broker: 'nats',
|
|
103
|
+
confidence: 0.75,
|
|
104
|
+
symbolName: 'nc.publish',
|
|
105
|
+
},
|
|
106
|
+
query: `
|
|
107
|
+
(call
|
|
108
|
+
function: (attribute
|
|
109
|
+
object: (identifier) @obj (#eq? @obj "nc")
|
|
110
|
+
attribute: (identifier) @method (#eq? @method "publish"))
|
|
111
|
+
arguments: (argument_list . (string) @value))
|
|
112
|
+
`,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
export const PYTHON_TOPIC_PROVIDER = compilePatterns(PYTHON_TOPIC_SPEC);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the topic-extractor language plugins.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin lives in its own file (java.ts, go.ts, ...) and owns the
|
|
5
|
+
* tree-sitter grammar import + query sources. The top-level
|
|
6
|
+
* `topic-extractor.ts` orchestrator only knows about this type module and
|
|
7
|
+
* the plugin registry (`./index.ts`). It MUST NOT import any grammar or
|
|
8
|
+
* query text directly — that's the whole point of the split.
|
|
9
|
+
*/
|
|
10
|
+
export type Broker = 'kafka' | 'rabbitmq' | 'nats';
|
|
11
|
+
/**
|
|
12
|
+
* Per-pattern payload every topic plugin attaches to its query. Whatever
|
|
13
|
+
* the pattern matches, the orchestrator receives this object verbatim
|
|
14
|
+
* and uses it to build an `ExtractedContract`.
|
|
15
|
+
*
|
|
16
|
+
* Plugins produce one `TopicMeta` per pattern (not per match) because a
|
|
17
|
+
* single query uniquely identifies its broker/role/confidence triple.
|
|
18
|
+
*/
|
|
19
|
+
export interface TopicMeta {
|
|
20
|
+
role: 'provider' | 'consumer';
|
|
21
|
+
broker: Broker;
|
|
22
|
+
confidence: number;
|
|
23
|
+
/** Short human-readable label of the API being detected. */
|
|
24
|
+
symbolName: string;
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the topic-extractor language plugins.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin lives in its own file (java.ts, go.ts, ...) and owns the
|
|
5
|
+
* tree-sitter grammar import + query sources. The top-level
|
|
6
|
+
* `topic-extractor.ts` orchestrator only knows about this type module and
|
|
7
|
+
* the plugin registry (`./index.ts`). It MUST NOT import any grammar or
|
|
8
|
+
* query text directly — that's the whole point of the split.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
/**
|
|
3
|
+
* Shared, language-agnostic tree-sitter scanning utilities used by group
|
|
4
|
+
* extractors (topic, http, grpc, ...).
|
|
5
|
+
*
|
|
6
|
+
* Design goals:
|
|
7
|
+
* - The top-level extractors must not import any tree-sitter grammar.
|
|
8
|
+
* - Per-language plugins own their grammar import, their query sources,
|
|
9
|
+
* and the mapping from capture → meta.
|
|
10
|
+
* - This module provides the plumbing: compile queries once per plugin,
|
|
11
|
+
* parse a file with a given grammar, run all patterns, and return the
|
|
12
|
+
* captured `string_literal`-style nodes together with the plugin's meta.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* One pattern owned by a language plugin. Each pattern owns a tree-sitter
|
|
16
|
+
* S-expression query. Plugins can freely choose which capture names to
|
|
17
|
+
* use — the scanner exposes every capture in the returned `captures`
|
|
18
|
+
* map and does not privilege any particular name.
|
|
19
|
+
*
|
|
20
|
+
* `TMeta` is the plugin-specific payload the orchestrator receives back
|
|
21
|
+
* when this pattern matches — e.g. for topic extraction it carries the
|
|
22
|
+
* broker name, role, confidence, symbol name.
|
|
23
|
+
*/
|
|
24
|
+
export interface PatternSpec<TMeta> {
|
|
25
|
+
/** Tree-sitter S-expression. */
|
|
26
|
+
query: string;
|
|
27
|
+
/** Plugin-specific payload returned on every match. */
|
|
28
|
+
meta: TMeta;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A set of patterns owned by one language plugin, bound to a specific
|
|
32
|
+
* tree-sitter grammar.
|
|
33
|
+
*
|
|
34
|
+
* `language` is typed as `unknown` because tree-sitter's TypeScript
|
|
35
|
+
* declarations use `any` for the grammar object, and the grammar modules
|
|
36
|
+
* export different shapes (plain grammar vs. namespace with `typescript`
|
|
37
|
+
* / `tsx` members). Callers pass the concrete grammar object; this
|
|
38
|
+
* module forwards it to `parser.setLanguage` / `new Parser.Query`.
|
|
39
|
+
*/
|
|
40
|
+
export interface LanguagePatterns<TMeta> {
|
|
41
|
+
/** Human-readable plugin name for diagnostics. */
|
|
42
|
+
name: string;
|
|
43
|
+
/** tree-sitter grammar object. */
|
|
44
|
+
language: unknown;
|
|
45
|
+
/** Patterns authored against `language`. */
|
|
46
|
+
patterns: PatternSpec<TMeta>[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Compiled form of a `LanguagePatterns` bundle. Queries are compiled
|
|
50
|
+
* eagerly at module load time so a broken grammar/query pair fails
|
|
51
|
+
* loudly the first time the plugin is imported, instead of silently
|
|
52
|
+
* at scan time when no contract is produced.
|
|
53
|
+
*/
|
|
54
|
+
export interface CompiledPatterns<TMeta> {
|
|
55
|
+
name: string;
|
|
56
|
+
language: unknown;
|
|
57
|
+
patterns: CompiledPattern<TMeta>[];
|
|
58
|
+
}
|
|
59
|
+
export interface CompiledPattern<TMeta> {
|
|
60
|
+
query: Parser.Query;
|
|
61
|
+
meta: TMeta;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Map from capture name → syntax node. Every named capture the query
|
|
65
|
+
* binds is exposed as an entry. If a query captures the same name more
|
|
66
|
+
* than once (unusual), the first occurrence wins — plugins that need
|
|
67
|
+
* all occurrences should use distinct capture names or fall back to
|
|
68
|
+
* `match.captures` array directly by iterating `query.matches()`
|
|
69
|
+
* themselves.
|
|
70
|
+
*/
|
|
71
|
+
export type CaptureMap = Record<string, Parser.SyntaxNode>;
|
|
72
|
+
/**
|
|
73
|
+
* One match returned by `scanFile` / `runCompiledPatterns`. The caller
|
|
74
|
+
* receives the full capture map plus the plugin meta, and is
|
|
75
|
+
* responsible for turning it into a domain object.
|
|
76
|
+
*/
|
|
77
|
+
export interface ScanMatch<TMeta> {
|
|
78
|
+
meta: TMeta;
|
|
79
|
+
captures: CaptureMap;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Compile a LanguagePatterns bundle. Call this once per plugin, at
|
|
83
|
+
* module load time, and export the result. Throws if any pattern
|
|
84
|
+
* fails to compile against the grammar — that's a bug in the plugin
|
|
85
|
+
* author's query, not a runtime condition.
|
|
86
|
+
*/
|
|
87
|
+
export declare function compilePatterns<TMeta>(bundle: LanguagePatterns<TMeta>): CompiledPatterns<TMeta>;
|
|
88
|
+
/**
|
|
89
|
+
* Run every compiled pattern in `plugin` against an already-parsed
|
|
90
|
+
* tree. Use this when a plugin needs multiple query bundles against
|
|
91
|
+
* the same file (e.g. one query for class-level prefixes and another
|
|
92
|
+
* for method-level annotations) and wants to avoid re-parsing.
|
|
93
|
+
*/
|
|
94
|
+
export declare function runCompiledPatterns<TMeta>(plugin: CompiledPatterns<TMeta>, tree: Parser.Tree): ScanMatch<TMeta>[];
|
|
95
|
+
/**
|
|
96
|
+
* Parse `content` with the plugin's grammar and run every compiled
|
|
97
|
+
* pattern against the AST. Returns one `ScanMatch` per matched query
|
|
98
|
+
* occurrence, carrying the plugin's meta payload.
|
|
99
|
+
*
|
|
100
|
+
* Errors are swallowed at the file level (malformed file must not abort
|
|
101
|
+
* the whole extract). Individual pattern failures are swallowed too so
|
|
102
|
+
* a single unusable query doesn't block the rest of the plugin.
|
|
103
|
+
*/
|
|
104
|
+
export declare function scanFile<TMeta>(parser: Parser, plugin: CompiledPatterns<TMeta>, content: string): ScanMatch<TMeta>[];
|
|
105
|
+
/**
|
|
106
|
+
* Strip enclosing quotes from a tree-sitter string literal node's text.
|
|
107
|
+
* Handles single / double / template quotes, Python triple-quoted strings,
|
|
108
|
+
* and Go raw string literals (backticks).
|
|
109
|
+
*
|
|
110
|
+
* Returns null for empty/nullish input so callers can uniformly skip
|
|
111
|
+
* captures whose value is missing.
|
|
112
|
+
*/
|
|
113
|
+
export declare function unquoteLiteral(raw: string): string | null;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Parser from 'tree-sitter';
|
|
2
|
+
/**
|
|
3
|
+
* Compile a LanguagePatterns bundle. Call this once per plugin, at
|
|
4
|
+
* module load time, and export the result. Throws if any pattern
|
|
5
|
+
* fails to compile against the grammar — that's a bug in the plugin
|
|
6
|
+
* author's query, not a runtime condition.
|
|
7
|
+
*/
|
|
8
|
+
export function compilePatterns(bundle) {
|
|
9
|
+
const compiled = [];
|
|
10
|
+
for (const spec of bundle.patterns) {
|
|
11
|
+
try {
|
|
12
|
+
const query = new Parser.Query(bundle.language, spec.query);
|
|
13
|
+
compiled.push({ query, meta: spec.meta });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
17
|
+
throw new Error(`[tree-sitter-scanner] Failed to compile pattern in ${bundle.name}: ${message}\n` +
|
|
18
|
+
`Query source:\n${spec.query}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return { name: bundle.name, language: bundle.language, patterns: compiled };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run every compiled pattern in `plugin` against an already-parsed
|
|
25
|
+
* tree. Use this when a plugin needs multiple query bundles against
|
|
26
|
+
* the same file (e.g. one query for class-level prefixes and another
|
|
27
|
+
* for method-level annotations) and wants to avoid re-parsing.
|
|
28
|
+
*/
|
|
29
|
+
export function runCompiledPatterns(plugin, tree) {
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const compiled of plugin.patterns) {
|
|
32
|
+
let matches;
|
|
33
|
+
try {
|
|
34
|
+
matches = compiled.query.matches(tree.rootNode);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
for (const match of matches) {
|
|
40
|
+
const captures = {};
|
|
41
|
+
for (const cap of match.captures) {
|
|
42
|
+
if (!(cap.name in captures))
|
|
43
|
+
captures[cap.name] = cap.node;
|
|
44
|
+
}
|
|
45
|
+
out.push({ meta: compiled.meta, captures });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Parse `content` with the plugin's grammar and run every compiled
|
|
52
|
+
* pattern against the AST. Returns one `ScanMatch` per matched query
|
|
53
|
+
* occurrence, carrying the plugin's meta payload.
|
|
54
|
+
*
|
|
55
|
+
* Errors are swallowed at the file level (malformed file must not abort
|
|
56
|
+
* the whole extract). Individual pattern failures are swallowed too so
|
|
57
|
+
* a single unusable query doesn't block the rest of the plugin.
|
|
58
|
+
*/
|
|
59
|
+
export function scanFile(parser, plugin, content) {
|
|
60
|
+
let tree;
|
|
61
|
+
try {
|
|
62
|
+
parser.setLanguage(plugin.language);
|
|
63
|
+
tree = parser.parse(content);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
return runCompiledPatterns(plugin, tree);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Strip enclosing quotes from a tree-sitter string literal node's text.
|
|
72
|
+
* Handles single / double / template quotes, Python triple-quoted strings,
|
|
73
|
+
* and Go raw string literals (backticks).
|
|
74
|
+
*
|
|
75
|
+
* Returns null for empty/nullish input so callers can uniformly skip
|
|
76
|
+
* captures whose value is missing.
|
|
77
|
+
*/
|
|
78
|
+
export function unquoteLiteral(raw) {
|
|
79
|
+
if (!raw)
|
|
80
|
+
return null;
|
|
81
|
+
// Python triple-quoted
|
|
82
|
+
if ((raw.startsWith('"""') && raw.endsWith('"""')) ||
|
|
83
|
+
(raw.startsWith("'''") && raw.endsWith("'''"))) {
|
|
84
|
+
return raw.slice(3, -3);
|
|
85
|
+
}
|
|
86
|
+
const first = raw[0];
|
|
87
|
+
const last = raw[raw.length - 1];
|
|
88
|
+
if ((first === '"' || first === "'" || first === '`') && last === first && raw.length >= 2) {
|
|
89
|
+
return raw.slice(1, -1);
|
|
90
|
+
}
|
|
91
|
+
// Some grammars expose the string content without quotes already (e.g.
|
|
92
|
+
// Python `string_content` child). Return as-is.
|
|
93
|
+
return raw;
|
|
94
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StoredContract, CrossLink } from './types.js';
|
|
2
|
+
export interface MatchResult {
|
|
3
|
+
matched: CrossLink[];
|
|
4
|
+
unmatched: StoredContract[];
|
|
5
|
+
}
|
|
6
|
+
export interface WildcardMatchResult {
|
|
7
|
+
matched: CrossLink[];
|
|
8
|
+
remaining: StoredContract[];
|
|
9
|
+
}
|
|
10
|
+
export declare function normalizeContractId(id: string): string;
|
|
11
|
+
export declare function buildProviderIndex(contracts: StoredContract[]): Map<string, StoredContract[]>;
|
|
12
|
+
export declare function runExactMatch(contracts: StoredContract[], providerIndex?: Map<string, StoredContract[]>): MatchResult;
|
|
13
|
+
export declare function runWildcardMatch(unmatched: StoredContract[], providerIndex: Map<string, StoredContract[]>): WildcardMatchResult;
|