code clear

This commit is contained in:
熊潇 2025-03-22 23:06:03 +08:00
parent 5f63c4cf4b
commit 74a484718a
17 changed files with 27 additions and 483 deletions

2
.gitignore vendored
View File

@ -17,3 +17,5 @@ release/*
!release/.gitkeep !release/.gitkeep
.turbo .turbo
.env

View File

@ -23,7 +23,8 @@
"pub": "envision pack -p -u", "pub": "envision pack -p -u",
"ssh": "ssh -L 6379:localhost:6379 light ", "ssh": "ssh -L 6379:localhost:6379 light ",
"ssh:sky": "ssh -L 6379:172.21.32.13:6379 sky", "ssh:sky": "ssh -L 6379:172.21.32.13:6379 sky",
"dev:lib": "turbo run dev:lib" "dev:lib": "turbo run dev:lib",
"dev:oss": "turbo run dev:lib --filter=@kevisual/oss"
}, },
"keywords": [], "keywords": [],
"types": "types/index.d.ts", "types": "types/index.d.ts",

18
pnpm-lock.yaml generated
View File

@ -16,9 +16,6 @@ importers:
'@kevisual/local-app-manager': '@kevisual/local-app-manager':
specifier: 0.1.9 specifier: 0.1.9
version: 0.1.9(@kevisual/router@0.0.9)(@kevisual/types@0.0.6)(@kevisual/use-config@1.0.9)(pm2@6.0.5) version: 0.1.9(@kevisual/router@0.0.9)(@kevisual/types@0.0.6)(@kevisual/use-config@1.0.9)(pm2@6.0.5)
'@kevisual/permission':
specifier: workspace:*
version: link:submodules/permission
'@kevisual/router': '@kevisual/router':
specifier: 0.0.9 specifier: 0.0.9
version: 0.0.9 version: 0.0.9
@ -98,6 +95,12 @@ importers:
'@kevisual/code-center-module': '@kevisual/code-center-module':
specifier: workspace:* specifier: workspace:*
version: link:submodules/code-center-module version: link:submodules/code-center-module
'@kevisual/oss':
specifier: workspace:*
version: link:submodules/oss
'@kevisual/permission':
specifier: workspace:*
version: link:submodules/permission
'@kevisual/types': '@kevisual/types':
specifier: ^0.0.6 specifier: ^0.0.6
version: 0.0.6 version: 0.0.6
@ -288,6 +291,9 @@ importers:
submodules/oss: submodules/oss:
devDependencies: devDependencies:
dotenv:
specifier: ^16.4.7
version: 16.4.7
minio: minio:
specifier: ^8.0.5 specifier: ^8.0.5
version: 8.0.5 version: 8.0.5
@ -1255,6 +1261,10 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'} engines: {node: '>=8'}
dotenv@16.4.7:
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
engines: {node: '>=12'}
dotignore@0.1.2: dotignore@0.1.2:
resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==} resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==}
hasBin: true hasBin: true
@ -3791,6 +3801,8 @@ snapshots:
dependencies: dependencies:
path-type: 4.0.0 path-type: 4.0.0
dotenv@16.4.7: {}
dotignore@0.1.2: dotignore@0.1.2:
dependencies: dependencies:
minimatch: 3.1.2 minimatch: 3.1.2

View File

@ -6,7 +6,7 @@ import { router } from '../router.ts';
router.post('/api/minio', async (ctx) => { router.post('/api/minio', async (ctx) => {
let { username, appKey } = { username: '', appKey: '' }; let { username, appKey } = { username: '', appKey: '' };
const path = `${username}/${appKey}`; const path = `${username}/${appKey}`;
const res = await minioClient.listObjects(bucketName, path, true); const res = await minioClient.listObjectsV2(bucketName, path, true);
const file = res.filter((item) => item.isFile); const file = res.filter((item) => item.isFile);
const fileList = file.map((item) => { const fileList = file.map((item) => {
return { return {

View File

@ -1,6 +1,6 @@
import { sequelize } from '../../../modules/sequelize.ts'; import { sequelize } from '../../../modules/sequelize.ts';
import { DataTypes, Model } from 'sequelize'; import { DataTypes, Model } from 'sequelize';
import { AppData, AppType, AppStatus } from './app.ts'; import { AppData } from './app.ts';
export type AppList = Partial<InstanceType<typeof AppListModel>>; export type AppList = Partial<InstanceType<typeof AppListModel>>;

View File

@ -20,7 +20,7 @@ export class ConfigModel extends Model {
declare description: string; declare description: string;
declare tags: string[]; declare tags: string[];
/** /**
* key * @important key
*/ */
declare key: string; declare key: string;
declare data: ConfigData; // files declare data: ConfigData; // files
@ -121,6 +121,10 @@ ConfigModel.init(
type: DataTypes.JSONB, type: DataTypes.JSONB,
defaultValue: [], defaultValue: [],
}, },
hash: {
type: DataTypes.TEXT,
defaultValue: '',
},
data: { data: {
type: DataTypes.JSONB, type: DataTypes.JSONB,
defaultValue: {}, defaultValue: {},

View File

@ -1,9 +1,5 @@
import './container/index.ts'; import './container/index.ts';
import './page/index.ts';
import './resource/index.ts';
import './user/index.ts'; import './user/index.ts';
import './github/index.ts'; import './github/index.ts';
@ -12,8 +8,6 @@ import './app-manager/index.ts';
import './file/index.ts'; import './file/index.ts';
// import './packages/index.ts';
import './micro-app/index.ts'; import './micro-app/index.ts';
import './config/index.ts'; import './config/index.ts';

View File

@ -1 +0,0 @@
import './list.ts'

View File

@ -1,120 +0,0 @@
import { app } from '@/app.ts';
import { PackagesModel } from './models/index.ts';
import { Op } from 'sequelize';
import { CustomError } from '@kevisual/router';
app
.route({
path: 'packages',
key: 'list',
middleware: ['auth'],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const { uid } = tokenUser;
const { page = 1, pageSize = 999, search } = ctx.query;
const searchWhere = search ? { title: { [Op.like]: `%${search}%` } } : {};
const { rows: packages, count } = await PackagesModel.findAndCountAll({
where: {
uid,
...searchWhere,
},
limit: pageSize,
offset: (page - 1) * pageSize,
});
ctx.body = {
pagination: {
current: page,
pageSize,
total: count,
},
list: packages,
};
})
.addTo(app);
app
.route({
path: 'packages',
key: 'get',
middleware: ['auth'],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const { uid } = tokenUser;
const { id } = ctx.query;
if (!id) {
throw new CustomError('id is required');
}
const packages = await PackagesModel.findOne({
where: {
uid,
id,
},
});
if (!packages) {
throw new CustomError('not found data');
}
ctx.body = packages;
})
.addTo(app);
app
.route({
path: 'packages',
key: 'update',
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const { uid } = tokenUser;
const { id, ...rest } = ctx.request.body;
let packages: PackagesModel;
if (!id) {
packages = await PackagesModel.create({
...rest,
uid,
});
} else {
packages = await PackagesModel.findOne({
where: {
uid,
id,
},
});
if (!packages) {
throw new CustomError('not found data');
}
await packages.update({
...rest,
});
}
ctx.body = packages;
})
.addTo(app);
app
.route({
path: 'packages',
key: 'delete',
middleware: ['auth'],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const { uid } = tokenUser;
const { id } = ctx.request.body;
if (!id) {
throw new CustomError('id is required');
}
const packages = await PackagesModel.findOne({
where: {
uid,
id,
},
});
if (!packages) {
throw new CustomError('not found data');
}
await packages.destroy();
ctx.body = packages;
})
.addTo(app);

View File

@ -1,73 +0,0 @@
import { sequelize } from '../../../modules/sequelize.ts';
import { DataTypes, Model } from 'sequelize';
export interface PackagesData {}
export type PackagesPublish = {
key: string;
title?: string;
description?: string;
version?: string;
filesName?: any[];
};
export type Packages = Partial<InstanceType<typeof PackagesModel>>;
/**
*
*/
export class PackagesModel extends Model {
declare id: string;
declare title: string;
declare description: string;
declare tags: string[];
declare data: PackagesData; // files
declare publish: PackagesPublish;
declare uid: string;
declare expand: any;
}
PackagesModel.init(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
comment: 'id',
},
title: {
type: DataTypes.TEXT,
defaultValue: '',
},
description: {
type: DataTypes.TEXT,
defaultValue: '',
},
tags: {
type: DataTypes.JSONB,
defaultValue: [],
},
data: {
type: DataTypes.JSONB,
defaultValue: {},
},
publish: {
type: DataTypes.JSONB,
defaultValue: {},
},
expand: {
type: DataTypes.JSONB,
defaultValue: {},
},
uid: {
type: DataTypes.UUID,
allowNull: true,
},
},
{
sequelize,
tableName: 'kv_packages',
paranoid: true,
},
);
PackagesModel.sync({ alter: true, logging: false }).catch((e) => {
console.error('PackagesModel sync', e);
});

