From 0eae9458c62dc198b84f49930966c5f226fd5157 Mon Sep 17 00:00:00 2001 From: xion Date: Mon, 21 Oct 2024 01:31:58 +0800 Subject: [PATCH] feat: add snippet and test for supa db --- packages/var-proxy | 2 +- src/models-supa/snippet.ts | 54 +++++++++++++++++++++++ src/models/user.ts | 21 ++++++++- src/modules/sequelize-supa.ts | 26 +++++++++++ src/routes/app-manager/list.ts | 79 ++++++++++++++++++---------------- src/routes/snippet/index.ts | 1 + src/routes/snippet/list.ts | 13 ++++++ src/scripts/sp-snippet.ts | 21 +++++++++ 8 files changed, 177 insertions(+), 40 deletions(-) create mode 100644 src/models-supa/snippet.ts create mode 100644 src/modules/sequelize-supa.ts create mode 100644 src/routes/snippet/index.ts create mode 100644 src/routes/snippet/list.ts create mode 100644 src/scripts/sp-snippet.ts diff --git a/packages/var-proxy b/packages/var-proxy index 42e32ad..73118f8 160000 --- a/packages/var-proxy +++ b/packages/var-proxy @@ -1 +1 @@ -Subproject commit 42e32adf869afcaaff13a3f283a590741611558d +Subproject commit 73118f845456d18a22dc652fbf240d4b955c4fc5 diff --git a/src/models-supa/snippet.ts b/src/models-supa/snippet.ts new file mode 100644 index 0000000..259fdb2 --- /dev/null +++ b/src/models-supa/snippet.ts @@ -0,0 +1,54 @@ +import { sequelize } from '@/modules/sequelize-supa.ts'; +import { DataTypes, Model } from 'sequelize'; + +export class Snippet extends Model { + declare id: string; + declare title: string; + declare description: string; + declare snippet: string; + declare keyword: string; + declare user_id: string; + declare data: any; +} + +Snippet.init( + { + id: { + type: DataTypes.UUID, + primaryKey: true, + defaultValue: DataTypes.UUIDV4, + }, + title: { + type: DataTypes.TEXT, + allowNull: true, + }, + description: { + type: DataTypes.TEXT, + allowNull: true, + }, + snippet: { + type: DataTypes.TEXT, + allowNull: true, + }, + keyword: { + type: DataTypes.STRING, + }, + user_id: { + type: DataTypes.UUID, + }, + data: { + type: DataTypes.JSONB, + allowNull: true, + defaultValue: {}, + }, + }, + { + sequelize, + tableName: 'snippet', + paranoid: true, + }, +); +// 当 +// Snippet.sync({ alter: true, logging: false }).catch((e) => { +// console.error('Snippet sync error', e); +// }); diff --git a/src/models/user.ts b/src/models/user.ts index a21a0e2..23c646f 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -26,15 +26,29 @@ export class User extends Model { declare orgId: string; declare email: string; declare avatar: string; + declare supaId: string; tokenUser: any; setTokenUser(tokenUser: any) { this.tokenUser = tokenUser; } + /** + * uid 是用于 orgId 的用户id + * @param uid + * @returns + */ async createToken(uid?: string) { - const { id, username, type } = this; + const { id, username, type, supaId } = this; const expireTime = 60 * 60 * 24 * 7; // 7 days const now = new Date().getTime(); - const token = await createToken({ id, username, uid, type }, config.tokenSecret); + let supa = {}; + if (supaId) { + supa = { + aud: 'authenticated', + role: 'authenticated', + sub: supaId, + }; + } + const token = await createToken({ id, username, uid, type, ...supa }, config.tokenSecret); return { token, expireTime: now + expireTime }; } static async verifyToken(token: string) { @@ -168,6 +182,9 @@ User.init( orgId: { type: DataTypes.UUID, }, + supaId: { + type: DataTypes.UUID, + }, needChangePassword: { type: DataTypes.BOOLEAN, defaultValue: false, diff --git a/src/modules/sequelize-supa.ts b/src/modules/sequelize-supa.ts new file mode 100644 index 0000000..a1e6eab --- /dev/null +++ b/src/modules/sequelize-supa.ts @@ -0,0 +1,26 @@ +import { useConfig } from '@abearxiong/use-config'; +import { Sequelize } from 'sequelize'; + +type PostgresConfig = { + supabaseSQL: { + username: string; + password: string; + host: string; + port: number; + database: string; + }; +}; +const config = useConfig(); + +const postgresConfig = config.supabaseSQL; + +if (!postgresConfig) { + console.error('postgres config is required'); + process.exit(1); +} +// connect to db +export const sequelize = new Sequelize({ + dialect: 'postgres', + ...postgresConfig, + // logging: false, +}); diff --git a/src/routes/app-manager/list.ts b/src/routes/app-manager/list.ts index 080864b..126070a 100644 --- a/src/routes/app-manager/list.ts +++ b/src/routes/app-manager/list.ts @@ -140,44 +140,49 @@ app middleware: ['auth'], }) .define(async (ctx) => { - const tokenUser = ctx.state.tokenUser; - const { appKey, files, version } = ctx.query.data; - if (!appKey) { - throw new CustomError('appKey is required'); - } - if (!files || !files.length) { - throw new CustomError('files is required'); - } - let am = await AppModel.findOne({ where: { key: appKey, uid: tokenUser.id } }); - if (!am) { - am = await AppModel.create({ - user: tokenUser.username, - key: appKey, - uid: tokenUser.id, - version: '0.0.0', - title: appKey, - data: { - files: [], - }, - }); - } - let app = await AppListModel.findOne({ where: { version: version, key: appKey, uid: tokenUser.id } }); - if (!app) { - // throw new CustomError('app not found'); - app = await AppListModel.create({ - key: appKey, - version, - uid: tokenUser.id, - data: { - files: [], - }, - }); - } - const dataFiles = app.data.files || []; - const newFiles = _.uniqBy([...dataFiles, ...files], 'name'); - const res = await app.update({ data: { ...app.data, files: newFiles } }); + try { + const tokenUser = ctx.state.tokenUser; + const { appKey, files, version } = ctx.query.data; + if (!appKey) { + throw new CustomError('appKey is required'); + } + if (!files || !files.length) { + throw new CustomError('files is required'); + } + let am = await AppModel.findOne({ where: { key: appKey, uid: tokenUser.id } }); + if (!am) { + am = await AppModel.create({ + user: tokenUser.username, + key: appKey, + uid: tokenUser.id, + version: '0.0.0', + title: appKey, + data: { + files: [], + }, + }); + } + let app = await AppListModel.findOne({ where: { version: version, key: appKey, uid: tokenUser.id } }); + if (!app) { + // throw new CustomError('app not found'); + app = await AppListModel.create({ + key: appKey, + version, + uid: tokenUser.id, + data: { + files: [], + }, + }); + } + const dataFiles = app.data.files || []; + const newFiles = _.uniqBy([...dataFiles, ...files], 'name'); + const res = await app.update({ data: { ...app.data, files: newFiles } }); - ctx.body = prefixFix(res, tokenUser.username); + ctx.body = prefixFix(res, tokenUser.username); + } catch (e) { + console.log('update error', e); + throw new CustomError(e.message); + } }) .addTo(app); diff --git a/src/routes/snippet/index.ts b/src/routes/snippet/index.ts new file mode 100644 index 0000000..9166f9d --- /dev/null +++ b/src/routes/snippet/index.ts @@ -0,0 +1 @@ +import './list.ts' \ No newline at end of file diff --git a/src/routes/snippet/list.ts b/src/routes/snippet/list.ts new file mode 100644 index 0000000..debbd30 --- /dev/null +++ b/src/routes/snippet/list.ts @@ -0,0 +1,13 @@ +import { Snippet } from '@/models-supa/snippet.ts'; +import { app } from '@/app.ts'; + +app + .route({ + path: 'snippet', + key: 'list', + middleware: ['auth'], + }) + .define(async (ctx) => { + // 获取所有的snippet + }) + .addTo(app); diff --git a/src/scripts/sp-snippet.ts b/src/scripts/sp-snippet.ts new file mode 100644 index 0000000..a09a285 --- /dev/null +++ b/src/scripts/sp-snippet.ts @@ -0,0 +1,21 @@ +import { Snippet } from '@/models-supa/snippet.ts'; + +const main = async () => { + const snippet = await Snippet.findAndCountAll(); + + console.log(snippet.count); +}; + +// main(); + +const addOne = async () => { + const snippet = await Snippet.create({ + title: 'Hello', + description: 'Hello World', + snippet: 'console.log("Hello")', + keyword: '!hello', + user_id: '3f82e3ae-b7c2-4244-849f-d453f304b2f2', + }); + console.log(snippet); +}; +// await addOne();