feat: add snippet and test for supa db
This commit is contained in:
parent
089f629096
commit
0eae9458c6
@ -1 +1 @@
|
||||
Subproject commit 42e32adf869afcaaff13a3f283a590741611558d
|
||||
Subproject commit 73118f845456d18a22dc652fbf240d4b955c4fc5
|
54
src/models-supa/snippet.ts
Normal file
54
src/models-supa/snippet.ts
Normal file
@ -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);
|
||||
// });
|
@ -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,
|
||||
|
26
src/modules/sequelize-supa.ts
Normal file
26
src/modules/sequelize-supa.ts
Normal file
@ -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<PostgresConfig>();
|
||||
|
||||
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,
|
||||
});
|
@ -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);
|
||||
|
||||
|
1
src/routes/snippet/index.ts
Normal file
1
src/routes/snippet/index.ts
Normal file
@ -0,0 +1 @@
|
||||
import './list.ts'
|
13
src/routes/snippet/list.ts
Normal file
13
src/routes/snippet/list.ts
Normal file
@ -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);
|
21
src/scripts/sp-snippet.ts
Normal file
21
src/scripts/sp-snippet.ts
Normal file
@ -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();
|
Loading…
x
Reference in New Issue
Block a user