ghostimport 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -79,6 +79,15 @@ function isBuiltin(name) {
79
79
  return BUILTIN_MODULES.has(name);
80
80
  }
81
81
  function toPackageName(importPath) {
82
+ if (importPath.startsWith("@/") || importPath.startsWith("~/") || importPath.startsWith("#") || importPath.startsWith("$")) {
83
+ return null;
84
+ }
85
+ if (/^[a-z][a-z0-9+.-]*:/i.test(importPath)) {
86
+ return null;
87
+ }
88
+ if (importPath.startsWith("\0") || importPath.startsWith("virtual:")) {
89
+ return null;
90
+ }
82
91
  if (importPath.startsWith("@")) {
83
92
  const parts = importPath.split("/");
84
93
  if (parts.length < 2) return null;
@@ -338,6 +347,27 @@ function readWorkspacePackages(dir) {
338
347
  }
339
348
  return names;
340
349
  }
350
+ function readTsconfigPaths(dir) {
351
+ const aliases = /* @__PURE__ */ new Set();
352
+ const candidates = ["tsconfig.json", "tsconfig.app.json", "jsconfig.json"];
353
+ for (const name of candidates) {
354
+ const configPath = path3.join(dir, name);
355
+ if (!fs3.existsSync(configPath)) continue;
356
+ try {
357
+ const raw = fs3.readFileSync(configPath, "utf8");
358
+ const stripped = raw.replace(/\/\/.*$/gm, "");
359
+ const config2 = JSON.parse(stripped);
360
+ const paths = config2.compilerOptions?.paths;
361
+ if (!paths) continue;
362
+ for (const key of Object.keys(paths)) {
363
+ const prefix = key.replace(/\/\*$/, "").replace(/\*$/, "");
364
+ if (prefix) aliases.add(prefix);
365
+ }
366
+ } catch {
367
+ }
368
+ }
369
+ return aliases;
370
+ }
341
371
 
342
372
  // src/scan.ts
343
373
  var CONCURRENCY = 10;
@@ -346,6 +376,7 @@ async function scan(targetDir2, { onProgress, useCache = true, scary = false, co
346
376
  const files = walkFiles(targetDir2);
347
377
  const declaredDeps = readPackageJsonDeps(targetDir2);
348
378
  const workspacePkgs = readWorkspacePackages(targetDir2);
379
+ const tsconfigAliases = readTsconfigPaths(targetDir2);
349
380
  const cache = useCache ? loadCache() : {};
350
381
  let cacheHits = 0;
351
382
  const importMap = /* @__PURE__ */ new Map();
@@ -362,7 +393,7 @@ async function scan(targetDir2, { onProgress, useCache = true, scary = false, co
362
393
  }
363
394
  }
364
395
  const allPkgs = [...importMap.keys()].filter(
365
- (pkg) => !matchesIgnore(pkg, conf.ignore) && !workspacePkgs.has(pkg)
396
+ (pkg) => !matchesIgnore(pkg, conf.ignore) && !workspacePkgs.has(pkg) && !tsconfigAliases.has(pkg)
366
397
  );
367
398
  const results2 = {
368
399
  scanned: files.length,
package/dist/files.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function walkFiles(dir: string): string[];
2
2
  export declare function readPackageJsonDeps(dir: string): Set<string>;
3
3
  export declare function readWorkspacePackages(dir: string): Set<string>;
4
+ export declare function readTsconfigPaths(dir: string): Set<string>;
package/dist/index.cjs CHANGED
@@ -112,6 +112,15 @@ function isBuiltin(name) {
112
112
  return BUILTIN_MODULES.has(name);
113
113
  }
114
114
  function toPackageName(importPath) {
115
+ if (importPath.startsWith("@/") || importPath.startsWith("~/") || importPath.startsWith("#") || importPath.startsWith("$")) {
116
+ return null;
117
+ }
118
+ if (/^[a-z][a-z0-9+.-]*:/i.test(importPath)) {
119
+ return null;
120
+ }
121
+ if (importPath.startsWith("\0") || importPath.startsWith("virtual:")) {
122
+ return null;
123
+ }
115
124
  if (importPath.startsWith("@")) {
116
125
  const parts = importPath.split("/");
117
126
  if (parts.length < 2) return null;
@@ -371,6 +380,27 @@ function readWorkspacePackages(dir) {
371
380
  }
372
381
  return names;
373
382
  }
383
+ function readTsconfigPaths(dir) {
384
+ const aliases = /* @__PURE__ */ new Set();
385
+ const candidates = ["tsconfig.json", "tsconfig.app.json", "jsconfig.json"];
386
+ for (const name of candidates) {
387
+ const configPath = import_path3.default.join(dir, name);
388
+ if (!import_fs3.default.existsSync(configPath)) continue;
389
+ try {
390
+ const raw = import_fs3.default.readFileSync(configPath, "utf8");
391
+ const stripped = raw.replace(/\/\/.*$/gm, "");
392
+ const config = JSON.parse(stripped);
393
+ const paths = config.compilerOptions?.paths;
394
+ if (!paths) continue;
395
+ for (const key of Object.keys(paths)) {
396
+ const prefix = key.replace(/\/\*$/, "").replace(/\*$/, "");
397
+ if (prefix) aliases.add(prefix);
398
+ }
399
+ } catch {
400
+ }
401
+ }
402
+ return aliases;
403
+ }
374
404
 
375
405
  // src/scan.ts
376
406
  var import_fs4 = __toESM(require("fs"), 1);
@@ -381,6 +411,7 @@ async function scan(targetDir, { onProgress, useCache = true, scary = false, con
381
411
  const files = walkFiles(targetDir);
382
412
  const declaredDeps = readPackageJsonDeps(targetDir);
383
413
  const workspacePkgs = readWorkspacePackages(targetDir);
414
+ const tsconfigAliases = readTsconfigPaths(targetDir);
384
415
  const cache = useCache ? loadCache() : {};
385
416
  let cacheHits = 0;
386
417
  const importMap = /* @__PURE__ */ new Map();
@@ -397,7 +428,7 @@ async function scan(targetDir, { onProgress, useCache = true, scary = false, con
397
428
  }
398
429
  }
399
430
  const allPkgs = [...importMap.keys()].filter(
400
- (pkg) => !matchesIgnore(pkg, conf.ignore) && !workspacePkgs.has(pkg)
431
+ (pkg) => !matchesIgnore(pkg, conf.ignore) && !workspacePkgs.has(pkg) && !tsconfigAliases.has(pkg)
401
432
  );
402
433
  const results = {
403
434
  scanned: files.length,
package/dist/index.js CHANGED
@@ -68,6 +68,15 @@ function isBuiltin(name) {
68
68
  return BUILTIN_MODULES.has(name);
69
69
  }
70
70
  function toPackageName(importPath) {
71
+ if (importPath.startsWith("@/") || importPath.startsWith("~/") || importPath.startsWith("#") || importPath.startsWith("$")) {
72
+ return null;
73
+ }
74
+ if (/^[a-z][a-z0-9+.-]*:/i.test(importPath)) {
75
+ return null;
76
+ }
77
+ if (importPath.startsWith("\0") || importPath.startsWith("virtual:")) {
78
+ return null;
79
+ }
71
80
  if (importPath.startsWith("@")) {
72
81
  const parts = importPath.split("/");
73
82
  if (parts.length < 2) return null;
@@ -327,6 +336,27 @@ function readWorkspacePackages(dir) {
327
336
  }
328
337
  return names;
329
338
  }
339
+ function readTsconfigPaths(dir) {
340
+ const aliases = /* @__PURE__ */ new Set();
341
+ const candidates = ["tsconfig.json", "tsconfig.app.json", "jsconfig.json"];
342
+ for (const name of candidates) {
343
+ const configPath = path3.join(dir, name);
344
+ if (!fs3.existsSync(configPath)) continue;
345
+ try {
346
+ const raw = fs3.readFileSync(configPath, "utf8");
347
+ const stripped = raw.replace(/\/\/.*$/gm, "");
348
+ const config = JSON.parse(stripped);
349
+ const paths = config.compilerOptions?.paths;
350
+ if (!paths) continue;
351
+ for (const key of Object.keys(paths)) {
352
+ const prefix = key.replace(/\/\*$/, "").replace(/\*$/, "");
353
+ if (prefix) aliases.add(prefix);
354
+ }
355
+ } catch {
356
+ }
357
+ }
358
+ return aliases;
359
+ }
330
360
 
331
361
  // src/scan.ts
332
362
  import fs4 from "fs";
@@ -337,6 +367,7 @@ async function scan(targetDir, { onProgress, useCache = true, scary = false, con
337
367
  const files = walkFiles(targetDir);
338
368
  const declaredDeps = readPackageJsonDeps(targetDir);
339
369
  const workspacePkgs = readWorkspacePackages(targetDir);
370
+ const tsconfigAliases = readTsconfigPaths(targetDir);
340
371
  const cache = useCache ? loadCache() : {};
341
372
  let cacheHits = 0;
342
373
  const importMap = /* @__PURE__ */ new Map();
@@ -353,7 +384,7 @@ async function scan(targetDir, { onProgress, useCache = true, scary = false, con
353
384
  }
354
385
  }
355
386
  const allPkgs = [...importMap.keys()].filter(
356
- (pkg) => !matchesIgnore(pkg, conf.ignore) && !workspacePkgs.has(pkg)
387
+ (pkg) => !matchesIgnore(pkg, conf.ignore) && !workspacePkgs.has(pkg) && !tsconfigAliases.has(pkg)
357
388
  );
358
389
  const results = {
359
390
  scanned: files.length,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghostimport",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Detects ghost imports in your code - imports that don't exist, hallucinated by AI coding tools.",
5
5
  "keywords": [
6
6
  "npm",