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
e0d42ac3
Commit
e0d42ac3
authored
Jan 23, 2022
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor with koishi-decorators
parent
714309db
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
290 additions
and
907 deletions
+290
-907
package-lock.json
package-lock.json
+166
-286
package.json
package.json
+1
-0
src/koishi.service.ts
src/koishi.service.ts
+6
-6
src/providers/koishi-context.service.ts
src/providers/koishi-context.service.ts
+5
-18
src/providers/koishi-metascan.service.ts
src/providers/koishi-metascan.service.ts
+48
-226
src/providers/koishi-websocket.gateway.ts
src/providers/koishi-websocket.gateway.ts
+2
-1
src/utility/koishi.constants.ts
src/utility/koishi.constants.ts
+2
-15
src/utility/koishi.decorators.ts
src/utility/koishi.decorators.ts
+6
-199
src/utility/koishi.interfaces.ts
src/utility/koishi.interfaces.ts
+3
-136
src/utility/koishi.utility.ts
src/utility/koishi.utility.ts
+0
-19
tests/koishi-tests.spec.ts
tests/koishi-tests.spec.ts
+51
-1
No files found.
package-lock.json
View file @
e0d42ac3
This diff is collapsed.
Click to expand it.
package.json
View file @
e0d42ac3
...
...
@@ -70,6 +70,7 @@
"
@types/ws
"
:
"
^8.2.0
"
,
"
koa
"
:
"
^2.13.3
"
,
"
koa-bodyparser
"
:
"
^4.3.0
"
,
"
koishi-decorators
"
:
"
^1.0.3
"
,
"
lodash
"
:
"
^4.17.21
"
,
"
ws
"
:
"
^8.2.3
"
},
...
...
src/koishi.service.ts
View file @
e0d42ac3
...
...
@@ -14,11 +14,11 @@ import { Server } from 'http';
import
Koa
from
'
koa
'
;
import
KoaBodyParser
from
'
koa-bodyparser
'
;
import
{
KoishiMetascanService
}
from
'
./providers/koishi-metascan.service
'
;
import
{
applySelector
}
from
'
./utility/koishi.utility
'
;
import
{
KOISHI_MODULE_OPTIONS
}
from
'
./utility/koishi.constants
'
;
import
{
KoishiLoggerService
}
from
'
./providers/koishi-logger.service
'
;
import
{
KoishiHttpDiscoveryService
}
from
'
./koishi-http-discovery/koishi-http-discovery.service
'
;
import
{
Filter
,
ReplacedContext
}
from
'
./utility/replaced-context
'
;
import
{
applySelector
}
from
'
koishi-decorators
'
;
// eslint-disable-next-line @typescript-eslint/no-empty-function
Router
.
prepare
=
()
=>
{};
...
...
@@ -70,17 +70,17 @@ export class KoishiService
async
onModuleInit
()
{
await
this
.
setHttpServer
();
await
this
.
metascan
.
preRegisterContext
(
this
.
any
());
this
.
metascan
.
preRegisterContext
(
this
.
any
());
if
(
this
.
koishiModuleOptions
.
usePlugins
)
{
for
(
const
pluginDe
sc
of
this
.
koishiModuleOptions
.
usePlugins
)
{
const
ctx
=
applySelector
(
this
,
pluginDe
sc
);
ctx
.
plugin
(
pluginDe
sc
.
plugin
,
pluginDesc
.
options
);
for
(
const
pluginDe
f
of
this
.
koishiModuleOptions
.
usePlugins
)
{
const
ctx
=
applySelector
(
this
,
pluginDe
f
);
ctx
.
plugin
(
pluginDe
f
.
plugin
,
pluginDef
.
options
);
}
}
}
async
onApplicationBootstrap
()
{
await
this
.
metascan
.
registerContext
(
this
.
any
());
this
.
metascan
.
registerContext
(
this
.
any
());
return
this
.
start
();
}
...
...
src/providers/koishi-context.service.ts
View file @
e0d42ac3
import
{
Inject
,
Injectable
,
Type
}
from
'
@nestjs/common
'
;
import
{
KOISHI_MODULE_OPTIONS
,
KoishiOnContextScope
,
}
from
'
../utility/koishi.constants
'
;
import
{
KOISHI_MODULE_OPTIONS
}
from
'
../utility/koishi.constants
'
;
import
{
KoishiModuleOptions
,
KoishiModuleSelection
,
}
from
'
../utility/koishi.interfaces
'
;
import
{
applySelector
}
from
'
../utility/koishi.utility
'
;
import
{
applySelector
,
Registrar
}
from
'
koishi-decorators
'
;
import
{
Context
}
from
'
koishi
'
;
import
{
Module
}
from
'
@nestjs/core/injector/module
'
;
import
{
KoishiMetadataFetcherService
}
from
'
../koishi-metadata-fetcher/koishi-metadata-fetcher.service
'
;
import
_
from
'
lodash
'
;
@
Injectable
()
export
class
KoishiContextService
{
moduleSelections
=
new
Map
<
Type
<
any
>
,
KoishiModuleSelection
>
();
constructor
(
@
Inject
(
KOISHI_MODULE_OPTIONS
)
options
:
KoishiModuleOptions
,
private
readonly
metaFetcher
:
KoishiMetadataFetcherService
,
)
{
constructor
(@
Inject
(
KOISHI_MODULE_OPTIONS
)
options
:
KoishiModuleOptions
)
{
if
(
options
.
moduleSelection
)
{
for
(
const
selection
of
options
.
moduleSelection
)
{
this
.
moduleSelections
.
set
(
selection
.
module
,
selection
);
...
...
@@ -37,13 +29,8 @@ export class KoishiContextService {
}
getProviderCtx
(
ctx
:
Context
,
...
instances
:
any
[])
{
const
contextFilters
=
_
.
flatten
(
instances
.
map
((
instance
)
=>
this
.
metaFetcher
.
getMetadataArray
(
KoishiOnContextScope
,
instance
),
),
);
for
(
const
filter
of
contextFilters
)
{
ctx
=
filter
(
ctx
)
||
ctx
;
for
(
const
instance
of
instances
)
{
ctx
=
new
Registrar
(
instance
).
getScopeContext
(
ctx
);
}
return
ctx
;
}
...
...
src/providers/koishi-metascan.service.ts
View file @
e0d42ac3
This diff is collapsed.
Click to expand it.
src/providers/koishi-websocket.gateway.ts
View file @
e0d42ac3
...
...
@@ -10,7 +10,8 @@ import { IncomingMessage } from 'http';
@
WebSocketGateway
()
export
class
KoishiWebsocketGateway
implements
OnGatewayInit
,
OnGatewayConnection
{
implements
OnGatewayInit
,
OnGatewayConnection
{
constructor
(
private
readonly
koishi
:
KoishiService
)
{}
@
WebSocketServer
()
...
...
src/utility/koishi.constants.ts
View file @
e0d42ac3
// Injections
import
{
CommandDefinitionFun
,
DoRegisterConfig
,
KoishiCommandInterceptorRegistration
,
OnContextFunction
,
}
from
'
./koishi.interfaces
'
;
import
{
KoishiCommandInterceptorRegistration
}
from
'
./koishi.interfaces
'
;
import
{
Context
}
from
'
koishi
'
;
export
const
KOISHI_MODULE_OPTIONS
=
'
KOISHI_MODULE_OPTIONS
'
;
export
const
KOISHI_CONTEXT
=
'
KOISHI_CONTEXT
'
;
// metadatas
export
const
KoishiOnContextScope
=
'
KoishiOnContextScope
'
;
export
const
KoishiDoRegister
=
'
KoishiDoRegister
'
;
export
const
KoishiCommandDefinition
=
'
KoishiCommandDefinition
'
;
export
const
KoishiCommandPutDef
=
'
KoishiCommandPutDef
'
;
export
const
KoishiCommandInterceptorDef
=
'
KoishiCommandInterceptorDef
'
;
export
const
KoishiServiceWireProperty
=
'
KoishiServiceWireProperty
'
;
...
...
@@ -24,12 +15,8 @@ export const KoishiServiceProvideSym = 'KoishiServiceProvideSym';
// metadata map
export
interface
MetadataArrayMap
{
KoishiOnContextScope
:
OnContextFunction
;
KoishiCommandDefinition
:
CommandDefinitionFun
;
KoishiServiceProvideSym
:
keyof
Context
.
Services
;
KoishiCommandInterceptorDef
:
KoishiCommandInterceptorRegistration
;
}
export
interface
MetadataMap
{
KoishiDoRegister
:
DoRegisterConfig
;
}
export
interface
MetadataMap
{}
src/utility/koishi.decorators.ts
View file @
e0d42ac3
import
{
CustomDecorator
,
Inject
}
from
'
@nestjs/common
'
;
import
{
KOISHI_CONTEXT
,
KoishiCommandDefinition
,
KoishiCommandInterceptorDef
,
KoishiCommandPutDef
,
KoishiDoRegister
,
KoishiOnContextScope
,
KoishiServiceProvideSym
,
KoishiServiceWireKeys
,
KoishiServiceWireProperty
,
MetadataArrayMap
,
}
from
'
./koishi.constants
'
;
import
{
BeforeEventName
,
CommandConfigExtended
,
CommandDefinitionFun
,
CommandPutConfig
,
CommandPutConfigMap
,
EventName
,
GenerateMappingStruct
,
KoishiCommandInterceptorRegistration
,
MetadataArrayValue
,
MetadataArrayValueMap
,
MetadataGenericMap
,
MetadataKey
,
OnContextFunction
,
}
from
'
./koishi.interfaces
'
;
import
{
Argv
,
Command
,
Context
,
FieldCollector
,
Selection
,
Session
,
}
from
'
koishi
'
;
import
{
Context
}
from
'
koishi
'
;
import
{
ContextScopeTypes
,
getContextProvideToken
,
...
...
@@ -96,6 +77,8 @@ export const AppendMetadata = <K extends keyof MetadataArrayMap>(
):
CustomDecorator
<
K
>
=>
TransformMetadata
<
K
,
MetadataArrayValueMap
>
(
metadataKey
,
(
arr
)
=>
{
const
newArr
=
arr
||
[];
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
newArr
.
push
(
metadataValue
);
return
newArr
;
});
...
...
@@ -108,186 +91,10 @@ export const ConcatMetadata = <K extends keyof MetadataArrayValueMap>(
((
arr
||
[])
as
any
[]).
concat
(
metadataValue
),
);
// Register methods
export
const
UseMiddleware
=
(
prepend
?:
boolean
):
MethodDecorator
=>
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
middleware
'
,
prepend
));
export
const
UseEvent
=
(
name
:
EventName
,
prepend
?:
boolean
):
MethodDecorator
=>
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
onevent
'
,
{
name
,
prepend
}),
);
export
const
BeforeEvent
=
(
name
:
BeforeEventName
,
prepend
?:
boolean
,
):
MethodDecorator
=>
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
beforeEvent
'
,
{
name
,
prepend
}),
);
export
const
UsePlugin
=
():
MethodDecorator
=>
SetMetadata
(
KoishiDoRegister
,
GenerateMappingStruct
(
'
plugin
'
));
export
function
UseCommand
<
D
extends
string
>
(
def
:
D
,
config
?:
CommandConfigExtended
,
):
MethodDecorator
;
export
function
UseCommand
<
D
extends
string
>
(
def
:
D
,
desc
:
string
,
config
?:
CommandConfigExtended
,
):
MethodDecorator
;
export
function
UseCommand
(
def
:
string
,
...
args
:
[
CommandConfigExtended
?]
|
[
string
,
CommandConfigExtended
?]
):
MethodDecorator
{
const
desc
=
typeof
args
[
0
]
===
'
string
'
?
(
args
.
shift
()
as
string
)
:
''
;
const
config
=
args
[
0
]
as
CommandConfigExtended
;
return
(
obj
,
key
:
string
,
des
)
=>
{
const
putOptions
:
CommandPutConfig
<
keyof
CommandPutConfigMap
>
[]
=
Reflect
.
getMetadata
(
KoishiCommandPutDef
,
obj
.
constructor
,
key
)
||
undefined
;
// console.log(Reflect.getMetadata('design:paramtypes', obj, key));
const
metadataDec
=
SetMetadata
(
KoishiDoRegister
,
{
type
:
'
command
'
,
data
:
{
def
,
desc
,
config
,
putOptions
,
},
});
return
metadataDec
(
obj
,
key
,
des
);
};
}
// Context scopes
export
const
OnContext
=
(
ctxFun
:
OnContextFunction
,
):
MethodDecorator
&
ClassDecorator
=>
AppendMetadata
(
KoishiOnContextScope
,
ctxFun
);
export
const
OnAnywhere
=
()
=>
OnContext
((
ctx
)
=>
ctx
.
any
());
export
const
OnNowhere
=
()
=>
OnContext
((
ctx
)
=>
ctx
.
never
());
export
const
OnUser
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
user
(...
values
));
export
const
OnSelf
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
self
(...
values
));
export
const
OnGuild
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
guild
(...
values
));
export
const
OnChannel
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
channel
(...
values
));
export
const
OnPlatform
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
platform
(...
values
));
export
const
OnPrivate
=
(...
values
:
string
[])
=>
OnContext
((
ctx
)
=>
ctx
.
private
(...
values
));
export
const
OnSelection
=
(
selection
:
Selection
)
=>
OnContext
((
ctx
)
=>
ctx
.
select
(
selection
));
// Command definition
export
const
CommandDef
=
(
def
:
CommandDefinitionFun
,
):
MethodDecorator
&
ClassDecorator
=>
AppendMetadata
(
KoishiCommandDefinition
,
def
);
export
const
CommandUse
=
<
T
extends
Command
,
R
extends
any
[]
>
(
callback
:
(
command
:
Command
,
...
args
:
R
)
=>
T
,
...
args
:
R
)
=>
CommandDef
((
cmd
)
=>
callback
(
cmd
,
...
args
));
export
const
CommandDescription
=
(
desc
:
string
)
=>
CommandDef
((
cmd
)
=>
{
cmd
.
description
=
desc
;
return
cmd
;
});
export
const
CommandAlias
=
(...
names
:
string
[])
=>
CommandDef
((
cmd
)
=>
cmd
.
alias
(...
names
));
export
const
CommandShortcut
=
(
name
:
string
|
RegExp
,
config
:
Command
.
Shortcut
=
{},
)
=>
CommandDef
((
cmd
)
=>
cmd
.
shortcut
(
name
,
config
));
export
const
CommandUsage
=
(
text
:
Command
.
Usage
)
=>
CommandDef
((
cmd
)
=>
cmd
.
usage
(
text
));
export
const
CommandExample
=
(
text
:
string
)
=>
CommandDef
((
cmd
)
=>
cmd
.
example
(
text
));
export
const
CommandOption
=
(
name
:
string
,
desc
:
string
,
config
:
Argv
.
OptionConfig
=
{},
)
=>
CommandDef
((
cmd
)
=>
cmd
.
option
(
name
,
desc
,
config
));
export
const
CommandUserFields
=
(
fields
:
FieldCollector
<
'
user
'
>
)
=>
CommandDef
((
cmd
)
=>
cmd
.
userFields
(
fields
));
export
const
CommandChannelFields
=
(
fields
:
FieldCollector
<
'
channel
'
>
)
=>
CommandDef
((
cmd
)
=>
cmd
.
channelFields
(
fields
));
export
const
CommandBefore
=
(
callback
:
Command
.
Action
,
append
=
false
)
=>
CommandDef
((
cmd
)
=>
cmd
.
before
(
callback
,
append
));
export
const
CommandAction
=
(
callback
:
Command
.
Action
,
prepend
=
false
)
=>
CommandDef
((
cmd
)
=>
cmd
.
action
(
callback
,
prepend
));
// Command put config
function
PutCommandParam
<
T
extends
keyof
CommandPutConfigMap
>
(
type
:
T
,
data
?:
CommandPutConfigMap
[
T
],
):
ParameterDecorator
{
return
(
obj
,
key
:
string
,
index
)
=>
{
const
objClass
=
obj
.
constructor
;
const
list
:
CommandPutConfig
<
T
>
[]
=
Reflect
.
getMetadata
(
KoishiCommandPutDef
,
objClass
,
key
)
||
[];
list
[
index
]
=
GenerateMappingStruct
(
type
,
data
);
Reflect
.
defineMetadata
(
KoishiCommandPutDef
,
list
,
objClass
,
key
);
};
}
export
const
PutArgv
=
(
field
?:
keyof
Argv
)
=>
field
?
PutCommandParam
(
'
argvField
'
,
field
)
:
PutCommandParam
(
'
argv
'
);
export
const
PutSession
=
(
field
?:
keyof
Session
)
=>
field
?
PutCommandParam
(
'
sessionField
'
,
field
)
:
PutArgv
(
'
session
'
);
export
const
PutArg
=
(
i
:
number
)
=>
PutCommandParam
(
'
arg
'
,
i
);
export
const
PutArgs
=
()
=>
PutCommandParam
(
'
args
'
);
export
const
PutOption
=
(
name
:
string
,
desc
:
string
,
config
:
Argv
.
OptionConfig
=
{},
)
=>
PutCommandParam
(
'
option
'
,
{
name
,
desc
,
config
});
export
const
PutUser
=
(
field
:
FieldCollector
<
'
user
'
>
)
=>
PutCommandParam
(
'
user
'
,
field
);
export
const
PutChannel
=
(
field
:
FieldCollector
<
'
channel
'
>
)
=>
PutCommandParam
(
'
channel
'
,
field
);
export
const
PutUserName
=
(
useDatabase
=
true
)
=>
PutCommandParam
(
'
username
'
,
useDatabase
);
// Export all koishi-decorator decorators
export
const
PutUserId
=
()
=>
PutSession
(
'
userId
'
);
export
const
PutGuildId
=
()
=>
PutSession
(
'
guildId
'
);
export
const
PutGuildName
=
()
=>
PutSession
(
'
guildName
'
);
export
const
PutChannelId
=
()
=>
PutSession
(
'
channelId
'
);
export
const
PutChannelName
=
()
=>
PutSession
(
'
channelName
'
);
export
const
PutSelfId
=
()
=>
PutSession
(
'
selfId
'
);
export
const
PutBot
=
()
=>
PutSession
(
'
bot
'
);
export
const
PutNext
=
()
=>
PutArgv
(
'
next
'
);
export
*
from
'
koishi-decorators/dist/src/decorators
'
;
export
{
PluginDef
}
from
'
koishi-decorators
'
;
// Service
...
...
src/utility/koishi.interfaces.ts
View file @
e0d42ac3
import
{
ModuleMetadata
,
Provider
,
Type
}
from
'
@nestjs/common
'
;
import
{
App
,
Argv
,
Channel
,
Command
,
Context
,
EventMap
,
FieldCollector
,
Modules
,
Plugin
,
Selection
,
Session
,
User
,
}
from
'
koishi
'
;
import
{
App
,
Channel
,
Command
,
User
}
from
'
koishi
'
;
import
{
MetadataArrayMap
,
MetadataMap
}
from
'
./koishi.constants
'
;
export
interface
ContextSelector
{
select
?:
Selection
;
useSelector
?:
OnContextFunction
;
}
export
type
KoishiPluginOptions
<
T
extends
Plugin
>
=
boolean
|
Plugin
.
Config
<
T
>
;
export
interface
KoishiModulePluginExact
<
T
extends
Plugin
>
extends
ContextSelector
{
plugin
:
T
;
options
?:
boolean
|
KoishiPluginOptions
<
T
>
;
}
export
interface
KoishiModulePluginName
extends
ContextSelector
{
plugin
:
string
;
options
?:
any
;
}
export
type
KoishiModulePlugin
<
T
extends
Plugin
=
any
>
=
|
KoishiModulePluginExact
<
T
>
|
KoishiModulePluginName
;
export
function
PluginDef
(
name
:
string
,
options
?:
any
,
select
?:
Selection
);
export
function
PluginDef
<
T
extends
Plugin
>
(
plugin
:
T
,
options
?:
KoishiPluginOptions
<
T
>
,
select
?:
Selection
,
);
export
function
PluginDef
<
T
extends
Plugin
>
(
plugin
:
T
,
options
?:
KoishiPluginOptions
<
T
>
,
select
?:
Selection
,
):
KoishiModulePlugin
<
T
>
{
return
{
plugin
,
options
,
select
};
}
import
{
ContextSelector
,
PluginDefinition
}
from
'
koishi-decorators
'
;
export
interface
KoishiModuleSelection
extends
ContextSelector
{
module
:
Type
<
any
>
;
...
...
@@ -63,7 +15,7 @@ export interface KoishiModuleTopOptions {
export
interface
KoishiModuleOptions
extends
App
.
Config
,
KoishiModuleTopOptions
{
usePlugins
?:
KoishiModulePlugi
n
<
any
>
[];
usePlugins
?:
PluginDefinitio
n
<
any
>
[];
loggerPrefix
?:
string
;
loggerColor
?:
number
;
moduleSelection
?:
KoishiModuleSelection
[];
...
...
@@ -86,91 +38,6 @@ export interface KoishiModuleAsyncOptions
extraProviders
?:
Provider
[];
}
export
interface
CommonEventNameAndPrepend
<
T
extends
keyof
any
>
{
name
:
T
;
prepend
?:
boolean
;
}
export
type
EventName
=
keyof
EventMap
;
export
type
EventNameAndPrepend
=
CommonEventNameAndPrepend
<
EventName
>
;
type
OmitSubstring
<
S
extends
string
,
T
extends
string
,
>
=
S
extends
`
${
infer
L
}${
T
}${
infer
R
}
`
?
`
${
L
}${
R
}
`
:
never
;
export
type
BeforeEventName
=
OmitSubstring
<
EventName
&
string
,
'
before-
'
>
;
export
type
BeforeEventNameAndPrepend
=
CommonEventNameAndPrepend
<
BeforeEventName
>
;
export
type
ContextFunction
<
T
>
=
(
ctx
:
Context
)
=>
T
;
export
type
OnContextFunction
=
ContextFunction
<
Context
>
;
export
interface
DoRegisterConfigDataMap
{
middleware
:
boolean
;
// prepend
onevent
:
EventNameAndPrepend
;
beforeEvent
:
BeforeEventNameAndPrepend
;
plugin
:
never
;
command
:
CommandRegisterConfig
;
}
export
interface
MappingStruct
<
T
extends
Record
<
string
|
number
|
symbol
,
any
>
,
K
extends
keyof
T
,
>
{
type
:
K
;
data
?:
T
[
K
];
}
export
function
GenerateMappingStruct
<
T
extends
Record
<
string
|
number
|
symbol
,
any
>
,
K
extends
keyof
T
,
>
(
type
:
K
,
data
?:
T
[
K
]):
MappingStruct
<
T
,
K
>
{
return
{
type
,
data
,
};
}
export
type
DoRegisterConfig
<
K
extends
keyof
DoRegisterConfigDataMap
=
keyof
DoRegisterConfigDataMap
,
>
=
MappingStruct
<
DoRegisterConfigDataMap
,
K
>
;
// Command stuff
export
interface
CommandRegisterConfig
<
D
extends
string
=
string
>
{
def
:
D
;
desc
?:
string
;
config
?:
CommandConfigExtended
;
putOptions
?:
CommandPutConfig
<
keyof
CommandPutConfigMap
>
[];
}
export
interface
CommandConfigExtended
extends
Command
.
Config
{
empty
?:
boolean
;
}
export
interface
CommandOptionConfig
{
name
:
string
;
desc
:
string
;
config
?:
Argv
.
OptionConfig
;
}
export
interface
CommandPutConfigMap
{
args
:
never
;
arg
:
number
;
argv
:
never
;
argvField
:
keyof
Argv
;
option
:
CommandOptionConfig
;
user
:
FieldCollector
<
'
user
'
>
;
channel
:
FieldCollector
<
'
channel
'
>
;
username
:
boolean
;
sessionField
:
keyof
Session
;
}
export
type
CommandPutConfig
<
K
extends
keyof
CommandPutConfigMap
=
keyof
CommandPutConfigMap
,
>
=
MappingStruct
<
CommandPutConfigMap
,
K
>
;
export
type
CommandDefinitionFun
=
(
cmd
:
Command
)
=>
Command
;
// metadata map
export
type
MetadataArrayValueMap
=
{
[
K
in
keyof
MetadataArrayMap
]:
MetadataArrayMap
[
K
][];
...
...
src/utility/koishi.utility.ts
deleted
100644 → 0
View file @
714309db
import
{
Context
}
from
'
koishi
'
;
import
{
ContextSelector
}
from
'
./koishi.interfaces
'
;
export
function
applySelector
(
ctx
:
Context
,
selector
:
ContextSelector
,
):
Context
{
if
(
!
selector
)
{
return
ctx
;
}
let
targetCtx
=
ctx
;
if
(
selector
.
select
)
{
targetCtx
=
targetCtx
.
select
(
selector
.
select
);
}
if
(
selector
.
useSelector
)
{
targetCtx
=
selector
.
useSelector
(
targetCtx
)
||
targetCtx
;
}
return
targetCtx
;
}
tests/koishi-tests.spec.ts
View file @
e0d42ac3
import
{
Test
}
from
'
@nestjs/testing
'
;
import
{
KoishiModule
}
from
'
../src/koishi.module
'
;
import
{
KoishiService
}
from
'
../src/koishi.service
'
;
import
{
INestApplication
}
from
'
@nestjs/common
'
;
import
{
INestApplication
,
Injectable
}
from
'
@nestjs/common
'
;
import
{
KoishiWsAdapter
}
from
'
../src/koishi.ws-adapter
'
;
import
http
from
'
http
'
;
import
request
from
'
supertest
'
;
import
{
CommandUsage
,
OnGuild
,
OnPlatform
,
PutOption
,
UseCommand
,
}
from
'
koishi-decorators
'
;
import
{
Session
}
from
'
koishi
'
;
@
OnPlatform
(
'
discord
'
)
@
Injectable
()
class
KoishiTestService
{
@
OnGuild
(
'
1111111111
'
)
@
UseCommand
(
'
echo
'
,
'
hi
'
)
@
CommandUsage
(
'
foo
'
)
async
onEcho
(@
PutOption
(
'
content
'
,
'
-c <content:string>
'
)
content
:
string
)
{
return
`bot:
${
content
}
`
;
}
}
describe
(
'
HttpServer
'
,
()
=>
{
let
app
:
INestApplication
;
...
...
@@ -17,6 +36,7 @@ describe('HttpServer', () => {
useWs
:
true
,
}),
],
providers
:
[
KoishiTestService
],
}).
compile
();
app
=
moduleFixture
.
createNestApplication
();
app
.
useWebSocketAdapter
(
new
KoishiWsAdapter
(
app
));
...
...
@@ -37,6 +57,7 @@ describe('HttpServer', () => {
expect
(
koishiApp
.
_httpServer
).
toBeInstanceOf
(
http
.
Server
);
expect
(
app
.
getHttpServer
()).
toEqual
(
koishiApp
.
_httpServer
);
});
it
(
'
should response to koishi routes
'
,
()
=>
{
koishiApp
.
router
.
get
(
'
/ping
'
,
(
ctx
)
=>
{
ctx
.
status
=
233
;
...
...
@@ -44,4 +65,33 @@ describe('HttpServer', () => {
});
return
request
(
app
.
getHttpServer
()).
get
(
'
/ping
'
).
expect
(
233
).
expect
(
'
pong
'
);
});
it
(
'
should register command
'
,
()
=>
{
const
command
=
koishiApp
.
command
(
'
echo
'
);
expect
(
command
.
_usage
).
toBe
(
'
foo
'
);
expect
(
command
.
_options
.
content
.
name
).
toBe
(
'
content
'
);
expect
(
command
.
execute
({
options
:
{
content
:
'
hello
'
}
})).
resolves
.
toBe
(
'
bot: hello
'
,
);
const
correctSession
=
{
guildId
:
'
1111111111
'
,
platform
:
'
discord
'
,
}
as
Session
;
const
wrongSession1
=
{
guildId
:
'
2222222222
'
,
platform
:
'
discord
'
,
}
as
Session
;
const
wrongSession2
=
{
guildId
:
'
1111111111
'
,
platform
:
'
telegram
'
,
}
as
Session
;
const
methodCtx
=
command
.
context
;
expect
(
methodCtx
.
filter
(
correctSession
)).
toBe
(
true
);
expect
(
methodCtx
.
filter
(
wrongSession1
)).
toBe
(
false
);
expect
(
methodCtx
.
filter
(
wrongSession2
)).
toBe
(
false
);
});
});
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