Refactor: Remove unused Convex HTTP routes and schema definitions
- Deleted `http.ts` which contained custom HTTP routes for authentication and JWKS. - Removed `schema.ts` that defined database schemas for `github_starred`, `users`, and `sessions`. - Updated `package.json` to remove the Convex dependency and updated other dependencies. - Deleted SQL script `clear.sql` for removing constraints from tables. - Removed `update.sh` script for updating dependencies. - Deleted demo application routes and models in `app-demo` directory. - Cleaned up unused modules and imports across various files. - Removed Redis and common utility scripts that were not in use. - Deleted test scripts related to user and bucket management.
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
import { Op } from 'sequelize';
|
||||
import { AppDemoModel } from './models/index.ts';
|
||||
import { app } from '@/app.ts';
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app-demo',
|
||||
key: 'list',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { page = 1, pageSize = 20, search, sort = 'DESC' } = ctx.query;
|
||||
const searchWhere = search
|
||||
? {
|
||||
[Op.or]: [{ title: { [Op.like]: `%${search}%` } }, { summary: { [Op.like]: `%${search}%` } }],
|
||||
}
|
||||
: {};
|
||||
|
||||
const { rows: appDemo, count } = await AppDemoModel.findAndCountAll({
|
||||
where: {
|
||||
uid: tokenUser.id,
|
||||
...searchWhere,
|
||||
},
|
||||
offset: (page - 1) * pageSize,
|
||||
limit: pageSize,
|
||||
order: [['updatedAt', sort]],
|
||||
});
|
||||
|
||||
ctx.body = {
|
||||
list: appDemo,
|
||||
pagination: {
|
||||
page,
|
||||
current: page,
|
||||
pageSize,
|
||||
total: count,
|
||||
},
|
||||
};
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app-demo',
|
||||
key: 'update',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id, data, updatedAt: _clear, createdAt: _clear2, ...rest } = ctx.query.data;
|
||||
let appDemo: AppDemoModel;
|
||||
let isNew = false;
|
||||
if (id) {
|
||||
const appDemo = await AppDemoModel.findByPk(id);
|
||||
if (appDemo.uid !== tokenUser.uid) {
|
||||
ctx.throw(403, 'No permission');
|
||||
}
|
||||
} else {
|
||||
appDemo = await AppDemoModel.create({
|
||||
data: data,
|
||||
...rest,
|
||||
uid: tokenUser.uid,
|
||||
});
|
||||
isNew = true;
|
||||
}
|
||||
if (!appDemo) {
|
||||
ctx.throw(404, 'AppDemo not found');
|
||||
}
|
||||
if (!isNew) {
|
||||
appDemo = await appDemo.update({
|
||||
data: { ...appDemo.data, ...data },
|
||||
...rest,
|
||||
});
|
||||
}
|
||||
|
||||
ctx.body = appDemo;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app-demo',
|
||||
key: 'delete',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id, force = false } = ctx.query.data || {};
|
||||
if (!id) {
|
||||
ctx.throw(400, 'id is required');
|
||||
}
|
||||
const appDemo = await AppDemoModel.findByPk(id);
|
||||
if (appDemo.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'No permission');
|
||||
}
|
||||
await appDemo.destroy({ force });
|
||||
ctx.body = appDemo;
|
||||
})
|
||||
.addTo(app);
|
||||
|
||||
app
|
||||
.route({
|
||||
path: 'app-demo',
|
||||
key: 'get',
|
||||
middleware: ['auth'],
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const tokenUser = ctx.state.tokenUser;
|
||||
const { id } = ctx.query.data || {};
|
||||
if (!id) {
|
||||
ctx.throw(400, 'id is required');
|
||||
}
|
||||
const appDemo = await AppDemoModel.findByPk(id);
|
||||
if (appDemo.uid !== tokenUser.id) {
|
||||
ctx.throw(403, 'No permission');
|
||||
}
|
||||
ctx.body = appDemo;
|
||||
})
|
||||
.addTo(app);
|
||||
@@ -1,71 +0,0 @@
|
||||
import { sequelize } from '@/modules/sequelize.ts';
|
||||
import { DataTypes, Model } from 'sequelize';
|
||||
|
||||
export interface AppDemoData {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export type AppDemo = Partial<InstanceType<typeof AppDemoModel>>;
|
||||
|
||||
export class AppDemoModel extends Model {
|
||||
declare id: string;
|
||||
declare title: string;
|
||||
declare description: string;
|
||||
declare summary: string;
|
||||
|
||||
declare data: AppDemoData;
|
||||
declare tags: string[];
|
||||
declare version: string;
|
||||
|
||||
declare uid: string;
|
||||
|
||||
declare createdAt: Date;
|
||||
declare updatedAt: Date;
|
||||
}
|
||||
|
||||
AppDemoModel.init(
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
},
|
||||
title: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
description: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
summary: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
tags: {
|
||||
type: DataTypes.JSONB,
|
||||
defaultValue: [],
|
||||
},
|
||||
version: {
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: 0,
|
||||
},
|
||||
data: {
|
||||
type: DataTypes.JSONB,
|
||||
defaultValue: {},
|
||||
},
|
||||
uid: {
|
||||
type: DataTypes.UUID,
|
||||
allowNull: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
tableName: 'kv_app_demo',
|
||||
paranoid: true,
|
||||
},
|
||||
);
|
||||
|
||||
// AppDemoModel.sync({ alter: true, logging: false }).catch((e) => {
|
||||
// console.error('AppDemoModel sync', e);
|
||||
// });
|
||||
@@ -1,3 +1 @@
|
||||
export { sequelize } from './sequelize.ts';
|
||||
|
||||
export * from './minio.ts'
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Client, } from 'minio';
|
||||
import { useConfig } from '@kevisual/use-config';
|
||||
const config = useConfig();
|
||||
const minioConfig = {
|
||||
endPoint: config.MINIO_ENDPOINT || 'localhost',
|
||||
// @ts-ignore
|
||||
port: parseInt(config.MINIO_PORT || '9000'),
|
||||
useSSL: config.MINIO_USE_SSL === 'true',
|
||||
accessKey: config.MINIO_ACCESS_KEY,
|
||||
secretKey: config.MINIO_SECRET_KEY,
|
||||
};
|
||||
export const minioClient = new Client(minioConfig);
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import { program, Command } from 'commander';
|
||||
// import { useContextKey } from '@kevisual/context';
|
||||
// import * as redisLib from './modules/redis.ts';
|
||||
// import * as sequelizeLib from './modules/sequelize.ts';
|
||||
// import * as minioLib from './modules/minio.ts';
|
||||
|
||||
// export const redis = useContextKey('redis', () => redisLib.redis);
|
||||
// export const minioClient = useContextKey('minioClient', () => minioLib.minioClient);
|
||||
// export const sequelize = useContextKey('sequelize', () => sequelizeLib.sequelize);
|
||||
|
||||
export { program, Command };
|
||||
|
||||
program.description('code-center的一部分工具');
|
||||
program.version('1.0.0', '-v, --version');
|
||||
@@ -1,5 +1,4 @@
|
||||
import { app } from '@/app.ts';
|
||||
import { AppModel, AppListModel } from '../module/index.ts';
|
||||
import { AppModel } from '../module/index.ts';
|
||||
export const mvAppFromUserAToUserB = async (userA: string, userB: string) => {
|
||||
const appList = await AppModel.findAll({
|
||||
where: {
|
||||
|
||||
@@ -80,8 +80,4 @@ AppDomainModel.init(
|
||||
tableName: 'kv_app_domain',
|
||||
paranoid: true,
|
||||
},
|
||||
);
|
||||
|
||||
// AppDomainModel.sync({ alter: true, logging: false }).catch((e) => {
|
||||
// console.error('AppDomainModel sync', e);
|
||||
// });
|
||||
);
|
||||
@@ -1,327 +0,0 @@
|
||||
import { useContextKey } from '@kevisual/context';
|
||||
import { nanoid, customAlphabet } from 'nanoid';
|
||||
import { DataTypes, Model, ModelAttributes } from 'sequelize';
|
||||
import type { Sequelize } from 'sequelize';
|
||||
export const random = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
||||
export type Mark = Partial<InstanceType<typeof MarkModel>>;
|
||||
export type MarkData = {
|
||||
md?: string; // markdown
|
||||
mdList?: string[]; // markdown list
|
||||
type?: string; // 类型 markdown | json | html | image | video | audio | code | link | file
|
||||
data?: any;
|
||||
key?: string; // 文件的名称, 唯一
|
||||
push?: boolean; // 是否推送到elasticsearch
|
||||
pushTime?: Date; // 推送时间
|
||||
summary?: string; // 摘要
|
||||
nodes?: MarkDataNode[]; // 节点
|
||||
[key: string]: any;
|
||||
};
|
||||
export type MarkFile = {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
size: number;
|
||||
type: 'self' | 'data' | 'generate'; // generate为生成文件
|
||||
query: string; // 'data.nodes[id].content';
|
||||
hash: string;
|
||||
fileKey: string; // 文件的名称, 唯一
|
||||
};
|
||||
export type MarkDataNode = {
|
||||
id?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
export type MarkConfig = {
|
||||
[key: string]: any;
|
||||
};
|
||||
export type MarkAuth = {
|
||||
[key: string]: any;
|
||||
};
|
||||
/**
|
||||
* 隐秘内容
|
||||
* auth
|
||||
* config
|
||||
*
|
||||
*/
|
||||
export class MarkModel extends Model {
|
||||
declare id: string;
|
||||
declare title: string; // 标题,可以ai生成
|
||||
declare description: string; // 描述,可以ai生成
|
||||
declare cover: string; // 封面,可以ai生成
|
||||
declare thumbnail: string; // 缩略图
|
||||
declare key: string; // 文件路径
|
||||
declare markType: string; // markdown | json | html | image | video | audio | code | link | file
|
||||
declare link: string; // 访问链接
|
||||
declare tags: string[]; // 标签
|
||||
declare summary: string; // 摘要, description的简化版
|
||||
declare data: MarkData; // 数据
|
||||
|
||||
declare uid: string; // 操作用户的id
|
||||
declare puid: string; // 父级用户的id, 真实用户
|
||||
declare config: MarkConfig; // mark属于一定不会暴露的内容。
|
||||
|
||||
declare fileList: MarkFile[]; // 文件管理
|
||||
declare uname: string; // 用户的名称, 或者着别名
|
||||
|
||||
declare markedAt: Date; // 标记时间
|
||||
declare createdAt: Date;
|
||||
declare updatedAt: Date;
|
||||
declare version: number;
|
||||
/**
|
||||
* 加锁更新data中的node的节点,通过node的id
|
||||
* @param param0
|
||||
*/
|
||||
static async updateJsonNode(id: string, node: MarkDataNode, opts?: { operate?: 'update' | 'delete'; Model?: any; sequelize?: Sequelize }) {
|
||||
const sequelize = opts?.sequelize || (await useContextKey('sequelize'));
|
||||
const transaction = await sequelize.transaction(); // 开启事务
|
||||
const operate = opts.operate || 'update';
|
||||
const isUpdate = operate === 'update';
|
||||
const Model = opts.Model || MarkModel;
|
||||
try {
|
||||
// 1. 获取当前的 JSONB 字段值(加锁)
|
||||
const mark = await Model.findByPk(id, {
|
||||
transaction,
|
||||
lock: transaction.LOCK.UPDATE, // 加锁,防止其他事务同时修改
|
||||
});
|
||||
if (!mark) {
|
||||
throw new Error('Mark not found');
|
||||
}
|
||||
// 2. 修改特定的数组元素
|
||||
const data = mark.data as MarkData;
|
||||
const items = data.nodes;
|
||||
if (!node.id) {
|
||||
node.id = random(12);
|
||||
}
|
||||
|
||||
// 找到要更新的元素
|
||||
const itemIndex = items.findIndex((item) => item.id === node.id);
|
||||
if (itemIndex === -1) {
|
||||
isUpdate && items.push(node);
|
||||
} else {
|
||||
if (isUpdate) {
|
||||
items[itemIndex] = node;
|
||||
} else {
|
||||
items.splice(itemIndex, 1);
|
||||
}
|
||||
}
|
||||
const version = Number(mark.version) + 1;
|
||||
// 4. 更新 JSONB 字段
|
||||
const result = await mark.update(
|
||||
{
|
||||
data: {
|
||||
...data,
|
||||
nodes: items,
|
||||
},
|
||||
version,
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
|
||||
await transaction.commit();
|
||||
return result;
|
||||
} catch (error) {
|
||||
await transaction.rollback();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
static async updateJsonNodes(id: string, nodes: { node: MarkDataNode; operate?: 'update' | 'delete' }[], opts?: { Model?: any; sequelize?: Sequelize }) {
|
||||
const sequelize = opts?.sequelize || (await useContextKey('sequelize'));
|
||||
const transaction = await sequelize.transaction(); // 开启事务
|
||||
const Model = opts?.Model || MarkModel;
|
||||
try {
|
||||
const mark = await Model.findByPk(id, {
|
||||
transaction,
|
||||
lock: transaction.LOCK.UPDATE, // 加锁,防止其他事务同时修改
|
||||
});
|
||||
if (!mark) {
|
||||
throw new Error('Mark not found');
|
||||
}
|
||||
const data = mark.data as MarkData;
|
||||
const _nodes = data.nodes || [];
|
||||
// 过滤不在nodes中的节点
|
||||
const blankNodes = nodes.filter((node) => !_nodes.find((n) => n.id === node.node.id)).map((node) => node.node);
|
||||
// 更新或删除节点
|
||||
const newNodes = _nodes
|
||||
.map((node) => {
|
||||
const nodeOperate = nodes.find((n) => n.node.id === node.id);
|
||||
if (nodeOperate) {
|
||||
if (nodeOperate.operate === 'delete') {
|
||||
return null;
|
||||
}
|
||||
return nodeOperate.node;
|
||||
}
|
||||
return node;
|
||||
})
|
||||
.filter((node) => node !== null);
|
||||
const version = Number(mark.version) + 1;
|
||||
const result = await mark.update(
|
||||
{
|
||||
data: {
|
||||
...data,
|
||||
nodes: [...blankNodes, ...newNodes],
|
||||
},
|
||||
version,
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
await transaction.commit();
|
||||
return result;
|
||||
} catch (error) {
|
||||
await transaction.rollback();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
static async updateData(id: string, data: MarkData, opts: { Model?: any; sequelize?: Sequelize }) {
|
||||
const sequelize = opts.sequelize || (await useContextKey('sequelize'));
|
||||
const transaction = await sequelize.transaction(); // 开启事务
|
||||
const Model = opts.Model || MarkModel;
|
||||
const mark = await Model.findByPk(id, {
|
||||
transaction,
|
||||
lock: transaction.LOCK.UPDATE, // 加锁,防止其他事务同时修改
|
||||
});
|
||||
if (!mark) {
|
||||
throw new Error('Mark not found');
|
||||
}
|
||||
const version = Number(mark.version) + 1;
|
||||
const result = await mark.update(
|
||||
{
|
||||
...mark.data,
|
||||
...data,
|
||||
data: {
|
||||
...mark.data,
|
||||
...data,
|
||||
},
|
||||
version,
|
||||
},
|
||||
{ transaction },
|
||||
);
|
||||
await transaction.commit();
|
||||
return result;
|
||||
}
|
||||
static async createNew(data: any, opts: { Model?: any; sequelize?: Sequelize }) {
|
||||
const sequelize = opts.sequelize || (await useContextKey('sequelize'));
|
||||
const transaction = await sequelize.transaction(); // 开启事务
|
||||
const Model = opts.Model || MarkModel;
|
||||
const result = await Model.create({ ...data, version: 1 }, { transaction });
|
||||
await transaction.commit();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
export type MarkInitOpts<T = any> = {
|
||||
tableName: string;
|
||||
sequelize?: Sequelize;
|
||||
callInit?: (attribute: ModelAttributes) => ModelAttributes;
|
||||
Model?: T extends typeof MarkModel ? T : typeof MarkModel;
|
||||
};
|
||||
export type Opts = {
|
||||
sync?: boolean;
|
||||
alter?: boolean;
|
||||
logging?: boolean | ((...args: any) => any);
|
||||
force?: boolean;
|
||||
};
|
||||
export const MarkMInit = async <T = any>(opts: MarkInitOpts<T>, sync?: Opts) => {
|
||||
const sequelize = await useContextKey('sequelize');
|
||||
opts.sequelize = opts.sequelize || sequelize;
|
||||
const { callInit, Model, ...optsRest } = opts;
|
||||
const modelAttribute = {
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
comment: 'id',
|
||||
},
|
||||
title: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
key: {
|
||||
type: DataTypes.TEXT, // 对应的minio的文件路径
|
||||
defaultValue: '',
|
||||
},
|
||||
markType: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: 'md', // markdown | json | html | image | video | audio | code | link | file
|
||||
comment: '类型',
|
||||
},
|
||||
description: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
},
|
||||
cover: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
comment: '封面',
|
||||
},
|
||||
thumbnail: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
comment: '缩略图',
|
||||
},
|
||||
link: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
comment: '链接',
|
||||
},
|
||||
tags: {
|
||||
type: DataTypes.JSONB,
|
||||
defaultValue: [],
|
||||
},
|
||||
summary: {
|
||||
type: DataTypes.TEXT,
|
||||
defaultValue: '',
|
||||
comment: '摘要',
|
||||
},
|
||||
config: {
|
||||
type: DataTypes.JSONB,
|
||||
defaultValue: {},
|
||||
},
|
||||
data: {
|
||||
type: DataTypes.JSONB,
|
||||
defaultValue: {},
|
||||
},
|
||||
fileList: {
|
||||
type: DataTypes.JSONB,
|
||||
defaultValue: [],
|
||||
},
|
||||
uname: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: '',
|
||||
comment: '用户的名称, 更新后的用户的名称',
|
||||
},
|
||||
version: {
|
||||
type: DataTypes.INTEGER, // 更新刷新版本,多人协作
|
||||
defaultValue: 1,
|
||||
},
|
||||
markedAt: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '标记时间',
|
||||
},
|
||||
uid: {
|
||||
type: DataTypes.UUID,
|
||||
allowNull: true,
|
||||
},
|
||||
puid: {
|
||||
type: DataTypes.UUID,
|
||||
allowNull: true,
|
||||
},
|
||||
};
|
||||
const InitModel = Model || MarkModel;
|
||||
InitModel.init(callInit ? callInit(modelAttribute) : modelAttribute, {
|
||||
sequelize,
|
||||
paranoid: true,
|
||||
...optsRest,
|
||||
});
|
||||
if (sync && sync.sync) {
|
||||
const { sync: _, ...rest } = sync;
|
||||
MarkModel.sync({ alter: true, logging: false, ...rest }).catch((e) => {
|
||||
console.error('MarkModel sync', e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const markModelInit = MarkMInit;
|
||||
|
||||
export const syncMarkModel = async (sync?: Opts, tableName = 'micro_mark') => {
|
||||
const sequelize = await useContextKey('sequelize');
|
||||
await MarkMInit({ sequelize, tableName }, sync);
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
export * from '@kevisual/code-center-module/src/mark/mark-model.ts';
|
||||
import { markModelInit, MarkModel, syncMarkModel } from '@kevisual/code-center-module/src/mark/mark-model.ts';
|
||||
export { markModelInit, MarkModel };
|
||||
|
||||
syncMarkModel({ sync: true, alter: true, logging: false });
|
||||
@@ -1,4 +1,4 @@
|
||||
import { app, sequelize } from '@/app.ts';
|
||||
import { app } from '@/app.ts';
|
||||
import { Org } from '@/models/org.ts';
|
||||
import { User } from '@/models/user.ts';
|
||||
import { Op } from 'sequelize';
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import { program, Command } from '../program.ts';
|
||||
import { initUser, logger, close } from './common.ts';
|
||||
const usrCommand = new Command('user').description('用户相关操作');
|
||||
program.addCommand(usrCommand);
|
||||
|
||||
const changePwd = new Command('pwd')
|
||||
.description('修改用户密码')
|
||||
.option('-u, --username <username>', '用户名')
|
||||
.option('-p, --password <password>', '新密码')
|
||||
.action(async (opts) => {
|
||||
const username = opts.username;
|
||||
const password = opts.password;
|
||||
if (!username) {
|
||||
logger.error('用户名不能为空');
|
||||
close();
|
||||
return;
|
||||
}
|
||||
const { User } = await initUser();
|
||||
const newPassword = password || 'kevisual';
|
||||
|
||||
logger.info(`用户名: ${username}`);
|
||||
logger.info(`新密码: ${newPassword}`);
|
||||
const user = await User.findOne({ where: { username: username }, logging: false });
|
||||
if (!user) {
|
||||
logger.error('用户不存在');
|
||||
return;
|
||||
}
|
||||
const newP = await user.createPassword(newPassword);
|
||||
logger.info('新密码加密成功', '新密码: ', newPassword);
|
||||
close();
|
||||
});
|
||||
usrCommand.addCommand(changePwd);
|
||||
|
||||
const list = new Command('list').description('列出所有用户').action(async () => {
|
||||
console.log('列出所有用户 start');
|
||||
const { User } = await initUser();
|
||||
console.log('列出所有用户');
|
||||
const users = await User.findAll({ limit: 10, order: [['createdAt', 'DESC']] });
|
||||
if (users.length === 0) {
|
||||
logger.info('没有用户');
|
||||
return;
|
||||
}
|
||||
users.forEach((user) => {
|
||||
console.log(`用户名: ${user.username}`);
|
||||
});
|
||||
console.log(`用户数量: ${users.length}`);
|
||||
await close();
|
||||
});
|
||||
|
||||
usrCommand.addCommand(list);
|
||||
@@ -1,3 +0,0 @@
|
||||
import * as redisLib from '../modules/redis.ts';
|
||||
import { useContextKey, useContext } from '@kevisual/context';
|
||||
export const redis = useContextKey('redis', () => redisLib.redis);
|
||||
@@ -1,34 +0,0 @@
|
||||
import { config } from '../modules/config.ts';
|
||||
import { sequelize } from '../modules/sequelize.ts';
|
||||
export { program, Command } from '../program.ts';
|
||||
import { User, UserInit, OrgInit, Org, UserSecretInit, UserSecret } from '../auth/index.ts';
|
||||
import { Logger } from '@kevisual/logger';
|
||||
export const close = async () => {
|
||||
process.exit(0);
|
||||
};
|
||||
export { sequelize };
|
||||
export const logger = new Logger({
|
||||
level: (config?.LOG_LEVEL || 'info') as any,
|
||||
showTime: true,
|
||||
});
|
||||
|
||||
export const initUser = async () => {
|
||||
console.log('init user');
|
||||
await UserInit(sequelize, undefined, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
await OrgInit(sequelize, undefined, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
await UserSecretInit(sequelize, undefined, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
return {
|
||||
User: User,
|
||||
Org: Org,
|
||||
UserSecret: UserSecret,
|
||||
};
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
import { AppListModel, AppModel } from '../routes/app-manager/module/index.ts';
|
||||
|
||||
import { program, Command, close } from './common.ts';
|
||||
|
||||
const app = program.command('app');
|
||||
|
||||
const appList = new Command('list').action(async () => {
|
||||
const list = await AppListModel.findAll();
|
||||
console.log(list.map((item) => item.toJSON()));
|
||||
close();
|
||||
});
|
||||
app.addCommand(appList);
|
||||
@@ -1,22 +0,0 @@
|
||||
import { Client } from 'minio'
|
||||
|
||||
export async function createBucket(client: Client, bucketName: string) {
|
||||
const exists = await client.bucketExists(bucketName)
|
||||
if (!exists) {
|
||||
await client.makeBucket(bucketName, '')
|
||||
console.log(`Bucket "${bucketName}" created successfully.`)
|
||||
} else {
|
||||
console.log(`Bucket "${bucketName}" already exists.`)
|
||||
}
|
||||
}
|
||||
|
||||
const minioClient = new Client({
|
||||
endPoint: 'minio.kevisual.cn',
|
||||
port: 9000,
|
||||
useSSL: false,
|
||||
accessKey: 'admin',
|
||||
secretKey: 'xiongxiao',
|
||||
})
|
||||
createBucket(minioClient, 'nocodb').catch((err) => {
|
||||
console.error('Error creating bucket:', err)
|
||||
})
|
||||
@@ -1,62 +0,0 @@
|
||||
import { sequelize } from '../modules/sequelize.ts';
|
||||
import { initUser } from '../scripts/common.ts';
|
||||
import '../scripts/common-redis.ts';
|
||||
import { useContextKey } from '@kevisual/context';
|
||||
|
||||
export const main = async () => {
|
||||
const models = await initUser();
|
||||
|
||||
const username = 'root';
|
||||
const orgname = 'admin';
|
||||
|
||||
const user = await models.User.findOne({ where: { username } });
|
||||
const org = await models.User.findOne({ where: { username: orgname } });
|
||||
|
||||
console.log('user.id', user?.id);
|
||||
console.log('org.id', org?.id);
|
||||
// const userSecret1 = await models.UserSecret.createSecret(user?.id!);
|
||||
// userSecret1.title = 'root secret';
|
||||
// await userSecret1.save();
|
||||
// await models.UserSecret.destroy({
|
||||
// where: {
|
||||
// orgId: '16a496d4-8cd6-4e02-b403-c2adc006a53d',
|
||||
// },
|
||||
// });
|
||||
const userSecret2 = await models.UserSecret.createSecret(user?.id!, org?.id!);
|
||||
userSecret2.title = 'root org secret';
|
||||
await userSecret2.save();
|
||||
|
||||
const secretList = await models.UserSecret.findAll();
|
||||
for (const secret of secretList) {
|
||||
console.log(`\nSecret ID: ${secret.id}, User ID: ${secret.userId}, Org ID: ${secret.orgId}, Token: ${secret.token}, Expired Time: ${secret.expiredTime}`);
|
||||
}
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
export const dropTable = async () => {
|
||||
await sequelize.query('DROP TABLE IF EXISTS "cf_user_secrets"');
|
||||
console.log('UserSecret table dropped');
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
// dropTable()
|
||||
|
||||
const token1 = 'sk_tvwzgp5lky8iupawh0encvd52vji4o8argvd2x668gn15q83xpgo8fe10ny7wfsq';
|
||||
const orgToken2 = 'sk_x37p8iifh6k18c3f121w49nmfy1sbjqpyol9fcsz0lmc5dz493wrfwvtxc4gi9od';
|
||||
|
||||
export const main2 = async () => {
|
||||
const redis = useContextKey('redis');
|
||||
if (!redis) {
|
||||
console.error('Redis is not initialized');
|
||||
return;
|
||||
}
|
||||
const models = await initUser();
|
||||
const UserSecret = models.UserSecret;
|
||||
const v = await models.UserSecret.verifyToken(token1);
|
||||
console.log('verifyToken', v);
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
// main2();
|
||||
@@ -1,46 +0,0 @@
|
||||
import { useContextKey } from '@kevisual/context';
|
||||
import { sequelize } from '../modules/sequelize.ts';
|
||||
import { MarkModel, syncMarkModel } from '../routes/mark/model.ts';
|
||||
export const sequelize2 = useContextKey('sequelize', () => sequelize);
|
||||
|
||||
const main = async () => {
|
||||
// 把所有markmodel的表的source字段的类型改为jsonb
|
||||
// const marks = await MarkModel.findAll();
|
||||
// const mark = marks[0];
|
||||
|
||||
// for (const mark of marks) {
|
||||
// if (mark.source) {
|
||||
// try {
|
||||
// await MarkModel.update({ source: {} }, { where: { id: mark.id } });
|
||||
// } catch (e) {
|
||||
// console.error('update source error:', e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
console.log('update source success');
|
||||
// await MarkModel.sync({ alter: true, logging: true }).catch((e) => {
|
||||
// console.error('MarkModel.sync error:', e);
|
||||
// });
|
||||
await syncMarkModel({ alter: true, logging: true, sync: true });
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
const sql = `ALTER TABLE "micro_mark" ALTER COLUMN "source" DROP NOT NULL;ALTER TABLE "micro_mark" ALTER COLUMN "source" SET DEFAULT '{}';ALTER TABLE "micro_mark" ALTER COLUMN "source" TYPE JSONB ; COMMENT ON COLUMN "micro_mark"."source" IS '需要的数据的来源,作为一个备注使用。';`;
|
||||
|
||||
// sequelize
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
const runSql = async () => {
|
||||
sequelize
|
||||
.query(sql)
|
||||
.then(() => {
|
||||
console.log('update source success');
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error('update source error:', e);
|
||||
});
|
||||
};
|
||||
|
||||
// runSql();
|
||||
@@ -1,48 +0,0 @@
|
||||
import { sequelize } from '../modules/sequelize.ts';
|
||||
import { User, UserInit, UserServices, Org, OrgInit } from '../auth/index.ts';
|
||||
|
||||
// User.sync({ alter: true, logging: true }).then(() => {
|
||||
// console.log('sync user done');
|
||||
// });
|
||||
|
||||
// class UserChange extends User {
|
||||
// static async syncUser() {
|
||||
// await UserChange.sync({ alter: true, logging: false });
|
||||
// console.log('sync user done');
|
||||
// }
|
||||
// }
|
||||
export const main = async () => {
|
||||
await UserInit(sequelize, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
await OrgInit(sequelize, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
const user = await User.findAll({});
|
||||
for (const u of user) {
|
||||
console.log(u.username, u.type);
|
||||
}
|
||||
};
|
||||
|
||||
main();
|
||||
export const changeRootPassword = async () => {
|
||||
await OrgInit(sequelize, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
await UserInit(sequelize, null, {
|
||||
alter: true,
|
||||
logging: false,
|
||||
});
|
||||
const user = await User.findOne({ where: { username: 'root' } });
|
||||
if (user) {
|
||||
await user.createPassword('');
|
||||
await user.save();
|
||||
console.log('change root password done');
|
||||
process.exit(0);
|
||||
}
|
||||
};
|
||||
|
||||
// changeRootPassword();
|
||||
@@ -1,10 +0,0 @@
|
||||
import { sequelize } from '../modules/sequelize.ts';
|
||||
|
||||
console.log('sequelize');
|
||||
|
||||
// 获取所有表名
|
||||
const [tables] = await sequelize.query(
|
||||
"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';"
|
||||
);
|
||||
|
||||
console.log('tables', tables);
|
||||
Reference in New Issue
Block a user