@c4a/extract-ts 0.7.5 → 0.7.9
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/index.js +1425 -950
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -11444,15 +11444,21 @@ function replaceWithCount(value, pattern, replacement, count) {
|
|
|
11444
11444
|
return replacement(...args.slice(0, -2));
|
|
11445
11445
|
});
|
|
11446
11446
|
}
|
|
11447
|
+
var SECRET_TEXT_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)";
|
|
11448
|
+
var SECRET_TEXT_ASSIGNMENT = `(?:=\\s*|:\\s+(?=\\S)|:\\s*(?=["']))`;
|
|
11449
|
+
var AUTHORIZATION_TEXT_PATTERN = new RegExp(`(\\bauthorization\\s*:\\s*(?:bearer|basic)\\s+)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^\\s,;]+`, "giu");
|
|
11450
|
+
var QUERY_SECRET_TEXT_PATTERN = new RegExp(`([?&](?:access_token|refresh_token|api_key|password|secret)=)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^&#\\s]+`, "giu");
|
|
11451
|
+
var ASSIGNMENT_SECRET_TEXT_PATTERN = new RegExp(`((?:["']?${SECRET_TEXT_KEY}["']?)\\s*${SECRET_TEXT_ASSIGNMENT})` + `(?!["']?${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})` + `(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu");
|
|
11447
11452
|
function redactKnownText(value, count) {
|
|
11453
|
+
if (!value.includes(":") && !value.includes("=") && !value.includes("-----BEGIN ")) {
|
|
11454
|
+
return value;
|
|
11455
|
+
}
|
|
11448
11456
|
let output = value;
|
|
11449
11457
|
output = replaceWithCount(output, /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/gu, INDEXER_OUTPUT_REDACTION_MARKER, count);
|
|
11450
|
-
output = replaceWithCount(output,
|
|
11458
|
+
output = replaceWithCount(output, AUTHORIZATION_TEXT_PATTERN, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
|
|
11451
11459
|
output = replaceWithCount(output, /([a-z][a-z0-9+.-]*:\/\/)[^\s/@:]+:[^\s/@]+@/giu, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}@`, count);
|
|
11452
|
-
output = replaceWithCount(output,
|
|
11453
|
-
|
|
11454
|
-
const assignment = `(?:=\\s*|:\\s+(?=\\S)|:\\s*(?=["']))`;
|
|
11455
|
-
output = replaceWithCount(output, new RegExp(`((?:["']?${key}["']?)\\s*${assignment})` + `(?!["']?${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})` + `(?:"(?:\\\\.|[^"])*"|'(?:\\\\.|[^'])*'|[^\\s,;}\\]]+)`, "giu"), (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
|
|
11460
|
+
output = replaceWithCount(output, QUERY_SECRET_TEXT_PATTERN, (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
|
|
11461
|
+
output = replaceWithCount(output, ASSIGNMENT_SECRET_TEXT_PATTERN, (_match, prefix) => `${prefix}"${INDEXER_OUTPUT_REDACTION_MARKER}"`, count);
|
|
11456
11462
|
return output;
|
|
11457
11463
|
}
|
|
11458
11464
|
function redactBlockedText(value, blocked, count) {
|
|
@@ -12532,238 +12538,1006 @@ var detectEntries = async (manifest, fs) => {
|
|
|
12532
12538
|
};
|
|
12533
12539
|
};
|
|
12534
12540
|
|
|
12535
|
-
//
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
"
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
name:
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
path: exports_external.string().min(1),
|
|
12591
|
-
language: exports_external.string().min(1),
|
|
12592
|
-
lines: exports_external.number().int().nonnegative()
|
|
12593
|
-
});
|
|
12594
|
-
var extractionDiagnosticSchema = exports_external.object({
|
|
12595
|
-
code: exports_external.string().min(1),
|
|
12596
|
-
severity: exports_external.enum(["info", "warning", "error"]),
|
|
12597
|
-
file: exports_external.string().min(1),
|
|
12598
|
-
line: exports_external.number().int().positive(),
|
|
12599
|
-
column: exports_external.number().int().positive()
|
|
12600
|
-
});
|
|
12601
|
-
var extractionCoverageSchema = exports_external.object({
|
|
12602
|
-
tier: exports_external.enum(["ast-catalog", "lightweight-evidence"]),
|
|
12603
|
-
capabilities: exports_external.array(exports_external.string().min(1)),
|
|
12604
|
-
files: exports_external.array(exports_external.object({
|
|
12605
|
-
path: exports_external.string().min(1),
|
|
12606
|
-
disposition: exports_external.enum(["analyzed", "unsupported", "excluded"]),
|
|
12607
|
-
diagnosticCodes: exports_external.array(exports_external.string().min(1))
|
|
12608
|
-
})),
|
|
12609
|
-
diagnostics: exports_external.array(extractionDiagnosticSchema)
|
|
12610
|
-
});
|
|
12611
|
-
var extractionMetaSchema = exports_external.object({
|
|
12612
|
-
extractedAt: exports_external.string().datetime(),
|
|
12613
|
-
pluginId: exports_external.string().min(1),
|
|
12614
|
-
commitHash: exports_external.string().min(1).nullable(),
|
|
12615
|
-
language: exports_external.string().min(1)
|
|
12616
|
-
});
|
|
12617
|
-
var extractionPackageSchema = exports_external.object({
|
|
12618
|
-
name: exports_external.string().min(1),
|
|
12619
|
-
kind: packageKindSchema2,
|
|
12620
|
-
language: exports_external.string().min(1),
|
|
12621
|
-
version: exports_external.string().min(1).optional()
|
|
12622
|
-
});
|
|
12623
|
-
var extractionStatsSchema = exports_external.object({
|
|
12624
|
-
files: exports_external.number().int().nonnegative(),
|
|
12625
|
-
lines: exports_external.number().int().nonnegative(),
|
|
12626
|
-
exportedSymbols: exports_external.number().int().nonnegative(),
|
|
12627
|
-
internalSymbols: exports_external.number().int().nonnegative(),
|
|
12628
|
-
relations: exports_external.number().int().nonnegative()
|
|
12629
|
-
});
|
|
12630
|
-
var extractionResultSchema = exports_external.object({
|
|
12631
|
-
version: exports_external.literal("2"),
|
|
12632
|
-
meta: extractionMetaSchema,
|
|
12633
|
-
package: extractionPackageSchema,
|
|
12634
|
-
files: exports_external.array(fileInfoSchema),
|
|
12635
|
-
symbols: exports_external.array(symbolInfoSchema),
|
|
12636
|
-
relations: exports_external.array(relationInfoSchema),
|
|
12637
|
-
coverage: extractionCoverageSchema.optional(),
|
|
12638
|
-
stats: extractionStatsSchema
|
|
12639
|
-
});
|
|
12640
|
-
var digestStatsSchema = exports_external.object({
|
|
12641
|
-
files: exports_external.number().int().nonnegative(),
|
|
12642
|
-
lines: exports_external.number().int().nonnegative(),
|
|
12643
|
-
exported_count: exports_external.number().int().nonnegative(),
|
|
12644
|
-
internal_count: exports_external.number().int().nonnegative(),
|
|
12645
|
-
relations: exports_external.number().int().nonnegative()
|
|
12646
|
-
});
|
|
12647
|
-
var digestDataSchema = exports_external.object({
|
|
12648
|
-
version: exports_external.literal("2"),
|
|
12649
|
-
meta: extractionMetaSchema,
|
|
12650
|
-
package: extractionPackageSchema,
|
|
12651
|
-
files: exports_external.array(fileInfoSchema),
|
|
12652
|
-
symbols: exports_external.array(symbolInfoSchema),
|
|
12653
|
-
relations: exports_external.array(relationInfoSchema),
|
|
12654
|
-
coverage: extractionCoverageSchema.optional(),
|
|
12655
|
-
stats: digestStatsSchema
|
|
12656
|
-
});
|
|
12657
|
-
var symbolDiffSchema = exports_external.object({
|
|
12658
|
-
added: exports_external.array(exports_external.string().min(1)),
|
|
12659
|
-
removed: exports_external.array(exports_external.string().min(1))
|
|
12660
|
-
});
|
|
12661
|
-
// ../extract/src/protocol.ts
|
|
12662
|
-
var packageKindSchema3 = exports_external.enum(Object.values(PackageKind));
|
|
12663
|
-
var manifestTypeSchema = exports_external.enum([
|
|
12664
|
-
"package.json",
|
|
12665
|
-
"pyproject.toml",
|
|
12666
|
-
"Cargo.toml",
|
|
12667
|
-
"go.mod",
|
|
12668
|
-
"pom.xml"
|
|
12669
|
-
]);
|
|
12670
|
-
var entryFileSchema = exports_external.object({
|
|
12671
|
-
path: exports_external.string().min(1),
|
|
12672
|
-
subpath: exports_external.string().min(1),
|
|
12673
|
-
type: exports_external.enum(["library", "cli", "service", "webapp"])
|
|
12674
|
-
});
|
|
12675
|
-
var manifestInfoSchema = exports_external.object({
|
|
12676
|
-
type: manifestTypeSchema,
|
|
12677
|
-
path: exports_external.string().min(1),
|
|
12678
|
-
content: exports_external.record(exports_external.unknown())
|
|
12679
|
-
});
|
|
12680
|
-
var sourceInfoSchema = exports_external.object({
|
|
12681
|
-
path: exports_external.string().min(1),
|
|
12682
|
-
manifests: exports_external.array(manifestInfoSchema),
|
|
12683
|
-
language: exports_external.string().min(1).optional()
|
|
12684
|
-
});
|
|
12685
|
-
var entryDetectionResultSchema = exports_external.lazy(() => exports_external.object({
|
|
12686
|
-
package: exports_external.object({
|
|
12687
|
-
name: exports_external.string().min(1),
|
|
12688
|
-
kind: packageKindSchema3,
|
|
12689
|
-
language: exports_external.string().min(1),
|
|
12690
|
-
version: exports_external.string().min(1).optional()
|
|
12691
|
-
}),
|
|
12692
|
-
entries: exports_external.array(entryFileSchema),
|
|
12693
|
-
subPackages: exports_external.array(entryDetectionResultSchema).optional()
|
|
12694
|
-
}));
|
|
12695
|
-
var patternDetectionResultSchema = exports_external.object({
|
|
12696
|
-
endpoints: exports_external.array(exports_external.object({
|
|
12697
|
-
handler: exports_external.string().min(1),
|
|
12698
|
-
method: exports_external.string().min(1),
|
|
12699
|
-
path: exports_external.string().min(1),
|
|
12700
|
-
file: exports_external.string().min(1),
|
|
12701
|
-
line: exports_external.number().int().positive()
|
|
12702
|
-
})).optional(),
|
|
12703
|
-
implicitDeps: exports_external.array(exports_external.object({
|
|
12704
|
-
verb: exports_external.enum(["produce", "consume", "depends_on", "serve"]),
|
|
12705
|
-
target: exports_external.string().min(1),
|
|
12706
|
-
file: exports_external.string().min(1),
|
|
12707
|
-
line: exports_external.number().int().positive()
|
|
12708
|
-
})).optional(),
|
|
12709
|
-
configRefs: exports_external.array(exports_external.object({
|
|
12710
|
-
key: exports_external.string().min(1),
|
|
12711
|
-
file: exports_external.string().min(1),
|
|
12712
|
-
line: exports_external.number().int().positive()
|
|
12713
|
-
})).optional()
|
|
12714
|
-
});
|
|
12715
|
-
// ../extract/src/registry.ts
|
|
12716
|
-
var MANIFEST_LANGUAGE_CANDIDATES = {
|
|
12717
|
-
"package.json": ["typescript", "tsx", "javascript", "jsx"],
|
|
12718
|
-
"pyproject.toml": ["python"],
|
|
12719
|
-
"Cargo.toml": ["rust"],
|
|
12720
|
-
"go.mod": ["go"],
|
|
12721
|
-
"pom.xml": ["java"]
|
|
12722
|
-
};
|
|
12723
|
-
|
|
12724
|
-
class ExtractionPluginRegistry {
|
|
12725
|
-
#plugins = [];
|
|
12726
|
-
register(plugin) {
|
|
12727
|
-
this.#plugins.push(plugin);
|
|
12541
|
+
// src/componentContract.ts
|
|
12542
|
+
import ts from "typescript";
|
|
12543
|
+
function componentPropsNode(node2) {
|
|
12544
|
+
if (node2 === undefined || !ts.isTypeReferenceNode(node2))
|
|
12545
|
+
return;
|
|
12546
|
+
if (!["FC", "React.FC", "FunctionComponent", "React.FunctionComponent"].includes(node2.typeName.getText()))
|
|
12547
|
+
return;
|
|
12548
|
+
return node2.typeArguments?.length === 1 ? node2.typeArguments[0] : undefined;
|
|
12549
|
+
}
|
|
12550
|
+
function componentLocalPropsNode(node2, checker) {
|
|
12551
|
+
if (ts.isParenthesizedTypeNode(node2))
|
|
12552
|
+
return componentLocalPropsNode(node2.type, checker);
|
|
12553
|
+
if (!ts.isTypeReferenceNode(node2) || node2.typeArguments?.length !== 1)
|
|
12554
|
+
return;
|
|
12555
|
+
const name = node2.typeName;
|
|
12556
|
+
const identifier = ts.isIdentifier(name) ? name : ts.isIdentifier(name.left) ? name.left : undefined;
|
|
12557
|
+
if (identifier === undefined)
|
|
12558
|
+
return;
|
|
12559
|
+
const imported = checker.getSymbolAtLocation(identifier)?.declarations?.find((declaration) => ts.isImportSpecifier(declaration) || ts.isNamespaceImport(declaration) || ts.isImportClause(declaration));
|
|
12560
|
+
if (imported === undefined)
|
|
12561
|
+
return;
|
|
12562
|
+
let owner = imported;
|
|
12563
|
+
while (!ts.isImportDeclaration(owner) && owner.parent !== undefined)
|
|
12564
|
+
owner = owner.parent;
|
|
12565
|
+
if (!ts.isImportDeclaration(owner) || !ts.isStringLiteral(owner.moduleSpecifier) || owner.moduleSpecifier.text !== "react")
|
|
12566
|
+
return;
|
|
12567
|
+
const wrapper = ts.isIdentifier(name) ? ts.isImportSpecifier(imported) ? (imported.propertyName ?? imported.name).text : undefined : ts.isNamespaceImport(imported) || ts.isImportClause(imported) ? name.right.text : undefined;
|
|
12568
|
+
return wrapper === "PropsWithChildren" ? node2.typeArguments[0] : undefined;
|
|
12569
|
+
}
|
|
12570
|
+
function componentPropsName(annotation) {
|
|
12571
|
+
const source = ts.createSourceFile("contract.ts", `type Contract = ${annotation};`, ts.ScriptTarget.Latest, true);
|
|
12572
|
+
const declaration = source.statements[0];
|
|
12573
|
+
if (declaration === undefined || !ts.isTypeAliasDeclaration(declaration))
|
|
12574
|
+
return;
|
|
12575
|
+
const props = componentPropsNode(declaration.type);
|
|
12576
|
+
return props !== undefined && ts.isTypeReferenceNode(props) && ts.isIdentifier(props.typeName) && !props.typeArguments?.length ? props.typeName.text : undefined;
|
|
12577
|
+
}
|
|
12578
|
+
function componentBindingDefaults(pattern) {
|
|
12579
|
+
const source = ts.createSourceFile("contract.ts", `function input(${pattern}) {}`, ts.ScriptTarget.Latest, true);
|
|
12580
|
+
const diagnostics = source.parseDiagnostics;
|
|
12581
|
+
const fn = source.statements[0];
|
|
12582
|
+
if (diagnostics.length || source.statements.length !== 1 || fn === undefined || !ts.isFunctionDeclaration(fn) || fn.parameters.length !== 1 || fn.body?.statements.length)
|
|
12583
|
+
return {};
|
|
12584
|
+
const name = fn.parameters[0].name;
|
|
12585
|
+
return componentDefaultsFromBinding(name, source);
|
|
12586
|
+
}
|
|
12587
|
+
function componentDefaultsFromBinding(name, source) {
|
|
12588
|
+
if (!ts.isObjectBindingPattern(name))
|
|
12589
|
+
return {};
|
|
12590
|
+
const defaults = Object.create(null);
|
|
12591
|
+
for (const element of name.elements) {
|
|
12592
|
+
const key = element.propertyName ?? element.name;
|
|
12593
|
+
if (element.initializer === undefined || element.dotDotDotToken !== undefined || !ts.isIdentifier(key) && !ts.isStringLiteral(key) && !ts.isNumericLiteral(key))
|
|
12594
|
+
continue;
|
|
12595
|
+
defaults[key.text] = element.initializer.getText(source);
|
|
12728
12596
|
}
|
|
12729
|
-
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12597
|
+
return defaults;
|
|
12598
|
+
}
|
|
12599
|
+
|
|
12600
|
+
// src/federationContracts.ts
|
|
12601
|
+
import ts2 from "typescript";
|
|
12602
|
+
function federationContracts(source) {
|
|
12603
|
+
const factories = new Set;
|
|
12604
|
+
for (const statement of source.statements) {
|
|
12605
|
+
if (!ts2.isImportDeclaration(statement) || !ts2.isStringLiteral(statement.moduleSpecifier))
|
|
12606
|
+
continue;
|
|
12607
|
+
const module = statement.moduleSpecifier.text;
|
|
12608
|
+
const clause = statement.importClause;
|
|
12609
|
+
if (module === "webpack" && clause?.name !== undefined)
|
|
12610
|
+
factories.add(`${clause.name.text}.container.ModuleFederationPlugin`);
|
|
12611
|
+
if (!["webpack", "@module-federation/enhanced/webpack", "@module-federation/enhanced/rspack", "@module-federation/vite"].includes(module))
|
|
12612
|
+
continue;
|
|
12613
|
+
if (clause?.namedBindings !== undefined && ts2.isNamedImports(clause.namedBindings)) {
|
|
12614
|
+
for (const item of clause.namedBindings.elements) {
|
|
12615
|
+
if (["ModuleFederationPlugin", "federation"].includes((item.propertyName ?? item.name).text))
|
|
12616
|
+
factories.add(item.name.text);
|
|
12617
|
+
if (module === "webpack" && (item.propertyName ?? item.name).text === "container")
|
|
12618
|
+
factories.add(`${item.name.text}.ModuleFederationPlugin`);
|
|
12745
12619
|
}
|
|
12746
12620
|
}
|
|
12747
|
-
return null;
|
|
12748
|
-
}
|
|
12749
|
-
list() {
|
|
12750
|
-
return [...this.#plugins];
|
|
12751
12621
|
}
|
|
12622
|
+
const results = [];
|
|
12623
|
+
const visit = (node2) => {
|
|
12624
|
+
if ((ts2.isCallExpression(node2) || ts2.isNewExpression(node2)) && factories.has(node2.expression.getText(source))) {
|
|
12625
|
+
const config = node2.arguments?.[0];
|
|
12626
|
+
if (config !== undefined && ts2.isObjectLiteralExpression(config)) {
|
|
12627
|
+
const members = [];
|
|
12628
|
+
for (const property of config.properties) {
|
|
12629
|
+
if (!ts2.isPropertyAssignment(property))
|
|
12630
|
+
continue;
|
|
12631
|
+
const key = property.name.getText(source).replace(/^['"]|['"]$/gu, "");
|
|
12632
|
+
if (!["name", "filename", "exposes", "remotes", "shared"].includes(key))
|
|
12633
|
+
continue;
|
|
12634
|
+
const properties = ts2.isObjectLiteralExpression(property.initializer) ? property.initializer.properties.filter(ts2.isPropertyAssignment) : [property];
|
|
12635
|
+
for (const value of properties)
|
|
12636
|
+
members.push({
|
|
12637
|
+
name: value === property ? key : `${key}.${value.name.getText(source).replace(/^['"]|['"]$/gu, "")}`,
|
|
12638
|
+
kind: "config" /* Config */,
|
|
12639
|
+
visibility: "exported" /* Exported */,
|
|
12640
|
+
file: source.fileName.replace(/^\//u, ""),
|
|
12641
|
+
line: source.getLineAndCharacterOfPosition(value.getStart()).line + 1,
|
|
12642
|
+
endLine: source.getLineAndCharacterOfPosition(value.end).line + 1,
|
|
12643
|
+
typeAnnotation: value.initializer.getText(source)
|
|
12644
|
+
});
|
|
12645
|
+
}
|
|
12646
|
+
results.push({
|
|
12647
|
+
name: "Module federation configuration",
|
|
12648
|
+
kind: "config" /* Config */,
|
|
12649
|
+
visibility: "exported" /* Exported */,
|
|
12650
|
+
file: source.fileName.replace(/^\//u, ""),
|
|
12651
|
+
line: source.getLineAndCharacterOfPosition(node2.getStart()).line + 1,
|
|
12652
|
+
endLine: source.getLineAndCharacterOfPosition(node2.end).line + 1,
|
|
12653
|
+
signature: node2.expression.getText(source),
|
|
12654
|
+
members
|
|
12655
|
+
});
|
|
12656
|
+
}
|
|
12657
|
+
}
|
|
12658
|
+
ts2.forEachChild(node2, visit);
|
|
12659
|
+
};
|
|
12660
|
+
visit(source);
|
|
12661
|
+
return results;
|
|
12752
12662
|
}
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
import {
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
"
|
|
12762
|
-
"
|
|
12763
|
-
"
|
|
12764
|
-
"
|
|
12765
|
-
"
|
|
12766
|
-
|
|
12663
|
+
|
|
12664
|
+
// src/publicContracts.ts
|
|
12665
|
+
import { posix as posix3 } from "node:path";
|
|
12666
|
+
import ts5 from "typescript";
|
|
12667
|
+
|
|
12668
|
+
// src/typeReferences.ts
|
|
12669
|
+
import ts3 from "typescript";
|
|
12670
|
+
var BUILTIN_TYPES = new Set([
|
|
12671
|
+
"Array",
|
|
12672
|
+
"Boolean",
|
|
12673
|
+
"Date",
|
|
12674
|
+
"Error",
|
|
12675
|
+
"Map",
|
|
12676
|
+
"Number",
|
|
12677
|
+
"Object",
|
|
12678
|
+
"Promise",
|
|
12679
|
+
"ReadonlyArray",
|
|
12680
|
+
"Record",
|
|
12681
|
+
"Set",
|
|
12682
|
+
"String"
|
|
12683
|
+
]);
|
|
12684
|
+
function referencedTypeNames(text) {
|
|
12685
|
+
if (!text)
|
|
12686
|
+
return [];
|
|
12687
|
+
const file = ts3.createSourceFile("type.ts", `type __Value = ${text};`, ts3.ScriptTarget.Latest, true);
|
|
12688
|
+
const declaration = file.statements[0];
|
|
12689
|
+
if (!declaration || !ts3.isTypeAliasDeclaration(declaration))
|
|
12690
|
+
return [];
|
|
12691
|
+
const result = new Set;
|
|
12692
|
+
const visit = (node2, bound) => {
|
|
12693
|
+
const scope = new Set(bound);
|
|
12694
|
+
if ("typeParameters" in node2) {
|
|
12695
|
+
for (const parameter of node2.typeParameters ?? []) {
|
|
12696
|
+
scope.add(parameter.name.text);
|
|
12697
|
+
}
|
|
12698
|
+
}
|
|
12699
|
+
if (ts3.isMappedTypeNode(node2)) {
|
|
12700
|
+
if (node2.typeParameter.constraint)
|
|
12701
|
+
visit(node2.typeParameter.constraint, bound);
|
|
12702
|
+
scope.add(node2.typeParameter.name.text);
|
|
12703
|
+
if (node2.nameType)
|
|
12704
|
+
visit(node2.nameType, scope);
|
|
12705
|
+
if (node2.type)
|
|
12706
|
+
visit(node2.type, scope);
|
|
12707
|
+
return;
|
|
12708
|
+
}
|
|
12709
|
+
if (ts3.isConditionalTypeNode(node2)) {
|
|
12710
|
+
visit(node2.checkType, scope);
|
|
12711
|
+
visit(node2.extendsType, scope);
|
|
12712
|
+
const inferred = new Set(scope);
|
|
12713
|
+
const collect = (child) => {
|
|
12714
|
+
if (ts3.isInferTypeNode(child))
|
|
12715
|
+
inferred.add(child.typeParameter.name.text);
|
|
12716
|
+
else if (!ts3.isConditionalTypeNode(child))
|
|
12717
|
+
ts3.forEachChild(child, collect);
|
|
12718
|
+
};
|
|
12719
|
+
collect(node2.extendsType);
|
|
12720
|
+
visit(node2.trueType, inferred);
|
|
12721
|
+
visit(node2.falseType, scope);
|
|
12722
|
+
return;
|
|
12723
|
+
}
|
|
12724
|
+
if (ts3.isTypeReferenceNode(node2)) {
|
|
12725
|
+
const name = node2.typeName.getText(file);
|
|
12726
|
+
if (!scope.has(name.split(".")[0]) && !BUILTIN_TYPES.has(name))
|
|
12727
|
+
result.add(name);
|
|
12728
|
+
}
|
|
12729
|
+
ts3.forEachChild(node2, (child) => visit(child, scope));
|
|
12730
|
+
};
|
|
12731
|
+
visit(declaration.type, new Set);
|
|
12732
|
+
return [...result];
|
|
12733
|
+
}
|
|
12734
|
+
|
|
12735
|
+
// src/symbolExtractorAst.ts
|
|
12736
|
+
var DECLARATION_TYPES = new Set([
|
|
12737
|
+
"function_declaration",
|
|
12738
|
+
"class_declaration",
|
|
12739
|
+
"interface_declaration",
|
|
12740
|
+
"type_alias_declaration",
|
|
12741
|
+
"enum_declaration",
|
|
12742
|
+
"lexical_declaration"
|
|
12743
|
+
]);
|
|
12744
|
+
var countLines = (source) => {
|
|
12745
|
+
if (!source)
|
|
12746
|
+
return 0;
|
|
12747
|
+
return source.split(/\r\n|\r|\n/).filter((line) => line.trim().length > 0).length;
|
|
12748
|
+
};
|
|
12749
|
+
var createRelation = (type, from, to, isExternal, line) => ({
|
|
12750
|
+
type,
|
|
12751
|
+
from,
|
|
12752
|
+
to,
|
|
12753
|
+
isExternal,
|
|
12754
|
+
grounding: "code" /* Code */,
|
|
12755
|
+
confidence: 1,
|
|
12756
|
+
source: "ast" /* Ast */,
|
|
12757
|
+
...line ? { line } : {}
|
|
12758
|
+
});
|
|
12759
|
+
var getLine = (node2) => node2.startPosition.row + 1;
|
|
12760
|
+
var getEndLine = (node2) => node2.endPosition.row + 1;
|
|
12761
|
+
var extractJSDoc = (node2) => {
|
|
12762
|
+
const prev = node2.previousNamedSibling ?? node2.parent?.previousNamedSibling;
|
|
12763
|
+
if (!prev || prev.type !== "comment")
|
|
12764
|
+
return;
|
|
12765
|
+
const text = prev.text;
|
|
12766
|
+
if (!text.startsWith("/**"))
|
|
12767
|
+
return;
|
|
12768
|
+
const cleaned = text.replace(/^\/\*\*\s*/, "").replace(/\s*\*\/$/, "").replace(/^\s*\* ?/gm, "").trim();
|
|
12769
|
+
return cleaned || undefined;
|
|
12770
|
+
};
|
|
12771
|
+
var extractTypeAnnotation = (node2) => {
|
|
12772
|
+
if (!node2)
|
|
12773
|
+
return null;
|
|
12774
|
+
return node2.text.replace(/^:\s*/, "").trim() || null;
|
|
12775
|
+
};
|
|
12776
|
+
var getNameNodeText = (node2) => node2?.text?.trim() ? node2.text.trim() : null;
|
|
12777
|
+
var getReturnType = (node2) => {
|
|
12778
|
+
const returnNode = node2.childForFieldName("return_type") ?? node2.namedChildren.find((child) => child.type === "type_annotation") ?? null;
|
|
12779
|
+
return extractTypeAnnotation(returnNode);
|
|
12780
|
+
};
|
|
12781
|
+
var getInitializer = (node2) => node2.childForFieldName("value") ?? node2.namedChildren.find((child) => child.type === "arrow_function" || child.type === "function" || child.type === "call_expression") ?? null;
|
|
12782
|
+
var getCallableFromInitializer = (node2) => {
|
|
12783
|
+
if (!node2)
|
|
12784
|
+
return null;
|
|
12785
|
+
if (node2.type === "arrow_function" || node2.type === "function")
|
|
12786
|
+
return node2;
|
|
12787
|
+
if (node2.type === "call_expression") {
|
|
12788
|
+
return node2.namedChildren.find((child) => child.type === "arrow_function" || child.type === "function") ?? null;
|
|
12789
|
+
}
|
|
12790
|
+
return null;
|
|
12791
|
+
};
|
|
12792
|
+
var getInitializerTypeAnnotation = (node2, options = {}) => {
|
|
12793
|
+
if (!node2 || node2.type !== "call_expression")
|
|
12794
|
+
return null;
|
|
12795
|
+
const typeArguments = node2.namedChildren.find((child) => child.type === "type_arguments") ?? null;
|
|
12796
|
+
if (!typeArguments)
|
|
12797
|
+
return null;
|
|
12798
|
+
if (options.referencesOnly) {
|
|
12799
|
+
return `[${typeArguments.namedChildren.filter((child) => child.type !== "comment").map((child) => child.text).join(", ")}]`;
|
|
12800
|
+
}
|
|
12801
|
+
const callee = node2.namedChildren.find((child) => child.type !== "type_arguments" && child.type !== "arguments") ?? null;
|
|
12802
|
+
const calleeText = callee?.text?.trim();
|
|
12803
|
+
return calleeText ? `${calleeText}${typeArguments.text}` : typeArguments.text;
|
|
12804
|
+
};
|
|
12805
|
+
var getInitializerText = (node2, options = {}) => {
|
|
12806
|
+
if (!node2)
|
|
12807
|
+
return null;
|
|
12808
|
+
if ((node2.type === "arrow_function" || node2.type === "function") && !options.includeCallable)
|
|
12809
|
+
return null;
|
|
12810
|
+
const text = node2.text.trim();
|
|
12811
|
+
if ((node2.type === "arrow_function" || node2.type === "function") && text.length > 600)
|
|
12812
|
+
return null;
|
|
12813
|
+
return text.length > 0 ? text : null;
|
|
12814
|
+
};
|
|
12815
|
+
var inferReturnType = (node2) => {
|
|
12816
|
+
if (!node2)
|
|
12817
|
+
return null;
|
|
12818
|
+
return containsJsx(node2) ? "JSX.Element" : null;
|
|
12819
|
+
};
|
|
12820
|
+
var containsJsx = (node2) => {
|
|
12821
|
+
if (node2.type.startsWith("jsx_"))
|
|
12822
|
+
return true;
|
|
12823
|
+
return node2.namedChildren.some(containsJsx);
|
|
12824
|
+
};
|
|
12825
|
+
var resolveTypeBinding = (typeName, importBindings, declarations) => {
|
|
12826
|
+
const localName = typeName.split(".")[0] ?? typeName;
|
|
12827
|
+
const importBinding = importBindings.get(localName);
|
|
12828
|
+
if (importBinding)
|
|
12829
|
+
return importBinding.isExternal;
|
|
12830
|
+
if (declarations.has(localName))
|
|
12831
|
+
return false;
|
|
12832
|
+
return false;
|
|
12833
|
+
};
|
|
12834
|
+
var appendTypeRelations = (relations, relationType, from, typeText, importBindings, declarations, line) => {
|
|
12835
|
+
for (const typeName of referencedTypeNames(typeText)) {
|
|
12836
|
+
relations.push(createRelation(relationType, from, typeName, resolveTypeBinding(typeName, importBindings, declarations), line));
|
|
12837
|
+
}
|
|
12838
|
+
};
|
|
12839
|
+
var classifyVariable = (name, filePath) => {
|
|
12840
|
+
if ((filePath.endsWith(".tsx") || filePath.endsWith(".jsx")) && /^[A-Z]/.test(name)) {
|
|
12841
|
+
return "component" /* Component */;
|
|
12842
|
+
}
|
|
12843
|
+
return "variable" /* Variable */;
|
|
12844
|
+
};
|
|
12845
|
+
var collectParams = (node2) => {
|
|
12846
|
+
if (!node2)
|
|
12847
|
+
return [];
|
|
12848
|
+
return node2.namedChildren.map((child) => {
|
|
12849
|
+
const wrapper = child;
|
|
12850
|
+
const target = child.type === "required_parameter" || child.type === "optional_parameter" ? child.namedChildren[0] ?? child : child;
|
|
12851
|
+
const nameNode = target.childForFieldName("name") ?? target.namedChildren.find((candidate) => candidate.type === "identifier" || candidate.type === "property_identifier") ?? target.namedChildren[0] ?? target;
|
|
12852
|
+
const typeNode = wrapper.childForFieldName("type") ?? wrapper.namedChildren.find((candidate) => candidate.type === "type_annotation") ?? target.childForFieldName("type") ?? target.namedChildren.find((candidate) => candidate.type === "type_annotation") ?? null;
|
|
12853
|
+
return {
|
|
12854
|
+
name: nameNode.text,
|
|
12855
|
+
type: extractTypeAnnotation(typeNode),
|
|
12856
|
+
optional: wrapper.type === "optional_parameter" || wrapper.children.some((child2) => child2.text === "?"),
|
|
12857
|
+
rest: wrapper.text.trimStart().startsWith("..."),
|
|
12858
|
+
...wrapper.childForFieldName("value") === null ? {} : { defaultValue: wrapper.childForFieldName("value").text }
|
|
12859
|
+
};
|
|
12860
|
+
});
|
|
12861
|
+
};
|
|
12862
|
+
var collectMembers = (node2, declarations, importBindings, ownerName, relations) => {
|
|
12863
|
+
if (!node2)
|
|
12864
|
+
return;
|
|
12865
|
+
const members = [];
|
|
12866
|
+
for (const child of node2.namedChildren) {
|
|
12867
|
+
if (child.type === "public_field_definition" || child.type === "property_signature") {
|
|
12868
|
+
const nameNode = child.childForFieldName("name") ?? child.namedChildren.find((candidate) => candidate.type === "property_identifier" || candidate.type === "identifier");
|
|
12869
|
+
if (!nameNode)
|
|
12870
|
+
continue;
|
|
12871
|
+
const typeNode = child.childForFieldName("type") ?? child.namedChildren.find((candidate) => candidate.type === "type_annotation") ?? null;
|
|
12872
|
+
const typeAnnotation = extractTypeAnnotation(typeNode);
|
|
12873
|
+
const propDoc = extractJSDoc(child);
|
|
12874
|
+
members.push({
|
|
12875
|
+
name: nameNode.text,
|
|
12876
|
+
kind: "prop" /* Prop */,
|
|
12877
|
+
visibility: "internal" /* Internal */,
|
|
12878
|
+
file: "",
|
|
12879
|
+
line: getLine(child),
|
|
12880
|
+
endLine: getEndLine(child),
|
|
12881
|
+
optional: child.children.some((token) => token.text === "?"),
|
|
12882
|
+
readonly: child.children.some((token) => token.text === "readonly"),
|
|
12883
|
+
...typeAnnotation ? { typeAnnotation } : {},
|
|
12884
|
+
...propDoc ? { doc: propDoc } : {}
|
|
12885
|
+
});
|
|
12886
|
+
appendTypeRelations(relations, "of_type" /* OfType */, ownerName, typeAnnotation, importBindings, declarations, getLine(child));
|
|
12887
|
+
continue;
|
|
12888
|
+
}
|
|
12889
|
+
const indexMember = indexSignatureMember(child);
|
|
12890
|
+
if (indexMember) {
|
|
12891
|
+
members.push(indexMember.info);
|
|
12892
|
+
appendTypeRelations(relations, "of_type" /* OfType */, ownerName, indexMember.typeAnnotation, importBindings, declarations, getLine(child));
|
|
12893
|
+
continue;
|
|
12894
|
+
}
|
|
12895
|
+
if (child.type === "method_definition" || child.type === "method_signature") {
|
|
12896
|
+
const nameNode = child.childForFieldName("name") ?? child.namedChildren.find((candidate) => candidate.type === "property_identifier" || candidate.type === "identifier");
|
|
12897
|
+
if (!nameNode)
|
|
12898
|
+
continue;
|
|
12899
|
+
const paramsNode = child.childForFieldName("parameters") ?? child.namedChildren.find((candidate) => candidate.type === "formal_parameters") ?? null;
|
|
12900
|
+
const params = collectParams(paramsNode);
|
|
12901
|
+
const returnType = getReturnType(child);
|
|
12902
|
+
const methodDoc = extractJSDoc(child);
|
|
12903
|
+
members.push({
|
|
12904
|
+
name: nameNode.text,
|
|
12905
|
+
kind: "method" /* Method */,
|
|
12906
|
+
visibility: "internal" /* Internal */,
|
|
12907
|
+
file: "",
|
|
12908
|
+
line: getLine(child),
|
|
12909
|
+
endLine: getEndLine(child),
|
|
12910
|
+
...params.length > 0 ? { params } : {},
|
|
12911
|
+
...returnType ? { returnType } : {},
|
|
12912
|
+
...methodDoc ? { doc: methodDoc } : {}
|
|
12913
|
+
});
|
|
12914
|
+
for (const param of params) {
|
|
12915
|
+
appendTypeRelations(relations, "param_type" /* ParamType */, ownerName, param.type, importBindings, declarations, getLine(child));
|
|
12916
|
+
}
|
|
12917
|
+
appendTypeRelations(relations, "return_type" /* ReturnType */, ownerName, returnType, importBindings, declarations, getLine(child));
|
|
12918
|
+
}
|
|
12919
|
+
}
|
|
12920
|
+
return members.length > 0 ? members : undefined;
|
|
12921
|
+
};
|
|
12922
|
+
var indexSignatureMember = (node2) => {
|
|
12923
|
+
if (node2.type !== "index_signature")
|
|
12924
|
+
return null;
|
|
12925
|
+
const match = /^\s*(\[[^\]]+\])\s*:?\s*([^;]+)?;?\s*$/u.exec(node2.text);
|
|
12926
|
+
const name = match?.[1]?.trim();
|
|
12927
|
+
const typeAnnotation = match?.[2]?.trim();
|
|
12928
|
+
if (!name)
|
|
12929
|
+
return null;
|
|
12930
|
+
const propDoc = extractJSDoc(node2);
|
|
12931
|
+
return {
|
|
12932
|
+
info: {
|
|
12933
|
+
name,
|
|
12934
|
+
kind: "prop" /* Prop */,
|
|
12935
|
+
visibility: "internal" /* Internal */,
|
|
12936
|
+
file: "",
|
|
12937
|
+
line: getLine(node2),
|
|
12938
|
+
endLine: getEndLine(node2),
|
|
12939
|
+
...typeAnnotation ? { typeAnnotation } : {},
|
|
12940
|
+
...propDoc ? { doc: propDoc } : {}
|
|
12941
|
+
},
|
|
12942
|
+
typeAnnotation
|
|
12943
|
+
};
|
|
12944
|
+
};
|
|
12945
|
+
var collectEnumValues = (node2) => {
|
|
12946
|
+
const body = node2.namedChildren.find((child) => child.type === "enum_body") ?? null;
|
|
12947
|
+
if (!body)
|
|
12948
|
+
return;
|
|
12949
|
+
const values = [];
|
|
12950
|
+
for (const member of body.namedChildren.filter((child) => child.type === "enum_assignment" || child.type === "property_identifier")) {
|
|
12951
|
+
if (member.type === "property_identifier") {
|
|
12952
|
+
values.push(member.text);
|
|
12953
|
+
continue;
|
|
12954
|
+
}
|
|
12955
|
+
const name = member.childForFieldName("name")?.text ?? member.namedChildren[0]?.text;
|
|
12956
|
+
if (!name)
|
|
12957
|
+
continue;
|
|
12958
|
+
const valueNode = member.childForFieldName("value") ?? member.namedChildren.find((child) => child !== member.childForFieldName("name")) ?? null;
|
|
12959
|
+
const rawValue = valueNode?.text.replace(/^['"]|['"]$/gu, "");
|
|
12960
|
+
values.push(rawValue ? `${name} = ${rawValue}` : name);
|
|
12961
|
+
}
|
|
12962
|
+
return values.length > 0 ? values : undefined;
|
|
12963
|
+
};
|
|
12964
|
+
var extractUnionLiteralValues = (typeNode) => {
|
|
12965
|
+
if (!typeNode)
|
|
12966
|
+
return;
|
|
12967
|
+
if (typeNode.type === "literal_type") {
|
|
12968
|
+
const text = typeNode.text.replace(/^['"]|['"]$/g, "");
|
|
12969
|
+
return text ? [text] : undefined;
|
|
12970
|
+
}
|
|
12971
|
+
if (typeNode.type === "union_type") {
|
|
12972
|
+
const values = [];
|
|
12973
|
+
for (const child of typeNode.namedChildren) {
|
|
12974
|
+
if (child.type === "literal_type") {
|
|
12975
|
+
const text = child.text.replace(/^['"]|['"]$/g, "");
|
|
12976
|
+
if (text)
|
|
12977
|
+
values.push(text);
|
|
12978
|
+
} else if (child.type === "union_type") {
|
|
12979
|
+
const nested = extractUnionLiteralValues(child);
|
|
12980
|
+
if (!nested)
|
|
12981
|
+
return;
|
|
12982
|
+
values.push(...nested);
|
|
12983
|
+
} else {
|
|
12984
|
+
return;
|
|
12985
|
+
}
|
|
12986
|
+
}
|
|
12987
|
+
return values.length > 0 ? values : undefined;
|
|
12988
|
+
}
|
|
12989
|
+
return;
|
|
12990
|
+
};
|
|
12991
|
+
var findObjectTypeNodes = (node2) => {
|
|
12992
|
+
if (!node2)
|
|
12993
|
+
return [];
|
|
12994
|
+
if (node2.type === "object_type")
|
|
12995
|
+
return [node2];
|
|
12996
|
+
if (node2.type === "intersection_type" || node2.type === "union_type") {
|
|
12997
|
+
return node2.namedChildren.flatMap(findObjectTypeNodes);
|
|
12998
|
+
}
|
|
12999
|
+
if (node2.type === "parenthesized_type" && node2.namedChildCount > 0) {
|
|
13000
|
+
return findObjectTypeNodes(node2.namedChildren[0]);
|
|
13001
|
+
}
|
|
13002
|
+
return [];
|
|
13003
|
+
};
|
|
13004
|
+
|
|
13005
|
+
// src/runtimeRegistrations.ts
|
|
13006
|
+
import ts4 from "typescript";
|
|
13007
|
+
function runtimeRegistrations(source) {
|
|
13008
|
+
const imports = new Map;
|
|
13009
|
+
const receivers = new Map;
|
|
13010
|
+
const middleware = new Map;
|
|
13011
|
+
const result = [];
|
|
13012
|
+
const supported = new Set(["express", "fastify", "hono", "node-cron", "node:events", "events"]);
|
|
13013
|
+
for (const statement of source.statements) {
|
|
13014
|
+
if (!ts4.isImportDeclaration(statement) || !ts4.isStringLiteral(statement.moduleSpecifier))
|
|
13015
|
+
continue;
|
|
13016
|
+
const module = statement.moduleSpecifier.text;
|
|
13017
|
+
if (!supported.has(module))
|
|
13018
|
+
continue;
|
|
13019
|
+
const clause = statement.importClause;
|
|
13020
|
+
if (clause?.name !== undefined)
|
|
13021
|
+
imports.set(clause.name.text, module);
|
|
13022
|
+
if (clause?.namedBindings !== undefined) {
|
|
13023
|
+
if (ts4.isNamespaceImport(clause.namedBindings))
|
|
13024
|
+
imports.set(clause.namedBindings.name.text, module);
|
|
13025
|
+
else
|
|
13026
|
+
for (const item of clause.namedBindings.elements)
|
|
13027
|
+
imports.set(item.name.text, module);
|
|
13028
|
+
}
|
|
13029
|
+
}
|
|
13030
|
+
const rootName = (node2) => ts4.isIdentifier(node2) ? node2.text : ts4.isPropertyAccessExpression(node2) ? rootName(node2.expression) : undefined;
|
|
13031
|
+
const visit = (node2) => {
|
|
13032
|
+
if (ts4.isVariableDeclaration(node2) && ts4.isIdentifier(node2.name) && node2.initializer !== undefined && (ts4.isCallExpression(node2.initializer) || ts4.isNewExpression(node2.initializer))) {
|
|
13033
|
+
const root = rootName(node2.initializer.expression);
|
|
13034
|
+
const module = root === undefined ? undefined : imports.get(root);
|
|
13035
|
+
if (module !== undefined)
|
|
13036
|
+
receivers.set(node2.name.text, module);
|
|
13037
|
+
}
|
|
13038
|
+
if (ts4.isCallExpression(node2) && ts4.isPropertyAccessExpression(node2.expression)) {
|
|
13039
|
+
const receiver = node2.expression.expression.getText(source);
|
|
13040
|
+
const module = receivers.get(receiver) ?? imports.get(receiver);
|
|
13041
|
+
const operation = node2.expression.name.text;
|
|
13042
|
+
if (module !== undefined) {
|
|
13043
|
+
const args = node2.arguments;
|
|
13044
|
+
const http = ["express", "fastify", "hono"].includes(module);
|
|
13045
|
+
if (http && operation === "use") {
|
|
13046
|
+
middleware.set(receiver, [...middleware.get(receiver) ?? [], ...args.map((arg) => arg.getText(source))]);
|
|
13047
|
+
}
|
|
13048
|
+
const kind = http && ["get", "post", "put", "patch", "delete", "head", "options", "all"].includes(operation) ? "http" : module === "node-cron" && operation === "schedule" ? "schedule" : ["events", "node:events"].includes(module) && ["on", "once"].includes(operation) ? "event" : undefined;
|
|
13049
|
+
const first = args[0];
|
|
13050
|
+
if (kind !== undefined && first !== undefined && ts4.isStringLiteralLike(first) && args.length >= 2) {
|
|
13051
|
+
const handler = args.at(-1).getText(source);
|
|
13052
|
+
const line = source.getLineAndCharacterOfPosition(node2.getStart()).line + 1;
|
|
13053
|
+
result.push({
|
|
13054
|
+
name: `${kind === "http" ? operation.toUpperCase() : kind} ${first.text}`,
|
|
13055
|
+
kind: kind === "http" ? "endpoint" /* Endpoint */ : "process" /* Process */,
|
|
13056
|
+
visibility: "exported" /* Exported */,
|
|
13057
|
+
file: source.fileName.replace(/^\//u, ""),
|
|
13058
|
+
line,
|
|
13059
|
+
endLine: source.getLineAndCharacterOfPosition(node2.end).line + 1,
|
|
13060
|
+
signature: `${operation} ${first.text} → ${handler}`,
|
|
13061
|
+
registration: {
|
|
13062
|
+
kind,
|
|
13063
|
+
key: first.text,
|
|
13064
|
+
handler,
|
|
13065
|
+
...kind === "http" ? { method: operation.toUpperCase() } : {},
|
|
13066
|
+
middleware: [...middleware.get(receiver) ?? [], ...args.slice(1, -1).map((arg) => arg.getText(source))]
|
|
13067
|
+
}
|
|
13068
|
+
});
|
|
13069
|
+
}
|
|
13070
|
+
}
|
|
13071
|
+
}
|
|
13072
|
+
ts4.forEachChild(node2, visit);
|
|
13073
|
+
};
|
|
13074
|
+
visit(source);
|
|
13075
|
+
return result;
|
|
13076
|
+
}
|
|
13077
|
+
|
|
13078
|
+
// src/publicContracts.ts
|
|
13079
|
+
var format = ts5.TypeFormatFlags.NoTruncation | ts5.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
13080
|
+
function declarationAt(source, symbol) {
|
|
13081
|
+
const candidates = [];
|
|
13082
|
+
const visit = (node2) => {
|
|
13083
|
+
const line = source.getLineAndCharacterOfPosition(node2.getStart(source)).line + 1;
|
|
13084
|
+
if (line > symbol.endLine)
|
|
13085
|
+
return;
|
|
13086
|
+
if (line === symbol.line && (ts5.isFunctionDeclaration(node2) || ts5.isVariableDeclaration(node2) || ts5.isInterfaceDeclaration(node2) || ts5.isTypeAliasDeclaration(node2) || ts5.isClassDeclaration(node2))) {
|
|
13087
|
+
candidates.push(node2);
|
|
13088
|
+
}
|
|
13089
|
+
ts5.forEachChild(node2, visit);
|
|
13090
|
+
};
|
|
13091
|
+
visit(source);
|
|
13092
|
+
return candidates.find((node2) => ("name" in node2) && node2.name?.getText(source) === symbol.name) ?? (candidates.length === 1 ? candidates[0] : undefined);
|
|
13093
|
+
}
|
|
13094
|
+
function declaredObjectTypes(node2, checker, seen = new Set) {
|
|
13095
|
+
if (seen.has(node2))
|
|
13096
|
+
return [];
|
|
13097
|
+
seen.add(node2);
|
|
13098
|
+
if (ts5.isTypeAliasDeclaration(node2))
|
|
13099
|
+
return declaredObjectTypes(node2.type, checker, seen);
|
|
13100
|
+
if (ts5.isParenthesizedTypeNode(node2))
|
|
13101
|
+
return declaredObjectTypes(node2.type, checker, seen);
|
|
13102
|
+
if (ts5.isIntersectionTypeNode(node2))
|
|
13103
|
+
return node2.types.flatMap((type) => declaredObjectTypes(type, checker, seen));
|
|
13104
|
+
if (ts5.isTypeReferenceNode(node2) && !node2.typeArguments?.length) {
|
|
13105
|
+
let symbol = checker.getSymbolAtLocation(node2.typeName);
|
|
13106
|
+
if (symbol !== undefined && (symbol.flags & ts5.SymbolFlags.Alias) !== 0)
|
|
13107
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
13108
|
+
return (symbol?.declarations ?? []).flatMap((declaration) => declaredObjectTypes(declaration, checker, seen));
|
|
13109
|
+
}
|
|
13110
|
+
return ts5.isTypeLiteralNode(node2) || ts5.isInterfaceDeclaration(node2) ? [node2] : [];
|
|
13111
|
+
}
|
|
13112
|
+
function memberTypeText(checker, type, member, annotation) {
|
|
13113
|
+
const text = checker.typeToString(type, member, format);
|
|
13114
|
+
if (annotation === undefined)
|
|
13115
|
+
return { text, complete: (type.flags & (ts5.TypeFlags.Any | ts5.TypeFlags.Unknown)) === 0 };
|
|
13116
|
+
if (annotation.kind === ts5.SyntaxKind.AnyKeyword || annotation.kind === ts5.SyntaxKind.UnknownKeyword) {
|
|
13117
|
+
return { text: annotation.getText(), complete: true };
|
|
13118
|
+
}
|
|
13119
|
+
let incomplete = (type.flags & (ts5.TypeFlags.Any | ts5.TypeFlags.Unknown)) !== 0 || text === "{}" && !ts5.isTypeLiteralNode(annotation);
|
|
13120
|
+
const visit = (node2) => {
|
|
13121
|
+
if (ts5.isArrayTypeNode(node2) || ts5.isTupleTypeNode(node2) || ts5.isTypeReferenceNode(node2)) {
|
|
13122
|
+
const resolved = checker.getTypeFromTypeNode(node2);
|
|
13123
|
+
const rendered = checker.typeToString(resolved, node2, format);
|
|
13124
|
+
if ((resolved.flags & (ts5.TypeFlags.Any | ts5.TypeFlags.Unknown)) !== 0 || ts5.isArrayTypeNode(node2) && rendered === "{}")
|
|
13125
|
+
incomplete = true;
|
|
13126
|
+
}
|
|
13127
|
+
ts5.forEachChild(node2, visit);
|
|
13128
|
+
};
|
|
13129
|
+
visit(annotation);
|
|
13130
|
+
return { text: incomplete ? annotation.getText() : text, complete: !incomplete };
|
|
13131
|
+
}
|
|
13132
|
+
function callable(node2) {
|
|
13133
|
+
if (ts5.isFunctionDeclaration(node2))
|
|
13134
|
+
return node2;
|
|
13135
|
+
if (!ts5.isVariableDeclaration(node2))
|
|
13136
|
+
return;
|
|
13137
|
+
let value = node2.initializer;
|
|
13138
|
+
if (value !== undefined && ts5.isCallExpression(value)) {
|
|
13139
|
+
value = value.arguments.find((argument) => ts5.isArrowFunction(argument) || ts5.isFunctionExpression(argument));
|
|
13140
|
+
}
|
|
13141
|
+
return value !== undefined && (ts5.isArrowFunction(value) || ts5.isFunctionExpression(value)) ? value : undefined;
|
|
13142
|
+
}
|
|
13143
|
+
async function enrichPublicContracts(input) {
|
|
13144
|
+
const sources = new Map;
|
|
13145
|
+
for (const path2 of input.paths) {
|
|
13146
|
+
const source = await input.fs.readFile(path2);
|
|
13147
|
+
const absolute = posix3.resolve("/", path2);
|
|
13148
|
+
sources.set(absolute, ts5.createSourceFile(absolute, source, ts5.ScriptTarget.Latest, true));
|
|
13149
|
+
}
|
|
13150
|
+
const options = {
|
|
13151
|
+
noLib: true,
|
|
13152
|
+
skipLibCheck: true,
|
|
13153
|
+
allowJs: true,
|
|
13154
|
+
jsx: ts5.JsxEmit.Preserve,
|
|
13155
|
+
moduleResolution: ts5.ModuleResolutionKind.Node10,
|
|
13156
|
+
baseUrl: "/",
|
|
13157
|
+
paths: Object.fromEntries((input.resolver?.mappings ?? []).map((mapping) => [mapping.pattern, mapping.targets.map((target) => posix3.resolve("/", target))]))
|
|
13158
|
+
};
|
|
13159
|
+
const host = {
|
|
13160
|
+
getSourceFile: (path2) => sources.get(posix3.resolve("/", path2)),
|
|
13161
|
+
getDefaultLibFileName: () => "",
|
|
13162
|
+
writeFile: () => {},
|
|
13163
|
+
getCurrentDirectory: () => "/",
|
|
13164
|
+
getDirectories: () => [],
|
|
13165
|
+
fileExists: (path2) => sources.has(posix3.resolve("/", path2)),
|
|
13166
|
+
readFile: (path2) => sources.get(posix3.resolve("/", path2))?.text,
|
|
13167
|
+
getCanonicalFileName: (path2) => posix3.resolve("/", path2),
|
|
13168
|
+
useCaseSensitiveFileNames: () => true,
|
|
13169
|
+
getNewLine: () => `
|
|
13170
|
+
`
|
|
13171
|
+
};
|
|
13172
|
+
for (const source of sources.values())
|
|
13173
|
+
input.symbols.push(...runtimeRegistrations(source), ...federationContracts(source));
|
|
13174
|
+
if (!input.symbols.some((symbol) => symbol.visibility === "exported" /* Exported */))
|
|
13175
|
+
return;
|
|
13176
|
+
const program = ts5.createProgram([...sources.keys()], options, host);
|
|
13177
|
+
const checker = program.getTypeChecker();
|
|
13178
|
+
const diagnosticsByFile = new Map;
|
|
13179
|
+
for (const symbol of input.symbols) {
|
|
13180
|
+
if (symbol.visibility !== "exported" /* Exported */)
|
|
13181
|
+
continue;
|
|
13182
|
+
const source = sources.get(posix3.resolve("/", symbol.file));
|
|
13183
|
+
if (source === undefined)
|
|
13184
|
+
continue;
|
|
13185
|
+
const declaration = declarationAt(source, symbol);
|
|
13186
|
+
if (declaration === undefined)
|
|
13187
|
+
continue;
|
|
13188
|
+
symbol.contractResolution = "declaration-only";
|
|
13189
|
+
const fn = callable(declaration);
|
|
13190
|
+
if (fn !== undefined) {
|
|
13191
|
+
symbol.params = fn.parameters.map((parameter) => ({
|
|
13192
|
+
name: parameter.name.getText(source),
|
|
13193
|
+
type: parameter.type?.getText(source) ?? checker.typeToString(checker.getTypeAtLocation(parameter), parameter, format),
|
|
13194
|
+
optional: parameter.questionToken !== undefined || parameter.initializer !== undefined,
|
|
13195
|
+
rest: parameter.dotDotDotToken !== undefined,
|
|
13196
|
+
...parameter.initializer === undefined ? {} : { defaultValue: parameter.initializer.getText(source) }
|
|
13197
|
+
}));
|
|
13198
|
+
if (fn.typeParameters !== undefined)
|
|
13199
|
+
symbol.typeParameters = `<${fn.typeParameters.map((item) => item.getText(source)).join(", ")}>`;
|
|
13200
|
+
}
|
|
13201
|
+
const valueType = checker.getTypeAtLocation(declaration);
|
|
13202
|
+
const signatures = valueType.getCallSignatures();
|
|
13203
|
+
const declaredSignatures = signatures.flatMap((signature) => {
|
|
13204
|
+
const declared = signature.getDeclaration();
|
|
13205
|
+
if (declared === undefined || !sources.has(declared.getSourceFile().fileName))
|
|
13206
|
+
return [];
|
|
13207
|
+
const body = "body" in declared ? declared.body : undefined;
|
|
13208
|
+
return [declared.getSourceFile().text.slice(declared.getStart(), body?.pos ?? declared.getEnd()).trim().replace(/;$/u, "")];
|
|
13209
|
+
});
|
|
13210
|
+
if (declaredSignatures.length > 1)
|
|
13211
|
+
symbol.overloads = declaredSignatures;
|
|
13212
|
+
let contractType;
|
|
13213
|
+
let localProps;
|
|
13214
|
+
if (symbol.kind === "component" /* Component */) {
|
|
13215
|
+
const parameter = signatures[0]?.parameters[0];
|
|
13216
|
+
if (parameter !== undefined) {
|
|
13217
|
+
contractType = checker.getTypeOfSymbolAtLocation(parameter, declaration);
|
|
13218
|
+
symbol.propsType = checker.typeToString(contractType, declaration, format);
|
|
13219
|
+
}
|
|
13220
|
+
const annotation = fn?.parameters[0]?.type ?? (ts5.isVariableDeclaration(declaration) ? componentPropsNode(declaration.type) : undefined);
|
|
13221
|
+
if (annotation !== undefined) {
|
|
13222
|
+
contractType = checker.getTypeFromTypeNode(annotation);
|
|
13223
|
+
symbol.propsType = annotation.getText(source);
|
|
13224
|
+
localProps = componentLocalPropsNode(annotation, checker);
|
|
13225
|
+
}
|
|
13226
|
+
} else if (ts5.isInterfaceDeclaration(declaration) || ts5.isTypeAliasDeclaration(declaration)) {
|
|
13227
|
+
contractType = checker.getTypeAtLocation(declaration);
|
|
13228
|
+
}
|
|
13229
|
+
if (contractType === undefined)
|
|
13230
|
+
continue;
|
|
13231
|
+
const unresolved = (contractType.flags & (ts5.TypeFlags.Any | ts5.TypeFlags.Unknown)) !== 0;
|
|
13232
|
+
const localType = unresolved && localProps !== undefined ? checker.getTypeFromTypeNode(localProps) : undefined;
|
|
13233
|
+
const knownType = localType ?? contractType;
|
|
13234
|
+
const properties = (knownType.flags & (ts5.TypeFlags.Any | ts5.TypeFlags.Unknown)) !== 0 ? declaredObjectTypes(localProps ?? declaration, checker).flatMap((node2) => checker.getPropertiesOfType(checker.getTypeAtLocation(node2))) : checker.getPropertiesOfType(knownType);
|
|
13235
|
+
if (properties.length === 0)
|
|
13236
|
+
continue;
|
|
13237
|
+
if (symbol.kind === "component" /* Component */ && symbol.propsType !== undefined && input.relations !== undefined) {
|
|
13238
|
+
const typeSymbol = knownType.aliasSymbol ?? knownType.getSymbol();
|
|
13239
|
+
const declaration2 = typeSymbol?.declarations?.[0];
|
|
13240
|
+
if (typeSymbol !== undefined && declaration2 !== undefined)
|
|
13241
|
+
input.relations.push({ ...createRelation("of_type" /* OfType */, symbol.name, typeSymbol.name, !sources.has(declaration2.getSourceFile().fileName), symbol.line), file: symbol.file });
|
|
13242
|
+
}
|
|
13243
|
+
const pattern = fn?.parameters[0]?.name;
|
|
13244
|
+
const defaults = pattern === undefined ? {} : componentDefaultsFromBinding(pattern, source);
|
|
13245
|
+
const members = [];
|
|
13246
|
+
let completeMembers = true;
|
|
13247
|
+
for (const property of properties) {
|
|
13248
|
+
const member = property.valueDeclaration ?? property.declarations?.[0];
|
|
13249
|
+
if (member === undefined || !sources.has(member.getSourceFile().fileName))
|
|
13250
|
+
continue;
|
|
13251
|
+
const memberSource = member.getSourceFile();
|
|
13252
|
+
const modifiers = ts5.canHaveModifiers(member) ? ts5.getModifiers(member) : undefined;
|
|
13253
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(property, member);
|
|
13254
|
+
const annotation = "type" in member ? member.type : undefined;
|
|
13255
|
+
const documentedDefault = ts5.getJSDocTags(member).find((tag) => tag.tagName.text === "default" || tag.tagName.text === "defaultValue");
|
|
13256
|
+
const defaultComment = documentedDefault?.comment;
|
|
13257
|
+
const defaultText = typeof defaultComment === "string" ? defaultComment.trim() : defaultComment === undefined ? undefined : defaultComment.map((part) => part.getText(memberSource)).join("").trim();
|
|
13258
|
+
const defaultValue = (Object.hasOwn(defaults, property.name) ? defaults[property.name] : undefined) ?? (defaultText || undefined);
|
|
13259
|
+
const hidden = ts5.getJSDocTags(member).some((tag) => ["internal", "private"].includes(tag.tagName.text)) || modifiers?.some((modifier) => modifier.kind === ts5.SyntaxKind.PrivateKeyword || modifier.kind === ts5.SyntaxKind.ProtectedKeyword);
|
|
13260
|
+
if (hidden)
|
|
13261
|
+
continue;
|
|
13262
|
+
const renderedType = memberTypeText(checker, propertyType, member, annotation);
|
|
13263
|
+
completeMembers &&= renderedType.complete;
|
|
13264
|
+
members.push({
|
|
13265
|
+
name: property.name,
|
|
13266
|
+
kind: "prop" /* Prop */,
|
|
13267
|
+
visibility: "exported" /* Exported */,
|
|
13268
|
+
file: posix3.relative("/", memberSource.fileName),
|
|
13269
|
+
line: memberSource.getLineAndCharacterOfPosition(member.getStart()).line + 1,
|
|
13270
|
+
endLine: memberSource.getLineAndCharacterOfPosition(member.getEnd()).line + 1,
|
|
13271
|
+
optional: (property.flags & ts5.SymbolFlags.Optional) !== 0,
|
|
13272
|
+
...defaultValue === undefined ? {} : { defaultValue },
|
|
13273
|
+
readonly: modifiers?.some((modifier) => modifier.kind === ts5.SyntaxKind.ReadonlyKeyword) ?? false,
|
|
13274
|
+
typeAnnotation: renderedType.text,
|
|
13275
|
+
doc: ts5.displayPartsToString(property.getDocumentationComment(checker))
|
|
13276
|
+
});
|
|
13277
|
+
}
|
|
13278
|
+
if (properties.length > 0) {
|
|
13279
|
+
symbol.members = members;
|
|
13280
|
+
let diagnostics = diagnosticsByFile.get(source.fileName);
|
|
13281
|
+
if (diagnostics === undefined) {
|
|
13282
|
+
diagnostics = program.getSemanticDiagnostics(source);
|
|
13283
|
+
diagnosticsByFile.set(source.fileName, diagnostics);
|
|
13284
|
+
}
|
|
13285
|
+
symbol.contractResolution = !unresolved && completeMembers && diagnostics.length === 0 ? "resolved" : "declaration-only";
|
|
13286
|
+
}
|
|
13287
|
+
}
|
|
13288
|
+
}
|
|
13289
|
+
|
|
13290
|
+
// ../extract/src/types.ts
|
|
13291
|
+
var symbolKindSchema2 = exports_external.enum(Object.values(SymbolKind));
|
|
13292
|
+
var visibilitySchema2 = exports_external.enum(Object.values(Visibility));
|
|
13293
|
+
var relationTypeSchema = exports_external.enum([
|
|
13294
|
+
"imports" /* Imports */,
|
|
13295
|
+
"imports_type" /* ImportsType */,
|
|
13296
|
+
"calls" /* Calls */,
|
|
13297
|
+
"extends" /* Extends */,
|
|
13298
|
+
"implements" /* Implements */,
|
|
13299
|
+
"param_type" /* ParamType */,
|
|
13300
|
+
"return_type" /* ReturnType */,
|
|
13301
|
+
"of_type" /* OfType */,
|
|
13302
|
+
"depends_on" /* DependsOn */,
|
|
13303
|
+
"contains" /* Contains */
|
|
13304
|
+
]);
|
|
13305
|
+
var relationSourceSchema = exports_external.enum([
|
|
13306
|
+
"ast" /* Ast */,
|
|
13307
|
+
"doc" /* Doc */,
|
|
13308
|
+
"manual" /* Manual */
|
|
13309
|
+
]);
|
|
13310
|
+
var packageKindSchema2 = exports_external.enum(Object.values(PackageKind));
|
|
13311
|
+
var symbolParamSchema = exports_external.object({
|
|
13312
|
+
name: exports_external.string().min(1),
|
|
13313
|
+
type: exports_external.string().min(1).nullable(),
|
|
13314
|
+
optional: exports_external.boolean().optional(),
|
|
13315
|
+
rest: exports_external.boolean().optional(),
|
|
13316
|
+
defaultValue: exports_external.string().optional()
|
|
13317
|
+
});
|
|
13318
|
+
var registrationSchema = exports_external.object({
|
|
13319
|
+
kind: exports_external.enum(["http", "schedule", "event"]),
|
|
13320
|
+
key: exports_external.string(),
|
|
13321
|
+
handler: exports_external.string(),
|
|
13322
|
+
method: exports_external.string().optional(),
|
|
13323
|
+
middleware: exports_external.array(exports_external.string())
|
|
13324
|
+
});
|
|
13325
|
+
var symbolInfoSchema = exports_external.lazy(() => exports_external.object({
|
|
13326
|
+
name: exports_external.string().min(1),
|
|
13327
|
+
kind: symbolKindSchema2,
|
|
13328
|
+
visibility: visibilitySchema2,
|
|
13329
|
+
file: exports_external.string().min(1),
|
|
13330
|
+
line: exports_external.number().int().positive(),
|
|
13331
|
+
endLine: exports_external.number().int().positive(),
|
|
13332
|
+
members: exports_external.array(symbolInfoSchema).optional(),
|
|
13333
|
+
params: exports_external.array(symbolParamSchema).optional(),
|
|
13334
|
+
optional: exports_external.boolean().optional(),
|
|
13335
|
+
readonly: exports_external.boolean().optional(),
|
|
13336
|
+
defaultValue: exports_external.string().optional(),
|
|
13337
|
+
typeParameters: exports_external.string().optional(),
|
|
13338
|
+
overloads: exports_external.array(exports_external.string()).optional(),
|
|
13339
|
+
publicEntrypoints: exports_external.array(exports_external.string()).optional(),
|
|
13340
|
+
contractResolution: exports_external.enum(["resolved", "declaration-only"]).optional(),
|
|
13341
|
+
registration: registrationSchema.optional(),
|
|
13342
|
+
returnType: exports_external.string().min(1).nullable().optional(),
|
|
13343
|
+
typeAnnotation: exports_external.string().min(1).nullable().optional(),
|
|
13344
|
+
extends: exports_external.string().min(1).nullable().optional(),
|
|
13345
|
+
implements: exports_external.array(exports_external.string().min(1)).optional(),
|
|
13346
|
+
doc: exports_external.string().nullable().optional(),
|
|
13347
|
+
propsType: exports_external.string().min(1).nullable().optional(),
|
|
13348
|
+
unionValues: exports_external.array(exports_external.string()).optional(),
|
|
13349
|
+
initializer: exports_external.string().min(1).nullable().optional(),
|
|
13350
|
+
signature: exports_external.string().min(1).nullable().optional()
|
|
13351
|
+
}));
|
|
13352
|
+
var relationInfoSchema = exports_external.object({
|
|
13353
|
+
type: relationTypeSchema,
|
|
13354
|
+
from: exports_external.string().min(1),
|
|
13355
|
+
to: exports_external.string().min(1),
|
|
13356
|
+
file: exports_external.string().min(1).optional(),
|
|
13357
|
+
isExternal: exports_external.boolean(),
|
|
13358
|
+
grounding: groundingSchema,
|
|
13359
|
+
confidence: exports_external.number().min(0).max(1),
|
|
13360
|
+
source: relationSourceSchema,
|
|
13361
|
+
line: exports_external.number().int().positive().optional()
|
|
13362
|
+
});
|
|
13363
|
+
var fileInfoSchema = exports_external.object({
|
|
13364
|
+
path: exports_external.string().min(1),
|
|
13365
|
+
language: exports_external.string().min(1),
|
|
13366
|
+
lines: exports_external.number().int().nonnegative()
|
|
13367
|
+
});
|
|
13368
|
+
var extractionDiagnosticSchema = exports_external.object({
|
|
13369
|
+
code: exports_external.string().min(1),
|
|
13370
|
+
severity: exports_external.enum(["info", "warning", "error"]),
|
|
13371
|
+
file: exports_external.string().min(1),
|
|
13372
|
+
line: exports_external.number().int().positive(),
|
|
13373
|
+
column: exports_external.number().int().positive()
|
|
13374
|
+
});
|
|
13375
|
+
var extractionCoverageSchema = exports_external.object({
|
|
13376
|
+
tier: exports_external.enum(["ast-catalog", "lightweight-evidence"]),
|
|
13377
|
+
capabilities: exports_external.array(exports_external.string().min(1)),
|
|
13378
|
+
files: exports_external.array(exports_external.object({
|
|
13379
|
+
path: exports_external.string().min(1),
|
|
13380
|
+
disposition: exports_external.enum(["analyzed", "unsupported", "excluded"]),
|
|
13381
|
+
diagnosticCodes: exports_external.array(exports_external.string().min(1))
|
|
13382
|
+
})),
|
|
13383
|
+
diagnostics: exports_external.array(extractionDiagnosticSchema)
|
|
13384
|
+
});
|
|
13385
|
+
var extractionMetaSchema = exports_external.object({
|
|
13386
|
+
extractedAt: exports_external.string().datetime(),
|
|
13387
|
+
pluginId: exports_external.string().min(1),
|
|
13388
|
+
commitHash: exports_external.string().min(1).nullable(),
|
|
13389
|
+
language: exports_external.string().min(1)
|
|
13390
|
+
});
|
|
13391
|
+
var extractionPackageSchema = exports_external.object({
|
|
13392
|
+
name: exports_external.string().min(1),
|
|
13393
|
+
kind: packageKindSchema2,
|
|
13394
|
+
language: exports_external.string().min(1),
|
|
13395
|
+
version: exports_external.string().min(1).optional()
|
|
13396
|
+
});
|
|
13397
|
+
var extractionStatsSchema = exports_external.object({
|
|
13398
|
+
files: exports_external.number().int().nonnegative(),
|
|
13399
|
+
lines: exports_external.number().int().nonnegative(),
|
|
13400
|
+
exportedSymbols: exports_external.number().int().nonnegative(),
|
|
13401
|
+
internalSymbols: exports_external.number().int().nonnegative(),
|
|
13402
|
+
relations: exports_external.number().int().nonnegative()
|
|
13403
|
+
});
|
|
13404
|
+
var extractionResultSchema = exports_external.object({
|
|
13405
|
+
version: exports_external.literal("2"),
|
|
13406
|
+
meta: extractionMetaSchema,
|
|
13407
|
+
package: extractionPackageSchema,
|
|
13408
|
+
files: exports_external.array(fileInfoSchema),
|
|
13409
|
+
symbols: exports_external.array(symbolInfoSchema),
|
|
13410
|
+
relations: exports_external.array(relationInfoSchema),
|
|
13411
|
+
coverage: extractionCoverageSchema.optional(),
|
|
13412
|
+
stats: extractionStatsSchema
|
|
13413
|
+
});
|
|
13414
|
+
var digestStatsSchema = exports_external.object({
|
|
13415
|
+
files: exports_external.number().int().nonnegative(),
|
|
13416
|
+
lines: exports_external.number().int().nonnegative(),
|
|
13417
|
+
exported_count: exports_external.number().int().nonnegative(),
|
|
13418
|
+
internal_count: exports_external.number().int().nonnegative(),
|
|
13419
|
+
relations: exports_external.number().int().nonnegative()
|
|
13420
|
+
});
|
|
13421
|
+
var digestDataSchema = exports_external.object({
|
|
13422
|
+
version: exports_external.literal("2"),
|
|
13423
|
+
meta: extractionMetaSchema,
|
|
13424
|
+
package: extractionPackageSchema,
|
|
13425
|
+
files: exports_external.array(fileInfoSchema),
|
|
13426
|
+
symbols: exports_external.array(symbolInfoSchema),
|
|
13427
|
+
relations: exports_external.array(relationInfoSchema),
|
|
13428
|
+
coverage: extractionCoverageSchema.optional(),
|
|
13429
|
+
stats: digestStatsSchema
|
|
13430
|
+
});
|
|
13431
|
+
var symbolDiffSchema = exports_external.object({
|
|
13432
|
+
added: exports_external.array(exports_external.string().min(1)),
|
|
13433
|
+
removed: exports_external.array(exports_external.string().min(1))
|
|
13434
|
+
});
|
|
13435
|
+
// ../extract/src/protocol.ts
|
|
13436
|
+
var packageKindSchema3 = exports_external.enum(Object.values(PackageKind));
|
|
13437
|
+
var manifestTypeSchema = exports_external.enum([
|
|
13438
|
+
"package.json",
|
|
13439
|
+
"pyproject.toml",
|
|
13440
|
+
"Cargo.toml",
|
|
13441
|
+
"go.mod",
|
|
13442
|
+
"pom.xml"
|
|
13443
|
+
]);
|
|
13444
|
+
var entryFileSchema = exports_external.object({
|
|
13445
|
+
path: exports_external.string().min(1),
|
|
13446
|
+
subpath: exports_external.string().min(1),
|
|
13447
|
+
type: exports_external.enum(["library", "cli", "service", "webapp"])
|
|
13448
|
+
});
|
|
13449
|
+
var manifestInfoSchema = exports_external.object({
|
|
13450
|
+
type: manifestTypeSchema,
|
|
13451
|
+
path: exports_external.string().min(1),
|
|
13452
|
+
content: exports_external.record(exports_external.unknown())
|
|
13453
|
+
});
|
|
13454
|
+
var sourceInfoSchema = exports_external.object({
|
|
13455
|
+
path: exports_external.string().min(1),
|
|
13456
|
+
manifests: exports_external.array(manifestInfoSchema),
|
|
13457
|
+
language: exports_external.string().min(1).optional()
|
|
13458
|
+
});
|
|
13459
|
+
var entryDetectionResultSchema = exports_external.lazy(() => exports_external.object({
|
|
13460
|
+
package: exports_external.object({
|
|
13461
|
+
name: exports_external.string().min(1),
|
|
13462
|
+
kind: packageKindSchema3,
|
|
13463
|
+
language: exports_external.string().min(1),
|
|
13464
|
+
version: exports_external.string().min(1).optional()
|
|
13465
|
+
}),
|
|
13466
|
+
entries: exports_external.array(entryFileSchema),
|
|
13467
|
+
subPackages: exports_external.array(entryDetectionResultSchema).optional()
|
|
13468
|
+
}));
|
|
13469
|
+
var patternDetectionResultSchema = exports_external.object({
|
|
13470
|
+
endpoints: exports_external.array(exports_external.object({
|
|
13471
|
+
handler: exports_external.string().min(1),
|
|
13472
|
+
method: exports_external.string().min(1),
|
|
13473
|
+
path: exports_external.string().min(1),
|
|
13474
|
+
file: exports_external.string().min(1),
|
|
13475
|
+
line: exports_external.number().int().positive()
|
|
13476
|
+
})).optional(),
|
|
13477
|
+
implicitDeps: exports_external.array(exports_external.object({
|
|
13478
|
+
verb: exports_external.enum(["produce", "consume", "depends_on", "serve"]),
|
|
13479
|
+
target: exports_external.string().min(1),
|
|
13480
|
+
file: exports_external.string().min(1),
|
|
13481
|
+
line: exports_external.number().int().positive()
|
|
13482
|
+
})).optional(),
|
|
13483
|
+
configRefs: exports_external.array(exports_external.object({
|
|
13484
|
+
key: exports_external.string().min(1),
|
|
13485
|
+
file: exports_external.string().min(1),
|
|
13486
|
+
line: exports_external.number().int().positive()
|
|
13487
|
+
})).optional()
|
|
13488
|
+
});
|
|
13489
|
+
// ../extract/src/registry.ts
|
|
13490
|
+
var MANIFEST_LANGUAGE_CANDIDATES = {
|
|
13491
|
+
"package.json": ["typescript", "tsx", "javascript", "jsx"],
|
|
13492
|
+
"pyproject.toml": ["python"],
|
|
13493
|
+
"Cargo.toml": ["rust"],
|
|
13494
|
+
"go.mod": ["go"],
|
|
13495
|
+
"pom.xml": ["java"]
|
|
13496
|
+
};
|
|
13497
|
+
|
|
13498
|
+
class ExtractionPluginRegistry {
|
|
13499
|
+
#plugins = [];
|
|
13500
|
+
register(plugin) {
|
|
13501
|
+
this.#plugins.push(plugin);
|
|
13502
|
+
}
|
|
13503
|
+
resolve(source) {
|
|
13504
|
+
const declaredLanguage = source.language?.toLowerCase();
|
|
13505
|
+
const manifestLanguages = new Set(source.manifests.flatMap((manifest) => MANIFEST_LANGUAGE_CANDIDATES[manifest.type] ?? []));
|
|
13506
|
+
const candidates = this.#plugins.filter((plugin) => {
|
|
13507
|
+
const pluginLanguages = plugin.languages.map((language) => language.toLowerCase());
|
|
13508
|
+
if (declaredLanguage) {
|
|
13509
|
+
return pluginLanguages.includes(declaredLanguage);
|
|
13510
|
+
}
|
|
13511
|
+
if (manifestLanguages.size === 0) {
|
|
13512
|
+
return true;
|
|
13513
|
+
}
|
|
13514
|
+
return pluginLanguages.some((language) => manifestLanguages.has(language));
|
|
13515
|
+
});
|
|
13516
|
+
for (const plugin of candidates) {
|
|
13517
|
+
if (plugin.canHandle(source)) {
|
|
13518
|
+
return plugin;
|
|
13519
|
+
}
|
|
13520
|
+
}
|
|
13521
|
+
return null;
|
|
13522
|
+
}
|
|
13523
|
+
list() {
|
|
13524
|
+
return [...this.#plugins];
|
|
13525
|
+
}
|
|
13526
|
+
}
|
|
13527
|
+
// ../extract/src/scanner.ts
|
|
13528
|
+
import { execFile } from "node:child_process";
|
|
13529
|
+
import { promisify } from "node:util";
|
|
13530
|
+
var execFileAsync = promisify(execFile);
|
|
13531
|
+
var SUPPORTED_EXTENSIONS = new Set([
|
|
13532
|
+
".ts",
|
|
13533
|
+
".tsx",
|
|
13534
|
+
".mts",
|
|
13535
|
+
".cts",
|
|
13536
|
+
".js",
|
|
13537
|
+
".jsx",
|
|
13538
|
+
".mjs",
|
|
13539
|
+
".cjs"
|
|
13540
|
+
]);
|
|
12767
13541
|
var MANIFEST_FILES = [
|
|
12768
13542
|
"package.json",
|
|
12769
13543
|
"pyproject.toml",
|
|
@@ -12860,6 +13634,8 @@ function semanticExtractionPayload(extraction) {
|
|
|
12860
13634
|
};
|
|
12861
13635
|
}
|
|
12862
13636
|
function relationSourceFile(relation, symbols, filePaths) {
|
|
13637
|
+
if (relation.file !== undefined)
|
|
13638
|
+
return filePaths.has(relation.file) ? relation.file : null;
|
|
12863
13639
|
if (filePaths.has(relation.from))
|
|
12864
13640
|
return relation.from;
|
|
12865
13641
|
const candidates = symbols.filter((symbol) => symbol.name === relation.from);
|
|
@@ -13700,27 +14476,29 @@ var parseFile = async (source, isTsx) => {
|
|
|
13700
14476
|
}
|
|
13701
14477
|
};
|
|
13702
14478
|
// src/commonJsModule.ts
|
|
13703
|
-
import
|
|
14479
|
+
import ts7 from "typescript";
|
|
13704
14480
|
|
|
13705
14481
|
// src/typescriptAst.ts
|
|
13706
|
-
import
|
|
14482
|
+
import ts6 from "typescript";
|
|
13707
14483
|
var scriptKind = (filePath) => {
|
|
13708
14484
|
const lower = filePath.toLowerCase();
|
|
13709
14485
|
if (lower.endsWith(".tsx"))
|
|
13710
|
-
return
|
|
14486
|
+
return ts6.ScriptKind.TSX;
|
|
13711
14487
|
if (lower.endsWith(".jsx"))
|
|
13712
|
-
return
|
|
14488
|
+
return ts6.ScriptKind.JSX;
|
|
13713
14489
|
if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs")) {
|
|
13714
|
-
return
|
|
14490
|
+
return ts6.ScriptKind.JS;
|
|
13715
14491
|
}
|
|
13716
|
-
return
|
|
14492
|
+
return ts6.ScriptKind.TS;
|
|
13717
14493
|
};
|
|
13718
|
-
var createEcmaScriptSourceFile = (source, filePath) =>
|
|
14494
|
+
var createEcmaScriptSourceFile = (source, filePath) => ts6.createSourceFile(filePath, source, ts6.ScriptTarget.Latest, true, scriptKind(filePath));
|
|
13719
14495
|
var treeSitterCompatibleJsxSource = (sourceFile, source) => {
|
|
14496
|
+
if (!source.includes("&"))
|
|
14497
|
+
return source;
|
|
13720
14498
|
const characters = source.split("");
|
|
13721
14499
|
let changed = false;
|
|
13722
14500
|
const visit2 = (node2) => {
|
|
13723
|
-
const jsxPresentationLiteral =
|
|
14501
|
+
const jsxPresentationLiteral = ts6.isJsxText(node2) || ts6.isStringLiteral(node2) && ts6.isJsxAttribute(node2.parent);
|
|
13724
14502
|
if (jsxPresentationLiteral) {
|
|
13725
14503
|
for (let index = node2.getStart(sourceFile);index < node2.getEnd(); index += 1) {
|
|
13726
14504
|
if (characters[index] === "&") {
|
|
@@ -13729,7 +14507,7 @@ var treeSitterCompatibleJsxSource = (sourceFile, source) => {
|
|
|
13729
14507
|
}
|
|
13730
14508
|
}
|
|
13731
14509
|
}
|
|
13732
|
-
|
|
14510
|
+
ts6.forEachChild(node2, visit2);
|
|
13733
14511
|
};
|
|
13734
14512
|
visit2(sourceFile);
|
|
13735
14513
|
return changed ? characters.join("") : source;
|
|
@@ -13760,25 +14538,25 @@ var nodeLocation = (sourceFile, node2) => {
|
|
|
13760
14538
|
var staticStringValue = (node2) => {
|
|
13761
14539
|
if (!node2)
|
|
13762
14540
|
return null;
|
|
13763
|
-
if (
|
|
14541
|
+
if (ts6.isStringLiteral(node2) || ts6.isNoSubstitutionTemplateLiteral(node2))
|
|
13764
14542
|
return node2.text;
|
|
13765
14543
|
return null;
|
|
13766
14544
|
};
|
|
13767
14545
|
|
|
13768
14546
|
// src/commonJsModule.ts
|
|
13769
|
-
var requireCall = (node2) =>
|
|
14547
|
+
var requireCall = (node2) => ts7.isCallExpression(node2) && ts7.isIdentifier(node2.expression) && node2.expression.text === "require" ? node2 : null;
|
|
13770
14548
|
var requireReference = (node2) => {
|
|
13771
14549
|
const direct = requireCall(node2);
|
|
13772
14550
|
if (direct) {
|
|
13773
14551
|
const source = staticStringValue(direct.arguments[0]);
|
|
13774
14552
|
return source ? { source, importedName: "*" } : null;
|
|
13775
14553
|
}
|
|
13776
|
-
if (
|
|
14554
|
+
if (ts7.isPropertyAccessExpression(node2)) {
|
|
13777
14555
|
const call = requireCall(node2.expression);
|
|
13778
14556
|
const source = call ? staticStringValue(call.arguments[0]) : null;
|
|
13779
14557
|
return source ? { source, importedName: node2.name.text } : null;
|
|
13780
14558
|
}
|
|
13781
|
-
if (
|
|
14559
|
+
if (ts7.isElementAccessExpression(node2)) {
|
|
13782
14560
|
const call = requireCall(node2.expression);
|
|
13783
14561
|
const source = call ? staticStringValue(call.arguments[0]) : null;
|
|
13784
14562
|
const importedName = staticStringValue(node2.argumentExpression);
|
|
@@ -13787,20 +14565,20 @@ var requireReference = (node2) => {
|
|
|
13787
14565
|
return null;
|
|
13788
14566
|
};
|
|
13789
14567
|
var isModuleExports = (node2) => {
|
|
13790
|
-
if (
|
|
14568
|
+
if (ts7.isPropertyAccessExpression(node2) && ts7.isIdentifier(node2.expression) && node2.expression.text === "module" && node2.name.text === "exports")
|
|
13791
14569
|
return true;
|
|
13792
|
-
return
|
|
14570
|
+
return ts7.isElementAccessExpression(node2) && ts7.isIdentifier(node2.expression) && node2.expression.text === "module" && staticStringValue(node2.argumentExpression) === "exports";
|
|
13793
14571
|
};
|
|
13794
|
-
var isExportsObject = (node2) =>
|
|
14572
|
+
var isExportsObject = (node2) => ts7.isIdentifier(node2) && node2.text === "exports" || isModuleExports(node2);
|
|
13795
14573
|
var isUnsupportedExportMutationCall = (node2) => {
|
|
13796
|
-
if (
|
|
14574
|
+
if (ts7.isPropertyAccessExpression(node2.expression) && ts7.isIdentifier(node2.expression.expression) && node2.expression.expression.text === "Object" && ["assign", "defineProperties", "defineProperty"].includes(node2.expression.name.text) && node2.arguments[0] && isExportsObject(node2.arguments[0])) {
|
|
13797
14575
|
return !(node2.expression.name.text === "defineProperty" && staticStringValue(node2.arguments[1]) === "__esModule");
|
|
13798
14576
|
}
|
|
13799
|
-
return
|
|
14577
|
+
return ts7.isIdentifier(node2.expression) && ["__createBinding", "__export", "__exportStar"].includes(node2.expression.text) && node2.arguments.some(isExportsObject);
|
|
13800
14578
|
};
|
|
13801
14579
|
var commonJsExportTarget = (node2) => {
|
|
13802
|
-
if (
|
|
13803
|
-
if (
|
|
14580
|
+
if (ts7.isPropertyAccessExpression(node2)) {
|
|
14581
|
+
if (ts7.isIdentifier(node2.expression) && node2.expression.text === "exports") {
|
|
13804
14582
|
return { kind: "named", exportedName: node2.name.text };
|
|
13805
14583
|
}
|
|
13806
14584
|
if (isModuleExports(node2.expression)) {
|
|
@@ -13809,9 +14587,9 @@ var commonJsExportTarget = (node2) => {
|
|
|
13809
14587
|
if (isModuleExports(node2))
|
|
13810
14588
|
return { kind: "whole" };
|
|
13811
14589
|
}
|
|
13812
|
-
if (
|
|
14590
|
+
if (ts7.isElementAccessExpression(node2)) {
|
|
13813
14591
|
const property = staticStringValue(node2.argumentExpression);
|
|
13814
|
-
if (
|
|
14592
|
+
if (ts7.isIdentifier(node2.expression) && node2.expression.text === "exports" && property) {
|
|
13815
14593
|
return { kind: "named", exportedName: property };
|
|
13816
14594
|
}
|
|
13817
14595
|
if (isModuleExports(node2.expression) && property) {
|
|
@@ -13823,7 +14601,7 @@ var commonJsExportTarget = (node2) => {
|
|
|
13823
14601
|
return null;
|
|
13824
14602
|
};
|
|
13825
14603
|
var localReference = (expression, bindings) => {
|
|
13826
|
-
if (
|
|
14604
|
+
if (ts7.isIdentifier(expression)) {
|
|
13827
14605
|
const binding = bindings.get(expression.text);
|
|
13828
14606
|
if (binding) {
|
|
13829
14607
|
return {
|
|
@@ -13833,7 +14611,7 @@ var localReference = (expression, bindings) => {
|
|
|
13833
14611
|
}
|
|
13834
14612
|
return { localName: expression.text };
|
|
13835
14613
|
}
|
|
13836
|
-
if (
|
|
14614
|
+
if (ts7.isPropertyAccessExpression(expression) && ts7.isIdentifier(expression.expression)) {
|
|
13837
14615
|
const binding = bindings.get(expression.expression.text);
|
|
13838
14616
|
if (binding)
|
|
13839
14617
|
return { source: binding.source, importedName: expression.name.text };
|
|
@@ -13843,7 +14621,7 @@ var localReference = (expression, bindings) => {
|
|
|
13843
14621
|
};
|
|
13844
14622
|
var syntheticDeclaration = (name, expression, sourceFile) => {
|
|
13845
14623
|
const location = nodeLocation(sourceFile, expression);
|
|
13846
|
-
if (
|
|
14624
|
+
if (ts7.isFunctionExpression(expression) || ts7.isArrowFunction(expression)) {
|
|
13847
14625
|
return {
|
|
13848
14626
|
name,
|
|
13849
14627
|
kind: "function",
|
|
@@ -13852,10 +14630,10 @@ var syntheticDeclaration = (name, expression, sourceFile) => {
|
|
|
13852
14630
|
params: expression.parameters.map((parameter) => parameter.name.getText(sourceFile))
|
|
13853
14631
|
};
|
|
13854
14632
|
}
|
|
13855
|
-
if (
|
|
14633
|
+
if (ts7.isClassExpression(expression)) {
|
|
13856
14634
|
return { name, kind: "class", line: location.line, endLine: location.endLine, params: [] };
|
|
13857
14635
|
}
|
|
13858
|
-
if (
|
|
14636
|
+
if (ts7.isObjectLiteralExpression(expression) || ts7.isArrayLiteralExpression(expression) || ts7.isLiteralExpression(expression)) {
|
|
13859
14637
|
return { name, kind: "variable", line: location.line, endLine: location.endLine, params: [] };
|
|
13860
14638
|
}
|
|
13861
14639
|
return null;
|
|
@@ -13889,13 +14667,13 @@ var appendUnsupportedExportDiagnostic = (result, sourceFile, node2) => {
|
|
|
13889
14667
|
var collectBindings = (sourceFile) => {
|
|
13890
14668
|
const bindings = [];
|
|
13891
14669
|
for (const statement of sourceFile.statements) {
|
|
13892
|
-
if (!
|
|
14670
|
+
if (!ts7.isVariableStatement(statement))
|
|
13893
14671
|
continue;
|
|
13894
14672
|
for (const declaration of statement.declarationList.declarations) {
|
|
13895
14673
|
if (!declaration.initializer)
|
|
13896
14674
|
continue;
|
|
13897
14675
|
const line = nodeLocation(sourceFile, declaration).line;
|
|
13898
|
-
if (
|
|
14676
|
+
if (ts7.isIdentifier(declaration.name)) {
|
|
13899
14677
|
const reference = requireReference(declaration.initializer);
|
|
13900
14678
|
if (reference)
|
|
13901
14679
|
bindings.push({ localName: declaration.name.text, ...reference, line });
|
|
@@ -13903,10 +14681,10 @@ var collectBindings = (sourceFile) => {
|
|
|
13903
14681
|
}
|
|
13904
14682
|
const direct = requireCall(declaration.initializer);
|
|
13905
14683
|
const source = direct ? staticStringValue(direct.arguments[0]) : null;
|
|
13906
|
-
if (!source || !
|
|
14684
|
+
if (!source || !ts7.isObjectBindingPattern(declaration.name))
|
|
13907
14685
|
continue;
|
|
13908
14686
|
for (const element of declaration.name.elements) {
|
|
13909
|
-
if (!
|
|
14687
|
+
if (!ts7.isIdentifier(element.name))
|
|
13910
14688
|
continue;
|
|
13911
14689
|
const importedName = element.propertyName?.getText(sourceFile) ?? element.name.text;
|
|
13912
14690
|
bindings.push({ localName: element.name.text, source, importedName, line });
|
|
@@ -13918,7 +14696,7 @@ var collectBindings = (sourceFile) => {
|
|
|
13918
14696
|
var collectDynamicDiagnostics = (sourceFile) => {
|
|
13919
14697
|
const diagnostics = [];
|
|
13920
14698
|
const visit2 = (node2) => {
|
|
13921
|
-
if (
|
|
14699
|
+
if (ts7.isCallExpression(node2) && ts7.isIdentifier(node2.expression) && node2.expression.text === "require") {
|
|
13922
14700
|
if (staticStringValue(node2.arguments[0]) === null) {
|
|
13923
14701
|
const location = nodeLocation(sourceFile, node2);
|
|
13924
14702
|
diagnostics.push({
|
|
@@ -13930,7 +14708,7 @@ var collectDynamicDiagnostics = (sourceFile) => {
|
|
|
13930
14708
|
});
|
|
13931
14709
|
}
|
|
13932
14710
|
}
|
|
13933
|
-
if (
|
|
14711
|
+
if (ts7.isCallExpression(node2) && isUnsupportedExportMutationCall(node2)) {
|
|
13934
14712
|
const location = nodeLocation(sourceFile, node2);
|
|
13935
14713
|
diagnostics.push({
|
|
13936
14714
|
code: "unsupported-commonjs-export-form",
|
|
@@ -13940,9 +14718,9 @@ var collectDynamicDiagnostics = (sourceFile) => {
|
|
|
13940
14718
|
column: location.column
|
|
13941
14719
|
});
|
|
13942
14720
|
}
|
|
13943
|
-
if (
|
|
13944
|
-
if (
|
|
13945
|
-
const isCommonJsTarget =
|
|
14721
|
+
if (ts7.isBinaryExpression(node2) && node2.operatorToken.kind === ts7.SyntaxKind.EqualsToken) {
|
|
14722
|
+
if (ts7.isElementAccessExpression(node2.left)) {
|
|
14723
|
+
const isCommonJsTarget = ts7.isIdentifier(node2.left.expression) && node2.left.expression.text === "exports" || isModuleExports(node2.left.expression) || isModuleExports(node2.left);
|
|
13946
14724
|
if (isCommonJsTarget && commonJsExportTarget(node2.left) === null) {
|
|
13947
14725
|
const location = nodeLocation(sourceFile, node2.left);
|
|
13948
14726
|
diagnostics.push({
|
|
@@ -13955,13 +14733,12 @@ var collectDynamicDiagnostics = (sourceFile) => {
|
|
|
13955
14733
|
}
|
|
13956
14734
|
}
|
|
13957
14735
|
}
|
|
13958
|
-
|
|
14736
|
+
ts7.forEachChild(node2, visit2);
|
|
13959
14737
|
};
|
|
13960
14738
|
visit2(sourceFile);
|
|
13961
14739
|
return diagnostics;
|
|
13962
14740
|
};
|
|
13963
|
-
var analyzeCommonJsModule = (source, filePath) => {
|
|
13964
|
-
const sourceFile = createEcmaScriptSourceFile(source, filePath);
|
|
14741
|
+
var analyzeCommonJsModule = (source, filePath, sourceFile = createEcmaScriptSourceFile(source, filePath)) => {
|
|
13965
14742
|
const bindings = collectBindings(sourceFile);
|
|
13966
14743
|
const bindingMap = new Map(bindings.map((binding) => [binding.localName, binding]));
|
|
13967
14744
|
const result = {
|
|
@@ -13972,10 +14749,10 @@ var analyzeCommonJsModule = (source, filePath) => {
|
|
|
13972
14749
|
diagnostics: collectDynamicDiagnostics(sourceFile)
|
|
13973
14750
|
};
|
|
13974
14751
|
for (const statement of sourceFile.statements) {
|
|
13975
|
-
if (!
|
|
14752
|
+
if (!ts7.isExpressionStatement(statement) || !ts7.isBinaryExpression(statement.expression))
|
|
13976
14753
|
continue;
|
|
13977
14754
|
const assignment = statement.expression;
|
|
13978
|
-
if (assignment.operatorToken.kind !==
|
|
14755
|
+
if (assignment.operatorToken.kind !== ts7.SyntaxKind.EqualsToken)
|
|
13979
14756
|
continue;
|
|
13980
14757
|
const target = commonJsExportTarget(assignment.left);
|
|
13981
14758
|
if (!target)
|
|
@@ -13992,14 +14769,14 @@ var analyzeCommonJsModule = (source, filePath) => {
|
|
|
13992
14769
|
result.wildcardSources.push(directRequire.source);
|
|
13993
14770
|
continue;
|
|
13994
14771
|
}
|
|
13995
|
-
if (
|
|
14772
|
+
if (ts7.isObjectLiteralExpression(assignment.right)) {
|
|
13996
14773
|
for (const property of assignment.right.properties) {
|
|
13997
|
-
if (
|
|
14774
|
+
if (ts7.isShorthandPropertyAssignment(property)) {
|
|
13998
14775
|
pushExport(result, property.name.text, property.name, line, bindingMap, sourceFile);
|
|
13999
14776
|
continue;
|
|
14000
14777
|
}
|
|
14001
|
-
if (
|
|
14002
|
-
const name = property.name && (
|
|
14778
|
+
if (ts7.isPropertyAssignment(property)) {
|
|
14779
|
+
const name = property.name && (ts7.isIdentifier(property.name) || ts7.isStringLiteral(property.name)) ? property.name.text : null;
|
|
14003
14780
|
if (name) {
|
|
14004
14781
|
if (!pushExport(result, name, property.initializer, line, bindingMap, sourceFile)) {
|
|
14005
14782
|
appendUnsupportedExportDiagnostic(result, sourceFile, property.initializer);
|
|
@@ -14009,7 +14786,7 @@ var analyzeCommonJsModule = (source, filePath) => {
|
|
|
14009
14786
|
}
|
|
14010
14787
|
continue;
|
|
14011
14788
|
}
|
|
14012
|
-
if (
|
|
14789
|
+
if (ts7.isMethodDeclaration(property) && property.name && ts7.isIdentifier(property.name)) {
|
|
14013
14790
|
const location = nodeLocation(sourceFile, property);
|
|
14014
14791
|
result.syntheticDeclarations.push({
|
|
14015
14792
|
name: property.name.text,
|
|
@@ -14029,290 +14806,52 @@ var analyzeCommonJsModule = (source, filePath) => {
|
|
|
14029
14806
|
}
|
|
14030
14807
|
continue;
|
|
14031
14808
|
}
|
|
14032
|
-
if (
|
|
14809
|
+
if (ts7.isIdentifier(assignment.right)) {
|
|
14033
14810
|
const binding = bindingMap.get(assignment.right.text);
|
|
14034
14811
|
if (binding?.importedName === "*") {
|
|
14035
14812
|
result.wildcardSources.push(binding.source);
|
|
14036
14813
|
continue;
|
|
14037
14814
|
}
|
|
14038
|
-
if (!pushExport(result, assignment.right.text, assignment.right, line, bindingMap, sourceFile)) {
|
|
14039
|
-
appendUnsupportedExportDiagnostic(result, sourceFile, assignment.right);
|
|
14040
|
-
}
|
|
14041
|
-
continue;
|
|
14042
|
-
}
|
|
14043
|
-
if (!pushExport(result, "default", assignment.right, line, bindingMap, sourceFile)) {
|
|
14044
|
-
appendUnsupportedExportDiagnostic(result, sourceFile, assignment.right);
|
|
14045
|
-
}
|
|
14046
|
-
}
|
|
14047
|
-
result.bindings.sort((left, right) => left.localName.localeCompare(right.localName));
|
|
14048
|
-
result.exports.sort((left, right) => left.exportedName.localeCompare(right.exportedName) || left.line - right.line);
|
|
14049
|
-
result.wildcardSources = [...new Set(result.wildcardSources)].sort();
|
|
14050
|
-
result.syntheticDeclarations.sort((left, right) => left.name.localeCompare(right.name));
|
|
14051
|
-
result.diagnostics.sort((left, right) => left.line - right.line || left.column - right.column);
|
|
14052
|
-
return result;
|
|
14053
|
-
};
|
|
14054
|
-
|
|
14055
|
-
// src/commonJsExportTrace.ts
|
|
14056
|
-
var traceCommonJsExports = async (input) => {
|
|
14057
|
-
const traced = [];
|
|
14058
|
-
for (const item of input.analysis.exports) {
|
|
14059
|
-
if (item.localName && input.localDeclarations.has(item.localName)) {
|
|
14060
|
-
traced.push({
|
|
14061
|
-
exportedName: item.exportedName,
|
|
14062
|
-
localName: item.localName,
|
|
14063
|
-
declarationFile: input.filePath
|
|
14064
|
-
});
|
|
14065
|
-
continue;
|
|
14066
|
-
}
|
|
14067
|
-
if (item.source && item.importedName) {
|
|
14068
|
-
traced.push(...await input.traceImported(item.source, item.importedName, item.exportedName));
|
|
14069
|
-
}
|
|
14070
|
-
}
|
|
14071
|
-
for (const source of input.analysis.wildcardSources) {
|
|
14072
|
-
traced.push(...await input.traceWildcard(source));
|
|
14073
|
-
}
|
|
14074
|
-
return traced;
|
|
14075
|
-
};
|
|
14076
|
-
|
|
14077
|
-
// src/exportTracer.ts
|
|
14078
|
-
var DECLARATION_TYPES = new Set([
|
|
14079
|
-
"function_declaration",
|
|
14080
|
-
"class_declaration",
|
|
14081
|
-
"interface_declaration",
|
|
14082
|
-
"type_alias_declaration",
|
|
14083
|
-
"enum_declaration",
|
|
14084
|
-
"lexical_declaration"
|
|
14085
|
-
]);
|
|
14086
|
-
var stripQuotes = (value) => value.replace(/^['"]/, "").replace(/['"]$/, "");
|
|
14087
|
-
var getDeclarationName = (node2) => {
|
|
14088
|
-
if (node2.type === "lexical_declaration") {
|
|
14089
|
-
return node2.namedChildren.filter((child) => child.type === "variable_declarator").map((child) => child.childForFieldName("name")?.text ?? child.namedChildren[0]?.text ?? "").filter(Boolean);
|
|
14090
|
-
}
|
|
14091
|
-
const nameNode = node2.childForFieldName("name") ?? node2.namedChildren.find((child) => child.type === "identifier" || child.type === "type_identifier");
|
|
14092
|
-
return nameNode?.text ? [nameNode.text] : [];
|
|
14093
|
-
};
|
|
14094
|
-
var collectLocalDeclarations = (root) => {
|
|
14095
|
-
const declarations = new Map;
|
|
14096
|
-
const register = (node2) => {
|
|
14097
|
-
for (const name of getDeclarationName(node2)) {
|
|
14098
|
-
if (!declarations.has(name)) {
|
|
14099
|
-
declarations.set(name, name);
|
|
14100
|
-
}
|
|
14101
|
-
}
|
|
14102
|
-
};
|
|
14103
|
-
for (const child of root.namedChildren) {
|
|
14104
|
-
if (DECLARATION_TYPES.has(child.type)) {
|
|
14105
|
-
register(child);
|
|
14106
|
-
continue;
|
|
14107
|
-
}
|
|
14108
|
-
if (child.type !== "export_statement")
|
|
14109
|
-
continue;
|
|
14110
|
-
const declaration = child.namedChildren.find((node2) => DECLARATION_TYPES.has(node2.type));
|
|
14111
|
-
if (declaration) {
|
|
14112
|
-
register(declaration);
|
|
14113
|
-
}
|
|
14114
|
-
}
|
|
14115
|
-
return declarations;
|
|
14116
|
-
};
|
|
14117
|
-
var parseExportSpecifier = (node2) => {
|
|
14118
|
-
const identifiers = node2.namedChildren.filter((child) => child.type === "identifier" || child.type === "type_identifier").map((child) => child.text);
|
|
14119
|
-
if (identifiers.length === 0)
|
|
14120
|
-
return null;
|
|
14121
|
-
const localName = identifiers[0];
|
|
14122
|
-
const exportedName = identifiers[1] ?? localName;
|
|
14123
|
-
return { localName, exportedName };
|
|
14124
|
-
};
|
|
14125
|
-
var parseImportSpecifier = (node2) => {
|
|
14126
|
-
const identifiers = node2.namedChildren.filter((child) => child.type === "identifier" || child.type === "type_identifier").map((child) => child.text);
|
|
14127
|
-
if (identifiers.length === 0)
|
|
14128
|
-
return null;
|
|
14129
|
-
const importedName = identifiers[0];
|
|
14130
|
-
const localName = identifiers[1] ?? importedName;
|
|
14131
|
-
return { importedName, localName };
|
|
14132
|
-
};
|
|
14133
|
-
var collectImportBindings = (root) => {
|
|
14134
|
-
const bindings = new Map;
|
|
14135
|
-
for (const node2 of root.namedChildren) {
|
|
14136
|
-
if (node2.type !== "import_statement")
|
|
14137
|
-
continue;
|
|
14138
|
-
const stringNode = node2.namedChildren.find((child) => child.type === "string");
|
|
14139
|
-
if (!stringNode)
|
|
14140
|
-
continue;
|
|
14141
|
-
const source = stripQuotes(stringNode.text);
|
|
14142
|
-
const clause = node2.namedChildren.find((child) => child.type === "import_clause");
|
|
14143
|
-
for (const part of clause?.namedChildren ?? []) {
|
|
14144
|
-
if (part.type === "identifier") {
|
|
14145
|
-
bindings.set(part.text, { source, importedName: "default" });
|
|
14146
|
-
continue;
|
|
14147
|
-
}
|
|
14148
|
-
if (part.type !== "named_imports")
|
|
14149
|
-
continue;
|
|
14150
|
-
for (const specifier of part.namedChildren.filter((child) => child.type === "import_specifier")) {
|
|
14151
|
-
const parsed = parseImportSpecifier(specifier);
|
|
14152
|
-
if (parsed) {
|
|
14153
|
-
bindings.set(parsed.localName, { source, importedName: parsed.importedName });
|
|
14154
|
-
}
|
|
14155
|
-
}
|
|
14156
|
-
}
|
|
14157
|
-
}
|
|
14158
|
-
return bindings;
|
|
14159
|
-
};
|
|
14160
|
-
var uniqueExports = (exportsList) => {
|
|
14161
|
-
const seen = new Set;
|
|
14162
|
-
return exportsList.filter((item) => {
|
|
14163
|
-
const key = `${item.declarationFile}::${item.localName}::${item.exportedName}`;
|
|
14164
|
-
if (seen.has(key))
|
|
14165
|
-
return false;
|
|
14166
|
-
seen.add(key);
|
|
14167
|
-
return true;
|
|
14168
|
-
});
|
|
14169
|
-
};
|
|
14170
|
-
var traceImportedBinding = async (filePath, binding, exportedName, fs, state) => {
|
|
14171
|
-
const targetPath = await resolveImportSourcePath(filePath, binding.source, fs, state.resolver);
|
|
14172
|
-
if (!targetPath)
|
|
14173
|
-
return [];
|
|
14174
|
-
const traced = await traceFile(targetPath, fs, state);
|
|
14175
|
-
const match = traced.find((item) => item.exportedName === binding.importedName || binding.importedName === "default" && item.exportedName === item.localName);
|
|
14176
|
-
if (!match)
|
|
14177
|
-
return [];
|
|
14178
|
-
return [{
|
|
14179
|
-
exportedName,
|
|
14180
|
-
localName: match.localName,
|
|
14181
|
-
declarationFile: match.declarationFile
|
|
14182
|
-
}];
|
|
14183
|
-
};
|
|
14184
|
-
var traceFile = async (filePath, fs, state) => {
|
|
14185
|
-
const cached = state.cache.get(filePath);
|
|
14186
|
-
if (cached)
|
|
14187
|
-
return cached;
|
|
14188
|
-
if (state.inFlight.has(filePath))
|
|
14189
|
-
return [];
|
|
14190
|
-
const promise = (async () => {
|
|
14191
|
-
state.inFlight.add(filePath);
|
|
14192
|
-
state.files.add(filePath);
|
|
14193
|
-
const source = await fs.readFile(filePath);
|
|
14194
|
-
const commonJs = analyzeCommonJsModule(source, filePath);
|
|
14195
|
-
if (commonJs.diagnostics.length > 0)
|
|
14196
|
-
return [];
|
|
14197
|
-
const jsxLike = isJsxLikePath(filePath);
|
|
14198
|
-
const parserSource = jsxLike ? treeSitterCompatibleJsxSource(createEcmaScriptSourceFile(source, filePath), source) : source;
|
|
14199
|
-
const tree = await parseFile(parserSource, jsxLike);
|
|
14200
|
-
if (!tree)
|
|
14201
|
-
return [];
|
|
14202
|
-
const root = tree.rootNode;
|
|
14203
|
-
const localDeclarations = collectLocalDeclarations(root);
|
|
14204
|
-
const importBindings = collectImportBindings(root);
|
|
14205
|
-
for (const declaration of commonJs.syntheticDeclarations) {
|
|
14206
|
-
localDeclarations.set(declaration.name, declaration.name);
|
|
14207
|
-
}
|
|
14208
|
-
for (const binding of commonJs.bindings) {
|
|
14209
|
-
importBindings.set(binding.localName, {
|
|
14210
|
-
source: binding.source,
|
|
14211
|
-
importedName: binding.importedName
|
|
14212
|
-
});
|
|
14213
|
-
}
|
|
14214
|
-
const exportsList = [];
|
|
14215
|
-
for (const node2 of root.namedChildren) {
|
|
14216
|
-
if (node2.type !== "export_statement")
|
|
14217
|
-
continue;
|
|
14218
|
-
const stringNode = node2.namedChildren.find((child) => child.type === "string");
|
|
14219
|
-
const exportClause = node2.namedChildren.find((child) => child.type === "export_clause");
|
|
14220
|
-
const declaration = node2.namedChildren.find((child) => DECLARATION_TYPES.has(child.type));
|
|
14221
|
-
if (declaration) {
|
|
14222
|
-
for (const name of getDeclarationName(declaration)) {
|
|
14223
|
-
exportsList.push({ exportedName: name, localName: name, declarationFile: filePath });
|
|
14224
|
-
}
|
|
14225
|
-
continue;
|
|
14226
|
-
}
|
|
14227
|
-
if (node2.text.startsWith("export default ")) {
|
|
14228
|
-
const identifier = node2.namedChildren.find((child) => child.type === "identifier" || child.type === "type_identifier");
|
|
14229
|
-
if (identifier && localDeclarations.has(identifier.text)) {
|
|
14230
|
-
exportsList.push({
|
|
14231
|
-
exportedName: identifier.text,
|
|
14232
|
-
localName: identifier.text,
|
|
14233
|
-
declarationFile: filePath
|
|
14234
|
-
});
|
|
14235
|
-
}
|
|
14236
|
-
continue;
|
|
14237
|
-
}
|
|
14238
|
-
if (!exportClause) {
|
|
14239
|
-
if (stringNode && node2.text.startsWith("export *")) {
|
|
14240
|
-
const targetPath2 = await resolveImportSourcePath(filePath, stripQuotes(stringNode.text), fs, state.resolver);
|
|
14241
|
-
if (targetPath2) {
|
|
14242
|
-
exportsList.push(...await traceFile(targetPath2, fs, state));
|
|
14243
|
-
}
|
|
14244
|
-
}
|
|
14245
|
-
continue;
|
|
14246
|
-
}
|
|
14247
|
-
if (!stringNode) {
|
|
14248
|
-
for (const specifier of exportClause.namedChildren.filter((child) => child.type === "export_specifier")) {
|
|
14249
|
-
const parsed = parseExportSpecifier(specifier);
|
|
14250
|
-
if (!parsed)
|
|
14251
|
-
continue;
|
|
14252
|
-
if (localDeclarations.has(parsed.localName)) {
|
|
14253
|
-
exportsList.push({
|
|
14254
|
-
exportedName: parsed.exportedName,
|
|
14255
|
-
localName: parsed.localName,
|
|
14256
|
-
declarationFile: filePath
|
|
14257
|
-
});
|
|
14258
|
-
continue;
|
|
14259
|
-
}
|
|
14260
|
-
const importBinding = importBindings.get(parsed.localName);
|
|
14261
|
-
if (importBinding) {
|
|
14262
|
-
exportsList.push(...await traceImportedBinding(filePath, importBinding, parsed.exportedName, fs, state));
|
|
14263
|
-
}
|
|
14264
|
-
}
|
|
14265
|
-
continue;
|
|
14266
|
-
}
|
|
14267
|
-
const targetPath = await resolveImportSourcePath(filePath, stripQuotes(stringNode.text), fs, state.resolver);
|
|
14268
|
-
if (!targetPath)
|
|
14269
|
-
continue;
|
|
14270
|
-
const traced = await traceFile(targetPath, fs, state);
|
|
14271
|
-
for (const specifier of exportClause.namedChildren.filter((child) => child.type === "export_specifier")) {
|
|
14272
|
-
const parsed = parseExportSpecifier(specifier);
|
|
14273
|
-
if (!parsed)
|
|
14274
|
-
continue;
|
|
14275
|
-
const match = traced.find((item) => item.exportedName === parsed.localName);
|
|
14276
|
-
if (!match)
|
|
14277
|
-
continue;
|
|
14278
|
-
exportsList.push({
|
|
14279
|
-
exportedName: parsed.exportedName,
|
|
14280
|
-
localName: match.localName,
|
|
14281
|
-
declarationFile: match.declarationFile
|
|
14282
|
-
});
|
|
14815
|
+
if (!pushExport(result, assignment.right.text, assignment.right, line, bindingMap, sourceFile)) {
|
|
14816
|
+
appendUnsupportedExportDiagnostic(result, sourceFile, assignment.right);
|
|
14283
14817
|
}
|
|
14818
|
+
continue;
|
|
14284
14819
|
}
|
|
14285
|
-
|
|
14286
|
-
|
|
14287
|
-
|
|
14288
|
-
|
|
14289
|
-
|
|
14290
|
-
|
|
14291
|
-
|
|
14292
|
-
|
|
14293
|
-
|
|
14294
|
-
|
|
14295
|
-
state.inFlight.delete(filePath);
|
|
14296
|
-
return uniqueExports(exportsList);
|
|
14297
|
-
})();
|
|
14298
|
-
state.cache.set(filePath, promise);
|
|
14299
|
-
return promise;
|
|
14820
|
+
if (!pushExport(result, "default", assignment.right, line, bindingMap, sourceFile)) {
|
|
14821
|
+
appendUnsupportedExportDiagnostic(result, sourceFile, assignment.right);
|
|
14822
|
+
}
|
|
14823
|
+
}
|
|
14824
|
+
result.bindings.sort((left, right) => left.localName.localeCompare(right.localName));
|
|
14825
|
+
result.exports.sort((left, right) => left.exportedName.localeCompare(right.exportedName) || left.line - right.line);
|
|
14826
|
+
result.wildcardSources = [...new Set(result.wildcardSources)].sort();
|
|
14827
|
+
result.syntheticDeclarations.sort((left, right) => left.name.localeCompare(right.name));
|
|
14828
|
+
result.diagnostics.sort((left, right) => left.line - right.line || left.column - right.column);
|
|
14829
|
+
return result;
|
|
14300
14830
|
};
|
|
14301
|
-
|
|
14302
|
-
|
|
14303
|
-
|
|
14304
|
-
|
|
14305
|
-
|
|
14306
|
-
|
|
14307
|
-
|
|
14308
|
-
|
|
14309
|
-
|
|
14310
|
-
|
|
14311
|
-
|
|
14312
|
-
|
|
14831
|
+
|
|
14832
|
+
// src/commonJsExportTrace.ts
|
|
14833
|
+
var traceCommonJsExports = async (input) => {
|
|
14834
|
+
const traced = [];
|
|
14835
|
+
for (const item of input.analysis.exports) {
|
|
14836
|
+
if (item.localName && input.localDeclarations.has(item.localName)) {
|
|
14837
|
+
traced.push({
|
|
14838
|
+
exportedName: item.exportedName,
|
|
14839
|
+
localName: item.localName,
|
|
14840
|
+
declarationFile: input.filePath
|
|
14841
|
+
});
|
|
14842
|
+
continue;
|
|
14843
|
+
}
|
|
14844
|
+
if (item.source && item.importedName) {
|
|
14845
|
+
traced.push(...await input.traceImported(item.source, item.importedName, item.exportedName));
|
|
14846
|
+
}
|
|
14847
|
+
}
|
|
14848
|
+
for (const source of input.analysis.wildcardSources) {
|
|
14849
|
+
traced.push(...await input.traceWildcard(source));
|
|
14850
|
+
}
|
|
14851
|
+
return traced;
|
|
14313
14852
|
};
|
|
14314
14853
|
|
|
14315
|
-
// src/
|
|
14854
|
+
// src/exportTracer.ts
|
|
14316
14855
|
var DECLARATION_TYPES2 = new Set([
|
|
14317
14856
|
"function_declaration",
|
|
14318
14857
|
"class_declaration",
|
|
@@ -14321,296 +14860,247 @@ var DECLARATION_TYPES2 = new Set([
|
|
|
14321
14860
|
"enum_declaration",
|
|
14322
14861
|
"lexical_declaration"
|
|
14323
14862
|
]);
|
|
14324
|
-
var
|
|
14325
|
-
|
|
14326
|
-
"
|
|
14327
|
-
|
|
14328
|
-
"Error",
|
|
14329
|
-
"Map",
|
|
14330
|
-
"Number",
|
|
14331
|
-
"Object",
|
|
14332
|
-
"Promise",
|
|
14333
|
-
"ReadonlyArray",
|
|
14334
|
-
"Record",
|
|
14335
|
-
"Set",
|
|
14336
|
-
"String",
|
|
14337
|
-
"unknown",
|
|
14338
|
-
"void",
|
|
14339
|
-
"string",
|
|
14340
|
-
"number",
|
|
14341
|
-
"boolean",
|
|
14342
|
-
"null",
|
|
14343
|
-
"undefined",
|
|
14344
|
-
"never",
|
|
14345
|
-
"any"
|
|
14346
|
-
]);
|
|
14347
|
-
var countLines = (source) => {
|
|
14348
|
-
if (!source)
|
|
14349
|
-
return 0;
|
|
14350
|
-
return source.split(/\r\n|\r|\n/).filter((line) => line.trim().length > 0).length;
|
|
14351
|
-
};
|
|
14352
|
-
var createRelation = (type, from, to, isExternal, line) => ({
|
|
14353
|
-
type,
|
|
14354
|
-
from,
|
|
14355
|
-
to,
|
|
14356
|
-
isExternal,
|
|
14357
|
-
grounding: "code" /* Code */,
|
|
14358
|
-
confidence: 1,
|
|
14359
|
-
source: "ast" /* Ast */,
|
|
14360
|
-
...line ? { line } : {}
|
|
14361
|
-
});
|
|
14362
|
-
var getLine = (node2) => node2.startPosition.row + 1;
|
|
14363
|
-
var getEndLine = (node2) => node2.endPosition.row + 1;
|
|
14364
|
-
var extractJSDoc = (node2) => {
|
|
14365
|
-
const prev = node2.previousNamedSibling ?? node2.parent?.previousNamedSibling;
|
|
14366
|
-
if (!prev || prev.type !== "comment")
|
|
14367
|
-
return;
|
|
14368
|
-
const text = prev.text;
|
|
14369
|
-
if (!text.startsWith("/**"))
|
|
14370
|
-
return;
|
|
14371
|
-
const cleaned = text.replace(/^\/\*\*\s*/, "").replace(/\s*\*\/$/, "").replace(/^\s*\* ?/gm, "").trim();
|
|
14372
|
-
return cleaned || undefined;
|
|
14373
|
-
};
|
|
14374
|
-
var extractTypeAnnotation = (node2) => {
|
|
14375
|
-
if (!node2)
|
|
14376
|
-
return null;
|
|
14377
|
-
return node2.text.replace(/^:\s*/, "").trim() || null;
|
|
14378
|
-
};
|
|
14379
|
-
var getNameNodeText = (node2) => node2?.text?.trim() ? node2.text.trim() : null;
|
|
14380
|
-
var getReturnType = (node2) => {
|
|
14381
|
-
const returnNode = node2.childForFieldName("return_type") ?? node2.namedChildren.find((child) => child.type === "type_annotation") ?? null;
|
|
14382
|
-
return extractTypeAnnotation(returnNode);
|
|
14383
|
-
};
|
|
14384
|
-
var getInitializer = (node2) => node2.childForFieldName("value") ?? node2.namedChildren.find((child) => child.type === "arrow_function" || child.type === "function" || child.type === "call_expression") ?? null;
|
|
14385
|
-
var getCallableFromInitializer = (node2) => {
|
|
14386
|
-
if (!node2)
|
|
14387
|
-
return null;
|
|
14388
|
-
if (node2.type === "arrow_function" || node2.type === "function")
|
|
14389
|
-
return node2;
|
|
14390
|
-
if (node2.type === "call_expression") {
|
|
14391
|
-
return node2.namedChildren.find((child) => child.type === "arrow_function" || child.type === "function") ?? null;
|
|
14392
|
-
}
|
|
14393
|
-
return null;
|
|
14394
|
-
};
|
|
14395
|
-
var getInitializerTypeAnnotation = (node2) => {
|
|
14396
|
-
if (!node2 || node2.type !== "call_expression")
|
|
14397
|
-
return null;
|
|
14398
|
-
const typeArguments = node2.namedChildren.find((child) => child.type === "type_arguments") ?? null;
|
|
14399
|
-
if (!typeArguments)
|
|
14400
|
-
return null;
|
|
14401
|
-
const callee = node2.namedChildren.find((child) => child.type !== "type_arguments" && child.type !== "arguments") ?? null;
|
|
14402
|
-
const calleeText = callee?.text?.trim();
|
|
14403
|
-
return calleeText ? `${calleeText}${typeArguments.text}` : typeArguments.text;
|
|
14404
|
-
};
|
|
14405
|
-
var getInitializerText = (node2, options = {}) => {
|
|
14406
|
-
if (!node2)
|
|
14407
|
-
return null;
|
|
14408
|
-
if ((node2.type === "arrow_function" || node2.type === "function") && !options.includeCallable)
|
|
14409
|
-
return null;
|
|
14410
|
-
const text = node2.text.trim();
|
|
14411
|
-
if ((node2.type === "arrow_function" || node2.type === "function") && text.length > 600)
|
|
14412
|
-
return null;
|
|
14413
|
-
return text.length > 0 ? text : null;
|
|
14414
|
-
};
|
|
14415
|
-
var inferReturnType = (node2) => {
|
|
14416
|
-
if (!node2)
|
|
14417
|
-
return null;
|
|
14418
|
-
return containsJsx(node2) ? "JSX.Element" : null;
|
|
14419
|
-
};
|
|
14420
|
-
var containsJsx = (node2) => {
|
|
14421
|
-
if (node2.type.startsWith("jsx_"))
|
|
14422
|
-
return true;
|
|
14423
|
-
return node2.namedChildren.some(containsJsx);
|
|
14424
|
-
};
|
|
14425
|
-
var getTypeNames = (typeText) => {
|
|
14426
|
-
if (!typeText)
|
|
14427
|
-
return [];
|
|
14428
|
-
const matches = typeText.match(/\b[A-Z][A-Za-z0-9_]*(?:\.[A-Z][A-Za-z0-9_]*)*\b/g) ?? [];
|
|
14429
|
-
return [...new Set(matches)].filter((match) => !BUILTIN_TYPES.has(match));
|
|
14430
|
-
};
|
|
14431
|
-
var resolveTypeBinding = (typeName, importBindings, declarations) => {
|
|
14432
|
-
const localName = typeName.split(".")[0] ?? typeName;
|
|
14433
|
-
const importBinding = importBindings.get(localName);
|
|
14434
|
-
if (importBinding)
|
|
14435
|
-
return importBinding.isExternal;
|
|
14436
|
-
if (declarations.has(localName))
|
|
14437
|
-
return false;
|
|
14438
|
-
return false;
|
|
14439
|
-
};
|
|
14440
|
-
var appendTypeRelations = (relations, relationType, from, typeText, importBindings, declarations, line) => {
|
|
14441
|
-
for (const typeName of getTypeNames(typeText)) {
|
|
14442
|
-
relations.push(createRelation(relationType, from, typeName, resolveTypeBinding(typeName, importBindings, declarations), line));
|
|
14443
|
-
}
|
|
14444
|
-
};
|
|
14445
|
-
var classifyVariable = (name, filePath) => {
|
|
14446
|
-
if ((filePath.endsWith(".tsx") || filePath.endsWith(".jsx")) && /^[A-Z]/.test(name)) {
|
|
14447
|
-
return "component" /* Component */;
|
|
14863
|
+
var stripQuotes = (value) => value.replace(/^['"]/, "").replace(/['"]$/, "");
|
|
14864
|
+
var getDeclarationName = (node2) => {
|
|
14865
|
+
if (node2.type === "lexical_declaration") {
|
|
14866
|
+
return node2.namedChildren.filter((child) => child.type === "variable_declarator").map((child) => child.childForFieldName("name")?.text ?? child.namedChildren[0]?.text ?? "").filter(Boolean);
|
|
14448
14867
|
}
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
var collectParams = (node2) => {
|
|
14452
|
-
if (!node2)
|
|
14453
|
-
return [];
|
|
14454
|
-
return node2.namedChildren.map((child) => {
|
|
14455
|
-
const wrapper = child;
|
|
14456
|
-
const target = child.type === "required_parameter" || child.type === "optional_parameter" ? child.namedChildren[0] ?? child : child;
|
|
14457
|
-
const nameNode = target.childForFieldName("name") ?? target.namedChildren.find((candidate) => candidate.type === "identifier" || candidate.type === "property_identifier") ?? target.namedChildren[0] ?? target;
|
|
14458
|
-
const typeNode = wrapper.childForFieldName("type") ?? wrapper.namedChildren.find((candidate) => candidate.type === "type_annotation") ?? target.childForFieldName("type") ?? target.namedChildren.find((candidate) => candidate.type === "type_annotation") ?? null;
|
|
14459
|
-
return {
|
|
14460
|
-
name: nameNode.text,
|
|
14461
|
-
type: extractTypeAnnotation(typeNode)
|
|
14462
|
-
};
|
|
14463
|
-
});
|
|
14868
|
+
const nameNode = node2.childForFieldName("name") ?? node2.namedChildren.find((child) => child.type === "identifier" || child.type === "type_identifier");
|
|
14869
|
+
return nameNode?.text ? [nameNode.text] : [];
|
|
14464
14870
|
};
|
|
14465
|
-
var
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
|
|
14469
|
-
|
|
14470
|
-
|
|
14471
|
-
const nameNode = child.childForFieldName("name") ?? child.namedChildren.find((candidate) => candidate.type === "property_identifier" || candidate.type === "identifier");
|
|
14472
|
-
if (!nameNode)
|
|
14473
|
-
continue;
|
|
14474
|
-
const typeNode = child.childForFieldName("type") ?? child.namedChildren.find((candidate) => candidate.type === "type_annotation") ?? null;
|
|
14475
|
-
const typeAnnotation = extractTypeAnnotation(typeNode);
|
|
14476
|
-
const propDoc = extractJSDoc(child);
|
|
14477
|
-
members.push({
|
|
14478
|
-
name: nameNode.text,
|
|
14479
|
-
kind: "prop" /* Prop */,
|
|
14480
|
-
visibility: "internal" /* Internal */,
|
|
14481
|
-
file: "",
|
|
14482
|
-
line: getLine(child),
|
|
14483
|
-
endLine: getEndLine(child),
|
|
14484
|
-
...typeAnnotation ? { typeAnnotation } : {},
|
|
14485
|
-
...propDoc ? { doc: propDoc } : {}
|
|
14486
|
-
});
|
|
14487
|
-
appendTypeRelations(relations, "of_type" /* OfType */, ownerName, typeAnnotation, importBindings, declarations, getLine(child));
|
|
14488
|
-
continue;
|
|
14489
|
-
}
|
|
14490
|
-
const indexMember = indexSignatureMember(child);
|
|
14491
|
-
if (indexMember) {
|
|
14492
|
-
members.push(indexMember.info);
|
|
14493
|
-
appendTypeRelations(relations, "of_type" /* OfType */, ownerName, indexMember.typeAnnotation, importBindings, declarations, getLine(child));
|
|
14494
|
-
continue;
|
|
14495
|
-
}
|
|
14496
|
-
if (child.type === "method_definition" || child.type === "method_signature") {
|
|
14497
|
-
const nameNode = child.childForFieldName("name") ?? child.namedChildren.find((candidate) => candidate.type === "property_identifier" || candidate.type === "identifier");
|
|
14498
|
-
if (!nameNode)
|
|
14499
|
-
continue;
|
|
14500
|
-
const paramsNode = child.childForFieldName("parameters") ?? child.namedChildren.find((candidate) => candidate.type === "formal_parameters") ?? null;
|
|
14501
|
-
const params = collectParams(paramsNode);
|
|
14502
|
-
const returnType = getReturnType(child);
|
|
14503
|
-
const methodDoc = extractJSDoc(child);
|
|
14504
|
-
members.push({
|
|
14505
|
-
name: nameNode.text,
|
|
14506
|
-
kind: "method" /* Method */,
|
|
14507
|
-
visibility: "internal" /* Internal */,
|
|
14508
|
-
file: "",
|
|
14509
|
-
line: getLine(child),
|
|
14510
|
-
endLine: getEndLine(child),
|
|
14511
|
-
...params.length > 0 ? { params } : {},
|
|
14512
|
-
...returnType ? { returnType } : {},
|
|
14513
|
-
...methodDoc ? { doc: methodDoc } : {}
|
|
14514
|
-
});
|
|
14515
|
-
for (const param of params) {
|
|
14516
|
-
appendTypeRelations(relations, "param_type" /* ParamType */, ownerName, param.type, importBindings, declarations, getLine(child));
|
|
14871
|
+
var collectLocalDeclarations = (root) => {
|
|
14872
|
+
const declarations = new Map;
|
|
14873
|
+
const register = (node2) => {
|
|
14874
|
+
for (const name of getDeclarationName(node2)) {
|
|
14875
|
+
if (!declarations.has(name)) {
|
|
14876
|
+
declarations.set(name, name);
|
|
14517
14877
|
}
|
|
14518
|
-
|
|
14878
|
+
}
|
|
14879
|
+
};
|
|
14880
|
+
for (const child of root.namedChildren) {
|
|
14881
|
+
if (DECLARATION_TYPES2.has(child.type)) {
|
|
14882
|
+
register(child);
|
|
14883
|
+
continue;
|
|
14884
|
+
}
|
|
14885
|
+
if (child.type !== "export_statement")
|
|
14886
|
+
continue;
|
|
14887
|
+
const declaration = child.namedChildren.find((node2) => DECLARATION_TYPES2.has(node2.type));
|
|
14888
|
+
if (declaration) {
|
|
14889
|
+
register(declaration);
|
|
14519
14890
|
}
|
|
14520
14891
|
}
|
|
14521
|
-
return
|
|
14892
|
+
return declarations;
|
|
14522
14893
|
};
|
|
14523
|
-
var
|
|
14524
|
-
|
|
14894
|
+
var parseExportSpecifier = (node2) => {
|
|
14895
|
+
const identifiers = node2.namedChildren.filter((child) => child.type === "identifier" || child.type === "type_identifier").map((child) => child.text);
|
|
14896
|
+
if (identifiers.length === 0)
|
|
14525
14897
|
return null;
|
|
14526
|
-
const
|
|
14527
|
-
const
|
|
14528
|
-
|
|
14529
|
-
|
|
14898
|
+
const localName = identifiers[0];
|
|
14899
|
+
const exportedName = identifiers[1] ?? localName;
|
|
14900
|
+
return { localName, exportedName };
|
|
14901
|
+
};
|
|
14902
|
+
var parseImportSpecifier = (node2) => {
|
|
14903
|
+
const identifiers = node2.namedChildren.filter((child) => child.type === "identifier" || child.type === "type_identifier").map((child) => child.text);
|
|
14904
|
+
if (identifiers.length === 0)
|
|
14530
14905
|
return null;
|
|
14531
|
-
const
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
name,
|
|
14535
|
-
kind: "prop" /* Prop */,
|
|
14536
|
-
visibility: "internal" /* Internal */,
|
|
14537
|
-
file: "",
|
|
14538
|
-
line: getLine(node2),
|
|
14539
|
-
endLine: getEndLine(node2),
|
|
14540
|
-
...typeAnnotation ? { typeAnnotation } : {},
|
|
14541
|
-
...propDoc ? { doc: propDoc } : {}
|
|
14542
|
-
},
|
|
14543
|
-
typeAnnotation
|
|
14544
|
-
};
|
|
14906
|
+
const importedName = identifiers[0];
|
|
14907
|
+
const localName = identifiers[1] ?? importedName;
|
|
14908
|
+
return { importedName, localName };
|
|
14545
14909
|
};
|
|
14546
|
-
var
|
|
14547
|
-
const
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
const values = [];
|
|
14551
|
-
for (const member of body.namedChildren.filter((child) => child.type === "enum_assignment" || child.type === "property_identifier")) {
|
|
14552
|
-
if (member.type === "property_identifier") {
|
|
14553
|
-
values.push(member.text);
|
|
14910
|
+
var collectImportBindings = (root) => {
|
|
14911
|
+
const bindings = new Map;
|
|
14912
|
+
for (const node2 of root.namedChildren) {
|
|
14913
|
+
if (node2.type !== "import_statement")
|
|
14554
14914
|
continue;
|
|
14555
|
-
|
|
14556
|
-
|
|
14557
|
-
if (!name)
|
|
14915
|
+
const stringNode = node2.namedChildren.find((child) => child.type === "string");
|
|
14916
|
+
if (!stringNode)
|
|
14558
14917
|
continue;
|
|
14559
|
-
const
|
|
14560
|
-
const
|
|
14561
|
-
|
|
14562
|
-
|
|
14563
|
-
|
|
14564
|
-
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
|
|
14570
|
-
|
|
14571
|
-
|
|
14572
|
-
|
|
14573
|
-
const values = [];
|
|
14574
|
-
for (const child of typeNode.namedChildren) {
|
|
14575
|
-
if (child.type === "literal_type") {
|
|
14576
|
-
const text = child.text.replace(/^['"]|['"]$/g, "");
|
|
14577
|
-
if (text)
|
|
14578
|
-
values.push(text);
|
|
14579
|
-
} else if (child.type === "union_type") {
|
|
14580
|
-
const nested = extractUnionLiteralValues(child);
|
|
14581
|
-
if (!nested)
|
|
14582
|
-
return;
|
|
14583
|
-
values.push(...nested);
|
|
14584
|
-
} else {
|
|
14585
|
-
return;
|
|
14918
|
+
const source = stripQuotes(stringNode.text);
|
|
14919
|
+
const clause = node2.namedChildren.find((child) => child.type === "import_clause");
|
|
14920
|
+
for (const part of clause?.namedChildren ?? []) {
|
|
14921
|
+
if (part.type === "identifier") {
|
|
14922
|
+
bindings.set(part.text, { source, importedName: "default" });
|
|
14923
|
+
continue;
|
|
14924
|
+
}
|
|
14925
|
+
if (part.type !== "named_imports")
|
|
14926
|
+
continue;
|
|
14927
|
+
for (const specifier of part.namedChildren.filter((child) => child.type === "import_specifier")) {
|
|
14928
|
+
const parsed = parseImportSpecifier(specifier);
|
|
14929
|
+
if (parsed) {
|
|
14930
|
+
bindings.set(parsed.localName, { source, importedName: parsed.importedName });
|
|
14931
|
+
}
|
|
14586
14932
|
}
|
|
14587
14933
|
}
|
|
14588
|
-
return values.length > 0 ? values : undefined;
|
|
14589
14934
|
}
|
|
14590
|
-
return;
|
|
14935
|
+
return bindings;
|
|
14591
14936
|
};
|
|
14592
|
-
var
|
|
14593
|
-
|
|
14937
|
+
var uniqueExports = (exportsList) => {
|
|
14938
|
+
const seen = new Set;
|
|
14939
|
+
return exportsList.filter((item) => {
|
|
14940
|
+
const key = `${item.declarationFile}::${item.localName}::${item.exportedName}`;
|
|
14941
|
+
if (seen.has(key))
|
|
14942
|
+
return false;
|
|
14943
|
+
seen.add(key);
|
|
14944
|
+
return true;
|
|
14945
|
+
});
|
|
14946
|
+
};
|
|
14947
|
+
var traceImportedBinding = async (filePath, binding, exportedName, fs, state) => {
|
|
14948
|
+
const targetPath = await resolveImportSourcePath(filePath, binding.source, fs, state.resolver);
|
|
14949
|
+
if (!targetPath)
|
|
14594
14950
|
return [];
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
if (
|
|
14598
|
-
return
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
|
|
14603
|
-
|
|
14951
|
+
const traced = await traceFile(targetPath, fs, state);
|
|
14952
|
+
const match = traced.find((item) => item.exportedName === binding.importedName || binding.importedName === "default" && item.exportedName === item.localName);
|
|
14953
|
+
if (!match)
|
|
14954
|
+
return [];
|
|
14955
|
+
return [{
|
|
14956
|
+
exportedName,
|
|
14957
|
+
localName: match.localName,
|
|
14958
|
+
declarationFile: match.declarationFile
|
|
14959
|
+
}];
|
|
14960
|
+
};
|
|
14961
|
+
var traceFile = async (filePath, fs, state) => {
|
|
14962
|
+
const cached = state.cache.get(filePath);
|
|
14963
|
+
if (cached)
|
|
14964
|
+
return cached;
|
|
14965
|
+
if (state.inFlight.has(filePath))
|
|
14966
|
+
return [];
|
|
14967
|
+
const promise = (async () => {
|
|
14968
|
+
state.inFlight.add(filePath);
|
|
14969
|
+
state.files.add(filePath);
|
|
14970
|
+
const source = await fs.readFile(filePath);
|
|
14971
|
+
const commonJs = analyzeCommonJsModule(source, filePath);
|
|
14972
|
+
if (commonJs.diagnostics.length > 0)
|
|
14973
|
+
return [];
|
|
14974
|
+
const jsxLike = isJsxLikePath(filePath);
|
|
14975
|
+
const parserSource = jsxLike ? treeSitterCompatibleJsxSource(createEcmaScriptSourceFile(source, filePath), source) : source;
|
|
14976
|
+
const tree = await parseFile(parserSource, jsxLike);
|
|
14977
|
+
if (!tree)
|
|
14978
|
+
return [];
|
|
14979
|
+
try {
|
|
14980
|
+
const root = tree.rootNode;
|
|
14981
|
+
const localDeclarations = collectLocalDeclarations(root);
|
|
14982
|
+
const importBindings = collectImportBindings(root);
|
|
14983
|
+
for (const declaration of commonJs.syntheticDeclarations) {
|
|
14984
|
+
localDeclarations.set(declaration.name, declaration.name);
|
|
14985
|
+
}
|
|
14986
|
+
for (const binding of commonJs.bindings) {
|
|
14987
|
+
importBindings.set(binding.localName, {
|
|
14988
|
+
source: binding.source,
|
|
14989
|
+
importedName: binding.importedName
|
|
14990
|
+
});
|
|
14991
|
+
}
|
|
14992
|
+
const exportsList = [];
|
|
14993
|
+
for (const node2 of root.namedChildren) {
|
|
14994
|
+
if (node2.type !== "export_statement")
|
|
14995
|
+
continue;
|
|
14996
|
+
const stringNode = node2.namedChildren.find((child) => child.type === "string");
|
|
14997
|
+
const exportClause = node2.namedChildren.find((child) => child.type === "export_clause");
|
|
14998
|
+
const declaration = node2.namedChildren.find((child) => DECLARATION_TYPES2.has(child.type));
|
|
14999
|
+
if (declaration) {
|
|
15000
|
+
for (const name of getDeclarationName(declaration)) {
|
|
15001
|
+
exportsList.push({ exportedName: name, localName: name, declarationFile: filePath });
|
|
15002
|
+
}
|
|
15003
|
+
continue;
|
|
15004
|
+
}
|
|
15005
|
+
if (node2.text.startsWith("export default ")) {
|
|
15006
|
+
const identifier = node2.namedChildren.find((child) => child.type === "identifier" || child.type === "type_identifier");
|
|
15007
|
+
if (identifier && localDeclarations.has(identifier.text)) {
|
|
15008
|
+
exportsList.push({
|
|
15009
|
+
exportedName: identifier.text,
|
|
15010
|
+
localName: identifier.text,
|
|
15011
|
+
declarationFile: filePath
|
|
15012
|
+
});
|
|
15013
|
+
}
|
|
15014
|
+
continue;
|
|
15015
|
+
}
|
|
15016
|
+
if (!exportClause) {
|
|
15017
|
+
if (stringNode && node2.text.startsWith("export *")) {
|
|
15018
|
+
const targetPath2 = await resolveImportSourcePath(filePath, stripQuotes(stringNode.text), fs, state.resolver);
|
|
15019
|
+
if (targetPath2) {
|
|
15020
|
+
exportsList.push(...await traceFile(targetPath2, fs, state));
|
|
15021
|
+
}
|
|
15022
|
+
}
|
|
15023
|
+
continue;
|
|
15024
|
+
}
|
|
15025
|
+
if (!stringNode) {
|
|
15026
|
+
for (const specifier of exportClause.namedChildren.filter((child) => child.type === "export_specifier")) {
|
|
15027
|
+
const parsed = parseExportSpecifier(specifier);
|
|
15028
|
+
if (!parsed)
|
|
15029
|
+
continue;
|
|
15030
|
+
if (localDeclarations.has(parsed.localName)) {
|
|
15031
|
+
exportsList.push({
|
|
15032
|
+
exportedName: parsed.exportedName,
|
|
15033
|
+
localName: parsed.localName,
|
|
15034
|
+
declarationFile: filePath
|
|
15035
|
+
});
|
|
15036
|
+
continue;
|
|
15037
|
+
}
|
|
15038
|
+
const importBinding = importBindings.get(parsed.localName);
|
|
15039
|
+
if (importBinding) {
|
|
15040
|
+
exportsList.push(...await traceImportedBinding(filePath, importBinding, parsed.exportedName, fs, state));
|
|
15041
|
+
}
|
|
15042
|
+
}
|
|
15043
|
+
continue;
|
|
15044
|
+
}
|
|
15045
|
+
const targetPath = await resolveImportSourcePath(filePath, stripQuotes(stringNode.text), fs, state.resolver);
|
|
15046
|
+
if (!targetPath)
|
|
15047
|
+
continue;
|
|
15048
|
+
const traced = await traceFile(targetPath, fs, state);
|
|
15049
|
+
for (const specifier of exportClause.namedChildren.filter((child) => child.type === "export_specifier")) {
|
|
15050
|
+
const parsed = parseExportSpecifier(specifier);
|
|
15051
|
+
if (!parsed)
|
|
15052
|
+
continue;
|
|
15053
|
+
const match = traced.find((item) => item.exportedName === parsed.localName);
|
|
15054
|
+
if (!match)
|
|
15055
|
+
continue;
|
|
15056
|
+
exportsList.push({
|
|
15057
|
+
exportedName: parsed.exportedName,
|
|
15058
|
+
localName: match.localName,
|
|
15059
|
+
declarationFile: match.declarationFile
|
|
15060
|
+
});
|
|
15061
|
+
}
|
|
15062
|
+
}
|
|
15063
|
+
exportsList.push(...await traceCommonJsExports({
|
|
15064
|
+
analysis: commonJs,
|
|
15065
|
+
filePath,
|
|
15066
|
+
localDeclarations,
|
|
15067
|
+
traceImported: (source2, importedName, exportedName) => traceImportedBinding(filePath, { source: source2, importedName }, exportedName, fs, state),
|
|
15068
|
+
traceWildcard: async (source2) => {
|
|
15069
|
+
const targetPath = await resolveImportSourcePath(filePath, source2, fs, state.resolver);
|
|
15070
|
+
return targetPath ? traceFile(targetPath, fs, state) : [];
|
|
15071
|
+
}
|
|
15072
|
+
}));
|
|
15073
|
+
return uniqueExports(exportsList);
|
|
15074
|
+
} finally {
|
|
15075
|
+
tree.delete();
|
|
15076
|
+
state.inFlight.delete(filePath);
|
|
15077
|
+
}
|
|
15078
|
+
})();
|
|
15079
|
+
state.cache.set(filePath, promise);
|
|
15080
|
+
return promise;
|
|
15081
|
+
};
|
|
15082
|
+
var traceExports = async (entryPath, fs, resolver = { mappings: [] }) => {
|
|
15083
|
+
const state = {
|
|
15084
|
+
files: new Set,
|
|
15085
|
+
cache: new Map,
|
|
15086
|
+
inFlight: new Set,
|
|
15087
|
+
resolver
|
|
15088
|
+
};
|
|
15089
|
+
const exportsList = await traceFile(entryPath, fs, state);
|
|
15090
|
+
return {
|
|
15091
|
+
exports: uniqueExports(exportsList),
|
|
15092
|
+
files: [...state.files].sort()
|
|
15093
|
+
};
|
|
14604
15094
|
};
|
|
14605
15095
|
|
|
14606
15096
|
// src/staticCallRelations.ts
|
|
14607
|
-
import
|
|
15097
|
+
import ts8 from "typescript";
|
|
14608
15098
|
var callTarget = (expression, sourceFile) => {
|
|
14609
|
-
if (
|
|
15099
|
+
if (ts8.isIdentifier(expression))
|
|
14610
15100
|
return expression.text === "require" ? null : expression.text;
|
|
14611
|
-
if (
|
|
15101
|
+
if (ts8.isPropertyAccessExpression(expression))
|
|
14612
15102
|
return expression.getText(sourceFile).replace(/\s+/gu, "");
|
|
14613
|
-
if (
|
|
15103
|
+
if (ts8.isElementAccessExpression(expression)) {
|
|
14614
15104
|
const property = staticStringValue(expression.argumentExpression);
|
|
14615
15105
|
return property ? `${expression.expression.getText(sourceFile).replace(/\s+/gu, "")}.${property}` : null;
|
|
14616
15106
|
}
|
|
@@ -14618,32 +15108,31 @@ var callTarget = (expression, sourceFile) => {
|
|
|
14618
15108
|
};
|
|
14619
15109
|
var rootIdentifier = (expression) => {
|
|
14620
15110
|
let current = expression;
|
|
14621
|
-
while (
|
|
15111
|
+
while (ts8.isPropertyAccessExpression(current) || ts8.isElementAccessExpression(current)) {
|
|
14622
15112
|
current = current.expression;
|
|
14623
15113
|
}
|
|
14624
|
-
return
|
|
15114
|
+
return ts8.isIdentifier(current) ? current.text : null;
|
|
14625
15115
|
};
|
|
14626
15116
|
var declarationName = (node2, sourceFile) => {
|
|
14627
|
-
if (
|
|
15117
|
+
if (ts8.isFunctionDeclaration(node2) && node2.name)
|
|
14628
15118
|
return node2.name.text;
|
|
14629
|
-
if (
|
|
15119
|
+
if (ts8.isClassDeclaration(node2) && node2.name)
|
|
14630
15120
|
return node2.name.text;
|
|
14631
|
-
if (
|
|
15121
|
+
if (ts8.isVariableDeclaration(node2) && ts8.isIdentifier(node2.name))
|
|
14632
15122
|
return node2.name.text;
|
|
14633
|
-
if (
|
|
15123
|
+
if (ts8.isMethodDeclaration(node2) || ts8.isGetAccessorDeclaration(node2) || ts8.isSetAccessorDeclaration(node2)) {
|
|
14634
15124
|
const parent = node2.parent;
|
|
14635
|
-
if (parent &&
|
|
15125
|
+
if (parent && ts8.isClassDeclaration(parent) && parent.name)
|
|
14636
15126
|
return parent.name.text;
|
|
14637
15127
|
return node2.name?.getText(sourceFile) ?? null;
|
|
14638
15128
|
}
|
|
14639
15129
|
return null;
|
|
14640
15130
|
};
|
|
14641
|
-
var collectStaticCallRelations = (source, filePath, importBindings) => {
|
|
14642
|
-
const sourceFile = createEcmaScriptSourceFile(source, filePath);
|
|
15131
|
+
var collectStaticCallRelations = (source, filePath, importBindings, sourceFile = createEcmaScriptSourceFile(source, filePath)) => {
|
|
14643
15132
|
const relations = [];
|
|
14644
15133
|
const visit2 = (node2, owner) => {
|
|
14645
15134
|
const namedOwner = declarationName(node2, sourceFile) ?? owner;
|
|
14646
|
-
if (
|
|
15135
|
+
if (ts8.isCallExpression(node2) || ts8.isNewExpression(node2)) {
|
|
14647
15136
|
const target = callTarget(node2.expression, sourceFile);
|
|
14648
15137
|
if (target) {
|
|
14649
15138
|
const root = rootIdentifier(node2.expression);
|
|
@@ -14651,7 +15140,7 @@ var collectStaticCallRelations = (source, filePath, importBindings) => {
|
|
|
14651
15140
|
relations.push(createRelation("calls" /* Calls */, namedOwner, target, isExternal, nodeLocation(sourceFile, node2).line));
|
|
14652
15141
|
}
|
|
14653
15142
|
}
|
|
14654
|
-
|
|
15143
|
+
ts8.forEachChild(node2, (child) => visit2(child, namedOwner));
|
|
14655
15144
|
};
|
|
14656
15145
|
visit2(sourceFile, filePath);
|
|
14657
15146
|
const seen = new Set;
|
|
@@ -14786,10 +15275,10 @@ var analyzeLexicalDeclaration = (node2, filePath, declarations, importBindings,
|
|
|
14786
15275
|
continue;
|
|
14787
15276
|
const typeNode = declarator.childForFieldName("type") ?? declarator.namedChildren.find((child) => child.type === "type_annotation") ?? null;
|
|
14788
15277
|
const initializer = getInitializer(declarator);
|
|
14789
|
-
const
|
|
14790
|
-
const paramsNode =
|
|
15278
|
+
const callable2 = getCallableFromInitializer(initializer);
|
|
15279
|
+
const paramsNode = callable2?.childForFieldName("parameters") ?? callable2?.namedChildren.find((child) => child.type === "formal_parameters") ?? null;
|
|
14791
15280
|
const params = collectParams(paramsNode);
|
|
14792
|
-
const returnType =
|
|
15281
|
+
const returnType = callable2 ? getReturnType(callable2) ?? inferReturnType(callable2) : null;
|
|
14793
15282
|
const initializerTypeAnnotation = getInitializerTypeAnnotation(initializer);
|
|
14794
15283
|
const typeAnnotation = extractTypeAnnotation(typeNode) ?? initializerTypeAnnotation;
|
|
14795
15284
|
const initializerText = getInitializerText(initializer, {
|
|
@@ -14815,7 +15304,7 @@ var analyzeLexicalDeclaration = (node2, filePath, declarations, importBindings,
|
|
|
14815
15304
|
appendTypeRelations(relations, "param_type" /* ParamType */, nameNode.text, param.type, importBindings, declarations, getLine(declarator));
|
|
14816
15305
|
}
|
|
14817
15306
|
appendTypeRelations(relations, "return_type" /* ReturnType */, nameNode.text, returnType, importBindings, declarations, getLine(declarator));
|
|
14818
|
-
appendTypeRelations(relations, "of_type" /* OfType */, nameNode.text,
|
|
15307
|
+
appendTypeRelations(relations, "of_type" /* OfType */, nameNode.text, extractTypeAnnotation(typeNode) ?? getInitializerTypeAnnotation(initializer, { referencesOnly: true }), importBindings, declarations, getLine(declarator));
|
|
14819
15308
|
}
|
|
14820
15309
|
};
|
|
14821
15310
|
var analyzeFunctionDeclaration = (node2, name, filePath, declarations, importBindings, relations) => {
|
|
@@ -14823,7 +15312,8 @@ var analyzeFunctionDeclaration = (node2, name, filePath, declarations, importBin
|
|
|
14823
15312
|
const params = collectParams(paramsNode);
|
|
14824
15313
|
const returnType = getReturnType(node2);
|
|
14825
15314
|
const funcDoc = extractJSDoc(node2);
|
|
14826
|
-
const
|
|
15315
|
+
const body = node2.childForFieldName("body");
|
|
15316
|
+
const signature = body === null ? node2.text : node2.text.slice(0, body.startIndex - node2.startIndex).trimEnd();
|
|
14827
15317
|
declarations.set(name, {
|
|
14828
15318
|
info: {
|
|
14829
15319
|
name,
|
|
@@ -14954,7 +15444,7 @@ var appendCommonJsSyntheticDeclarations = (commonJs, filePath, declarations) =>
|
|
|
14954
15444
|
var analyzeFile = async (filePath, fs, resolver = { mappings: [] }) => {
|
|
14955
15445
|
const source = await fs.readFile(filePath);
|
|
14956
15446
|
const sourceFile = createEcmaScriptSourceFile(source, filePath);
|
|
14957
|
-
const commonJs = analyzeCommonJsModule(source, filePath);
|
|
15447
|
+
const commonJs = analyzeCommonJsModule(source, filePath, sourceFile);
|
|
14958
15448
|
const jsxLike = isJsxLikePath(filePath);
|
|
14959
15449
|
const parserSource = jsxLike ? treeSitterCompatibleJsxSource(sourceFile, source) : source;
|
|
14960
15450
|
const tree = await parseFile(parserSource, jsxLike);
|
|
@@ -14978,47 +15468,51 @@ var analyzeFile = async (filePath, fs, resolver = { mappings: [] }) => {
|
|
|
14978
15468
|
diagnostics
|
|
14979
15469
|
};
|
|
14980
15470
|
}
|
|
14981
|
-
|
|
14982
|
-
|
|
14983
|
-
|
|
14984
|
-
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
const root = tree.rootNode;
|
|
14992
|
-
const relations = [];
|
|
14993
|
-
const importBindings = await collectImportBindings2(root, filePath, fs, resolver, relations, commonJs);
|
|
14994
|
-
const declarations = new Map;
|
|
14995
|
-
for (const relation of relations) {
|
|
14996
|
-
if (relation.from === "") {
|
|
14997
|
-
relation.from = filePath;
|
|
15471
|
+
try {
|
|
15472
|
+
if (commonJs.diagnostics.length > 0) {
|
|
15473
|
+
return {
|
|
15474
|
+
declarations: new Map,
|
|
15475
|
+
importBindings: new Map,
|
|
15476
|
+
relations: [],
|
|
15477
|
+
lines: countLines(source),
|
|
15478
|
+
disposition: "unsupported",
|
|
15479
|
+
diagnostics: commonJs.diagnostics
|
|
15480
|
+
};
|
|
14998
15481
|
}
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
|
|
15003
|
-
|
|
15482
|
+
const root = tree.rootNode;
|
|
15483
|
+
const relations = [];
|
|
15484
|
+
const importBindings = await collectImportBindings2(root, filePath, fs, resolver, relations, commonJs);
|
|
15485
|
+
const declarations = new Map;
|
|
15486
|
+
for (const relation of relations) {
|
|
15487
|
+
if (relation.from === "") {
|
|
15488
|
+
relation.from = filePath;
|
|
15489
|
+
}
|
|
15004
15490
|
}
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15491
|
+
for (const child of root.namedChildren) {
|
|
15492
|
+
if (DECLARATION_TYPES.has(child.type)) {
|
|
15493
|
+
analyzeDeclaration(child, filePath, declarations, importBindings, relations);
|
|
15494
|
+
continue;
|
|
15495
|
+
}
|
|
15496
|
+
if (child.type !== "export_statement")
|
|
15497
|
+
continue;
|
|
15498
|
+
const declaration = child.namedChildren.find((node2) => DECLARATION_TYPES.has(node2.type));
|
|
15499
|
+
if (declaration) {
|
|
15500
|
+
analyzeDeclaration(declaration, filePath, declarations, importBindings, relations);
|
|
15501
|
+
}
|
|
15010
15502
|
}
|
|
15503
|
+
appendCommonJsSyntheticDeclarations(commonJs, filePath, declarations);
|
|
15504
|
+
relations.push(...collectStaticCallRelations(source, filePath, importBindings, sourceFile));
|
|
15505
|
+
return {
|
|
15506
|
+
declarations,
|
|
15507
|
+
importBindings,
|
|
15508
|
+
relations: relations.map((relation) => ({ ...relation, file: filePath })),
|
|
15509
|
+
lines: countLines(source),
|
|
15510
|
+
disposition: "analyzed",
|
|
15511
|
+
diagnostics: []
|
|
15512
|
+
};
|
|
15513
|
+
} finally {
|
|
15514
|
+
tree.delete();
|
|
15011
15515
|
}
|
|
15012
|
-
appendCommonJsSyntheticDeclarations(commonJs, filePath, declarations);
|
|
15013
|
-
relations.push(...collectStaticCallRelations(source, filePath, importBindings));
|
|
15014
|
-
return {
|
|
15015
|
-
declarations,
|
|
15016
|
-
importBindings,
|
|
15017
|
-
relations,
|
|
15018
|
-
lines: countLines(source),
|
|
15019
|
-
disposition: "analyzed",
|
|
15020
|
-
diagnostics: []
|
|
15021
|
-
};
|
|
15022
15516
|
};
|
|
15023
15517
|
|
|
15024
15518
|
// src/symbolExtractor.ts
|
|
@@ -15030,6 +15524,7 @@ var relationIdentity = (relation) => JSON.stringify([
|
|
|
15030
15524
|
relation.grounding,
|
|
15031
15525
|
relation.confidence,
|
|
15032
15526
|
relation.source,
|
|
15527
|
+
relation.file ?? null,
|
|
15033
15528
|
relation.line ?? null
|
|
15034
15529
|
]);
|
|
15035
15530
|
var uniqueRelations = (relations) => {
|
|
@@ -15069,14 +15564,19 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
15069
15564
|
continue;
|
|
15070
15565
|
const declKey = `${tracedExport.declarationFile}::${tracedExport.localName}`;
|
|
15071
15566
|
const exportKey = `${declKey}::${tracedExport.exportedName}`;
|
|
15072
|
-
if (exportedDeclarationKeys.has(exportKey))
|
|
15567
|
+
if (exportedDeclarationKeys.has(exportKey)) {
|
|
15568
|
+
const existing = exportedSymbols.find((symbol) => symbol.file === tracedExport.declarationFile && symbol.name === tracedExport.exportedName);
|
|
15569
|
+
if (existing !== undefined)
|
|
15570
|
+
existing.publicEntrypoints = [...new Set([...existing.publicEntrypoints, entry.path])].sort();
|
|
15073
15571
|
continue;
|
|
15572
|
+
}
|
|
15074
15573
|
exportedDeclarationKeys.add(declKey);
|
|
15075
15574
|
exportedDeclarationKeys.add(exportKey);
|
|
15076
15575
|
exportedSymbols.push({
|
|
15077
15576
|
...declaration.info,
|
|
15078
15577
|
name: tracedExport.exportedName,
|
|
15079
|
-
visibility: "exported" /* Exported
|
|
15578
|
+
visibility: "exported" /* Exported */,
|
|
15579
|
+
publicEntrypoints: [entry.path]
|
|
15080
15580
|
});
|
|
15081
15581
|
}
|
|
15082
15582
|
}
|
|
@@ -15098,34 +15598,7 @@ var extractSymbols = async (entries, fs, options) => {
|
|
|
15098
15598
|
}
|
|
15099
15599
|
}
|
|
15100
15600
|
const symbols = [...exportedSymbols, ...internalSymbols];
|
|
15101
|
-
|
|
15102
|
-
for (const analysis of analyses.values()) {
|
|
15103
|
-
for (const [name, decl] of analysis.declarations) {
|
|
15104
|
-
if (decl.info.kind === "interface" || decl.info.kind === "type") {
|
|
15105
|
-
typeDeclarations.set(name, decl.info.file);
|
|
15106
|
-
}
|
|
15107
|
-
}
|
|
15108
|
-
}
|
|
15109
|
-
for (const sym of symbols) {
|
|
15110
|
-
if (sym.kind !== "component")
|
|
15111
|
-
continue;
|
|
15112
|
-
let propsTypeName;
|
|
15113
|
-
if (sym.typeAnnotation) {
|
|
15114
|
-
const genericBody = /<(.+)>/u.exec(sym.typeAnnotation)?.[1];
|
|
15115
|
-
const genericNames = genericBody?.match(/\b[A-Z][A-Za-z0-9_]*\b/gu) ?? [];
|
|
15116
|
-
propsTypeName = genericNames.filter((name) => typeDeclarations.has(name)).at(-1);
|
|
15117
|
-
}
|
|
15118
|
-
if (!propsTypeName) {
|
|
15119
|
-
const conventionName = `${sym.name}Props`;
|
|
15120
|
-
if (typeDeclarations.has(conventionName)) {
|
|
15121
|
-
propsTypeName = conventionName;
|
|
15122
|
-
}
|
|
15123
|
-
}
|
|
15124
|
-
if (propsTypeName) {
|
|
15125
|
-
sym.propsType = propsTypeName;
|
|
15126
|
-
relations.push(createRelation("of_type" /* OfType */, sym.name, propsTypeName, false, sym.line));
|
|
15127
|
-
}
|
|
15128
|
-
}
|
|
15601
|
+
await enrichPublicContracts({ symbols, paths: [...analyses.keys()], fs, resolver, relations });
|
|
15129
15602
|
const deduplicatedRelations = uniqueRelations(relations);
|
|
15130
15603
|
const files = [...filePaths].sort().map((filePath) => ({
|
|
15131
15604
|
path: filePath,
|
|
@@ -15224,20 +15697,20 @@ class TypeScriptPlugin {
|
|
|
15224
15697
|
}
|
|
15225
15698
|
}
|
|
15226
15699
|
// src/reactRouter.ts
|
|
15227
|
-
import * as
|
|
15700
|
+
import * as ts9 from "typescript";
|
|
15228
15701
|
function compact(value) {
|
|
15229
15702
|
return value.replace(/\s+/gu, " ").trim();
|
|
15230
15703
|
}
|
|
15231
15704
|
function scalarValue(node2) {
|
|
15232
15705
|
if (!node2)
|
|
15233
15706
|
return;
|
|
15234
|
-
if (
|
|
15707
|
+
if (ts9.isStringLiteralLike(node2) || ts9.isNoSubstitutionTemplateLiteral(node2))
|
|
15235
15708
|
return node2.text;
|
|
15236
|
-
if (
|
|
15709
|
+
if (ts9.isNumericLiteral(node2))
|
|
15237
15710
|
return Number(node2.text);
|
|
15238
|
-
if (node2.kind ===
|
|
15711
|
+
if (node2.kind === ts9.SyntaxKind.TrueKeyword)
|
|
15239
15712
|
return true;
|
|
15240
|
-
if (node2.kind ===
|
|
15713
|
+
if (node2.kind === ts9.SyntaxKind.FalseKeyword)
|
|
15241
15714
|
return false;
|
|
15242
15715
|
return;
|
|
15243
15716
|
}
|
|
@@ -15246,37 +15719,37 @@ function findDynamicImport(node2) {
|
|
|
15246
15719
|
const visit2 = (child) => {
|
|
15247
15720
|
if (result)
|
|
15248
15721
|
return;
|
|
15249
|
-
if (
|
|
15722
|
+
if (ts9.isCallExpression(child) && child.expression.kind === ts9.SyntaxKind.ImportKeyword && child.arguments[0] && ts9.isStringLiteralLike(child.arguments[0])) {
|
|
15250
15723
|
result = child.arguments[0].text;
|
|
15251
15724
|
return;
|
|
15252
15725
|
}
|
|
15253
|
-
|
|
15726
|
+
ts9.forEachChild(child, visit2);
|
|
15254
15727
|
};
|
|
15255
15728
|
visit2(node2);
|
|
15256
15729
|
return result;
|
|
15257
15730
|
}
|
|
15258
15731
|
function parseSource(source, filePath) {
|
|
15259
|
-
const sourceFile =
|
|
15732
|
+
const sourceFile = ts9.createSourceFile(filePath, source, ts9.ScriptTarget.Latest, true, filePath.endsWith(".tsx") ? ts9.ScriptKind.TSX : ts9.ScriptKind.TS);
|
|
15260
15733
|
const imports = new Map;
|
|
15261
15734
|
const constants2 = new Map;
|
|
15262
15735
|
for (const statement of sourceFile.statements) {
|
|
15263
|
-
if (
|
|
15736
|
+
if (ts9.isImportDeclaration(statement) && ts9.isStringLiteral(statement.moduleSpecifier)) {
|
|
15264
15737
|
const moduleSource = statement.moduleSpecifier.text;
|
|
15265
15738
|
const clause = statement.importClause;
|
|
15266
15739
|
if (clause?.name)
|
|
15267
15740
|
imports.set(clause.name.text, moduleSource);
|
|
15268
15741
|
const bindings = clause?.namedBindings;
|
|
15269
|
-
if (bindings &&
|
|
15742
|
+
if (bindings && ts9.isNamedImports(bindings)) {
|
|
15270
15743
|
for (const element of bindings.elements)
|
|
15271
15744
|
imports.set(element.name.text, moduleSource);
|
|
15272
15745
|
}
|
|
15273
|
-
if (bindings &&
|
|
15746
|
+
if (bindings && ts9.isNamespaceImport(bindings))
|
|
15274
15747
|
imports.set(bindings.name.text, moduleSource);
|
|
15275
15748
|
}
|
|
15276
|
-
if (!
|
|
15749
|
+
if (!ts9.isVariableStatement(statement))
|
|
15277
15750
|
continue;
|
|
15278
15751
|
for (const declaration of statement.declarationList.declarations) {
|
|
15279
|
-
if (!
|
|
15752
|
+
if (!ts9.isIdentifier(declaration.name) || !declaration.initializer)
|
|
15280
15753
|
continue;
|
|
15281
15754
|
const scalar = scalarValue(declaration.initializer);
|
|
15282
15755
|
if (scalar !== undefined)
|
|
@@ -15305,13 +15778,13 @@ function routeConditions(node2, sourceFile) {
|
|
|
15305
15778
|
let current = node2;
|
|
15306
15779
|
while (current?.parent) {
|
|
15307
15780
|
const parent = current.parent;
|
|
15308
|
-
if (
|
|
15781
|
+
if (ts9.isConditionalExpression(parent)) {
|
|
15309
15782
|
const condition = compact(parent.condition.getText(sourceFile));
|
|
15310
15783
|
conditions.push(current === parent.whenTrue ? condition : `!(${condition})`);
|
|
15311
|
-
} else if (
|
|
15784
|
+
} else if (ts9.isBinaryExpression(parent) && parent.operatorToken.kind === ts9.SyntaxKind.AmpersandAmpersandToken && current === parent.right) {
|
|
15312
15785
|
conditions.push(compact(parent.left.getText(sourceFile)));
|
|
15313
15786
|
}
|
|
15314
|
-
if (
|
|
15787
|
+
if (ts9.isFunctionLike(parent))
|
|
15315
15788
|
break;
|
|
15316
15789
|
current = parent;
|
|
15317
15790
|
}
|
|
@@ -15320,36 +15793,36 @@ function routeConditions(node2, sourceFile) {
|
|
|
15320
15793
|
function jsxAttributes(node2) {
|
|
15321
15794
|
const result = new Map;
|
|
15322
15795
|
for (const property of node2.attributes.properties)
|
|
15323
|
-
if (
|
|
15796
|
+
if (ts9.isJsxAttribute(property))
|
|
15324
15797
|
result.set(property.name.getText(), property);
|
|
15325
15798
|
return result;
|
|
15326
15799
|
}
|
|
15327
15800
|
function jsxExpression(attribute) {
|
|
15328
15801
|
const initializer = attribute?.initializer;
|
|
15329
|
-
return initializer &&
|
|
15802
|
+
return initializer && ts9.isJsxExpression(initializer) ? initializer.expression : undefined;
|
|
15330
15803
|
}
|
|
15331
15804
|
function jsxScalar(attribute, constants2) {
|
|
15332
15805
|
if (!attribute)
|
|
15333
15806
|
return;
|
|
15334
15807
|
if (!attribute.initializer)
|
|
15335
15808
|
return true;
|
|
15336
|
-
if (
|
|
15809
|
+
if (ts9.isStringLiteral(attribute.initializer))
|
|
15337
15810
|
return attribute.initializer.text;
|
|
15338
15811
|
const expression = jsxExpression(attribute);
|
|
15339
|
-
return scalarValue(expression) ?? (expression &&
|
|
15812
|
+
return scalarValue(expression) ?? (expression && ts9.isIdentifier(expression) ? constants2.get(expression.text) : undefined);
|
|
15340
15813
|
}
|
|
15341
15814
|
function descendantTags(node2) {
|
|
15342
15815
|
const tags = new Set;
|
|
15343
15816
|
const visit2 = (child) => {
|
|
15344
|
-
if (
|
|
15345
|
-
const opening =
|
|
15817
|
+
if (ts9.isJsxElement(child) || ts9.isJsxSelfClosingElement(child)) {
|
|
15818
|
+
const opening = ts9.isJsxElement(child) ? child.openingElement : child;
|
|
15346
15819
|
const tag = opening.tagName.getText();
|
|
15347
15820
|
if (child !== node2 && tag === "Route")
|
|
15348
15821
|
return;
|
|
15349
15822
|
if (!["Route", "Routes", "Suspense", "Fragment", "React.Fragment", "Navigate"].includes(tag))
|
|
15350
15823
|
tags.add(tag);
|
|
15351
15824
|
}
|
|
15352
|
-
|
|
15825
|
+
ts9.forEachChild(child, visit2);
|
|
15353
15826
|
};
|
|
15354
15827
|
visit2(node2);
|
|
15355
15828
|
return [...tags];
|
|
@@ -15359,8 +15832,8 @@ function navigateTarget(node2, sourceFile) {
|
|
|
15359
15832
|
const visit2 = (child) => {
|
|
15360
15833
|
if (target)
|
|
15361
15834
|
return;
|
|
15362
|
-
if (
|
|
15363
|
-
const opening =
|
|
15835
|
+
if (ts9.isJsxElement(child) || ts9.isJsxSelfClosingElement(child)) {
|
|
15836
|
+
const opening = ts9.isJsxElement(child) ? child.openingElement : child;
|
|
15364
15837
|
if (child !== node2 && opening.tagName.getText() === "Route")
|
|
15365
15838
|
return;
|
|
15366
15839
|
if (opening.tagName.getText() === "Navigate") {
|
|
@@ -15375,7 +15848,7 @@ function navigateTarget(node2, sourceFile) {
|
|
|
15375
15848
|
}
|
|
15376
15849
|
}
|
|
15377
15850
|
}
|
|
15378
|
-
|
|
15851
|
+
ts9.forEachChild(child, visit2);
|
|
15379
15852
|
};
|
|
15380
15853
|
visit2(node2);
|
|
15381
15854
|
return target;
|
|
@@ -15392,12 +15865,12 @@ function componentSource(component, imports) {
|
|
|
15392
15865
|
}
|
|
15393
15866
|
function objectProperty(object2, name) {
|
|
15394
15867
|
for (const property of object2.properties) {
|
|
15395
|
-
if (!
|
|
15868
|
+
if (!ts9.isPropertyAssignment(property) && !ts9.isShorthandPropertyAssignment(property))
|
|
15396
15869
|
continue;
|
|
15397
|
-
const key = property.name && (
|
|
15870
|
+
const key = property.name && (ts9.isIdentifier(property.name) || ts9.isStringLiteralLike(property.name)) ? property.name.text : undefined;
|
|
15398
15871
|
if (key !== name)
|
|
15399
15872
|
continue;
|
|
15400
|
-
return
|
|
15873
|
+
return ts9.isPropertyAssignment(property) ? property.initializer : property.name;
|
|
15401
15874
|
}
|
|
15402
15875
|
return;
|
|
15403
15876
|
}
|
|
@@ -15439,7 +15912,7 @@ function extractReactRouterRoutes(source, filePath, options = {}) {
|
|
|
15439
15912
|
};
|
|
15440
15913
|
const visitRouteObjects = (array, parentPath) => {
|
|
15441
15914
|
for (const element of array.elements) {
|
|
15442
|
-
if (!
|
|
15915
|
+
if (!ts9.isObjectLiteralExpression(element))
|
|
15443
15916
|
continue;
|
|
15444
15917
|
const index = scalarValue(objectProperty(element, "index")) === true;
|
|
15445
15918
|
const pathValue = scalarValue(objectProperty(element, "path"));
|
|
@@ -15455,13 +15928,13 @@ function extractReactRouterRoutes(source, filePath, options = {}) {
|
|
|
15455
15928
|
index,
|
|
15456
15929
|
...component ? { component } : {},
|
|
15457
15930
|
...typeof redirect === "string" ? { redirectTo: redirect } : {},
|
|
15458
|
-
...children &&
|
|
15931
|
+
...children && ts9.isArrayLiteralExpression(children) ? { children } : {}
|
|
15459
15932
|
});
|
|
15460
15933
|
}
|
|
15461
15934
|
};
|
|
15462
15935
|
const visit2 = (node2, parentPath) => {
|
|
15463
|
-
if (
|
|
15464
|
-
const opening =
|
|
15936
|
+
if (ts9.isJsxElement(node2) || ts9.isJsxSelfClosingElement(node2)) {
|
|
15937
|
+
const opening = ts9.isJsxElement(node2) ? node2.openingElement : node2;
|
|
15465
15938
|
if (opening.tagName.getText() === "Route") {
|
|
15466
15939
|
const attributes = jsxAttributes(opening);
|
|
15467
15940
|
const index = jsxScalar(attributes.get("index"), parsed.constants) === true;
|
|
@@ -15474,30 +15947,30 @@ function extractReactRouterRoutes(source, filePath, options = {}) {
|
|
|
15474
15947
|
const fullPath = joinRoutePath(parentPath, typeof pathValue === "string" ? pathValue : "", index);
|
|
15475
15948
|
const redirectTo = navigateTarget(candidateNode, parsed.sourceFile);
|
|
15476
15949
|
pushRoute({ node: node2, parentPath, path: typeof pathValue === "string" ? pathValue : "", index, ...component ? { component } : {}, candidates, ...redirectTo ? { redirectTo } : {} });
|
|
15477
|
-
if (
|
|
15950
|
+
if (ts9.isJsxElement(node2))
|
|
15478
15951
|
for (const child of node2.children)
|
|
15479
15952
|
visit2(child, fullPath);
|
|
15480
15953
|
return;
|
|
15481
15954
|
}
|
|
15482
15955
|
}
|
|
15483
|
-
if (
|
|
15956
|
+
if (ts9.isCallExpression(node2)) {
|
|
15484
15957
|
const callee = node2.expression.getText(parsed.sourceFile);
|
|
15485
|
-
if ((callee === "createBrowserRouter" || callee === "createHashRouter" || callee === "useRoutes") && node2.arguments[0] &&
|
|
15958
|
+
if ((callee === "createBrowserRouter" || callee === "createHashRouter" || callee === "useRoutes") && node2.arguments[0] && ts9.isArrayLiteralExpression(node2.arguments[0])) {
|
|
15486
15959
|
visitRouteObjects(node2.arguments[0], mountPath);
|
|
15487
15960
|
}
|
|
15488
15961
|
}
|
|
15489
|
-
|
|
15962
|
+
ts9.forEachChild(node2, (child) => visit2(child, parentPath));
|
|
15490
15963
|
};
|
|
15491
15964
|
visit2(parsed.sourceFile, mountPath);
|
|
15492
15965
|
return routes.sort((left, right) => left.fullPath.localeCompare(right.fullPath) || left.location.startLine - right.location.startLine || left.location.startColumn - right.location.startColumn);
|
|
15493
15966
|
}
|
|
15494
15967
|
// src/moduleExports.ts
|
|
15495
|
-
import * as
|
|
15968
|
+
import * as ts10 from "typescript";
|
|
15496
15969
|
function exportedDeclarationName(statement) {
|
|
15497
|
-
const exported =
|
|
15970
|
+
const exported = ts10.canHaveModifiers(statement) && ts10.getModifiers(statement)?.some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword);
|
|
15498
15971
|
if (!exported)
|
|
15499
15972
|
return;
|
|
15500
|
-
if ((
|
|
15973
|
+
if ((ts10.isFunctionDeclaration(statement) || ts10.isClassDeclaration(statement) || ts10.isInterfaceDeclaration(statement) || ts10.isTypeAliasDeclaration(statement) || ts10.isEnumDeclaration(statement)) && statement.name) {
|
|
15501
15974
|
return statement.name.text;
|
|
15502
15975
|
}
|
|
15503
15976
|
return;
|
|
@@ -15508,17 +15981,17 @@ function extractTypeScriptModuleExports(source, filePath = "module.ts") {
|
|
|
15508
15981
|
const wildcard = new Set;
|
|
15509
15982
|
const targets = new Set;
|
|
15510
15983
|
for (const statement of sourceFile.statements) {
|
|
15511
|
-
if (
|
|
15512
|
-
const target = statement.moduleSpecifier &&
|
|
15984
|
+
if (ts10.isExportDeclaration(statement)) {
|
|
15985
|
+
const target = statement.moduleSpecifier && ts10.isStringLiteral(statement.moduleSpecifier) ? statement.moduleSpecifier.text : undefined;
|
|
15513
15986
|
if (target)
|
|
15514
15987
|
targets.add(target);
|
|
15515
15988
|
if (!statement.exportClause) {
|
|
15516
15989
|
if (target)
|
|
15517
15990
|
wildcard.add(target);
|
|
15518
|
-
} else if (
|
|
15991
|
+
} else if (ts10.isNamedExports(statement.exportClause)) {
|
|
15519
15992
|
for (const element of statement.exportClause.elements)
|
|
15520
15993
|
named.add(element.name.text);
|
|
15521
|
-
} else if (
|
|
15994
|
+
} else if (ts10.isNamespaceExport(statement.exportClause)) {
|
|
15522
15995
|
named.add(statement.exportClause.name.text);
|
|
15523
15996
|
}
|
|
15524
15997
|
continue;
|
|
@@ -15526,9 +15999,9 @@ function extractTypeScriptModuleExports(source, filePath = "module.ts") {
|
|
|
15526
15999
|
const declarationName2 = exportedDeclarationName(statement);
|
|
15527
16000
|
if (declarationName2)
|
|
15528
16001
|
named.add(declarationName2);
|
|
15529
|
-
if (
|
|
16002
|
+
if (ts10.isVariableStatement(statement) && ts10.getModifiers(statement)?.some((modifier) => modifier.kind === ts10.SyntaxKind.ExportKeyword)) {
|
|
15530
16003
|
for (const declaration of statement.declarationList.declarations) {
|
|
15531
|
-
if (
|
|
16004
|
+
if (ts10.isIdentifier(declaration.name))
|
|
15532
16005
|
named.add(declaration.name.text);
|
|
15533
16006
|
}
|
|
15534
16007
|
}
|
|
@@ -15593,6 +16066,8 @@ export {
|
|
|
15593
16066
|
extractReactRouterRoutes,
|
|
15594
16067
|
extractEcmaScriptModuleExports,
|
|
15595
16068
|
ecmaScriptLanguage,
|
|
16069
|
+
componentPropsName,
|
|
16070
|
+
componentBindingDefaults,
|
|
15596
16071
|
TypeScriptPlugin,
|
|
15597
16072
|
EXTRACT_TS_COVERAGE_TIER,
|
|
15598
16073
|
EXTRACT_TS_CAPABILITIES
|