Skip to content

Commit 3656b33

Browse files
committed
Merge remote-tracking branch 'origin/feat/dynamic-sql-edge-cases' into fix/review-672
2 parents d3aea40 + 2b755f0 commit 3656b33

7 files changed

Lines changed: 71 additions & 11 deletions

File tree

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@
44
"description": "Local code graph CLI — parse codebases with tree-sitter, build dependency graphs, query them",
55
"type": "module",
66
"main": "dist/index.js",
7+
"imports": {
8+
"#shared/*": { "@codegraph/source": "./src/shared/*", "default": "./dist/shared/*" },
9+
"#infrastructure/*": { "@codegraph/source": "./src/infrastructure/*", "default": "./dist/infrastructure/*" },
10+
"#db/*": { "@codegraph/source": "./src/db/*", "default": "./dist/db/*" },
11+
"#domain/*": { "@codegraph/source": "./src/domain/*", "default": "./dist/domain/*" },
12+
"#features/*": { "@codegraph/source": "./src/features/*", "default": "./dist/features/*" },
13+
"#presentation/*": { "@codegraph/source": "./src/presentation/*", "default": "./dist/presentation/*" },
14+
"#graph/*": { "@codegraph/source": "./src/graph/*", "default": "./dist/graph/*" },
15+
"#mcp/*": { "@codegraph/source": "./src/mcp/*", "default": "./dist/mcp/*" },
16+
"#ast-analysis/*": { "@codegraph/source": "./src/ast-analysis/*", "default": "./dist/ast-analysis/*" },
17+
"#extractors/*": { "@codegraph/source": "./src/extractors/*", "default": "./dist/extractors/*" },
18+
"#cli/*": { "@codegraph/source": "./src/cli/*", "default": "./dist/cli/*" },
19+
"#types": { "@codegraph/source": "./src/types.ts", "default": "./dist/types.js" }
20+
},
721
"exports": {
822
".": {
923
"import": "./dist/index.js",

scripts/verify-imports.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,37 @@ import { fileURLToPath } from 'node:url';
1717

1818
const __filename = fileURLToPath(import.meta.url);
1919
const __dirname = dirname(__filename);
20-
const srcDir = resolve(__dirname, '..', 'src');
20+
const projectRoot = resolve(__dirname, '..');
21+
const srcDir = resolve(projectRoot, 'src');
22+
23+
// ── load package.json subpath imports ───────────────────────────────────
24+
const pkg = JSON.parse(readFileSync(resolve(projectRoot, 'package.json'), 'utf8'));
25+
const subpathImports: Record<string, unknown> = pkg.imports || {};
26+
27+
/** Resolve a #-prefixed subpath import to an absolute file path (source condition). */
28+
function resolveSubpathImport(specifier: string): string | null {
29+
for (const [pattern, mapping] of Object.entries(subpathImports)) {
30+
const target =
31+
typeof mapping === 'string'
32+
? mapping
33+
: (mapping as Record<string, string>)['@codegraph/source'] ??
34+
(mapping as Record<string, string>).default;
35+
if (!target) continue;
36+
37+
// Exact match (e.g., "#types")
38+
if (pattern === specifier) return resolve(projectRoot, target);
39+
40+
// Wildcard match (e.g., "#shared/*")
41+
if (pattern.includes('*')) {
42+
const prefix = pattern.slice(0, pattern.indexOf('*'));
43+
if (specifier.startsWith(prefix)) {
44+
const rest = specifier.slice(prefix.length);
45+
return resolve(projectRoot, target.replace('*', rest));
46+
}
47+
}
48+
}
49+
return null;
50+
}
2151

2252
// ── collect source files ────────────────────────────────────────────────
2353
function walk(dir) {
@@ -102,6 +132,18 @@ function extractDynamicImports(filePath) {
102132

103133
// ── resolve a specifier to a file on disk ───────────────────────────────
104134
function resolveSpecifier(specifier, fromFile) {
135+
// Handle #-prefixed subpath imports via package.json "imports" field
136+
if (specifier.startsWith('#')) {
137+
const resolved = resolveSubpathImport(specifier);
138+
if (!resolved) return specifier; // no matching pattern — broken
139+
if (existsSync(resolved) && statSync(resolved).isFile()) return null;
140+
if (resolved.endsWith('.js')) {
141+
const tsTarget = resolved.replace(/\.js$/, '.ts');
142+
if (existsSync(tsTarget) && statSync(tsTarget).isFile()) return null;
143+
}
144+
return specifier; // mapped but file missing — broken
145+
}
146+
105147
// Skip bare specifiers (packages): 'node:*', '@scope/pkg', 'pkg'
106148
if (!specifier.startsWith('.') && !specifier.startsWith('/')) return null;
107149

src/domain/graph/builder/stages/build-edges.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
*/
77
import path from 'node:path';
88
import { performance } from 'node:perf_hooks';
9-
import { getNodeId } from '../../../../db/index.js';
10-
import { debug } from '../../../../infrastructure/logger.js';
11-
import { loadNative } from '../../../../infrastructure/native.js';
9+
import { getNodeId } from '#db/index.js';
10+
import { debug } from '#infrastructure/logger.js';
11+
import { loadNative } from '#infrastructure/native.js';
1212
import type {
1313
BetterSqlite3Database,
1414
Call,
@@ -18,7 +18,7 @@ import type {
1818
NativeAddon,
1919
NodeRow,
2020
TypeMapEntry,
21-
} from '../../../../types.js';
21+
} from '#types';
2222
import { computeConfidence } from '../../resolve.js';
2323
import type { PipelineContext } from '../context.js';
2424
import { BUILTIN_RECEIVERS, batchInsertEdges } from '../helpers.js';

src/domain/graph/builder/stages/build-structure.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
*/
66
import path from 'node:path';
77
import { performance } from 'node:perf_hooks';
8-
import { debug } from '../../../../infrastructure/logger.js';
9-
import { loadNative } from '../../../../infrastructure/native.js';
10-
import { normalizePath } from '../../../../shared/constants.js';
11-
import type { ExtractorOutput } from '../../../../types.js';
8+
import { debug } from '#infrastructure/logger.js';
9+
import { loadNative } from '#infrastructure/native.js';
10+
import { normalizePath } from '#shared/constants.js';
11+
import type { ExtractorOutput } from '#types';
1212
import type { PipelineContext } from '../context.js';
1313
import { readFileSafe } from '../helpers.js';
1414

src/domain/graph/builder/stages/collect-files.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
*/
88
import fs from 'node:fs';
99
import path from 'node:path';
10-
import { debug, info } from '../../../../infrastructure/logger.js';
11-
import { normalizePath } from '../../../../shared/constants.js';
10+
import { debug, info } from '#infrastructure/logger.js';
11+
import { normalizePath } from '#shared/constants.js';
1212
import { readJournal } from '../../journal.js';
1313
import type { PipelineContext } from '../context.js';
1414
import { collectFiles as collectFilesUtil } from '../helpers.js';

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
/* Modules */
99
"module": "nodenext",
1010
"moduleResolution": "nodenext",
11+
"customConditions": ["@codegraph/source"],
1112
"rootDir": "./src",
1213

1314
/* Emit */

vitest.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ const supportsStripTypes = major > 22 || (major === 22 && minor >= 6);
66
const stripFlag = major >= 23 ? '--strip-types' : '--experimental-strip-types';
77

88
export default defineConfig({
9+
resolve: {
10+
conditions: ['@codegraph/source'],
11+
},
912
test: {
1013
globals: true,
1114
testTimeout: 30000,

0 commit comments

Comments
 (0)