apollo-codegen
Advanced tools
Comparing version 0.17.0-alpha.10 to 0.17.0-alpha.11
@@ -110,2 +110,7 @@ #!/usr/bin/env node | ||
}, | ||
only: { | ||
describe: 'Parse all input files, but only output generated code for the specified file [Swift only]', | ||
normalize: true, | ||
coerce: path.resolve, | ||
}, | ||
namespace: { | ||
@@ -166,3 +171,3 @@ demand: false, | ||
}; | ||
_1.generate(inputPaths, argv.schema, argv.output, argv.target, argv.tagName, options); | ||
_1.generate(inputPaths, argv.schema, argv.output, argv.only, argv.target, argv.tagName, options); | ||
}) | ||
@@ -169,0 +174,0 @@ .fail(function (message, error) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const loading_1 = require("./loading"); | ||
@@ -13,11 +14,11 @@ const validation_1 = require("./validation"); | ||
const scala_1 = require("./scala"); | ||
function generate(inputPaths, schemaPath, outputPath, target, tagName, options) { | ||
function generate(inputPaths, schemaPath, outputPath, only, target, tagName, options) { | ||
const schema = loading_1.loadSchema(schemaPath); | ||
const document = loading_1.loadAndMergeQueryDocuments(inputPaths, tagName); | ||
validation_1.validateQueryDocument(schema, document); | ||
let output; | ||
if (target === 'swift') { | ||
options.addTypename = true; | ||
const context = compiler_1.compileToIR(schema, document, options); | ||
output = swift_1.generateSource(context); | ||
const generatedFiles = swift_1.generateSource(context, outputPath, only); | ||
writeGeneratedFiles(generatedFiles, outputPath); | ||
if (options.generateOperationIds) { | ||
@@ -28,2 +29,3 @@ writeOperationIdsMap(context); | ||
else { | ||
let output; | ||
const context = legacyIR_1.compileToLegacyIR(schema, document, options); | ||
@@ -44,11 +46,19 @@ switch (target) { | ||
} | ||
if (outputPath) { | ||
fs.writeFileSync(outputPath, output); | ||
} | ||
else { | ||
console.log(output); | ||
} | ||
} | ||
if (outputPath) { | ||
fs.writeFileSync(outputPath, output); | ||
} | ||
exports.default = generate; | ||
function writeGeneratedFiles(generatedFiles, outputDirectory) { | ||
if (!fs.existsSync(outputDirectory)) { | ||
fs.mkdirSync(outputDirectory); | ||
} | ||
else { | ||
console.log(output); | ||
for (const [fileName, generatedFile] of Object.entries(generatedFiles)) { | ||
fs.writeFileSync(path.join(outputDirectory, fileName), generatedFile.output); | ||
} | ||
} | ||
exports.default = generate; | ||
function writeOperationIdsMap(context) { | ||
@@ -55,0 +65,0 @@ let operationIdsMap = {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const graphql_1 = require("graphql"); | ||
@@ -13,17 +15,55 @@ const printing_1 = require("../utilities/printing"); | ||
require("../utilities/array"); | ||
function generateSource(context) { | ||
function generateSource(context, outputPath, only) { | ||
const generator = new SwiftAPIGenerator(context); | ||
generator.fileHeader(); | ||
generator.namespaceDeclaration(context.options.namespace, () => { | ||
context.typesUsed.forEach(type => { | ||
generator.typeDeclarationForGraphQLType(type); | ||
if (fs.statSync(outputPath).isDirectory()) { | ||
generator.withinFile(`Types.graphql.swift`, () => { | ||
generator.fileHeader(); | ||
generator.namespaceDeclaration(context.options.namespace, () => { | ||
context.typesUsed.forEach(type => { | ||
generator.typeDeclarationForGraphQLType(type); | ||
}); | ||
}); | ||
}); | ||
const inputFilePaths = new Set(); | ||
Object.values(context.operations).forEach(operation => { | ||
generator.classDeclarationForOperation(operation); | ||
inputFilePaths.add(operation.filePath); | ||
}); | ||
Object.values(context.fragments).forEach(fragment => { | ||
generator.structDeclarationForFragment(fragment); | ||
inputFilePaths.add(fragment.filePath); | ||
}); | ||
}); | ||
return generator.output; | ||
for (const inputFilePath of inputFilePaths) { | ||
if (only && inputFilePath !== only) | ||
continue; | ||
generator.withinFile(`${path.basename(inputFilePath)}.swift`, () => { | ||
generator.fileHeader(); | ||
generator.namespaceExtensionDeclaration(context.options.namespace, () => { | ||
Object.values(context.operations).forEach(operation => { | ||
if (operation.filePath === inputFilePath) { | ||
generator.classDeclarationForOperation(operation); | ||
} | ||
}); | ||
Object.values(context.fragments).forEach(fragment => { | ||
if (fragment.filePath === inputFilePath) { | ||
generator.structDeclarationForFragment(fragment); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
else { | ||
generator.fileHeader(); | ||
generator.namespaceDeclaration(context.options.namespace, () => { | ||
context.typesUsed.forEach(type => { | ||
generator.typeDeclarationForGraphQLType(type); | ||
}); | ||
Object.values(context.operations).forEach(operation => { | ||
generator.classDeclarationForOperation(operation); | ||
}); | ||
Object.values(context.fragments).forEach(fragment => { | ||
generator.structDeclarationForFragment(fragment); | ||
}); | ||
}); | ||
} | ||
return generator.generatedFiles; | ||
} | ||
@@ -30,0 +70,0 @@ exports.generateSource = generateSource; |
@@ -63,2 +63,17 @@ "use strict"; | ||
} | ||
namespaceExtensionDeclaration(namespace, closure) { | ||
if (namespace) { | ||
this.printNewlineIfNeeded(); | ||
this.printOnNewline(`/// ${namespace} namespace`); | ||
this.printOnNewline(`public extension ${namespace}`); | ||
this.pushScope({ typeName: namespace }); | ||
this.withinBlock(closure); | ||
this.popScope(); | ||
} | ||
else { | ||
if (closure) { | ||
closure(); | ||
} | ||
} | ||
} | ||
classDeclaration({ className, modifiers, superClass, adoptedProtocols = [] }, closure) { | ||
@@ -65,0 +80,0 @@ this.printNewlineIfNeeded(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class CodeGenerator { | ||
constructor(context) { | ||
this.context = context; | ||
class GeneratedFile { | ||
constructor() { | ||
this.scopeStack = []; | ||
@@ -20,8 +19,8 @@ this.indentWidth = 2; | ||
if (this.scopeStack.length < 1) | ||
throw Error('No active scope'); | ||
throw new Error('No active scope'); | ||
return this.scopeStack[this.scopeStack.length - 1]; | ||
} | ||
print(maybeString) { | ||
if (maybeString) { | ||
this.output += maybeString; | ||
print(string) { | ||
if (string) { | ||
this.output += string; | ||
} | ||
@@ -40,7 +39,7 @@ } | ||
} | ||
printOnNewline(maybeString) { | ||
if (maybeString) { | ||
printOnNewline(string) { | ||
if (string) { | ||
this.printNewline(); | ||
this.printIndent(); | ||
this.print(maybeString); | ||
this.print(string); | ||
} | ||
@@ -66,3 +65,55 @@ } | ||
} | ||
exports.GeneratedFile = GeneratedFile; | ||
class CodeGenerator { | ||
constructor(context) { | ||
this.context = context; | ||
this.generatedFiles = {}; | ||
this.currentFile = new GeneratedFile(); | ||
} | ||
withinFile(fileName, closure) { | ||
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() { | ||
return this.currentFile.output; | ||
} | ||
pushScope(scope) { | ||
this.currentFile.pushScope(scope); | ||
} | ||
popScope() { | ||
this.currentFile.popScope(); | ||
} | ||
get scope() { | ||
return this.currentFile.scope; | ||
} | ||
print(string) { | ||
this.currentFile.print(string); | ||
} | ||
printNewline() { | ||
this.currentFile.printNewline(); | ||
} | ||
printNewlineIfNeeded() { | ||
this.currentFile.printNewlineIfNeeded(); | ||
} | ||
printOnNewline(string) { | ||
this.currentFile.printOnNewline(string); | ||
} | ||
printIndent() { | ||
this.currentFile.printIndent(); | ||
} | ||
withIndent(closure) { | ||
this.currentFile.withIndent(closure); | ||
} | ||
withinBlock(closure, open = ' {', close = '}') { | ||
this.currentFile.withinBlock(closure, open, close); | ||
} | ||
} | ||
exports.default = CodeGenerator; | ||
//# sourceMappingURL=CodeGenerator.js.map |
@@ -46,3 +46,6 @@ "use strict"; | ||
const name = node.loc && node.loc.source && node.loc.source.name; | ||
return (name === "GraphQL") ? undefined : name; | ||
if (!name || name === "GraphQL") { | ||
throw new Error("Node does not seem to have a file path"); | ||
} | ||
return name; | ||
} | ||
@@ -49,0 +52,0 @@ exports.filePathForNode = filePathForNode; |
{ | ||
"name": "apollo-codegen", | ||
"version": "0.17.0-alpha.10", | ||
"version": "0.17.0-alpha.11", | ||
"description": "Generate API code or type annotations based on a GraphQL schema and query documents", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
@@ -121,2 +121,7 @@ #!/usr/bin/env node | ||
}, | ||
only: { | ||
describe: 'Parse all input files, but only output generated code for the specified file [Swift only]', | ||
normalize: true, | ||
coerce: path.resolve, | ||
}, | ||
namespace: { | ||
@@ -184,3 +189,3 @@ demand: false, | ||
generate(inputPaths, argv.schema, argv.output, argv.target, argv.tagName, options); | ||
generate(inputPaths, argv.schema, argv.output, argv.only, argv.target, argv.tagName, options); | ||
}, | ||
@@ -187,0 +192,0 @@ ) |
@@ -68,3 +68,3 @@ import { | ||
}[]; | ||
filePath?: string; | ||
filePath: string; | ||
source: string; | ||
@@ -76,3 +76,3 @@ rootType: GraphQLObjectType; | ||
export interface Fragment { | ||
filePath?: string; | ||
filePath: string; | ||
fragmentName: string; | ||
@@ -79,0 +79,0 @@ source: string; |
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
@@ -8,2 +9,3 @@ import { loadSchema, loadAndMergeQueryDocuments } from './loading'; | ||
import serializeToJSON from './serializeToJSON'; | ||
import { GeneratedFile } from './utilities/CodeGenerator' | ||
import { generateSource as generateSwiftSource } from './swift'; | ||
@@ -20,2 +22,3 @@ import { generateSource as generateTypescriptSource } from './typescript'; | ||
outputPath: string, | ||
only: string, | ||
target: TargetType, | ||
@@ -31,8 +34,7 @@ tagName: string, | ||
let output; | ||
if (target === 'swift') { | ||
options.addTypename = true; | ||
const context = compileToIR(schema, document, options); | ||
output = generateSwiftSource(context); | ||
const generatedFiles = generateSwiftSource(context, outputPath, only); | ||
writeGeneratedFiles(generatedFiles, outputPath); | ||
if (options.generateOperationIds) { | ||
@@ -42,2 +44,3 @@ writeOperationIdsMap(context); | ||
} else { | ||
let output; | ||
const context = compileToLegacyIR(schema, document, options); | ||
@@ -58,9 +61,18 @@ switch (target) { | ||
} | ||
if (outputPath) { | ||
fs.writeFileSync(outputPath, output); | ||
} else { | ||
console.log(output); | ||
} | ||
} | ||
} | ||
if (outputPath) { | ||
fs.writeFileSync(outputPath, output); | ||
} else { | ||
console.log(output); | ||
function writeGeneratedFiles(generatedFiles: { [fileName: string]: GeneratedFile }, outputDirectory: string) { | ||
if (!fs.existsSync(outputDirectory)) { | ||
fs.mkdirSync(outputDirectory); | ||
} | ||
for (const [fileName, generatedFile] of Object.entries(generatedFiles)) { | ||
fs.writeFileSync(path.join(outputDirectory, fileName), generatedFile.output); | ||
} | ||
} | ||
@@ -67,0 +79,0 @@ |
@@ -0,1 +1,4 @@ | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import { | ||
@@ -26,2 +29,3 @@ GraphQLError, | ||
import '../utilities/array'; | ||
import { GeneratedFile } from '../utilities/CodeGenerator'; | ||
@@ -34,22 +38,70 @@ export interface Options { | ||
export function generateSource(context: CompilerContext) { | ||
export function generateSource( | ||
context: CompilerContext, | ||
outputPath: string, | ||
only?: string | ||
): { [fileName: string]: GeneratedFile } { | ||
const generator = new SwiftAPIGenerator(context); | ||
generator.fileHeader(); | ||
if (fs.statSync(outputPath).isDirectory()) { | ||
generator.withinFile(`Types.graphql.swift`, () => { | ||
generator.fileHeader(); | ||
generator.namespaceDeclaration(context.options.namespace, () => { | ||
context.typesUsed.forEach(type => { | ||
generator.typeDeclarationForGraphQLType(type); | ||
generator.namespaceDeclaration(context.options.namespace, () => { | ||
context.typesUsed.forEach(type => { | ||
generator.typeDeclarationForGraphQLType(type); | ||
}); | ||
}); | ||
}); | ||
const inputFilePaths = new Set<string>(); | ||
Object.values(context.operations).forEach(operation => { | ||
generator.classDeclarationForOperation(operation); | ||
inputFilePaths.add(operation.filePath); | ||
}); | ||
Object.values(context.fragments).forEach(fragment => { | ||
generator.structDeclarationForFragment(fragment); | ||
inputFilePaths.add(fragment.filePath); | ||
}); | ||
}); | ||
return generator.output; | ||
for (const inputFilePath of inputFilePaths) { | ||
if (only && inputFilePath !== only) continue; | ||
generator.withinFile(`${path.basename(inputFilePath)}.swift`, () => { | ||
generator.fileHeader(); | ||
generator.namespaceExtensionDeclaration(context.options.namespace, () => { | ||
Object.values(context.operations).forEach(operation => { | ||
if (operation.filePath === inputFilePath) { | ||
generator.classDeclarationForOperation(operation); | ||
} | ||
}); | ||
Object.values(context.fragments).forEach(fragment => { | ||
if (fragment.filePath === inputFilePath) { | ||
generator.structDeclarationForFragment(fragment); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
} else { | ||
generator.fileHeader(); | ||
generator.namespaceDeclaration(context.options.namespace, () => { | ||
context.typesUsed.forEach(type => { | ||
generator.typeDeclarationForGraphQLType(type); | ||
}); | ||
Object.values(context.operations).forEach(operation => { | ||
generator.classDeclarationForOperation(operation); | ||
}); | ||
Object.values(context.fragments).forEach(fragment => { | ||
generator.structDeclarationForFragment(fragment); | ||
}); | ||
}); | ||
} | ||
return generator.generatedFiles; | ||
} | ||
@@ -56,0 +108,0 @@ |
@@ -93,2 +93,17 @@ import CodeGenerator from '../utilities/CodeGenerator'; | ||
namespaceExtensionDeclaration(namespace: string | undefined, closure: Function) { | ||
if (namespace) { | ||
this.printNewlineIfNeeded(); | ||
this.printOnNewline(`/// ${namespace} namespace`); | ||
this.printOnNewline(`public extension ${namespace}`); | ||
this.pushScope({ typeName: namespace }); | ||
this.withinBlock(closure); | ||
this.popScope(); | ||
} else { | ||
if (closure) { | ||
closure(); | ||
} | ||
} | ||
} | ||
classDeclaration({ className, modifiers, superClass, adoptedProtocols = [] }: Class, closure: Function) { | ||
@@ -95,0 +110,0 @@ this.printNewlineIfNeeded(); |
@@ -1,11 +0,9 @@ | ||
export default class CodeGenerator<Context = any, Scope = any> { | ||
private scopeStack: Scope[] = []; | ||
private indentWidth = 2; | ||
private indentLevel = 0; | ||
private startOfIndentLevel = false; | ||
export class GeneratedFile<Scope = any> { | ||
scopeStack: Scope[] = []; | ||
indentWidth = 2; | ||
indentLevel = 0; | ||
startOfIndentLevel = false; | ||
public output = ''; | ||
constructor(public context: Context) {} | ||
pushScope(scope: Scope) { | ||
@@ -20,3 +18,3 @@ this.scopeStack.push(scope); | ||
get scope(): Scope { | ||
if (this.scopeStack.length < 1) throw Error('No active scope'); | ||
if (this.scopeStack.length < 1) throw new Error('No active scope'); | ||
@@ -26,5 +24,5 @@ return this.scopeStack[this.scopeStack.length - 1]; | ||
print(maybeString?: string) { | ||
if (maybeString) { | ||
this.output += maybeString; | ||
print(string?: string) { | ||
if (string) { | ||
this.output += string; | ||
} | ||
@@ -46,7 +44,7 @@ } | ||
printOnNewline(maybeString?: string) { | ||
if (maybeString) { | ||
printOnNewline(string?: string) { | ||
if (string) { | ||
this.printNewline(); | ||
this.printIndent(); | ||
this.print(maybeString); | ||
this.print(string); | ||
} | ||
@@ -75,1 +73,66 @@ } | ||
} | ||
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); | ||
} | ||
} |
@@ -84,5 +84,8 @@ import { | ||
export function filePathForNode(node: ASTNode): string | undefined { | ||
export function filePathForNode(node: ASTNode): string { | ||
const name = node.loc && node.loc.source && node.loc.source.name; | ||
return (name === "GraphQL") ? undefined : name; | ||
if (!name || name === "GraphQL") { | ||
throw new Error("Node does not seem to have a file path"); | ||
} | ||
return name; | ||
} | ||
@@ -89,0 +92,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
461280
8107
8