import { Injectable } from '@angular/core' ; export interface DirectoryEntry { filesystem : any ; fullpath : string ; isDirectory : boolean ; isFile : boolean ; name : string ; createReader ( ) ; } export interface FileEntry { filesystem : any ; fullpath : string ; isDirectory : boolean ; isFile : boolean ; name : string ; file ( successCallBack , errorCallBack ) ; } @ Injectable ( { providedIn : 'root' } ) export class ImportService { async import ( dataTransfer ) { const entry = await new Promise ( resolve => setTimeout ( resolve , 0 , this . validate ( dataTransfer ) ) ) ; const entries = await new Promise ( resolve => setTimeout ( resolve , 0 , this . parseDirectoryEntry ( entry ) ) ) ; return await new Promise ( resolve => setTimeout ( resolve , 0 , this . getAngularConfig ( entries , entry ) ) ) ; } param dataTransfer validate ( dataTransfer ) { return new Promise ( ( resolve , reject ) => { if ( dataTransfer . items . length > 0 ) { let entry = dataTransfer . items [ 0 ] . webkitGetAsEntry ( ) ; console . log ( 'directory entry webkitGetAsEntry' , entry ) ; if ( ! entry ) { /**
                     * References:-
                     * 1) https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/webkitGetAsEntry
                     * 2) https://github.com/froala/wysiwyg-editor/issues/1457
                     */ entry = ( dataTransfer . items [ 0 ] as any ) . getAsEntry ( ) ; console . log ( 'directory entry getAsEntry' , entry ) ; } if ( entry && entry . isDirectory ) { resolve ( entry ) ; } else { reject ( 'Dropped object must be a directory' ) ; } } else { reject ( 'Data transfer item is empty' ) ; } } ) ; } param directoryData parseDirectoryEntry ( directoryData ) { const directoryReader = directoryData . createReader ( ) ; return new Promise ( ( resolve , reject ) => { directoryReader . readEntries ( ( entries ) => { resolve ( entries ) ; } , err => { reject ( err ) ; } ) ; } ) ; } param directoryData param entry param configData getData ( directoryData , entry , configData ) { return { directory : entry . name , 'skip-git' : this . getSkipGitFlag ( directoryData ) , 'app-name' : this . getAppName ( configData ) , prefix : this . getPrefix ( configData ) , 'inline-style' : this . getInlineStyle ( configData ) , 'inline-template' : this . getInlineTemplate ( configData ) , 'skip-tests' : this . getSkipTestsFlag ( configData ) , style : this . getStyle ( configData ) , 'skip-install' : this . getSkipInstall ( directoryData ) , 'routing' : this . getRoutingFlag ( directoryData ) } ; } async getRoutingFlag ( directoryData ) { const srcDirectory = directoryData . filter ( ( entry ) => entry . isDirectory && entry . name === 'src' ) ; if ( srcDirectory . length === 1 ) { const srcEntries = await new Promise ( ( resolve ) => setTimeout ( resolve , 0 , this . parseDirectoryEntry ( srcDirectory [ 0 ] ) ) ) ; const appDirectory = srcEntries . filter ( ( entry ) => ( entry . isDirectory ) && entry . name === 'app' ) ; if ( appDirectory . length === 1 ) { const appEntries = await new Promise ( ( resolve ) => setTimeout ( resolve , 0 , this . parseDirectoryEntry ( appDirectory [ 0 ] ) ) ) ; return ( appEntries . filter ( ( entry ) => entry . name . lastIndexOf ( 'routing.module.ts' ) > - 1 ) . length === 1 ) ; } } return false ; } getSkipInstall ( directoryData ) { return directoryData . filter ( ( entry ) => ( entry . isDirectory && entry . name === 'node_modules' ) ) . length === 0 ; } param configData getStyle ( configData ) { const schematics = configData [ configData . newProjectRoot ] [ configData . defaultProject ] [ 'schematics' ] ; return schematics [ '@schematics/angular:component' ] ? schematics [ '@schematics/angular:component' ] [ 'styleext' ] : '' ; } param configData getSkipTestsFlag ( configData ) { const schematics = configData [ configData . newProjectRoot ] [ configData . defaultProject ] [ 'schematics' ] ; return schematics [ '@schematics/angular:component' ] ? ! schematics [ '@schematics/angular:component' ] [ 'spec' ] : false ; } param configData getInlineTemplate ( configData ) { const schematics = configData [ configData . newProjectRoot ] [ configData . defaultProject ] [ 'schematics' ] ; return schematics [ '@schematics/angular:component' ] ? schematics [ '@schematics/angular:component' ] [ 'inlineTemplate' ] : false ; } param configData getInlineStyle ( configData ) { const schematics = configData [ configData . newProjectRoot ] [ configData . defaultProject ] [ 'schematics' ] ; return schematics [ '@schematics/angular:component' ] ? schematics [ '@schematics/angular:component' ] [ 'inlineStyle' ] : false ; } param configData getAppName ( configData ) { return configData . defaultProject ; } param entries getSkipGitFlag ( entries ) { return entries . filter ( ( entry ) => ( entry . isDirectory && entry . name === '.git' ) ) . length === 0 ; } param configData getPrefix ( configData ) { const projectRoot = configData . newProjectRoot ; return ( configData [ projectRoot ] && configData [ projectRoot ] [ configData . defaultProject ] ) ? configData [ projectRoot ] [ configData . defaultProject ] . prefix : '' ; } param directoryData param directoryEntry getAngularConfig ( directoryData , directoryEntry ) { return new Promise ( ( resolve , reject ) => { const angularConfig = directoryData . filter ( ( entry ) => ( entry . isFile && entry . name === 'angular.json' ) ) ; if ( angularConfig . length === 1 ) { angularConfig [ 0 ] . file ( file => { const render = new FileReader ( ) ; render . onloadend = e => { const target = < FileReader > e . currentTarget ; resolve ( this . getData ( directoryData , directoryEntry , JSON . parse ( < string > target . result ) ) ) ; } ; render . readAsText ( file ) ; } , error => { reject ( error ) ; } ) ; } else { reject ( 'angular.json missing' ) ; } } ) ; } }