import type { NodePath } from '@babel/traverse' ; import traverse from '@babel/traverse' ; import * as t from '@babel/types' ; param node param parentPath export const getPathOfNode = < TNode extends unknown > ( node , parentPath ) : NodePath < TNode > => { let foundPath = null ; traverse ( t . expressionStatement ( node as any ) , { enter ( path ) { foundPath = path ; path . stop ( ) ; } , } , parentPath . scope , undefined , parentPath ) ; if ( ! foundPath ) { throw parentPath . buildCodeFrameError ( 'No path for a child node was found.' ) ; } return foundPath ; } ; param error param node param parentPath export const buildCodeFrameError = ( error , node , parentPath ) : Error => { if ( ! node ) { throw parentPath . buildCodeFrameError ( error ) ; } const startLoc = node . loc ? ` (${ node . loc . start . line }:${ node . loc . start . column })` : '' ; return getPathOfNode ( node , parentPath ) . buildCodeFrameError ( `${ error }${ startLoc }.` ) ; } ; param node export const getKey = ( node ) : string => { if ( t . isIdentifier ( node ) ) { return node . name ; } if ( t . isStringLiteral ( node ) ) { return node . value ; } throw new Error ( `${ node . type } has no name.'` ) ; } ; param node export const wrapNodeInIIFE = ( node ) : t . CallExpression => t . callExpression ( t . arrowFunctionExpression ( [ ] , node ) , [ ] ) ; const tryWrappingBlockStatementInIIFE = ( node ) => t . isBlockStatement ( node ) ? wrapNodeInIIFE ( node ) : node ; param node export const pickFunctionBody = ( node ) : t . Expression => tryWrappingBlockStatementInIIFE ( node . body ) ;