import path from 'path' ; import { selectAll } from 'unist-util-select' ; import { defaults , isString , find } from 'lodash' ; import cheerio from 'cheerio' ; import { slash } from './utils' ; export type GatsbyNodePluginArgs = { files : GatsbyFile [ ] ; markdownNode : MarkdownNode ; markdownAST : any ; reporter : { info : ( msg : string , error ? : Error ) => void ; } ; } ; export type GatsbyFile = { absolutePath : string ; } ; export type PluginOptions = { staticFolderName : string ; include : string [ ] ; exclude : string [ ] ; } ; export type FrontMatterOptions = { staticFolderName : string ; include : string [ ] ; exclude : string [ ] ; } ; export type MarkdownNode = { id : string ; parent : string ; url : string ; frontmatter ? : object ; internal : { type : string ; } ; fileAbsolutePath : string ; } ; export type Node = { dir : string ; } ; export type HtmlNode = { value : string ; } & MarkdownNode ; export const defaultPluginOptions = { staticFolderName : 'static' , include : [ ] , exclude : [ ] , } ; export const findMatchingFile = ( src , files , options ) => { const result = find ( files , ( file ) => { const staticPath = slash ( path . join ( options . staticFolderName , src ) ) ; return slash ( path . normalize ( file . absolutePath ) ) . endsWith ( staticPath ) ; } ) ; if ( ! result ) { throw new Error ( `No matching file found for src "${ src }" in static folder "${ options . staticFolderName }". Please check static folder name and that file exists at "${ options . staticFolderName }${ src }". This error will probably cause a "GraphQLDocumentError" later in build. All converted field paths MUST resolve to a matching file in the "static" folder.` ) ; } return result ; } ; export default async ( { files , markdownNode , markdownAST } , pluginOptions ) => { const options = defaults ( pluginOptions , defaultPluginOptions ) ; if ( ! markdownNode . fileAbsolutePath ) return ; const directory = path . dirname ( markdownNode . fileAbsolutePath ) ; selectAll ( 'image' , markdownAST ) . forEach ( ( _node ) => { const node = _node as MarkdownNode ; if ( ! isString ( node . url ) ) return ; if ( ! path . isAbsolute ( node . url ) || ! path . extname ( node . url ) ) return ; const file = findMatchingFile ( node . url , files , options ) ; node . url = path . relative ( directory , file . absolutePath ) ; } ) ; selectAll ( 'html' , markdownAST ) . forEach ( ( _node ) => { const node = _node as HtmlNode ; const $ = cheerio . load ( node . value ) ; if ( $ ( `img` ) . length === 0 ) return ; $ ( `img` ) . each ( ( _ , element ) => { const url = $ ( element ) . attr ( `src` ) ; if ( ! isString ( url ) ) return ; if ( ! path . isAbsolute ( url ) || ! path . extname ( url ) ) return ; const file = findMatchingFile ( url , files , options ) ; const src = path . relative ( directory , file . absolutePath ) ; $ ( element ) . attr ( 'src' , src ) ; node . value = $ ( `body` ) . html ( ) ?? '' ; } ) ; } ) ; } ;