feat: 更新安装应用逻辑,添加用户 ID 处理,优化应用路径检查
This commit is contained in:
@@ -4,6 +4,7 @@ import { manager } from './manager-app.ts';
|
|||||||
import { selfRestart } from '@/modules/self-restart.ts';
|
import { selfRestart } from '@/modules/self-restart.ts';
|
||||||
import { AppList } from '../app-manager/module/index.ts';
|
import { AppList } from '../app-manager/module/index.ts';
|
||||||
import { eq, and } from 'drizzle-orm';
|
import { eq, and } from 'drizzle-orm';
|
||||||
|
import { UserId } from '../user/modules/user-id.ts';
|
||||||
// curl http://localhost:4002/api/router?path=micro-app&key=deploy
|
// curl http://localhost:4002/api/router?path=micro-app&key=deploy
|
||||||
// 把对应的应用安装到系统的apps目录下,并解压,然后把配置项写入数据库配置
|
// 把对应的应用安装到系统的apps目录下,并解压,然后把配置项写入数据库配置
|
||||||
// key 是应用的唯一标识,和package.json中的key一致,绑定关系
|
// key 是应用的唯一标识,和package.json中的key一致,绑定关系
|
||||||
@@ -48,20 +49,21 @@ app
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { version } = microApp;
|
const { version } = microApp;
|
||||||
const appKey = username + '/' + microApp.key;
|
const userAppKey = username + '/' + microApp.key;
|
||||||
const check = await appPathCheck({ appKey });
|
const uid = await UserId.getUserIdByName(username);
|
||||||
|
const check = await appPathCheck({ appKey: userAppKey });
|
||||||
let appType: string;
|
let appType: string;
|
||||||
if (check) {
|
if (check) {
|
||||||
if (!force) {
|
if (!force) {
|
||||||
ctx.throw(400, 'App already exists, please remove it first');
|
ctx.throw(400, 'App already exists, please remove it first');
|
||||||
} else {
|
} else {
|
||||||
const app = manager.getAppShowInfo(appKey);
|
const app = manager.getAppShowInfo(userAppKey);
|
||||||
appType = app?.type;
|
appType = app?.type;
|
||||||
|
|
||||||
await manager.removeApp(appKey);
|
await manager.removeApp(userAppKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const installAppData = await installApp({ appKey, version, needInstallDeps: !!install });
|
const installAppData = await installApp({ uid, username, appKey: microApp.key, version, needInstallDeps: !!install });
|
||||||
await manager.add(installAppData.showAppInfo);
|
await manager.add(installAppData.showAppInfo);
|
||||||
ctx.body = installAppData;
|
ctx.body = installAppData;
|
||||||
if (appType === 'system-app') {
|
if (appType === 'system-app') {
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
import { oss } from '@/app.ts';
|
import { oss } from '@/app.ts';
|
||||||
import { fileIsExist } from '@kevisual/use-config';
|
import { fileIsExist } from '@kevisual/use-config';
|
||||||
import { spawn, spawnSync } from 'child_process';
|
import { spawn, spawnSync } from 'child_process';
|
||||||
import { getFileStat, getMinioList, MinioFile } from '@/routes/file/index.ts';
|
import { getMinioList, MinioFile } from '@/routes/file/index.ts';
|
||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { appsPath } from '../lib/index.ts';
|
import { appsPath } from '../lib/index.ts';
|
||||||
import { installAppFromKey } from './manager.ts';
|
import { installAppFromKey } from './manager.ts';
|
||||||
import { Readable } from 'stream';
|
import { Readable } from 'stream';
|
||||||
|
import { CustomError } from '@kevisual/router';
|
||||||
export type InstallAppOpts = {
|
export type InstallAppOpts = {
|
||||||
needInstallDeps?: boolean;
|
needInstallDeps?: boolean;
|
||||||
// minio中
|
// minio中
|
||||||
appKey?: string;
|
appKey?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
|
uid?: string;
|
||||||
|
username?: string;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 检测路径是否存在
|
* 检测路径是否存在
|
||||||
@@ -28,12 +31,13 @@ export const appPathCheck = async (opts: InstallAppOpts) => {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
export const installApp = async (opts: InstallAppOpts) => {
|
export const installApp = async (opts: InstallAppOpts) => {
|
||||||
const { needInstallDeps, appKey, version } = opts;
|
const { needInstallDeps, appKey, version, uid, username } = opts;
|
||||||
const prefix = `${appKey}/${version}`;
|
const userAppKey = `${username}/${appKey}`;
|
||||||
|
const prefix = `data/${uid}/${appKey}/${version}`;
|
||||||
const pkgPrefix = prefix + '/package.json';
|
const pkgPrefix = prefix + '/package.json';
|
||||||
const stat = await getFileStat(pkgPrefix);
|
const stat = await oss.statObject(pkgPrefix);
|
||||||
if (!stat) {
|
if (!stat) {
|
||||||
throw new Error('App not found');
|
throw new CustomError({ code: 400, message: 'App not found' });
|
||||||
}
|
}
|
||||||
const fileList = await getMinioList({
|
const fileList = await getMinioList({
|
||||||
prefix,
|
prefix,
|
||||||
@@ -41,7 +45,7 @@ export const installApp = async (opts: InstallAppOpts) => {
|
|||||||
});
|
});
|
||||||
for (const file of fileList) {
|
for (const file of fileList) {
|
||||||
const { name } = file as MinioFile;
|
const { name } = file as MinioFile;
|
||||||
const outputPath = path.join(appsPath, appKey, name.replace(prefix, ''));
|
const outputPath = path.join(appsPath, userAppKey, name.replace(prefix, ''));
|
||||||
const dir = path.dirname(outputPath);
|
const dir = path.dirname(outputPath);
|
||||||
if (!fileIsExist(dir)) {
|
if (!fileIsExist(dir)) {
|
||||||
fs.mkdirSync(dir, { recursive: true });
|
fs.mkdirSync(dir, { recursive: true });
|
||||||
@@ -55,7 +59,7 @@ export const installApp = async (opts: InstallAppOpts) => {
|
|||||||
writeStream.on('error', reject);
|
writeStream.on('error', reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const directory = path.join(appsPath, appKey);
|
const directory = path.join(appsPath, userAppKey);
|
||||||
if (!fileIsExist(directory)) {
|
if (!fileIsExist(directory)) {
|
||||||
fs.mkdirSync(directory, { recursive: true });
|
fs.mkdirSync(directory, { recursive: true });
|
||||||
}
|
}
|
||||||
@@ -66,7 +70,7 @@ export const installApp = async (opts: InstallAppOpts) => {
|
|||||||
console.log('installDeps error, [need manual install deps]', e);
|
console.log('installDeps error, [need manual install deps]', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return installAppFromKey(appKey);
|
return installAppFromKey(userAppKey);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkPnpm = () => {
|
export const checkPnpm = () => {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { appsPath } from '../lib/index.ts';
|
|||||||
export const installAppFromKey = async (key: string) => {
|
export const installAppFromKey = async (key: string) => {
|
||||||
const directory = path.join(appsPath, key);
|
const directory = path.join(appsPath, key);
|
||||||
if (!fileIsExist(directory)) {
|
if (!fileIsExist(directory)) {
|
||||||
throw new Error('App not found');
|
throw new Error('FileIsNotExist: App not found');
|
||||||
}
|
}
|
||||||
const pkgs = path.join(directory, 'package.json');
|
const pkgs = path.join(directory, 'package.json');
|
||||||
if (!fileIsExist(pkgs)) {
|
if (!fileIsExist(pkgs)) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { oss } from '@/modules/s3.ts'
|
import { oss } from '@/modules/s3.ts'
|
||||||
|
|
||||||
const stat = await oss.statObject('root/codepod/0.0.3/index.html');
|
const stat = await oss.statObject('data/0e700dc8-90dd-41b7-91dd-336ea51de3d2/cnb/0.0.61/package.json');
|
||||||
console.log('Object Stat:', stat);
|
console.log('Object Stat:', stat);
|
||||||
Reference in New Issue
Block a user