Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
K
Koishi Nestjs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
3rdeye
Koishi Nestjs
Commits
67f7abde
Commit
67f7abde
authored
Oct 30, 2021
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
interceptor
parent
116e50a9
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
167 additions
and
61 deletions
+167
-61
index.ts
index.ts
+4
-3
src/koishi-metadata-fetcher/koishi-metadata-fetcher.service.ts
...oishi-metadata-fetcher/koishi-metadata-fetcher.service.ts
+6
-4
src/koishi.module.ts
src/koishi.module.ts
+2
-2
src/koishi.service.ts
src/koishi.service.ts
+2
-3
src/providers/koishi-context.service.ts
src/providers/koishi-context.service.ts
+1
-1
src/providers/koishi-logger.service.ts
src/providers/koishi-logger.service.ts
+1
-1
src/providers/koishi-metascan.service.ts
src/providers/koishi-metascan.service.ts
+30
-6
src/utility/koishi-context.factory.ts
src/utility/koishi-context.factory.ts
+1
-1
src/utility/koishi.constants.ts
src/utility/koishi.constants.ts
+6
-6
src/utility/koishi.decorators.ts
src/utility/koishi.decorators.ts
+68
-33
src/utility/koishi.interfaces.ts
src/utility/koishi.interfaces.ts
+45
-0
src/utility/koishi.utility.ts
src/utility/koishi.utility.ts
+1
-1
No files found.
index.ts
View file @
67f7abde
export
*
from
'
./src/koishi.decorators
'
;
export
*
from
'
./src/koishi.interfaces
'
;
export
*
from
'
./src/utility/koishi.decorators
'
;
export
*
from
'
./src/utility/koishi.interfaces
'
;
export
*
from
'
./src/utility/koishi.constants
'
;
export
*
from
'
./src/koishi.service
'
;
export
*
from
'
./src/koishi.module
'
;
export
*
from
'
./src/koishi-context.factory
'
;
export
*
from
'
./src/
utility/
koishi-context.factory
'
;
export
*
from
'
./src/koishi.ws-adapter
'
;
src/koishi-metadata-fetcher/koishi-metadata-fetcher.service.ts
View file @
67f7abde
import
{
Injectable
}
from
'
@nestjs/common
'
;
import
{
Reflector
}
from
'
@nestjs/core
'
;
import
{
MetadataArrayMap
}
from
'
../utility/koishi.constants
'
;
import
{
MetadataArray
Map
,
MetadataArray
Value
,
MetadataGenericMap
,
}
from
'
../utility/koishi.constants
'
;
MetadataMapValue
,
}
from
'
../utility/koishi.interfaces
'
;
@
Injectable
()
export
class
KoishiMetadataFetcherService
{
...
...
@@ -25,7 +27,7 @@ export class KoishiMetadataFetcherService {
instance
:
any
,
)
{
return
(
this
.
reflector
.
get
<
MetadataArray
Map
[
K
][]
>
(
metadataKey
,
instance
)
||
[]
this
.
reflector
.
get
<
MetadataArray
Value
<
K
>
>
(
metadataKey
,
instance
)
||
[]
);
}
...
...
@@ -33,6 +35,6 @@ export class KoishiMetadataFetcherService {
metadataKey
:
K
,
instance
:
any
,
)
{
return
this
.
reflector
.
get
<
Metadata
GenericMap
[
K
]
>
(
metadataKey
,
instance
);
return
this
.
reflector
.
get
<
Metadata
MapValue
<
K
>
>
(
metadataKey
,
instance
);
}
}
src/koishi.module.ts
View file @
67f7abde
...
...
@@ -10,7 +10,7 @@ import {
KoishiModuleAsyncOptions
,
KoishiModuleOptions
,
KoishiModuleOptionsFactory
,
}
from
'
./koishi.interfaces
'
;
}
from
'
./
utility/
koishi.interfaces
'
;
import
{
KoishiService
}
from
'
./koishi.service
'
;
import
{
KOISHI_CONTEXT
,
...
...
@@ -21,7 +21,7 @@ import { KoishiLoggerService } from './providers/koishi-logger.service';
import
{
KoishiMetascanService
}
from
'
./providers/koishi-metascan.service
'
;
import
{
DiscoveryModule
,
INQUIRER
}
from
'
@nestjs/core
'
;
import
{
Context
}
from
'
koishi
'
;
import
{
defaultContextContainer
}
from
'
./koishi-context.factory
'
;
import
{
defaultContextContainer
}
from
'
./
utility/
koishi-context.factory
'
;
import
{
KoishiInjectionService
}
from
'
./providers/koishi-injection.service
'
;
import
{
KoishiContextService
}
from
'
./providers/koishi-context.service
'
;
import
{
KoishiHttpDiscoveryService
}
from
'
./koishi-http-discovery/koishi-http-discovery.service
'
;
...
...
src/koishi.service.ts
View file @
67f7abde
...
...
@@ -6,7 +6,7 @@ import {
OnModuleDestroy
,
OnModuleInit
,
}
from
'
@nestjs/common
'
;
import
{
KoishiModuleOptions
}
from
'
./koishi.interfaces
'
;
import
{
KoishiModuleOptions
}
from
'
./
utility/
koishi.interfaces
'
;
import
{
Server
}
from
'
http
'
;
import
Koa
from
'
koa
'
;
import
KoaBodyParser
from
'
koa-bodyparser
'
;
...
...
@@ -19,8 +19,7 @@ import { KoishiHttpDiscoveryService } from './koishi-http-discovery/koishi-http-
@
Injectable
()
export
class
KoishiService
extends
App
implements
OnModuleInit
,
OnApplicationBootstrap
,
OnModuleDestroy
{
implements
OnModuleInit
,
OnApplicationBootstrap
,
OnModuleDestroy
{
constructor
(
@
Inject
(
KOISHI_MODULE_OPTIONS
)
private
readonly
koishiModuleOptions
:
KoishiModuleOptions
,
...
...
src/providers/koishi-context.service.ts
View file @
67f7abde
...
...
@@ -3,7 +3,7 @@ import { KOISHI_MODULE_OPTIONS } from '../utility/koishi.constants';
import
{
KoishiModuleOptions
,
KoishiModuleSelection
,
}
from
'
../koishi.interfaces
'
;
}
from
'
../
utility/
koishi.interfaces
'
;
import
{
applySelector
}
from
'
../utility/koishi.utility
'
;
import
{
Context
}
from
'
koishi
'
;
import
{
Module
}
from
'
@nestjs/core/injector/module
'
;
...
...
src/providers/koishi-logger.service.ts
View file @
67f7abde
import
{
ConsoleLogger
,
Inject
,
Injectable
}
from
'
@nestjs/common
'
;
import
{
Logger
}
from
'
koishi
'
;
import
{
KOISHI_MODULE_OPTIONS
}
from
'
../utility/koishi.constants
'
;
import
{
KoishiModuleOptions
}
from
'
../koishi.interfaces
'
;
import
{
KoishiModuleOptions
}
from
'
../
utility/
koishi.interfaces
'
;
@
Injectable
()
export
class
KoishiLoggerService
extends
ConsoleLogger
{
...
...
src/providers/koishi-metascan.service.ts
View file @
67f7abde
...
...
@@ -4,6 +4,7 @@ import { Argv, Command, Context, User } from 'koishi';
import
{
InstanceWrapper
}
from
'
@nestjs/core/injector/instance-wrapper
'
;
import
{
KoishiCommandDefinition
,
KoishiCommandInterceptorDef
,
KoishiDoRegister
,
KoishiOnContextScope
,
KoishiServiceProvideSym
,
...
...
@@ -14,8 +15,10 @@ import {
CommandPutConfig
,
DoRegisterConfig
,
EventName
,
KoishiCommandInterceptor
,
KoishiCommandInterceptorRegistration
,
KoishiModulePlugin
,
}
from
'
../koishi.interfaces
'
;
}
from
'
../
utility/
koishi.interfaces
'
;
import
{
applySelector
}
from
'
../utility/koishi.utility
'
;
import
_
from
'
lodash
'
;
import
{
KoishiContextService
}
from
'
./koishi-context.service
'
;
...
...
@@ -105,6 +108,21 @@ export class KoishiMetascanService {
}
}
private
getInterceptor
(
interceptorDef
:
KoishiCommandInterceptorRegistration
)
{
if
(
typeof
interceptorDef
!==
'
object
'
)
{
return
this
.
moduleRef
.
get
(
interceptorDef
,
{
strict
:
false
});
}
return
interceptorDef
;
}
private
addInterceptor
(
command
:
Command
,
interceptorDef
:
KoishiCommandInterceptorRegistration
,
)
{
const
interceptor
=
this
.
getInterceptor
(
interceptorDef
);
command
.
before
((...
params
)
=>
interceptor
.
intercept
(...
params
));
}
private
async
handleInstanceRegistration
(
ctx
:
Context
,
instance
:
Record
<
string
,
any
>
,
...
...
@@ -165,12 +183,18 @@ export class KoishiMetascanService {
);
const
commandDefs
=
this
.
metaFetcher
.
getMetadataArray
(
KoishiCommandDefinition
,
methodFun
()
,
methodFun
,
);
if
(
commandDefs
)
{
for
(
const
commandDef
of
commandDefs
)
{
command
=
commandDef
(
command
)
||
command
;
}
for
(
const
commandDef
of
commandDefs
)
{
command
=
commandDef
(
command
)
||
command
;
}
const
interceptorDefs
=
this
.
metaFetcher
.
getPropertyMetadataArray
(
KoishiCommandInterceptorDef
,
instance
,
methodKey
,
);
for
(
const
interceptorDef
of
interceptorDefs
)
{
this
.
addInterceptor
(
command
,
interceptorDef
);
}
if
(
!
commandData
.
putOptions
)
{
command
.
action
((
argv
:
Argv
,
...
args
:
any
[])
=>
...
...
src/koishi-context.factory.ts
→
src/
utility/
koishi-context.factory.ts
View file @
67f7abde
import
{
Context
}
from
'
koishi
'
;
import
{
Provider
,
Scope
}
from
'
@nestjs/common
'
;
import
{
KOISHI_CONTEXT
}
from
'
./
utility/
koishi.constants
'
;
import
{
KOISHI_CONTEXT
}
from
'
./koishi.constants
'
;
export
type
ContextScopeTypes
=
|
'
guild
'
...
...
src/utility/koishi.constants.ts
View file @
67f7abde
...
...
@@ -2,9 +2,12 @@
import
{
CommandDefinitionFun
,
DoRegisterConfig
,
KoishiCommandInterceptor
,
KoishiCommandInterceptorRegistration
,
OnContextFunction
,
}
from
'
.
.
/koishi.interfaces
'
;
}
from
'
./koishi.interfaces
'
;
import
{
Context
}
from
'
koishi
'
;
import
{
Type
}
from
'
@nestjs/common
'
;
export
const
KOISHI_MODULE_OPTIONS
=
'
KOISHI_MODULE_OPTIONS
'
;
export
const
KOISHI_CONTEXT
=
'
KOISHI_CONTEXT
'
;
...
...
@@ -14,6 +17,7 @@ export const KoishiOnContextScope = 'KoishiOnContextScope';
export
const
KoishiDoRegister
=
'
KoishiDoRegister
'
;
export
const
KoishiCommandDefinition
=
'
KoishiCommandDefinition
'
;
export
const
KoishiCommandPutDef
=
'
KoishiCommandPutDef
'
;
export
const
KoishiCommandInterceptorDef
=
'
KoishiCommandInterceptorDef
'
;
export
const
KoishiServiceWireProperty
=
'
KoishiServiceWireProperty
'
;
export
const
KoishiServiceWireKeys
=
'
KoishiServiceWireKeys
'
;
...
...
@@ -25,13 +29,9 @@ export interface MetadataArrayMap {
KoishiOnContextScope
:
OnContextFunction
;
KoishiCommandDefinition
:
CommandDefinitionFun
;
KoishiServiceProvideSym
:
keyof
Context
.
Services
;
KoishiCommandInterceptorDef
:
KoishiCommandInterceptorRegistration
;
}
export
interface
MetadataMap
{
KoishiDoRegister
:
DoRegisterConfig
;
}
export
type
MetadataGenericMap
=
{
[
K
in
keyof
MetadataArrayMap
]:
MetadataArrayMap
[
K
][];
}
&
MetadataMap
;
src/koishi.decorators.ts
→
src/
utility/
koishi.decorators.ts
View file @
67f7abde
import
{
CustomDecorator
,
Inject
,
SetMetadata
}
from
'
@nestjs/common
'
;
import
{
CustomDecorator
,
Inject
,
Type
}
from
'
@nestjs/common
'
;
import
{
KOISHI_CONTEXT
,
KoishiCommandDefinition
,
KoishiCommandInterceptorDef
,
KoishiCommandPutDef
,
KoishiDoRegister
,
KoishiOnContextScope
,
...
...
@@ -9,7 +10,8 @@ import {
KoishiServiceWireKeys
,
KoishiServiceWireProperty
,
MetadataArrayMap
,
}
from
'
./utility/koishi.constants
'
;
MetadataMap
,
}
from
'
./koishi.constants
'
;
import
{
CommandDefinitionFun
,
CommandPutConfig
,
...
...
@@ -17,6 +19,13 @@ import {
DoRegisterConfig
,
EventName
,
GenerateMappingStruct
,
KoishiCommandInterceptor
,
KoishiCommandInterceptorDeclaration
,
MetadataArrayValue
,
MetadataArrayValueMap
,
MetadataGenericMap
,
MetadataKey
,
MetadataMapValue
,
OnContextFunction
,
Selection
,
}
from
'
./koishi.interfaces
'
;
...
...
@@ -45,44 +54,66 @@ export const InjectContextPlatform = (...values: string[]) =>
export
const
InjectContextUser
=
(...
values
:
string
[])
=>
InjectContextSpecific
(
'
user
'
,
values
);
export
const
SetExtraMetadata
=
<
K
extends
keyof
MetadataArrayMap
>
(
// metadata extended
export
function
TransformMetadata
<
K
extends
MetadataKey
,
VM
extends
Partial
<
MetadataGenericMap
>
=
MetadataGenericMap
>
(
metadataKey
:
K
,
metadataValue
:
MetadataArrayMap
[
K
],
):
CustomDecorator
<
K
>
=>
{
metadataValue
Fun
:
(
oldValue
:
VM
[
K
])
=>
VM
[
K
],
):
CustomDecorator
<
K
>
{
const
decoratorFactory
=
(
target
:
any
,
key
?:
any
,
descriptor
?:
any
)
=>
{
const
currentMetadata
:
any
[
]
=
const
oldValue
:
VM
[
K
]
=
Reflect
.
getMetadata
(
metadataKey
,
descriptor
?
descriptor
.
value
:
target
,
)
||
[];
c
urrentMetadata
.
push
(
metadata
Value
);
c
onst
newValue
=
metadataValueFun
(
old
Value
);
if
(
descriptor
)
{
Reflect
.
defineMetadata
(
metadataKey
,
currentMetadata
,
descriptor
.
value
);
Reflect
.
defineMetadata
(
metadataKey
,
newValue
,
descriptor
.
value
);
return
descriptor
;
}
Reflect
.
defineMetadata
(
metadataKey
,
currentMetadata
,
target
);
Reflect
.
defineMetadata
(
metadataKey
,
newValue
,
target
);
return
target
;
};
decoratorFactory
.
KEY
=
metadataKey
;
return
decoratorFactory
;
};
}
export
const
SetMetadata
=
<
K
extends
keyof
MetadataGenericMap
>
(
metadataKey
:
K
,
metadataValue
:
MetadataGenericMap
[
K
],
):
CustomDecorator
<
K
>
=>
TransformMetadata
<
K
>
(
metadataKey
,
()
=>
metadataValue
);
export
const
AppendMetadata
=
<
K
extends
keyof
MetadataArrayMap
>
(
metadataKey
:
K
,
metadataValue
:
MetadataArrayMap
[
K
],
):
CustomDecorator
<
K
>
=>
TransformMetadata
<
K
,
MetadataArrayValueMap
>
(
metadataKey
,
(
arr
)
=>
{
const
newArr
=
arr
||
[];
newArr
.
push
(
metadataValue
);
return
newArr
;
});
export
const
ConcatMetadata
=
<
K
extends
keyof
MetadataArrayValueMap
>
(
metadataKey
:
K
,
metadataValue
:
MetadataArrayValue
<
K
>
,
):
CustomDecorator
<
K
>
=>
TransformMetadata
<
K
,
MetadataArrayValueMap
>
(
metadataKey
,
(
arr
)
=>
((
arr
||
[])
as
any
[]).
concat
(
metadataValue
),
);
// Register methods
export
const
UseMiddleware
=
(
prepend
?:
boolean
):
MethodDecorator
=>
SetMetadata
<
string
,
DoRegisterConfig
<
'
middleware
'
>>
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
middleware
'
,
prepend
),
);
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
middleware
'
,
prepend
));
export
const
UseEvent
=
(
name
:
EventName
,
prepend
?:
boolean
):
MethodDecorator
=>
SetMetadata
<
string
,
DoRegisterConfig
<
'
onevent
'
>>
(
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
onevent
'
,
{
name
,
prepend
}),
);
export
const
UsePlugin
=
():
MethodDecorator
=>
SetMetadata
<
string
,
DoRegisterConfig
<
'
plugin
'
>>
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
plugin
'
),
);
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
plugin
'
));
export
function
UseCommand
<
D
extends
string
>
(
def
:
D
,
...
...
@@ -104,18 +135,15 @@ export function UseCommand(
Reflect
.
getMetadata
(
KoishiCommandPutDef
,
obj
.
constructor
,
key
)
||
undefined
;
// console.log(Reflect.getMetadata('design:paramtypes', obj, key));
const
metadataDec
=
SetMetadata
<
string
,
DoRegisterConfig
<
'
command
'
>>
(
KoishiDoRegister
,
{
type
:
'
command
'
,
data
:
{
def
,
desc
,
config
,
putOptions
,
},
const
metadataDec
=
SetMetadata
(
KoishiDoRegister
,
{
type
:
'
command
'
,
data
:
{
def
,
desc
,
config
,
putOptions
,
},
);
}
);
return
metadataDec
(
obj
,
key
,
des
);
};
}
...
...
@@ -125,7 +153,7 @@ export function UseCommand(
export
const
OnContext
=
(
ctxFun
:
OnContextFunction
,
):
MethodDecorator
&
ClassDecorator
=>
SetExtra
Metadata
(
KoishiOnContextScope
,
ctxFun
);
Append
Metadata
(
KoishiOnContextScope
,
ctxFun
);
export
const
OnUser
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
user
(...
values
));
...
...
@@ -151,7 +179,7 @@ export const OnSelection = (selection: Selection) =>
// Command definition
export
const
CommandDef
=
(
def
:
CommandDefinitionFun
):
MethodDecorator
=>
SetExtra
Metadata
(
KoishiCommandDefinition
,
def
);
Append
Metadata
(
KoishiCommandDefinition
,
def
);
export
const
CommandDescription
=
(
desc
:
string
)
=>
CommandDef
((
cmd
)
=>
{
...
...
@@ -249,5 +277,12 @@ export function ProvideContextService(
name
:
keyof
Context
.
Services
,
):
ClassDecorator
{
Context
.
service
(
name
);
return
SetExtra
Metadata
(
KoishiServiceProvideSym
,
name
);
return
Append
Metadata
(
KoishiServiceProvideSym
,
name
);
}
// Command interceptor
export
const
CommandInterceptors
=
(
...
interceptors
:
KoishiCommandInterceptorDeclaration
[]
):
MethodDecorator
&
ClassDecorator
=>
ConcatMetadata
(
KoishiCommandInterceptorDef
,
interceptors
);
src/koishi.interfaces.ts
→
src/
utility/
koishi.interfaces.ts
View file @
67f7abde
import
{
ModuleMetadata
,
Provider
,
Type
}
from
'
@nestjs/common
'
;
import
{
Channel
,
User
}
from
'
koishi
'
;
import
{
App
,
Argv
,
...
...
@@ -10,6 +11,7 @@ import {
Plugin
,
Session
,
}
from
'
koishi
'
;
import
{
MetadataArrayMap
,
MetadataMap
}
from
'
./koishi.constants
'
;
const
selectors
=
[
'
user
'
,
...
...
@@ -150,3 +152,46 @@ export type CommandPutConfig<
>
=
MappingStruct
<
CommandPutConfigMap
,
K
>
;
export
type
CommandDefinitionFun
=
(
cmd
:
Command
)
=>
Command
;
// metadata map
export
type
MetadataArrayValueMap
=
{
[
K
in
keyof
MetadataArrayMap
]:
MetadataArrayMap
[
K
][];
};
export
type
MetadataGenericMap
=
MetadataArrayValueMap
&
MetadataMap
;
export
type
MetadataArrayValue
<
K
extends
keyof
MetadataArrayValueMap
>
=
MetadataArrayValueMap
[
K
];
export
type
MetadataKey
=
keyof
MetadataArrayMap
|
keyof
MetadataMap
;
export
type
MetadataMapValue
<
K
extends
MetadataKey
>
=
K
extends
keyof
MetadataArrayValueMap
?
MetadataArrayValue
<
K
>
:
K
extends
keyof
MetadataMap
?
MetadataMap
[
K
]
:
never
;
// command interceptor
export
interface
KoishiCommandInterceptor
<
U
extends
User
.
Field
=
never
,
G
extends
Channel
.
Field
=
never
,
A
extends
any
[]
=
any
[],
O
extends
{}
=
{}
>
{
intercept
:
Command
.
Action
<
U
,
G
,
A
,
O
>
;
}
export
type
KoishiCommandInterceptorRegistration
<
U
extends
User
.
Field
=
never
,
G
extends
Channel
.
Field
=
never
,
A
extends
any
[]
=
any
[],
O
extends
{}
=
{}
>
=
|
KoishiCommandInterceptor
<
U
,
G
,
A
,
O
>
|
Type
<
KoishiCommandInterceptor
<
U
,
G
,
A
,
O
>>
|
string
|
symbol
;
src/utility/koishi.utility.ts
View file @
67f7abde
import
{
Context
}
from
'
koishi
'
;
import
{
ContextSelector
}
from
'
.
.
/koishi.interfaces
'
;
import
{
ContextSelector
}
from
'
./koishi.interfaces
'
;
export
function
applySelector
(
ctx
:
Context
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment