update interface.ts

This commit is contained in:
undefined committed 2020-07-14 17:17:49 +08:00
1 parent 10956f1fee
commit d4e849a133
8 files changed
+99 -71

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
@requireCsrfToken @requireCsrfToken
消息提醒 为model.system添加缓存
bug修复 bug修复
使用BigInt管理权限 使用BigInt管理权限
修复discussion前端权限节点显示异常 修复discussion前端权限节点显示异常
+41 -20
View File
@@ -1,13 +1,12 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import { ObjectID, GridFSBucket } from 'mongodb'; import { ObjectID, GridFSBucket } from 'mongodb';
import fs from 'fs'; import fs from 'fs';
import { Dictionary, NumericDictionary } from 'lodash';
export type Dict<T> = { [key: string]: T };
export interface Setting { export interface Setting {
family: string, family: string,
key: string, key: string,
range: Array<[string, string]> | Dict<string>, range: Array<[string, string]> | Dictionary<string>,
value: any, value: any,
type: string, type: string,
name: string, name: string,
@@ -15,7 +14,7 @@ export interface Setting {
flag: number, flag: number,
} }
export interface Udoc { export interface Udoc extends Dictionary<any> {
udoc: () => any, udoc: () => any,
dudoc: () => any, dudoc: () => any,
_id: number, _id: number,
@@ -34,12 +33,9 @@ export interface Udoc {
hasPerm: (perm: string) => boolean, hasPerm: (perm: string) => boolean,
hasPriv: (priv: number) => boolean, hasPriv: (priv: number) => boolean,
checkPassword: (password: string) => void, checkPassword: (password: string) => void,
[key: string]: any,
} }
export interface Udict { export type Udict = NumericDictionary<Udoc>;
[key: number]: Udoc,
}
export interface Pdoc { export interface Pdoc {
_id: ObjectID, _id: ObjectID,
@@ -59,9 +55,7 @@ export interface Pdoc {
config: string, config: string,
} }
export interface Pdict { export type Pdict = Dictionary<Pdoc>;
[key: string]: Pdoc,
}
export interface TestCase { export interface TestCase {
time: number, time: number,
@@ -102,9 +96,7 @@ export interface ScoreboardNode {
raw?: any, raw?: any,
} }
export interface PenaltyRules { export type PenaltyRules = Dictionary<number>;
[key: string]: number,
}
export interface Tdoc { export interface Tdoc {
_id: ObjectID, _id: ObjectID,
@@ -128,9 +120,40 @@ export interface Tdoc {
dag: any dag: any
} }
interface ContestStat { export interface DomainDoc extends Dictionary<any> {
_id: string,
owner: number,
roles: Dictionary<string>,
gravatar: string,
bulletin: string,
}
// Message
export interface Mdoc {
_id: ObjectID,
from: number,
to: number,
content: string,
unread: boolean,
}
// Userfile
export interface Ufdoc {
_id: ObjectID,
secret: string,
md5: string,
owner: number,
size: number,
}
// Blacklist
export interface Bdoc {
_id: string, // ip
expireAt: Date,
}
interface ContestStat extends Dictionary<any> {
detail: any, detail: any,
[key: string]: any,
} }
export interface ContestRule { export interface ContestRule {
@@ -147,9 +170,7 @@ export interface ContestRule {
rank: (tsdocs: any[]) => any[] | Generator<any>, rank: (tsdocs: any[]) => any[] | Generator<any>,
} }
export interface ContestRules { export type ContestRules = Dictionary<ContestRule>;
[key: string]: ContestRule,
}
export type ProblemImporter = (url: string, handler: any) => export type ProblemImporter = (url: string, handler: any) =>
Promise<[Pdoc, fs.ReadStream?]> | [Pdoc, fs.ReadStream?]; Promise<[Pdoc, fs.ReadStream?]> | [Pdoc, fs.ReadStream?];
@@ -224,7 +245,7 @@ declare global {
template: { [key: string]: string }, template: { [key: string]: string },
ui: any, ui: any,
error: typeof import('./error'), error: typeof import('./error'),
locales: { [id: string]: { [key: string]: string } }, locales: Dict<Dict<string>>,
postInit: Function[], postInit: Function[],
}, },
nodeModules: any, nodeModules: any,
+9 -3
View File
@@ -1,13 +1,19 @@
import * as db from '../service/db'; import * as db from '../service/db';
import { Bdoc } from '../interface';
const coll = db.collection('blacklist'); const coll = db.collection('blacklist');
export async function add(ip: string) { export async function add(ip: string): Promise<Bdoc> {
const expireAt = new Date(new Date().getTime() + 365 * 24 * 60 * 60 * 1000); const expireAt = new Date(new Date().getTime() + 365 * 24 * 60 * 60 * 1000);
return coll.findOneAndUpdate({ _id: ip }, { $set: { expireAt } }, { upsert: true }); const res = await coll.findOneAndUpdate(
{ _id: ip },
{ $set: { expireAt } },
{ upsert: true, returnOriginal: false },
);
return res.value;
} }
export function get(ip: string) { export function get(ip: string): Promise<Bdoc> {
return coll.findOne({ _id: ip }); return coll.findOne({ _id: ip });
} }
+6 -5
View File
@@ -1,5 +1,6 @@
import { Dictionary } from 'lodash';
import { BUILTIN_ROLES, PRIV } from './builtin'; import { BUILTIN_ROLES, PRIV } from './builtin';
import { Udoc } from '../interface'; import { Udoc, DomainDoc } from '../interface';
import * as db from '../service/db'; import * as db from '../service/db';
const coll = db.collection('domain'); const coll = db.collection('domain');
@@ -12,11 +13,11 @@ export async function add(domainId: string, owner: number, name: string, bulleti
return domainId; return domainId;
} }
export function get(domainId: string) { export function get(domainId: string): Promise<DomainDoc> {
return coll.findOne({ _id: domainId }); return coll.findOne({ _id: domainId });
} }
export function getMany(query: any, sort: any, page: number, limit: number) { export function getMany(query: any, sort: any, page: number, limit: number): Promise<DomainDoc[]> {
return coll.find(query).sort(sort).skip((page - 1) * limit).limit(limit) return coll.find(query).sort(sort).skip((page - 1) * limit).limit(limit)
.toArray(); .toArray();
} }
@@ -29,7 +30,7 @@ export function edit(domainId: string, $set: any) {
return coll.updateOne({ _id: domainId }, { $set }); return coll.updateOne({ _id: domainId }, { $set });
} }
export async function inc(domainId: string, field: string, n: number) { export async function inc(domainId: string, field: string, n: number): Promise<DomainDoc | null> {
const res = await coll.findOneAndUpdate( const res = await coll.findOneAndUpdate(
{ _id: domainId }, { _id: domainId },
{ $inc: { [field]: n } }, { $inc: { [field]: n } },
@@ -38,7 +39,7 @@ export async function inc(domainId: string, field: string, n: number) {
return res.value; return res.value;
} }
export async function getList(domainIds: string[]) { export async function getList(domainIds: string[]): Promise<Dictionary<DomainDoc>> {
const r = {}; const r = {};
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
for (const domainId of domainIds) r[domainId] = await get(domainId); for (const domainId of domainIds) r[domainId] = await get(domainId);
+14 -6
View File
@@ -1,9 +1,11 @@
import { ObjectID } from 'mongodb'; import { ObjectID } from 'mongodb';
import * as fs from 'fs'; import * as fs from 'fs';
import { Dictionary } from 'lodash';
import { ForbiddenError, NotFoundError } from '../error'; import { ForbiddenError, NotFoundError } from '../error';
import * as db from '../service/db'; import * as db from '../service/db';
import gridfs from '../service/gridfs'; import gridfs from '../service/gridfs';
import hash from '../lib/hash.hydro'; import hash from '../lib/hash.hydro';
import { Ufdoc } from '../interface';
const coll = db.collection('file'); const coll = db.collection('file');
const collFile = db.collection('fs.files'); const collFile = db.collection('fs.files');
@@ -22,7 +24,12 @@ export async function add(
else stream = streamOrPath; else stream = streamOrPath;
const w = gridfs.openUploadStream(filename); const w = gridfs.openUploadStream(filename);
await coll.insertOne({ await coll.insertOne({
...meta, _id: w.id, secret: String.random(32), owner, filename, ...meta,
_id: w.id,
secret: String.random(32),
owner,
filename,
count: 1,
}); });
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
w.on('error', reject); w.on('error', reject);
@@ -42,21 +49,22 @@ export function del(_id: ObjectID) {
]); ]);
} }
export async function inc(_id: ObjectID) { export async function inc(_id: ObjectID): Promise<number> {
const doc = await coll.findOneAndUpdate( const doc = await coll.findOneAndUpdate(
{ _id }, { _id },
{ $inc: { count: 1 } }, { $inc: { count: 1 } },
{ returnOriginal: false }, { returnOriginal: false },
); );
return (doc.value || {}).count; return doc.value?.count;
} }
export async function dec(_id: ObjectID) { export async function dec(_id: ObjectID): Promise<number> {
const file = await coll.findOneAndUpdate( const file = await coll.findOneAndUpdate(
{ _id }, { _id },
{ $inc: { count: -1 } }, { $inc: { count: -1 } },
{ returnOriginal: false }, { returnOriginal: false },
); );
if (!file.value) return 0;
if (!file.value.count) await del(_id); if (!file.value.count) await del(_id);
return file.value.count; return file.value.count;
} }
@@ -79,11 +87,11 @@ export async function get(_id: ObjectID) {
return gridfs.openDownloadStream(_id); return gridfs.openDownloadStream(_id);
} }
export function getMeta(_id: ObjectID) { export function getMeta(_id: ObjectID): Promise<Ufdoc> {
return coll.findOne({ _id }); return coll.findOne({ _id });
} }
export async function getMetaDict(ufids: ObjectID[]) { export async function getMetaDict(ufids: ObjectID[]): Promise<Dictionary<Ufdoc>> {
const r = {}; const r = {};
ufids = Array.from(new Set(ufids)); ufids = Array.from(new Set(ufids));
const ufdocs = await coll.find({ _id: { $in: ufids } }).toArray(); const ufdocs = await coll.find({ _id: { $in: ufids } }).toArray();
+12 -14
View File
@@ -1,10 +1,10 @@
import { ObjectID, QuerySelector } from 'mongodb'; import { ObjectID } from 'mongodb';
import { MessageNotFoundError } from '../error'; import { Mdoc } from '../interface';
import * as db from '../service/db'; import * as db from '../service/db';
const coll = db.collection('message'); const coll = db.collection('message');
export async function send(from: number, to: number, content: string) { export async function send(from: number, to: number, content: string): Promise<Mdoc> {
const res = await coll.insertOne({ const res = await coll.insertOne({
from, to, content, unread: true, from, to, content, unread: true,
}); });
@@ -13,27 +13,25 @@ export async function send(from: number, to: number, content: string) {
}; };
} }
export async function get(_id: ObjectID) { export async function get(_id: ObjectID): Promise<Mdoc> {
const doc = await coll.findOne({ _id }); return await coll.findOne({ _id });
if (!doc) throw new MessageNotFoundError(_id);
return doc;
} }
export function getByUser(uid: number) { export async function getByUser(uid: number): Promise<Mdoc[]> {
return coll.find({ $or: [{ from: uid }, { to: uid }] }).sort('_id', 1).toArray(); return await coll.find({ $or: [{ from: uid }, { to: uid }] }).sort('_id', 1).toArray();
} }
export function getMany<T>(query: QuerySelector<T>, sort, page: number, limit: number) { export async function getMany(query: any, sort: any, page: number, limit: number): Promise<Mdoc[]> {
return coll.find(query).sort(sort) return await coll.find(query).sort(sort)
.skip((page - 1) * limit).limit(limit) .skip((page - 1) * limit).limit(limit)
.toArray(); .toArray();
} }
export function del(_id: ObjectID) { export async function del(_id: ObjectID) {
return coll.deleteOne({ _id }); return await coll.deleteOne({ _id });
} }
export function count<T>(query: QuerySelector<T>) { export function count(query: any) {
return coll.find(query).count(); return coll.find(query).count();
} }
+14 -21
View File
@@ -1,9 +1,10 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { Dictionary } from 'lodash';
import * as builtin from './builtin'; import * as builtin from './builtin';
import { Setting as _Setting, Dict } from '../interface'; import { Setting as _Setting } from '../interface';
type SettingDict = Dict<_Setting>; type SettingDict = Dictionary<_Setting>;
const countries = moment.tz.countries(); const countries = moment.tz.countries();
const tzs: Set<string> = new Set(); const tzs: Set<string> = new Set();
@@ -11,8 +12,8 @@ for (const country of countries) {
const tz = moment.tz.zonesForCountry(country); const tz = moment.tz.zonesForCountry(country);
for (const t of tz) tzs.add(t); for (const t of tz) tzs.add(t);
} }
const timezones = Array.from(tzs).sort().map((tz) => [tz, tz]); const timezones = Array.from(tzs).sort().map((tz) => [tz, tz]) as [string, string][];
const langRange: Dict<string> = {}; const langRange: Dictionary<string> = {};
for (const lang in global.Hydro.locales) { for (const lang in global.Hydro.locales) {
langRange[lang] = global.Hydro.locales[lang].__langname; langRange[lang] = global.Hydro.locales[lang].__langname;
@@ -34,7 +35,7 @@ export const DOMAIN_SETTINGS_BY_KEY: SettingDict = {};
export const SYSTEM_SETTINGS_BY_KEY: SettingDict = {}; export const SYSTEM_SETTINGS_BY_KEY: SettingDict = {};
export const Setting = ( export const Setting = (
family: string, key: string, range: Array<[string, string]> | Dict<string> = null, family: string, key: string, range: Array<[string, string]> | Dictionary<string> = null,
value: any = null, type = 'text', name = '', value: any = null, type = 'text', name = '',
desc = '', flag = 0, desc = '', flag = 0,
): _Setting => ({ ): _Setting => ({
@@ -75,27 +76,19 @@ export const SystemSetting = (...settings: _Setting[]) => {
}; };
PreferenceSetting( PreferenceSetting(
Setting('setting_display', 'viewLang', langRange, Setting('setting_display', 'viewLang', langRange, 'zh_CN', 'select', 'UI Language'),
'zh_CN', 'select', 'UI Language'), Setting('setting_display', 'timeZone', timezones, 'Asia/Shanghai', 'select', 'Timezone'),
Setting('setting_display', 'timeZone', timezones as [string, string][], Setting('setting_usage', 'codeLang', builtin.LANG_TEXTS, null, 'select', 'Default Code Language'),
'Asia/Shanghai', 'select', 'Timezone'), Setting('setting_usage', 'codeTemplate', null, null, 'textarea', 'Default Code Template',
Setting('setting_usage', 'codeLang', builtin.LANG_TEXTS,
null, 'select', 'Default Code Language'),
Setting('setting_usage', 'codeTemplate', null,
null, 'textarea', 'Default Code Template',
'If left blank, the built-in template of the corresponding language will be used.'), 'If left blank, the built-in template of the corresponding language will be used.'),
); );
AccountSetting( AccountSetting(
Setting('setting_info', 'gravatar', null, Setting('setting_info', 'gravatar', null, null, 'text', 'Gravatar Email',
null, 'text', 'Gravatar Email',
'We use <a href="https://en.gravatar.com/" target="_blank">Gravatar</a> to present your avatar icon.'), 'We use <a href="https://en.gravatar.com/" target="_blank">Gravatar</a> to present your avatar icon.'),
Setting('setting_info', 'qq', null, Setting('setting_info', 'qq', null, null, 'text', 'QQ'),
null, 'text', 'QQ'), Setting('setting_info', 'gender', builtin.USER_GENDER_RANGE, null, 'select', 'Gender'),
Setting('setting_info', 'gender', builtin.USER_GENDER_RANGE, Setting('setting_info', 'bio', null, null, 'markdown', 'Bio'),
null, 'select', 'Gender'),
Setting('setting_info', 'bio', null,
null, 'markdown', 'Bio'),
Setting('setting_customize', 'backgroundImage', null, Setting('setting_customize', 'backgroundImage', null,
'/components/profile/backgrounds/1.jpg', 'text', 'Profile Background Image', '/components/profile/backgrounds/1.jpg', 'text', 'Profile Background Image',
'Choose the background image in your profile page.'), 'Choose the background image in your profile page.'),
+2 -1
View File
@@ -1,4 +1,5 @@
import { FindOneAndUpdateOption } from 'mongodb'; import { FindOneAndUpdateOption } from 'mongodb';
import { Dictionary } from 'lodash';
import * as db from '../service/db'; import * as db from '../service/db';
const coll = db.collection('system'); const coll = db.collection('system');
@@ -9,7 +10,7 @@ export async function get(_id: string) {
return null; return null;
} }
export async function getMany(keys: string[]) { export async function getMany(keys: string[]): Promise<Dictionary<any>> {
const docs = await coll.find({ _id: { $in: keys } }).toArray(); const docs = await coll.find({ _id: { $in: keys } }).toArray();
const dict = {}; const dict = {};
const res = []; const res = [];