MCPcopy Create free account
hub / github.com/Graphify-Labs/graphify / _import_js

Function _import_js

graphify/extract.py:1854–1948  ·  view source on GitHub ↗
(node, source: bytes, file_nid: str, stem: str, edges: list, str_path: str, scope_stack: list[str] | None = None)

Source from the content-addressed store, hash-verified

1852
1853
1854def _import_js(node, source: bytes, file_nid: str, stem: str, edges: list, str_path: str, scope_stack: list[str] | None = None) -> None:
1855 is_reexport = node.type == "export_statement"
1856 # Only handle export_statement if it has a `from` clause (re-export).
1857 # Pure exports like `export const x = 1` or `export { localVar }` have no source module.
1858 if is_reexport:
1859 has_from = any(child.type == "from" or (_read_text(child, source) == "from") for child in node.children if child.type in ("from", "identifier"))
1860 if not has_from:
1861 # Check for string child (source path) as a more reliable indicator
1862 has_from = any(child.type == "string" for child in node.children)
1863 if not has_from:
1864 return
1865
1866 resolved_path: "Path | None" = None
1867 module_string = None
1868 for child in node.children:
1869 if child.type == "string":
1870 module_string = child
1871 break
1872 if child.type == "import_require_clause":
1873 # TS import-equals form: `import x = require("./m")`. The module
1874 # string sits inside the clause, not on the import_statement
1875 # itself, so the direct-child scan above never sees it.
1876 module_string = next(
1877 (sub for sub in child.children if sub.type == "string"), None
1878 )
1879 break
1880 if module_string is not None:
1881 raw = _read_text(module_string, source).strip("'\"` ")
1882 resolved = _resolve_js_import_target(raw, str_path)
1883 if resolved is not None:
1884 tgt_nid, resolved_path = resolved
1885 edges.append({
1886 "source": file_nid,
1887 "target": tgt_nid,
1888 "relation": "imports_from",
1889 "context": "re-export" if is_reexport else "import",
1890 "confidence": "EXTRACTED",
1891 "source_file": str_path,
1892 "source_location": f"L{node.start_point[0] + 1}",
1893 "weight": 1.0,
1894 })
1895
1896 # Emit symbol-level edges for named imports/re-exports from local/aliased files.
1897 # e.g. `import { Foo, type Bar } from './bar'` → file → Foo, file → Bar (EXTRACTED)
1898 # e.g. `export { Foo } from './bar'` → file → Foo (re_exports edge)
1899 # Uses the same _make_id(target_stem, name) key that _extract_generic emits when
1900 # defining the symbol, so these edges wire importers directly to existing symbol nodes.
1901 if resolved_path is not None:
1902 target_stem = _file_stem(resolved_path)
1903 line = node.start_point[0] + 1
1904
1905 if is_reexport:
1906 # Handle: export { foo, bar } from './module'
1907 # export { default as baz } from './module'
1908 for child in node.children:
1909 if child.type == "export_clause":
1910 for spec in child.children:
1911 if spec.type == "export_specifier":

Callers

nothing calls this directly

Calls 4

_read_textFunction · 0.90
_file_stemFunction · 0.90
_make_idFunction · 0.90

Tested by

no test coverage detected