View File

@ -1,2 +0,0 @@
import './publish.ts';
import './list.ts';

View File

@ -1 +0,0 @@
export * from './publish-minio.ts';

View File

@ -1,35 +0,0 @@
import { Resource } from '../models/index.ts';
import { minioClient, bucketName } from '../../../modules/minio.ts';
type MinioRes = {
etag?: string; // 文件的etag, 用于后续的文件下载
versionId?: string;
};
type PublishOptions = {
name: string;
version: string;
code: string;
};
export const publishJsCode = async ({ name, version, code }: PublishOptions) => {
// publish to minio
const codeBuffer = Buffer.from(code);
const codePath = `${name}/${version}/index.js`;
try {
const res = await minioClient.putObject(bucketName, codePath, codeBuffer, codeBuffer.length, {
'Content-Type': 'application/javascript',
'Cache-Control': 'max-age=31536000, immutable',
});
return {
code: 200,
data: { ...res, path: codePath },
};
} catch (e) {
console.error('publish error', e.message);
return {
code: 500,
message: e.message,
};
}
};

View File

@ -1,77 +0,0 @@
import { ResourceModel } from './models/index.ts';
import { app } from '../../app.ts';
app
.route({
path: 'resource',
key: 'list',
middleware: ['auth'],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const list = await ResourceModel.findAll({
order: [['updatedAt', 'DESC']],
where: {
uid: tokenUser.id,
},
});
ctx.body = list;
return ctx;
})
.addTo(app);
app
.route({
path: 'resource',
key: 'get',
})
.define(async (ctx) => {
const id = ctx.query.id;
if (!id) {
ctx.throw('id is required');
}
const rm = await ResourceModel.findByPk(id);
if (!rm) {
ctx.throw('resource not found');
}
ctx.body = rm;
return ctx;
})
.addTo(app);
app
.route({ path: 'resource', key: 'update' })
.define(async (ctx) => {
const { data, id, ...rest } = ctx.query.data;
if (id) {
const resource = await ResourceModel.findByPk(id);
if (resource) {
const newResource = await resource.update({ data, ...rest });
ctx.body = newResource;
}
} else if (data) {
const resource = await ResourceModel.create({ data, ...rest });
ctx.body = resource;
}
})
.addTo(app);
app
.route({
path: 'resource',
key: 'delete',
middleware: ['auth'],
})
.define(async (ctx) => {
const id = ctx.query.id;
if (!id) {
ctx.throw('id is required');
}
const resource = await ResourceModel.findByPk(id);
if (!resource) {
ctx.throw('resource not found');
}
await resource.destroy();
ctx.body = 'success';
})
.addTo(app);

