2024-11-24 20:50:22 +08:00

96 lines
2.6 KiB
TypeScript

import { minioClient } from '@/app.ts';
import { bucketName } from '@/modules/minio.ts';
import { fileIsExist } from '@kevisual/use-config';
import fs from 'fs';
import path from 'path';
import * as tar from 'tar';
import { appsPath } from '../lib/index.ts';
export type InstallAppOpts = {
path?: string;
key?: string;
};
/**
* 检测路径是否存在
* @param opts
* @returns
*/
export const appPathCheck = async (opts: InstallAppOpts) => {
const { key } = opts;
const directory = path.join(appsPath, key);
if (fileIsExist(directory)) {
return true;
}
return false;
};
export const installApp = async (opts: InstallAppOpts) => {
const { key } = opts;
const fileStream = await minioClient.getObject(bucketName, opts.path);
const pathName = opts.path.split('/').pop();
const directory = path.join(appsPath, key);
if (!fileIsExist(directory)) {
fs.mkdirSync(directory, { recursive: true });
}
const filePath = path.join(directory, pathName);
const writeStream = fs.createWriteStream(filePath);
fileStream.pipe(writeStream);
await new Promise((resolve, reject) => {
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
// 解压 tgz文件
const extractPath = path.join(directory);
await tar.x({
file: filePath,
cwd: extractPath,
});
return installAppFromKey(key);
};
export const installAppFromKey = async (key: string) => {
const directory = path.join(appsPath, key);
if (!fileIsExist(directory)) {
throw new Error('App not found');
}
const pkgs = path.join(directory, 'package.json');
if (!fileIsExist(pkgs)) {
throw new Error('Invalid package.json');
}
const json = fs.readFileSync(pkgs, 'utf-8');
const pkg = JSON.parse(json);
const { name, version, app } = pkg;
if (!name || !version || !app) {
throw new Error('Invalid package.json');
}
const readmeFile = path.join(directory, 'README.md');
let readmeDesc = '';
if (fileIsExist(readmeFile)) {
readmeDesc = fs.readFileSync(readmeFile, 'utf-8');
}
let showAppInfo = {
key,
status: 'inactive',
type: app?.type || 'system-app',
description: readmeDesc || '',
version,
//
entry: app?.entry || '',
path: directory,
origin: app,
};
app.key = key;
fs.writeFileSync(pkgs, JSON.stringify(pkg, null, 2));
return { pkg, showAppInfo };
};
export const getAppPathKeys = async () => {
let files = fs.readdirSync(appsPath);
files = files.filter((file) => {
const stat = fs.statSync(path.join(appsPath, file));
if (file === 'node_modules') return false;
return stat.isDirectory();
});
return files;
};