-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathingest-docs-api.js
92 lines (80 loc) · 3.22 KB
/
ingest-docs-api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const { program } = require('commander');
function isValidFile(filePath) {
return fs.statSync(filePath).isFile() && !path.basename(filePath).startsWith('.');
}
async function sendFileToApi(filePath, apiUrl, ingestSecret) {
const content = fs.readFileSync(filePath, { encoding: 'base64' });
const metadata = { 'source': path.basename(filePath) };
const payload = { 'content': content, 'metadata': metadata };
try {
console.log(`Sending: ${filePath} to ${apiUrl}`);
const response = await axios.post(apiUrl, payload, {
headers: {
'Content-Type': 'application/json',
'X-Ingest-Secret': ingestSecret
}
});
return response;
} catch (error) {
console.error(`Error sending file: ${error.message}`);
return { status: error.response ? error.response.status : 500 };
}
}
function isExcluded(filePath, excludeFiles) {
return excludeFiles.some(pattern => {
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
return regex.test(filePath);
});
}
async function processFile(filePath, apiUrl, ingestSecret) {
console.log(`Sending file: ${filePath}`);
const response = await sendFileToApi(filePath, apiUrl, ingestSecret);
if (response.status === 200) {
console.log(`Successfully ingested: ${filePath}`);
} else {
console.log(`Failed to ingest ${filePath}. Status code: ${response.status}`);
}
}
async function ingestFiles(directoryPath, apiUrl, ingestSecret, excludeFiles = []) {
if (!fs.existsSync(directoryPath)) {
console.error(`Error: ${directoryPath} does not exist.`);
return;
}
const stats = fs.statSync(directoryPath);
if (stats.isFile()) {
if (isValidFile(directoryPath) && !isExcluded(directoryPath, excludeFiles)) {
await processFile(directoryPath, apiUrl, ingestSecret);
}
return;
}
if (!stats.isDirectory()) {
console.error(`Error: ${directoryPath} is not a valid directory or file.`);
return;
}
const files = fs.readdirSync(directoryPath, { withFileTypes: true });
for (const file of files) {
const filePath = path.join(directoryPath, file.name);
if (file.isDirectory()) {
await ingestFiles(filePath, apiUrl, ingestSecret, excludeFiles);
} else if (isValidFile(filePath) && !isExcluded(filePath, excludeFiles)) {
await processFile(filePath, apiUrl, ingestSecret);
} else {
console.log(`Skipping invalid, hidden, or excluded file: ${filePath}`);
}
}
}
program
.description('Ingest files from a directory to the API')
.argument('<path>', 'Path to the directory containing files to ingest')
.requiredOption('--ingest-secret <secret>', 'Ingest secret for API authentication')
.option('--endpoint <url>', 'API endpoint URL', 'http://localhost:5328')
.option('--exclude <files>', 'Comma-separated list of files or patterns to exclude', 'node_modules,.git,.env,package-lock.json')
.action(async (directoryPath, options) => {
const apiUrl = `${options.endpoint}/api/ingest`;
const excludeFiles = options.exclude.split(',').map(item => item.trim());
await ingestFiles(directoryPath, apiUrl, options.ingestSecret, excludeFiles);
});
program.parse(process.argv);