core: emit types for callable model operation

This commit is contained in:
undefined committed 2021-03-15 02:05:22 +08:00
1 parent 2fe5d37c03
commit 599c1f7c18
29 files changed
+329 -354

No files matched your search

+92 -104
View File
@@ -1,117 +1,105 @@
import { FilterQuery } from 'mongodb';
import { ArgMethod } from '../utils';
import { TokenDoc } from '../interface';
import db from '../service/db';
import * as bus from '../service/bus';
export const coll = db.collection('token');
class TokenModel {
static coll = db.collection('token');
static TYPE_SESSION = 0;
static TYPE_REGISTRATION = 2;
static TYPE_CHANGEMAIL = 3;
static TYPE_OAUTH = 4;
static TYPE_LOSTPASS = 5;
static TYPE_EXPORT = 6;
static TYPE_IMPORT = 7;
export const TYPE_SESSION = 0;
export const TYPE_REGISTRATION = 2;
export const TYPE_CHANGEMAIL = 3;
export const TYPE_OAUTH = 4;
export const TYPE_LOSTPASS = 5;
export const TYPE_EXPORT = 6;
export const TYPE_IMPORT = 7;
static async add(
tokenType: number, expireSeconds: number, data: any, id = String.random(32),
): Promise<[string, TokenDoc]> {
const now = new Date();
const res = await TokenModel.coll.insertOne({
...data,
_id: id,
tokenType,
createAt: now,
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
});
return [id, res.ops[0]];
}
@ArgMethod
static async get(tokenId: string, tokenType: number): Promise<TokenDoc | null> {
return await TokenModel.coll.findOne({ _id: tokenId, tokenType });
}
static getMulti(tokenType: number, query: FilterQuery<TokenDoc> = {}) {
return TokenModel.coll.find({ tokenType, ...query });
}
static async update(
tokenId: string, tokenType: number, expireSeconds: number,
data: object,
) {
const now = new Date();
const res = await TokenModel.coll.findOneAndUpdate(
{ _id: tokenId, tokenType },
{
$set: {
...data,
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
tokenType,
},
},
{ returnOriginal: false },
);
return res.value;
}
@ArgMethod
static async del(tokenId: string, tokenType: number) {
const result = await TokenModel.coll.deleteOne({ _id: tokenId, tokenType });
return !!result.deletedCount;
}
static async createOrUpdate(
tokenType: number, expireSeconds: number, data: any,
): Promise<string> {
const d = await TokenModel.coll.findOne({ tokenType, ...data });
if (!d) {
const res = await TokenModel.add(tokenType, expireSeconds, data);
return res[0];
}
await TokenModel.update(d._id, tokenType, expireSeconds, data);
return d._id;
}
@ArgMethod
static getSessionListByUid(uid: number) {
return TokenModel.coll.find({ uid, tokenType: TokenModel.TYPE_SESSION }).sort('updateAt', -1).toArray();
}
@ArgMethod
static async getMostRecentSessionByUid(uid: number) {
const res = await TokenModel.coll.find({ uid, tokenType: TokenModel.TYPE_SESSION }).sort('updateAt', -1).toArray();
return res[0];
}
@ArgMethod
static delByUid(uid: number) {
return TokenModel.coll.deleteMany({ uid });
}
}
function ensureIndexes() {
return Promise.all([
coll.createIndex({ uid: 1, tokenType: 1, updateAt: -1 }, { sparse: true }),
coll.createIndex('expireAt', { expireAfterSeconds: 0 }),
TokenModel.coll.createIndex({ uid: 1, tokenType: 1, updateAt: -1 }, { sparse: true }),
TokenModel.coll.createIndex('expireAt', { expireAfterSeconds: 0 }),
]);
}
export async function add(
tokenType: number, expireSeconds: number, data: any, id = String.random(32),
): Promise<[string, TokenDoc]> {
const now = new Date();
const res = await coll.insertOne({
...data,
_id: id,
tokenType,
createAt: now,
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
});
return [id, res.ops[0]];
}
export async function get(tokenId: string, tokenType: number): Promise<TokenDoc | null> {
return await coll.findOne({ _id: tokenId, tokenType });
}
export function getMulti(tokenType: number, query: FilterQuery<TokenDoc> = {}) {
return coll.find({ tokenType, ...query });
}
export async function update(
tokenId: string, tokenType: number, expireSeconds: number,
data: object,
) {
const now = new Date();
const res = await coll.findOneAndUpdate(
{ _id: tokenId, tokenType },
{
$set: {
...data,
updateAt: now,
expireAt: new Date(now.getTime() + expireSeconds * 1000),
tokenType,
},
},
{ returnOriginal: false },
);
return res.value;
}
export async function del(tokenId: string, tokenType: number) {
const result = await coll.deleteOne({ _id: tokenId, tokenType });
return !!result.deletedCount;
}
export async function createOrUpdate(
tokenType: number, expireSeconds: number, data: any,
): Promise<string> {
const d = await coll.findOne({ tokenType, ...data });
if (!d) {
const res = await add(tokenType, expireSeconds, data);
return res[0];
}
await update(d._id, tokenType, expireSeconds, data);
return d._id;
}
export function getSessionListByUid(uid: number) {
return coll.find({ uid, tokenType: TYPE_SESSION }).sort('updateAt', -1).toArray();
}
export async function getMostRecentSessionByUid(uid: number) {
const res = await coll.find({ uid, tokenType: TYPE_SESSION }).sort('updateAt', -1).toArray();
return res[0];
}
export function delByUid(uid: number) {
return coll.deleteMany({ uid });
}
bus.once('app/started', ensureIndexes);
global.Hydro.model.token = {
coll,
TYPE_SESSION,
TYPE_CHANGEMAIL,
TYPE_OAUTH,
TYPE_REGISTRATION,
TYPE_LOSTPASS,
TYPE_EXPORT,
TYPE_IMPORT,
add,
createOrUpdate,
get,
getMulti,
update,
del,
delByUid,
getMostRecentSessionByUid,
getSessionListByUid,
};
export = TokenModel;
global.Hydro.model.token = TokenModel;