UNPKG

apollo-codegen

Version:

Generate API code or type annotations based on a GraphQL schema and query documents

140 lines (110 loc) 2.82 kB
export interface BasicGeneratedFile { output: string } export class GeneratedFile<Scope = any> implements BasicGeneratedFile { scopeStack: Scope[] = []; indentWidth = 2; indentLevel = 0; startOfIndentLevel = false; public output = ''; pushScope(scope: Scope) { this.scopeStack.push(scope); } popScope() { return this.scopeStack.pop(); } get scope(): Scope { if (this.scopeStack.length < 1) throw new Error('No active scope'); return this.scopeStack[this.scopeStack.length - 1]; } print(string?: string) { if (string) { this.output += string; } } printNewline() { if (this.output) { this.print('\n'); this.startOfIndentLevel = false; } } printNewlineIfNeeded() { if (!this.startOfIndentLevel) { this.printNewline(); } } printOnNewline(string?: string) { if (string) { this.printNewline(); this.printIndent(); this.print(string); } } printIndent() { const indentation = ' '.repeat(this.indentLevel * this.indentWidth); this.output += indentation; } withIndent(closure: Function) { if (!closure) return; this.indentLevel++; this.startOfIndentLevel = true; closure(); this.indentLevel--; } withinBlock(closure: Function, open = ' {', close = '}') { this.print(open); this.withIndent(closure); this.printOnNewline(close); } } export default class CodeGenerator<Context = any, Scope = any> { generatedFiles: { [fileName: string]: GeneratedFile<Scope> } = {}; currentFile: GeneratedFile<Scope>; constructor(public context: Context) { this.currentFile = new GeneratedFile(); } withinFile(fileName: string, closure: Function) { let file = this.generatedFiles[fileName]; if (!file) { file = new GeneratedFile(); this.generatedFiles[fileName] = file; } const oldCurrentFile = this.currentFile; this.currentFile = file; closure(); this.currentFile = oldCurrentFile; } get output(): string { return this.currentFile.output; } pushScope(scope: Scope) { this.currentFile.pushScope(scope); } popScope() { this.currentFile.popScope(); } get scope(): Scope { return this.currentFile.scope; } print(string?: string) { this.currentFile.print(string); } printNewline() { this.currentFile.printNewline(); } printNewlineIfNeeded() { this.currentFile.printNewlineIfNeeded(); } printOnNewline(string?: string) { this.currentFile.printOnNewline(string); } printIndent() { this.currentFile.printIndent(); } withIndent(closure: Function) { this.currentFile.withIndent(closure); } withinBlock(closure: Function, open = ' {', close = '}') { this.currentFile.withinBlock(closure, open, close); } }