diff --git a/.gitignore b/.gitignore index 0f7caac..40af2b4 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ release/* !release/.gitkeep .turbo + +.env diff --git a/package.json b/package.json index 3d4b0d0..7fb86d6 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "pub": "envision pack -p -u", "ssh": "ssh -L 6379:localhost:6379 light ", "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": [], "types": "types/index.d.ts", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c25100e..031c4e6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,9 +16,6 @@ importers: '@kevisual/local-app-manager': 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) - '@kevisual/permission': - specifier: workspace:* - version: link:submodules/permission '@kevisual/router': specifier: 0.0.9 version: 0.0.9 @@ -98,6 +95,12 @@ importers: '@kevisual/code-center-module': specifier: workspace:* version: link:submodules/code-center-module + '@kevisual/oss': + specifier: workspace:* + version: link:submodules/oss + '@kevisual/permission': + specifier: workspace:* + version: link:submodules/permission '@kevisual/types': specifier: ^0.0.6 version: 0.0.6 @@ -288,6 +291,9 @@ importers: submodules/oss: devDependencies: + dotenv: + specifier: ^16.4.7 + version: 16.4.7 minio: specifier: ^8.0.5 version: 8.0.5 @@ -1255,6 +1261,10 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + dotignore@0.1.2: resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==} hasBin: true @@ -3791,6 +3801,8 @@ snapshots: dependencies: path-type: 4.0.0 + dotenv@16.4.7: {} + dotignore@0.1.2: dependencies: minimatch: 3.1.2 diff --git a/src/routes-simple/minio/download.ts b/src/routes-simple/minio/download.ts index f1de090..58ba56d 100644 --- a/src/routes-simple/minio/download.ts +++ b/src/routes-simple/minio/download.ts @@ -6,7 +6,7 @@ import { router } from '../router.ts'; router.post('/api/minio', async (ctx) => { let { username, appKey } = { 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 fileList = file.map((item) => { return { diff --git a/src/routes/app-manager/module/app-list.ts b/src/routes/app-manager/module/app-list.ts index f24f53a..3650b38 100644 --- a/src/routes/app-manager/module/app-list.ts +++ b/src/routes/app-manager/module/app-list.ts @@ -1,6 +1,6 @@ import { sequelize } from '../../../modules/sequelize.ts'; import { DataTypes, Model } from 'sequelize'; -import { AppData, AppType, AppStatus } from './app.ts'; +import { AppData } from './app.ts'; export type AppList = Partial>; diff --git a/src/routes/config/models/model.ts b/src/routes/config/models/model.ts index 485fb98..6e23f32 100644 --- a/src/routes/config/models/model.ts +++ b/src/routes/config/models/model.ts @@ -20,7 +20,7 @@ export class ConfigModel extends Model { declare description: string; declare tags: string[]; /** - * 配置key, 默认可以为空,如何设置了,必须要唯一。 + * @important 配置key, 默认可以为空,如何设置了,必须要唯一。 */ declare key: string; declare data: ConfigData; // files @@ -121,6 +121,10 @@ ConfigModel.init( type: DataTypes.JSONB, defaultValue: [], }, + hash: { + type: DataTypes.TEXT, + defaultValue: '', + }, data: { type: DataTypes.JSONB, defaultValue: {}, diff --git a/src/routes/index.ts b/src/routes/index.ts index c9844c1..237dd35 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,9 +1,5 @@ import './container/index.ts'; -import './page/index.ts'; - -import './resource/index.ts'; - import './user/index.ts'; import './github/index.ts'; @@ -12,8 +8,6 @@ import './app-manager/index.ts'; import './file/index.ts'; -// import './packages/index.ts'; - import './micro-app/index.ts'; import './config/index.ts'; diff --git a/src/routes/packages/index.ts b/src/routes/packages/index.ts deleted file mode 100644 index 9166f9d..0000000 --- a/src/routes/packages/index.ts +++ /dev/null @@ -1 +0,0 @@ -import './list.ts' \ No newline at end of file diff --git a/src/routes/packages/list.ts b/src/routes/packages/list.ts deleted file mode 100644 index 9e8660d..0000000 --- a/src/routes/packages/list.ts +++ /dev/null @@ -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); diff --git a/src/routes/packages/models/index.ts b/src/routes/packages/models/index.ts deleted file mode 100644 index be383f6..0000000 --- a/src/routes/packages/models/index.ts +++ /dev/null @@ -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>; - -/** - * 用户代码容器 - */ -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); -}); diff --git a/src/routes/resource/index.ts b/src/routes/resource/index.ts deleted file mode 100644 index a3e8ab4..0000000 --- a/src/routes/resource/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import './publish.ts'; -import './list.ts'; diff --git a/src/routes/resource/lib/index.ts b/src/routes/resource/lib/index.ts deleted file mode 100644 index b002fd9..0000000 --- a/src/routes/resource/lib/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './publish-minio.ts'; diff --git a/src/routes/resource/lib/publish-minio.ts b/src/routes/resource/lib/publish-minio.ts deleted file mode 100644 index 7d822df..0000000 --- a/src/routes/resource/lib/publish-minio.ts +++ /dev/null @@ -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, - }; - } -}; diff --git a/src/routes/resource/list.ts b/src/routes/resource/list.ts deleted file mode 100644 index 388cfae..0000000 --- a/src/routes/resource/list.ts +++ /dev/null @@ -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); diff --git a/src/routes/resource/models/index.ts b/src/routes/resource/models/index.ts deleted file mode 100644 index 0a6a352..0000000 --- a/src/routes/resource/models/index.ts +++ /dev/null @@ -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); -}); diff --git a/src/routes/resource/publish.ts b/src/routes/resource/publish.ts deleted file mode 100644 index af08944..0000000 --- a/src/routes/resource/publish.ts +++ /dev/null @@ -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); diff --git a/turbo.json b/turbo.json index a7a1e28..a1a46af 100644 --- a/turbo.json +++ b/turbo.json @@ -11,7 +11,7 @@ }, "dev:lib": { "persistent": true, - "cache": false + "cache": true } } } \ No newline at end of file