@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.
Files changed (2) hide show
  1. package/index.js +1425 -950
  2. 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, new RegExp(`(\\bauthorization\\s*:\\s*(?:bearer|basic)\\s+)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^\\s,;]+`, "giu"), (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
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, new RegExp(`([?&](?:access_token|refresh_token|api_key|password|secret)=)` + `(?!${escapeRegExp(INDEXER_OUTPUT_REDACTION_MARKER)})[^&#\\s]+`, "giu"), (_match, prefix) => `${prefix}${INDEXER_OUTPUT_REDACTION_MARKER}`, count);
11453
- const key = "(?:[A-Za-z0-9_.-]*(?:password|passwd|pwd|secret|token|credential|cookie)[A-Za-z0-9_.-]*|api[-_]?key|access[-_]?(?:key|token)|private[-_]?key|client[-_]?secret|authorization)";
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
- // ../extract/src/types.ts
12536
- var symbolKindSchema2 = exports_external.enum(Object.values(SymbolKind));
12537
- var visibilitySchema2 = exports_external.enum(Object.values(Visibility));
12538
- var relationTypeSchema = exports_external.enum([
12539
- "imports" /* Imports */,
12540
- "imports_type" /* ImportsType */,
12541
- "calls" /* Calls */,
12542
- "extends" /* Extends */,
12543
- "implements" /* Implements */,
12544
- "param_type" /* ParamType */,
12545
- "return_type" /* ReturnType */,
12546
- "of_type" /* OfType */,
12547
- "depends_on" /* DependsOn */,
12548
- "contains" /* Contains */
12549
- ]);
12550
- var relationSourceSchema = exports_external.enum([
12551
- "ast" /* Ast */,
12552
- "doc" /* Doc */,
12553
- "manual" /* Manual */
12554
- ]);
12555
- var packageKindSchema2 = exports_external.enum(Object.values(PackageKind));
12556
- var symbolParamSchema = exports_external.object({
12557
- name: exports_external.string().min(1),
12558
- type: exports_external.string().min(1).nullable()
12559
- });
12560
- var symbolInfoSchema = exports_external.lazy(() => exports_external.object({
12561
- name: exports_external.string().min(1),
12562
- kind: symbolKindSchema2,
12563
- visibility: visibilitySchema2,
12564
- file: exports_external.string().min(1),
12565
- line: exports_external.number().int().positive(),
12566
- endLine: exports_external.number().int().positive(),
12567
- members: exports_external.array(symbolInfoSchema).optional(),
12568
- params: exports_external.array(symbolParamSchema).optional(),
12569
- returnType: exports_external.string().min(1).nullable().optional(),
12570
- typeAnnotation: exports_external.string().min(1).nullable().optional(),
12571
- extends: exports_external.string().min(1).nullable().optional(),
12572
- implements: exports_external.array(exports_external.string().min(1)).optional(),
12573
- doc: exports_external.string().nullable().optional(),
12574
- propsType: exports_external.string().min(1).nullable().optional(),
12575
- unionValues: exports_external.array(exports_external.string()).optional(),
12576
- initializer: exports_external.string().min(1).nullable().optional(),
12577
- signature: exports_external.string().min(1).nullable().optional()
12578
- }));
12579
- var relationInfoSchema = exports_external.object({
12580
- type: relationTypeSchema,
12581
- from: exports_external.string().min(1),
12582
- to: exports_external.string().min(1),
12583
- isExternal: exports_external.boolean(),
12584
- grounding: groundingSchema,
12585
- confidence: exports_external.number().min(0).max(1),
12586
- source: relationSourceSchema,
12587
- line: exports_external.number().int().positive().optional()
12588
- });
12589
- var fileInfoSchema = exports_external.object({
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
- resolve(source) {
12730
- const declaredLanguage = source.language?.toLowerCase();
12731
- const manifestLanguages = new Set(source.manifests.flatMap((manifest) => MANIFEST_LANGUAGE_CANDIDATES[manifest.type] ?? []));
12732
- const candidates = this.#plugins.filter((plugin) => {
12733
- const pluginLanguages = plugin.languages.map((language) => language.toLowerCase());
12734
- if (declaredLanguage) {
12735
- return pluginLanguages.includes(declaredLanguage);
12736
- }
12737
- if (manifestLanguages.size === 0) {
12738
- return true;
12739
- }
12740
- return pluginLanguages.some((language) => manifestLanguages.has(language));
12741
- });
12742
- for (const plugin of candidates) {
12743
- if (plugin.canHandle(source)) {
12744
- return plugin;
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
- // ../extract/src/scanner.ts
12754
- import { execFile } from "node:child_process";
12755
- import { promisify } from "node:util";
12756
- var execFileAsync = promisify(execFile);
12757
- var SUPPORTED_EXTENSIONS = new Set([
12758
- ".ts",
12759
- ".tsx",
12760
- ".mts",
12761
- ".cts",
12762
- ".js",
12763
- ".jsx",
12764
- ".mjs",
12765
- ".cjs"
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 ts2 from "typescript";
14479
+ import ts7 from "typescript";
13704
14480
 
13705
14481
  // src/typescriptAst.ts
13706
- import ts from "typescript";
14482
+ import ts6 from "typescript";
13707
14483
  var scriptKind = (filePath) => {
13708
14484
  const lower = filePath.toLowerCase();
13709
14485
  if (lower.endsWith(".tsx"))
13710
- return ts.ScriptKind.TSX;
14486
+ return ts6.ScriptKind.TSX;
13711
14487
  if (lower.endsWith(".jsx"))
13712
- return ts.ScriptKind.JSX;
14488
+ return ts6.ScriptKind.JSX;
13713
14489
  if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".cjs")) {
13714
- return ts.ScriptKind.JS;
14490
+ return ts6.ScriptKind.JS;
13715
14491
  }
13716
- return ts.ScriptKind.TS;
14492
+ return ts6.ScriptKind.TS;
13717
14493
  };
13718
- var createEcmaScriptSourceFile = (source, filePath) => ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true, scriptKind(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 = ts.isJsxText(node2) || ts.isStringLiteral(node2) && ts.isJsxAttribute(node2.parent);
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
- ts.forEachChild(node2, visit2);
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 (ts.isStringLiteral(node2) || ts.isNoSubstitutionTemplateLiteral(node2))
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) => ts2.isCallExpression(node2) && ts2.isIdentifier(node2.expression) && node2.expression.text === "require" ? node2 : null;
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 (ts2.isPropertyAccessExpression(node2)) {
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 (ts2.isElementAccessExpression(node2)) {
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 (ts2.isPropertyAccessExpression(node2) && ts2.isIdentifier(node2.expression) && node2.expression.text === "module" && node2.name.text === "exports")
14568
+ if (ts7.isPropertyAccessExpression(node2) && ts7.isIdentifier(node2.expression) && node2.expression.text === "module" && node2.name.text === "exports")
13791
14569
  return true;
13792
- return ts2.isElementAccessExpression(node2) && ts2.isIdentifier(node2.expression) && node2.expression.text === "module" && staticStringValue(node2.argumentExpression) === "exports";
14570
+ return ts7.isElementAccessExpression(node2) && ts7.isIdentifier(node2.expression) && node2.expression.text === "module" && staticStringValue(node2.argumentExpression) === "exports";
13793
14571
  };
13794
- var isExportsObject = (node2) => ts2.isIdentifier(node2) && node2.text === "exports" || isModuleExports(node2);
14572
+ var isExportsObject = (node2) => ts7.isIdentifier(node2) && node2.text === "exports" || isModuleExports(node2);
13795
14573
  var isUnsupportedExportMutationCall = (node2) => {
13796
- if (ts2.isPropertyAccessExpression(node2.expression) && ts2.isIdentifier(node2.expression.expression) && node2.expression.expression.text === "Object" && ["assign", "defineProperties", "defineProperty"].includes(node2.expression.name.text) && node2.arguments[0] && isExportsObject(node2.arguments[0])) {
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 ts2.isIdentifier(node2.expression) && ["__createBinding", "__export", "__exportStar"].includes(node2.expression.text) && node2.arguments.some(isExportsObject);
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 (ts2.isPropertyAccessExpression(node2)) {
13803
- if (ts2.isIdentifier(node2.expression) && node2.expression.text === "exports") {
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 (ts2.isElementAccessExpression(node2)) {
14590
+ if (ts7.isElementAccessExpression(node2)) {
13813
14591
  const property = staticStringValue(node2.argumentExpression);
13814
- if (ts2.isIdentifier(node2.expression) && node2.expression.text === "exports" && property) {
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 (ts2.isIdentifier(expression)) {
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 (ts2.isPropertyAccessExpression(expression) && ts2.isIdentifier(expression.expression)) {
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 (ts2.isFunctionExpression(expression) || ts2.isArrowFunction(expression)) {
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 (ts2.isClassExpression(expression)) {
14633
+ if (ts7.isClassExpression(expression)) {
13856
14634
  return { name, kind: "class", line: location.line, endLine: location.endLine, params: [] };
13857
14635
  }
13858
- if (ts2.isObjectLiteralExpression(expression) || ts2.isArrayLiteralExpression(expression) || ts2.isLiteralExpression(expression)) {
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 (!ts2.isVariableStatement(statement))
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 (ts2.isIdentifier(declaration.name)) {
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 || !ts2.isObjectBindingPattern(declaration.name))
14684
+ if (!source || !ts7.isObjectBindingPattern(declaration.name))
13907
14685
  continue;
13908
14686
  for (const element of declaration.name.elements) {
13909
- if (!ts2.isIdentifier(element.name))
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 (ts2.isCallExpression(node2) && ts2.isIdentifier(node2.expression) && node2.expression.text === "require") {
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 (ts2.isCallExpression(node2) && isUnsupportedExportMutationCall(node2)) {
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 (ts2.isBinaryExpression(node2) && node2.operatorToken.kind === ts2.SyntaxKind.EqualsToken) {
13944
- if (ts2.isElementAccessExpression(node2.left)) {
13945
- const isCommonJsTarget = ts2.isIdentifier(node2.left.expression) && node2.left.expression.text === "exports" || isModuleExports(node2.left.expression) || isModuleExports(node2.left);
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
- ts2.forEachChild(node2, visit2);
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 (!ts2.isExpressionStatement(statement) || !ts2.isBinaryExpression(statement.expression))
14752
+ if (!ts7.isExpressionStatement(statement) || !ts7.isBinaryExpression(statement.expression))
13976
14753
  continue;
13977
14754
  const assignment = statement.expression;
13978
- if (assignment.operatorToken.kind !== ts2.SyntaxKind.EqualsToken)
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 (ts2.isObjectLiteralExpression(assignment.right)) {
14772
+ if (ts7.isObjectLiteralExpression(assignment.right)) {
13996
14773
  for (const property of assignment.right.properties) {
13997
- if (ts2.isShorthandPropertyAssignment(property)) {
14774
+ if (ts7.isShorthandPropertyAssignment(property)) {
13998
14775
  pushExport(result, property.name.text, property.name, line, bindingMap, sourceFile);
13999
14776
  continue;
14000
14777
  }
14001
- if (ts2.isPropertyAssignment(property)) {
14002
- const name = property.name && (ts2.isIdentifier(property.name) || ts2.isStringLiteral(property.name)) ? property.name.text : null;
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 (ts2.isMethodDeclaration(property) && property.name && ts2.isIdentifier(property.name)) {
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 (ts2.isIdentifier(assignment.right)) {
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
- exportsList.push(...await traceCommonJsExports({
14286
- analysis: commonJs,
14287
- filePath,
14288
- localDeclarations,
14289
- traceImported: (source2, importedName, exportedName) => traceImportedBinding(filePath, { source: source2, importedName }, exportedName, fs, state),
14290
- traceWildcard: async (source2) => {
14291
- const targetPath = await resolveImportSourcePath(filePath, source2, fs, state.resolver);
14292
- return targetPath ? traceFile(targetPath, fs, state) : [];
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
- var traceExports = async (entryPath, fs, resolver = { mappings: [] }) => {
14302
- const state = {
14303
- files: new Set,
14304
- cache: new Map,
14305
- inFlight: new Set,
14306
- resolver
14307
- };
14308
- const exportsList = await traceFile(entryPath, fs, state);
14309
- return {
14310
- exports: uniqueExports(exportsList),
14311
- files: [...state.files].sort()
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/symbolExtractorAst.ts
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 BUILTIN_TYPES = new Set([
14325
- "Array",
14326
- "Boolean",
14327
- "Date",
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
- return "variable" /* Variable */;
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 collectMembers = (node2, declarations, importBindings, ownerName, relations) => {
14466
- if (!node2)
14467
- return;
14468
- const members = [];
14469
- for (const child of node2.namedChildren) {
14470
- if (child.type === "public_field_definition" || child.type === "property_signature") {
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
- appendTypeRelations(relations, "return_type" /* ReturnType */, ownerName, returnType, importBindings, declarations, getLine(child));
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 members.length > 0 ? members : undefined;
14892
+ return declarations;
14522
14893
  };
14523
- var indexSignatureMember = (node2) => {
14524
- if (node2.type !== "index_signature")
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 match = /^\s*(\[[^\]]+\])\s*:?\s*([^;]+)?;?\s*$/u.exec(node2.text);
14527
- const name = match?.[1]?.trim();
14528
- const typeAnnotation = match?.[2]?.trim();
14529
- if (!name)
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 propDoc = extractJSDoc(node2);
14532
- return {
14533
- info: {
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 collectEnumValues = (node2) => {
14547
- const body = node2.namedChildren.find((child) => child.type === "enum_body") ?? null;
14548
- if (!body)
14549
- return;
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
- const name = member.childForFieldName("name")?.text ?? member.namedChildren[0]?.text;
14557
- if (!name)
14915
+ const stringNode = node2.namedChildren.find((child) => child.type === "string");
14916
+ if (!stringNode)
14558
14917
  continue;
14559
- const valueNode = member.childForFieldName("value") ?? member.namedChildren.find((child) => child !== member.childForFieldName("name")) ?? null;
14560
- const rawValue = valueNode?.text.replace(/^['"]|['"]$/gu, "");
14561
- values.push(rawValue ? `${name} = ${rawValue}` : name);
14562
- }
14563
- return values.length > 0 ? values : undefined;
14564
- };
14565
- var extractUnionLiteralValues = (typeNode) => {
14566
- if (!typeNode)
14567
- return;
14568
- if (typeNode.type === "literal_type") {
14569
- const text = typeNode.text.replace(/^['"]|['"]$/g, "");
14570
- return text ? [text] : undefined;
14571
- }
14572
- if (typeNode.type === "union_type") {
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 findObjectTypeNodes = (node2) => {
14593
- if (!node2)
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
- if (node2.type === "object_type")
14596
- return [node2];
14597
- if (node2.type === "intersection_type" || node2.type === "union_type") {
14598
- return node2.namedChildren.flatMap(findObjectTypeNodes);
14599
- }
14600
- if (node2.type === "parenthesized_type" && node2.namedChildCount > 0) {
14601
- return findObjectTypeNodes(node2.namedChildren[0]);
14602
- }
14603
- return [];
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 ts3 from "typescript";
15097
+ import ts8 from "typescript";
14608
15098
  var callTarget = (expression, sourceFile) => {
14609
- if (ts3.isIdentifier(expression))
15099
+ if (ts8.isIdentifier(expression))
14610
15100
  return expression.text === "require" ? null : expression.text;
14611
- if (ts3.isPropertyAccessExpression(expression))
15101
+ if (ts8.isPropertyAccessExpression(expression))
14612
15102
  return expression.getText(sourceFile).replace(/\s+/gu, "");
14613
- if (ts3.isElementAccessExpression(expression)) {
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 (ts3.isPropertyAccessExpression(current) || ts3.isElementAccessExpression(current)) {
15111
+ while (ts8.isPropertyAccessExpression(current) || ts8.isElementAccessExpression(current)) {
14622
15112
  current = current.expression;
14623
15113
  }
14624
- return ts3.isIdentifier(current) ? current.text : null;
15114
+ return ts8.isIdentifier(current) ? current.text : null;
14625
15115
  };
14626
15116
  var declarationName = (node2, sourceFile) => {
14627
- if (ts3.isFunctionDeclaration(node2) && node2.name)
15117
+ if (ts8.isFunctionDeclaration(node2) && node2.name)
14628
15118
  return node2.name.text;
14629
- if (ts3.isClassDeclaration(node2) && node2.name)
15119
+ if (ts8.isClassDeclaration(node2) && node2.name)
14630
15120
  return node2.name.text;
14631
- if (ts3.isVariableDeclaration(node2) && ts3.isIdentifier(node2.name))
15121
+ if (ts8.isVariableDeclaration(node2) && ts8.isIdentifier(node2.name))
14632
15122
  return node2.name.text;
14633
- if (ts3.isMethodDeclaration(node2) || ts3.isGetAccessorDeclaration(node2) || ts3.isSetAccessorDeclaration(node2)) {
15123
+ if (ts8.isMethodDeclaration(node2) || ts8.isGetAccessorDeclaration(node2) || ts8.isSetAccessorDeclaration(node2)) {
14634
15124
  const parent = node2.parent;
14635
- if (parent && ts3.isClassDeclaration(parent) && parent.name)
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 (ts3.isCallExpression(node2) || ts3.isNewExpression(node2)) {
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
- ts3.forEachChild(node2, (child) => visit2(child, namedOwner));
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 callable = getCallableFromInitializer(initializer);
14790
- const paramsNode = callable?.childForFieldName("parameters") ?? callable?.namedChildren.find((child) => child.type === "formal_parameters") ?? null;
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 = callable ? getReturnType(callable) ?? inferReturnType(callable) : null;
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, typeAnnotation, importBindings, declarations, getLine(declarator));
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 signature = `${name}(${params.map((param) => `${param.name}${param.type ? `: ${param.type}` : ""}`).join(", ")})`;
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
- if (commonJs.diagnostics.length > 0) {
14982
- return {
14983
- declarations: new Map,
14984
- importBindings: new Map,
14985
- relations: [],
14986
- lines: countLines(source),
14987
- disposition: "unsupported",
14988
- diagnostics: commonJs.diagnostics
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
- for (const child of root.namedChildren) {
15001
- if (DECLARATION_TYPES2.has(child.type)) {
15002
- analyzeDeclaration(child, filePath, declarations, importBindings, relations);
15003
- continue;
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
- if (child.type !== "export_statement")
15006
- continue;
15007
- const declaration = child.namedChildren.find((node2) => DECLARATION_TYPES2.has(node2.type));
15008
- if (declaration) {
15009
- analyzeDeclaration(declaration, filePath, declarations, importBindings, relations);
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
- const typeDeclarations = new Map;
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 ts4 from "typescript";
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 (ts4.isStringLiteralLike(node2) || ts4.isNoSubstitutionTemplateLiteral(node2))
15707
+ if (ts9.isStringLiteralLike(node2) || ts9.isNoSubstitutionTemplateLiteral(node2))
15235
15708
  return node2.text;
15236
- if (ts4.isNumericLiteral(node2))
15709
+ if (ts9.isNumericLiteral(node2))
15237
15710
  return Number(node2.text);
15238
- if (node2.kind === ts4.SyntaxKind.TrueKeyword)
15711
+ if (node2.kind === ts9.SyntaxKind.TrueKeyword)
15239
15712
  return true;
15240
- if (node2.kind === ts4.SyntaxKind.FalseKeyword)
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 (ts4.isCallExpression(child) && child.expression.kind === ts4.SyntaxKind.ImportKeyword && child.arguments[0] && ts4.isStringLiteralLike(child.arguments[0])) {
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
- ts4.forEachChild(child, visit2);
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 = ts4.createSourceFile(filePath, source, ts4.ScriptTarget.Latest, true, filePath.endsWith(".tsx") ? ts4.ScriptKind.TSX : ts4.ScriptKind.TS);
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 (ts4.isImportDeclaration(statement) && ts4.isStringLiteral(statement.moduleSpecifier)) {
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 && ts4.isNamedImports(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 && ts4.isNamespaceImport(bindings))
15746
+ if (bindings && ts9.isNamespaceImport(bindings))
15274
15747
  imports.set(bindings.name.text, moduleSource);
15275
15748
  }
15276
- if (!ts4.isVariableStatement(statement))
15749
+ if (!ts9.isVariableStatement(statement))
15277
15750
  continue;
15278
15751
  for (const declaration of statement.declarationList.declarations) {
15279
- if (!ts4.isIdentifier(declaration.name) || !declaration.initializer)
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 (ts4.isConditionalExpression(parent)) {
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 (ts4.isBinaryExpression(parent) && parent.operatorToken.kind === ts4.SyntaxKind.AmpersandAmpersandToken && current === parent.right) {
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 (ts4.isFunctionLike(parent))
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 (ts4.isJsxAttribute(property))
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 && ts4.isJsxExpression(initializer) ? initializer.expression : undefined;
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 (ts4.isStringLiteral(attribute.initializer))
15809
+ if (ts9.isStringLiteral(attribute.initializer))
15337
15810
  return attribute.initializer.text;
15338
15811
  const expression = jsxExpression(attribute);
15339
- return scalarValue(expression) ?? (expression && ts4.isIdentifier(expression) ? constants2.get(expression.text) : undefined);
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 (ts4.isJsxElement(child) || ts4.isJsxSelfClosingElement(child)) {
15345
- const opening = ts4.isJsxElement(child) ? child.openingElement : child;
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
- ts4.forEachChild(child, visit2);
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 (ts4.isJsxElement(child) || ts4.isJsxSelfClosingElement(child)) {
15363
- const opening = ts4.isJsxElement(child) ? child.openingElement : child;
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
- ts4.forEachChild(child, visit2);
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 (!ts4.isPropertyAssignment(property) && !ts4.isShorthandPropertyAssignment(property))
15868
+ if (!ts9.isPropertyAssignment(property) && !ts9.isShorthandPropertyAssignment(property))
15396
15869
  continue;
15397
- const key = property.name && (ts4.isIdentifier(property.name) || ts4.isStringLiteralLike(property.name)) ? property.name.text : undefined;
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 ts4.isPropertyAssignment(property) ? property.initializer : property.name;
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 (!ts4.isObjectLiteralExpression(element))
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 && ts4.isArrayLiteralExpression(children) ? { children } : {}
15931
+ ...children && ts9.isArrayLiteralExpression(children) ? { children } : {}
15459
15932
  });
15460
15933
  }
15461
15934
  };
15462
15935
  const visit2 = (node2, parentPath) => {
15463
- if (ts4.isJsxElement(node2) || ts4.isJsxSelfClosingElement(node2)) {
15464
- const opening = ts4.isJsxElement(node2) ? node2.openingElement : node2;
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 (ts4.isJsxElement(node2))
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 (ts4.isCallExpression(node2)) {
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] && ts4.isArrayLiteralExpression(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
- ts4.forEachChild(node2, (child) => visit2(child, parentPath));
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 ts5 from "typescript";
15968
+ import * as ts10 from "typescript";
15496
15969
  function exportedDeclarationName(statement) {
15497
- const exported = ts5.canHaveModifiers(statement) && ts5.getModifiers(statement)?.some((modifier) => modifier.kind === ts5.SyntaxKind.ExportKeyword);
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 ((ts5.isFunctionDeclaration(statement) || ts5.isClassDeclaration(statement) || ts5.isInterfaceDeclaration(statement) || ts5.isTypeAliasDeclaration(statement) || ts5.isEnumDeclaration(statement)) && statement.name) {
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 (ts5.isExportDeclaration(statement)) {
15512
- const target = statement.moduleSpecifier && ts5.isStringLiteral(statement.moduleSpecifier) ? statement.moduleSpecifier.text : undefined;
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 (ts5.isNamedExports(statement.exportClause)) {
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 (ts5.isNamespaceExport(statement.exportClause)) {
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 (ts5.isVariableStatement(statement) && ts5.getModifiers(statement)?.some((modifier) => modifier.kind === ts5.SyntaxKind.ExportKeyword)) {
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 (ts5.isIdentifier(declaration.name))
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