/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import path from 'path' ; import StackFrame from './stack-frame' ; import { getSourceMap } from './getSourceMap' ; import { getLinesAround } from './getLinesAround' ; function count ( search , string ) { let count = - 1 , index = - 1 ; do { ++ count ; index = string . indexOf ( search , index + 1 ) ; } while ( index !== - 1 ) ; return count ; } param { string } fileUri param { StackFrame [ ] } frames param { number } fileContents async function unmap ( _fileUri , frames , contextLines = 3 ) { let fileContents = typeof _fileUri === 'object' ? _fileUri . contents : null ; const fileUri = typeof _fileUri === 'object' ? _fileUri . uri : _fileUri ; if ( fileContents == null ) { fileContents = await fetch ( fileUri ) . then ( ( res ) => res . text ( ) ) ; } const map = await getSourceMap ( fileUri , fileContents ! ) ; return frames . map ( ( frame ) => { const { functionName , lineNumber , columnNumber , _originalLineNumber } = frame ; if ( _originalLineNumber != null ) { return frame ; } let { fileName } = frame ; if ( fileName ) { fileName = path . normalize ( fileName . replace ( /[\\]+/g , '/' ) ) ; } if ( fileName == null ) { return frame ; } const fN = fileName ; const source = map . getSources ( ) . map ( ( s ) => s . replace ( /[\\]+/g , '/' ) ) . filter ( ( p ) => { p = path . normalize ( p ) ; const i = p . lastIndexOf ( fN ) ; return i !== - 1 && i === p . length - fN . length ; } ) . map ( ( p ) => ( { token : p , seps : count ( path . sep , path . normalize ( p ) ) , penalties : count ( 'node_modules' , p ) + count ( '~' , p ) , } ) ) . sort ( ( a , b ) => { const s = Math . sign ( a . seps - b . seps ) ; if ( s !== 0 ) { return s ; } return Math . sign ( a . penalties - b . penalties ) ; } ) ; if ( source . length < 1 || lineNumber == null ) { return new StackFrame ( null , null , null , null , null , functionName , fN , lineNumber , columnNumber , null ) ; } const sourceT = source [ 0 ] . token ; const { line , column } = map . getGeneratedPosition ( sourceT , lineNumber , columnNumber ! ) ; const originalSource = map . getSource ( sourceT ) ; return new StackFrame ( functionName , fileUri , line , column || null , getLinesAround ( line ! , contextLines , fileContents || [ ] ) , functionName , fN , lineNumber , columnNumber , getLinesAround ( lineNumber , contextLines , originalSource ! ) ) ; } ) ; } export { unmap } ; export default unmap ;