- Removed MinIO client and related imports from various modules. - Introduced S3 client and OSS integration for object storage. - Updated all references to MinIO methods with corresponding S3 methods. - Added new flowme table schema to the database. - Adjusted upload and download routes to utilize S3 for file operations. - Removed obsolete MinIO-related files and routes. - Ensured compatibility with existing application logic while transitioning to S3.
104 lines
2.9 KiB
TypeScript
104 lines
2.9 KiB
TypeScript
import { oss } from '@/app.ts';
|
|
import { fileIsExist } from '@kevisual/use-config';
|
|
import { spawn, spawnSync } from 'child_process';
|
|
import { getFileStat, getMinioList, MinioFile } from '@/routes/file/index.ts';
|
|
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { appsPath } from '../lib/index.ts';
|
|
import { installAppFromKey } from './manager.ts';
|
|
import { Readable } from 'stream';
|
|
export type InstallAppOpts = {
|
|
needInstallDeps?: boolean;
|
|
// minio中
|
|
appKey?: string;
|
|
version?: string;
|
|
};
|
|
/**
|
|
* 检测路径是否存在
|
|
* @param opts
|
|
* @returns
|
|
*/
|
|
export const appPathCheck = async (opts: InstallAppOpts) => {
|
|
const { appKey } = opts;
|
|
const directory = path.join(appsPath, appKey);
|
|
if (fileIsExist(directory)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
export const installApp = async (opts: InstallAppOpts) => {
|
|
const { needInstallDeps, appKey, version } = opts;
|
|
const prefix = `${appKey}/${version}`;
|
|
const pkgPrefix = prefix + '/package.json';
|
|
const stat = await getFileStat(pkgPrefix);
|
|
if (!stat) {
|
|
throw new Error('App not found');
|
|
}
|
|
const fileList = await getMinioList({
|
|
prefix,
|
|
recursive: true,
|
|
});
|
|
for (const file of fileList) {
|
|
const { name } = file as MinioFile;
|
|
const outputPath = path.join(appsPath, appKey, name.replace(prefix, ''));
|
|
const dir = path.dirname(outputPath);
|
|
if (!fileIsExist(dir)) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
const fileStream = (await oss.getObject(`${name}`)).Body as Readable;
|
|
const writeStream = fs.createWriteStream(outputPath);
|
|
fileStream.pipe(writeStream);
|
|
|
|
await new Promise((resolve, reject) => {
|
|
writeStream.on('finish', () => resolve(true));
|
|
writeStream.on('error', reject);
|
|
});
|
|
}
|
|
const directory = path.join(appsPath, appKey);
|
|
if (!fileIsExist(directory)) {
|
|
fs.mkdirSync(directory, { recursive: true });
|
|
}
|
|
if (needInstallDeps) {
|
|
try {
|
|
installDeps({ appPath: directory, isProduction: true, sync: true });
|
|
} catch (e) {
|
|
console.log('installDeps error, [need manual install deps]', e);
|
|
}
|
|
}
|
|
return installAppFromKey(appKey);
|
|
};
|
|
|
|
export const checkPnpm = () => {
|
|
try {
|
|
spawnSync('pnpm', ['--version']);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
type InstallDepsOptions = {
|
|
appPath: string;
|
|
isProduction?: boolean;
|
|
sync?: boolean;
|
|
};
|
|
export const installDeps = async (opts: InstallDepsOptions) => {
|
|
const { appPath } = opts;
|
|
const isProduction = opts.isProduction ?? true;
|
|
const isPnpm = checkPnpm();
|
|
const params = ['i'];
|
|
if (isProduction && isPnpm) {
|
|
params.push('--production');
|
|
} else {
|
|
params.push('--omit=dev');
|
|
}
|
|
console.log('installDeps', appPath, params);
|
|
const syncSpawn = opts.sync ? spawnSync : spawn;
|
|
if (isPnpm) {
|
|
syncSpawn('pnpm', params, { cwd: appPath, stdio: 'inherit', env: process.env });
|
|
} else {
|
|
syncSpawn('npm', params, { cwd: appPath, stdio: 'inherit', env: process.env });
|
|
}
|
|
};
|