@gqlts/cli
Version:
Generate a client sdk from your GraphQl API
92 lines (71 loc) • 2.52 kB
text/typescript
import { Config } from '../../config';
import { relativeImportPath } from './relativeImportPath';
import { GraphQLSchema } from 'graphql';
import { BuiltInParserName } from 'prettier';
import { prettify } from '../../helpers/prettify';
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) {
if (block) {
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: string[] = [];
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;
}
async toCode(parser?: BuiltInParserName, pretty = false) {
const blocks = [...this.codeBlocks];
if (parser && (parser === 'typescript' || parser === 'babel')) {
const importBlock = this.getImportBlock();
if (importBlock) blocks.unshift(importBlock);
}
if (parser && pretty) {
return prettify(blocks.join('\n\n'), parser);
}
if (parser) {
return blocks.join('\n\n');
}
return blocks.join('');
}
}