apollo-codegen-swift
Version:
Swift generator module for Apollo Codegen
684 lines • 39 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SwiftAPIGenerator = exports.generateSource = void 0;
const path_1 = __importDefault(require("path"));
const graphql_1 = require("graphql");
const language_1 = require("./language");
const helpers_1 = require("./helpers");
const graphql_2 = require("apollo-codegen-core/lib/utilities/graphql");
const typeCase_1 = require("apollo-codegen-core/lib/compiler/visitors/typeCase");
const collectFragmentsReferenced_1 = require("apollo-codegen-core/lib/compiler/visitors/collectFragmentsReferenced");
const generateOperationId_1 = require("apollo-codegen-core/lib/compiler/visitors/generateOperationId");
const collectAndMergeFields_1 = require("apollo-codegen-core/lib/compiler/visitors/collectAndMergeFields");
require("apollo-codegen-core/lib/utilities/array");
const { join, wrap } = language_1.SwiftSource;
function generateSource(context, outputIndividualFiles, suppressMultilineStringLiterals, only) {
const generator = new SwiftAPIGenerator(context);
if (outputIndividualFiles) {
generator.withinFile(`Types.graphql.swift`, () => {
generator.fileHeader();
generator.namespaceDeclaration(context.options.namespace, () => {
context.typesUsed.forEach((type) => {
generator.typeDeclarationForGraphQLType(type, true);
});
});
});
const inputFilePaths = new Set();
Object.values(context.operations).forEach((operation) => {
inputFilePaths.add(operation.filePath);
});
Object.values(context.fragments).forEach((fragment) => {
inputFilePaths.add(fragment.filePath);
});
for (const inputFilePath of inputFilePaths) {
if (only && inputFilePath !== only)
continue;
generator.withinFile(`${path_1.default.basename(inputFilePath)}.swift`, () => {
generator.fileHeader();
generator.namespaceExtensionDeclaration(context.options.namespace, () => {
Object.values(context.operations).forEach((operation) => {
if (operation.filePath === inputFilePath) {
generator.classDeclarationForOperation(operation, true, suppressMultilineStringLiterals);
}
});
Object.values(context.fragments).forEach((fragment) => {
if (fragment.filePath === inputFilePath) {
generator.structDeclarationForFragment(fragment, true, suppressMultilineStringLiterals);
}
});
});
});
}
}
else {
generator.fileHeader();
generator.namespaceDeclaration(context.options.namespace, () => {
context.typesUsed.forEach((type) => {
generator.typeDeclarationForGraphQLType(type, false);
});
Object.values(context.operations).forEach((operation) => {
generator.classDeclarationForOperation(operation, false, suppressMultilineStringLiterals);
});
Object.values(context.fragments).forEach((fragment) => {
generator.structDeclarationForFragment(fragment, false, suppressMultilineStringLiterals);
});
});
}
return generator;
}
exports.generateSource = generateSource;
class SwiftAPIGenerator extends language_1.SwiftGenerator {
constructor(context) {
super(context);
this.helpers = new helpers_1.Helpers(context.options);
}
fileHeader() {
this.printOnNewline(language_1.SwiftSource.raw `// @generated`);
this.printOnNewline(language_1.SwiftSource.raw `// This file was automatically generated and should not be edited.`);
this.printNewline();
this.printOnNewline((0, language_1.swift) `import Apollo`);
this.printOnNewline((0, language_1.swift) `import Foundation`);
}
classDeclarationForOperation(operation, outputIndividualFiles, suppressMultilineStringLiterals) {
const { operationName, operationType, variables, source, selectionSet } = operation;
let className;
let protocol;
switch (operationType) {
case "query":
className = `${this.helpers.operationClassName(operationName)}Query`;
protocol = "GraphQLQuery";
break;
case "mutation":
className = `${this.helpers.operationClassName(operationName)}Mutation`;
protocol = "GraphQLMutation";
break;
case "subscription":
className = `${this.helpers.operationClassName(operationName)}Subscription`;
protocol = "GraphQLSubscription";
break;
default:
throw new graphql_1.GraphQLError(`Unsupported operation type "${operationType}"`);
}
const { options: { namespace }, fragments, } = this.context;
const isRedundant = !!namespace && outputIndividualFiles;
const modifiers = isRedundant ? ["final"] : ["public", "final"];
this.classDeclaration({
className,
modifiers,
adoptedProtocols: [protocol],
}, () => {
if (source) {
this.comment("The raw GraphQL definition of this operation.");
this.printOnNewline((0, language_1.swift) `public let operationDefinition: String =`);
this.withIndent(() => {
this.multilineString(source, suppressMultilineStringLiterals);
});
}
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public let operationName: String = ${language_1.SwiftSource.string(operationName)}`);
const fragmentsReferenced = (0, collectFragmentsReferenced_1.collectFragmentsReferenced)(operation.selectionSet, fragments);
if (this.context.options.generateOperationIds) {
const { operationId, sourceWithFragments } = (0, generateOperationId_1.generateOperationId)(operation, fragments, fragmentsReferenced);
operation.operationId = operationId;
operation.sourceWithFragments = sourceWithFragments;
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public let operationIdentifier: String? = ${language_1.SwiftSource.string(operationId)}`);
}
if (fragmentsReferenced.size > 0) {
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public var queryDocument: String`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `var document: String = operationDefinition`);
fragmentsReferenced.forEach((fragmentName) => {
this.printOnNewline((0, language_1.swift) `document.append("\\n" + ${this.helpers.structNameForFragmentName(fragmentName)}.fragmentDefinition)`);
});
this.printOnNewline((0, language_1.swift) `return document`);
});
}
this.printNewlineIfNeeded();
if (variables && variables.length > 0) {
const properties = variables.map(({ name, type }) => {
const typeName = this.helpers.typeNameFromGraphQLType(type);
const isOptional = !((0, graphql_1.isNonNullType)(type) ||
((0, graphql_1.isListType)(type) && (0, graphql_1.isNonNullType)(type.ofType)));
return { name, propertyName: name, type, typeName, isOptional };
});
this.propertyDeclarations(properties);
this.printNewlineIfNeeded();
this.initializerDeclarationForProperties(properties);
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public var variables: GraphQLMap?`);
this.withinBlock(() => {
this.printOnNewline(wrap((0, language_1.swift) `return [`, join(properties.map(({ name, propertyName }) => (0, language_1.swift) `${language_1.SwiftSource.string(name)}: ${propertyName}`), ", ") || (0, language_1.swift) `:`, (0, language_1.swift) `]`));
});
}
else {
this.initializerDeclarationForProperties([]);
}
this.structDeclarationForSelectionSet({
structName: "Data",
selectionSet,
}, outputIndividualFiles);
});
}
structDeclarationForFragment({ fragmentName, selectionSet, source }, outputIndividualFiles, suppressMultilineStringLiterals) {
const structName = this.helpers.structNameForFragmentName(fragmentName);
this.structDeclarationForSelectionSet({
structName,
adoptedProtocols: ["GraphQLFragment"],
selectionSet,
}, outputIndividualFiles, () => {
if (source) {
this.comment("The raw GraphQL definition of this fragment.");
this.printOnNewline((0, language_1.swift) `public static let fragmentDefinition: String =`);
this.withIndent(() => {
this.multilineString(source, suppressMultilineStringLiterals);
});
}
});
}
structDeclarationForSelectionSet({ structName, adoptedProtocols = ["GraphQLSelectionSet"], selectionSet, }, outputIndividualFiles, before) {
const typeCase = (0, typeCase_1.typeCaseForSelectionSet)(selectionSet, !!this.context.options.mergeInFieldsFromFragmentSpreads);
this.structDeclarationForVariant({
structName,
adoptedProtocols,
variant: typeCase.default,
typeCase,
}, outputIndividualFiles, before, () => {
const variants = typeCase.variants.map(this.helpers.propertyFromVariant, this.helpers);
for (const variant of variants) {
this.propertyDeclarationForVariant(variant);
this.structDeclarationForVariant({
structName: variant.structName,
variant,
}, outputIndividualFiles);
}
});
}
structDeclarationForVariant({ structName, adoptedProtocols = ["GraphQLSelectionSet"], variant, typeCase, }, outputIndividualFiles, before, after) {
const { options: { namespace, mergeInFieldsFromFragmentSpreads, omitDeprecatedEnumCases, }, } = this.context;
this.structDeclaration({ structName, adoptedProtocols, namespace }, outputIndividualFiles, () => {
if (before) {
before();
}
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public static let possibleTypes: [String] = [`);
this.print(join(variant.possibleTypes.map((type) => (0, language_1.swift) `${language_1.SwiftSource.string(type.name)}`), ", "));
this.print((0, language_1.swift) `]`);
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public static var selections: [GraphQLSelection] {`);
this.withIndent(() => {
this.printOnNewline((0, language_1.swift) `return `);
if (typeCase) {
this.typeCaseInitialization(typeCase);
}
else {
this.selectionSetInitialization(variant);
}
});
this.printOnNewline((0, language_1.swift) `}`);
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public private(set) var resultMap: ResultMap`);
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public init(unsafeResultMap: ResultMap)`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `self.resultMap = unsafeResultMap`);
});
if (typeCase) {
this.initializersForTypeCase(typeCase);
}
else {
this.initializersForVariant(variant);
}
const fields = (0, collectAndMergeFields_1.collectAndMergeFields)(variant, !!mergeInFieldsFromFragmentSpreads).map((field) => this.helpers.propertyFromField(field));
const fragmentSpreads = variant.fragmentSpreads.map((fragmentSpread) => {
const isConditional = variant.possibleTypes.some((type) => !fragmentSpread.selectionSet.possibleTypes.includes(type));
return this.helpers.propertyFromFragmentSpread(fragmentSpread, isConditional);
});
fields.forEach(this.propertyDeclarationForField, this);
if (fragmentSpreads.length > 0) {
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public var fragments: Fragments`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `return Fragments(unsafeResultMap: resultMap)`);
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `resultMap += newValue.resultMap`);
});
});
this.structDeclaration({
structName: "Fragments",
}, outputIndividualFiles, () => {
this.printOnNewline((0, language_1.swift) `public private(set) var resultMap: ResultMap`);
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public init(unsafeResultMap: ResultMap)`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `self.resultMap = unsafeResultMap`);
});
for (const fragmentSpread of fragmentSpreads) {
const { propertyName, typeName, structName, isConditional } = fragmentSpread;
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public var ${propertyName}: ${typeName}`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
if (isConditional) {
this.printOnNewline((0, language_1.swift) `if !${structName}.possibleTypes.contains(resultMap["__typename"]! as! String) { return nil }`);
}
this.printOnNewline((0, language_1.swift) `return ${structName}(unsafeResultMap: resultMap)`);
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
if (isConditional) {
this.printOnNewline((0, language_1.swift) `guard let newValue = newValue else { return }`);
this.printOnNewline((0, language_1.swift) `resultMap += newValue.resultMap`);
}
else {
this.printOnNewline((0, language_1.swift) `resultMap += newValue.resultMap`);
}
});
});
}
});
}
for (const field of fields) {
if ((0, graphql_1.isCompositeType)((0, graphql_1.getNamedType)(field.type)) && field.selectionSet) {
this.structDeclarationForSelectionSet({
structName: field.structName,
selectionSet: field.selectionSet,
}, outputIndividualFiles);
}
}
if (after) {
after();
}
});
}
initializersForTypeCase(typeCase) {
const variants = typeCase.variants;
if (variants.length == 0) {
this.initializersForVariant(typeCase.default);
}
else {
const remainder = typeCase.remainder;
for (const variant of remainder ? [remainder, ...variants] : variants) {
this.initializersForVariant(variant, variant === remainder
? undefined
: this.helpers.structNameForVariant(variant), false);
}
}
}
initializersForVariant(variant, namespace, useInitializerIfPossible = true) {
if (useInitializerIfPossible && variant.possibleTypes.length == 1) {
const properties = this.helpers.propertiesForSelectionSet(variant);
if (!properties)
return;
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public init`);
this.parametersForProperties(properties);
this.withinBlock(() => {
this.printOnNewline(wrap((0, language_1.swift) `self.init(unsafeResultMap: [`, join([
(0, language_1.swift) `"__typename": ${language_1.SwiftSource.string(variant.possibleTypes[0].toString())}`,
...properties.map((p) => this.propertyAssignmentForField(p, properties)),
], ", ") || (0, language_1.swift) `:`, (0, language_1.swift) `])`));
});
}
else {
const structName = this.scope.typeName;
for (const possibleType of variant.possibleTypes) {
const properties = this.helpers.propertiesForSelectionSet({
possibleTypes: [possibleType],
selections: variant.selections,
}, namespace);
if (!properties)
continue;
this.printNewlineIfNeeded();
this.printOnNewline(language_1.SwiftSource.raw `public static func make${possibleType}`);
this.parametersForProperties(properties);
this.print((0, language_1.swift) ` -> ${structName}`);
this.withinBlock(() => {
this.printOnNewline(wrap((0, language_1.swift) `return ${structName}(unsafeResultMap: [`, join([
(0, language_1.swift) `"__typename": ${language_1.SwiftSource.string(possibleType.toString())}`,
...properties.map((p) => this.propertyAssignmentForField(p, properties)),
], ", ") || (0, language_1.swift) `:`, (0, language_1.swift) `])`));
});
}
}
}
propertyAssignmentForField(field, properties) {
const { responseKey, propertyName, type, isConditional, structName } = field;
const parameterName = this.helpers.internalParameterName(propertyName, properties);
const valueExpression = (0, graphql_1.isCompositeType)((0, graphql_1.getNamedType)(type))
? this.helpers.mapExpressionForType(type, isConditional, (expression) => (0, language_1.swift) `${expression}.resultMap`, language_1.SwiftSource.identifier(parameterName), structName, "ResultMap")
: language_1.SwiftSource.identifier(parameterName);
return (0, language_1.swift) `${language_1.SwiftSource.string(responseKey)}: ${valueExpression}`;
}
propertyDeclarationForField(field) {
const { responseKey, propertyName, typeName, type, isOptional, isConditional, } = field;
const unmodifiedFieldType = (0, graphql_1.getNamedType)(type);
this.printNewlineIfNeeded();
this.comment(field.description);
this.deprecationAttributes(field.isDeprecated, field.deprecationReason);
this.printOnNewline((0, language_1.swift) `public var ${propertyName}: ${typeName}`);
this.withinBlock(() => {
if ((0, graphql_1.isCompositeType)(unmodifiedFieldType)) {
const structName = this.helpers.structNameForPropertyName(responseKey);
if ((0, graphql_2.isList)(type)) {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
const resultMapTypeName = this.helpers.typeNameFromGraphQLType(type, "ResultMap", false);
let expression;
if (isOptional) {
expression = (0, language_1.swift) `(resultMap[${language_1.SwiftSource.string(responseKey)}] as? ${resultMapTypeName})`;
}
else {
expression = (0, language_1.swift) `(resultMap[${language_1.SwiftSource.string(responseKey)}] as! ${resultMapTypeName})`;
}
this.printOnNewline((0, language_1.swift) `return ${this.helpers.mapExpressionForType(type, isConditional, (expression) => (0, language_1.swift) `${structName}(unsafeResultMap: ${expression})`, expression, "ResultMap", structName)}`);
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
let newValueExpression = this.helpers.mapExpressionForType(type, isConditional, (expression) => (0, language_1.swift) `${expression}.resultMap`, (0, language_1.swift) `newValue`, structName, "ResultMap");
this.printOnNewline((0, language_1.swift) `resultMap.updateValue(${newValueExpression}, forKey: ${language_1.SwiftSource.string(responseKey)})`);
});
}
else {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
if (isOptional) {
this.printOnNewline((0, language_1.swift) `return (resultMap[${language_1.SwiftSource.string(responseKey)}] as? ResultMap).flatMap { ${structName}(unsafeResultMap: $0) }`);
}
else {
this.printOnNewline((0, language_1.swift) `return ${structName}(unsafeResultMap: resultMap[${language_1.SwiftSource.string(responseKey)}]! as! ResultMap)`);
}
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
let newValueExpression;
if (isOptional) {
newValueExpression = "newValue?.resultMap";
}
else {
newValueExpression = "newValue.resultMap";
}
this.printOnNewline((0, language_1.swift) `resultMap.updateValue(${newValueExpression}, forKey: ${language_1.SwiftSource.string(responseKey)})`);
});
}
}
else {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
if (isOptional) {
this.printOnNewline((0, language_1.swift) `return resultMap[${language_1.SwiftSource.string(responseKey)}] as? ${typeName.slice(0, -1)}`);
}
else {
this.printOnNewline((0, language_1.swift) `return resultMap[${language_1.SwiftSource.string(responseKey)}]! as! ${typeName}`);
}
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `resultMap.updateValue(newValue, forKey: ${language_1.SwiftSource.string(responseKey)})`);
});
}
});
}
propertyDeclarationForVariant(variant) {
const { propertyName, typeName, structName } = variant;
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public var ${propertyName}: ${typeName}`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `if !${structName}.possibleTypes.contains(__typename) { return nil }`);
this.printOnNewline((0, language_1.swift) `return ${structName}(unsafeResultMap: resultMap)`);
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `guard let newValue = newValue else { return }`);
this.printOnNewline((0, language_1.swift) `resultMap = newValue.resultMap`);
});
});
}
initializerDeclarationForProperties(properties) {
this.printOnNewline((0, language_1.swift) `public init`);
this.parametersForProperties(properties);
this.withinBlock(() => {
properties.forEach(({ propertyName }) => {
this.printOnNewline((0, language_1.swift) `self.${propertyName} = ${this.helpers.internalParameterName(propertyName, properties)}`);
});
});
}
parametersForProperties(properties) {
this.print((0, language_1.swift) `(`);
this.print(join(properties.map(({ propertyName, typeName, isOptional }) => {
const internalName = this.helpers.internalParameterName(propertyName, properties);
const decl = internalName === propertyName
? propertyName
: (0, language_1.swift) `${propertyName} ${internalName}`;
return join([
(0, language_1.swift) `${decl}: ${typeName}`,
isOptional ? (0, language_1.swift) ` = nil` : undefined,
]);
}), ", "));
this.print((0, language_1.swift) `)`);
}
typeCaseInitialization(typeCase) {
if (typeCase.variants.length < 1) {
this.selectionSetInitialization(typeCase.default);
return;
}
this.print((0, language_1.swift) `[`);
this.withIndent(() => {
this.printOnNewline((0, language_1.swift) `GraphQLTypeCase(`);
this.withIndent(() => {
this.printOnNewline((0, language_1.swift) `variants: [`);
this.print(join(typeCase.variants.flatMap((variant) => {
const structName = this.helpers.structNameForVariant(variant);
return variant.possibleTypes.map((type) => (0, language_1.swift) `${language_1.SwiftSource.string(type.toString())}: ${structName}.selections`);
}), ", "));
this.print((0, language_1.swift) `],`);
this.printOnNewline((0, language_1.swift) `default: `);
this.selectionSetInitialization(typeCase.default);
});
this.printOnNewline((0, language_1.swift) `)`);
});
this.printOnNewline((0, language_1.swift) `]`);
}
selectionSetInitialization(selectionSet) {
this.print((0, language_1.swift) `[`);
this.withIndent(() => {
for (const selection of selectionSet.selections) {
switch (selection.kind) {
case "Field": {
const { name, alias, args, type } = selection;
const responseKey = selection.alias || selection.name;
const structName = this.helpers.structNameForPropertyName(responseKey);
this.printOnNewline((0, language_1.swift) `GraphQLField(`);
this.print(join([
(0, language_1.swift) `${language_1.SwiftSource.string(name)}`,
alias
? (0, language_1.swift) `alias: ${language_1.SwiftSource.string(alias)}`
: undefined,
args && args.length
? (0, language_1.swift) `arguments: ${this.helpers.dictionaryLiteralForFieldArguments(args)}`
: undefined,
(0, language_1.swift) `type: ${this.helpers.fieldTypeEnum(type, structName)}`,
], ", "));
this.print((0, language_1.swift) `),`);
break;
}
case "BooleanCondition":
this.printOnNewline((0, language_1.swift) `GraphQLBooleanCondition(`);
this.print(join([
(0, language_1.swift) `variableName: ${language_1.SwiftSource.string(selection.variableName)}`,
(0, language_1.swift) `inverted: ${selection.inverted}`,
(0, language_1.swift) `selections: `,
], ", "));
this.selectionSetInitialization(selection.selectionSet);
this.print((0, language_1.swift) `),`);
break;
case "TypeCondition": {
this.printOnNewline((0, language_1.swift) `GraphQLTypeCondition(`);
this.print(join([
(0, language_1.swift) `possibleTypes: [${join(selection.selectionSet.possibleTypes.map((type) => (0, language_1.swift) `${language_1.SwiftSource.string(type.name)}`), ", ")}]`,
(0, language_1.swift) `selections: `,
], ", "));
this.selectionSetInitialization(selection.selectionSet);
this.print((0, language_1.swift) `),`);
break;
}
case "FragmentSpread": {
const structName = this.helpers.structNameForFragmentName(selection.fragmentName);
this.printOnNewline((0, language_1.swift) `GraphQLFragmentSpread(${structName}.self),`);
break;
}
}
}
});
this.printOnNewline((0, language_1.swift) `]`);
}
typeDeclarationForGraphQLType(type, outputIndividualFiles) {
if ((0, graphql_1.isEnumType)(type)) {
this.enumerationDeclaration(type);
}
else if ((0, graphql_1.isInputObjectType)(type)) {
this.structDeclarationForInputObjectType(type, outputIndividualFiles);
}
}
enumerationDeclaration(type) {
const { name, description } = type;
const values = type.getValues().filter((value) => {
return (!value.isDeprecated || !this.context.options.omitDeprecatedEnumCases);
});
this.printNewlineIfNeeded();
this.comment(description || undefined);
this.printOnNewline((0, language_1.swift) `public enum ${name}: RawRepresentable, Equatable, Hashable, CaseIterable, Apollo.JSONDecodable, Apollo.JSONEncodable`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `public typealias RawValue = String`);
values.forEach((value) => {
this.comment(value.description || undefined);
this.deprecationAttributes(value.isDeprecated, value.deprecationReason || undefined);
this.printOnNewline((0, language_1.swift) `case ${this.helpers.enumCaseName(value.name)}`);
});
this.comment("Auto generated constant for unknown enum values");
this.printOnNewline((0, language_1.swift) `case __unknown(RawValue)`);
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public init?(rawValue: RawValue)`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `switch rawValue`);
this.withinBlock(() => {
values.forEach((value) => {
this.printOnNewline((0, language_1.swift) `case ${language_1.SwiftSource.string(value.value)}: self = ${this.helpers.enumDotCaseName(value.name)}`);
});
this.printOnNewline((0, language_1.swift) `default: self = .__unknown(rawValue)`);
});
});
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public var rawValue: RawValue`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `switch self`);
this.withinBlock(() => {
values.forEach((value) => {
this.printOnNewline((0, language_1.swift) `case ${this.helpers.enumDotCaseName(value.name)}: return ${language_1.SwiftSource.string(value.value)}`);
});
this.printOnNewline((0, language_1.swift) `case .__unknown(let value): return value`);
});
});
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public static func == (lhs: ${name}, rhs: ${name}) -> Bool`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `switch (lhs, rhs)`);
this.withinBlock(() => {
values.forEach((value) => {
const enumDotCaseName = this.helpers.enumDotCaseName(value.name);
const tuple = (0, language_1.swift) `(${enumDotCaseName}, ${enumDotCaseName})`;
this.printOnNewline((0, language_1.swift) `case ${tuple}: return true`);
});
this.printOnNewline((0, language_1.swift) `case (.__unknown(let lhsValue), .__unknown(let rhsValue)): return lhsValue == rhsValue`);
this.printOnNewline((0, language_1.swift) `default: return false`);
});
});
this.printNewlineIfNeeded();
this.printOnNewline((0, language_1.swift) `public static var allCases: [${name}]`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `return [`);
values.forEach((value) => {
const enumDotCaseName = this.helpers.enumDotCaseName(value.name);
this.withIndent(() => {
this.printOnNewline((0, language_1.swift) `${enumDotCaseName},`);
});
});
this.printOnNewline((0, language_1.swift) `]`);
});
});
}
structDeclarationForInputObjectType(type, outputIndividualFiles) {
const { name: structName, description } = type;
const adoptedProtocols = ["GraphQLMapConvertible"];
const fields = Object.values(type.getFields());
const properties = fields.map(this.helpers.propertyFromInputField, this.helpers);
properties.forEach((property) => {
if (property.isOptional) {
property.typeName = `Swift.Optional<${property.typeName}>`;
}
});
this.structDeclaration({ structName, description: description || undefined, adoptedProtocols }, outputIndividualFiles, () => {
this.printOnNewline((0, language_1.swift) `public var graphQLMap: GraphQLMap`);
this.printNewlineIfNeeded();
if (properties.length > 0) {
this.comment("- Parameters:");
properties.forEach((property) => {
var propertyDescription = "";
if (property.description) {
propertyDescription = `: ${property.description}`;
}
this.comment(` - ${property.propertyName}${propertyDescription}`, false);
});
}
this.printOnNewline((0, language_1.swift) `public init`);
this.print((0, language_1.swift) `(`);
this.print(join(properties.map(({ propertyName, typeName, isOptional }) => {
const internalName = this.helpers.internalParameterName(propertyName, properties);
const decl = internalName === propertyName
? propertyName
: (0, language_1.swift) `${propertyName} ${internalName}`;
return join([
(0, language_1.swift) `${decl}: ${typeName}`,
isOptional ? (0, language_1.swift) ` = nil` : undefined,
]);
}), ", "));
this.print((0, language_1.swift) `)`);
this.withinBlock(() => {
this.printOnNewline(wrap((0, language_1.swift) `graphQLMap = [`, join(properties.map(({ name, propertyName }) => (0, language_1.swift) `${language_1.SwiftSource.string(name)}: ${this.helpers.internalParameterName(propertyName, properties)}`), ", ") || (0, language_1.swift) `:`, (0, language_1.swift) `]`));
});
for (const { name, propertyName, typeName, description, isOptional, } of properties) {
this.printNewlineIfNeeded();
this.comment(description || undefined);
this.printOnNewline((0, language_1.swift) `public var ${propertyName}: ${typeName}`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `get`);
this.withinBlock(() => {
if (isOptional) {
this.printOnNewline((0, language_1.swift) `return graphQLMap[${language_1.SwiftSource.string(name)}] as? ${typeName} ?? ${typeName}.none`);
}
else {
this.printOnNewline((0, language_1.swift) `return graphQLMap[${language_1.SwiftSource.string(name)}] as! ${typeName}`);
}
});
this.printOnNewline((0, language_1.swift) `set`);
this.withinBlock(() => {
this.printOnNewline((0, language_1.swift) `graphQLMap.updateValue(newValue, forKey: ${language_1.SwiftSource.string(name)})`);
});
});
}
});
}
}
exports.SwiftAPIGenerator = SwiftAPIGenerator;
//# sourceMappingURL=codeGeneration.js.map