import * as path from "path" ; import * as fs from "fs" ; import { TelemetryHelper } from "./telemetryHelper" ; import { CordovaProjectHelper } from "./cordovaProjectHelper" ; import { findFileInFolderHierarchy } from "./extensionHelper" ; export class TsdHelper { private static CORDOVA_TYPINGS_FOLDERNAME = "CordovaTypings" ; private static CORDOVA_TYPINGS_PATH = findFileInFolderHierarchy ( __dirname , TsdHelper . CORDOVA_TYPINGS_FOLDERNAME ) ; private static USER_TYPINGS_FOLDERNAME = "typings" ; /**
     *   Helper to install type defintion files for Cordova plugins and Ionic projects.
     *   {typingsFolderPath} - the parent folder where the type definitions need to be installed
     *   {typeDefsPath} - the relative paths of all plugin type definitions that need to be
     *   installed (relative to <project_root>\.vscode\typings)
     */ public static installTypings ( typingsFolderPath , typeDefsPath , projectRoot ? ) { let installedTypeDefs = [ ] ; TelemetryHelper . generate ( "addTypings" , ( generator ) => { generator . add ( "addedTypeDefinitions" , typeDefsPath , false ) ; return Promise . all ( typeDefsPath . map ( ( relativePath ) => { let src = path . resolve ( TsdHelper . CORDOVA_TYPINGS_PATH , relativePath ) ; let dest = path . resolve ( typingsFolderPath , relativePath ) ; if ( CordovaProjectHelper . existsSync ( dest ) ) { return Promise . resolve ( void 0 ) ; } if ( projectRoot ) { let userTypingsShortPath = path . join ( projectRoot , TsdHelper . USER_TYPINGS_FOLDERNAME , path . basename ( relativePath ) ) ; let userTypingsLongPath = path . join ( projectRoot , TsdHelper . USER_TYPINGS_FOLDERNAME , relativePath ) ; if ( CordovaProjectHelper . existsSync ( userTypingsShortPath ) || CordovaProjectHelper . existsSync ( userTypingsLongPath ) ) { return Promise . resolve ( void 0 ) ; } } return TsdHelper . installTypeDefinitionFile ( src , dest ) . then ( ( ) => installedTypeDefs . push ( dest ) ) ; } ) ) ; } ) . finally ( ( ) => { if ( installedTypeDefs . length === 0 ) return ; let typingsFolder = path . resolve ( projectRoot , TsdHelper . USER_TYPINGS_FOLDERNAME ) ; let indexFile = path . resolve ( typingsFolder , "cordova-typings.d.ts" ) ; if ( ! CordovaProjectHelper . existsSync ( typingsFolder ) ) { CordovaProjectHelper . makeDirectoryRecursive ( typingsFolder ) ; } let references = CordovaProjectHelper . existsSync ( indexFile ) ? fs . readFileSync ( indexFile , "utf8" ) : "" ; let referencesToAdd = installedTypeDefs . filter ( typeDef => CordovaProjectHelper . existsSync ( typeDef ) ) . map ( typeDef => path . relative ( typingsFolder , typeDef ) ) . filter ( typeDef => references . indexOf ( typeDef ) < 0 ) . map ( typeDef => `/// <reference path="${ typeDef }"/>` ) ; if ( referencesToAdd . length === 0 ) return ; fs . writeFileSync ( indexFile , [ references ] . concat ( referencesToAdd ) . join ( "\n" ) ) ; } ) ; } public static removeTypings ( typingsFolderPath , typeDefsToRemove , projectRoot ) { if ( typeDefsToRemove . length === 0 ) return ; typeDefsToRemove . forEach ( typeDef => { fs . unlink ( path . resolve ( typingsFolderPath , typeDef ) , err => { if ( err ) console . error ( err ) ; } ) ; } ) ; let references = [ ] ; let indexFile = path . resolve ( projectRoot , TsdHelper . USER_TYPINGS_FOLDERNAME , "cordova-typings.d.ts" ) ; try { references = fs . readFileSync ( indexFile , "utf8" ) . split ( "\n" ) ; } catch ( e ) { return ; } let referencesToPersist = references . filter ( ref => ref && ! typeDefsToRemove . some ( typedef => ref . indexOf ( typedef ) >= 0 ) ) ; referencesToPersist . length === 0 ? fs . unlinkSync ( indexFile ) : fs . writeFileSync ( indexFile , referencesToPersist . join ( "\n" ) , "utf8" ) ; } private static installTypeDefinitionFile ( src , dest ) { let parentFolder = path . resolve ( dest , ".." ) ; if ( ! CordovaProjectHelper . existsSync ( parentFolder ) ) { CordovaProjectHelper . makeDirectoryRecursive ( parentFolder ) ; } return CordovaProjectHelper . copyFile ( src , dest ) ; } }