Commit 2176878c authored by nanahira's avatar nanahira

service catchup for koishi beta4

parent 578c2934
......@@ -9,6 +9,7 @@
"version": "4.0.1",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.21",
"reflect-metadata": "^0.1.13",
"schemastery": "^2.0.0",
"schemastery-gen": "2.0.2",
......@@ -16,6 +17,7 @@
},
"devDependencies": {
"@koishijs/plugin-adapter-onebot": "^4.0.0-beta.2",
"@types/lodash": "^4.14.177",
"@types/node": "^16.11.9",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
......@@ -433,6 +435,12 @@
"@types/koa": "*"
}
},
"node_modules/@types/lodash": {
"version": "4.14.177",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.177.tgz",
"integrity": "sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==",
"dev": true
},
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
......@@ -3574,6 +3582,12 @@
"@types/koa": "*"
}
},
"@types/lodash": {
"version": "4.14.177",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.177.tgz",
"integrity": "sha512-0fDwydE2clKe9MNfvXHBHF9WEahRuj+msTuQqOmAApNORFvhMYZKNGGJdCzuhheVjMps/ti0Ak/iJPACMaevvw==",
"dev": true
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
......
......@@ -5,6 +5,7 @@ import {
DoRegisterConfig,
EventName,
GenerateMappingStruct,
KoishiAddUsingList,
KoishiCommandDefinition,
KoishiCommandPutDef,
KoishiDoRegister,
......@@ -17,6 +18,7 @@ import {
KoishiSystemInjectSymKeys,
MetadataMap,
OnContextFunction,
ProvideOptions,
Selection,
SystemInjectFun,
} from './def';
......@@ -181,7 +183,26 @@ export const PutBot = () => PutSession('bot');
// Service
export function Inject(name?: keyof Context.Services): PropertyDecorator {
export function Inject(
name?: keyof Context.Services,
addUsing?: boolean,
): PropertyDecorator;
export function Inject(addUsing?: boolean): PropertyDecorator;
export function Inject(
...args: [(keyof Context.Services | boolean)?, boolean?]
): PropertyDecorator {
let name: keyof Context.Services;
let addUsing = false;
if (args.length === 1) {
if (typeof args[0] === 'boolean') {
addUsing = args[0];
} else {
name = args[0];
}
} else if (args.length >= 2) {
name = args[0] as keyof Context.Services;
addUsing = args[1];
}
return (obj, key) => {
if (!name) {
const functionType = Reflect.getMetadata('design:type', obj, key);
......@@ -196,6 +217,9 @@ export function Inject(name?: keyof Context.Services): PropertyDecorator {
}
}
const serviceName = name || (key as keyof Context.Services);
if (addUsing) {
Metadata.appendUnique(KoishiAddUsingList, serviceName)(obj.constructor);
}
const dec = Metadata.set(
KoishiServiceInjectSym,
serviceName,
......@@ -207,10 +231,13 @@ export function Inject(name?: keyof Context.Services): PropertyDecorator {
export function Provide(
name: keyof Context.Services,
options?: Context.Options,
options?: ProvideOptions,
): ClassDecorator {
Context.service(name, options);
return Metadata.appendUnique(KoishiServiceProvideSym, name);
Context.service(name);
return Metadata.append(KoishiServiceProvideSym, {
...options,
serviceName: name,
});
}
const InjectSystem = (fun: SystemInjectFun) =>
......
......@@ -4,6 +4,7 @@ import {
CommandDefinitionFun,
DoRegisterConfig,
OnContextFunction,
ProvideDefinition,
SystemInjectFun,
} from './interfaces';
......@@ -18,16 +19,18 @@ export const KoishiServiceInjectSymKeys = 'KoishiServiceInjectSymKeys';
export const KoishiServiceProvideSym = 'KoishiServiceProvideSym';
export const KoishiSystemInjectSym = 'KoishiSystemInjectSym';
export const KoishiSystemInjectSymKeys = 'KoishiSystemInjectSymKeys';
export const KoishiAddUsingList = 'KoishiAddUsingList';
// metadata map
export interface MetadataArrayMap {
KoishiOnContextScope: OnContextFunction;
KoishiCommandDefinition: CommandDefinitionFun;
KoishiServiceProvideSym: keyof Context.Services;
KoishiServiceProvideSym: ProvideDefinition;
KoishiDoRegisterKeys: string;
KoishiServiceInjectSymKeys: string;
KoishiSystemInjectSymKeys: string;
KoishiAddUsingList: keyof Context.Services;
}
export interface MetadataMap {
......
......@@ -147,3 +147,11 @@ export type SystemInjectFun = <T = any>(
obj: PluginClass<T>,
pluginMeta: KoishiPluginRegistrationOptions<T>,
) => any;
export interface ProvideOptions {
immediate?: boolean;
}
export interface ProvideDefinition extends ProvideOptions {
serviceName: keyof Context.Services;
}
......@@ -2,6 +2,7 @@ import { Argv, Command, Context, Schema, User } from 'koishi';
import {
CommandPutConfig,
DoRegisterConfig,
KoishiAddUsingList,
KoishiCommandDefinition,
KoishiDoRegister,
KoishiDoRegisterKeys,
......@@ -18,10 +19,12 @@ import {
import { reflector } from './meta/meta-fetch';
import { applySelector } from './utility/utility';
import { ClassType, SchemaClass } from 'schemastery-gen';
import _ from 'lodash';
export interface KoishiPluginRegistrationOptions<T = any> {
name?: string;
schema?: Schema<any, T> | Type<T>;
using?: (keyof Context.Services)[];
}
export interface PluginClass<T = any> {
......@@ -54,12 +57,18 @@ export function KoishiPlugin<T = any>(
options: KoishiPluginRegistrationOptions<T> = {},
) {
return function <
C extends { new (...args: any[]): any; schema?: Schema; name?: string }
C extends {
new (...args: any[]): any;
} & KoishiPluginRegistrationOptions<any>
>(originalClass: C) {
const addUsingList = reflector.getArray(KoishiAddUsingList, originalClass);
const newClass = class extends originalClass implements PluginClass {
static schema = (options.schema as Schema).type
static schema =
options.schema &&
((options.schema as Schema).type
? (options.schema as Schema<Partial<T>, T>)
: SchemaClass(options.schema as ClassType<T>);
: SchemaClass(options.schema as ClassType<T>));
static using = _.uniq([...(options.using || []), ...addUsingList]);
__ctx: Context;
__config: T;
__pluginOptions: KoishiPluginRegistrationOptions<T>;
......@@ -271,15 +280,15 @@ export function KoishiPlugin<T = any>(
);
}
_handleServiceProvide(connect = true) {
_handleServiceProvide(immediate: boolean) {
// console.log(`Handling service provide`);
const providingServices = [
...reflector.getArray(KoishiServiceProvideSym, originalClass),
...reflector.getArray(KoishiServiceProvideSym, this),
];
].filter((serviceDef) => !serviceDef.immediate === !immediate);
for (const key of providingServices) {
// console.log(`Processing ${key}`);
this.__ctx[key] = connect ? (this as any) : null;
this.__ctx[key.serviceName] = this as any;
}
}
......@@ -289,17 +298,18 @@ export function KoishiPlugin<T = any>(
if (typeof this.onConnect === 'function') {
await this.onConnect();
}
this._handleServiceProvide(true);
this._handleServiceProvide(false);
});
this.__ctx.on('disconnect', async () => {
if (typeof this.onDisconnect === 'function') {
await this.onDisconnect();
}
this._handleServiceProvide(false);
// this._handleServiceProvide(false);
});
}
async _initializePluginClass() {
this._handleServiceProvide(true);
this._handleSystemInjections();
this._handleServiceInjections();
this._registerAfterInit();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment