import { dirname , isAbsolute , join , relative , resolve } from 'path' ; import parse from 'parse-filepath' ; export type ImportDeclaration < T = string > = { outputPath : string ; importSource : ImportSource < T > ; baseOutputDir : string ; baseDir : string ; typesImport : boolean ; } ; export type ImportSource < T = string > = { /**
     * Source path, relative to the `baseOutputDir`
     */ path : string ; /**
     * Namespace to import source as
     */ namespace ? : string ; /**
     * Entity names to import
     */ identifiers ? : T [ ] ; } ; export type FragmentImport = { name : string ; kind : 'type' | 'document' ; } ; export function generateFragmentImportStatement ( statement , kind ) { const { importSource : fragmentImportSource , ... rest } = statement ; const { identifiers , path , namespace } = fragmentImportSource ; const importSource = { identifiers : identifiers . filter ( fragmentImport => kind === 'both' || kind === fragmentImport . kind ) . map ( ( { name } ) => name ) , path , namespace , } ; return generateImportStatement ( { importSource , ... rest , typesImport : kind === 'type' ? statement . typesImport : false , } ) ; } export function generateImportStatement ( statement ) { const { baseDir , importSource , outputPath , typesImport } = statement ; const importPath = resolveImportPath ( baseDir , outputPath , importSource . path ) ; const importNames = importSource . identifiers && importSource . identifiers . length ? `{ ${ Array . from ( new Set ( importSource . identifiers ) ) . join ( ', ' ) } }` : '*' ; const importAlias = importSource . namespace ? ` as ${ importSource . namespace }` : '' ; const importStatement = typesImport ? 'import type' : 'import' ; return `${ importStatement } ${ importNames }${ importAlias } from '${ importPath }';${ importAlias ? '\n' : '' }` ; } function resolveImportPath ( baseDir , outputPath , sourcePath ) { const shouldAbsolute = ! sourcePath . startsWith ( '~' ) ; if ( shouldAbsolute ) { const absGeneratedFilePath = resolve ( baseDir , outputPath ) ; const absImportFilePath = resolve ( baseDir , sourcePath ) ; return resolveRelativeImport ( absGeneratedFilePath , absImportFilePath ) ; } else { return sourcePath . replace ( `~` , '' ) ; } } export function resolveRelativeImport ( from , to ) { if ( ! isAbsolute ( from ) ) { throw new Error ( `Argument 'from' must be an absolute path, '${ from }' given.` ) ; } if ( ! isAbsolute ( to ) ) { throw new Error ( `Argument 'to' must be an absolute path, '${ to }' given.` ) ; } return fixLocalFilePath ( clearExtension ( relative ( dirname ( from ) , to ) ) ) ; } export function resolveImportSource < T > ( source ) { return typeof source === 'string' ? { path : source } : source ; } export function clearExtension ( path ) { const parsedPath = parse ( path ) ; return join ( parsedPath . dir , parsedPath . name ) . replace ( /\\/g , '/' ) ; } export function fixLocalFilePath ( path ) { return ! path . startsWith ( '..' ) ? `./${ path }` : path ; }