View File

@ -1,91 +0,0 @@
import { sequelize } from '../../../modules/sequelize.ts';
import { DataTypes, Model } from 'sequelize';
type FileUrlList = {
path: string;
etag: string;
versionId: string;
};
export interface ResourceData {
list: FileUrlList[];
lastestVersion: string;
updatedAt: string;
[key: string]: any;
}
export const defaultData: ResourceData = {
list: [],
lastestVersion: '0.0.0',
updatedAt: '',
};
export type Resource = {
id?: string;
name?: string;
description?: string;
source?: string;
sourceId?: string;
data?: ResourceData;
version?: string;
uid?: string;
};
/**
*
*/
export class ResourceModel extends Model {
declare id: string;
declare name: string;
declare description: string;
declare source: string;
declare sourceId: string;
declare data: ResourceData;
declare version: string;
declare uid: string;
}
ResourceModel.init(
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
comment: 'id',
},
name: {
type: DataTypes.STRING, // 第一次创建之后就不能修改了,因为这个是用来做唯一标识的
defaultValue: '',
},
description: {
type: DataTypes.TEXT,
defaultValue: '',
},
source: {
type: DataTypes.STRING,
defaultValue: '',
},
sourceId: {
type: DataTypes.STRING,
defaultValue: '',
},
version: {
type: DataTypes.STRING,
defaultValue: '0.0.0',
},
data: {
type: DataTypes.JSON,
defaultValue: {},
},
uid: {
type: DataTypes.UUID,
allowNull: true,
},
},
{
sequelize,
tableName: 'kv_resource',
paranoid: true,
},
);
ResourceModel.sync({ alter: true, logging: false }).catch((e) => {
console.error('ResourceModel sync', e);
});

