File tree Expand file tree Collapse file tree 9 files changed +153
-0
lines changed Expand file tree Collapse file tree 9 files changed +153
-0
lines changed Original file line number Diff line number Diff line change
1
+ /node_modules
2
+ /build
Original file line number Diff line number Diff line change
1
+ {
2
+ "name" : " @modelsjs/resolver" ,
3
+ "version" : " 0.0.1" ,
4
+ "type" : " module" ,
5
+ "main" : " build/index.js" ,
6
+ "types" : " build/index.d.ts" ,
7
+ "scripts" : {
8
+ "build" : " tsc"
9
+ },
10
+ "dependencies" : {
11
+ "@modelsjs/model" : " ^0.0.1" ,
12
+ "@modelsjs/tsconfig" : " ^0.0.1" ,
13
+ "@modelsjs/types" : " ^0.0.1"
14
+ }
15
+ }
Original file line number Diff line number Diff line change
1
+ import { IStrategy } from './types' ;
2
+
3
+ const prop = < T > ( key : string , defaults ?: T ) => ( {
4
+ get ( ) : T {
5
+ if ( defaults ) {
6
+ return defaults ;
7
+ }
8
+
9
+ throw new Error ( `Key '${ key } ' is not configured.` ) ;
10
+ } ,
11
+
12
+ set ( value : T ) {
13
+ Object . defineProperty ( this , key , {
14
+ set ( ) {
15
+ throw new Error ( `Key '${ key } ' is already configured.` ) ;
16
+ } ,
17
+
18
+ get ( ) {
19
+ return value ;
20
+ }
21
+ } ) ;
22
+ }
23
+ } ) ;
24
+
25
+ export const config = Object . create ( null , {
26
+ defaultStrategy : prop < Nullable < IStrategy > > ( 'defaultStrategy' , null )
27
+ } ) ;
Original file line number Diff line number Diff line change
1
+ export type { IStrategy , TResolver } from './types' ;
2
+ export { config } from './config' ;
3
+ export { resolve } from './resolve' ;
4
+ export { resolvable } from './resolvable' ;
Original file line number Diff line number Diff line change
1
+ import type { Model } from '@modelsjs/model' ;
2
+ import type { IStrategy } from './types' ;
3
+ import { config } from './config' ;
4
+ import { ResolveStrategy } from './symbols' ;
5
+
6
+ type TStrategies = Record < symbol , IStrategy > ;
7
+
8
+ export interface IResolvable < M extends Model > {
9
+ [ prop : string ] : any ;
10
+
11
+ [ ResolveStrategy ] : TStrategies ;
12
+ }
13
+
14
+ export function resolvable < M extends Model > ( strategy : IStrategy ) : ClassDecorator
15
+ export function resolvable < M extends Model > ( target : ClassDescriptor ) : void
16
+ export function resolvable < M extends Model > ( target : any ) : any {
17
+ const strategy : IStrategy = isClassDescriptor ( target ) ? config . defaultStrategy : target ;
18
+
19
+ function decorator ( { elements} : ClassDescriptor ) {
20
+ elements . push ( {
21
+ kind : 'field' ,
22
+ placement : 'own' ,
23
+ key : strategy . kind ,
24
+ descriptor : { } ,
25
+ initializer : function ( ) {
26
+ return strategy ;
27
+ }
28
+ } as FieldDescriptor ) ;
29
+ }
30
+
31
+ return isClassDescriptor ( target ) ? decorator ( target ) : decorator ;
32
+ }
33
+
34
+ resolvable . get = < M extends Model > ( resolvable : Partial < IResolvable < M > > ) : TStrategies | null => {
35
+ return resolvable [ ResolveStrategy ] || null ;
36
+ }
37
+
38
+ function isClassDescriptor ( target : any ) : target is ClassDescriptor {
39
+ return target ?. kind === 'class' && Array . isArray ( target . elements ) ;
40
+ }
Original file line number Diff line number Diff line change
1
+ import type { Model } from '@modelsjs/model' ;
2
+ import type { TResolver , ISyncResolver } from './types' ;
3
+
4
+ export async function resolve ( models : Model [ ] , resolvers : TResolver [ ] ) {
5
+ let [ resolved , rest ] = [ [ ] as Model [ ] , models . slice ( ) ] ;
6
+ for ( const resolver of resolvers ) {
7
+ if ( ! rest . length ) {
8
+ return ;
9
+ }
10
+
11
+ if ( isSync ( resolver ) ) {
12
+ [ resolved , rest ] = resolver . sync ( models ) ;
13
+ } else {
14
+ [ resolved , rest ] = await resolver . async ( models ) ;
15
+ }
16
+ }
17
+ }
18
+
19
+ resolve . sync = ( models : Model [ ] , resolvers : TResolver [ ] ) => {
20
+ let [ resolved , rest ] = [ [ ] as Model [ ] , models . slice ( ) ] ;
21
+ for ( const resolver of resolvers ) {
22
+ if ( ! rest . length ) {
23
+ return ;
24
+ }
25
+
26
+ if ( isSync ( resolver ) ) {
27
+ [ resolved , rest ] = resolver . sync ( models ) ;
28
+ }
29
+ }
30
+ }
31
+
32
+ function isSync ( resolver : TResolver ) : resolver is ISyncResolver {
33
+ return 'sync' in resolver ;
34
+ }
Original file line number Diff line number Diff line change
1
+ export const ResolveStrategy = Symbol ( 'ResolveStrategy' ) ;
Original file line number Diff line number Diff line change
1
+ import type { Model } from '@modelsjs/model' ;
2
+
3
+ export type TDecorated < T > = T & {
4
+ [ prop : symbol ] : IStrategy
5
+ } ;
6
+
7
+ export interface ISyncResolver {
8
+ sync ( models : Model [ ] ) : [ Model [ ] , Model [ ] ] ;
9
+ }
10
+
11
+ export interface IAsyncResolver {
12
+ async ( models : Model [ ] ) : Promise < [ Model [ ] , Model [ ] ] > ;
13
+ }
14
+
15
+ export type TResolver = OneOf < ISyncResolver & IAsyncResolver > ;
16
+
17
+ export interface IStrategy {
18
+ kind : symbol ;
19
+ }
Original file line number Diff line number Diff line change
1
+ {
2
+ "extends" : " @modelsjs/tsconfig/tsconfig" ,
3
+ "compilerOptions" : {
4
+ "outDir" : " build"
5
+ },
6
+ "include" : [
7
+ " src" ,
8
+ " node_modules/@modelsjs/types" ,
9
+ " ../../node_modules/@modelsjs/types"
10
+ ]
11
+ }
You can’t perform that action at this time.
0 commit comments