@dastbal/nestjs-ai-agent 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/README.md +116 -0
- package/dist/ai-agent.module.d.ts +2 -0
- package/dist/ai-agent.module.js +30 -0
- package/dist/bin/cli.d.ts +2 -0
- package/dist/bin/cli.js +81 -0
- package/dist/core/agent/factory.d.ts +24 -0
- package/dist/core/agent/factory.js +155 -0
- package/dist/core/agent/safe-backend.d.ts +46 -0
- package/dist/core/agent/safe-backend.js +113 -0
- package/dist/core/llm/provider.d.ts +8 -0
- package/dist/core/llm/provider.js +84 -0
- package/dist/core/rag/indexer.d.ts +37 -0
- package/dist/core/rag/indexer.js +215 -0
- package/dist/core/rag/math.d.ts +11 -0
- package/dist/core/rag/math.js +29 -0
- package/dist/core/rag/retriever.d.ts +28 -0
- package/dist/core/rag/retriever.js +156 -0
- package/dist/core/state/db.d.ts +23 -0
- package/dist/core/state/db.js +118 -0
- package/dist/core/state/file-registry.d.ts +38 -0
- package/dist/core/state/file-registry.js +112 -0
- package/dist/core/tools/ast/chunker.d.ts +58 -0
- package/dist/core/tools/ast/chunker.js +297 -0
- package/dist/core/tools/ast/definitions.d.ts +0 -0
- package/dist/core/tools/ast/definitions.js +29 -0
- package/dist/core/tools/tools.d.ts +42 -0
- package/dist/core/tools/tools.js +196 -0
- package/dist/core/types.d.ts +53 -0
- package/dist/core/types.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +23 -0
- package/package.json +52 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const safeWriteFileTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
3
|
+
filePath: z.ZodString;
|
|
4
|
+
content: z.ZodString;
|
|
5
|
+
}, z.core.$strip>, {
|
|
6
|
+
filePath: string;
|
|
7
|
+
content: string;
|
|
8
|
+
}, {
|
|
9
|
+
filePath: string;
|
|
10
|
+
content: string;
|
|
11
|
+
}, string, "safe_write_file">;
|
|
12
|
+
export declare const safeReadFileTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
13
|
+
filePath: z.ZodString;
|
|
14
|
+
}, z.core.$strip>, {
|
|
15
|
+
filePath: string;
|
|
16
|
+
}, {
|
|
17
|
+
filePath: string;
|
|
18
|
+
}, string, "safe_read_file">;
|
|
19
|
+
/**
|
|
20
|
+
* 🔍 TOOL: Ask Codebase (Semantic & Graph Search)
|
|
21
|
+
* This is the Agent's "Eyes". It retrieves code + context.
|
|
22
|
+
*/
|
|
23
|
+
export declare const askCodebaseTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{
|
|
24
|
+
query: z.ZodString;
|
|
25
|
+
}, z.core.$strip>, {
|
|
26
|
+
query: string;
|
|
27
|
+
}, {
|
|
28
|
+
query: string;
|
|
29
|
+
}, string, "ask_codebase">;
|
|
30
|
+
/**
|
|
31
|
+
* ✅ TOOL: Integrity Check (Compiler)
|
|
32
|
+
* Validates the project state using TypeScript compiler.
|
|
33
|
+
*/
|
|
34
|
+
export declare const integrityCheckTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{}, z.core.$strip>, Record<string, never>, Record<string, never>, string, "run_integrity_check">;
|
|
35
|
+
/**
|
|
36
|
+
* Maintenance tool to update the vector knowledge base.
|
|
37
|
+
* * This tool forces a re-read and vectorization of the project files.
|
|
38
|
+
* It is useful for ensuring the LLM has access to the most recent code changes
|
|
39
|
+
* that may not have been synchronized automatically.
|
|
40
|
+
* * @returns {Promise<string>} A confirmation message or error details.
|
|
41
|
+
*/
|
|
42
|
+
export declare const refreshIndexTool: import("@langchain/core/tools").DynamicStructuredTool<z.ZodObject<{}, z.core.$strip>, Record<string, never>, Record<string, never>, string, "refresh_project_index">;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.refreshIndexTool = exports.integrityCheckTool = exports.askCodebaseTool = exports.safeReadFileTool = exports.safeWriteFileTool = void 0;
|
|
40
|
+
const tools_1 = require("@langchain/core/tools");
|
|
41
|
+
const zod_1 = require("zod");
|
|
42
|
+
const child_process_1 = require("child_process");
|
|
43
|
+
const util_1 = require("util");
|
|
44
|
+
const retriever_1 = require("../rag/retriever");
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
48
|
+
const indexer_1 = require("../rag/indexer");
|
|
49
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
50
|
+
const log = {
|
|
51
|
+
ai: (msg) => console.log(chalk_1.default.blue('🤖 [AI]: ') + msg),
|
|
52
|
+
tool: (msg) => console.log(chalk_1.default.yellow('🛠️ [TOOL]: ') + msg),
|
|
53
|
+
sys: (msg) => console.log(chalk_1.default.gray('⚙️ [SYS]: ') + msg),
|
|
54
|
+
error: (msg) => console.log(chalk_1.default.red('❌ [ERR]: ') + msg),
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* 💾 Genera un backup antes de modificar un archivo real.
|
|
58
|
+
*/
|
|
59
|
+
const createBackup = (filePath) => {
|
|
60
|
+
const rootDir = process.cwd();
|
|
61
|
+
const backupDir = path.join(rootDir, '.agent', 'backups');
|
|
62
|
+
if (!fs.existsSync(backupDir))
|
|
63
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
64
|
+
const realPath = path.resolve(rootDir, filePath);
|
|
65
|
+
if (fs.existsSync(realPath)) {
|
|
66
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
67
|
+
const filename = path.basename(realPath);
|
|
68
|
+
const backupPath = path.join(backupDir, `${timestamp}_${filename}.bak`);
|
|
69
|
+
fs.copyFileSync(realPath, backupPath);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
exports.safeWriteFileTool = (0, tools_1.tool)(async ({ filePath, content }) => {
|
|
73
|
+
try {
|
|
74
|
+
const rootDir = process.cwd();
|
|
75
|
+
const targetPath = path.resolve(rootDir, filePath);
|
|
76
|
+
if (!targetPath.startsWith(rootDir))
|
|
77
|
+
return '❌ Error: Access denied.';
|
|
78
|
+
const dir = path.dirname(targetPath);
|
|
79
|
+
if (!fs.existsSync(dir))
|
|
80
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
81
|
+
createBackup(filePath); // Tu lógica de backup
|
|
82
|
+
fs.writeFileSync(targetPath, content, 'utf-8');
|
|
83
|
+
log.sys(`Indexando cambio en: ${filePath}`);
|
|
84
|
+
const indexer = new indexer_1.IndexerService();
|
|
85
|
+
indexer.indexProject().catch((err) => log.error(` ${err.message}`));
|
|
86
|
+
return `✅ File saved to REAL DISK: ${filePath}`;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return `❌ Error: ${error.message}`;
|
|
90
|
+
}
|
|
91
|
+
}, {
|
|
92
|
+
name: 'safe_write_file',
|
|
93
|
+
description: 'WRITES code to the REAL local disk. Creates a backup automatically.',
|
|
94
|
+
schema: zod_1.z.object({
|
|
95
|
+
filePath: zod_1.z.string().describe('Relative path (e.g., src/app.service.ts)'),
|
|
96
|
+
content: zod_1.z.string().describe('Full file content'),
|
|
97
|
+
}),
|
|
98
|
+
});
|
|
99
|
+
// --- TOOL 2: READ FILE (Manual) ---
|
|
100
|
+
exports.safeReadFileTool = (0, tools_1.tool)(async ({ filePath }) => {
|
|
101
|
+
try {
|
|
102
|
+
const rootDir = process.cwd();
|
|
103
|
+
const targetPath = path.resolve(rootDir, filePath);
|
|
104
|
+
if (!fs.existsSync(targetPath))
|
|
105
|
+
return '❌ File not found.';
|
|
106
|
+
return fs.readFileSync(targetPath, 'utf-8');
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
return `Error: ${e.message}`;
|
|
110
|
+
}
|
|
111
|
+
}, {
|
|
112
|
+
name: 'safe_read_file',
|
|
113
|
+
description: 'READS code from the REAL local disk.',
|
|
114
|
+
schema: zod_1.z.object({ filePath: zod_1.z.string() }),
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* 🔍 TOOL: Ask Codebase (Semantic & Graph Search)
|
|
118
|
+
* This is the Agent's "Eyes". It retrieves code + context.
|
|
119
|
+
*/
|
|
120
|
+
exports.askCodebaseTool = (0, tools_1.tool)(async ({ query }) => {
|
|
121
|
+
try {
|
|
122
|
+
// We assume the streaming UI handles the 'Thinking...' log via the framework events
|
|
123
|
+
const retriever = new retriever_1.RetrieverService();
|
|
124
|
+
const context = await retriever.getContextForLLM(query);
|
|
125
|
+
return context;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return `❌ Error querying codebase: ${error}`;
|
|
129
|
+
}
|
|
130
|
+
}, {
|
|
131
|
+
name: 'ask_codebase',
|
|
132
|
+
description: 'CRITICAL TOOL. Use this tool FIRST to explore the codebase. ' +
|
|
133
|
+
'It performs a semantic search AND a dependency graph lookup. ' +
|
|
134
|
+
'Returns: Relevant code snippets, lists of dependencies (imports), and ACCURATE FILE PATHS. ' +
|
|
135
|
+
'Strategy: Use this to find *where* logic is located. If you need the full file content to edit it safely, ' +
|
|
136
|
+
"copy the 'FILE PATH' returned by this tool and use the native 'read_file' tool.",
|
|
137
|
+
schema: zod_1.z.object({
|
|
138
|
+
query: zod_1.z
|
|
139
|
+
.string()
|
|
140
|
+
.describe("A natural language query describing the logic, DTO, or functionality you are looking for. (e.g., 'How is the RefundEntity defined?', 'Show me the auth guard')"),
|
|
141
|
+
}),
|
|
142
|
+
});
|
|
143
|
+
/**
|
|
144
|
+
* ✅ TOOL: Integrity Check (Compiler)
|
|
145
|
+
* Validates the project state using TypeScript compiler.
|
|
146
|
+
*/
|
|
147
|
+
exports.integrityCheckTool = (0, tools_1.tool)(async () => {
|
|
148
|
+
try {
|
|
149
|
+
const rootDir = process.cwd();
|
|
150
|
+
// 'tsc --noEmit' checks types without generating JS files. Fast and safe.
|
|
151
|
+
const { stdout } = await execAsync('npx tsc --noEmit', { cwd: rootDir });
|
|
152
|
+
console.log('INTEGRITY CHECK PASSED.', rootDir, stdout);
|
|
153
|
+
return `✅ INTEGRITY CHECK PASSED. The codebase is strictly typed and compiles correctly.\n${stdout}`;
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
// Return the exact compiler error so the agent can fix it
|
|
157
|
+
return `❌ INTEGRITY CHECK FAILED. You must fix these TypeScript errors before finishing:\n${error.stdout || error.message}`;
|
|
158
|
+
}
|
|
159
|
+
}, {
|
|
160
|
+
name: 'run_integrity_check',
|
|
161
|
+
description: 'Runs the TypeScript compiler (tsc) to verify type safety. ' +
|
|
162
|
+
"MANDATORY: Run this tool after every 'write_file' or 'edit_file' operation to ensure you haven't broken the build.",
|
|
163
|
+
schema: zod_1.z.object({}),
|
|
164
|
+
});
|
|
165
|
+
/**
|
|
166
|
+
* Maintenance tool to update the vector knowledge base.
|
|
167
|
+
* * This tool forces a re-read and vectorization of the project files.
|
|
168
|
+
* It is useful for ensuring the LLM has access to the most recent code changes
|
|
169
|
+
* that may not have been synchronized automatically.
|
|
170
|
+
* * @returns {Promise<string>} A confirmation message or error details.
|
|
171
|
+
*/
|
|
172
|
+
exports.refreshIndexTool = (0, tools_1.tool)(async () => {
|
|
173
|
+
log.sys('🔄 Starting full project re-indexing...');
|
|
174
|
+
try {
|
|
175
|
+
// Start the expensive operation
|
|
176
|
+
const indexer = new indexer_1.IndexerService();
|
|
177
|
+
indexer.indexProject().catch((err) => log.error(` ${err.message}`));
|
|
178
|
+
log.sys('✅ Re-indexing completed successfully.');
|
|
179
|
+
return '✅ Index successfully updated. I now have access to the latest code version.';
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
// Safe error handling in TypeScript
|
|
183
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
184
|
+
log.error(`❌ Indexing failed: ${errorMessage}`);
|
|
185
|
+
return `❌ Critical error while attempting to index the project: ${errorMessage}. Please try again or check the logs.`;
|
|
186
|
+
}
|
|
187
|
+
}, {
|
|
188
|
+
name: 'refresh_project_index',
|
|
189
|
+
// CRITICAL IMPROVEMENT: Instruction-oriented description for the LLM
|
|
190
|
+
description: 'Triggers a forced, full re-indexing of the project codebase. That fucntion is optimazed only index changes comparing hash' +
|
|
191
|
+
'USE THIS TOOL ONLY WHEN: ' +
|
|
192
|
+
'1) The user explicitly states that files have changed. ' +
|
|
193
|
+
'2) You cannot find information that should be present (stale context). ' +
|
|
194
|
+
'Note: This is a computationally expensive operation; inform the user before running it.',
|
|
195
|
+
schema: zod_1.z.object({}),
|
|
196
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the type of relation between two files in the project.
|
|
3
|
+
* - 'import': Standard ES6 import.
|
|
4
|
+
* - 'extends': Class inheritance.
|
|
5
|
+
* - 'implements': Interface implementation.
|
|
6
|
+
*/
|
|
7
|
+
export type DependencyRelation = 'import' | 'extends' | 'implements' | 'injects';
|
|
8
|
+
/**
|
|
9
|
+
* Represents the granularity of a code chunk.
|
|
10
|
+
* - 'file': The whole file (e.g., DTOs, Entities).
|
|
11
|
+
* - 'method': A specific function inside a class (e.g., Service methods).
|
|
12
|
+
* - 'class_signature': The class definition line + properties (Parent context).
|
|
13
|
+
*/
|
|
14
|
+
export type ChunkType = 'file' | 'method' | 'class_signature' | 'config';
|
|
15
|
+
/**
|
|
16
|
+
* Structure of a row in the Dependency Graph table.
|
|
17
|
+
*/
|
|
18
|
+
export interface GraphEdge {
|
|
19
|
+
sourcePath: string;
|
|
20
|
+
targetPath: string;
|
|
21
|
+
relation: DependencyRelation;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Metadata stored alongside vectors to help the LLM understand context.
|
|
25
|
+
*/
|
|
26
|
+
export interface ChunkMetadata {
|
|
27
|
+
startLine: number;
|
|
28
|
+
endLine: number;
|
|
29
|
+
decorators?: string[];
|
|
30
|
+
className?: string;
|
|
31
|
+
methodName?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Represents a processed piece of code ready for storage.
|
|
35
|
+
*/
|
|
36
|
+
export interface ProcessedChunk {
|
|
37
|
+
id: string;
|
|
38
|
+
filePath?: string;
|
|
39
|
+
type: ChunkType;
|
|
40
|
+
content: string;
|
|
41
|
+
metadata: ChunkMetadata;
|
|
42
|
+
parentId?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Full analysis result of a single file.
|
|
46
|
+
*/
|
|
47
|
+
export interface FileAnalysisResult {
|
|
48
|
+
filePath: string;
|
|
49
|
+
fileHash: string;
|
|
50
|
+
chunks: ProcessedChunk[];
|
|
51
|
+
dependencies: GraphEdge[];
|
|
52
|
+
skeleton: object | null;
|
|
53
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// Exportamos el Módulo para NestJS
|
|
18
|
+
__exportStar(require("./ai-agent.module"), exports);
|
|
19
|
+
// Exportamos la Factory y los tipos por si alguien quiere uso manual
|
|
20
|
+
__exportStar(require("./core/agent/factory"), exports);
|
|
21
|
+
__exportStar(require("./core/llm/provider"), exports);
|
|
22
|
+
// Exportamos las herramientas por si el usuario quiere crear su propio agente
|
|
23
|
+
__exportStar(require("./core/tools/tools"), exports);
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dastbal/nestjs-ai-agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Autonomous AI Agent for NestJS - Principal Software Engineer Level with RAG and SQLite persistence",
|
|
5
|
+
"author": "David Balladares",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"gen": "dist/bin/cli.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"gen": "ts-node src/bin/cli.ts",
|
|
22
|
+
"start:dev": "ts-node src/bin/cli.ts",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@langchain/google-vertexai": "^2.1.6",
|
|
27
|
+
"@langchain/langgraph": "1.0.7",
|
|
28
|
+
"@langchain/langgraph-checkpoint-sqlite": "^1.0.0",
|
|
29
|
+
"better-sqlite3": "^12.5.0",
|
|
30
|
+
"chalk": "^4.1.2",
|
|
31
|
+
"commander": "^14.0.2",
|
|
32
|
+
"deepagents": "^1.6.1",
|
|
33
|
+
"dotenv": "^17.2.3",
|
|
34
|
+
"langchain": "^1.2.7",
|
|
35
|
+
"sqlite3": "^5.1.7",
|
|
36
|
+
"ts-morph": "^27.0.2",
|
|
37
|
+
"uuid": "^13.0.0",
|
|
38
|
+
"zod": "^4.3.5"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@nestjs/common": "^10.0.0",
|
|
42
|
+
"reflect-metadata": "^0.1.13"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@nestjs/common": "^10.4.22",
|
|
46
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
47
|
+
"@types/node": "^20.19.30",
|
|
48
|
+
"@types/uuid": "^10.0.0",
|
|
49
|
+
"ts-node": "^10.9.2",
|
|
50
|
+
"typescript": "^5.0.0"
|
|
51
|
+
}
|
|
52
|
+
}
|