Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
Schemastery Gen
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
Schemastery Gen
Commits
d27177d0
Commit
d27177d0
authored
May 03, 2022
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add mixin
parent
4b783ff2
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
207 additions
and
2 deletions
+207
-2
index.ts
index.ts
+1
-0
src/decorators/register.ts
src/decorators/register.ts
+2
-1
src/def/interfaces.ts
src/def/interfaces.ts
+25
-1
src/def/matrix.ts
src/def/matrix.ts
+51
-0
src/mixin.ts
src/mixin.ts
+60
-0
src/utility/utility.ts
src/utility/utility.ts
+1
-0
tests/mixin.spec.ts
tests/mixin.spec.ts
+67
-0
No files found.
index.ts
View file @
d27177d0
export
*
from
'
./src/def
'
;
export
*
from
'
./src/decorators
'
;
export
*
from
'
./src/mixin
'
;
src/decorators/register.ts
View file @
d27177d0
...
...
@@ -229,10 +229,11 @@ export function SchemaClass<T>(originalClass: ClassType<T>) {
}
as
unknown
as
ClassType
<
T
>
&
Schema
<
Partial
<
T
>
,
T
>
;
newClass
[
GeneratedSym
]
=
schema
;
newClass
[
OriginalClassSym
]
=
originalClass
;
newClass
.
prototype
=
Object
.
create
(
originalClass
.
prototype
);
Object
.
defineProperty
(
newClass
,
'
name
'
,
{
value
:
originalClass
.
name
,
});
Object
.
setPrototypeOf
(
newClass
,
originalClass
.
prototype
);
Object
.
setPrototypeOf
(
newClass
,
originalClass
);
for
(
const
field
of
schemaFields
)
{
Object
.
defineProperty
(
newClass
,
field
,
{
configurable
:
true
,
...
...
src/def/interfaces.ts
View file @
d27177d0
import
Schema
from
'
schemastery
'
;
import
Schema
,
{
never
,
number
}
from
'
schemastery
'
;
import
{
MatrixToUnionArray
,
MatrixTwist
}
from
'
./matrix
'
;
export
type
ClassType
<
T
>
=
{
new
(...
args
:
any
[]):
T
};
...
...
@@ -48,3 +49,26 @@ export type SchemaOptionsDict<T> = { [P in keyof T]?: SchemaOptions };
export
const
RefSym
=
Symbol
(
'
SchemasteryGenRef
'
);
export
const
GeneratedSym
=
Symbol
(
'
GeneratedSym
'
);
export
const
OriginalClassSym
=
Symbol
(
'
OriginalClassSym
'
);
type
UnionToIntersection
<
T
>
=
(
T
extends
any
?
(
x
:
T
)
=>
any
:
never
)
extends
(
x
:
infer
R
,
)
=>
any
?
R
:
never
;
type
ArrayToUnion
<
T
extends
any
[]
>
=
T
[
number
];
type
Intersecton
<
T
extends
any
[]
>
=
UnionToIntersection
<
ArrayToUnion
<
T
>>
;
export
type
AnyClass
=
{
new
(...
args
:
any
[]):
any
};
type
TypeOf
<
T
>
=
T
extends
{
new
(...
args
:
any
[]):
infer
R
}
?
R
:
never
;
type
ClassesToTypes
<
A
extends
any
[]
>
=
A
extends
[
infer
L
,
...
infer
R
]
?
[
TypeOf
<
L
>
,
...
ClassesToTypes
<
R
>
]
:
[];
/*type ClassesToParams<A extends any[]> = A extends [infer L, ...infer R]
? [
L extends new (...params: infer P) => any ? P : never,
...ClassesToParams<R>
]
: [];
*/
export
type
FusionClass
<
A
extends
AnyClass
[]
>
=
new
()
=>
//...args: MatrixToUnionArray<MatrixTwist<ClassesToParams<A>>>
Intersecton
<
ClassesToTypes
<
A
>>
;
src/def/matrix.ts
0 → 100644
View file @
d27177d0
import
{
never
}
from
'
schemastery
'
;
type
MatrixColumn
<
A
extends
any
[],
P
extends
any
[]
=
[]
>
=
A
extends
[
infer
L
,
...
infer
R
]
?
[
L
extends
[...
P
,
infer
E
,
...
any
[]]
?
E
:
never
,
...
MatrixColumn
<
R
,
P
>
]
:
[];
type
MatrixRow
<
A
extends
any
[],
P
extends
any
[]
=
[]
>
=
A
extends
[
...
P
,
infer
TargetRow
,
...
any
[]
]
?
TargetRow
:
[];
type
MapAny
<
A
extends
any
[]
>
=
A
extends
[
any
,
...
infer
R
]
?
[
any
,
...
MapAny
<
R
>
]
:
[];
type
IsLongerOrEqual
<
A
extends
any
[],
B
extends
any
[]
>
=
A
extends
[
...
MapAny
<
B
>
,
...
any
[]
]
?
true
:
false
;
type
ShouldFinish
<
A
extends
any
[],
P
extends
any
[],
CP
extends
any
[]
=
[],
>
=
IsLongerOrEqual
<
P
,
MatrixRow
<
A
,
CP
>>
extends
true
?
IsLongerOrEqual
<
CP
,
A
>
extends
true
?
true
:
ShouldFinish
<
A
,
P
,
[
any
,
...
CP
]
>
:
false
;
export
type
MatrixTwist
<
A
extends
any
[],
P
extends
any
[]
=
[]
>
=
ShouldFinish
<
A
,
P
>
extends
true
?
[]
:
[
MatrixColumn
<
A
,
P
>
,
...
MatrixTwist
<
A
,
[
any
,
...
P
]
>
];
export
type
MatrixToUnionArray
<
A
extends
any
[]
>
=
A
extends
[
infer
L
,
...
infer
R
]
?
[
L
extends
any
[]
?
L
[
number
]
:
never
,
...
MatrixToUnionArray
<
R
>
]
:
[];
src/mixin.ts
0 → 100644
View file @
d27177d0
import
{
AnyClass
,
FusionClass
,
OriginalClassSym
}
from
'
./def
'
;
import
{
reflector
}
from
'
./metadata/reflector
'
;
import
{
Metadata
}
from
'
./metadata/metadata
'
;
export
const
getOriginalClass
=
<
C
extends
new
(...
args
:
any
[])
=>
any
>
(
cls
:
C
,
):
C
=>
{
if
(
cls
[
OriginalClassSym
])
{
return
cls
[
OriginalClassSym
];
}
return
cls
;
};
function
applyMixin
(
mixedClass
:
AnyClass
,
sourceClass
:
AnyClass
,
// eslint-disable-next-line @typescript-eslint/ban-types
visited
=
new
Set
<
Function
>
(),
)
{
if
(
visited
.
has
(
sourceClass
))
{
return
;
}
visited
.
add
(
sourceClass
);
Object
.
getOwnPropertyNames
(
sourceClass
.
prototype
).
forEach
((
name
)
=>
{
if
(
!
mixedClass
.
prototype
[
name
])
{
mixedClass
.
prototype
[
name
]
=
sourceClass
.
prototype
[
name
];
}
});
const
schemaKeys
=
reflector
.
getArray
(
'
SchemaMetaKey
'
,
sourceClass
);
for
(
const
name
of
schemaKeys
)
{
const
schemaMeta
=
reflector
.
get
(
'
SchemaMeta
'
,
sourceClass
,
name
);
if
(
!
schemaMeta
)
{
continue
;
}
Metadata
.
set
(
'
SchemaMeta
'
,
schemaMeta
,
'
SchemaMetaKey
'
,
)(
mixedClass
.
prototype
,
name
);
const
transformerMeta
=
reflector
.
get
(
'
Transformer
'
,
sourceClass
,
name
);
if
(
transformerMeta
)
{
Metadata
.
set
(
'
Transformer
'
,
transformerMeta
)(
mixedClass
.
prototype
,
name
);
}
}
const
sourceParentClass
=
Object
.
getPrototypeOf
(
sourceClass
);
if
(
sourceParentClass
?.
prototype
)
{
applyMixin
(
sourceParentClass
,
sourceParentClass
,
visited
);
}
}
export
function
Mixin
<
A
extends
AnyClass
[]
>
(...
classes
:
A
):
FusionClass
<
A
>
;
// eslint-disable-next-line @typescript-eslint/ban-types
export
function
Mixin
<
A
extends
AnyClass
[]
>
(...
classes
:
A
):
Function
{
const
originalClasses
=
classes
.
map
(
getOriginalClass
);
const
mixedClass
=
class
MixedClass
{};
// eslint-disable-next-line @typescript-eslint/ban-types
const
visited
=
new
Set
<
Function
>
();
originalClasses
.
forEach
((
cls
)
=>
applyMixin
(
mixedClass
,
cls
,
visited
));
return
mixedClass
;
}
src/utility/utility.ts
View file @
d27177d0
import
Schema
from
'
schemastery
'
;
import
{
OriginalClassSym
}
from
'
../def
'
;
// eslint-disable-next-line @typescript-eslint/ban-types
export
function
getStringFromNativeType
(
nativeType
:
Function
)
{
...
...
tests/mixin.spec.ts
0 → 100644
View file @
d27177d0
import
{
RegisterSchema
,
SchemaProperty
}
from
'
../src/decorators
'
;
import
{
Mixin
}
from
'
../src/mixin
'
;
@
RegisterSchema
()
export
class
Sleeve
{
@
SchemaProperty
()
size
:
number
;
getSleeveSize
()
{
return
this
.
size
;
}
}
@
RegisterSchema
()
class
Dress
{
@
SchemaProperty
({
type
:
Sleeve
})
sleeves
:
Sleeve
[];
@
SchemaProperty
()
color
:
string
;
getColor
()
{
return
this
.
color
;
}
}
@
RegisterSchema
()
class
Shirt
{
@
SchemaProperty
()
size
:
string
;
pockets
=
3
;
getSize
()
{
return
this
.
size
;
}
}
@
RegisterSchema
()
class
Cloth
extends
Mixin
(
Dress
,
Shirt
)
{
constructor
(
data
:
any
)
{
super
();
}
@
SchemaProperty
()
material
:
string
;
getMaterial
()
{
return
this
.
material
;
}
}
describe
(
'
Schema registration
'
,
()
=>
{
it
(
'
should be instance
'
,
()
=>
{
const
cloth
=
new
Cloth
({
color
:
'
red
'
,
sleeves
:
[{
size
:
10
},
{
size
:
20
}],
size
:
'
M
'
,
material
:
'
cotton
'
,
});
expect
(
cloth
.
getColor
()).
toBe
(
'
red
'
);
expect
(
cloth
.
getSize
()).
toBe
(
'
M
'
);
expect
(
cloth
.
getMaterial
()).
toBe
(
'
cotton
'
);
expect
(
cloth
.
sleeves
[
0
].
getSleeveSize
()).
toBe
(
10
);
expect
(
cloth
.
sleeves
[
1
].
getSleeveSize
()).
toBe
(
20
);
});
});
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