import isUrl from 'is-url' ; import 'isomorphic-fetch' ; import Target from './lib/Target' ; import Generator from './lib/Generator' ; import Publisher from './lib/Publisher' ; import ElementsLibrary from './lib/ElementsLibrary' ; import ElementsLibraryTargetMapping from './lib/ElementsLibraryTargetMapping' ; import transformers from './transformers' ; import { Mapping , LibraryDefinition } from './types' ; export default class Teleport { public libraries : { [ key ] : ElementsLibrary ; } = { } ; public mappings : { [ key ] : ElementsLibraryTargetMapping ; } = { } ; public targets : { [ key ] : Target ; } = { } ; public generators : { [ key ] : Generator ; } = { } ; public publishers : { [ key ] : Publisher ; } = { } ; public transformers : { [ key ] : object ; } = transformers ; public async readPluginDefinitionFromUrl ( url ) { try { const response = await fetch ( url ) ; if ( response . status !== 200 ) throw new Error ( `Could not download ${ url }: ${ response . statusText }` ) ; const data = await response . json ( ) ; if ( ! data ) throw new Error ( `Could not download ${ url }: EMPTY RESPONSE` ) ; return data ; } catch ( error ) { throw new Error ( error ) ; } } public async use ( plugin ) { switch ( typeof plugin ) { case 'string' : if ( isUrl ( plugin ) ) { this . usePlugin ( await this . readPluginDefinitionFromUrl ( plugin as string ) ) ; } else { throw new Error ( `\`${ plugin }\` is not an url` ) ; } break ; case 'object' : if ( Array . isArray ( plugin ) ) { for ( let i = 0 ; i < plugin . length ; i ++ ) { await this . use ( plugin [ i ] ) ; } } else { this . usePlugin ( plugin as object ) ; } break ; } return this ; } public usePlugin ( pluginData ) { switch ( ( pluginData as any ) . type ) { case 'library' : this . useLibrary ( pluginData as LibraryDefinition ) ; break ; case 'mapping' : this . useMapping ( pluginData as Mapping ) ; break ; case 'generator' : this . useGenerator ( pluginData as Generator ) ; break ; case 'publisher' : this . usePublisher ( pluginData as Publisher ) ; break ; default : throw new Error ( 'unrecognised plugin type:' + pluginData ) ; } } public useLibrary ( libraryDefinition ) { const library = new ElementsLibrary ( libraryDefinition ) ; this . libraries [ library . name ] = library ; return this ; } public library ( libraryName ) { if ( ! this . libraries [ libraryName ] ) throw new Error ( `Library ${ libraryName } has not been loaded` ) ; return this . libraries [ libraryName ] ; } public useMapping ( mappingData ) { const map = new ElementsLibraryTargetMapping ( mappingData , this ) ; this . mappings [ map . name ] = map ; if ( ! this . targets [ map . target as string ] ) { this . useTarget ( map . target as string ) ; } this . target ( map . target as string ) . useMapping ( map ) ; this . library ( map . library as string ) . useMapping ( map ) ; return this ; } public mapping ( mappingName ) { return this . mappings [ mappingName ] ; } public map ( targetName , source , type ) { const target = this . target ( targetName ) ; return target . map ( source , type ) ; } public useTarget ( targetName ) { if ( this . targets [ targetName ] ) throw new Error ( `Target ${ targetName } is already registered` ) ; this . targets [ targetName ] = new Target ( targetName ) ; return this ; } public target ( targetName ) { if ( ! this . targets [ targetName ] ) throw new Error ( `No target named '${ targetName }' exists.Did you register a mapping or a generator for this target?` ) ; return this . targets [ targetName ] ; } public useGenerator ( generator ) { if ( ! this . targets [ generator . targetName ] ) { this . useTarget ( generator . targetName ) ; } const target = this . target ( generator . targetName ) ; generator . setTarget ( target ) ; target . setGenerator ( generator ) ; this . generators [ generator . name ] = generator ; return this ; } public generator ( generatorName ) { return this . generators [ generatorName ] ; } public usePublisher ( publisher ) { this . publishers [ publisher . name ] = publisher ; return this ; } public publisher ( publisherName ) { return this . publishers [ publisherName ] ; } }