Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
K
Koishi Thirdeye
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 Thirdeye
Commits
a13f8e41
Commit
a13f8e41
authored
Jan 21, 2022
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add UsingService
parent
4f828a42
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
166 additions
and
317 deletions
+166
-317
README.md
README.md
+2
-288
src/decorators.ts
src/decorators.ts
+17
-2
src/def/constants.ts
src/def/constants.ts
+2
-0
src/register.ts
src/register.ts
+37
-24
tests/caller.spec.ts
tests/caller.spec.ts
+39
-0
tests/service-activate.spec.ts
tests/service-activate.spec.ts
+69
-3
No files found.
README.md
View file @
a13f8e41
This diff is collapsed.
Click to expand it.
src/decorators.ts
View file @
a13f8e41
...
@@ -13,6 +13,7 @@ import {
...
@@ -13,6 +13,7 @@ import {
KoishiDoRegister
,
KoishiDoRegister
,
KoishiDoRegisterKeys
,
KoishiDoRegisterKeys
,
KoishiOnContextScope
,
KoishiOnContextScope
,
KoishiPartialUsing
,
KoishiRouteDef
,
KoishiRouteDef
,
KoishiServiceInjectSym
,
KoishiServiceInjectSym
,
KoishiServiceInjectSymKeys
,
KoishiServiceInjectSymKeys
,
...
@@ -313,7 +314,21 @@ export const InjectLogger = (name?: string) =>
...
@@ -313,7 +314,21 @@ export const InjectLogger = (name?: string) =>
);
);
export
const
Caller
=
()
=>
export
const
Caller
=
()
=>
InjectSystem
((
obj
)
=>
{
InjectSystem
((
obj
)
=>
{
const
ctx
=
obj
.
__ctx
;
const
targetCtx
:
Context
=
obj
[
Context
.
current
]
||
obj
.
__ctx
;
const
targetCtx
:
Context
=
ctx
[
Context
.
current
]
||
ctx
;
return
targetCtx
;
return
targetCtx
;
});
});
export
function
UsingService
(
...
services
:
(
keyof
Context
.
Services
)[]
):
ClassDecorator
&
MethodDecorator
{
return
(
obj
,
key
?)
=>
{
for
(
const
service
of
services
)
{
if
(
!
key
)
{
// fallback to KoishiAddUsingList
Metadata
.
appendUnique
(
KoishiAddUsingList
,
service
)(
obj
.
constructor
);
}
else
{
Metadata
.
appendUnique
(
KoishiPartialUsing
,
service
)(
obj
,
key
);
}
}
};
}
src/def/constants.ts
View file @
a13f8e41
...
@@ -20,6 +20,7 @@ export const KoishiServiceProvideSym = 'KoishiServiceProvideSym';
...
@@ -20,6 +20,7 @@ export const KoishiServiceProvideSym = 'KoishiServiceProvideSym';
export
const
KoishiSystemInjectSym
=
'
KoishiSystemInjectSym
'
;
export
const
KoishiSystemInjectSym
=
'
KoishiSystemInjectSym
'
;
export
const
KoishiSystemInjectSymKeys
=
'
KoishiSystemInjectSymKeys
'
;
export
const
KoishiSystemInjectSymKeys
=
'
KoishiSystemInjectSymKeys
'
;
export
const
KoishiAddUsingList
=
'
KoishiAddUsingList
'
;
export
const
KoishiAddUsingList
=
'
KoishiAddUsingList
'
;
export
const
KoishiPartialUsing
=
'
KoishiPartialUsing
'
;
// metadata map
// metadata map
...
@@ -31,6 +32,7 @@ export interface MetadataArrayMap {
...
@@ -31,6 +32,7 @@ export interface MetadataArrayMap {
KoishiServiceInjectSymKeys
:
string
;
KoishiServiceInjectSymKeys
:
string
;
KoishiSystemInjectSymKeys
:
string
;
KoishiSystemInjectSymKeys
:
string
;
KoishiAddUsingList
:
keyof
Context
.
Services
;
KoishiAddUsingList
:
keyof
Context
.
Services
;
KoishiPartialUsing
:
keyof
Context
.
Services
;
}
}
export
interface
MetadataMap
{
export
interface
MetadataMap
{
...
...
src/register.ts
View file @
a13f8e41
...
@@ -6,6 +6,7 @@ import {
...
@@ -6,6 +6,7 @@ import {
Schema
,
Schema
,
User
,
User
,
WebSocketLayer
,
WebSocketLayer
,
Plugin
,
}
from
'
koishi
'
;
}
from
'
koishi
'
;
import
{
import
{
CommandPutConfig
,
CommandPutConfig
,
...
@@ -16,6 +17,7 @@ import {
...
@@ -16,6 +17,7 @@ import {
KoishiDoRegisterKeys
,
KoishiDoRegisterKeys
,
KoishiModulePlugin
,
KoishiModulePlugin
,
KoishiOnContextScope
,
KoishiOnContextScope
,
KoishiPartialUsing
,
KoishiServiceInjectSym
,
KoishiServiceInjectSym
,
KoishiServiceInjectSymKeys
,
KoishiServiceInjectSymKeys
,
KoishiServiceProvideSym
,
KoishiServiceProvideSym
,
...
@@ -89,10 +91,8 @@ export function DefinePlugin<T = any>(
...
@@ -89,10 +91,8 @@ export function DefinePlugin<T = any>(
__wsLayers
:
WebSocketLayer
[];
__wsLayers
:
WebSocketLayer
[];
_handleSystemInjections
()
{
_handleSystemInjections
()
{
// console.log('Handling system injection');
const
injectKeys
=
reflector
.
getArray
(
KoishiSystemInjectSymKeys
,
this
);
const
injectKeys
=
reflector
.
getArray
(
KoishiSystemInjectSymKeys
,
this
);
for
(
const
key
of
injectKeys
)
{
for
(
const
key
of
injectKeys
)
{
// console.log(`Processing ${key}`);
const
valueFunction
=
reflector
.
get
(
KoishiSystemInjectSym
,
this
,
key
);
const
valueFunction
=
reflector
.
get
(
KoishiSystemInjectSym
,
this
,
key
);
Object
.
defineProperty
(
this
,
key
,
{
Object
.
defineProperty
(
this
,
key
,
{
configurable
:
true
,
configurable
:
true
,
...
@@ -103,10 +103,8 @@ export function DefinePlugin<T = any>(
...
@@ -103,10 +103,8 @@ export function DefinePlugin<T = any>(
}
}
_handleServiceInjections
()
{
_handleServiceInjections
()
{
// console.log('Handling service injection');
const
injectKeys
=
reflector
.
getArray
(
KoishiServiceInjectSymKeys
,
this
);
const
injectKeys
=
reflector
.
getArray
(
KoishiServiceInjectSymKeys
,
this
);
for
(
const
key
of
injectKeys
)
{
for
(
const
key
of
injectKeys
)
{
// console.log(`Processing ${key}`);
const
name
=
reflector
.
get
(
KoishiServiceInjectSym
,
this
,
key
);
const
name
=
reflector
.
get
(
KoishiServiceInjectSym
,
this
,
key
);
Object
.
defineProperty
(
this
,
key
,
{
Object
.
defineProperty
(
this
,
key
,
{
enumerable
:
true
,
enumerable
:
true
,
...
@@ -231,22 +229,13 @@ export function DefinePlugin<T = any>(
...
@@ -231,22 +229,13 @@ export function DefinePlugin<T = any>(
}
}
}
}
_registerDeclarationsFor
(
methodKey
:
keyof
C
&
string
)
{
_registerDeclarationsProcess
(
methodKey
:
keyof
C
&
string
,
ctx
:
Context
)
{
// console.log(`Handling declaration for ${methodKey}`);
const
regData
=
reflector
.
get
(
KoishiDoRegister
,
this
,
methodKey
);
const
regData
=
reflector
.
get
(
KoishiDoRegister
,
this
,
methodKey
);
if
(
!
regData
)
{
return
;
}
// console.log(`Type: ${regData.type}`);
const
baseContext
=
getContextFromFilters
(
this
.
__ctx
,
reflector
.
getArray
(
KoishiOnContextScope
,
this
,
methodKey
),
);
switch
(
regData
.
type
)
{
switch
(
regData
.
type
)
{
case
'
middleware
'
:
case
'
middleware
'
:
const
{
data
:
midPrepend
}
=
const
{
data
:
midPrepend
}
=
regData
as
DoRegisterConfig
<
'
middleware
'
>
;
regData
as
DoRegisterConfig
<
'
middleware
'
>
;
baseContext
.
middleware
(
ctx
.
middleware
(
(
session
,
next
)
=>
this
[
methodKey
](
session
,
next
),
(
session
,
next
)
=>
this
[
methodKey
](
session
,
next
),
midPrepend
,
midPrepend
,
);
);
...
@@ -254,7 +243,7 @@ export function DefinePlugin<T = any>(
...
@@ -254,7 +243,7 @@ export function DefinePlugin<T = any>(
case
'
onevent
'
:
case
'
onevent
'
:
const
{
data
:
eventData
}
=
regData
as
DoRegisterConfig
<
'
onevent
'
>
;
const
{
data
:
eventData
}
=
regData
as
DoRegisterConfig
<
'
onevent
'
>
;
const
eventName
=
eventData
.
name
;
const
eventName
=
eventData
.
name
;
baseContext
.
on
(
ctx
.
on
(
eventName
,
eventName
,
(...
args
:
any
[])
=>
this
[
methodKey
](...
args
),
(...
args
:
any
[])
=>
this
[
methodKey
](...
args
),
eventData
.
prepend
,
eventData
.
prepend
,
...
@@ -264,18 +253,18 @@ export function DefinePlugin<T = any>(
...
@@ -264,18 +253,18 @@ export function DefinePlugin<T = any>(
const
{
data
:
beforeEventData
}
=
const
{
data
:
beforeEventData
}
=
regData
as
DoRegisterConfig
<
'
beforeEvent
'
>
;
regData
as
DoRegisterConfig
<
'
beforeEvent
'
>
;
const
beforeEventName
=
beforeEventData
.
name
;
const
beforeEventName
=
beforeEventData
.
name
;
baseContext
.
before
(
ctx
.
before
(
beforeEventName
,
beforeEventName
,
(...
args
:
any
[])
=>
this
[
methodKey
](...
args
),
(...
args
:
any
[])
=>
this
[
methodKey
](...
args
),
beforeEventData
.
prepend
,
beforeEventData
.
prepend
,
);
);
case
'
plugin
'
:
case
'
plugin
'
:
this
.
_applyInnerPlugin
(
baseContext
,
methodKey
);
this
.
_applyInnerPlugin
(
ctx
,
methodKey
);
break
;
break
;
case
'
command
'
:
case
'
command
'
:
const
{
data
:
commandData
}
=
const
{
data
:
commandData
}
=
regData
as
DoRegisterConfig
<
'
command
'
>
;
regData
as
DoRegisterConfig
<
'
command
'
>
;
let
command
=
baseContext
.
command
(
let
command
=
ctx
.
command
(
commandData
.
def
,
commandData
.
def
,
commandData
.
desc
,
commandData
.
desc
,
commandData
.
config
,
commandData
.
config
,
...
@@ -312,13 +301,13 @@ export function DefinePlugin<T = any>(
...
@@ -312,13 +301,13 @@ export function DefinePlugin<T = any>(
const
realPath
=
routeData
.
path
.
startsWith
(
'
/
'
)
const
realPath
=
routeData
.
path
.
startsWith
(
'
/
'
)
?
routeData
.
path
?
routeData
.
path
:
`/
${
routeData
.
path
}
`
;
:
`/
${
routeData
.
path
}
`
;
baseContext
.
router
[
routeData
.
method
](
realPath
,
(
ctx
,
next
)
=>
ctx
.
router
[
routeData
.
method
](
realPath
,
(
ctx
,
next
)
=>
this
[
methodKey
](
ctx
,
next
),
this
[
methodKey
](
ctx
,
next
),
);
);
break
;
break
;
case
'
ws
'
:
case
'
ws
'
:
const
{
data
:
wsPath
}
=
regData
as
DoRegisterConfig
<
'
ws
'
>
;
const
{
data
:
wsPath
}
=
regData
as
DoRegisterConfig
<
'
ws
'
>
;
const
layer
=
baseContext
.
router
.
ws
(
wsPath
,
(
socket
,
req
)
=>
const
layer
=
ctx
.
router
.
ws
(
wsPath
,
(
socket
,
req
)
=>
this
[
methodKey
](
socket
,
req
),
this
[
methodKey
](
socket
,
req
),
);
);
this
.
__wsLayers
.
push
(
layer
);
this
.
__wsLayers
.
push
(
layer
);
...
@@ -328,19 +317,44 @@ export function DefinePlugin<T = any>(
...
@@ -328,19 +317,44 @@ export function DefinePlugin<T = any>(
}
}
}
}
_registerDeclarationsFor
(
methodKey
:
keyof
C
&
string
)
{
if
(
!
reflector
.
get
(
KoishiDoRegister
,
this
,
methodKey
))
{
return
;
}
const
ctx
=
getContextFromFilters
(
this
.
__ctx
,
reflector
.
getArray
(
KoishiOnContextScope
,
this
,
methodKey
),
);
const
partialUsing
=
reflector
.
getArray
(
KoishiPartialUsing
,
this
,
methodKey
,
);
if
(
partialUsing
.
length
)
{
const
name
=
`
${
options
.
name
||
originalClass
.
name
}
-
${
methodKey
}
`
;
const
innerPlugin
:
Plugin
.
Object
=
{
name
,
using
:
partialUsing
,
apply
:
(
innerCtx
)
=>
this
.
_registerDeclarationsProcess
(
methodKey
,
innerCtx
),
};
ctx
.
plugin
(
innerPlugin
);
}
else
{
this
.
_registerDeclarationsProcess
(
methodKey
,
ctx
);
}
}
_registerDeclarations
()
{
_registerDeclarations
()
{
const
methodKeys
=
reflector
.
getArray
(
const
methodKeys
=
reflector
.
getArray
(
KoishiDoRegisterKeys
,
KoishiDoRegisterKeys
,
this
,
this
,
)
as
(
keyof
C
&
string
)[];
)
as
(
keyof
C
&
string
)[];
// console.log(methodKeys);
methodKeys
.
forEach
((
methodKey
)
=>
methodKeys
.
forEach
((
methodKey
)
=>
this
.
_registerDeclarationsFor
(
methodKey
),
this
.
_registerDeclarationsFor
(
methodKey
),
);
);
}
}
_handleServiceProvide
(
immediate
:
boolean
)
{
_handleServiceProvide
(
immediate
:
boolean
)
{
// console.log(`Handling service provide`);
const
providingServices
=
[
const
providingServices
=
[
...
reflector
.
getArray
(
KoishiServiceProvideSym
,
originalClass
),
...
reflector
.
getArray
(
KoishiServiceProvideSym
,
originalClass
),
...
reflector
.
getArray
(
KoishiServiceProvideSym
,
this
),
...
reflector
.
getArray
(
KoishiServiceProvideSym
,
this
),
...
@@ -352,7 +366,6 @@ export function DefinePlugin<T = any>(
...
@@ -352,7 +366,6 @@ export function DefinePlugin<T = any>(
}
}
_registerAfterInit
()
{
_registerAfterInit
()
{
// console.log(`Handling after init.`);
this
.
__ctx
.
on
(
'
ready
'
,
async
()
=>
{
this
.
__ctx
.
on
(
'
ready
'
,
async
()
=>
{
if
(
typeof
this
.
onConnect
===
'
function
'
)
{
if
(
typeof
this
.
onConnect
===
'
function
'
)
{
await
this
.
onConnect
();
await
this
.
onConnect
();
...
...
tests/caller.spec.ts
0 → 100644
View file @
a13f8e41
import
{
DefinePlugin
}
from
'
../src/register
'
;
import
{
BasePlugin
}
from
'
../src/base-plugin
'
;
import
{
Caller
,
Provide
}
from
'
../src/decorators
'
;
import
{
App
}
from
'
koishi
'
;
declare
module
'
koishi
'
{
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace
Context
{
interface
Services
{
callerTester
:
CallerTester
;
}
}
}
@
Provide
(
'
callerTester
'
)
@
DefinePlugin
()
class
CallerTester
extends
BasePlugin
<
any
>
{
@
Caller
()
caller
:
string
;
}
describe
(
'
Caller
'
,
()
=>
{
let
app
:
App
;
beforeEach
(
async
()
=>
{
app
=
new
App
();
app
.
plugin
(
CallerTester
);
await
app
.
start
();
});
it
(
'
should put caller with correct values
'
,
async
()
=>
{
const
ctx1
=
app
.
any
();
const
ctx2
=
app
.
any
();
const
caller1
=
ctx1
.
callerTester
.
caller
;
const
caller2
=
ctx2
.
callerTester
.
caller
;
expect
(
caller1
).
toEqual
(
ctx1
);
expect
(
caller2
).
toEqual
(
ctx2
);
expect
(
app
.
callerTester
.
caller
).
toEqual
(
app
);
});
});
tests/service-activate.spec.ts
View file @
a13f8e41
import
{
App
,
Context
}
from
'
koishi
'
;
import
{
App
,
Context
}
from
'
koishi
'
;
import
{
DefinePlugin
}
from
'
../src/register
'
;
import
{
DefinePlugin
}
from
'
../src/register
'
;
import
{
Inject
,
Provide
,
UseEvent
}
from
'
../src/decorators
'
;
import
{
Inject
,
Provide
,
UseEvent
,
UsingService
}
from
'
../src/decorators
'
;
import
{
BasePlugin
}
from
'
../src/base-plugin
'
;
declare
module
'
koishi
'
{
declare
module
'
koishi
'
{
// eslint-disable-next-line @typescript-eslint/no-namespace
// eslint-disable-next-line @typescript-eslint/no-namespace
...
@@ -10,24 +11,39 @@ declare module 'koishi' {
...
@@ -10,24 +11,39 @@ declare module 'koishi' {
myEagerProvider
:
MyEagerProvider
;
myEagerProvider
:
MyEagerProvider
;
myConsumer
:
MyConsumer
;
myConsumer
:
MyConsumer
;
myUsingConsumer
:
MyUsingConsumer
;
myUsingConsumer
:
MyUsingConsumer
;
myPartialConsumer
:
MyPartialConsumer
;
dummyProvider
:
any
;
}
}
}
}
interface
EventMap
{
'
pang
'
(
message
:
string
):
Promise
<
string
>
;
'
pong
'
(
message
:
string
):
Promise
<
string
>
;
}
}
}
@
Provide
(
'
myProvider
'
)
@
Provide
(
'
myProvider
'
)
@
DefinePlugin
()
@
DefinePlugin
()
class
MyProvider
{
class
MyProvider
extends
BasePlugin
<
any
>
{
ping
()
{
ping
()
{
return
'
pong
'
;
return
'
pong
'
;
}
}
dispose
()
{
return
this
.
ctx
.
dispose
();
}
}
}
@
Provide
(
'
myEagerProvider
'
,
{
immediate
:
true
})
@
Provide
(
'
myEagerProvider
'
,
{
immediate
:
true
})
@
DefinePlugin
()
@
DefinePlugin
()
class
MyEagerProvider
{
class
MyEagerProvider
extends
BasePlugin
<
any
>
{
ping
()
{
ping
()
{
return
'
pong eager
'
;
return
'
pong eager
'
;
}
}
dispose
()
{
return
this
.
ctx
.
dispose
();
}
}
}
@
Provide
(
'
myConsumer
'
,
{
immediate
:
true
})
@
Provide
(
'
myConsumer
'
,
{
immediate
:
true
})
...
@@ -74,6 +90,32 @@ class MyUsingConsumer {
...
@@ -74,6 +90,32 @@ class MyUsingConsumer {
this
.
eagerPongResult
=
this
.
myEagerProvider
.
ping
();
this
.
eagerPongResult
=
this
.
myEagerProvider
.
ping
();
}
}
}
}
emitResult
:
string
;
}
@
Provide
(
'
myPartialConsumer
'
,
{
immediate
:
true
})
@
DefinePlugin
()
class
MyPartialConsumer
{
@
Inject
()
dummyProvider
:
number
;
pongResult
:
string
;
@
UsingService
(
'
dummyProvider
'
)
@
UseEvent
(
'
pang
'
)
async
onPang
(
content
:
string
)
{
const
msg
=
`pang:
${
content
}
`
;
console
.
log
(
msg
);
return
msg
;
}
@
UseEvent
(
'
pong
'
)
async
onPong
(
content
:
string
)
{
const
msg
=
`pong:
${
content
}
`
;
console
.
log
(
msg
);
return
msg
;
}
}
}
describe
(
'
On service
'
,
()
=>
{
describe
(
'
On service
'
,
()
=>
{
...
@@ -111,4 +153,28 @@ describe('On service', () => {
...
@@ -111,4 +153,28 @@ describe('On service', () => {
//expect(app.myUsingConsumer.eagerPongResult).toBe('pong eager');
//expect(app.myUsingConsumer.eagerPongResult).toBe('pong eager');
//expect(app.myUsingConsumer.pongResult).toBe('pong');
//expect(app.myUsingConsumer.pongResult).toBe('pong');
});
});
/*
it('Should handle partial using deps', async () => {
Context.service('dummyProvider');
app = new App();
app.on('service', (name) => {
console.log('service', name);
});
await app.start();
app.plugin(MyPartialConsumer);
expect(app.myPartialConsumer).toBeDefined();
expect(await app.waterfall('pang', 'hello')).toEqual('hello');
expect(await app.waterfall('pong', 'hello')).toEqual('pong: hello');
app.dummyProvider = { foo: 'bar' };
expect(await app.waterfall('pang', 'hello')).toEqual('pang: hello');
expect(await app.waterfall('pong', 'hello')).toEqual('pong: hello');
app.dummyProvider = undefined;
expect(await app.waterfall('pang', 'hi')).toEqual('hi');
expect(await app.waterfall('pong', 'hi')).toEqual('pong: hi');
app.dummyProvider = { foo: 'baz' };
expect(await app.waterfall('pang', 'hi')).toEqual('pang: hi');
expect(await app.waterfall('pong', 'hi')).toEqual('pong: hi');
});
*/
});
});
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