Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
K
koishi-entities
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-entities
Commits
16765d8c
Commit
16765d8c
authored
Mar 29, 2022
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add field mixin
parent
6746196e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
27 deletions
+98
-27
src/register.ts
src/register.ts
+22
-1
tests/user-mixin.spec.ts
tests/user-mixin.spec.ts
+76
-26
No files found.
src/register.ts
View file @
16765d8c
import
{
Context
,
Keys
,
Model
}
from
'
koishi
'
;
import
{
Context
,
Dict
,
Flatten
,
Keys
,
Model
,
Tables
}
from
'
koishi
'
;
import
{
ModelClassType
}
from
'
./def
'
;
import
{
reflector
}
from
'
./meta/meta
'
;
import
_
from
'
lodash
'
;
class
ModelRegistrar
<
T
=
any
>
{
constructor
(
private
cls
:
ModelClassType
<
T
>
,
private
prefix
=
''
)
{}
...
...
@@ -170,3 +171,23 @@ export function registerModel(
ctx
.
model
.
extend
(
tableName
,
...
registrar
.
getModelResult
());
Object
.
assign
(
ctx
.
model
.
config
[
tableName
].
internal
,
registrar
.
getInternal
());
}
export
function
mixinModel
<
K
extends
Keys
<
Tables
>>
(
ctx
:
Context
,
tableName
:
K
,
classDict
:
{
[
F
in
Keys
<
Tables
[
K
]
>
]?:
ModelClassType
<
Flatten
<
Tables
[
K
][
F
]
>>
;
},
)
{
for
(
const
_key
in
classDict
)
{
const
key
=
_key
as
Keys
<
Tables
[
K
]
>
;
const
cls
=
classDict
[
key
];
const
registrar
=
new
ModelRegistrar
<
any
>
(
cls
,
key
+
'
.
'
);
const
result
=
registrar
.
getModelResult
();
ctx
.
model
.
extend
(
tableName
,
...
result
);
Object
.
assign
(
ctx
.
model
.
config
[
tableName
].
internal
,
registrar
.
getInternal
(),
);
}
}
tests/user-mixin.spec.ts
View file @
16765d8c
import
{
ChildModel
,
DefineModel
,
ModelField
}
from
'
../src/decorators
'
;
import
{
App
}
from
'
koishi
'
;
import
{
registerModel
}
from
'
../src/register
'
;
import
{
mixinModel
,
registerModel
}
from
'
../src/register
'
;
import
MemoryDatabase
from
'
@koishijs/plugin-database-memory
'
;
import
exp
from
'
constants
'
;
declare
module
'
koishi
'
{
// eslint-disable-next-line @typescript-eslint/no-empty-interface
...
...
@@ -11,30 +12,38 @@ declare module 'koishi' {
}
}
class
Dress
{
class
WearingPreference
{
@
ModelField
(
'
string(8)
'
)
color
:
string
;
@
ModelField
(
'
integer(7)
'
)
size
:
string
;
@
ModelField
(
'
string(12)
'
)
shape
:
string
;
format
()
{
return
`
${
this
.
color
}
${
this
.
shape
}
`
;
}
}
class
Shirt
{
@
ModelField
(
'
string(8)
'
)
color
:
string
;
@
ModelField
(
'
integer(7)
'
)
class
Wearing
{
@
ModelField
(
'
string(3)
'
)
size
:
string
;
}
@
DefineModel
(
'
user
'
)
class
UserMixin1
{
getSize
()
{
return
this
.
size
;
}
@
ChildModel
()
dress
:
Dress
;
preference
:
WearingPreference
;
}
@
DefineModel
(
'
user
'
)
class
UserMixin2
{
@
ChildModel
()
shirt
:
Shirt
;
class
Dress
extends
Wearing
{
getDressSize
()
{
return
this
.
getSize
();
}
}
class
Shirt
extends
Wearing
{
getShirtSize
()
{
return
this
.
getSize
();
}
}
describe
(
'
Model test
'
,
()
=>
{
...
...
@@ -43,22 +52,63 @@ describe('Model test', () => {
beforeEach
(
async
()
=>
{
app
=
new
App
();
app
.
plugin
(
MemoryDatabase
);
mixinModel
(
app
,
'
user
'
,
{
dress
:
Dress
,
shirt
:
Shirt
});
await
app
.
start
();
});
it
(
'
should register model fields
'
,
()
=>
{
registerModel
(
app
,
UserMixin1
);
registerModel
(
app
,
UserMixin2
);
const
{
user
}
=
app
.
model
.
config
;
expect
(
user
.
fields
[
'
dress.color
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
dress.size
'
].
type
).
toBe
(
'
integer
'
);
expect
(
user
.
fields
[
'
dress.color
'
].
length
).
toBe
(
8
);
expect
(
user
.
fields
[
'
dress.size
'
].
length
).
toBe
(
7
);
expect
(
user
.
fields
[
'
shirt.color
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
shirt.size
'
].
type
).
toBe
(
'
integer
'
);
expect
(
user
.
fields
[
'
shirt.color
'
].
length
).
toBe
(
8
);
expect
(
user
.
fields
[
'
shirt.size
'
].
length
).
toBe
(
7
);
expect
(
user
.
fields
[
'
dress.size
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
dress.size
'
].
length
).
toBe
(
3
);
expect
(
user
.
fields
[
'
shirt.size
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
shirt.size
'
].
length
).
toBe
(
3
);
expect
(
user
.
fields
[
'
dress.preference.color
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
dress.preference.color
'
].
length
).
toBe
(
8
);
expect
(
user
.
fields
[
'
shirt.preference.color
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
shirt.preference.color
'
].
length
).
toBe
(
8
);
expect
(
user
.
fields
[
'
dress.preference.shape
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
dress.preference.shape
'
].
length
).
toBe
(
12
);
expect
(
user
.
fields
[
'
shirt.preference.shape
'
].
type
).
toBe
(
'
string
'
);
expect
(
user
.
fields
[
'
shirt.preference.shape
'
].
length
).
toBe
(
12
);
expect
(
user
.
internal
[
'
dress.
'
]).
toEqual
(
Dress
.
prototype
);
expect
(
user
.
internal
[
'
shirt.
'
]).
toEqual
(
Shirt
.
prototype
);
expect
(
user
.
internal
[
'
dress.preference.
'
]).
toEqual
(
WearingPreference
.
prototype
,
);
expect
(
user
.
internal
[
'
shirt.preference.
'
]).
toEqual
(
WearingPreference
.
prototype
,
);
});
it
(
'
should make class instance
'
,
async
()
=>
{
await
app
.
database
.
upsert
(
'
user
'
,
[
{
id
:
'
111111
'
,
dress
:
{
size
:
'
S
'
,
preference
:
{
color
:
'
red
'
,
shape
:
'
round
'
,
},
},
shirt
:
{
size
:
'
M
'
,
preference
:
{
color
:
'
blue
'
,
shape
:
'
square
'
,
},
},
},
]);
const
[
user
]
=
await
app
.
database
.
get
(
'
user
'
,
{
id
:
'
111111
'
});
expect
(
user
.
dress
).
toBeInstanceOf
(
Dress
);
expect
(
user
.
dress
.
getDressSize
()).
toBe
(
'
S
'
);
expect
(
user
.
dress
.
preference
).
toBeInstanceOf
(
WearingPreference
);
expect
(
user
.
dress
.
preference
.
format
()).
toBe
(
'
red round
'
);
expect
(
user
.
shirt
).
toBeInstanceOf
(
Shirt
);
expect
(
user
.
shirt
.
getShirtSize
()).
toBe
(
'
M
'
);
expect
(
user
.
shirt
.
preference
).
toBeInstanceOf
(
WearingPreference
);
expect
(
user
.
shirt
.
preference
.
format
()).
toBe
(
'
blue square
'
);
});
});
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