UNPKG

38.1 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.SwiftAPIGenerator = exports.generateSource = void 0;
7const path_1 = __importDefault(require("path"));
8const graphql_1 = require("graphql");
9const language_1 = require("./language");
10const helpers_1 = require("./helpers");
11const graphql_2 = require("apollo-codegen-core/lib/utilities/graphql");
12const typeCase_1 = require("apollo-codegen-core/lib/compiler/visitors/typeCase");
13const collectFragmentsReferenced_1 = require("apollo-codegen-core/lib/compiler/visitors/collectFragmentsReferenced");
14const generateOperationId_1 = require("apollo-codegen-core/lib/compiler/visitors/generateOperationId");
15const collectAndMergeFields_1 = require("apollo-codegen-core/lib/compiler/visitors/collectAndMergeFields");
16require("apollo-codegen-core/lib/utilities/array");
17const { join, wrap } = language_1.SwiftSource;
18function generateSource(context, outputIndividualFiles, suppressMultilineStringLiterals, only) {
19 const generator = new SwiftAPIGenerator(context);
20 if (outputIndividualFiles) {
21 generator.withinFile(`Types.graphql.swift`, () => {
22 generator.fileHeader();
23 generator.namespaceDeclaration(context.options.namespace, () => {
24 context.typesUsed.forEach(type => {
25 generator.typeDeclarationForGraphQLType(type, true);
26 });
27 });
28 });
29 const inputFilePaths = new Set();
30 Object.values(context.operations).forEach(operation => {
31 inputFilePaths.add(operation.filePath);
32 });
33 Object.values(context.fragments).forEach(fragment => {
34 inputFilePaths.add(fragment.filePath);
35 });
36 for (const inputFilePath of inputFilePaths) {
37 if (only && inputFilePath !== only)
38 continue;
39 generator.withinFile(`${path_1.default.basename(inputFilePath)}.swift`, () => {
40 generator.fileHeader();
41 generator.namespaceExtensionDeclaration(context.options.namespace, () => {
42 Object.values(context.operations).forEach(operation => {
43 if (operation.filePath === inputFilePath) {
44 generator.classDeclarationForOperation(operation, true, suppressMultilineStringLiterals);
45 }
46 });
47 Object.values(context.fragments).forEach(fragment => {
48 if (fragment.filePath === inputFilePath) {
49 generator.structDeclarationForFragment(fragment, true, suppressMultilineStringLiterals);
50 }
51 });
52 });
53 });
54 }
55 }
56 else {
57 generator.fileHeader();
58 generator.namespaceDeclaration(context.options.namespace, () => {
59 context.typesUsed.forEach(type => {
60 generator.typeDeclarationForGraphQLType(type, false);
61 });
62 Object.values(context.operations).forEach(operation => {
63 generator.classDeclarationForOperation(operation, false, suppressMultilineStringLiterals);
64 });
65 Object.values(context.fragments).forEach(fragment => {
66 generator.structDeclarationForFragment(fragment, false, suppressMultilineStringLiterals);
67 });
68 });
69 }
70 return generator;
71}
72exports.generateSource = generateSource;
73class SwiftAPIGenerator extends language_1.SwiftGenerator {
74 constructor(context) {
75 super(context);
76 this.helpers = new helpers_1.Helpers(context.options);
77 }
78 fileHeader() {
79 this.printOnNewline(language_1.SwiftSource.raw `// @generated`);
80 this.printOnNewline(language_1.SwiftSource.raw `// This file was automatically generated and should not be edited.`);
81 this.printNewline();
82 this.printOnNewline(language_1.swift `import Apollo`);
83 this.printOnNewline(language_1.swift `import Foundation`);
84 }
85 classDeclarationForOperation(operation, outputIndividualFiles, suppressMultilineStringLiterals) {
86 const { operationName, operationType, variables, source, selectionSet } = operation;
87 let className;
88 let protocol;
89 switch (operationType) {
90 case "query":
91 className = `${this.helpers.operationClassName(operationName)}Query`;
92 protocol = "GraphQLQuery";
93 break;
94 case "mutation":
95 className = `${this.helpers.operationClassName(operationName)}Mutation`;
96 protocol = "GraphQLMutation";
97 break;
98 case "subscription":
99 className = `${this.helpers.operationClassName(operationName)}Subscription`;
100 protocol = "GraphQLSubscription";
101 break;
102 default:
103 throw new graphql_1.GraphQLError(`Unsupported operation type "${operationType}"`);
104 }
105 const { options: { namespace }, fragments } = this.context;
106 const isRedundant = !!namespace && outputIndividualFiles;
107 const modifiers = isRedundant ? ["final"] : ["public", "final"];
108 this.classDeclaration({
109 className,
110 modifiers,
111 adoptedProtocols: [protocol]
112 }, () => {
113 if (source) {
114 this.comment("The raw GraphQL definition of this operation.");
115 this.printOnNewline(language_1.swift `public let operationDefinition: String =`);
116 this.withIndent(() => {
117 this.multilineString(source, suppressMultilineStringLiterals);
118 });
119 }
120 this.printNewlineIfNeeded();
121 this.printOnNewline(language_1.swift `public let operationName: String = ${language_1.SwiftSource.string(operationName)}`);
122 const fragmentsReferenced = collectFragmentsReferenced_1.collectFragmentsReferenced(operation.selectionSet, fragments);
123 if (this.context.options.generateOperationIds) {
124 const { operationId, sourceWithFragments } = generateOperationId_1.generateOperationId(operation, fragments, fragmentsReferenced);
125 operation.operationId = operationId;
126 operation.sourceWithFragments = sourceWithFragments;
127 this.printNewlineIfNeeded();
128 this.printOnNewline(language_1.swift `public let operationIdentifier: String? = ${language_1.SwiftSource.string(operationId)}`);
129 }
130 if (fragmentsReferenced.size > 0) {
131 this.printNewlineIfNeeded();
132 this.printOnNewline(language_1.swift `public var queryDocument: String`);
133 this.withinBlock(() => {
134 this.printOnNewline(language_1.swift `var document: String = operationDefinition`);
135 fragmentsReferenced.forEach(fragmentName => {
136 this.printOnNewline(language_1.swift `document.append("\\n" + ${this.helpers.structNameForFragmentName(fragmentName)}.fragmentDefinition)`);
137 });
138 this.printOnNewline(language_1.swift `return document`);
139 });
140 }
141 this.printNewlineIfNeeded();
142 if (variables && variables.length > 0) {
143 const properties = variables.map(({ name, type }) => {
144 const typeName = this.helpers.typeNameFromGraphQLType(type);
145 const isOptional = !(graphql_1.isNonNullType(type) ||
146 (graphql_1.isListType(type) && graphql_1.isNonNullType(type.ofType)));
147 return { name, propertyName: name, type, typeName, isOptional };
148 });
149 this.propertyDeclarations(properties);
150 this.printNewlineIfNeeded();
151 this.initializerDeclarationForProperties(properties);
152 this.printNewlineIfNeeded();
153 this.printOnNewline(language_1.swift `public var variables: GraphQLMap?`);
154 this.withinBlock(() => {
155 this.printOnNewline(wrap(language_1.swift `return [`, join(properties.map(({ name, propertyName }) => language_1.swift `${language_1.SwiftSource.string(name)}: ${propertyName}`), ", ") || language_1.swift `:`, language_1.swift `]`));
156 });
157 }
158 else {
159 this.initializerDeclarationForProperties([]);
160 }
161 this.structDeclarationForSelectionSet({
162 structName: "Data",
163 selectionSet
164 }, outputIndividualFiles);
165 });
166 }
167 structDeclarationForFragment({ fragmentName, selectionSet, source }, outputIndividualFiles, suppressMultilineStringLiterals) {
168 const structName = this.helpers.structNameForFragmentName(fragmentName);
169 this.structDeclarationForSelectionSet({
170 structName,
171 adoptedProtocols: ["GraphQLFragment"],
172 selectionSet
173 }, outputIndividualFiles, () => {
174 if (source) {
175 this.comment("The raw GraphQL definition of this fragment.");
176 this.printOnNewline(language_1.swift `public static let fragmentDefinition: String =`);
177 this.withIndent(() => {
178 this.multilineString(source, suppressMultilineStringLiterals);
179 });
180 }
181 });
182 }
183 structDeclarationForSelectionSet({ structName, adoptedProtocols = ["GraphQLSelectionSet"], selectionSet }, outputIndividualFiles, before) {
184 const typeCase = typeCase_1.typeCaseForSelectionSet(selectionSet, !!this.context.options.mergeInFieldsFromFragmentSpreads);
185 this.structDeclarationForVariant({
186 structName,
187 adoptedProtocols,
188 variant: typeCase.default,
189 typeCase
190 }, outputIndividualFiles, before, () => {
191 const variants = typeCase.variants.map(this.helpers.propertyFromVariant, this.helpers);
192 for (const variant of variants) {
193 this.propertyDeclarationForVariant(variant);
194 this.structDeclarationForVariant({
195 structName: variant.structName,
196 variant
197 }, outputIndividualFiles);
198 }
199 });
200 }
201 structDeclarationForVariant({ structName, adoptedProtocols = ["GraphQLSelectionSet"], variant, typeCase }, outputIndividualFiles, before, after) {
202 const { options: { namespace, mergeInFieldsFromFragmentSpreads, omitDeprecatedEnumCases } } = this.context;
203 this.structDeclaration({ structName, adoptedProtocols, namespace }, outputIndividualFiles, () => {
204 if (before) {
205 before();
206 }
207 this.printNewlineIfNeeded();
208 this.printOnNewline(language_1.swift `public static let possibleTypes: [String] = [`);
209 this.print(join(variant.possibleTypes.map(type => language_1.swift `${language_1.SwiftSource.string(type.name)}`), ", "));
210 this.print(language_1.swift `]`);
211 this.printNewlineIfNeeded();
212 this.printOnNewline(language_1.swift `public static var selections: [GraphQLSelection] {`);
213 this.withIndent(() => {
214 this.printOnNewline(language_1.swift `return `);
215 if (typeCase) {
216 this.typeCaseInitialization(typeCase);
217 }
218 else {
219 this.selectionSetInitialization(variant);
220 }
221 });
222 this.printOnNewline(language_1.swift `}`);
223 this.printNewlineIfNeeded();
224 this.printOnNewline(language_1.swift `public private(set) var resultMap: ResultMap`);
225 this.printNewlineIfNeeded();
226 this.printOnNewline(language_1.swift `public init(unsafeResultMap: ResultMap)`);
227 this.withinBlock(() => {
228 this.printOnNewline(language_1.swift `self.resultMap = unsafeResultMap`);
229 });
230 if (typeCase) {
231 this.initializersForTypeCase(typeCase);
232 }
233 else {
234 this.initializersForVariant(variant);
235 }
236 const fields = collectAndMergeFields_1.collectAndMergeFields(variant, !!mergeInFieldsFromFragmentSpreads).map(field => this.helpers.propertyFromField(field));
237 const fragmentSpreads = variant.fragmentSpreads.map(fragmentSpread => {
238 const isConditional = variant.possibleTypes.some(type => !fragmentSpread.selectionSet.possibleTypes.includes(type));
239 return this.helpers.propertyFromFragmentSpread(fragmentSpread, isConditional);
240 });
241 fields.forEach(this.propertyDeclarationForField, this);
242 if (fragmentSpreads.length > 0) {
243 this.printNewlineIfNeeded();
244 this.printOnNewline(language_1.swift `public var fragments: Fragments`);
245 this.withinBlock(() => {
246 this.printOnNewline(language_1.swift `get`);
247 this.withinBlock(() => {
248 this.printOnNewline(language_1.swift `return Fragments(unsafeResultMap: resultMap)`);
249 });
250 this.printOnNewline(language_1.swift `set`);
251 this.withinBlock(() => {
252 this.printOnNewline(language_1.swift `resultMap += newValue.resultMap`);
253 });
254 });
255 this.structDeclaration({
256 structName: "Fragments"
257 }, outputIndividualFiles, () => {
258 this.printOnNewline(language_1.swift `public private(set) var resultMap: ResultMap`);
259 this.printNewlineIfNeeded();
260 this.printOnNewline(language_1.swift `public init(unsafeResultMap: ResultMap)`);
261 this.withinBlock(() => {
262 this.printOnNewline(language_1.swift `self.resultMap = unsafeResultMap`);
263 });
264 for (const fragmentSpread of fragmentSpreads) {
265 const { propertyName, typeName, structName, isConditional } = fragmentSpread;
266 this.printNewlineIfNeeded();
267 this.printOnNewline(language_1.swift `public var ${propertyName}: ${typeName}`);
268 this.withinBlock(() => {
269 this.printOnNewline(language_1.swift `get`);
270 this.withinBlock(() => {
271 if (isConditional) {
272 this.printOnNewline(language_1.swift `if !${structName}.possibleTypes.contains(resultMap["__typename"]! as! String) { return nil }`);
273 }
274 this.printOnNewline(language_1.swift `return ${structName}(unsafeResultMap: resultMap)`);
275 });
276 this.printOnNewline(language_1.swift `set`);
277 this.withinBlock(() => {
278 if (isConditional) {
279 this.printOnNewline(language_1.swift `guard let newValue = newValue else { return }`);
280 this.printOnNewline(language_1.swift `resultMap += newValue.resultMap`);
281 }
282 else {
283 this.printOnNewline(language_1.swift `resultMap += newValue.resultMap`);
284 }
285 });
286 });
287 }
288 });
289 }
290 for (const field of fields) {
291 if (graphql_1.isCompositeType(graphql_1.getNamedType(field.type)) && field.selectionSet) {
292 this.structDeclarationForSelectionSet({
293 structName: field.structName,
294 selectionSet: field.selectionSet
295 }, outputIndividualFiles);
296 }
297 }
298 if (after) {
299 after();
300 }
301 });
302 }
303 initializersForTypeCase(typeCase) {
304 const variants = typeCase.variants;
305 if (variants.length == 0) {
306 this.initializersForVariant(typeCase.default);
307 }
308 else {
309 const remainder = typeCase.remainder;
310 for (const variant of remainder ? [remainder, ...variants] : variants) {
311 this.initializersForVariant(variant, variant === remainder
312 ? undefined
313 : this.helpers.structNameForVariant(variant), false);
314 }
315 }
316 }
317 initializersForVariant(variant, namespace, useInitializerIfPossible = true) {
318 if (useInitializerIfPossible && variant.possibleTypes.length == 1) {
319 const properties = this.helpers.propertiesForSelectionSet(variant);
320 if (!properties)
321 return;
322 this.printNewlineIfNeeded();
323 this.printOnNewline(language_1.swift `public init`);
324 this.parametersForProperties(properties);
325 this.withinBlock(() => {
326 this.printOnNewline(wrap(language_1.swift `self.init(unsafeResultMap: [`, join([
327 language_1.swift `"__typename": ${language_1.SwiftSource.string(variant.possibleTypes[0].toString())}`,
328 ...properties.map(p => this.propertyAssignmentForField(p, properties))
329 ], ", ") || language_1.swift `:`, language_1.swift `])`));
330 });
331 }
332 else {
333 const structName = this.scope.typeName;
334 for (const possibleType of variant.possibleTypes) {
335 const properties = this.helpers.propertiesForSelectionSet({
336 possibleTypes: [possibleType],
337 selections: variant.selections
338 }, namespace);
339 if (!properties)
340 continue;
341 this.printNewlineIfNeeded();
342 this.printOnNewline(language_1.SwiftSource.raw `public static func make${possibleType}`);
343 this.parametersForProperties(properties);
344 this.print(language_1.swift ` -> ${structName}`);
345 this.withinBlock(() => {
346 this.printOnNewline(wrap(language_1.swift `return ${structName}(unsafeResultMap: [`, join([
347 language_1.swift `"__typename": ${language_1.SwiftSource.string(possibleType.toString())}`,
348 ...properties.map(p => this.propertyAssignmentForField(p, properties))
349 ], ", ") || language_1.swift `:`, language_1.swift `])`));
350 });
351 }
352 }
353 }
354 propertyAssignmentForField(field, properties) {
355 const { responseKey, propertyName, type, isConditional, structName } = field;
356 const parameterName = this.helpers.internalParameterName(propertyName, properties);
357 const valueExpression = graphql_1.isCompositeType(graphql_1.getNamedType(type))
358 ? this.helpers.mapExpressionForType(type, isConditional, expression => language_1.swift `${expression}.resultMap`, language_1.SwiftSource.identifier(parameterName), structName, "ResultMap")
359 : language_1.SwiftSource.identifier(parameterName);
360 return language_1.swift `${language_1.SwiftSource.string(responseKey)}: ${valueExpression}`;
361 }
362 propertyDeclarationForField(field) {
363 const { responseKey, propertyName, typeName, type, isOptional, isConditional } = field;
364 const unmodifiedFieldType = graphql_1.getNamedType(type);
365 this.printNewlineIfNeeded();
366 this.comment(field.description);
367 this.deprecationAttributes(field.isDeprecated, field.deprecationReason);
368 this.printOnNewline(language_1.swift `public var ${propertyName}: ${typeName}`);
369 this.withinBlock(() => {
370 if (graphql_1.isCompositeType(unmodifiedFieldType)) {
371 const structName = this.helpers.structNameForPropertyName(responseKey);
372 if (graphql_2.isList(type)) {
373 this.printOnNewline(language_1.swift `get`);
374 this.withinBlock(() => {
375 const resultMapTypeName = this.helpers.typeNameFromGraphQLType(type, "ResultMap", false);
376 let expression;
377 if (isOptional) {
378 expression = language_1.swift `(resultMap[${language_1.SwiftSource.string(responseKey)}] as? ${resultMapTypeName})`;
379 }
380 else {
381 expression = language_1.swift `(resultMap[${language_1.SwiftSource.string(responseKey)}] as! ${resultMapTypeName})`;
382 }
383 this.printOnNewline(language_1.swift `return ${this.helpers.mapExpressionForType(type, isConditional, expression => language_1.swift `${structName}(unsafeResultMap: ${expression})`, expression, "ResultMap", structName)}`);
384 });
385 this.printOnNewline(language_1.swift `set`);
386 this.withinBlock(() => {
387 let newValueExpression = this.helpers.mapExpressionForType(type, isConditional, expression => language_1.swift `${expression}.resultMap`, language_1.swift `newValue`, structName, "ResultMap");
388 this.printOnNewline(language_1.swift `resultMap.updateValue(${newValueExpression}, forKey: ${language_1.SwiftSource.string(responseKey)})`);
389 });
390 }
391 else {
392 this.printOnNewline(language_1.swift `get`);
393 this.withinBlock(() => {
394 if (isOptional) {
395 this.printOnNewline(language_1.swift `return (resultMap[${language_1.SwiftSource.string(responseKey)}] as? ResultMap).flatMap { ${structName}(unsafeResultMap: $0) }`);
396 }
397 else {
398 this.printOnNewline(language_1.swift `return ${structName}(unsafeResultMap: resultMap[${language_1.SwiftSource.string(responseKey)}]! as! ResultMap)`);
399 }
400 });
401 this.printOnNewline(language_1.swift `set`);
402 this.withinBlock(() => {
403 let newValueExpression;
404 if (isOptional) {
405 newValueExpression = "newValue?.resultMap";
406 }
407 else {
408 newValueExpression = "newValue.resultMap";
409 }
410 this.printOnNewline(language_1.swift `resultMap.updateValue(${newValueExpression}, forKey: ${language_1.SwiftSource.string(responseKey)})`);
411 });
412 }
413 }
414 else {
415 this.printOnNewline(language_1.swift `get`);
416 this.withinBlock(() => {
417 if (isOptional) {
418 this.printOnNewline(language_1.swift `return resultMap[${language_1.SwiftSource.string(responseKey)}] as? ${typeName.slice(0, -1)}`);
419 }
420 else {
421 this.printOnNewline(language_1.swift `return resultMap[${language_1.SwiftSource.string(responseKey)}]! as! ${typeName}`);
422 }
423 });
424 this.printOnNewline(language_1.swift `set`);
425 this.withinBlock(() => {
426 this.printOnNewline(language_1.swift `resultMap.updateValue(newValue, forKey: ${language_1.SwiftSource.string(responseKey)})`);
427 });
428 }
429 });
430 }
431 propertyDeclarationForVariant(variant) {
432 const { propertyName, typeName, structName } = variant;
433 this.printNewlineIfNeeded();
434 this.printOnNewline(language_1.swift `public var ${propertyName}: ${typeName}`);
435 this.withinBlock(() => {
436 this.printOnNewline(language_1.swift `get`);
437 this.withinBlock(() => {
438 this.printOnNewline(language_1.swift `if !${structName}.possibleTypes.contains(__typename) { return nil }`);
439 this.printOnNewline(language_1.swift `return ${structName}(unsafeResultMap: resultMap)`);
440 });
441 this.printOnNewline(language_1.swift `set`);
442 this.withinBlock(() => {
443 this.printOnNewline(language_1.swift `guard let newValue = newValue else { return }`);
444 this.printOnNewline(language_1.swift `resultMap = newValue.resultMap`);
445 });
446 });
447 }
448 initializerDeclarationForProperties(properties) {
449 this.printOnNewline(language_1.swift `public init`);
450 this.parametersForProperties(properties);
451 this.withinBlock(() => {
452 properties.forEach(({ propertyName }) => {
453 this.printOnNewline(language_1.swift `self.${propertyName} = ${this.helpers.internalParameterName(propertyName, properties)}`);
454 });
455 });
456 }
457 parametersForProperties(properties) {
458 this.print(language_1.swift `(`);
459 this.print(join(properties.map(({ propertyName, typeName, isOptional }) => {
460 const internalName = this.helpers.internalParameterName(propertyName, properties);
461 const decl = internalName === propertyName
462 ? propertyName
463 : language_1.swift `${propertyName} ${internalName}`;
464 return join([
465 language_1.swift `${decl}: ${typeName}`,
466 isOptional ? language_1.swift ` = nil` : undefined
467 ]);
468 }), ", "));
469 this.print(language_1.swift `)`);
470 }
471 typeCaseInitialization(typeCase) {
472 if (typeCase.variants.length < 1) {
473 this.selectionSetInitialization(typeCase.default);
474 return;
475 }
476 this.print(language_1.swift `[`);
477 this.withIndent(() => {
478 this.printOnNewline(language_1.swift `GraphQLTypeCase(`);
479 this.withIndent(() => {
480 this.printOnNewline(language_1.swift `variants: [`);
481 this.print(join(typeCase.variants.flatMap(variant => {
482 const structName = this.helpers.structNameForVariant(variant);
483 return variant.possibleTypes.map(type => language_1.swift `${language_1.SwiftSource.string(type.toString())}: ${structName}.selections`);
484 }), ", "));
485 this.print(language_1.swift `],`);
486 this.printOnNewline(language_1.swift `default: `);
487 this.selectionSetInitialization(typeCase.default);
488 });
489 this.printOnNewline(language_1.swift `)`);
490 });
491 this.printOnNewline(language_1.swift `]`);
492 }
493 selectionSetInitialization(selectionSet) {
494 this.print(language_1.swift `[`);
495 this.withIndent(() => {
496 for (const selection of selectionSet.selections) {
497 switch (selection.kind) {
498 case "Field": {
499 const { name, alias, args, type } = selection;
500 const responseKey = selection.alias || selection.name;
501 const structName = this.helpers.structNameForPropertyName(responseKey);
502 this.printOnNewline(language_1.swift `GraphQLField(`);
503 this.print(join([
504 language_1.swift `${language_1.SwiftSource.string(name)}`,
505 alias
506 ? language_1.swift `alias: ${language_1.SwiftSource.string(alias)}`
507 : undefined,
508 args && args.length
509 ? language_1.swift `arguments: ${this.helpers.dictionaryLiteralForFieldArguments(args)}`
510 : undefined,
511 language_1.swift `type: ${this.helpers.fieldTypeEnum(type, structName)}`
512 ], ", "));
513 this.print(language_1.swift `),`);
514 break;
515 }
516 case "BooleanCondition":
517 this.printOnNewline(language_1.swift `GraphQLBooleanCondition(`);
518 this.print(join([
519 language_1.swift `variableName: ${language_1.SwiftSource.string(selection.variableName)}`,
520 language_1.swift `inverted: ${selection.inverted}`,
521 language_1.swift `selections: `
522 ], ", "));
523 this.selectionSetInitialization(selection.selectionSet);
524 this.print(language_1.swift `),`);
525 break;
526 case "TypeCondition": {
527 this.printOnNewline(language_1.swift `GraphQLTypeCondition(`);
528 this.print(join([
529 language_1.swift `possibleTypes: [${join(selection.selectionSet.possibleTypes.map(type => language_1.swift `${language_1.SwiftSource.string(type.name)}`), ", ")}]`,
530 language_1.swift `selections: `
531 ], ", "));
532 this.selectionSetInitialization(selection.selectionSet);
533 this.print(language_1.swift `),`);
534 break;
535 }
536 case "FragmentSpread": {
537 const structName = this.helpers.structNameForFragmentName(selection.fragmentName);
538 this.printOnNewline(language_1.swift `GraphQLFragmentSpread(${structName}.self),`);
539 break;
540 }
541 }
542 }
543 });
544 this.printOnNewline(language_1.swift `]`);
545 }
546 typeDeclarationForGraphQLType(type, outputIndividualFiles) {
547 if (graphql_1.isEnumType(type)) {
548 this.enumerationDeclaration(type);
549 }
550 else if (graphql_1.isInputObjectType(type)) {
551 this.structDeclarationForInputObjectType(type, outputIndividualFiles);
552 }
553 }
554 enumerationDeclaration(type) {
555 const { name, description } = type;
556 const values = type.getValues().filter(value => {
557 return (!value.isDeprecated || !this.context.options.omitDeprecatedEnumCases);
558 });
559 this.printNewlineIfNeeded();
560 this.comment(description || undefined);
561 this.printOnNewline(language_1.swift `public enum ${name}: RawRepresentable, Equatable, Hashable, CaseIterable, Apollo.JSONDecodable, Apollo.JSONEncodable`);
562 this.withinBlock(() => {
563 this.printOnNewline(language_1.swift `public typealias RawValue = String`);
564 values.forEach(value => {
565 this.comment(value.description || undefined);
566 this.deprecationAttributes(value.isDeprecated, value.deprecationReason || undefined);
567 this.printOnNewline(language_1.swift `case ${this.helpers.enumCaseName(value.name)}`);
568 });
569 this.comment("Auto generated constant for unknown enum values");
570 this.printOnNewline(language_1.swift `case __unknown(RawValue)`);
571 this.printNewlineIfNeeded();
572 this.printOnNewline(language_1.swift `public init?(rawValue: RawValue)`);
573 this.withinBlock(() => {
574 this.printOnNewline(language_1.swift `switch rawValue`);
575 this.withinBlock(() => {
576 values.forEach(value => {
577 this.printOnNewline(language_1.swift `case ${language_1.SwiftSource.string(value.value)}: self = ${this.helpers.enumDotCaseName(value.name)}`);
578 });
579 this.printOnNewline(language_1.swift `default: self = .__unknown(rawValue)`);
580 });
581 });
582 this.printNewlineIfNeeded();
583 this.printOnNewline(language_1.swift `public var rawValue: RawValue`);
584 this.withinBlock(() => {
585 this.printOnNewline(language_1.swift `switch self`);
586 this.withinBlock(() => {
587 values.forEach(value => {
588 this.printOnNewline(language_1.swift `case ${this.helpers.enumDotCaseName(value.name)}: return ${language_1.SwiftSource.string(value.value)}`);
589 });
590 this.printOnNewline(language_1.swift `case .__unknown(let value): return value`);
591 });
592 });
593 this.printNewlineIfNeeded();
594 this.printOnNewline(language_1.swift `public static func == (lhs: ${name}, rhs: ${name}) -> Bool`);
595 this.withinBlock(() => {
596 this.printOnNewline(language_1.swift `switch (lhs, rhs)`);
597 this.withinBlock(() => {
598 values.forEach(value => {
599 const enumDotCaseName = this.helpers.enumDotCaseName(value.name);
600 const tuple = language_1.swift `(${enumDotCaseName}, ${enumDotCaseName})`;
601 this.printOnNewline(language_1.swift `case ${tuple}: return true`);
602 });
603 this.printOnNewline(language_1.swift `case (.__unknown(let lhsValue), .__unknown(let rhsValue)): return lhsValue == rhsValue`);
604 this.printOnNewline(language_1.swift `default: return false`);
605 });
606 });
607 this.printNewlineIfNeeded();
608 this.printOnNewline(language_1.swift `public static var allCases: [${name}]`);
609 this.withinBlock(() => {
610 this.printOnNewline(language_1.swift `return [`);
611 values.forEach(value => {
612 const enumDotCaseName = this.helpers.enumDotCaseName(value.name);
613 this.withIndent(() => {
614 this.printOnNewline(language_1.swift `${enumDotCaseName},`);
615 });
616 });
617 this.printOnNewline(language_1.swift `]`);
618 });
619 });
620 }
621 structDeclarationForInputObjectType(type, outputIndividualFiles) {
622 const { name: structName, description } = type;
623 const adoptedProtocols = ["GraphQLMapConvertible"];
624 const fields = Object.values(type.getFields());
625 const properties = fields.map(this.helpers.propertyFromInputField, this.helpers);
626 properties.forEach(property => {
627 if (property.isOptional) {
628 property.typeName = `Swift.Optional<${property.typeName}>`;
629 }
630 });
631 this.structDeclaration({ structName, description: description || undefined, adoptedProtocols }, outputIndividualFiles, () => {
632 this.printOnNewline(language_1.swift `public var graphQLMap: GraphQLMap`);
633 this.printNewlineIfNeeded();
634 if (properties.length > 0) {
635 this.comment("- Parameters:");
636 properties.forEach(property => {
637 var propertyDescription = "";
638 if (property.description) {
639 propertyDescription = `: ${property.description}`;
640 }
641 this.comment(` - ${property.propertyName}${propertyDescription}`, false);
642 });
643 }
644 this.printOnNewline(language_1.swift `public init`);
645 this.print(language_1.swift `(`);
646 this.print(join(properties.map(({ propertyName, typeName, isOptional }) => {
647 const internalName = this.helpers.internalParameterName(propertyName, properties);
648 const decl = internalName === propertyName
649 ? propertyName
650 : language_1.swift `${propertyName} ${internalName}`;
651 return join([
652 language_1.swift `${decl}: ${typeName}`,
653 isOptional ? language_1.swift ` = nil` : undefined
654 ]);
655 }), ", "));
656 this.print(language_1.swift `)`);
657 this.withinBlock(() => {
658 this.printOnNewline(wrap(language_1.swift `graphQLMap = [`, join(properties.map(({ name, propertyName }) => language_1.swift `${language_1.SwiftSource.string(name)}: ${this.helpers.internalParameterName(propertyName, properties)}`), ", ") || language_1.swift `:`, language_1.swift `]`));
659 });
660 for (const { name, propertyName, typeName, description, isOptional } of properties) {
661 this.printNewlineIfNeeded();
662 this.comment(description || undefined);
663 this.printOnNewline(language_1.swift `public var ${propertyName}: ${typeName}`);
664 this.withinBlock(() => {
665 this.printOnNewline(language_1.swift `get`);
666 this.withinBlock(() => {
667 if (isOptional) {
668 this.printOnNewline(language_1.swift `return graphQLMap[${language_1.SwiftSource.string(name)}] as? ${typeName} ?? ${typeName}.none`);
669 }
670 else {
671 this.printOnNewline(language_1.swift `return graphQLMap[${language_1.SwiftSource.string(name)}] as! ${typeName}`);
672 }
673 });
674 this.printOnNewline(language_1.swift `set`);
675 this.withinBlock(() => {
676 this.printOnNewline(language_1.swift `graphQLMap.updateValue(newValue, forKey: ${language_1.SwiftSource.string(name)})`);
677 });
678 });
679 }
680 });
681 }
682}
683exports.SwiftAPIGenerator = SwiftAPIGenerator;
684//# sourceMappingURL=codeGeneration.js.map
\No newline at end of file