MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / isExternalImport

Function isExternalImport

src/resolution/import-resolver.ts:298–377  ·  view source on GitHub ↗

* Check if an import is external (npm package, etc.) * * `context` is consulted for project-defined path aliases * (tsconfig/jsconfig `paths`). Without that check, custom prefixes * like `@components/*` would fail the bare-specifier heuristic and * be classified as external before alias resolut

(
  importPath: string,
  language: Language,
  context?: ResolutionContext
)

Source from the content-addressed store, hash-verified

296 * be classified as external before alias resolution can run.
297 */
298function isExternalImport(
299 importPath: string,
300 language: Language,
301 context?: ResolutionContext
302): boolean {
303 // Relative imports are not external
304 if (importPath.startsWith('.')) {
305 return false;
306 }
307
308 // Workspace-member imports (`@scope/ui`, `@scope/ui/widgets`) are LOCAL to
309 // a monorepo even though they look like bare npm specifiers. Consult the
310 // workspace map first so they aren't misclassified as external (#629). The
311 // map is null for single-package repos, so this is a no-op there.
312 const workspaces = context?.getWorkspacePackages?.();
313 if (workspaces && resolveWorkspaceImport(importPath, workspaces)) {
314 return false;
315 }
316
317 // Common external patterns
318 if (language === 'typescript' || language === 'javascript' || language === 'tsx' || language === 'jsx' || language === 'arkts') {
319 // Node built-ins
320 if (['fs', 'path', 'os', 'crypto', 'http', 'https', 'url', 'util', 'events', 'stream', 'child_process', 'buffer'].includes(importPath)) {
321 return true;
322 }
323 // Project-defined alias prefix? Treat as local.
324 const aliases = context?.getProjectAliases?.();
325 if (aliases) {
326 for (const pat of aliases.patterns) {
327 if (importPath.startsWith(pat.prefix)) return false;
328 }
329 }
330 // Scoped packages or bare specifiers that don't start with aliases
331 if (!importPath.startsWith('@/') && !importPath.startsWith('~/') && !importPath.startsWith('src/')) {
332 // Likely an npm package
333 return true;
334 }
335 }
336
337 if (language === 'python') {
338 // Standard library modules
339 const stdLibs = ['os', 'sys', 'json', 're', 'math', 'datetime', 'collections', 'typing', 'pathlib', 'logging'];
340 if (stdLibs.includes(importPath.split('.')[0]!)) {
341 return true;
342 }
343 }
344
345 if (language === 'go') {
346 // Relative imports (rare in idiomatic Go but the grammar allows them).
347 if (importPath.startsWith('.')) {
348 return false;
349 }
350 // In-module imports look like `<module-path>/sub/pkg` — local to
351 // this project. Without the module-path check we'd flag every
352 // cross-package call in a Go monorepo as external (issue #388).
353 const mod = context?.getGoModule?.();
354 if (mod && (importPath === mod.modulePath || importPath.startsWith(mod.modulePath + '/'))) {
355 return false;

Callers 1

Calls 5

resolveWorkspaceImportFunction · 0.90
getWorkspacePackagesMethod · 0.80
getProjectAliasesMethod · 0.80
getGoModuleMethod · 0.80
hasMethod · 0.80

Tested by

no test coverage detected