mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: use serviceInstance for system model
This commit is contained in:
30 files changed
+143
-104
No files matched your search
@@ -4,6 +4,7 @@ import cac from 'cac';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
import { Context } from '../context';
|
import { Context } from '../context';
|
||||||
|
import SystemModel from '../model/system';
|
||||||
import { load as loadOptions } from '../options';
|
import { load as loadOptions } from '../options';
|
||||||
import { MongoService } from '../service/db';
|
import { MongoService } from '../service/db';
|
||||||
import { SettingService } from '../settings';
|
import { SettingService } from '../settings';
|
||||||
@@ -111,9 +112,9 @@ export async function load(ctx: Context) {
|
|||||||
const fail = [];
|
const fail = [];
|
||||||
await ctx.plugin(MongoService, loadOptions() || {});
|
await ctx.plugin(MongoService, loadOptions() || {});
|
||||||
await ctx.plugin(SettingService);
|
await ctx.plugin(SettingService);
|
||||||
await require('../model/system').runConfig();
|
await ctx.plugin(SystemModel.Service);
|
||||||
ctx = await new Promise((resolve) => {
|
ctx = await new Promise((resolve) => {
|
||||||
ctx.inject(['loader', 'setting', 'db'], (c) => {
|
ctx.inject(['loader', 'setting', 'db', 'model:system'], (c) => {
|
||||||
resolve(c);
|
resolve(c);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ export async function builtinModel(ctx: Context) {
|
|||||||
for (const t of models.filter((i) => i.endsWith('.ts'))) {
|
for (const t of models.filter((i) => i.endsWith('.ts'))) {
|
||||||
const q = path.resolve(modelDir, t);
|
const q = path.resolve(modelDir, t);
|
||||||
const module = require(q);
|
const module = require(q);
|
||||||
if ('apply' in module || isClass(unwrapExports(module))) ctx.loader.reloadPlugin(q, '');
|
if ('apply' in module) ctx.loader.reloadPlugin(q, '');
|
||||||
|
const exports = unwrapExports(module);
|
||||||
|
if (isClass(exports) && !(Symbol.for('hydro.initialize') in exports)) ctx.loader.reloadPlugin(q, '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import cac from 'cac';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { Context } from '../context';
|
import { Context } from '../context';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
|
import SystemModel from '../model/system';
|
||||||
import { load } from '../options';
|
import { load } from '../options';
|
||||||
import { MongoService } from '../service/db';
|
import { MongoService } from '../service/db';
|
||||||
import { SettingService } from '../settings';
|
import { SettingService } from '../settings';
|
||||||
@@ -30,10 +31,9 @@ export async function apply(ctx: Context) {
|
|||||||
await locale(pending, fail);
|
await locale(pending, fail);
|
||||||
await ctx.plugin(MongoService, load() || {});
|
await ctx.plugin(MongoService, load() || {});
|
||||||
await ctx.plugin(SettingService);
|
await ctx.plugin(SettingService);
|
||||||
const modelSystem = require('../model/system');
|
await ctx.plugin(SystemModel.Service);
|
||||||
await modelSystem.runConfig();
|
|
||||||
ctx = await new Promise((resolve) => {
|
ctx = await new Promise((resolve) => {
|
||||||
ctx.inject(['loader', 'setting', 'db'], (c) => {
|
ctx.inject(['loader', 'setting', 'db', 'model:system'], (c) => {
|
||||||
resolve(c);
|
resolve(c);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Context } from '../context';
|
import { Context } from '../context';
|
||||||
import { ForbiddenError } from '../error';
|
import { ForbiddenError } from '../error';
|
||||||
import * as SystemModel from '../model/system';
|
import SystemModel from '../model/system';
|
||||||
import TokenModel from '../model/token';
|
import TokenModel from '../model/token';
|
||||||
import UserModel from '../model/user';
|
import UserModel from '../model/user';
|
||||||
import { ConnectionHandler } from '../service/server';
|
import { ConnectionHandler } from '../service/server';
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import domain from '../model/domain';
|
|||||||
import MessageModel from '../model/message';
|
import MessageModel from '../model/message';
|
||||||
import * as oplog from '../model/oplog';
|
import * as oplog from '../model/oplog';
|
||||||
import { DOMAIN_SETTINGS, DOMAIN_SETTINGS_BY_KEY } from '../model/setting';
|
import { DOMAIN_SETTINGS, DOMAIN_SETTINGS_BY_KEY } from '../model/setting';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import {
|
import {
|
||||||
Handler, Mutation, param, post, Query, query, requireSudo, Types,
|
Handler, Mutation, param, post, Query, query, requireSudo, Types,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import message from '../model/message';
|
|||||||
import ProblemModel from '../model/problem';
|
import ProblemModel from '../model/problem';
|
||||||
import * as setting from '../model/setting';
|
import * as setting from '../model/setting';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import token from '../model/token';
|
import token from '../model/token';
|
||||||
import * as training from '../model/training';
|
import * as training from '../model/training';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import * as discussion from '../model/discussion';
|
|||||||
import problem from '../model/problem';
|
import problem from '../model/problem';
|
||||||
import record from '../model/record';
|
import record from '../model/record';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import {
|
import {
|
||||||
Handler, param, post, Types,
|
Handler, param, post, Types,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import problem from '../model/problem';
|
|||||||
import record from '../model/record';
|
import record from '../model/record';
|
||||||
import * as setting from '../model/setting';
|
import * as setting from '../model/setting';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import task, { Consumer } from '../model/task';
|
import task, { Consumer } from '../model/task';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import bus from '../service/bus';
|
import bus from '../service/bus';
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { PRIV, STATUS } from '../model/builtin';
|
|||||||
import domain from '../model/domain';
|
import domain from '../model/domain';
|
||||||
import record from '../model/record';
|
import record from '../model/record';
|
||||||
import * as setting from '../model/setting';
|
import * as setting from '../model/setting';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import {
|
import {
|
||||||
ConnectionHandler, Handler, param, requireSudo, Types,
|
ConnectionHandler, Handler, param, requireSudo, Types,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
import { PRIV } from '../model/builtin';
|
import { PRIV } from '../model/builtin';
|
||||||
import * as oplog from '../model/oplog';
|
import * as oplog from '../model/oplog';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import user, { User } from '../model/user';
|
import user, { User } from '../model/user';
|
||||||
import {
|
import {
|
||||||
Handler, param, post, requireSudo, Types,
|
Handler, param, post, requireSudo, Types,
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import record from '../model/record';
|
|||||||
import * as setting from '../model/setting';
|
import * as setting from '../model/setting';
|
||||||
import solution from '../model/solution';
|
import solution from '../model/solution';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import {
|
import {
|
||||||
Handler, param, post, Query, query, route, Types,
|
Handler, param, post, Query, query, route, Types,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import problem, { ProblemDoc } from '../model/problem';
|
|||||||
import record from '../model/record';
|
import record from '../model/record';
|
||||||
import { langs } from '../model/setting';
|
import { langs } from '../model/setting';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import TaskModel from '../model/task';
|
import TaskModel from '../model/task';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { PERM, PRIV, STATUS } from '../model/builtin';
|
|||||||
import * as oplog from '../model/oplog';
|
import * as oplog from '../model/oplog';
|
||||||
import problem from '../model/problem';
|
import problem from '../model/problem';
|
||||||
import storage from '../model/storage';
|
import storage from '../model/storage';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import * as training from '../model/training';
|
import * as training from '../model/training';
|
||||||
import user from '../model/user';
|
import user from '../model/user';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import * as oplog from '../model/oplog';
|
|||||||
import problem, { ProblemDoc } from '../model/problem';
|
import problem, { ProblemDoc } from '../model/problem';
|
||||||
import ScheduleModel from '../model/schedule';
|
import ScheduleModel from '../model/schedule';
|
||||||
import SolutionModel from '../model/solution';
|
import SolutionModel from '../model/solution';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import token from '../model/token';
|
import token from '../model/token';
|
||||||
import user, { deleteUserCache } from '../model/user';
|
import user, { deleteUserCache } from '../model/user';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -588,7 +588,7 @@ export interface Model {
|
|||||||
record: typeof import('./model/record').default;
|
record: typeof import('./model/record').default;
|
||||||
setting: typeof import('./model/setting');
|
setting: typeof import('./model/setting');
|
||||||
solution: typeof import('./model/solution').default;
|
solution: typeof import('./model/solution').default;
|
||||||
system: typeof import('./model/system');
|
system: typeof import('./model/system').default;
|
||||||
task: typeof import('./model/task').default;
|
task: typeof import('./model/task').default;
|
||||||
schedule: typeof import('./model/schedule').default;
|
schedule: typeof import('./model/schedule').default;
|
||||||
oplog: typeof import('./model/oplog');
|
oplog: typeof import('./model/oplog');
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import bus from '../service/bus';
|
|||||||
import db from '../service/db';
|
import db from '../service/db';
|
||||||
import { ArgMethod } from '../utils';
|
import { ArgMethod } from '../utils';
|
||||||
import { PRIV } from './builtin';
|
import { PRIV } from './builtin';
|
||||||
import * as system from './system';
|
import system from './system';
|
||||||
import user from './user';
|
import user from './user';
|
||||||
|
|
||||||
class MessageModel {
|
class MessageModel {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import DomainModel from './domain';
|
|||||||
import RecordModel from './record';
|
import RecordModel from './record';
|
||||||
import SolutionModel from './solution';
|
import SolutionModel from './solution';
|
||||||
import storage from './storage';
|
import storage from './storage';
|
||||||
import * as SystemModel from './system';
|
import SystemModel from './system';
|
||||||
|
|
||||||
export interface ProblemDoc extends Document { }
|
export interface ProblemDoc extends Document { }
|
||||||
export type Field = keyof ProblemDoc;
|
export type Field = keyof ProblemDoc;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { ArgMethod, buildProjection, Time } from '../utils';
|
|||||||
import { STATUS } from './builtin';
|
import { STATUS } from './builtin';
|
||||||
import DomainModel from './domain';
|
import DomainModel from './domain';
|
||||||
import problem from './problem';
|
import problem from './problem';
|
||||||
import * as SystemModel from './system';
|
import SystemModel from './system';
|
||||||
import task from './task';
|
import task from './task';
|
||||||
|
|
||||||
export default class RecordModel {
|
export default class RecordModel {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import mime from '../lib/mime';
|
|||||||
import db from '../service/db';
|
import db from '../service/db';
|
||||||
import storage from '../service/storage';
|
import storage from '../service/storage';
|
||||||
import ScheduleModel from './schedule';
|
import ScheduleModel from './schedule';
|
||||||
import * as system from './system';
|
import system from './system';
|
||||||
|
|
||||||
export class StorageModel {
|
export class StorageModel {
|
||||||
static coll = db.collection('storage');
|
static coll = db.collection('storage');
|
||||||
|
|||||||
@@ -1,81 +1,74 @@
|
|||||||
|
import { Context, Service } from '../context';
|
||||||
import { SystemKeys } from '../interface';
|
import { SystemKeys } from '../interface';
|
||||||
import bus from '../service/bus';
|
import { serviceInstance } from '../utils';
|
||||||
import db from '../service/db';
|
|
||||||
import { NumberKeys } from '../typeutils';
|
|
||||||
import { SYSTEM_SETTINGS } from './setting';
|
import { SYSTEM_SETTINGS } from './setting';
|
||||||
|
|
||||||
const coll = db.collection('system');
|
class SystemModelService extends Service {
|
||||||
const cache: Record<string, any> = Object.create(null);
|
static readonly inject = ['db'];
|
||||||
|
static readonly name = 'model:system';
|
||||||
|
|
||||||
export function get<K extends keyof SystemKeys>(key: K): SystemKeys[K];
|
coll = this.ctx.db.collection('system');
|
||||||
export function get(key: string): any;
|
cache: Record<string, any> = Object.create(null);
|
||||||
export function get(key: string): any {
|
|
||||||
return cache[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getMany<
|
constructor(ctx: Context) {
|
||||||
A extends keyof SystemKeys, B extends keyof SystemKeys,
|
super(ctx, 'model:system');
|
||||||
>(keys: [A, B]): [SystemKeys[A], SystemKeys[B]];
|
}
|
||||||
export function getMany<
|
|
||||||
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
get<K extends keyof SystemKeys>(key: K): SystemKeys[K];
|
||||||
>(keys: [A, B, C]): [SystemKeys[A], SystemKeys[B], SystemKeys[C]];
|
get(key: string): any;
|
||||||
export function getMany<
|
get(key: string): any {
|
||||||
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
return this.cache[key];
|
||||||
D extends keyof SystemKeys,
|
}
|
||||||
>(keys: [A, B, C, D]): [SystemKeys[A], SystemKeys[B], SystemKeys[C], SystemKeys[D]];
|
|
||||||
export function getMany<
|
getMany<
|
||||||
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
A extends keyof SystemKeys, B extends keyof SystemKeys,
|
||||||
D extends keyof SystemKeys, E extends keyof SystemKeys,
|
>(keys: [A, B]): [SystemKeys[A], SystemKeys[B]];
|
||||||
>(keys: [A, B, C, D, E]): [SystemKeys[A], SystemKeys[B], SystemKeys[C], SystemKeys[D], SystemKeys[E]];
|
getMany<
|
||||||
export function getMany<
|
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
||||||
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
>(keys: [A, B, C]): [SystemKeys[A], SystemKeys[B], SystemKeys[C]];
|
||||||
D extends keyof SystemKeys, E extends keyof SystemKeys, F extends keyof SystemKeys,
|
getMany<
|
||||||
>(keys: [A, B, C, D, E, F]): [SystemKeys[A], SystemKeys[B], SystemKeys[C], SystemKeys[D], SystemKeys[E], SystemKeys[F]];
|
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
||||||
export function getMany(keys: (keyof SystemKeys)[]): any[];
|
D extends keyof SystemKeys,
|
||||||
export function getMany(keys: string[]): any[] {
|
>(keys: [A, B, C, D]): [SystemKeys[A], SystemKeys[B], SystemKeys[C], SystemKeys[D]];
|
||||||
return keys.map((key) => cache[key]);
|
getMany<
|
||||||
}
|
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
||||||
|
D extends keyof SystemKeys, E extends keyof SystemKeys,
|
||||||
export async function set<K extends keyof SystemKeys>(_id: K, value: SystemKeys[K], broadcast?: boolean): Promise<SystemKeys[K]>;
|
>(keys: [A, B, C, D, E]): [SystemKeys[A], SystemKeys[B], SystemKeys[C], SystemKeys[D], SystemKeys[E]];
|
||||||
export async function set<K>(_id: string, value: K, broadcast?: boolean): Promise<K>;
|
getMany<
|
||||||
export async function set(_id: string, value: any, broadcast = true) {
|
A extends keyof SystemKeys, B extends keyof SystemKeys, C extends keyof SystemKeys,
|
||||||
if (broadcast) bus.broadcast('system/setting', { [_id]: value });
|
D extends keyof SystemKeys, E extends keyof SystemKeys, F extends keyof SystemKeys,
|
||||||
const res = await coll.findOneAndUpdate(
|
>(keys: [A, B, C, D, E, F]): [SystemKeys[A], SystemKeys[B], SystemKeys[C], SystemKeys[D], SystemKeys[E], SystemKeys[F]];
|
||||||
{ _id },
|
getMany(keys: (keyof SystemKeys)[]): any[];
|
||||||
{ $set: { value } },
|
getMany(keys: string[]): any[] {
|
||||||
{ upsert: true, returnDocument: 'after' },
|
return keys.map((key) => this.cache[key]);
|
||||||
);
|
}
|
||||||
cache[_id] = res.value;
|
|
||||||
return res.value;
|
async set<K extends keyof SystemKeys>(_id: K, value: SystemKeys[K], broadcast?: boolean): Promise<SystemKeys[K]>;
|
||||||
}
|
async set<K>(_id: string, value: K, broadcast?: boolean): Promise<K>;
|
||||||
|
async set(_id: string, value: any, broadcast = true) {
|
||||||
export async function inc<K extends NumberKeys<SystemKeys>>(_id: K) {
|
if (broadcast) this.ctx.broadcast('system/setting', { [_id]: value });
|
||||||
const res = await coll.findOneAndUpdate(
|
const res = await this.coll.findOneAndUpdate(
|
||||||
{ _id },
|
{ _id },
|
||||||
{ $inc: { value: 1 } as any },
|
{ $set: { value } },
|
||||||
{ upsert: true, returnDocument: 'after' },
|
{ upsert: true, returnDocument: 'after' },
|
||||||
);
|
);
|
||||||
cache[_id] = res.value;
|
this.cache[_id] = res.value;
|
||||||
return res.value;
|
return res.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runConfig() {
|
async [Service.init]() {
|
||||||
for (const setting of SYSTEM_SETTINGS) {
|
for (const setting of SYSTEM_SETTINGS) {
|
||||||
if (setting.value) cache[setting.key] = setting.value;
|
if (setting.value) this.cache[setting.key] = setting.value;
|
||||||
|
}
|
||||||
|
const config = await this.coll.find().toArray();
|
||||||
|
for (const i of config) this.cache[i._id] = i.value;
|
||||||
|
this.ctx.emit('database/config');
|
||||||
|
return this.ctx.on('system/setting', (args) => {
|
||||||
|
for (const key in args) this.cache[key] = args[key];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const config = await coll.find().toArray();
|
|
||||||
for (const i of config) cache[i._id] = i.value;
|
|
||||||
await bus.emit('database/config');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bus.on('system/setting', (args) => {
|
const SystemModel = serviceInstance(SystemModelService);
|
||||||
for (const key in args) cache[key] = args[key];
|
export default SystemModel;
|
||||||
});
|
global.Hydro.model.system = SystemModel;
|
||||||
|
|
||||||
global.Hydro.model.system = {
|
|
||||||
runConfig,
|
|
||||||
get,
|
|
||||||
getMany,
|
|
||||||
inc,
|
|
||||||
set,
|
|
||||||
};
|
|
||||||
@@ -16,7 +16,7 @@ import { ArgMethod, buildProjection, randomstring, sleep } from '../utils';
|
|||||||
import { PERM, PRIV } from './builtin';
|
import { PERM, PRIV } from './builtin';
|
||||||
import domain from './domain';
|
import domain from './domain';
|
||||||
import * as setting from './setting';
|
import * as setting from './setting';
|
||||||
import * as system from './system';
|
import system from './system';
|
||||||
import token from './token';
|
import token from './token';
|
||||||
|
|
||||||
export const coll: Collection<Udoc> = db.collection('user');
|
export const coll: Collection<Udoc> = db.collection('user');
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export * from './pipelineUtils';
|
|||||||
export * from './error';
|
export * from './error';
|
||||||
export * from './libs';
|
export * from './libs';
|
||||||
export * from './settings';
|
export * from './settings';
|
||||||
export * as SystemModel from './model/system';
|
export { default as SystemModel } from './model/system';
|
||||||
export * as TrainingModel from './model/training';
|
export * as TrainingModel from './model/training';
|
||||||
export * as OpcountModel from './model/opcount';
|
export * as OpcountModel from './model/opcount';
|
||||||
export * as OplogModel from './model/oplog';
|
export * as OplogModel from './model/oplog';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Schema from 'schemastery';
|
|||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import superagent from 'superagent';
|
import superagent from 'superagent';
|
||||||
import MessageModel from '../model/message';
|
import MessageModel from '../model/message';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
|
|
||||||
async function getRemoteVersion(id: string) {
|
async function getRemoteVersion(id: string) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DisposableList } from 'cordis';
|
|||||||
import inspector from 'inspector';
|
import inspector from 'inspector';
|
||||||
import { randomstring } from '@hydrooj/utils';
|
import { randomstring } from '@hydrooj/utils';
|
||||||
import { Context, Service } from '../context';
|
import { Context, Service } from '../context';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import db from './db';
|
import db from './db';
|
||||||
import storage from './storage';
|
import storage from './storage';
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { cloneDeep, omit } from 'lodash';
|
|||||||
import type { KoaContext } from '@hydrooj/framework';
|
import type { KoaContext } from '@hydrooj/framework';
|
||||||
import { randomPick, Time } from '@hydrooj/utils';
|
import { randomPick, Time } from '@hydrooj/utils';
|
||||||
import { PERM } from '../../model/builtin';
|
import { PERM } from '../../model/builtin';
|
||||||
import * as system from '../../model/system';
|
import system from '../../model/system';
|
||||||
import token from '../../model/token';
|
import token from '../../model/token';
|
||||||
|
|
||||||
export interface UiContextBase {
|
export interface UiContextBase {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { KoaContext, NotFoundError } from '@hydrooj/framework';
|
import { KoaContext, NotFoundError } from '@hydrooj/framework';
|
||||||
import BlackListModel from '../../model/blacklist';
|
import BlackListModel from '../../model/blacklist';
|
||||||
import DomainModel from '../../model/domain';
|
import DomainModel from '../../model/domain';
|
||||||
import * as system from '../../model/system';
|
import system from '../../model/system';
|
||||||
|
|
||||||
export default async (ctx: KoaContext, next) => {
|
export default async (ctx: KoaContext, next) => {
|
||||||
const forceDomain = /^\/d\/([^/]+)\//.exec(ctx.request.path);
|
const forceDomain = /^\/d\/([^/]+)\//.exec(ctx.request.path);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import cac from 'cac';
|
import cac from 'cac';
|
||||||
import { Logger } from '@hydrooj/utils';
|
import { Logger } from '@hydrooj/utils';
|
||||||
import { Context, Service } from '../context';
|
import { Context, Service } from '../context';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
|
|
||||||
const argv = cac().parse();
|
const argv = cac().parse();
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { Logger } from '../logger';
|
|||||||
import { PERM, PRIV } from '../model/builtin';
|
import { PERM, PRIV } from '../model/builtin';
|
||||||
import * as opcount from '../model/opcount';
|
import * as opcount from '../model/opcount';
|
||||||
import * as OplogModel from '../model/oplog';
|
import * as OplogModel from '../model/oplog';
|
||||||
import * as system from '../model/system';
|
import system from '../model/system';
|
||||||
import db from './db';
|
import db from './db';
|
||||||
import baseLayer from './layers/base';
|
import baseLayer from './layers/base';
|
||||||
import domainLayer from './layers/domain';
|
import domainLayer from './layers/domain';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import problem from './model/problem';
|
|||||||
import RecordModel from './model/record';
|
import RecordModel from './model/record';
|
||||||
import ScheduleModel from './model/schedule';
|
import ScheduleModel from './model/schedule';
|
||||||
import StorageModel from './model/storage';
|
import StorageModel from './model/storage';
|
||||||
import * as system from './model/system';
|
import system from './model/system';
|
||||||
import TaskModel from './model/task';
|
import TaskModel from './model/task';
|
||||||
import * as training from './model/training';
|
import * as training from './model/training';
|
||||||
import user, { handleMailLower } from './model/user';
|
import user, { handleMailLower } from './model/user';
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { isNullable } from 'cosmokit';
|
import { isNullable } from 'cosmokit';
|
||||||
|
import { Service } from './context';
|
||||||
|
|
||||||
export function buildProjection<T extends string | number = string>(fields: readonly T[]): Record<T, true> {
|
export function buildProjection<T extends string | number = string>(fields: readonly T[]): Record<T, true> {
|
||||||
const o: Record<T, true> = Object.create(null);
|
const o: Record<T, true> = Object.create(null);
|
||||||
@@ -28,4 +29,46 @@ export function unwrapExports(module: any) {
|
|||||||
return module.default ?? module;
|
return module.default ?? module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EXPERIMENTAL: This function is subject to change
|
||||||
|
// Don't try to understand this wrapper
|
||||||
|
export function serviceInstance<T extends new (...args: any[]) => any>(ImplClass: T) {
|
||||||
|
let instance: any = null;
|
||||||
|
let state: 'pending' | 'initializing' | 'initialized' = 'pending';
|
||||||
|
const onClass: (symbol | string)[] = ['name', 'Config', 'inject', 'prototype'];
|
||||||
|
const name = ImplClass.name;
|
||||||
|
|
||||||
|
const proxyObj = new Proxy(ImplClass, {
|
||||||
|
get(_, key) {
|
||||||
|
if (key === 'Service') return proxyObj;
|
||||||
|
if (Reflect.has(ImplClass, key) || onClass.includes(key)) return Reflect.get(ImplClass, key);
|
||||||
|
if (state === 'pending') throw new Error(`${name} is not initialized yet (getting ${String(key)})`);
|
||||||
|
if (state === 'initializing') throw new Error(`${name} is still initializing (getting ${String(key)})`);
|
||||||
|
return Reflect.get(instance, key);
|
||||||
|
},
|
||||||
|
has(_, key) {
|
||||||
|
if (key === Symbol.for('hydro.initialize')) return state !== 'pending';
|
||||||
|
return Reflect.has(_, key);
|
||||||
|
},
|
||||||
|
construct(_, args, target) {
|
||||||
|
if (state !== 'pending') throw new Error(`${name} is already constructed`);
|
||||||
|
state = 'initializing';
|
||||||
|
const originalInit = ImplClass.prototype[Service.init];
|
||||||
|
if (originalInit) {
|
||||||
|
ImplClass.prototype[Service.init] = new Proxy(originalInit, {
|
||||||
|
apply(...applyArgs) {
|
||||||
|
const result = Reflect.apply(...applyArgs);
|
||||||
|
if (result instanceof Promise) result.then(() => { state = 'initialized'; });
|
||||||
|
else state = 'initialized';
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
instance = Reflect.construct(ImplClass, args, target);
|
||||||
|
if (!Reflect.has(ImplClass, Service.init)) state = 'initialized';
|
||||||
|
return instance;
|
||||||
|
},
|
||||||
|
}) as (T extends (new (...args: any[]) => infer R) ? (R & { Service: (new (...args: any[]) => R) }) : never);
|
||||||
|
return proxyObj;
|
||||||
|
}
|
||||||
|
|
||||||
export * from '@hydrooj/utils/lib/utils';
|
export * from '@hydrooj/utils/lib/utils';
|
||||||
Reference in new issue
Block a user