@c4a/extract-ts 0.7.0 → 0.7.4
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 +16 -36
- package/README.zh-CN.md +11 -28
- package/index.js +316 -40
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
`@c4a/extract-ts` turns TypeScript, JavaScript, TSX, and JSX structure into deterministic code
|
|
6
6
|
evidence for Context knowledge production. It implements the
|
|
7
|
-
`ExtractionPlugin` protocol from `@c4a/extract` and is the
|
|
8
|
-
|
|
9
|
-
packages.
|
|
7
|
+
`ExtractionPlugin` protocol from `@c4a/extract` and is the community Code
|
|
8
|
+
Indexer Provider's ECMAScript parser for npm-style packages.
|
|
10
9
|
|
|
11
10
|
It extracts code facts; it does not decide product meaning, write approved
|
|
12
11
|
Markdown, or choose the user's source boundary. Knowledge-workspace users reach
|
|
13
|
-
it through the
|
|
14
|
-
|
|
12
|
+
it through the selected Code Indexer Provider. The direct APIs below are for
|
|
13
|
+
Provider authors and reusable structural analysis.
|
|
15
14
|
|
|
16
15
|
## Package Role
|
|
17
16
|
|
|
@@ -24,12 +23,12 @@ confirmed TypeScript/JavaScript boundary
|
|
|
24
23
|
↓
|
|
25
24
|
entry detection + export tracing + AST facts
|
|
26
25
|
↓
|
|
27
|
-
|
|
26
|
+
Indexer facts → reader-oriented Candidates → approved knowledge
|
|
28
27
|
```
|
|
29
28
|
|
|
30
29
|
## React Router structural facts
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
Indexer Providers can reuse `extractReactRouterRoutes()` to
|
|
33
32
|
index JSX `<Route>` declarations and route-object arrays. It reports paths,
|
|
34
33
|
components, redirects, conditions, import sources, notes, and source locations
|
|
35
34
|
without classifying product meaning:
|
|
@@ -83,10 +82,9 @@ const moduleFacts = extractEcmaScriptModuleExports(source, "src/index.cjs");
|
|
|
83
82
|
- package version propagation into `ExtractionResult.package.version`
|
|
84
83
|
- authored `.js`, `.jsx`, `.mjs`, and `.cjs` entry files without remapping them to TypeScript
|
|
85
84
|
|
|
86
|
-
The
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
not need to modify the analyzed package solely to declare extraction entries.
|
|
85
|
+
The Code Indexer Provider may override auto-detection with source-relative
|
|
86
|
+
entries, or use scan mode to make every include-matched file an extraction
|
|
87
|
+
root. Consumers do not modify the analyzed package solely to configure parsing.
|
|
90
88
|
|
|
91
89
|
Entry files are returned as module-relative paths. The repository runner later prefixes them to repo-relative paths in raw snapshots.
|
|
92
90
|
|
|
@@ -160,9 +158,8 @@ identities, per-file owner/disposition, explicit denominators, diagnostics, and
|
|
|
160
158
|
the ordered parser receipt through `context.indexer.evidence-adapter-result/v1`.
|
|
161
159
|
`ExtractionResult` remains available for the existing raw snapshot runner.
|
|
162
160
|
|
|
163
|
-
The
|
|
164
|
-
|
|
165
|
-
important projection inputs are:
|
|
161
|
+
The Code Indexer Provider consumes those facts while producing the current
|
|
162
|
+
Indexer result. Important authoring inputs include:
|
|
166
163
|
|
|
167
164
|
- stable package names and versions
|
|
168
165
|
- stable exported symbol names
|
|
@@ -187,33 +184,16 @@ const registry = new ExtractionPluginRegistry();
|
|
|
187
184
|
registry.register(new TypeScriptPlugin());
|
|
188
185
|
```
|
|
189
186
|
|
|
190
|
-
Workspace usage
|
|
191
|
-
|
|
192
|
-
```ts
|
|
193
|
-
import { defineProject, extractTs, reviewValidity, source } from "@c4a/context";
|
|
194
|
-
|
|
195
|
-
const componentLib = source("component-lib");
|
|
196
|
-
|
|
197
|
-
export default defineProject({
|
|
198
|
-
sources: [componentLib],
|
|
199
|
-
phases: [
|
|
200
|
-
extractTs({ source: componentLib, collection: "codegraph" }),
|
|
201
|
-
reviewValidity({ collection: "codegraph" }),
|
|
202
|
-
],
|
|
203
|
-
packages: [],
|
|
204
|
-
});
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
The source boundary is registered first, then the phase is previewed or run:
|
|
187
|
+
Workspace usage registers the source boundary, then selects the Code Indexer
|
|
188
|
+
Provider through `src/indexers.yaml`:
|
|
208
189
|
|
|
209
190
|
```bash
|
|
210
191
|
context source add repo component-lib --local ../packages/component-lib
|
|
211
|
-
context
|
|
212
|
-
context run extract:component-lib:codegraph
|
|
192
|
+
context status --format json
|
|
213
193
|
```
|
|
214
194
|
|
|
215
|
-
Agents should not hand-build
|
|
216
|
-
workspace operation.
|
|
195
|
+
Agents should not hand-build parser input, raw snapshots, or Candidate files
|
|
196
|
+
for normal Context workspace operation.
|
|
217
197
|
|
|
218
198
|
## Development
|
|
219
199
|
|
package/README.zh-CN.md
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
[English](./README.md)
|
|
4
4
|
|
|
5
5
|
`@c4a/extract-ts` 将 TypeScript、JavaScript、TSX 和 JSX 结构转化为 Context 知识生产可使用的确定性
|
|
6
|
-
代码证据。它实现 `@c4a/extract` 的 `ExtractionPlugin`
|
|
7
|
-
|
|
6
|
+
代码证据。它实现 `@c4a/extract` 的 `ExtractionPlugin` 协议,也是社区 Code
|
|
7
|
+
Indexer Provider 面向 npm-style package 使用的 ECMAScript 解析器。
|
|
8
8
|
|
|
9
9
|
它只提取代码事实,不判断产品含义、不写正式 Markdown,也不替用户选择来源边界。
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
知识工作区用户通过选中的 Code Indexer Provider 使用它;直接 API 面向 Provider
|
|
11
|
+
作者和可复用结构分析。
|
|
12
12
|
|
|
13
13
|
## 在知识生产链中的职责
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ package 使用 `extractTs({ source, collection: "codegraph" })` 阶段时的默
|
|
|
17
17
|
↓
|
|
18
18
|
入口检测 + 导出追踪 + AST 事实
|
|
19
19
|
↓
|
|
20
|
-
|
|
20
|
+
Indexer 事实 → 面向读者的 Candidate → 正式知识
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
`@c4a/extract-ts` 负责 npm package 入口检测和 ECMAScript-family AST 提取。它不直接写工作区;
|
|
@@ -29,7 +29,7 @@ package 使用 `extractTs({ source, collection: "codegraph" })` 阶段时的默
|
|
|
29
29
|
|
|
30
30
|
### React Router 结构事实
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Indexer Provider 可以复用 `extractReactRouterRoutes()`,索引 JSX
|
|
33
33
|
`<Route>` 声明和 route-object 数组:
|
|
34
34
|
|
|
35
35
|
```ts
|
|
@@ -83,9 +83,8 @@ const moduleFacts = extractEcmaScriptModuleExports(source, "src/index.cjs");
|
|
|
83
83
|
- 将 package version 写入 `ExtractionResult.package.version`。
|
|
84
84
|
- 直接识别源码目录中的 `.js`、`.jsx`、`.mjs` 和 `.cjs`,不会误映射为 TypeScript。
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
无需修改被分析 package。
|
|
86
|
+
Code Indexer Provider 可以使用 source-relative entries 覆盖自动检测,或用 scan
|
|
87
|
+
模式把所有命中 include 的文件作为解析根;无需修改被分析 package。
|
|
89
88
|
|
|
90
89
|
入口文件以 module-relative 路径返回,Repository Runner 再为原始快照补充
|
|
91
90
|
repo-relative 前缀。
|
|
@@ -162,25 +161,9 @@ const registry = new ExtractionPluginRegistry();
|
|
|
162
161
|
registry.register(new TypeScriptPlugin());
|
|
163
162
|
```
|
|
164
163
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
import { defineProject, extractTs, reviewValidity, source } from "@c4a/context";
|
|
169
|
-
|
|
170
|
-
const componentLib = source("component-lib");
|
|
171
|
-
|
|
172
|
-
export default defineProject({
|
|
173
|
-
sources: [componentLib],
|
|
174
|
-
phases: [
|
|
175
|
-
extractTs({ source: componentLib, collection: "codegraph" }),
|
|
176
|
-
reviewValidity({ collection: "codegraph" }),
|
|
177
|
-
],
|
|
178
|
-
packages: [],
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
实际提取由当前 Context Route 驱动。Agent 不应在正常知识生产中手工构造 Runner
|
|
183
|
-
输入或原始快照。
|
|
164
|
+
正常工作区先登记来源,再由 `src/indexers.yaml` 选择 Code Indexer Provider。
|
|
165
|
+
实际解析由当前 Context Route 驱动。Agent 不应在正常知识生产中手工构造 Runner
|
|
166
|
+
输入、原始快照或 Candidate 文件。
|
|
184
167
|
|
|
185
168
|
## 开发
|
|
186
169
|
|
package/index.js
CHANGED
|
@@ -11404,6 +11404,8 @@ function keyTokens(key) {
|
|
|
11404
11404
|
return key.replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replace(/[^A-Za-z0-9]+/gu, "-").toLowerCase().split("-").filter(Boolean);
|
|
11405
11405
|
}
|
|
11406
11406
|
function sensitiveKey(key, value) {
|
|
11407
|
+
if (value === INDEXER_OUTPUT_REDACTION_MARKER)
|
|
11408
|
+
return false;
|
|
11407
11409
|
const tokens = keyTokens(key);
|
|
11408
11410
|
if (tokens.length === 0)
|
|
11409
11411
|
return false;
|
|
@@ -11445,12 +11447,12 @@ function replaceWithCount(value, pattern, replacement, count) {
|
|
|
11445
11447
|
function redactKnownText(value, count) {
|
|
11446
11448
|
let output = value;
|
|
11447
11449
|
output = replaceWithCount(output, /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/gu, INDEXER_OUTPUT_REDACTION_MARKER, count);
|
|
11448
|
-
output = replaceWithCount(output,
|
|
11450
|
+
output = replaceWithCount(output, new RegExp(`(\\bauthorization\\s*:\\s*(?:bearer|basic)\\s+)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^\\s,;]+`, "giu"), (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
|
|
11449
11451
|
output = replaceWithCount(output, /([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}@`, count);
|
|
11450
|
-
output = replaceWithCount(output,
|
|
11452
|
+
output = replaceWithCount(output, new RegExp(`([?&](?:access_token|refresh_token|api_key|password|secret)=)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^&#\\s]+`, "giu"), (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
|
|
11451
11453
|
const key = "(?:[A-Za-z0-9_.-]*(?:password|passwd|pwd|secret|token|credential|cookie)[A-Za-z0-9_.-]*|api[-_]?key|access[-_]?(?:key|token)|private[-_]?key|client[-_]?secret|authorization)";
|
|
11452
11454
|
const assignment = `(?:=\\s*|:\\s+(?=\\S)|:\\s*(?=["']))`;
|
|
11453
|
-
output = replaceWithCount(output, new RegExp(`((?:["']?${key}["']?)\\s*${assignment})(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu"), (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
|
|
11455
|
+
output = replaceWithCount(output, new RegExp(`((?:["']?${key}["']?)\\s*${assignment})` + `(?!["']?${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})` + `(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu"), (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
|
|
11454
11456
|
return output;
|
|
11455
11457
|
}
|
|
11456
11458
|
function redactBlockedText(value, blocked, count) {
|
|
@@ -12312,6 +12314,7 @@ var buildToSourcePaths = (withoutExtension) => {
|
|
|
12312
12314
|
}
|
|
12313
12315
|
const fullRest = rest.join("/");
|
|
12314
12316
|
results.push(`src/${fullRest}`);
|
|
12317
|
+
results.push(fullRest);
|
|
12315
12318
|
return unique(results);
|
|
12316
12319
|
};
|
|
12317
12320
|
var createCandidatePaths = (value, options = {}) => {
|
|
@@ -12463,7 +12466,7 @@ var expandWorkspacePattern = async (rootDir, pattern, fs) => {
|
|
|
12463
12466
|
if (pattern.endsWith("/*")) {
|
|
12464
12467
|
const prefix = pattern.slice(0, -2);
|
|
12465
12468
|
const baseDir = prefix ? `${rootDir}/${prefix}` : rootDir;
|
|
12466
|
-
const entries = await fs.readdir(baseDir);
|
|
12469
|
+
const entries = (await fs.readdir(baseDir)).sort();
|
|
12467
12470
|
return entries.map((entry) => `${baseDir}/${entry}`.replace(/^\.\//, ""));
|
|
12468
12471
|
}
|
|
12469
12472
|
return [`${rootDir}/${pattern}`.replace(/^\.\//, "")];
|
|
@@ -12814,6 +12817,10 @@ var codeExtractRunnerInputSchema = exports_external.object({
|
|
|
12814
12817
|
});
|
|
12815
12818
|
// ../extract/src/evidenceAdapter.ts
|
|
12816
12819
|
function fact2(input) {
|
|
12820
|
+
const payload = redactIndexerOutput({
|
|
12821
|
+
channel: "success-payload",
|
|
12822
|
+
value: input.payload
|
|
12823
|
+
}).value;
|
|
12817
12824
|
return createIndexerEvidenceAdapterFact({
|
|
12818
12825
|
source_ref: input.sourceRef,
|
|
12819
12826
|
module_ref: input.moduleRef,
|
|
@@ -12821,10 +12828,21 @@ function fact2(input) {
|
|
|
12821
12828
|
qualified_item_path: input.qualifiedItemPath,
|
|
12822
12829
|
kind: input.kind,
|
|
12823
12830
|
signature: input.signature,
|
|
12824
|
-
payload
|
|
12831
|
+
payload,
|
|
12825
12832
|
denominator: input.denominator
|
|
12826
12833
|
});
|
|
12827
12834
|
}
|
|
12835
|
+
function uniqueFacts(facts) {
|
|
12836
|
+
const byRef = new Map;
|
|
12837
|
+
for (const value of facts) {
|
|
12838
|
+
const previous = byRef.get(value.fact_ref);
|
|
12839
|
+
if (previous !== undefined && indexerEvidenceAdapterProtocolDigest(previous) !== indexerEvidenceAdapterProtocolDigest(value)) {
|
|
12840
|
+
throw new TypeError(`ExtractionResult emits conflicting facts for ${value.fact_ref}`);
|
|
12841
|
+
}
|
|
12842
|
+
byRef.set(value.fact_ref, previous ?? value);
|
|
12843
|
+
}
|
|
12844
|
+
return [...byRef.values()];
|
|
12845
|
+
}
|
|
12828
12846
|
function semanticExtractionPayload(extraction) {
|
|
12829
12847
|
return {
|
|
12830
12848
|
version: extraction.version,
|
|
@@ -12841,7 +12859,9 @@ function semanticExtractionPayload(extraction) {
|
|
|
12841
12859
|
stats: extraction.stats
|
|
12842
12860
|
};
|
|
12843
12861
|
}
|
|
12844
|
-
function relationSourceFile(relation, symbols) {
|
|
12862
|
+
function relationSourceFile(relation, symbols, filePaths) {
|
|
12863
|
+
if (filePaths.has(relation.from))
|
|
12864
|
+
return relation.from;
|
|
12845
12865
|
const candidates = symbols.filter((symbol) => symbol.name === relation.from);
|
|
12846
12866
|
if (candidates.length === 1)
|
|
12847
12867
|
return candidates[0].file;
|
|
@@ -12852,6 +12872,13 @@ function relationSourceFile(relation, symbols) {
|
|
|
12852
12872
|
}
|
|
12853
12873
|
return null;
|
|
12854
12874
|
}
|
|
12875
|
+
function relationQualifiedItemPath(relation) {
|
|
12876
|
+
const identityDigest = indexerEvidenceAdapterProtocolDigest({
|
|
12877
|
+
from: relation.from,
|
|
12878
|
+
to: relation.to
|
|
12879
|
+
});
|
|
12880
|
+
return `relation:${relation.type}@${relation.line ?? 0}#${identityDigest}`;
|
|
12881
|
+
}
|
|
12855
12882
|
function diagnosticPayload(diagnostic) {
|
|
12856
12883
|
return {
|
|
12857
12884
|
code: diagnostic.code,
|
|
@@ -12871,6 +12898,7 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
12871
12898
|
}
|
|
12872
12899
|
const coverageByPath = new Map(coverage.files.map((file) => [file.path, file]));
|
|
12873
12900
|
const fileInfoByPath = new Map(extraction.files.map((file) => [file.path, file]));
|
|
12901
|
+
const filePaths = new Set([...coverageByPath.keys(), ...fileInfoByPath.keys()]);
|
|
12874
12902
|
for (const file of extraction.files) {
|
|
12875
12903
|
if (!coverageByPath.has(file.path)) {
|
|
12876
12904
|
throw new TypeError(`ExtractionResult file ${file.path} has no coverage disposition`);
|
|
@@ -12887,7 +12915,7 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
12887
12915
|
const generatedDiagnostics = [];
|
|
12888
12916
|
const relationsByFile = new Map;
|
|
12889
12917
|
for (const relation of extraction.relations) {
|
|
12890
|
-
const file = relationSourceFile(relation, extraction.symbols);
|
|
12918
|
+
const file = relationSourceFile(relation, extraction.symbols, filePaths);
|
|
12891
12919
|
if (file === null || coverageByPath.get(file)?.disposition !== "analyzed") {
|
|
12892
12920
|
generatedDiagnostics.push({
|
|
12893
12921
|
code: "relation-locator-unresolved",
|
|
@@ -12957,7 +12985,7 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
12957
12985
|
sourceRef: invocation.authorized_scope.source_ref,
|
|
12958
12986
|
moduleRef: invocation.module_ref,
|
|
12959
12987
|
normalizedPath: normalizedPath2,
|
|
12960
|
-
qualifiedItemPath:
|
|
12988
|
+
qualifiedItemPath: relationQualifiedItemPath(relation),
|
|
12961
12989
|
kind: "code-relation",
|
|
12962
12990
|
signature: relation,
|
|
12963
12991
|
payload: relation,
|
|
@@ -12973,7 +13001,7 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
12973
13001
|
role,
|
|
12974
13002
|
coverage_tier: coverage.tier,
|
|
12975
13003
|
disposition: coverageFile.disposition,
|
|
12976
|
-
facts
|
|
13004
|
+
facts: uniqueFacts(facts)
|
|
12977
13005
|
};
|
|
12978
13006
|
});
|
|
12979
13007
|
const diagnostics = [
|
|
@@ -13014,6 +13042,184 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
13014
13042
|
}]
|
|
13015
13043
|
});
|
|
13016
13044
|
}
|
|
13045
|
+
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
13046
|
+
var CharacterCodes;
|
|
13047
|
+
(function(CharacterCodes2) {
|
|
13048
|
+
CharacterCodes2[CharacterCodes2["lineFeed"] = 10] = "lineFeed";
|
|
13049
|
+
CharacterCodes2[CharacterCodes2["carriageReturn"] = 13] = "carriageReturn";
|
|
13050
|
+
CharacterCodes2[CharacterCodes2["space"] = 32] = "space";
|
|
13051
|
+
CharacterCodes2[CharacterCodes2["_0"] = 48] = "_0";
|
|
13052
|
+
CharacterCodes2[CharacterCodes2["_1"] = 49] = "_1";
|
|
13053
|
+
CharacterCodes2[CharacterCodes2["_2"] = 50] = "_2";
|
|
13054
|
+
CharacterCodes2[CharacterCodes2["_3"] = 51] = "_3";
|
|
13055
|
+
CharacterCodes2[CharacterCodes2["_4"] = 52] = "_4";
|
|
13056
|
+
CharacterCodes2[CharacterCodes2["_5"] = 53] = "_5";
|
|
13057
|
+
CharacterCodes2[CharacterCodes2["_6"] = 54] = "_6";
|
|
13058
|
+
CharacterCodes2[CharacterCodes2["_7"] = 55] = "_7";
|
|
13059
|
+
CharacterCodes2[CharacterCodes2["_8"] = 56] = "_8";
|
|
13060
|
+
CharacterCodes2[CharacterCodes2["_9"] = 57] = "_9";
|
|
13061
|
+
CharacterCodes2[CharacterCodes2["a"] = 97] = "a";
|
|
13062
|
+
CharacterCodes2[CharacterCodes2["b"] = 98] = "b";
|
|
13063
|
+
CharacterCodes2[CharacterCodes2["c"] = 99] = "c";
|
|
13064
|
+
CharacterCodes2[CharacterCodes2["d"] = 100] = "d";
|
|
13065
|
+
CharacterCodes2[CharacterCodes2["e"] = 101] = "e";
|
|
13066
|
+
CharacterCodes2[CharacterCodes2["f"] = 102] = "f";
|
|
13067
|
+
CharacterCodes2[CharacterCodes2["g"] = 103] = "g";
|
|
13068
|
+
CharacterCodes2[CharacterCodes2["h"] = 104] = "h";
|
|
13069
|
+
CharacterCodes2[CharacterCodes2["i"] = 105] = "i";
|
|
13070
|
+
CharacterCodes2[CharacterCodes2["j"] = 106] = "j";
|
|
13071
|
+
CharacterCodes2[CharacterCodes2["k"] = 107] = "k";
|
|
13072
|
+
CharacterCodes2[CharacterCodes2["l"] = 108] = "l";
|
|
13073
|
+
CharacterCodes2[CharacterCodes2["m"] = 109] = "m";
|
|
13074
|
+
CharacterCodes2[CharacterCodes2["n"] = 110] = "n";
|
|
13075
|
+
CharacterCodes2[CharacterCodes2["o"] = 111] = "o";
|
|
13076
|
+
CharacterCodes2[CharacterCodes2["p"] = 112] = "p";
|
|
13077
|
+
CharacterCodes2[CharacterCodes2["q"] = 113] = "q";
|
|
13078
|
+
CharacterCodes2[CharacterCodes2["r"] = 114] = "r";
|
|
13079
|
+
CharacterCodes2[CharacterCodes2["s"] = 115] = "s";
|
|
13080
|
+
CharacterCodes2[CharacterCodes2["t"] = 116] = "t";
|
|
13081
|
+
CharacterCodes2[CharacterCodes2["u"] = 117] = "u";
|
|
13082
|
+
CharacterCodes2[CharacterCodes2["v"] = 118] = "v";
|
|
13083
|
+
CharacterCodes2[CharacterCodes2["w"] = 119] = "w";
|
|
13084
|
+
CharacterCodes2[CharacterCodes2["x"] = 120] = "x";
|
|
13085
|
+
CharacterCodes2[CharacterCodes2["y"] = 121] = "y";
|
|
13086
|
+
CharacterCodes2[CharacterCodes2["z"] = 122] = "z";
|
|
13087
|
+
CharacterCodes2[CharacterCodes2["A"] = 65] = "A";
|
|
13088
|
+
CharacterCodes2[CharacterCodes2["B"] = 66] = "B";
|
|
13089
|
+
CharacterCodes2[CharacterCodes2["C"] = 67] = "C";
|
|
13090
|
+
CharacterCodes2[CharacterCodes2["D"] = 68] = "D";
|
|
13091
|
+
CharacterCodes2[CharacterCodes2["E"] = 69] = "E";
|
|
13092
|
+
CharacterCodes2[CharacterCodes2["F"] = 70] = "F";
|
|
13093
|
+
CharacterCodes2[CharacterCodes2["G"] = 71] = "G";
|
|
13094
|
+
CharacterCodes2[CharacterCodes2["H"] = 72] = "H";
|
|
13095
|
+
CharacterCodes2[CharacterCodes2["I"] = 73] = "I";
|
|
13096
|
+
CharacterCodes2[CharacterCodes2["J"] = 74] = "J";
|
|
13097
|
+
CharacterCodes2[CharacterCodes2["K"] = 75] = "K";
|
|
13098
|
+
CharacterCodes2[CharacterCodes2["L"] = 76] = "L";
|
|
13099
|
+
CharacterCodes2[CharacterCodes2["M"] = 77] = "M";
|
|
13100
|
+
CharacterCodes2[CharacterCodes2["N"] = 78] = "N";
|
|
13101
|
+
CharacterCodes2[CharacterCodes2["O"] = 79] = "O";
|
|
13102
|
+
CharacterCodes2[CharacterCodes2["P"] = 80] = "P";
|
|
13103
|
+
CharacterCodes2[CharacterCodes2["Q"] = 81] = "Q";
|
|
13104
|
+
CharacterCodes2[CharacterCodes2["R"] = 82] = "R";
|
|
13105
|
+
CharacterCodes2[CharacterCodes2["S"] = 83] = "S";
|
|
13106
|
+
CharacterCodes2[CharacterCodes2["T"] = 84] = "T";
|
|
13107
|
+
CharacterCodes2[CharacterCodes2["U"] = 85] = "U";
|
|
13108
|
+
CharacterCodes2[CharacterCodes2["V"] = 86] = "V";
|
|
13109
|
+
CharacterCodes2[CharacterCodes2["W"] = 87] = "W";
|
|
13110
|
+
CharacterCodes2[CharacterCodes2["X"] = 88] = "X";
|
|
13111
|
+
CharacterCodes2[CharacterCodes2["Y"] = 89] = "Y";
|
|
13112
|
+
CharacterCodes2[CharacterCodes2["Z"] = 90] = "Z";
|
|
13113
|
+
CharacterCodes2[CharacterCodes2["asterisk"] = 42] = "asterisk";
|
|
13114
|
+
CharacterCodes2[CharacterCodes2["backslash"] = 92] = "backslash";
|
|
13115
|
+
CharacterCodes2[CharacterCodes2["closeBrace"] = 125] = "closeBrace";
|
|
13116
|
+
CharacterCodes2[CharacterCodes2["closeBracket"] = 93] = "closeBracket";
|
|
13117
|
+
CharacterCodes2[CharacterCodes2["colon"] = 58] = "colon";
|
|
13118
|
+
CharacterCodes2[CharacterCodes2["comma"] = 44] = "comma";
|
|
13119
|
+
CharacterCodes2[CharacterCodes2["dot"] = 46] = "dot";
|
|
13120
|
+
CharacterCodes2[CharacterCodes2["doubleQuote"] = 34] = "doubleQuote";
|
|
13121
|
+
CharacterCodes2[CharacterCodes2["minus"] = 45] = "minus";
|
|
13122
|
+
CharacterCodes2[CharacterCodes2["openBrace"] = 123] = "openBrace";
|
|
13123
|
+
CharacterCodes2[CharacterCodes2["openBracket"] = 91] = "openBracket";
|
|
13124
|
+
CharacterCodes2[CharacterCodes2["plus"] = 43] = "plus";
|
|
13125
|
+
CharacterCodes2[CharacterCodes2["slash"] = 47] = "slash";
|
|
13126
|
+
CharacterCodes2[CharacterCodes2["formFeed"] = 12] = "formFeed";
|
|
13127
|
+
CharacterCodes2[CharacterCodes2["tab"] = 9] = "tab";
|
|
13128
|
+
})(CharacterCodes || (CharacterCodes = {}));
|
|
13129
|
+
|
|
13130
|
+
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/string-intern.js
|
|
13131
|
+
var cachedSpaces = new Array(20).fill(0).map((_, index) => {
|
|
13132
|
+
return " ".repeat(index);
|
|
13133
|
+
});
|
|
13134
|
+
var maxCachedValues = 200;
|
|
13135
|
+
var cachedBreakLinesWithSpaces = {
|
|
13136
|
+
" ": {
|
|
13137
|
+
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
13138
|
+
return `
|
|
13139
|
+
` + " ".repeat(index);
|
|
13140
|
+
}),
|
|
13141
|
+
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
13142
|
+
return "\r" + " ".repeat(index);
|
|
13143
|
+
}),
|
|
13144
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
13145
|
+
return `\r
|
|
13146
|
+
` + " ".repeat(index);
|
|
13147
|
+
})
|
|
13148
|
+
},
|
|
13149
|
+
"\t": {
|
|
13150
|
+
"\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
13151
|
+
return `
|
|
13152
|
+
` + "\t".repeat(index);
|
|
13153
|
+
}),
|
|
13154
|
+
"\r": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
13155
|
+
return "\r" + "\t".repeat(index);
|
|
13156
|
+
}),
|
|
13157
|
+
"\r\n": new Array(maxCachedValues).fill(0).map((_, index) => {
|
|
13158
|
+
return `\r
|
|
13159
|
+
` + "\t".repeat(index);
|
|
13160
|
+
})
|
|
13161
|
+
}
|
|
13162
|
+
};
|
|
13163
|
+
|
|
13164
|
+
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/parser.js
|
|
13165
|
+
var ParseOptions;
|
|
13166
|
+
(function(ParseOptions2) {
|
|
13167
|
+
ParseOptions2.DEFAULT = {
|
|
13168
|
+
allowTrailingComma: false
|
|
13169
|
+
};
|
|
13170
|
+
})(ParseOptions || (ParseOptions = {}));
|
|
13171
|
+
|
|
13172
|
+
// ../../node_modules/.bun/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/main.js
|
|
13173
|
+
var ScanError;
|
|
13174
|
+
(function(ScanError2) {
|
|
13175
|
+
ScanError2[ScanError2["None"] = 0] = "None";
|
|
13176
|
+
ScanError2[ScanError2["UnexpectedEndOfComment"] = 1] = "UnexpectedEndOfComment";
|
|
13177
|
+
ScanError2[ScanError2["UnexpectedEndOfString"] = 2] = "UnexpectedEndOfString";
|
|
13178
|
+
ScanError2[ScanError2["UnexpectedEndOfNumber"] = 3] = "UnexpectedEndOfNumber";
|
|
13179
|
+
ScanError2[ScanError2["InvalidUnicode"] = 4] = "InvalidUnicode";
|
|
13180
|
+
ScanError2[ScanError2["InvalidEscapeCharacter"] = 5] = "InvalidEscapeCharacter";
|
|
13181
|
+
ScanError2[ScanError2["InvalidCharacter"] = 6] = "InvalidCharacter";
|
|
13182
|
+
})(ScanError || (ScanError = {}));
|
|
13183
|
+
var SyntaxKind;
|
|
13184
|
+
(function(SyntaxKind2) {
|
|
13185
|
+
SyntaxKind2[SyntaxKind2["OpenBraceToken"] = 1] = "OpenBraceToken";
|
|
13186
|
+
SyntaxKind2[SyntaxKind2["CloseBraceToken"] = 2] = "CloseBraceToken";
|
|
13187
|
+
SyntaxKind2[SyntaxKind2["OpenBracketToken"] = 3] = "OpenBracketToken";
|
|
13188
|
+
SyntaxKind2[SyntaxKind2["CloseBracketToken"] = 4] = "CloseBracketToken";
|
|
13189
|
+
SyntaxKind2[SyntaxKind2["CommaToken"] = 5] = "CommaToken";
|
|
13190
|
+
SyntaxKind2[SyntaxKind2["ColonToken"] = 6] = "ColonToken";
|
|
13191
|
+
SyntaxKind2[SyntaxKind2["NullKeyword"] = 7] = "NullKeyword";
|
|
13192
|
+
SyntaxKind2[SyntaxKind2["TrueKeyword"] = 8] = "TrueKeyword";
|
|
13193
|
+
SyntaxKind2[SyntaxKind2["FalseKeyword"] = 9] = "FalseKeyword";
|
|
13194
|
+
SyntaxKind2[SyntaxKind2["StringLiteral"] = 10] = "StringLiteral";
|
|
13195
|
+
SyntaxKind2[SyntaxKind2["NumericLiteral"] = 11] = "NumericLiteral";
|
|
13196
|
+
SyntaxKind2[SyntaxKind2["LineCommentTrivia"] = 12] = "LineCommentTrivia";
|
|
13197
|
+
SyntaxKind2[SyntaxKind2["BlockCommentTrivia"] = 13] = "BlockCommentTrivia";
|
|
13198
|
+
SyntaxKind2[SyntaxKind2["LineBreakTrivia"] = 14] = "LineBreakTrivia";
|
|
13199
|
+
SyntaxKind2[SyntaxKind2["Trivia"] = 15] = "Trivia";
|
|
13200
|
+
SyntaxKind2[SyntaxKind2["Unknown"] = 16] = "Unknown";
|
|
13201
|
+
SyntaxKind2[SyntaxKind2["EOF"] = 17] = "EOF";
|
|
13202
|
+
})(SyntaxKind || (SyntaxKind = {}));
|
|
13203
|
+
var ParseErrorCode;
|
|
13204
|
+
(function(ParseErrorCode2) {
|
|
13205
|
+
ParseErrorCode2[ParseErrorCode2["InvalidSymbol"] = 1] = "InvalidSymbol";
|
|
13206
|
+
ParseErrorCode2[ParseErrorCode2["InvalidNumberFormat"] = 2] = "InvalidNumberFormat";
|
|
13207
|
+
ParseErrorCode2[ParseErrorCode2["PropertyNameExpected"] = 3] = "PropertyNameExpected";
|
|
13208
|
+
ParseErrorCode2[ParseErrorCode2["ValueExpected"] = 4] = "ValueExpected";
|
|
13209
|
+
ParseErrorCode2[ParseErrorCode2["ColonExpected"] = 5] = "ColonExpected";
|
|
13210
|
+
ParseErrorCode2[ParseErrorCode2["CommaExpected"] = 6] = "CommaExpected";
|
|
13211
|
+
ParseErrorCode2[ParseErrorCode2["CloseBraceExpected"] = 7] = "CloseBraceExpected";
|
|
13212
|
+
ParseErrorCode2[ParseErrorCode2["CloseBracketExpected"] = 8] = "CloseBracketExpected";
|
|
13213
|
+
ParseErrorCode2[ParseErrorCode2["EndOfFileExpected"] = 9] = "EndOfFileExpected";
|
|
13214
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCommentToken"] = 10] = "InvalidCommentToken";
|
|
13215
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfComment"] = 11] = "UnexpectedEndOfComment";
|
|
13216
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfString"] = 12] = "UnexpectedEndOfString";
|
|
13217
|
+
ParseErrorCode2[ParseErrorCode2["UnexpectedEndOfNumber"] = 13] = "UnexpectedEndOfNumber";
|
|
13218
|
+
ParseErrorCode2[ParseErrorCode2["InvalidUnicode"] = 14] = "InvalidUnicode";
|
|
13219
|
+
ParseErrorCode2[ParseErrorCode2["InvalidEscapeCharacter"] = 15] = "InvalidEscapeCharacter";
|
|
13220
|
+
ParseErrorCode2[ParseErrorCode2["InvalidCharacter"] = 16] = "InvalidCharacter";
|
|
13221
|
+
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
13222
|
+
|
|
13017
13223
|
// ../../node_modules/.bun/eslint-visitor-keys@5.0.1/node_modules/eslint-visitor-keys/lib/visitor-keys.js
|
|
13018
13224
|
var KEYS = {
|
|
13019
13225
|
ArrayExpression: ["elements"],
|
|
@@ -13502,6 +13708,24 @@ var scriptKind = (filePath) => {
|
|
|
13502
13708
|
return ts.ScriptKind.TS;
|
|
13503
13709
|
};
|
|
13504
13710
|
var createEcmaScriptSourceFile = (source, filePath) => ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, scriptKind(filePath));
|
|
13711
|
+
var treeSitterCompatibleJsxSource = (sourceFile, source) => {
|
|
13712
|
+
const characters = source.split("");
|
|
13713
|
+
let changed = false;
|
|
13714
|
+
const visit2 = (node2) => {
|
|
13715
|
+
const jsxPresentationLiteral = ts.isJsxText(node2) || ts.isStringLiteral(node2) && ts.isJsxAttribute(node2.parent);
|
|
13716
|
+
if (jsxPresentationLiteral) {
|
|
13717
|
+
for (let index = node2.getStart(sourceFile);index < node2.getEnd(); index += 1) {
|
|
13718
|
+
if (characters[index] === "&") {
|
|
13719
|
+
characters[index] = " ";
|
|
13720
|
+
changed = true;
|
|
13721
|
+
}
|
|
13722
|
+
}
|
|
13723
|
+
}
|
|
13724
|
+
ts.forEachChild(node2, visit2);
|
|
13725
|
+
};
|
|
13726
|
+
visit2(sourceFile);
|
|
13727
|
+
return changed ? characters.join("") : source;
|
|
13728
|
+
};
|
|
13505
13729
|
var syntaxDiagnostics = (sourceFile) => {
|
|
13506
13730
|
const diagnostics = sourceFile.parseDiagnostics ?? [];
|
|
13507
13731
|
return diagnostics.map((diagnostic) => {
|
|
@@ -13685,7 +13909,7 @@ var collectBindings = (sourceFile) => {
|
|
|
13685
13909
|
};
|
|
13686
13910
|
var collectDynamicDiagnostics = (sourceFile) => {
|
|
13687
13911
|
const diagnostics = [];
|
|
13688
|
-
const
|
|
13912
|
+
const visit2 = (node2) => {
|
|
13689
13913
|
if (ts2.isCallExpression(node2) && ts2.isIdentifier(node2.expression) && node2.expression.text === "require") {
|
|
13690
13914
|
if (staticStringValue(node2.arguments[0]) === null) {
|
|
13691
13915
|
const location = nodeLocation(sourceFile, node2);
|
|
@@ -13723,9 +13947,9 @@ var collectDynamicDiagnostics = (sourceFile) => {
|
|
|
13723
13947
|
}
|
|
13724
13948
|
}
|
|
13725
13949
|
}
|
|
13726
|
-
ts2.forEachChild(node2,
|
|
13950
|
+
ts2.forEachChild(node2, visit2);
|
|
13727
13951
|
};
|
|
13728
|
-
|
|
13952
|
+
visit2(sourceFile);
|
|
13729
13953
|
return diagnostics;
|
|
13730
13954
|
};
|
|
13731
13955
|
var analyzeCommonJsModule = (source, filePath) => {
|
|
@@ -13962,7 +14186,9 @@ var traceFile = async (filePath, fs, state) => {
|
|
|
13962
14186
|
const commonJs = analyzeCommonJsModule(source, filePath);
|
|
13963
14187
|
if (commonJs.diagnostics.length > 0)
|
|
13964
14188
|
return [];
|
|
13965
|
-
const
|
|
14189
|
+
const jsxLike = isJsxLikePath(filePath);
|
|
14190
|
+
const parserSource = jsxLike ? treeSitterCompatibleJsxSource(createEcmaScriptSourceFile(source, filePath), source) : source;
|
|
14191
|
+
const tree = await parseFile(parserSource, jsxLike);
|
|
13966
14192
|
if (!tree)
|
|
13967
14193
|
return [];
|
|
13968
14194
|
const root = tree.rootNode;
|
|
@@ -14407,7 +14633,7 @@ var declarationName = (node2, sourceFile) => {
|
|
|
14407
14633
|
var collectStaticCallRelations = (source, filePath, importBindings) => {
|
|
14408
14634
|
const sourceFile = createEcmaScriptSourceFile(source, filePath);
|
|
14409
14635
|
const relations = [];
|
|
14410
|
-
const
|
|
14636
|
+
const visit2 = (node2, owner) => {
|
|
14411
14637
|
const namedOwner = declarationName(node2, sourceFile) ?? owner;
|
|
14412
14638
|
if (ts3.isCallExpression(node2) || ts3.isNewExpression(node2)) {
|
|
14413
14639
|
const target = callTarget(node2.expression, sourceFile);
|
|
@@ -14417,9 +14643,9 @@ var collectStaticCallRelations = (source, filePath, importBindings) => {
|
|
|
14417
14643
|
relations.push(createRelation("calls" /* Calls */, namedOwner, target, isExternal, nodeLocation(sourceFile, node2).line));
|
|
14418
14644
|
}
|
|
14419
14645
|
}
|
|
14420
|
-
ts3.forEachChild(node2, (child) =>
|
|
14646
|
+
ts3.forEachChild(node2, (child) => visit2(child, namedOwner));
|
|
14421
14647
|
};
|
|
14422
|
-
|
|
14648
|
+
visit2(sourceFile, filePath);
|
|
14423
14649
|
const seen = new Set;
|
|
14424
14650
|
return relations.sort((left, right) => (left.line ?? 0) - (right.line ?? 0) || left.from.localeCompare(right.from) || left.to.localeCompare(right.to)).filter((relation) => {
|
|
14425
14651
|
const key = `${relation.from}\x00${relation.to}\x00${relation.line ?? 0}`;
|
|
@@ -14721,7 +14947,9 @@ var analyzeFile = async (filePath, fs, resolver = { mappings: [] }) => {
|
|
|
14721
14947
|
const source = await fs.readFile(filePath);
|
|
14722
14948
|
const sourceFile = createEcmaScriptSourceFile(source, filePath);
|
|
14723
14949
|
const commonJs = analyzeCommonJsModule(source, filePath);
|
|
14724
|
-
const
|
|
14950
|
+
const jsxLike = isJsxLikePath(filePath);
|
|
14951
|
+
const parserSource = jsxLike ? treeSitterCompatibleJsxSource(sourceFile, source) : source;
|
|
14952
|
+
const tree = await parseFile(parserSource, jsxLike);
|
|
14725
14953
|
if (!tree) {
|
|
14726
14954
|
const diagnostics = syntaxDiagnostics(sourceFile);
|
|
14727
14955
|
if (diagnostics.length === 0) {
|
|
@@ -14786,6 +15014,26 @@ var analyzeFile = async (filePath, fs, resolver = { mappings: [] }) => {
|
|
|
14786
15014
|
};
|
|
14787
15015
|
|
|
14788
15016
|
// src/symbolExtractor.ts
|
|
15017
|
+
var relationIdentity = (relation) => JSON.stringify([
|
|
15018
|
+
relation.type,
|
|
15019
|
+
relation.from,
|
|
15020
|
+
relation.to,
|
|
15021
|
+
relation.isExternal,
|
|
15022
|
+
relation.grounding,
|
|
15023
|
+
relation.confidence,
|
|
15024
|
+
relation.source,
|
|
15025
|
+
relation.line ?? null
|
|
15026
|
+
]);
|
|
15027
|
+
var uniqueRelations = (relations) => {
|
|
15028
|
+
const seen = new Set;
|
|
15029
|
+
return relations.filter((relation) => {
|
|
15030
|
+
const identity = relationIdentity(relation);
|
|
15031
|
+
if (seen.has(identity))
|
|
15032
|
+
return false;
|
|
15033
|
+
seen.add(identity);
|
|
15034
|
+
return true;
|
|
15035
|
+
});
|
|
15036
|
+
};
|
|
14789
15037
|
var extractSymbols = async (entries, fs, options) => {
|
|
14790
15038
|
const resolver = await loadTsConfigPathResolver(fs);
|
|
14791
15039
|
const exportedSymbols = [];
|
|
@@ -14794,15 +15042,19 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
14794
15042
|
const filePaths = new Set;
|
|
14795
15043
|
const exportedDeclarationKeys = new Set;
|
|
14796
15044
|
const analyses = new Map;
|
|
15045
|
+
const analysisScope = options.analysisPaths === undefined ? null : new Set(options.analysisPaths);
|
|
15046
|
+
const isInScope = (path2) => analysisScope === null || analysisScope.has(path2);
|
|
14797
15047
|
for (const entry of entries) {
|
|
14798
15048
|
const traced = await traceExports(entry.path, fs, resolver);
|
|
14799
|
-
traced.files.forEach((filePath) => filePaths.add(filePath));
|
|
14800
|
-
for (const filePath of traced.files) {
|
|
15049
|
+
traced.files.filter(isInScope).forEach((filePath) => filePaths.add(filePath));
|
|
15050
|
+
for (const filePath of traced.files.filter(isInScope)) {
|
|
14801
15051
|
if (!analyses.has(filePath)) {
|
|
14802
15052
|
analyses.set(filePath, await analyzeFile(filePath, fs, resolver));
|
|
14803
15053
|
}
|
|
14804
15054
|
}
|
|
14805
15055
|
for (const tracedExport of traced.exports) {
|
|
15056
|
+
if (!isInScope(tracedExport.declarationFile))
|
|
15057
|
+
continue;
|
|
14806
15058
|
const analysis = analyses.get(tracedExport.declarationFile);
|
|
14807
15059
|
const declaration = analysis?.declarations.get(tracedExport.localName);
|
|
14808
15060
|
if (!declaration)
|
|
@@ -14820,6 +15072,12 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
14820
15072
|
});
|
|
14821
15073
|
}
|
|
14822
15074
|
}
|
|
15075
|
+
for (const filePath of [...analysisScope ?? []].sort()) {
|
|
15076
|
+
filePaths.add(filePath);
|
|
15077
|
+
if (!analyses.has(filePath)) {
|
|
15078
|
+
analyses.set(filePath, await analyzeFile(filePath, fs, resolver));
|
|
15079
|
+
}
|
|
15080
|
+
}
|
|
14823
15081
|
for (const [filePath, analysis] of analyses) {
|
|
14824
15082
|
relations.push(...analysis.relations);
|
|
14825
15083
|
for (const [name, declaration] of analysis.declarations) {
|
|
@@ -14860,6 +15118,7 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
14860
15118
|
relations.push(createRelation("of_type" /* OfType */, sym.name, propsTypeName, false, sym.line));
|
|
14861
15119
|
}
|
|
14862
15120
|
}
|
|
15121
|
+
const deduplicatedRelations = uniqueRelations(relations);
|
|
14863
15122
|
const files = [...filePaths].sort().map((filePath) => ({
|
|
14864
15123
|
path: filePath,
|
|
14865
15124
|
language: ecmaScriptLanguage(filePath),
|
|
@@ -14887,7 +15146,7 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
14887
15146
|
package: options.packageInfo,
|
|
14888
15147
|
files,
|
|
14889
15148
|
symbols,
|
|
14890
|
-
relations,
|
|
15149
|
+
relations: deduplicatedRelations,
|
|
14891
15150
|
coverage: {
|
|
14892
15151
|
tier: EXTRACT_TS_COVERAGE_TIER,
|
|
14893
15152
|
capabilities: [...EXTRACT_TS_CAPABILITIES],
|
|
@@ -14899,7 +15158,7 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
14899
15158
|
lines: files.reduce((sum, file) => sum + file.lines, 0),
|
|
14900
15159
|
exportedSymbols: exportedSymbols.length,
|
|
14901
15160
|
internalSymbols: internalSymbols.length,
|
|
14902
|
-
relations:
|
|
15161
|
+
relations: deduplicatedRelations.length
|
|
14903
15162
|
}
|
|
14904
15163
|
};
|
|
14905
15164
|
};
|
|
@@ -14926,12 +15185,29 @@ class TypeScriptPlugin {
|
|
|
14926
15185
|
if (!packageInfo) {
|
|
14927
15186
|
throw new Error("TypeScriptPlugin.extractSymbols requires detectEntries to run first");
|
|
14928
15187
|
}
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
15188
|
+
try {
|
|
15189
|
+
return await extractSymbols(entries, fs, {
|
|
15190
|
+
packageInfo,
|
|
15191
|
+
pluginId: this.id
|
|
15192
|
+
});
|
|
15193
|
+
} finally {
|
|
15194
|
+
this.#lastDetection = null;
|
|
15195
|
+
}
|
|
15196
|
+
}
|
|
15197
|
+
async extractSymbolsInScope(entries, analysisPaths, fs) {
|
|
15198
|
+
const packageInfo = this.#lastDetection?.package;
|
|
15199
|
+
if (!packageInfo) {
|
|
15200
|
+
throw new Error("TypeScriptPlugin.extractSymbolsInScope requires detectEntries to run first");
|
|
15201
|
+
}
|
|
15202
|
+
try {
|
|
15203
|
+
return await extractSymbols(entries, fs, {
|
|
15204
|
+
packageInfo,
|
|
15205
|
+
pluginId: this.id,
|
|
15206
|
+
analysisPaths
|
|
15207
|
+
});
|
|
15208
|
+
} finally {
|
|
15209
|
+
this.#lastDetection = null;
|
|
15210
|
+
}
|
|
14935
15211
|
}
|
|
14936
15212
|
}
|
|
14937
15213
|
// src/reactRouter.ts
|
|
@@ -14954,16 +15230,16 @@ function scalarValue(node2) {
|
|
|
14954
15230
|
}
|
|
14955
15231
|
function findDynamicImport(node2) {
|
|
14956
15232
|
let result;
|
|
14957
|
-
const
|
|
15233
|
+
const visit2 = (child) => {
|
|
14958
15234
|
if (result)
|
|
14959
15235
|
return;
|
|
14960
15236
|
if (ts4.isCallExpression(child) && child.expression.kind === ts4.SyntaxKind.ImportKeyword && child.arguments[0] && ts4.isStringLiteralLike(child.arguments[0])) {
|
|
14961
15237
|
result = child.arguments[0].text;
|
|
14962
15238
|
return;
|
|
14963
15239
|
}
|
|
14964
|
-
ts4.forEachChild(child,
|
|
15240
|
+
ts4.forEachChild(child, visit2);
|
|
14965
15241
|
};
|
|
14966
|
-
|
|
15242
|
+
visit2(node2);
|
|
14967
15243
|
return result;
|
|
14968
15244
|
}
|
|
14969
15245
|
function parseSource(source, filePath) {
|
|
@@ -15051,7 +15327,7 @@ function jsxScalar(attribute, constants2) {
|
|
|
15051
15327
|
}
|
|
15052
15328
|
function descendantTags(node2) {
|
|
15053
15329
|
const tags = new Set;
|
|
15054
|
-
const
|
|
15330
|
+
const visit2 = (child) => {
|
|
15055
15331
|
if (ts4.isJsxElement(child) || ts4.isJsxSelfClosingElement(child)) {
|
|
15056
15332
|
const opening = ts4.isJsxElement(child) ? child.openingElement : child;
|
|
15057
15333
|
const tag = opening.tagName.getText();
|
|
@@ -15060,14 +15336,14 @@ function descendantTags(node2) {
|
|
|
15060
15336
|
if (!["Route", "Routes", "Suspense", "Fragment", "React.Fragment", "Navigate"].includes(tag))
|
|
15061
15337
|
tags.add(tag);
|
|
15062
15338
|
}
|
|
15063
|
-
ts4.forEachChild(child,
|
|
15339
|
+
ts4.forEachChild(child, visit2);
|
|
15064
15340
|
};
|
|
15065
|
-
|
|
15341
|
+
visit2(node2);
|
|
15066
15342
|
return [...tags];
|
|
15067
15343
|
}
|
|
15068
15344
|
function navigateTarget(node2, sourceFile) {
|
|
15069
15345
|
let target;
|
|
15070
|
-
const
|
|
15346
|
+
const visit2 = (child) => {
|
|
15071
15347
|
if (target)
|
|
15072
15348
|
return;
|
|
15073
15349
|
if (ts4.isJsxElement(child) || ts4.isJsxSelfClosingElement(child)) {
|
|
@@ -15086,9 +15362,9 @@ function navigateTarget(node2, sourceFile) {
|
|
|
15086
15362
|
}
|
|
15087
15363
|
}
|
|
15088
15364
|
}
|
|
15089
|
-
ts4.forEachChild(child,
|
|
15365
|
+
ts4.forEachChild(child, visit2);
|
|
15090
15366
|
};
|
|
15091
|
-
|
|
15367
|
+
visit2(node2);
|
|
15092
15368
|
return target;
|
|
15093
15369
|
}
|
|
15094
15370
|
function leadingNote(node2, sourceFile) {
|
|
@@ -15170,7 +15446,7 @@ function extractReactRouterRoutes(source, filePath, options = {}) {
|
|
|
15170
15446
|
});
|
|
15171
15447
|
}
|
|
15172
15448
|
};
|
|
15173
|
-
const
|
|
15449
|
+
const visit2 = (node2, parentPath) => {
|
|
15174
15450
|
if (ts4.isJsxElement(node2) || ts4.isJsxSelfClosingElement(node2)) {
|
|
15175
15451
|
const opening = ts4.isJsxElement(node2) ? node2.openingElement : node2;
|
|
15176
15452
|
if (opening.tagName.getText() === "Route") {
|
|
@@ -15187,7 +15463,7 @@ function extractReactRouterRoutes(source, filePath, options = {}) {
|
|
|
15187
15463
|
pushRoute({ node: node2, parentPath, path: typeof pathValue === "string" ? pathValue : "", index, ...component ? { component } : {}, candidates, ...redirectTo ? { redirectTo } : {} });
|
|
15188
15464
|
if (ts4.isJsxElement(node2))
|
|
15189
15465
|
for (const child of node2.children)
|
|
15190
|
-
|
|
15466
|
+
visit2(child, fullPath);
|
|
15191
15467
|
return;
|
|
15192
15468
|
}
|
|
15193
15469
|
}
|
|
@@ -15197,9 +15473,9 @@ function extractReactRouterRoutes(source, filePath, options = {}) {
|
|
|
15197
15473
|
visitRouteObjects(node2.arguments[0], mountPath);
|
|
15198
15474
|
}
|
|
15199
15475
|
}
|
|
15200
|
-
ts4.forEachChild(node2, (child) =>
|
|
15476
|
+
ts4.forEachChild(node2, (child) => visit2(child, parentPath));
|
|
15201
15477
|
};
|
|
15202
|
-
|
|
15478
|
+
visit2(parsed.sourceFile, mountPath);
|
|
15203
15479
|
return routes.sort((left, right) => left.fullPath.localeCompare(right.fullPath) || left.location.startLine - right.location.startLine || left.location.startColumn - right.location.startColumn);
|
|
15204
15480
|
}
|
|
15205
15481
|
// src/moduleExports.ts
|