import { RawResolversConfig , ParsedResolversConfig } from './base-resolvers-visitor' ; import { DirectiveArgumentAndInputFieldMappings , ParsedDirectiveArgumentAndInputFieldMappings } from './types' ; export type ParsedMapper = InternalParsedMapper | ExternalParsedMapper ; export interface InternalParsedMapper { isExternal : false ; type : string ; } export interface ExternalParsedMapper { isExternal : true ; type : string ; import : string ; source : string ; default : boolean ; } export function isExternalMapperType ( m ) { return ! ! ( m as ExternalParsedMapper ) . import ; } enum MapperKind { Namespace , Default , Regular } interface Helpers { items : string [ ] ; isNamespace : boolean ; isDefault : boolean ; hasAlias : boolean ; } function prepareLegacy ( mapper ) { const items = mapper . split ( '#' ) ; const isNamespace = items . length === 3 ; const isDefault = items [ 1 ] . trim ( ) === 'default' || items [ 1 ] . startsWith ( 'default ' ) ; const hasAlias = items [ 1 ] . includes ( ' as ' ) ; return { items , isDefault , isNamespace , hasAlias , } ; } function prepare ( mapper ) { const [ source , path ] = mapper . split ( '#' ) ; const isNamespace = path . includes ( '.' ) ; const isDefault = path . trim ( ) === 'default' || path . startsWith ( 'default ' ) ; const hasAlias = path . includes ( ' as ' ) ; return { items : isNamespace ? [ source , ... path . split ( '.' ) ] : [ source , path ] , isDefault , isNamespace , hasAlias , } ; } function isLegacyMode ( mapper ) { return mapper . split ( '#' ) . length === 3 ; } export function parseMapper ( mapper , gqlTypeName = null , suffix ? ) { if ( isExternalMapper ( mapper ) ) { const { isNamespace , isDefault , hasAlias , items } = isLegacyMode ( mapper ) ? prepareLegacy ( mapper ) : prepare ( mapper ) ; const mapperKind = isNamespace ? MapperKind . Namespace : isDefault ? MapperKind . Default : MapperKind . Regular ; function handleAlias ( isDefault = false ) { const [ importedType , aliasType ] = items [ 1 ] . split ( /\s+as\s+/ ) ; const type = maybeSuffix ( aliasType ) ; return { importElement : isDefault ? type : `${ importedType } as ${ type }` , type : type , } ; } function maybeSuffix ( type ) { if ( suffix ) { return addSuffix ( type , suffix ) ; } return type ; } function handle ( ) { switch ( mapperKind ) { case MapperKind . Namespace : { const [ , ns , identifier ] = items ; return { type : `${ ns }.${ identifier }` , importElement : ns , } ; } case MapperKind . Default : { if ( hasAlias ) { return handleAlias ( true ) ; } const type = maybeSuffix ( `${ gqlTypeName }` ) ; return { importElement : type , type , } ; } case MapperKind . Regular : { if ( hasAlias ) { return handleAlias ( ) ; } const identifier = items [ 1 ] ; const type = maybeSuffix ( identifier ) ; return { type , importElement : suffix ? `${ identifier } as ${ type }` : type , } ; } } } const { type , importElement } = handle ( ) ; return { default : isDefault , isExternal : true , source : items [ 0 ] , type , import : importElement . replace ( /<(.*?)>/g , '' ) , } ; } return { isExternal : false , type : mapper , } ; } function addSuffix ( element , suffix ) { const generic = element . indexOf ( '<' ) ; if ( generic === - 1 ) { return `${ element }${ suffix }` ; } return `${ element . slice ( 0 , generic ) }${ suffix }${ element . slice ( generic ) }` ; } export function isExternalMapper ( value ) { return value . includes ( '#' ) ; } export function transformMappers ( rawMappers , mapperTypeSuffix ? ) { const result = { } ; Object . keys ( rawMappers ) . forEach ( gqlTypeName => { const mapperDef = rawMappers [ gqlTypeName ] ; const parsedMapper = parseMapper ( mapperDef , gqlTypeName , mapperTypeSuffix ) ; result [ gqlTypeName ] = parsedMapper ; } ) ; return result ; } export function transformDirectiveArgumentAndInputFieldMappings ( rawDirectiveArgumentAndInputFieldMappings , directiveArgumentAndInputFieldMappingTypeSuffix ? ) { const result = { } ; Object . keys ( rawDirectiveArgumentAndInputFieldMappings ) . forEach ( directive => { const mapperDef = rawDirectiveArgumentAndInputFieldMappings [ directive ] ; const parsedMapper = parseMapper ( mapperDef , directive , directiveArgumentAndInputFieldMappingTypeSuffix ) ; result [ directive ] = parsedMapper ; } ) ; return result ; } export function buildMapperImport ( source , types , useTypeImports ) { if ( ! types || types . length === 0 ) { return null ; } const defaultType = types . find ( t => t . asDefault === true ) ; let namedTypes = types . filter ( t => ! t . asDefault ) ; if ( useTypeImports ) { if ( defaultType ) { namedTypes = [ { identifier : `default as ${ defaultType . identifier }` } , ... namedTypes ] ; } const namedImports = namedTypes . length ? `{ ${ namedTypes . map ( t => t . identifier ) . join ( ', ' ) } }` : '' ; return `import type ${ [ namedImports ] . filter ( Boolean ) . join ( ', ' ) } from '${ source }';` ; } const namedImports = namedTypes . length ? `{ ${ namedTypes . map ( t => t . identifier ) . join ( ', ' ) } }` : '' ; const defaultImport = defaultType ? defaultType . identifier : '' ; return `import ${ [ defaultImport , namedImports ] . filter ( Boolean ) . join ( ', ' ) } from '${ source }';` ; }