Spaces:
Sleeping
Sleeping
; | |
var __assign = (this && this.__assign) || function () { | |
__assign = Object.assign || function(t) { | |
for (var s, i = 1, n = arguments.length; i < n; i++) { | |
s = arguments[i]; | |
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | |
t[p] = s[p]; | |
} | |
return t; | |
}; | |
return __assign.apply(this, arguments); | |
}; | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
var __generator = (this && this.__generator) || function (thisArg, body) { | |
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); | |
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | |
function verb(n) { return function (v) { return step([n, v]); }; } | |
function step(op) { | |
if (f) throw new TypeError("Generator is already executing."); | |
while (g && (g = 0, op[0] && (_ = 0)), _) try { | |
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | |
if (y = 0, t) op = [op[0] & 2, t.value]; | |
switch (op[0]) { | |
case 0: case 1: t = op; break; | |
case 4: _.label++; return { value: op[1], done: false }; | |
case 5: _.label++; y = op[1]; op = [0]; continue; | |
case 7: op = _.ops.pop(); _.trys.pop(); continue; | |
default: | |
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | |
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | |
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | |
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | |
if (t[2]) _.ops.pop(); | |
_.trys.pop(); continue; | |
} | |
op = body.call(thisArg, _); | |
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | |
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | |
} | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
var express_1 = require("express"); | |
var multer_1 = require("multer"); | |
var path_1 = require("path"); | |
var fs_1 = require("fs"); | |
var database_1 = require("../db/database"); | |
var router = express_1.default.Router(); | |
// Configure multer for file uploads | |
var storage = multer_1.default.diskStorage({ | |
destination: function (req, file, cb) { | |
var uploadDir = process.env.UPLOAD_DIR || './uploads'; | |
if (!fs_1.default.existsSync(uploadDir)) { | |
fs_1.default.mkdirSync(uploadDir, { recursive: true }); | |
} | |
cb(null, uploadDir); | |
}, | |
filename: function (req, file, cb) { | |
var uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9); | |
cb(null, file.fieldname + '-' + uniqueSuffix + path_1.default.extname(file.originalname)); | |
} | |
}); | |
var upload = (0, multer_1.default)({ | |
storage: storage, | |
limits: { | |
fileSize: parseInt(process.env.MAX_FILE_SIZE || '10485760') // 10MB default | |
}, | |
fileFilter: function (req, file, cb) { | |
var allowedTypes = ['.pdf', '.docx', '.txt', '.md']; | |
var ext = path_1.default.extname(file.originalname).toLowerCase(); | |
if (allowedTypes.includes(ext)) { | |
cb(null, true); | |
} | |
else { | |
cb(new Error('Invalid file type. Only PDF, DOCX, TXT, and MD files are allowed.')); | |
} | |
} | |
}); | |
// Get knowledge base documents | |
router.get('/', function (req, res) { return __awaiter(void 0, void 0, void 0, function () { | |
var tenantId, documents, error_1; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 2, , 3]); | |
tenantId = req.user.tenantId; | |
return [4 /*yield*/, database_1.database.query('SELECT id, name, type, source, status, size, created_at, updated_at FROM knowledge_base WHERE tenant_id = ? ORDER BY created_at DESC', [tenantId])]; | |
case 1: | |
documents = _a.sent(); | |
res.json({ documents: documents }); | |
return [3 /*break*/, 3]; | |
case 2: | |
error_1 = _a.sent(); | |
console.error('Get knowledge base error:', error_1); | |
res.status(500).json({ error: 'Internal server error' }); | |
return [3 /*break*/, 3]; | |
case 3: return [2 /*return*/]; | |
} | |
}); | |
}); }); | |
// Upload document | |
router.post('/upload', upload.single('document'), function (req, res) { return __awaiter(void 0, void 0, void 0, function () { | |
var tenantId, _a, originalname, filename, size, mimetype, fileType, result, error_2; | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
_b.trys.push([0, 3, , 4]); | |
tenantId = req.user.tenantId; | |
if (!req.file) { | |
return [2 /*return*/, res.status(400).json({ error: 'No file uploaded' })]; | |
} | |
_a = req.file, originalname = _a.originalname, filename = _a.filename, size = _a.size, mimetype = _a.mimetype; | |
fileType = path_1.default.extname(originalname).toLowerCase().substring(1); | |
return [4 /*yield*/, database_1.database.run('INSERT INTO knowledge_base (tenant_id, name, type, source, status, size, metadata) VALUES (?, ?, ?, ?, ?, ?, ?)', [ | |
tenantId, | |
originalname, | |
fileType, | |
filename, | |
'processing', | |
size, | |
JSON.stringify({ mimetype: mimetype, uploadedAt: new Date().toISOString() }) | |
])]; | |
case 1: | |
result = _b.sent(); | |
// Log analytics event | |
return [4 /*yield*/, database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'document_uploaded', JSON.stringify({ | |
documentId: result.lastID, | |
type: fileType, | |
size: size | |
})])]; | |
case 2: | |
// Log analytics event | |
_b.sent(); | |
res.status(201).json({ | |
id: result.lastID, | |
name: originalname, | |
type: fileType, | |
status: 'processing', | |
message: 'Document uploaded successfully' | |
}); | |
return [3 /*break*/, 4]; | |
case 3: | |
error_2 = _b.sent(); | |
console.error('Upload document error:', error_2); | |
res.status(500).json({ error: 'Internal server error' }); | |
return [3 /*break*/, 4]; | |
case 4: return [2 /*return*/]; | |
} | |
}); | |
}); }); | |
// Add website URL | |
router.post('/url', function (req, res) { return __awaiter(void 0, void 0, void 0, function () { | |
var tenantId, _a, url, name_1, displayName, result, error_3; | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
_b.trys.push([0, 3, , 4]); | |
tenantId = req.user.tenantId; | |
_a = req.body, url = _a.url, name_1 = _a.name; | |
if (!url) { | |
return [2 /*return*/, res.status(400).json({ error: 'URL is required' })]; | |
} | |
// Basic URL validation | |
try { | |
new URL(url); | |
} | |
catch (_c) { | |
return [2 /*return*/, res.status(400).json({ error: 'Invalid URL format' })]; | |
} | |
displayName = name_1 || new URL(url).hostname; | |
return [4 /*yield*/, database_1.database.run('INSERT INTO knowledge_base (tenant_id, name, type, source, status, metadata) VALUES (?, ?, ?, ?, ?, ?)', [ | |
tenantId, | |
displayName, | |
'website', | |
url, | |
'processing', | |
JSON.stringify({ addedAt: new Date().toISOString() }) | |
])]; | |
case 1: | |
result = _b.sent(); | |
// Log analytics event | |
return [4 /*yield*/, database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'website_added', JSON.stringify({ | |
documentId: result.lastID, | |
url: url | |
})])]; | |
case 2: | |
// Log analytics event | |
_b.sent(); | |
res.status(201).json({ | |
id: result.lastID, | |
name: displayName, | |
type: 'website', | |
source: url, | |
status: 'processing', | |
message: 'Website added successfully' | |
}); | |
return [3 /*break*/, 4]; | |
case 3: | |
error_3 = _b.sent(); | |
console.error('Add URL error:', error_3); | |
res.status(500).json({ error: 'Internal server error' }); | |
return [3 /*break*/, 4]; | |
case 4: return [2 /*return*/]; | |
} | |
}); | |
}); }); | |
// Delete document | |
router.delete('/:documentId', function (req, res) { return __awaiter(void 0, void 0, void 0, function () { | |
var tenantId, documentId, document_1, filePath, error_4; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 4, , 5]); | |
tenantId = req.user.tenantId; | |
documentId = req.params.documentId; | |
return [4 /*yield*/, database_1.database.get('SELECT * FROM knowledge_base WHERE id = ? AND tenant_id = ?', [documentId, tenantId])]; | |
case 1: | |
document_1 = _a.sent(); | |
if (!document_1) { | |
return [2 /*return*/, res.status(404).json({ error: 'Document not found' })]; | |
} | |
// Delete file if it's a uploaded document | |
if (document_1.type !== 'website') { | |
filePath = path_1.default.join(process.env.UPLOAD_DIR || './uploads', document_1.source); | |
if (fs_1.default.existsSync(filePath)) { | |
fs_1.default.unlinkSync(filePath); | |
} | |
} | |
// Delete from database | |
return [4 /*yield*/, database_1.database.run('DELETE FROM knowledge_base WHERE id = ? AND tenant_id = ?', [documentId, tenantId])]; | |
case 2: | |
// Delete from database | |
_a.sent(); | |
// Log analytics event | |
return [4 /*yield*/, database_1.database.run('INSERT INTO analytics_events (tenant_id, event_type, event_data) VALUES (?, ?, ?)', [tenantId, 'document_deleted', JSON.stringify({ | |
documentId: documentId, | |
name: document_1.name, | |
type: document_1.type | |
})])]; | |
case 3: | |
// Log analytics event | |
_a.sent(); | |
res.json({ message: 'Document deleted successfully' }); | |
return [3 /*break*/, 5]; | |
case 4: | |
error_4 = _a.sent(); | |
console.error('Delete document error:', error_4); | |
res.status(500).json({ error: 'Internal server error' }); | |
return [3 /*break*/, 5]; | |
case 5: return [2 /*return*/]; | |
} | |
}); | |
}); }); | |
// Update document status (for processing updates) | |
router.put('/:documentId/status', function (req, res) { return __awaiter(void 0, void 0, void 0, function () { | |
var tenantId, documentId, status_1, error_5; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 2, , 3]); | |
tenantId = req.user.tenantId; | |
documentId = req.params.documentId; | |
status_1 = req.body.status; | |
if (!['processing', 'active', 'error'].includes(status_1)) { | |
return [2 /*return*/, res.status(400).json({ error: 'Invalid status' })]; | |
} | |
return [4 /*yield*/, database_1.database.run('UPDATE knowledge_base SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? AND tenant_id = ?', [status_1, documentId, tenantId])]; | |
case 1: | |
_a.sent(); | |
res.json({ message: 'Document status updated successfully' }); | |
return [3 /*break*/, 3]; | |
case 2: | |
error_5 = _a.sent(); | |
console.error('Update document status error:', error_5); | |
res.status(500).json({ error: 'Internal server error' }); | |
return [3 /*break*/, 3]; | |
case 3: return [2 /*return*/]; | |
} | |
}); | |
}); }); | |
// Get document by ID | |
router.get('/:documentId', function (req, res) { return __awaiter(void 0, void 0, void 0, function () { | |
var tenantId, documentId, document_2, error_6; | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
_a.trys.push([0, 2, , 3]); | |
tenantId = req.user.tenantId; | |
documentId = req.params.documentId; | |
return [4 /*yield*/, database_1.database.get('SELECT * FROM knowledge_base WHERE id = ? AND tenant_id = ?', [documentId, tenantId])]; | |
case 1: | |
document_2 = _a.sent(); | |
if (!document_2) { | |
return [2 /*return*/, res.status(404).json({ error: 'Document not found' })]; | |
} | |
res.json(__assign(__assign({}, document_2), { metadata: JSON.parse(document_2.metadata || '{}') })); | |
return [3 /*break*/, 3]; | |
case 2: | |
error_6 = _a.sent(); | |
console.error('Get document error:', error_6); | |
res.status(500).json({ error: 'Internal server error' }); | |
return [3 /*break*/, 3]; | |
case 3: return [2 /*return*/]; | |
} | |
}); | |
}); }); | |
exports.default = router; | |