feat(container): add CRUD operations for container management
- Implemented routes for listing, retrieving, updating, and deleting containers. - Added ContainerModel with necessary fields and methods for data handling. - Created utility functions for fetching container data by ID. feat(page): enhance page management with CRUD and publish functionality - Developed routes for managing pages, including listing, updating, and deleting. - Integrated caching and zip file generation for page exports. - Added publish functionality to manage app versions and file uploads. feat(prompts): implement prompt management with CRUD operations - Created routes for listing, updating, and deleting prompts. - Added pagination and search capabilities for prompt listing. test: add common query utilities and prompt tests - Implemented common query utilities for API interactions. - Added tests for prompt listing functionality.
This commit is contained in:
1
src/old-apps/container/index.ts
Normal file
1
src/old-apps/container/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
import './list.ts';
|
||||
108
src/old-apps/container/list.ts
Normal file
108
src/old-apps/container/list.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { CustomError } from '@kevisual/router';
|
||||
import { app } from '../../app.ts';
|
||||
import { ContainerModel, ContainerData, Container } from './models/index.ts';
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'container',
|
||||
key: 'list',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const list = await ContainerModel.findAll({
|
||||
order: [['updatedAt', 'DESC']],
|
||||
where: {
|
||||
uid: tokenUser.id,
|
||||
},
|
||||
attributes: { exclude: ['code'] },
|
||||
});
|
||||
ctx.body = list;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'container',
|
||||
key: 'get',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const id = ctx.query.id;
|
||||
if (!id) {
|
||||
throw new CustomError('id is required');
|
||||
}
|
||||
const container = await ContainerModel.findByPk(id);
|
||||
if (!container) {
|
||||
throw new CustomError('container not found');
|
||||
}
|
||||
if (container.uid !== tokenUser.id) {
|
||||
throw new CustomError('container not found');
|
||||
}
|
||||
ctx.body = container;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'container',
|
||||
key: 'update',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const data = ctx.query.data;
|
||||
const { id, ...container } = data;
|
||||
let containerModel: ContainerModel | null = null;
|
||||
if (id) {
|
||||
containerModel = await ContainerModel.findByPk(id);
|
||||
if (containerModel) {
|
||||
containerModel.update({
|
||||
...container,
|
||||
publish: {
|
||||
...containerModel.publish,
|
||||
...container.publish,
|
||||
},
|
||||
});
|
||||
await containerModel.save();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
containerModel = await ContainerModel.create({
|
||||
...container,
|
||||
uid: tokenUser.id,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log('error', e);
|
||||
}
|
||||
console.log('containerModel', container);
|
||||
}
|
||||
ctx.body = containerModel;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'container',
|
||||
key: 'delete',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const id = ctx.query.id;
|
||||
const container = await ContainerModel.findByPk(id);
|
||||
if (!container) {
|
||||
throw new CustomError('container not found');
|
||||
}
|
||||
if (container.uid !== tokenUser.id) {
|
||||
throw new CustomError('container not found');
|
||||
}
|
||||
await container.destroy();
|
||||
ctx.body = container;
|
||||
return ctx;
|
||||
})
|
||||
.addTo(app);
|
||||
101
src/old-apps/container/models/index.ts
Normal file
101
src/old-apps/container/models/index.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { sequelize } from '../../../modules/sequelize.ts';
|
||||
import { DataTypes, Model } from 'sequelize';
|
||||
import crypto from 'crypto';
|
||||
export interface ContainerData {}
|
||||
export type ContainerPublish = {
|
||||
key: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
fileName?: string;
|
||||
version?: string;
|
||||
};
|
||||
export type Container = Partial<InstanceType<typeof ContainerModel>>;
|
||||
|
||||
/**
|
||||
* 用户代码容器
|
||||
*/
|
||||
export class ContainerModel extends Model {
|
||||
declare id: string;
|
||||
// 标题
|
||||
declare title: string;
|
||||
// 描述
|
||||
declare description: string;
|
||||
// 类型
|
||||
declare type: string;
|
||||
// 标签
|
||||
declare tags: string[];
|
||||
// 代码
|
||||
declare code: string;
|
||||
// hash 值
|
||||
declare hash: string;
|
||||
// 数据
|
||||
declare data: ContainerData;
|
||||
// 发布
|
||||
declare publish: ContainerPublish;
|
||||
// 用户 id
|
||||
declare uid: string;
|
||||
declare updatedAt: Date;
|
||||
declare createdAt: Date;
|
||||
createHash() {
|
||||
const { code } = this;
|
||||
const hash = crypto.createHash('md5');
|
||||
hash.update(code);
|
||||
this.hash = hash.digest('hex');
|
||||
}
|
||||
}
|
||||
ContainerModel.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.JSON,
|
||||
defaultValue: [],
|
||||
},
|
||||
type: {
|
||||
type: DataTypes.STRING, // 代码类型, html, js, render-js
|
||||
defaultValue: 'render-js',
|
||||
},
|
||||
code: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
hash: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
data: {
|
||||
type: DataTypes.JSON,
|
||||
defaultValue: {},
|
||||
},
|
||||
publish: {
|
||||
type: DataTypes.JSON,
|
||||
defaultValue: {},
|
||||
},
|
||||
|
||||
uid: {
|
||||
type: DataTypes.UUID,
|
||||
allowNull: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
tableName: 'kv_container',
|
||||
paranoid: true,
|
||||
},
|
||||
);
|
||||
|
||||
// ContainerModel.sync({ alter: true, logging: false }).catch((e) => {
|
||||
// console.error('ContainerModel sync', e);
|
||||
// });
|
||||
11
src/old-apps/container/module/get-container-file.ts
Normal file
11
src/old-apps/container/module/get-container-file.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { ContainerModel } from '../models/index.ts';
|
||||
|
||||
export const getContainerById = async (id: string) => {
|
||||
const container = await ContainerModel.findByPk(id);
|
||||
const code = container?.code;
|
||||
return {
|
||||
code,
|
||||
id: container?.id,
|
||||
updatedAt: new Date(container?.updatedAt).getTime(),
|
||||
};
|
||||
};
|
||||
3
src/old-apps/container/type.ts
Normal file
3
src/old-apps/container/type.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { ContainerData } from './models/index.ts';
|
||||
|
||||
export { ContainerData };
|
||||
Reference in New Issue
Block a user