@rpcajr/smart-graph-indexer 1.0.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/.agents/rules/antigravity-rtk-rules.md +32 -0
- package/README.md +116 -0
- package/dist/graph.d.ts +32 -0
- package/dist/graph.js +86 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +227 -0
- package/dist/mcp_server.d.ts +48 -0
- package/dist/mcp_server.js +433 -0
- package/dist/parser.d.ts +42 -0
- package/dist/parser.js +529 -0
- package/dist/stats.d.ts +43 -0
- package/dist/stats.js +146 -0
- package/dist/ui.d.ts +2 -0
- package/dist/ui.js +1003 -0
- package/dist/vector.d.ts +66 -0
- package/dist/vector.js +144 -0
- package/dist/wasm/tree-sitter-c.wasm +0 -0
- package/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/wasm/tree-sitter-cpp.wasm +0 -0
- package/dist/wasm/tree-sitter-go.wasm +0 -0
- package/dist/wasm/tree-sitter-java.wasm +0 -0
- package/dist/wasm/tree-sitter-python.wasm +0 -0
- package/dist/wasm/tree-sitter-ruby.wasm +0 -0
- package/dist/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/wasm/tree-sitter.wasm +0 -0
- package/dist/watcher.d.ts +36 -0
- package/dist/watcher.js +166 -0
- package/mcp-config-example.json +12 -0
- package/mcp_smart_indexer_implementation_spec.md +366 -0
- package/package.json +35 -0
- package/src/graph.ts +93 -0
- package/src/index.ts +216 -0
- package/src/mcp_server.ts +454 -0
- package/src/parser.ts +484 -0
- package/src/stats.ts +156 -0
- package/src/ui.ts +956 -0
- package/src/vector.ts +166 -0
- package/src/watcher.ts +144 -0
- package/test_project/App.java +16 -0
- package/test_project/BillingService.cs +31 -0
- package/test_project/auth.ts +18 -0
- package/test_project/config.ts +11 -0
- package/test_project/database.ts +21 -0
- package/test_project/index.ts +13 -0
- package/test_project/main.go +11 -0
- package/test_project/main.py +21 -0
- package/test_project/processor.py +12 -0
- package/test_project/utils.py +13 -0
- package/tsconfig.json +16 -0
- package/wasm/tree-sitter-c.wasm +0 -0
- package/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/wasm/tree-sitter-cpp.wasm +0 -0
- package/wasm/tree-sitter-go.wasm +0 -0
- package/wasm/tree-sitter-java.wasm +0 -0
- package/wasm/tree-sitter-python.wasm +0 -0
- package/wasm/tree-sitter-ruby.wasm +0 -0
- package/wasm/tree-sitter-rust.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
- package/wasm/tree-sitter.wasm +0 -0
package/src/vector.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { pipeline } from '@xenova/transformers';
|
|
2
|
+
import { SymbolSkeleton } from './parser.js';
|
|
3
|
+
|
|
4
|
+
export interface VectorSymbol {
|
|
5
|
+
id: string; // filePath + ":" + symbolName
|
|
6
|
+
filePath: string;
|
|
7
|
+
symbolName: string;
|
|
8
|
+
kind: string;
|
|
9
|
+
signature: string;
|
|
10
|
+
docstring?: string;
|
|
11
|
+
embedding: number[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class VectorStore {
|
|
15
|
+
private extractor: any = null;
|
|
16
|
+
private symbols: VectorSymbol[] = [];
|
|
17
|
+
private isInitialized = false;
|
|
18
|
+
|
|
19
|
+
constructor() {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Initializes the embedding model.
|
|
23
|
+
*/
|
|
24
|
+
public async init() {
|
|
25
|
+
if (this.isInitialized) return;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// Disable remote downloading if you want pure local, but first-time execution
|
|
29
|
+
// needs to fetch the 90MB all-MiniLM-L6-v2 model from Hugging Face Xenova repository.
|
|
30
|
+
// After the first download, it will be cached locally and run entirely offline.
|
|
31
|
+
this.extractor = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
|
|
32
|
+
this.isInitialized = true;
|
|
33
|
+
} catch (err) {
|
|
34
|
+
console.error('Failed to initialize local embedding engine:', err);
|
|
35
|
+
throw err;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Generates embedding vector for a given string.
|
|
41
|
+
*/
|
|
42
|
+
public async generateEmbedding(text: string): Promise<number[]> {
|
|
43
|
+
if (!this.isInitialized) {
|
|
44
|
+
await this.init();
|
|
45
|
+
}
|
|
46
|
+
const output = await this.extractor(text, { pooling: 'mean', normalize: true });
|
|
47
|
+
return Array.from(output.data) as number[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Helper to format symbol for vectorization following spec template.
|
|
52
|
+
*/
|
|
53
|
+
public formatSymbolForEmbedding(filePath: string, symbol: SymbolSkeleton): string {
|
|
54
|
+
return `File: ${filePath} | Symbol: ${symbol.name} (${symbol.kind}) | Signature: ${symbol.signature} | Doc: ${symbol.docstring || ''}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Adds or updates a symbol in the vector store.
|
|
59
|
+
*/
|
|
60
|
+
public async addSymbol(filePath: string, symbol: SymbolSkeleton) {
|
|
61
|
+
const id = `${filePath}:${symbol.name}`;
|
|
62
|
+
this.removeSymbol(filePath, symbol.name);
|
|
63
|
+
|
|
64
|
+
const textToEmbed = this.formatSymbolForEmbedding(filePath, symbol);
|
|
65
|
+
try {
|
|
66
|
+
const embedding = await this.generateEmbedding(textToEmbed);
|
|
67
|
+
this.symbols.push({
|
|
68
|
+
id,
|
|
69
|
+
filePath,
|
|
70
|
+
symbolName: symbol.name,
|
|
71
|
+
kind: symbol.kind,
|
|
72
|
+
signature: symbol.signature,
|
|
73
|
+
docstring: symbol.docstring,
|
|
74
|
+
embedding,
|
|
75
|
+
});
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.error(`Error embedding symbol ${id}:`, err);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Removes symbols belonging to a specific file.
|
|
83
|
+
*/
|
|
84
|
+
public removeFileSymbols(filePath: string) {
|
|
85
|
+
this.symbols = this.symbols.filter(s => s.filePath !== filePath);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Removes a specific symbol.
|
|
90
|
+
*/
|
|
91
|
+
public removeSymbol(filePath: string, symbolName: string) {
|
|
92
|
+
const id = `${filePath}:${symbolName}`;
|
|
93
|
+
this.symbols = this.symbols.filter(s => s.id !== id);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Clears the vector store.
|
|
98
|
+
*/
|
|
99
|
+
public clear() {
|
|
100
|
+
this.symbols = [];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Computes dot product (cosine similarity since embeddings are normalized).
|
|
105
|
+
*/
|
|
106
|
+
private cosineSimilarity(a: number[], b: number[]): number {
|
|
107
|
+
let dotProduct = 0;
|
|
108
|
+
for (let i = 0; i < a.length; i++) {
|
|
109
|
+
dotProduct += a[i] * b[i];
|
|
110
|
+
}
|
|
111
|
+
return dotProduct;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Performs hybrid search (semantic similarity + exact substring matching).
|
|
116
|
+
*/
|
|
117
|
+
public async search(query: string, limit: number = 5): Promise<Array<{ symbol: Omit<VectorSymbol, 'embedding'>; score: number }>> {
|
|
118
|
+
if (!query.trim()) return [];
|
|
119
|
+
|
|
120
|
+
// 1. Generate query embedding
|
|
121
|
+
const queryEmbedding = await this.generateEmbedding(query);
|
|
122
|
+
|
|
123
|
+
// 2. Compute similarity for all indexed symbols
|
|
124
|
+
const results = this.symbols.map(s => {
|
|
125
|
+
let score = this.cosineSimilarity(queryEmbedding, s.embedding);
|
|
126
|
+
|
|
127
|
+
// Boost score if query is a substring of the symbol name (lexical matching)
|
|
128
|
+
const nameLower = s.symbolName.toLowerCase();
|
|
129
|
+
const queryLower = query.toLowerCase();
|
|
130
|
+
if (nameLower.includes(queryLower)) {
|
|
131
|
+
score += 0.25; // boost for direct match
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
symbol: {
|
|
136
|
+
id: s.id,
|
|
137
|
+
filePath: s.filePath,
|
|
138
|
+
symbolName: s.symbolName,
|
|
139
|
+
kind: s.kind,
|
|
140
|
+
signature: s.signature,
|
|
141
|
+
docstring: s.docstring,
|
|
142
|
+
},
|
|
143
|
+
score,
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// 3. Sort by score descending and limit results
|
|
148
|
+
return results
|
|
149
|
+
.sort((a, b) => b.score - a.score)
|
|
150
|
+
.slice(0, limit);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Retrieves all loaded symbols.
|
|
155
|
+
*/
|
|
156
|
+
public getAllSymbols() {
|
|
157
|
+
return this.symbols.map(s => ({
|
|
158
|
+
id: s.id,
|
|
159
|
+
filePath: s.filePath,
|
|
160
|
+
symbolName: s.symbolName,
|
|
161
|
+
kind: s.kind,
|
|
162
|
+
signature: s.signature,
|
|
163
|
+
docstring: s.docstring,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
}
|
package/src/watcher.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import chokidar from 'chokidar';
|
|
6
|
+
import ignore from 'ignore';
|
|
7
|
+
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
|
|
10
|
+
export interface WatcherOptions {
|
|
11
|
+
projectPath: string;
|
|
12
|
+
onChange: (changedFiles: string[]) => void;
|
|
13
|
+
debounceMs?: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class GitAwareWatcher {
|
|
17
|
+
private projectPath: string;
|
|
18
|
+
private onChange: (changedFiles: string[]) => void;
|
|
19
|
+
private debounceMs: number;
|
|
20
|
+
private watcher: chokidar.FSWatcher | null = null;
|
|
21
|
+
private ig: ReturnType<typeof ignore>;
|
|
22
|
+
private changedQueue: Set<string> = new Set();
|
|
23
|
+
private debounceTimeout: NodeJS.Timeout | null = null;
|
|
24
|
+
|
|
25
|
+
constructor(options: WatcherOptions) {
|
|
26
|
+
this.projectPath = path.resolve(options.projectPath);
|
|
27
|
+
this.onChange = options.onChange;
|
|
28
|
+
this.debounceMs = options.debounceMs ?? 1500;
|
|
29
|
+
this.ig = ignore();
|
|
30
|
+
this.loadGitignore();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Loads and parses .gitignore rules.
|
|
35
|
+
*/
|
|
36
|
+
private loadGitignore() {
|
|
37
|
+
const gitignorePath = path.join(this.projectPath, '.gitignore');
|
|
38
|
+
this.ig = ignore();
|
|
39
|
+
// Always ignore standard node_modules and .git folders
|
|
40
|
+
this.ig.add(['node_modules', '.git', 'dist', '.graph-indexer']);
|
|
41
|
+
|
|
42
|
+
if (fs.existsSync(gitignorePath)) {
|
|
43
|
+
try {
|
|
44
|
+
const content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
45
|
+
this.ig.add(content);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.error('Error reading .gitignore file:', err);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Helper to check if a relative path is ignored.
|
|
54
|
+
*/
|
|
55
|
+
public isIgnored(relativeFilePath: string): boolean {
|
|
56
|
+
// Normalize path separators to forward slashes for the ignore library
|
|
57
|
+
const normalized = relativeFilePath.replace(/\\/g, '/');
|
|
58
|
+
if (!normalized || normalized === '.') return true;
|
|
59
|
+
return this.ig.ignores(normalized);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Runs `git status --porcelain` to get the list of modified/untracked files.
|
|
64
|
+
*/
|
|
65
|
+
public async getGitDeltas(): Promise<string[]> {
|
|
66
|
+
try {
|
|
67
|
+
const { stdout } = await execAsync('git status --porcelain', { cwd: this.projectPath });
|
|
68
|
+
const deltas: string[] = [];
|
|
69
|
+
|
|
70
|
+
for (const line of stdout.split('\n')) {
|
|
71
|
+
if (!line.trim()) continue;
|
|
72
|
+
// git status --porcelain outputs: XY path/to/file -> path/to/file or XY path/to/file
|
|
73
|
+
// We capture everything after the first 3 characters
|
|
74
|
+
const filePath = line.substring(3).trim();
|
|
75
|
+
const relativePath = path.relative(this.projectPath, path.resolve(this.projectPath, filePath));
|
|
76
|
+
|
|
77
|
+
if (!this.isIgnored(relativePath)) {
|
|
78
|
+
deltas.push(relativePath);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return deltas;
|
|
82
|
+
} catch (err) {
|
|
83
|
+
// If not a git repo or git not found, return empty array
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Starts watching the filesystem.
|
|
90
|
+
*/
|
|
91
|
+
public start() {
|
|
92
|
+
this.loadGitignore();
|
|
93
|
+
|
|
94
|
+
this.watcher = chokidar.watch(this.projectPath, {
|
|
95
|
+
ignored: (filePath) => {
|
|
96
|
+
const relativePath = path.relative(this.projectPath, filePath);
|
|
97
|
+
return this.isIgnored(relativePath);
|
|
98
|
+
},
|
|
99
|
+
persistent: true,
|
|
100
|
+
ignoreInitial: true,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const handleFileChange = (filePath: string) => {
|
|
104
|
+
const relativePath = path.relative(this.projectPath, filePath);
|
|
105
|
+
if (this.isIgnored(relativePath)) return;
|
|
106
|
+
|
|
107
|
+
this.changedQueue.add(relativePath);
|
|
108
|
+
this.triggerDebounce();
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
this.watcher
|
|
112
|
+
.on('add', handleFileChange)
|
|
113
|
+
.on('change', handleFileChange)
|
|
114
|
+
.on('unlink', handleFileChange);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Stops the filesystem watcher.
|
|
119
|
+
*/
|
|
120
|
+
public async stop() {
|
|
121
|
+
if (this.watcher) {
|
|
122
|
+
await this.watcher.close();
|
|
123
|
+
this.watcher = null;
|
|
124
|
+
}
|
|
125
|
+
if (this.debounceTimeout) {
|
|
126
|
+
clearTimeout(this.debounceTimeout);
|
|
127
|
+
this.debounceTimeout = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private triggerDebounce() {
|
|
132
|
+
if (this.debounceTimeout) {
|
|
133
|
+
clearTimeout(this.debounceTimeout);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
this.debounceTimeout = setTimeout(() => {
|
|
137
|
+
const changed = Array.from(this.changedQueue);
|
|
138
|
+
this.changedQueue.clear();
|
|
139
|
+
if (changed.length > 0) {
|
|
140
|
+
this.onChange(changed);
|
|
141
|
+
}
|
|
142
|
+
}, this.debounceMs);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
|
|
4
|
+
namespace Shop.Services
|
|
5
|
+
{
|
|
6
|
+
/// <summary>
|
|
7
|
+
/// Servico responsavel pelo faturamento e calculo de taxas.
|
|
8
|
+
/// </summary>
|
|
9
|
+
public class BillingService : IBillingService
|
|
10
|
+
{
|
|
11
|
+
private readonly ITaxCalculator _taxCalculator;
|
|
12
|
+
|
|
13
|
+
public BillingService(ITaxCalculator taxCalculator)
|
|
14
|
+
{
|
|
15
|
+
_taxCalculator = taxCalculator;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// <summary>
|
|
19
|
+
/// Calcula o valor final com taxas baseadas na regiao.
|
|
20
|
+
/// </summary>
|
|
21
|
+
public decimal ProcessOrder(Order order, decimal discount)
|
|
22
|
+
{
|
|
23
|
+
if (order == null) throw new ArgumentNullException(nameof(order));
|
|
24
|
+
|
|
25
|
+
var baseAmount = order.Total - discount;
|
|
26
|
+
var tax = _taxCalculator.CalculateVAT(baseAmount, order.Region);
|
|
27
|
+
|
|
28
|
+
return baseAmount + tax;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { config } from './config.js';
|
|
2
|
+
import { Database } from './database.js';
|
|
3
|
+
|
|
4
|
+
export class AuthService {
|
|
5
|
+
private db: Database;
|
|
6
|
+
|
|
7
|
+
constructor(db: Database) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public login(username: string): string {
|
|
12
|
+
const users = this.db.query(`SELECT * FROM users WHERE name = '${username}'`);
|
|
13
|
+
if (users.length > 0) {
|
|
14
|
+
return `token-for-${username}-with-${config.jwtSecret}`;
|
|
15
|
+
}
|
|
16
|
+
throw new Error('User not found');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { config } from './config.js';
|
|
2
|
+
|
|
3
|
+
export class Database {
|
|
4
|
+
private isConnected = false;
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
console.log(`Connecting to database at ${config.dbHost}:${config.dbPort}`);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public connect(): boolean {
|
|
11
|
+
this.isConnected = true;
|
|
12
|
+
return this.isConnected;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public query(sql: string): any[] {
|
|
16
|
+
if (!this.isConnected) {
|
|
17
|
+
throw new Error('Database not connected');
|
|
18
|
+
}
|
|
19
|
+
return [{ id: 1, query: sql }];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Database } from './database.js';
|
|
2
|
+
import { AuthService } from './auth.js';
|
|
3
|
+
|
|
4
|
+
export function main() {
|
|
5
|
+
const db = new Database();
|
|
6
|
+
db.connect();
|
|
7
|
+
|
|
8
|
+
const auth = new AuthService(db);
|
|
9
|
+
const token = auth.login('admin');
|
|
10
|
+
console.log(`Success: logged in with token ${token}`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
main();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from processor import Processor
|
|
3
|
+
from utils import log_info
|
|
4
|
+
|
|
5
|
+
class DataProcessor:
|
|
6
|
+
"""
|
|
7
|
+
Class designed to process mathematical datasets.
|
|
8
|
+
"""
|
|
9
|
+
def __init__(self, precision: int = 2):
|
|
10
|
+
self.precision = precision
|
|
11
|
+
self.processor = Processor()
|
|
12
|
+
|
|
13
|
+
def calculate_average(self, values: list[float]) -> float:
|
|
14
|
+
"""
|
|
15
|
+
Computes the arithmetic mean of the provided values.
|
|
16
|
+
"""
|
|
17
|
+
if not values:
|
|
18
|
+
return 0.0
|
|
19
|
+
log_info("Calculating average")
|
|
20
|
+
processed = self.processor.run(values)
|
|
21
|
+
return round(sum(processed) / len(processed), self.precision)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from utils import log_info
|
|
2
|
+
|
|
3
|
+
class Processor:
|
|
4
|
+
"""
|
|
5
|
+
Main processor class.
|
|
6
|
+
"""
|
|
7
|
+
def __init__(self):
|
|
8
|
+
log_info("Processor initialized")
|
|
9
|
+
|
|
10
|
+
def run(self, data: list):
|
|
11
|
+
log_info(f"Processing data with length: {len(data)}")
|
|
12
|
+
return [x * 2 for x in data]
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"declaration": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src/**/*"]
|
|
16
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|