import { GraphQLSchema } from 'graphql' import { BuiltInParserName } from 'prettier' import { Config } from '../../config' import { prettify } from '../../helpers/prettify' import { relativeImportPath } from './relativeImportPath' interface Import { isDefault: boolean module?: string alias?: string } interface ImportMap { [from: string]: Import[] } export class RenderContext { protected codeBlocks: string[] = [] protected imports: ImportMap = {} protected importAliasCounter = 0 constructor(public schema?: GraphQLSchema, public config?: Config) {} addCodeBlock(block: string) { this.codeBlocks.push(block) } addImport(from: string, isDefault: boolean, module?: string, fromAbsolute?: boolean, noAlias?: boolean) { if (this.config && this.config.output) { from = fromAbsolute ? from : relativeImportPath(this.config.output, from) } if (!this.imports[from]) this.imports[from] = [] const imports = this.imports[from] const existing = imports.find(i => (isDefault && i.isDefault) || (!isDefault && i.module === module)) if (existing) return existing.alias this.importAliasCounter++ const alias = noAlias ? undefined : `a${this.importAliasCounter}` imports.push({ isDefault, module, alias }) return alias } protected getImportBlock() { const imports: string[] = [] Object.keys(this.imports).forEach(from => { let defaultImport = this.imports[from].find(i => i.isDefault) const namedImports = this.imports[from].filter(i => !i.isDefault) const statements = [] if (defaultImport) { statements.push(defaultImport.alias) } if (namedImports.length > 0) { statements.push(`{${namedImports.map(i => (i.alias ? `${i.module} as ${i.alias}` : i.module)).join(',')}}`) } imports.push(`import ${statements.join(',')} from '${from}'`) }) if (imports.length > 0) return imports.join('\n') else return } toCode(parser?: BuiltInParserName) { const blocks = [...this.codeBlocks] if (parser && (parser === 'typescript' || parser === 'babel')) { const importBlock = this.getImportBlock() if (importBlock) blocks.unshift(importBlock) } return parser ? prettify(blocks.join('\n\n'), parser) : blocks.join('') } }