import * as path from 'path' ; import { BaseSourceMapTransformer , logger as vsCodeChromeDebugLogger , utils as vsCodeChromeDebugUtils } from 'vscode-chrome-debug-core' ; import * as sourceMapUtils from 'vscode-chrome-debug-core/out/src/sourceMaps/sourceMapUtils' ; import { NativeScriptDebugAdapter } from './nativeScriptDebugAdapter' ; export class NativeScriptSourceMapTransformer extends BaseSourceMapTransformer { private debugAdapter : NativeScriptDebugAdapter ; private targetPlatform : string ; constructor ( sourceHandles ) { super ( sourceHandles ) ; this . setupSourceMapPathOverrides ( ) ; } public setTransformOptions ( targetPlatform , debugAdapter ) { this . targetPlatform = targetPlatform . toLowerCase ( ) ; this . debugAdapter = debugAdapter ; } public async scriptParsed ( pathToGenerated , originalUrlToGenerated , sourceMapURL ) { const scriptParsedResult = await super . scriptParsed ( pathToGenerated , originalUrlToGenerated , sourceMapURL ) ; if ( scriptParsedResult && scriptParsedResult . length ) { for ( const script of scriptParsedResult ) { await this . debugAdapter . setCachedBreakpointsForScript ( script ) ; } } return scriptParsedResult ; } private setupSourceMapPathOverrides ( ) { sourceMapUtils . applySourceMapPathOverrides = ( sourcePath , sourceMapPathOverrides , isVSClient = false ) => { const forwardSlashSourcePath = sourcePath . replace ( /\\/g , '/' ) ; const sortedOverrideKeys = Object . keys ( sourceMapPathOverrides ) . sort ( ( a , b ) => b . length - a . length ) ; for ( const leftPattern of sortedOverrideKeys ) { const rightPattern = sourceMapPathOverrides [ leftPattern ] ; const entryStr = `"${ leftPattern }": "${ rightPattern }"` ; const asterisks = leftPattern . match ( /\*/g ) || [ ] ; if ( asterisks . length > 1 ) { vsCodeChromeDebugLogger . log ( `Warning: only one asterisk allowed in a sourceMapPathOverrides entry - ${ entryStr }` ) ; continue ; } const replacePatternAsterisks = rightPattern . match ( /\*/g ) || [ ] ; if ( replacePatternAsterisks . length > asterisks . length ) { vsCodeChromeDebugLogger . log ( `Warning: the right side of a sourceMapPathOverrides entry must have 0 or 1 asterisks - ${ entryStr }}` ) ; continue ; } const escapedLeftPattern = vsCodeChromeDebugUtils . escapeRegexSpecialChars ( leftPattern , '/*' ) ; const leftRegexSegment = escapedLeftPattern . replace ( /\*/g , '(.*)' ) . replace ( /\\\\/g , '/' ) ; const leftRegex = new RegExp ( `^${ leftRegexSegment }$` , 'i' ) ; const overridePatternMatches = forwardSlashSourcePath . match ( leftRegex ) ; if ( ! overridePatternMatches ) { continue ; } const wildcardValue = overridePatternMatches [ 1 ] ; let mappedPath = path . isAbsolute ( wildcardValue ) ? wildcardValue : rightPattern . replace ( /\*/g , wildcardValue ) ; mappedPath = path . join ( mappedPath ) ; const { dir , name , ext } = path . parse ( mappedPath ) ; const tnsFileName = `${ name }.tns${ ext }` ; const tnsPath = path . join ( dir , tnsFileName ) ; if ( vsCodeChromeDebugUtils . existsSync ( tnsPath ) ) { mappedPath = tnsPath ; } const platformFileName = `${ name }.${ this . targetPlatform }${ ext }` ; const platformPath = path . join ( dir , platformFileName ) ; if ( vsCodeChromeDebugUtils . existsSync ( platformPath ) ) { mappedPath = platformPath ; } if ( isVSClient && leftPattern === 'webpack:///./*' && ! vsCodeChromeDebugUtils . existsSync ( mappedPath ) ) { const pathFixingASPNETBug = path . join ( rightPattern . replace ( /\*/g , path . join ( '../ClientApp' , wildcardValue ) ) ) ; if ( vsCodeChromeDebugUtils . existsSync ( pathFixingASPNETBug ) ) { mappedPath = pathFixingASPNETBug ; } } vsCodeChromeDebugLogger . log ( `SourceMap: mapping ${ sourcePath } => ${ mappedPath }, via sourceMapPathOverrides entry - ${ entryStr }` ) ; return mappedPath ; } return sourcePath ; } ; } }