@zipbul/gildash 0.5.1 → 0.7.0
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/README.ko.md +92 -52
- package/README.md +94 -51
- package/dist/index.js +7 -5
- package/dist/index.js.map +42 -28
- package/dist/migrations/0003_majestic_mongu.sql +1 -0
- package/dist/migrations/0004_cool_firestar.sql +23 -0
- package/dist/migrations/meta/0003_snapshot.json +422 -0
- package/dist/migrations/meta/0004_snapshot.json +429 -0
- package/dist/migrations/meta/_journal.json +14 -0
- package/dist/src/errors.d.ts +9 -7
- package/dist/src/extractor/relation-extractor.d.ts +2 -1
- package/dist/src/gildash/context.d.ts +91 -0
- package/dist/src/gildash/extract-api.d.ts +7 -0
- package/dist/src/gildash/graph-api.d.ts +28 -0
- package/dist/src/gildash/index.d.ts +91 -0
- package/dist/src/gildash/lifecycle.d.ts +60 -0
- package/dist/src/gildash/misc-api.d.ts +20 -0
- package/dist/src/gildash/parse-api.d.ts +9 -0
- package/dist/src/gildash/query-api.d.ts +33 -0
- package/dist/src/gildash/semantic-api.d.ts +20 -0
- package/dist/src/gildash/types.d.ts +162 -0
- package/dist/src/index.d.ts +4 -3
- package/dist/src/indexer/index-coordinator.d.ts +8 -2
- package/dist/src/indexer/relation-indexer.d.ts +6 -0
- package/dist/src/search/dependency-graph.d.ts +1 -0
- package/dist/src/search/relation-search.d.ts +11 -1
- package/dist/src/search/symbol-search.d.ts +6 -0
- package/dist/src/semantic/ast-node-utils.d.ts +9 -0
- package/dist/src/semantic/implementation-finder.d.ts +22 -0
- package/dist/src/semantic/index.d.ts +68 -0
- package/dist/src/semantic/reference-resolver.d.ts +19 -0
- package/dist/src/semantic/symbol-graph.d.ts +36 -0
- package/dist/src/semantic/tsc-program.d.ts +67 -0
- package/dist/src/semantic/type-collector.d.ts +27 -0
- package/dist/src/semantic/types.d.ts +103 -0
- package/dist/src/store/repositories/relation.repository.d.ts +14 -2
- package/dist/src/store/repositories/symbol.repository.d.ts +2 -0
- package/dist/src/store/schema.d.ts +38 -0
- package/package.json +10 -4
- package/dist/src/gildash.d.ts +0 -821
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SymbolGraph — tsc Symbol API로 심볼의 계층(parent/members/exports)을 탐색하고
|
|
3
|
+
* LRU 캐시로 결과를 재사용한다.
|
|
4
|
+
*/
|
|
5
|
+
import type { TscProgram } from "./tsc-program";
|
|
6
|
+
export interface SymbolNode {
|
|
7
|
+
/** 심볼 이름 (`ts.Symbol.getName()`) */
|
|
8
|
+
name: string;
|
|
9
|
+
/** 첫 번째 선언이 위치한 파일 경로 */
|
|
10
|
+
filePath: string;
|
|
11
|
+
/** 첫 번째 선언의 이름 식별자 `getStart()` 오프셋 */
|
|
12
|
+
position: number;
|
|
13
|
+
/** 컨테이너 심볼 (namespace·class·enum의 멤버인 경우) */
|
|
14
|
+
parent?: SymbolNode;
|
|
15
|
+
/** 클래스·인터페이스·enum의 멤버 심볼 목록 */
|
|
16
|
+
members?: SymbolNode[];
|
|
17
|
+
/** namespace의 export 심볼 목록 */
|
|
18
|
+
exports?: SymbolNode[];
|
|
19
|
+
}
|
|
20
|
+
export declare class SymbolGraph {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(program: TscProgram, capacity?: number);
|
|
23
|
+
/**
|
|
24
|
+
* `filePath`의 `position` 위치 심볼을 `SymbolNode`로 반환한다.
|
|
25
|
+
* - 프로그램이 dispose되었거나 심볼을 찾을 수 없으면 `null`을 반환한다.
|
|
26
|
+
* - 결과는 LRU 캐시에 저장된다.
|
|
27
|
+
*/
|
|
28
|
+
get(filePath: string, position: number): SymbolNode | null;
|
|
29
|
+
/**
|
|
30
|
+
* `filePath`에 해당하는 캐시 항목을 모두 제거한다.
|
|
31
|
+
* 파일 변경 시 호출하여 stale 결과를 무효화한다.
|
|
32
|
+
*/
|
|
33
|
+
invalidate(filePath: string): void;
|
|
34
|
+
/** 캐시 전체를 초기화한다. */
|
|
35
|
+
clear(): void;
|
|
36
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TscProgram — tsc Program/TypeChecker/LanguageService lifecycle manager.
|
|
3
|
+
*
|
|
4
|
+
* Wraps `ts.createLanguageService()` with a custom `LanguageServiceHost`
|
|
5
|
+
* that tracks file versions in-memory for incremental updates.
|
|
6
|
+
*
|
|
7
|
+
* All I/O is injected via the `TscProgramOptions` DI parameters so that
|
|
8
|
+
* unit tests can run without touching the filesystem.
|
|
9
|
+
*/
|
|
10
|
+
import ts from "typescript";
|
|
11
|
+
import { type Result } from "@zipbul/result";
|
|
12
|
+
import { type GildashError } from "../errors";
|
|
13
|
+
/**
|
|
14
|
+
* Reads a file at `path` and returns its content, or `undefined` if missing.
|
|
15
|
+
*/
|
|
16
|
+
export type ReadConfigFileFn = (path: string) => string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves content for files NOT tracked by the user project
|
|
19
|
+
* (e.g. TypeScript lib declarations on disk).
|
|
20
|
+
* Returns file content or `undefined` if not found.
|
|
21
|
+
*/
|
|
22
|
+
export type ResolveNonTrackedFileFn = (path: string) => string | undefined;
|
|
23
|
+
export interface TscProgramOptions {
|
|
24
|
+
/** Reads tsconfig.json content. Injected for testability. */
|
|
25
|
+
readConfigFile?: ReadConfigFileFn;
|
|
26
|
+
/** Resolves non-tracked files (ts libs, node_modules). Injected for testability. */
|
|
27
|
+
resolveNonTrackedFile?: ResolveNonTrackedFileFn;
|
|
28
|
+
}
|
|
29
|
+
export declare class TscProgram {
|
|
30
|
+
#private;
|
|
31
|
+
/** @internal — exposed for unit test verification only. */
|
|
32
|
+
readonly __testing__: {
|
|
33
|
+
host: ts.LanguageServiceHost;
|
|
34
|
+
};
|
|
35
|
+
private constructor();
|
|
36
|
+
/**
|
|
37
|
+
* Create a TscProgram from a tsconfig.json path.
|
|
38
|
+
*
|
|
39
|
+
* Parses the config, creates a LanguageServiceHost, and initializes the LanguageService.
|
|
40
|
+
* Returns `Err<GildashError>` on config read/parse failure.
|
|
41
|
+
*/
|
|
42
|
+
static create(tsconfigPath: string, options?: TscProgramOptions): Result<TscProgram, GildashError>;
|
|
43
|
+
get isDisposed(): boolean;
|
|
44
|
+
getProgram(): ts.Program;
|
|
45
|
+
getChecker(): ts.TypeChecker;
|
|
46
|
+
getLanguageService(): ts.LanguageService;
|
|
47
|
+
/**
|
|
48
|
+
* Notify that a file's content has changed (or a new file was added).
|
|
49
|
+
* Bumps the internal version so the LanguageService will re-evaluate on next query.
|
|
50
|
+
*
|
|
51
|
+
* No-op if already disposed.
|
|
52
|
+
*/
|
|
53
|
+
notifyFileChanged(filePath: string, content: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Remove a tracked file from the LanguageService host.
|
|
56
|
+
* After removal the file will no longer appear in `getScriptFileNames()`
|
|
57
|
+
* and `getScriptSnapshot()` will return `undefined` for it.
|
|
58
|
+
*
|
|
59
|
+
* No-op if already disposed or the file was never tracked.
|
|
60
|
+
*/
|
|
61
|
+
removeFile(filePath: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Dispose the LanguageService and release references.
|
|
64
|
+
* Idempotent — safe to call multiple times.
|
|
65
|
+
*/
|
|
66
|
+
dispose(): void;
|
|
67
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeCollector — tsc TypeChecker 직접 호출로 심볼의 ResolvedType을 수집한다.
|
|
3
|
+
*
|
|
4
|
+
* TscProgram에서 Program/TypeChecker를 가져와 AST를 탐색하고
|
|
5
|
+
* 각 심볼 위치의 타입을 ResolvedType으로 변환한다.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResolvedType } from "./types";
|
|
8
|
+
import type { TscProgram } from "./tsc-program";
|
|
9
|
+
export declare class TypeCollector {
|
|
10
|
+
private readonly program;
|
|
11
|
+
constructor(program: TscProgram);
|
|
12
|
+
/**
|
|
13
|
+
* `filePath`의 `position` 위치(0-based 문자 오프셋)에 있는 심볼의 타입을 수집한다.
|
|
14
|
+
*
|
|
15
|
+
* - 파일이 없거나 위치에 식별자가 없으면 `null` 반환
|
|
16
|
+
* - `TscProgram이` disposed 상태이면 throw (getProgram이 throw)
|
|
17
|
+
*/
|
|
18
|
+
collectAt(filePath: string, position: number): ResolvedType | null;
|
|
19
|
+
/**
|
|
20
|
+
* `filePath`에서 모든 선언 이름 심볼의 타입을 수집한다.
|
|
21
|
+
*
|
|
22
|
+
* 반환 Map의 key = 선언 이름 식별자의 시작 위치(0-based).
|
|
23
|
+
* 파일이 없으면 빈 Map 반환.
|
|
24
|
+
* `TscProgram`이 disposed 상태이면 throw.
|
|
25
|
+
*/
|
|
26
|
+
collectFile(filePath: string): Map<number, ResolvedType>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the gildash Semantic Layer (tsc-based).
|
|
3
|
+
*
|
|
4
|
+
* All types in this file are plain data shapes — no runtime logic.
|
|
5
|
+
* The Semantic Layer is opt-in via `Gildash.open({ semantic: true })`.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* The resolved type of a TypeScript symbol, as determined by the tsc TypeChecker.
|
|
9
|
+
*
|
|
10
|
+
* Captures the full structural description of a type including union/intersection
|
|
11
|
+
* decomposition and generic argument resolution.
|
|
12
|
+
*/
|
|
13
|
+
export interface ResolvedType {
|
|
14
|
+
/** Human-readable type string, e.g. `"string | undefined"`, `"Promise<number>"`. */
|
|
15
|
+
text: string;
|
|
16
|
+
/** Raw TypeScript `TypeFlags` bitmask. */
|
|
17
|
+
flags: number;
|
|
18
|
+
/** Whether this type is a union type (`A | B`). */
|
|
19
|
+
isUnion: boolean;
|
|
20
|
+
/** Whether this type is an intersection type (`A & B`). */
|
|
21
|
+
isIntersection: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Whether this type is a generic instantiation (has type arguments).
|
|
24
|
+
* `true` when the type was instantiated with concrete type arguments
|
|
25
|
+
* (e.g. `Promise<string>`), `false` for non-generic types or uninstantiated generics.
|
|
26
|
+
*/
|
|
27
|
+
isGeneric: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Constituent types for union or intersection.
|
|
30
|
+
* Populated only when `isUnion` or `isIntersection` is `true`.
|
|
31
|
+
*/
|
|
32
|
+
members?: ResolvedType[];
|
|
33
|
+
/**
|
|
34
|
+
* Resolved type arguments for generic instantiations.
|
|
35
|
+
* e.g. `Promise<string>` → `[{ text: "string", ... }]`
|
|
36
|
+
*/
|
|
37
|
+
typeArguments?: ResolvedType[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A single reference to a symbol, resolved via `LanguageService.findReferences`.
|
|
41
|
+
*
|
|
42
|
+
* Unlike text-based search, semantic references are based on symbol identity —
|
|
43
|
+
* renames, re-exports, and shadowed names are handled correctly.
|
|
44
|
+
*/
|
|
45
|
+
export interface SemanticReference {
|
|
46
|
+
/** Absolute path of the file containing the reference. */
|
|
47
|
+
filePath: string;
|
|
48
|
+
/** Zero-based character offset within the file. */
|
|
49
|
+
position: number;
|
|
50
|
+
/** One-based line number. */
|
|
51
|
+
line: number;
|
|
52
|
+
/** Zero-based column offset. */
|
|
53
|
+
column: number;
|
|
54
|
+
/** Whether this reference is the symbol's own declaration site. */
|
|
55
|
+
isDefinition: boolean;
|
|
56
|
+
/** Whether this reference is a write (assignment) rather than a read. */
|
|
57
|
+
isWrite: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A concrete implementation of an interface or abstract class,
|
|
61
|
+
* found via `LanguageService.getImplementationAtPosition` and
|
|
62
|
+
* `TypeChecker.isTypeAssignableTo`.
|
|
63
|
+
*
|
|
64
|
+
* Includes both explicit (`implements` keyword) and structural (duck-typing) implementations.
|
|
65
|
+
*/
|
|
66
|
+
export interface Implementation {
|
|
67
|
+
/** Absolute path of the file containing the implementation. */
|
|
68
|
+
filePath: string;
|
|
69
|
+
/** Name of the implementing symbol (class, function, or object literal). */
|
|
70
|
+
symbolName: string;
|
|
71
|
+
/** Zero-based character offset within the file. */
|
|
72
|
+
position: number;
|
|
73
|
+
/** Syntactic kind of the implementing construct. */
|
|
74
|
+
kind: 'class' | 'function' | 'object';
|
|
75
|
+
/** `true` if the `implements` keyword is explicitly present; `false` for duck-typing matches. */
|
|
76
|
+
isExplicit: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The semantic view of a module's public interface — exports augmented with resolved types.
|
|
80
|
+
*
|
|
81
|
+
* The syntax-layer extractor already captures export names and kinds.
|
|
82
|
+
* This type adds tsc-resolved type information for each export.
|
|
83
|
+
*/
|
|
84
|
+
export interface SemanticModuleInterface {
|
|
85
|
+
/** Absolute path of the module file. */
|
|
86
|
+
filePath: string;
|
|
87
|
+
/** Per-export type information. */
|
|
88
|
+
exports: SemanticExport[];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A single export entry within a {@link SemanticModuleInterface}.
|
|
92
|
+
*/
|
|
93
|
+
export interface SemanticExport {
|
|
94
|
+
/** Export name as it appears in the source. */
|
|
95
|
+
name: string;
|
|
96
|
+
/** Syntactic kind of the exported symbol. */
|
|
97
|
+
kind: string;
|
|
98
|
+
/**
|
|
99
|
+
* Resolved type of this export, or `null` if type resolution failed.
|
|
100
|
+
* `null` does not propagate as an error — the syntax-layer data remains intact.
|
|
101
|
+
*/
|
|
102
|
+
resolvedType: ResolvedType | null;
|
|
103
|
+
}
|
|
@@ -4,6 +4,7 @@ export interface RelationRecord {
|
|
|
4
4
|
type: string;
|
|
5
5
|
srcFilePath: string;
|
|
6
6
|
srcSymbolName: string | null;
|
|
7
|
+
dstProject: string;
|
|
7
8
|
dstFilePath: string;
|
|
8
9
|
dstSymbolName: string | null;
|
|
9
10
|
metaJson: string | null;
|
|
@@ -13,17 +14,28 @@ export declare class RelationRepository {
|
|
|
13
14
|
constructor(db: DbConnection);
|
|
14
15
|
replaceFileRelations(project: string, srcFilePath: string, rels: ReadonlyArray<Partial<RelationRecord>>): void;
|
|
15
16
|
getOutgoing(project: string, srcFilePath: string, srcSymbolName?: string): RelationRecord[];
|
|
16
|
-
getIncoming(
|
|
17
|
+
getIncoming(opts: {
|
|
18
|
+
dstProject: string;
|
|
19
|
+
dstFilePath: string;
|
|
20
|
+
}): RelationRecord[];
|
|
17
21
|
getByType(project: string, type: string): RelationRecord[];
|
|
18
22
|
deleteFileRelations(project: string, srcFilePath: string): void;
|
|
19
23
|
searchRelations(opts: {
|
|
20
24
|
srcFilePath?: string;
|
|
21
25
|
srcSymbolName?: string;
|
|
26
|
+
dstProject?: string;
|
|
22
27
|
dstFilePath?: string;
|
|
23
28
|
dstSymbolName?: string;
|
|
24
29
|
type?: string;
|
|
25
30
|
project?: string;
|
|
26
31
|
limit: number;
|
|
27
32
|
}): RelationRecord[];
|
|
28
|
-
retargetRelations(
|
|
33
|
+
retargetRelations(opts: {
|
|
34
|
+
dstProject: string;
|
|
35
|
+
oldFile: string;
|
|
36
|
+
oldSymbol: string | null;
|
|
37
|
+
newFile: string;
|
|
38
|
+
newSymbol: string | null;
|
|
39
|
+
newDstProject?: string;
|
|
40
|
+
}): void;
|
|
29
41
|
}
|
|
@@ -14,6 +14,7 @@ export interface SymbolRecord {
|
|
|
14
14
|
detailJson: string | null;
|
|
15
15
|
contentHash: string;
|
|
16
16
|
indexedAt: string;
|
|
17
|
+
resolvedType?: string | null;
|
|
17
18
|
}
|
|
18
19
|
export interface SearchOptions {
|
|
19
20
|
kind?: string;
|
|
@@ -50,6 +51,7 @@ export declare class SymbolRepository {
|
|
|
50
51
|
limit: number;
|
|
51
52
|
decorator?: string;
|
|
52
53
|
regex?: string;
|
|
54
|
+
resolvedType?: string;
|
|
53
55
|
}): (SymbolRecord & {
|
|
54
56
|
id: number;
|
|
55
57
|
})[];
|
|
@@ -409,6 +409,25 @@ export declare const symbols: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
409
409
|
}, {}, {
|
|
410
410
|
length: number | undefined;
|
|
411
411
|
}>;
|
|
412
|
+
resolvedType: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
413
|
+
name: "resolved_type";
|
|
414
|
+
tableName: "symbols";
|
|
415
|
+
dataType: "string";
|
|
416
|
+
columnType: "SQLiteText";
|
|
417
|
+
data: string;
|
|
418
|
+
driverParam: string;
|
|
419
|
+
notNull: false;
|
|
420
|
+
hasDefault: false;
|
|
421
|
+
isPrimaryKey: false;
|
|
422
|
+
isAutoincrement: false;
|
|
423
|
+
hasRuntimeDefault: false;
|
|
424
|
+
enumValues: [string, ...string[]];
|
|
425
|
+
baseColumn: never;
|
|
426
|
+
identity: undefined;
|
|
427
|
+
generated: undefined;
|
|
428
|
+
}, {}, {
|
|
429
|
+
length: number | undefined;
|
|
430
|
+
}>;
|
|
412
431
|
};
|
|
413
432
|
dialect: "sqlite";
|
|
414
433
|
}>;
|
|
@@ -509,6 +528,25 @@ export declare const relations: import("drizzle-orm/sqlite-core").SQLiteTableWit
|
|
|
509
528
|
}, {}, {
|
|
510
529
|
length: number | undefined;
|
|
511
530
|
}>;
|
|
531
|
+
dstProject: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
532
|
+
name: "dst_project";
|
|
533
|
+
tableName: "relations";
|
|
534
|
+
dataType: "string";
|
|
535
|
+
columnType: "SQLiteText";
|
|
536
|
+
data: string;
|
|
537
|
+
driverParam: string;
|
|
538
|
+
notNull: true;
|
|
539
|
+
hasDefault: false;
|
|
540
|
+
isPrimaryKey: false;
|
|
541
|
+
isAutoincrement: false;
|
|
542
|
+
hasRuntimeDefault: false;
|
|
543
|
+
enumValues: [string, ...string[]];
|
|
544
|
+
baseColumn: never;
|
|
545
|
+
identity: undefined;
|
|
546
|
+
generated: undefined;
|
|
547
|
+
}, {}, {
|
|
548
|
+
length: number | undefined;
|
|
549
|
+
}>;
|
|
512
550
|
dstFilePath: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
513
551
|
name: "dst_file_path";
|
|
514
552
|
tableName: "relations";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zipbul/gildash",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "TypeScript code indexing and dependency graph engine for Bun",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@ast-grep/napi": "^0.41.0",
|
|
46
46
|
"@parcel/watcher": "^2.5.6",
|
|
47
|
+
"@zipbul/result": "^0.1.4",
|
|
47
48
|
"comment-parser": "1.4.5",
|
|
48
49
|
"drizzle-orm": "^0.45.1",
|
|
49
50
|
"oxc-parser": "0.115.0"
|
|
@@ -55,10 +56,15 @@
|
|
|
55
56
|
"@commitlint/config-conventional": "^20.4.2",
|
|
56
57
|
"@types/bun": "latest",
|
|
57
58
|
"drizzle-kit": "^0.31.9",
|
|
58
|
-
"husky": "^9.1.7"
|
|
59
|
+
"husky": "^9.1.7",
|
|
60
|
+
"typescript": "^5.8.0"
|
|
59
61
|
},
|
|
60
62
|
"peerDependencies": {
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
+
"typescript": ">=5.0.0"
|
|
64
|
+
},
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"typescript": {
|
|
67
|
+
"optional": true
|
|
68
|
+
}
|
|
63
69
|
}
|
|
64
70
|
}
|