@nine-lab/nine-connector 0.1.2 → 0.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nine-lab/nine-connector",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "NineQuery AI Connector for Database",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ class DatabaseManager {
9
9
  this.dialect = Dialects[this.type];
10
10
 
11
11
  if (!this.dialect) {
12
- throw new Error(`❌ Unsupported Dialect for: ${this.type}`);
12
+ throw new Error(`Unsupported Dialect for: ${this.type}`);
13
13
  }
14
14
  }
15
15
 
@@ -23,9 +23,9 @@ class DatabaseManager {
23
23
 
24
24
  // 단순 연결 확인 쿼리
25
25
  await this.query('SELECT 1');
26
- console.log(`✅ [${this.type}] Database connection successful.`);
26
+ console.log(`[${this.type}] Database connection successful.`);
27
27
  } catch (error) {
28
- console.error(`❌ [${this.type}] Connection failed:`, error.message);
28
+ console.error(`[${this.type}] Connection failed:`, error.message);
29
29
  throw error;
30
30
  }
31
31
  }
package/src/index.js CHANGED
@@ -1,19 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  import 'dotenv/config';
3
- import express from 'express';
4
- import cors from 'cors';
5
- import fs from 'fs';
6
- import path from 'path'; // path 모듈 추가
7
- import DatabaseManager from './database/core/DatabaseManager.js';
8
3
  import { runInit } from './core/init.js';
9
- import { AIProcessor } from './ai/AIProcessor.js';
10
- import { AIService } from './ai/AIService.js';
11
4
 
12
5
  /**
13
6
  * 서버 실행 로직
14
7
  */
15
8
  async function bootstrap() {
16
- // 1. 필수 환경 변수 체크
9
+ // 1. 서버 실행 시점에만 필요한 모듈들을 다이나믹 임포트
10
+ // 상단에 static import가 있으면 이 로직이 무의미해지므로,
11
+ // 관련 모듈들은 여기서만 로드합니다.
12
+ const express = (await import('express')).default;
13
+ const cors = (await import('cors')).default;
14
+ const fs = (await import('fs')).default;
15
+ const path = (await import('path')).default;
16
+
17
+ const { default: DatabaseManager } = await import('./database/core/DatabaseManager.js');
18
+ const { AIProcessor } = await import('./ai/AIProcessor.js');
19
+ const { AIService } = await import('./ai/AIService.js');
20
+
21
+ // 2. 필수 환경 변수 체크
17
22
  if (!process.env.DB_HOST || !process.env.DB_NAME) {
18
23
  console.error("설정 정보가 부족합니다. 'nine-connector init'을 먼저 실행해주세요.");
19
24
  process.exit(1);
@@ -22,7 +27,7 @@ async function bootstrap() {
22
27
  const app = express();
23
28
  const SERVER_PORT = process.env.SERVER_PORT || 3000;
24
29
 
25
- // 2. DB 매니저 초기화
30
+ // 3. DB 매니저 초기화
26
31
  const db = new DatabaseManager({
27
32
  type: process.env.DB_TYPE,
28
33
  host: process.env.DB_HOST,
@@ -38,11 +43,10 @@ async function bootstrap() {
38
43
  app.use(cors());
39
44
  app.use(express.json());
40
45
 
41
- // 3. AI 프로세서 초기화 및 체인 등록
46
+ // 4. AI 프로세서 초기화 및 체인 등록
42
47
  const ai = new AIProcessor(process.env.GEMINI_API_KEY, process.env.GEMINI_MODEL);
43
48
 
44
49
  try {
45
- // init.js에서 생성한 경로와 일치시킵니다. (보통 루트의 prompts 폴더)
46
50
  const promptPath = path.join(process.cwd(), 'prompts');
47
51
 
48
52
  const tableFilterPrompt = fs.readFileSync(
@@ -61,25 +65,19 @@ async function bootstrap() {
61
65
  process.exit(1);
62
66
  }
63
67
 
64
- // 서비스 인스턴스 생성
65
68
  const aiService = new AIService(db, ai);
66
69
 
67
70
  // [API] 자연어 질의 엔드포인트
68
71
  app.post('/api/ask', async (req, res) => {
69
72
  const { question } = req.body;
70
- if (!question) {
71
- return res.status(400).json({ success: false, error: "질문을 입력해주세요." });
72
- }
73
+ if (!question) return res.status(400).json({ success: false, error: "질문을 입력해주세요." });
73
74
 
74
75
  try {
75
76
  const result = await aiService.processNaturalLanguageQuery(question);
76
77
  res.json({ success: true, ...result });
77
78
  } catch (err) {
78
79
  console.error("AI 질의 처리 중 오류:", err);
79
- res.status(500).json({
80
- success: false,
81
- error: err.message || "쿼리 처리 중 서버 오류가 발생했습니다."
82
- });
80
+ res.status(500).json({ success: false, error: err.message || "서버 오류" });
83
81
  }
84
82
  });
85
83
 
@@ -87,29 +85,18 @@ async function bootstrap() {
87
85
  await db.connect();
88
86
  console.log("데이터베이스 연결 성공");
89
87
 
90
- // 스키마 조회 API
91
88
  app.get('/api/schema', async (req, res) => {
92
- try {
93
- const schema = await db.getTableSchema();
94
- res.json({ success: true, data: schema });
95
- } catch (err) {
96
- res.status(500).json({ success: false, error: "Failed to fetch schema" });
97
- }
89
+ const schema = await db.getTableSchema();
90
+ res.json({ success: true, data: schema });
98
91
  });
99
92
 
100
- // 쿼리 실행 API
101
93
  app.post('/api/query', async (req, res) => {
102
94
  const { sql } = req.body;
103
- if (!sql || !sql.trim().toLowerCase().startsWith("select")) {
95
+ if (!sql?.trim().toLowerCase().startsWith("select")) {
104
96
  return res.status(400).json({ success: false, error: "Only SELECT queries are allowed" });
105
97
  }
106
-
107
- try {
108
- const rows = await db.query(sql);
109
- res.json({ success: true, data: rows });
110
- } catch (err) {
111
- res.status(500).json({ success: false, error: "Database query error" });
112
- }
98
+ const rows = await db.query(sql);
99
+ res.json({ success: true, data: rows });
113
100
  });
114
101
 
115
102
  app.listen(SERVER_PORT, () => {