Files
podkop/fe-app-podkop/watch-upload.js
2025-10-10 20:39:28 +03:00

97 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dotenv/config';
import chokidar from 'chokidar';
import SFTPClient from 'ssh2-sftp-client';
import path from 'path';
import fs from 'fs';
import { glob } from 'glob';
const sftp = new SFTPClient();
const config = {
host: process.env.SFTP_HOST,
port: Number(process.env.SFTP_PORT || 22),
username: process.env.SFTP_USER,
...(process.env.SFTP_PRIVATE_KEY
? { privateKey: fs.readFileSync(process.env.SFTP_PRIVATE_KEY) }
: { password: process.env.SFTP_PASS }),
};
const syncDirs = [
{
local: path.resolve(process.env.LOCAL_DIR_FE ?? '../luci-app-podkop/htdocs/luci-static/resources/view/podkop'),
remote: process.env.REMOTE_DIR_FE ?? '/www/luci-static/resources/view/podkop',
},
{
local: path.resolve(process.env.LOCAL_DIR_BIN ?? '../podkop/files/usr/bin/'),
remote: process.env.REMOTE_DIR_BIN ?? '/usr/bin/',
},
{
local: path.resolve(process.env.LOCAL_DIR_LIB ?? '../podkop/files/usr/lib/'),
remote: process.env.REMOTE_DIR_LIB ?? '/usr/lib/podkop/',
},
];
async function uploadFile(filePath, baseDir, remoteBase) {
const relativePath = path.relative(baseDir, filePath);
const remotePath = path.posix.join(remoteBase, relativePath);
console.log(`↑ Uploading: ${relativePath} -> ${remotePath}`);
try {
await sftp.fastPut(filePath, remotePath);
console.log(`✓ Uploaded: ${relativePath}`);
} catch (err) {
console.error(`✗ Failed: ${relativePath}: ${err.message}`);
}
}
async function deleteFile(filePath, baseDir, remoteBase) {
const relativePath = path.relative(baseDir, filePath);
const remotePath = path.posix.join(remoteBase, relativePath);
console.log(` Removing: ${relativePath}`);
try {
await sftp.delete(remotePath);
console.log(`✓ Removed: ${relativePath}`);
} catch (err) {
console.warn(`⚠ Could not delete ${relativePath}: ${err.message}`);
}
}
async function uploadAllFiles() {
for (const { local, remote } of syncDirs) {
console.log(`📂 Uploading all from ${local}`);
const files = await glob(`${local}/**/*`, { nodir: true });
for (const file of files) {
await uploadFile(file, local, remote);
}
}
console.log('✅ Initial upload complete!');
}
async function main() {
await sftp.connect(config);
console.log(`🔌 Connected to ${config.host}`);
await uploadAllFiles();
for (const { local, remote } of syncDirs) {
chokidar.watch(local, { ignoreInitial: true }).on('all', async (event, filePath) => {
if (event === 'add' || event === 'change') {
await uploadFile(filePath, local, remote);
} else if (event === 'unlink') {
await deleteFile(filePath, local, remote);
}
});
}
process.on('SIGINT', async () => {
console.log('👋 Disconnecting...');
await sftp.end();
process.exit();
});
}
main().catch((err) => {
console.error('💥 Fatal:', err);
});