View File

@ -1,69 +0,0 @@
import { defaultData, Resource, ResourceModel } from './models/index.ts';
import { ContainerModel } from './../container/models/index.ts';
import { app } from '../../app.ts';
import { Op } from 'sequelize';
import { publishJsCode } from './lib/publish-minio.ts';
import { CustomError } from '@kevisual/router';
// app
// .route({
// path: 'resource',
// key: 'publishContainer',
// idUsePath: true,
// })
// .define(async (ctx) => {
// const container = ctx.state.container as ContainerModel;
// const publish = container.publish;
// const code = container.code;
// let { name, rid, description, version = '0.0.1' } = publish;
// const where = [];
// if (rid) {
// where.push({ id: rid });
// }
// if (name) {
// where.push({ name });
// }
// let resource = await ResourceModel.findOne({ where: { [Op.or]: where } });
// let isCreate = false;
// if (!resource) {
// isCreate = true;
// resource = await ResourceModel.create({
// name,
// description,
// version,
// source: 'container',
// sourceId: container.id,
// data: {
// ...defaultData,
// updatedAt: new Date().toISOString(),
// },
// });
// }
// publish.rid = publish.rid || resource.id;
// // TODO: check version
// const res = await publishJsCode({ name, version, code });
// if (res.code === 200) {
// await container.update({ publish });
// const { etag, versionId, path } = res.data;
// resource.version = version;
// const newData = {
// list: [],
// ...resource.data,
// };
// newData.list.push({
// etag,
// versionId,
// path,
// });
// newData.lastestVersion = version;
// newData.updatedAt = new Date().toISOString();
// resource.data = newData;
// await resource.save();
// ctx.body = { resource, container, resourceIsNew: isCreate };
// } else {
// throw new CustomError(res.message);
// }
// // await container.update({ publish });
// })
// .addTo(app);

View File

@ -11,7 +11,7 @@
}, },
"dev:lib": { "dev:lib": {
"persistent": true, "persistent": true,
"cache": false "cache": true
} }
} }
} }